1 // Copyright 2023 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.net.telemetry; 6 7 /** Utility class for grouping requests/responses into buckets */ 8 public final class SizeBuckets { 9 /** 10 * Accepts a value in Bytes and groups it in buckets based on the Kilobyte value; 11 * 12 * @param sizeBytes size in Bytes 13 * @return int bucket group 14 */ calcRequestHeadersSizeBucket(long sizeBytes)15 public static int calcRequestHeadersSizeBucket(long sizeBytes) { 16 checkSizeIsValid(sizeBytes, "Request header size is negative"); 17 18 double sizeKB = sizeBytes / 1024.0; 19 20 if (isInClosedOpenRange(sizeKB, 0, 1)) { 21 return CronetStatsLog 22 .CRONET_TRAFFIC_REPORTED__REQUEST_HEADERS_SIZE__REQUEST_HEADERS_SIZE_BUCKET_UNDER_ONE_KIB; 23 } else if (isInClosedOpenRange(sizeKB, 1, 10)) { 24 return CronetStatsLog 25 .CRONET_TRAFFIC_REPORTED__REQUEST_HEADERS_SIZE__REQUEST_HEADERS_SIZE_BUCKET_ONE_TO_TEN_KIB; 26 } else if (isInClosedOpenRange(sizeKB, 10, 25)) { 27 return CronetStatsLog 28 .CRONET_TRAFFIC_REPORTED__REQUEST_HEADERS_SIZE__REQUEST_HEADERS_SIZE_BUCKET_TEN_TO_TWENTY_FIVE_KIB; 29 } else if (isInClosedOpenRange(sizeKB, 25, 50)) { 30 return CronetStatsLog 31 .CRONET_TRAFFIC_REPORTED__REQUEST_HEADERS_SIZE__REQUEST_HEADERS_SIZE_BUCKET_TWENTY_FIVE_TO_FIFTY_KIB; 32 } else if (isInClosedOpenRange(sizeKB, 50, 100)) { 33 return CronetStatsLog 34 .CRONET_TRAFFIC_REPORTED__REQUEST_HEADERS_SIZE__REQUEST_HEADERS_SIZE_BUCKET_FIFTY_TO_HUNDRED_KIB; 35 } else { // sizeKB >= 100 36 return CronetStatsLog 37 .CRONET_TRAFFIC_REPORTED__REQUEST_HEADERS_SIZE__REQUEST_HEADERS_SIZE_BUCKET_OVER_HUNDRED_KIB; 38 } 39 } 40 41 /** 42 * Accepts a value in Bytes and groups it in buckets based on the Kilobyte value; 43 * 44 * @param sizeBytes size in Bytes 45 * @return int bucket group 46 */ calcResponseHeadersSizeBucket(long sizeBytes)47 public static int calcResponseHeadersSizeBucket(long sizeBytes) { 48 checkSizeIsValid(sizeBytes, "Response header size is negative"); 49 50 double sizeKB = sizeBytes / 1024.0; 51 52 if (isInClosedOpenRange(sizeKB, 0, 1)) { 53 return CronetStatsLog 54 .CRONET_TRAFFIC_REPORTED__RESPONSE_HEADERS_SIZE__RESPONSE_HEADERS_SIZE_BUCKET_UNDER_ONE_KIB; 55 } else if (isInClosedOpenRange(sizeKB, 1, 10)) { 56 return CronetStatsLog 57 .CRONET_TRAFFIC_REPORTED__RESPONSE_HEADERS_SIZE__RESPONSE_HEADERS_SIZE_BUCKET_ONE_TO_TEN_KIB; 58 } else if (isInClosedOpenRange(sizeKB, 10, 25)) { 59 return CronetStatsLog 60 .CRONET_TRAFFIC_REPORTED__RESPONSE_HEADERS_SIZE__RESPONSE_HEADERS_SIZE_BUCKET_TEN_TO_TWENTY_FIVE_KIB; 61 } else if (isInClosedOpenRange(sizeKB, 25, 50)) { 62 return CronetStatsLog 63 .CRONET_TRAFFIC_REPORTED__RESPONSE_HEADERS_SIZE__RESPONSE_HEADERS_SIZE_BUCKET_TWENTY_FIVE_TO_FIFTY_KIB; 64 } else if (isInClosedOpenRange(sizeKB, 50, 100)) { 65 return CronetStatsLog 66 .CRONET_TRAFFIC_REPORTED__RESPONSE_HEADERS_SIZE__RESPONSE_HEADERS_SIZE_BUCKET_FIFTY_TO_HUNDRED_KIB; 67 } else { // sizeKB >= 100 68 return CronetStatsLog 69 .CRONET_TRAFFIC_REPORTED__RESPONSE_HEADERS_SIZE__RESPONSE_HEADERS_SIZE_BUCKET_OVER_HUNDRED_KIB; 70 } 71 } 72 73 /** 74 * Accepts a value in Bytes and groups it in buckets based on the Kilobyte value; 75 * 76 * @param sizeBytes size in Bytes 77 * @return int bucket group 78 */ calcRequestBodySizeBucket(long sizeBytes)79 public static int calcRequestBodySizeBucket(long sizeBytes) { 80 checkSizeIsValid(sizeBytes, "Request body size is negative"); 81 82 double sizeKB = sizeBytes / 1024.0; 83 84 if (sizeKB == 0) { 85 return CronetStatsLog 86 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_ZERO; 87 } else if (sizeKB > 0 && sizeKB < 10) { 88 return CronetStatsLog 89 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_UNDER_TEN_KIB; 90 } else if (isInClosedOpenRange(sizeKB, 10, 50)) { 91 return CronetStatsLog 92 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_TEN_TO_FIFTY_KIB; 93 } else if (isInClosedOpenRange(sizeKB, 50, 200)) { 94 return CronetStatsLog 95 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_FIFTY_TO_TWO_HUNDRED_KIB; 96 } else if (isInClosedOpenRange(sizeKB, 200, 500)) { 97 return CronetStatsLog 98 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_TWO_HUNDRED_TO_FIVE_HUNDRED_KIB; 99 } else if (isInClosedOpenRange(sizeKB, 500, 1000)) { 100 return CronetStatsLog 101 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_FIVE_HUNDRED_KIB_TO_ONE_MIB; 102 } else if (isInClosedOpenRange(sizeKB, 1000, 5000)) { 103 return CronetStatsLog 104 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_ONE_TO_FIVE_MIB; 105 } else { // sizeKB >= 5000 106 return CronetStatsLog 107 .CRONET_TRAFFIC_REPORTED__REQUEST_BODY_SIZE__REQUEST_BODY_SIZE_BUCKET_OVER_FIVE_MIB; 108 } 109 } 110 111 /** 112 * Accepts a value in Bytes and groups it in buckets based on the Kilobyte value; 113 * 114 * @param sizeBytes size in Bytes 115 * @return int bucket group 116 */ calcResponseBodySizeBucket(long sizeBytes)117 public static int calcResponseBodySizeBucket(long sizeBytes) { 118 checkSizeIsValid(sizeBytes, "Response body size is negative"); 119 120 double sizeKB = sizeBytes / 1024.0; 121 122 if (sizeKB == 0) { 123 return CronetStatsLog 124 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_ZERO; 125 } else if (sizeKB > 0 && sizeKB < 10) { 126 return CronetStatsLog 127 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_UNDER_TEN_KIB; 128 } else if (isInClosedOpenRange(sizeKB, 10, 50)) { 129 return CronetStatsLog 130 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_TEN_TO_FIFTY_KIB; 131 } else if (isInClosedOpenRange(sizeKB, 50, 200)) { 132 return CronetStatsLog 133 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_FIFTY_TO_TWO_HUNDRED_KIB; 134 } else if (isInClosedOpenRange(sizeKB, 200, 500)) { 135 return CronetStatsLog 136 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_TWO_HUNDRED_TO_FIVE_HUNDRED_KIB; 137 } else if (isInClosedOpenRange(sizeKB, 500, 1000)) { 138 return CronetStatsLog 139 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_FIVE_HUNDRED_KIB_TO_ONE_MIB; 140 } else if (isInClosedOpenRange(sizeKB, 1000, 5000)) { 141 return CronetStatsLog 142 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_ONE_TO_FIVE_MIB; 143 } else { 144 return CronetStatsLog 145 .CRONET_TRAFFIC_REPORTED__RESPONSE_BODY_SIZE__RESPONSE_BODY_SIZE_BUCKET_OVER_FIVE_MIB; 146 } 147 } 148 checkSizeIsValid(long sizeBytes, String errMessage)149 private static void checkSizeIsValid(long sizeBytes, String errMessage) { 150 if (sizeBytes < 0) { 151 throw new IllegalArgumentException(errMessage); 152 } 153 } 154 isInClosedOpenRange(double value, int lowerBound, int upperBound)155 private static boolean isInClosedOpenRange(double value, int lowerBound, int upperBound) { 156 return value >= lowerBound && value < upperBound; 157 } 158 SizeBuckets()159 private SizeBuckets() {} 160 } 161