histogram.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #pragma once
  2. #include <util/generic/ptr.h>
  3. #include <util/generic/noncopyable.h>
  4. #include <util/memory/alloc.h>
  5. struct hdr_histogram;
  6. namespace NHdr {
  7. /**
  8. * A High Dynamic Range (HDR) Histogram
  9. *
  10. * THdrHistogram supports the recording and analyzing sampled data value counts
  11. * across a configurable integer value range with configurable value precision
  12. * within the range. Value precision is expressed as the number of significant
  13. * digits in the value recording, and provides control over value quantization
  14. * behavior across the value range and the subsequent value resolution at any
  15. * given level.
  16. */
  17. class THistogram: public TMoveOnly {
  18. public:
  19. /**
  20. * Construct a histogram given the Highest value to be tracked and a number
  21. * of significant decimal digits. The histogram will be constructed to
  22. * implicitly track (distinguish from 0) values as low as 1. Default
  23. * allocator will be used to allocate underlying memory.
  24. *
  25. * @param highestTrackableValue The highest value to be tracked by the
  26. * histogram. Must be a positive integer that is literal >= 2.
  27. *
  28. * @param numberOfSignificantValueDigits Specifies the precision to use.
  29. * This is the number of significant decimal digits to which the
  30. * histogram will maintain value resolution and separation. Must be
  31. * a non-negative integer between 0 and 5.
  32. */
  33. THistogram(i64 highestTrackableValue, i32 numberOfSignificantValueDigits)
  34. : THistogram(1, highestTrackableValue, numberOfSignificantValueDigits)
  35. {
  36. }
  37. /**
  38. * Construct a histogram given the Lowest and Highest values to be tracked
  39. * and a number of significant decimal digits. Providing a
  40. * lowestDiscernibleValue is useful in situations where the units used for
  41. * the histogram's values are much smaller that the minimal accuracy
  42. * required. E.g. when tracking time values stated in nanosecond units,
  43. * where the minimal accuracy required is a microsecond, the proper value
  44. * for lowestDiscernibleValue would be 1000.
  45. *
  46. * @param lowestDiscernibleValue The lowest value that can be discerned
  47. * (distinguished from 0) by the histogram. Must be a positive
  48. * integer that is >= 1. May be internally rounded down to nearest
  49. * power of 2.
  50. *
  51. * @param highestTrackableValue The highest value to be tracked by the
  52. * histogram. Must be a positive integer that is
  53. * >= (2 * lowestDiscernibleValue).
  54. *
  55. * @param numberOfSignificantValueDigits Specifies the precision to use.
  56. * This is the number of significant decimal digits to which the
  57. * histogram will maintain value resolution and separation. Must be
  58. * a non-negative integer between 0 and 5.
  59. *
  60. * @param allocator Specifies allocator which will be used to allocate
  61. * memory for histogram.
  62. */
  63. THistogram(i64 lowestDiscernibleValue, i64 highestTrackableValue,
  64. i32 numberOfSignificantValueDigits,
  65. IAllocator* allocator = TDefaultAllocator::Instance());
  66. ~THistogram();
  67. // Histogram structure querying support -----------------------------------
  68. /**
  69. * @return The configured lowestDiscernibleValue
  70. */
  71. i64 GetLowestDiscernibleValue() const;
  72. /**
  73. * @return The configured highestTrackableValue
  74. */
  75. i64 GetHighestTrackableValue() const;
  76. /**
  77. * @return The configured numberOfSignificantValueDigits
  78. */
  79. i32 GetNumberOfSignificantValueDigits() const;
  80. /**
  81. * @return The size of allocated memory for histogram
  82. */
  83. size_t GetMemorySize() const;
  84. /**
  85. * @return The number of created counters
  86. */
  87. i32 GetCountsLen() const;
  88. /**
  89. * @return The total count of all recorded values in the histogram
  90. */
  91. i64 GetTotalCount() const;
  92. // Value recording support ------------------------------------------------
  93. /**
  94. * Records a value in the histogram, will round this value of to a
  95. * precision at or better than the NumberOfSignificantValueDigits specified
  96. * at construction time.
  97. *
  98. * @param value Value to add to the histogram
  99. * @return false if the value is larger than the HighestTrackableValue
  100. * and can't be recorded, true otherwise.
  101. */
  102. bool RecordValue(i64 value);
  103. /**
  104. * Records count values in the histogram, will round this value of to a
  105. * precision at or better than the NumberOfSignificantValueDigits specified
  106. * at construction time.
  107. *
  108. * @param value Value to add to the histogram
  109. * @param count Number of values to add to the histogram
  110. * @return false if the value is larger than the HighestTrackableValue
  111. * and can't be recorded, true otherwise.
  112. */
  113. bool RecordValues(i64 value, i64 count);
  114. /**
  115. * Records a value in the histogram and backfill based on an expected
  116. * interval. Value will be rounded this to a precision at or better
  117. * than the NumberOfSignificantValueDigits specified at contruction time.
  118. * This is specifically used for recording latency. If the value is larger
  119. * than the expectedInterval then the latency recording system has
  120. * experienced co-ordinated omission. This method fills in the values that
  121. * would have occured had the client providing the load not been blocked.
  122. *
  123. * @param value Value to add to the histogram
  124. * @param expectedInterval The delay between recording values
  125. * @return false if the value is larger than the HighestTrackableValue
  126. * and can't be recorded, true otherwise.
  127. */
  128. bool RecordValueWithExpectedInterval(i64 value, i64 expectedInterval);
  129. /**
  130. * Record a value in the histogram count times. Applies the same correcting
  131. * logic as {@link THistogram::RecordValueWithExpectedInterval}.
  132. *
  133. * @param value Value to add to the histogram
  134. * @param count Number of values to add to the histogram
  135. * @param expectedInterval The delay between recording values.
  136. * @return false if the value is larger than the HighestTrackableValue
  137. * and can't be recorded, true otherwise.
  138. */
  139. bool RecordValuesWithExpectedInterval(
  140. i64 value, i64 count, i64 expectedInterval);
  141. /**
  142. * Adds all of the values from rhs to this histogram. Will return the
  143. * number of values that are dropped when copying. Values will be dropped
  144. * if they around outside of [LowestDiscernibleValue, GetHighestTrackableValue].
  145. *
  146. * @param rhs Histogram to copy values from.
  147. * @return The number of values dropped when copying.
  148. */
  149. i64 Add(const THistogram& rhs);
  150. /**
  151. * Adds all of the values from rhs to this histogram. Will return the
  152. * number of values that are dropped when copying. Values will be dropped
  153. * if they around outside of [LowestDiscernibleValue, GetHighestTrackableValue].
  154. * Applies the same correcting logic as
  155. * {@link THistogram::RecordValueWithExpectedInterval}.
  156. *
  157. * @param rhs Histogram to copy values from.
  158. * @return The number of values dropped when copying.
  159. */
  160. i64 AddWithExpectedInterval(const THistogram& rhs, i64 expectedInterval);
  161. // Histogram Data access support ------------------------------------------
  162. /**
  163. * Get the lowest recorded value level in the histogram. If the histogram
  164. * has no recorded values, the value returned is undefined.
  165. *
  166. * @return the Min value recorded in the histogram
  167. */
  168. i64 GetMin() const;
  169. /**
  170. * Get the highest recorded value level in the histogram. If the histogram
  171. * has no recorded values, the value returned is undefined.
  172. *
  173. * @return the Max value recorded in the histogram
  174. */
  175. i64 GetMax() const;
  176. /**
  177. * Get the computed mean value of all recorded values in the histogram
  178. *
  179. * @return the mean value (in value units) of the histogram data
  180. */
  181. double GetMean() const;
  182. /**
  183. * Get the computed standard deviation of all recorded values in the histogram
  184. *
  185. * @return the standard deviation (in value units) of the histogram data
  186. */
  187. double GetStdDeviation() const;
  188. /**
  189. * Get the value at a given percentile.
  190. * Note that two values are "equivalent" in this statement if
  191. * {@link THistogram::ValuesAreEquivalent} would return true.
  192. *
  193. * @param percentile The percentile for which to return the associated
  194. * value
  195. * @return The value that the given percentage of the overall recorded
  196. * value entries in the histogram are either smaller than or
  197. * equivalent to. When the percentile is 0.0, returns the value
  198. * that all value entries in the histogram are either larger than
  199. * or equivalent to.
  200. */
  201. i64 GetValueAtPercentile(double percentile) const;
  202. /**
  203. * Get the count of recorded values at a specific value (to within the
  204. * histogram resolution at the value level).
  205. *
  206. * @param value The value for which to provide the recorded count
  207. * @return The total count of values recorded in the histogram within the
  208. * value range that is >= GetLowestEquivalentValue(value) and
  209. * <= GetHighestEquivalentValue(value)
  210. */
  211. i64 GetCountAtValue(i64 value) const;
  212. /**
  213. * Determine if two values are equivalent with the histogram's resolution.
  214. * Where "equivalent" means that value samples recorded for any two
  215. * equivalent values are counted in a common total count.
  216. *
  217. * @param v1 first value to compare
  218. * @param v2 second value to compare
  219. * @return True if values are equivalent with the histogram's resolution.
  220. */
  221. bool ValuesAreEqual(i64 v1, i64 v2) const;
  222. /**
  223. * Get the lowest value that is equivalent to the given value within the
  224. * histogram's resolution. Where "equivalent" means that value samples
  225. * recorded for any two equivalent values are counted in a common total
  226. * count.
  227. *
  228. * @param value The given value
  229. * @return The lowest value that is equivalent to the given value within
  230. * the histogram's resolution.
  231. */
  232. i64 GetLowestEquivalentValue(i64 value) const;
  233. /**
  234. * Get the highest value that is equivalent to the given value within the
  235. * histogram's resolution. Where "equivalent" means that value samples
  236. * recorded for any two equivalent values are counted in a common total
  237. * count.
  238. *
  239. * @param value The given value
  240. * @return The highest value that is equivalent to the given value within
  241. * the histogram's resolution.
  242. */
  243. i64 GetHighestEquivalentValue(i64 value) const;
  244. /**
  245. * Get a value that lies in the middle (rounded up) of the range of values
  246. * equivalent the given value. Where "equivalent" means that value samples
  247. * recorded for any two equivalent values are counted in a common total
  248. * count.
  249. *
  250. * @param value The given value
  251. * @return The value lies in the middle (rounded up) of the range of values
  252. * equivalent the given value.
  253. */
  254. i64 GetMedianEquivalentValue(i64 value) const;
  255. // misc functions ---------------------------------------------------------
  256. /**
  257. * Reset a histogram to zero - empty out a histogram and re-initialise it.
  258. * If you want to re-use an existing histogram, but reset everything back
  259. * to zero, this is the routine to use.
  260. */
  261. void Reset();
  262. const hdr_histogram* GetHdrHistogramImpl() const {
  263. return Data_.Get();
  264. }
  265. private:
  266. THolder<hdr_histogram> Data_;
  267. IAllocator* Allocator_;
  268. };
  269. }