proxygen
folly::detail::HistogramBuckets< T, BucketT > Class Template Reference

#include <Histogram.h>

Public Types

typedef T ValueType
 
typedef BucketT BucketType
 

Public Member Functions

 HistogramBuckets (ValueType bucketSize, ValueType min, ValueType max, const BucketType &defaultBucket)
 
ValueType getBucketSize () const
 
ValueType getMin () const
 
ValueType getMax () const
 
size_t getNumBuckets () const
 
size_t getBucketIdx (ValueType value) const
 
BucketTypegetByValue (ValueType value)
 
const BucketTypegetByValue (ValueType value) const
 
BucketTypegetByIndex (size_t idx)
 
const BucketTypegetByIndex (size_t idx) const
 
ValueType getBucketMin (size_t idx) const
 
ValueType getBucketMax (size_t idx) const
 
template<typename CountFn >
uint64_t computeTotalCount (CountFn countFromBucket) const
 
template<typename CountFn >
size_t getPercentileBucketIdx (double pct, CountFn countFromBucket, double *lowPct=nullptr, double *highPct=nullptr) const
 
template<typename CountFn , typename AvgFn >
ValueType getPercentileEstimate (double pct, CountFn countFromBucket, AvgFn avgFromBucket) const
 
std::vector< BucketType >::const_iterator begin () const
 
std::vector< BucketType >::iterator begin ()
 
std::vector< BucketType >::const_iterator end () const
 
std::vector< BucketType >::iterator end ()
 
template<typename CountFn , typename AvgFn >
T getPercentileEstimate (double pct, CountFn countFromBucket, AvgFn avgFromBucket) const
 

Private Attributes

ValueType bucketSize_
 
ValueType min_
 
ValueType max_
 
std::vector< BucketTypebuckets_
 

Detailed Description

template<typename T, typename BucketT>
class folly::detail::HistogramBuckets< T, BucketT >

Definition at line 39 of file Histogram.h.

Member Typedef Documentation

template<typename T, typename BucketT>
typedef BucketT folly::detail::HistogramBuckets< T, BucketT >::BucketType

Definition at line 42 of file Histogram.h.

template<typename T, typename BucketT>
typedef T folly::detail::HistogramBuckets< T, BucketT >::ValueType

Definition at line 41 of file Histogram.h.

Constructor & Destructor Documentation

template<typename T , typename BucketT >
folly::detail::HistogramBuckets< T, BucketT >::HistogramBuckets ( ValueType  bucketSize,
ValueType  min,
ValueType  max,
const BucketType defaultBucket 
)

Definition at line 29 of file Histogram-defs.h.

References folly::detail::HistogramBuckets< T, BucketT >::buckets_, folly::detail::HistogramBuckets< T, BucketT >::bucketSize_, int64_t, folly::detail::HistogramBuckets< T, BucketT >::max_, and folly::detail::HistogramBuckets< T, BucketT >::min_.

34  : bucketSize_(bucketSize), min_(min), max_(max) {
35  CHECK_GT(bucketSize_, ValueType(0));
36  CHECK_LT(min_, max_);
37 
38  // Deliberately make this a signed type, because we're about
39  // to compare it against max-min, which is nominally signed, too.
40  int64_t numBuckets = int64_t((max - min) / bucketSize);
41  // Round up if the bucket size does not fit evenly
42  if (numBuckets * bucketSize < max - min) {
43  ++numBuckets;
44  }
45  // Add 2 for the extra 'below min' and 'above max' buckets
46  numBuckets += 2;
47  buckets_.assign(size_t(numBuckets), defaultBucket);
48 }
LogLevel max
Definition: LogLevel.cpp:31
LogLevel min
Definition: LogLevel.cpp:30
std::vector< BucketType > buckets_
Definition: Histogram.h:227

Member Function Documentation

template<typename T, typename BucketT>
std::vector<BucketType>::const_iterator folly::detail::HistogramBuckets< T, BucketT >::begin ( ) const
inline

Definition at line 210 of file Histogram.h.

210  {
211  return buckets_.begin();
212  }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T, typename BucketT>
std::vector<BucketType>::iterator folly::detail::HistogramBuckets< T, BucketT >::begin ( )
inline

Definition at line 213 of file Histogram.h.

213  {
214  return buckets_.begin();
215  }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T , typename BucketType >
template<typename CountFn >
template uint64_t folly::detail::HistogramBuckets< T, BucketT >::computeTotalCount< Histogram< int64_t >::CountFromBucket > ( CountFn  countFromBucket) const

Computes the total number of values stored across all buckets.

Runs in O(numBuckets)

Parameters
countFnA function that takes a const BucketType&, and returns the number of values in that bucket
Returns
Returns the total number of values stored across all buckets

Definition at line 64 of file Histogram-defs.h.

References folly::detail::HistogramBuckets< T, BucketT >::buckets_, count, and uint64_t.

Referenced by folly::detail::HistogramBuckets< ValueType, ContainerType >::getBucketMax().

65  {
66  uint64_t count = 0;
67  for (size_t n = 0; n < buckets_.size(); ++n) {
68  count += countFromBucket(const_cast<const BucketType&>(buckets_[n]));
69  }
70  return count;
71 }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
int * count
template<typename T, typename BucketT>
std::vector<BucketType>::const_iterator folly::detail::HistogramBuckets< T, BucketT >::end ( ) const
inline

Definition at line 216 of file Histogram.h.

216  {
217  return buckets_.end();
218  }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T, typename BucketT>
std::vector<BucketType>::iterator folly::detail::HistogramBuckets< T, BucketT >::end ( )
inline

Definition at line 219 of file Histogram.h.

219  {
220  return buckets_.end();
221  }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T , typename BucketType >
size_t folly::detail::HistogramBuckets< T, BucketType >::getBucketIdx ( ValueType  value) const

Definition at line 51 of file Histogram-defs.h.

References folly::detail::HistogramBuckets< T, BucketT >::buckets_, folly::detail::HistogramBuckets< T, BucketT >::bucketSize_, folly::detail::HistogramBuckets< T, BucketT >::max_, and folly::detail::HistogramBuckets< T, BucketT >::min_.

Referenced by folly::detail::HistogramBuckets< ValueType, ContainerType >::getByValue(), and folly::detail::HistogramBuckets< ValueType, ContainerType >::getNumBuckets().

51  {
52  if (value < min_) {
53  return 0;
54  } else if (value >= max_) {
55  return buckets_.size() - 1;
56  } else {
57  // the 1 is the below_min bucket
58  return size_t(((value - min_) / bucketSize_) + 1);
59  }
60 }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
template<typename T, typename BucketT>
ValueType folly::detail::HistogramBuckets< T, BucketT >::getBucketMax ( size_t  idx) const
inline

Definition at line 142 of file Histogram.h.

Referenced by folly::detail::HistogramBuckets< T, BucketT >::getPercentileEstimate(), and folly::Histogram< T >::toTSV().

142  {
143  if (idx == buckets_.size() - 1) {
145  }
146 
147  return ValueType(min_ + (idx * bucketSize_));
148  }
LogLevel max
Definition: LogLevel.cpp:31
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T, typename BucketT>
ValueType folly::detail::HistogramBuckets< T, BucketT >::getBucketMin ( size_t  idx) const
inline

Definition at line 124 of file Histogram.h.

Referenced by folly::TimeseriesHistogram< T, CT, C >::getBucketMin(), folly::detail::HistogramBuckets< T, BucketT >::getPercentileEstimate(), folly::TimeseriesHistogram< T, CT, C >::getString(), and folly::Histogram< T >::toTSV().

124  {
125  if (idx == 0) {
127  }
128  if (idx == buckets_.size() - 1) {
129  return max_;
130  }
131 
132  return ValueType(min_ + ((idx - 1) * bucketSize_));
133  }
LogLevel min
Definition: LogLevel.cpp:30
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T, typename BucketT>
ValueType folly::detail::HistogramBuckets< T, BucketT >::getBucketSize ( ) const
inline
template<typename T, typename BucketT>
const BucketType& folly::detail::HistogramBuckets< T, BucketT >::getByIndex ( size_t  idx) const
inline

Definition at line 113 of file Histogram.h.

113  {
114  return buckets_[idx];
115  }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T, typename BucketT>
BucketType& folly::detail::HistogramBuckets< T, BucketT >::getByValue ( ValueType  value)
inline

Definition at line 93 of file Histogram.h.

Referenced by folly::TimeseriesHistogram< T, CT, C >::addValue().

93  {
94  return buckets_[getBucketIdx(value)];
95  }
size_t getBucketIdx(ValueType value) const
std::vector< BucketType > buckets_
Definition: Histogram.h:227
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
template<typename T, typename BucketT>
const BucketType& folly::detail::HistogramBuckets< T, BucketT >::getByValue ( ValueType  value) const
inline

Definition at line 98 of file Histogram.h.

98  {
99  return buckets_[getBucketIdx(value)];
100  }
size_t getBucketIdx(ValueType value) const
std::vector< BucketType > buckets_
Definition: Histogram.h:227
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
template<typename T, typename BucketT>
ValueType folly::detail::HistogramBuckets< T, BucketT >::getMax ( ) const
inline
template<typename T, typename BucketT>
ValueType folly::detail::HistogramBuckets< T, BucketT >::getMin ( ) const
inline
template<typename T , typename BucketType >
template<typename CountFn >
template size_t folly::detail::HistogramBuckets< T, BucketT >::getPercentileBucketIdx< Histogram< int64_t >::CountFromBucket > ( double  pct,
CountFn  countFromBucket,
double *  lowPct = nullptr,
double *  highPct = nullptr 
) const

Determine which bucket the specified percentile falls into.

Looks for the bucket that contains the Nth percentile data point.

Parameters
pctThe desired percentile to find, as a value from 0.0 to 1.0.
countFnA function that takes a const BucketType&, and returns the number of values in that bucket.
lowPctThe lowest percentile stored in the selected bucket will be returned via this parameter.
highPctThe highest percentile stored in the selected bucket will be returned via this parameter.
Returns
Returns the index of the bucket that contains the Nth percentile data point.

Definition at line 75 of file Histogram-defs.h.

References folly::detail::HistogramBuckets< T, BucketT >::buckets_, and uint64_t.

Referenced by folly::detail::HistogramBuckets< ValueType, ContainerType >::getBucketMax(), folly::TimeseriesHistogram< T, CT, C >::getPercentileBucketIdx(), and folly::detail::HistogramBuckets< T, BucketT >::getPercentileEstimate().

79  {
80  CHECK_GE(pct, 0.0);
81  CHECK_LE(pct, 1.0);
82 
83  auto numBuckets = buckets_.size();
84 
85  // Compute the counts in each bucket
86  std::vector<uint64_t> counts(numBuckets);
87  uint64_t totalCount = 0;
88  for (size_t n = 0; n < numBuckets; ++n) {
89  uint64_t bucketCount =
90  countFromBucket(const_cast<const BucketType&>(buckets_[n]));
91  counts[n] = bucketCount;
92  totalCount += bucketCount;
93  }
94 
95  // If there are no elements, just return the lowest bucket.
96  // Note that we return bucket 1, which is the first bucket in the
97  // histogram range; bucket 0 is for all values below min_.
98  if (totalCount == 0) {
99  // Set lowPct and highPct both to 0.
100  // getPercentileEstimate() will recognize this to mean that the histogram
101  // is empty.
102  if (lowPct) {
103  *lowPct = 0.0;
104  }
105  if (highPct) {
106  *highPct = 0.0;
107  }
108  return 1;
109  }
110 
111  // Loop through all the buckets, keeping track of each bucket's
112  // percentile range: [0,10], [10,17], [17,45], etc. When we find a range
113  // that includes our desired percentile, we return that bucket index.
114  double prevPct = 0.0;
115  double curPct = 0.0;
116  uint64_t curCount = 0;
117  size_t idx;
118  for (idx = 0; idx < numBuckets; ++idx) {
119  if (counts[idx] == 0) {
120  // skip empty buckets
121  continue;
122  }
123 
124  prevPct = curPct;
125  curCount += counts[idx];
126  curPct = static_cast<double>(curCount) / totalCount;
127  if (pct <= curPct) {
128  // This is the desired bucket
129  break;
130  }
131  }
132 
133  if (lowPct) {
134  *lowPct = prevPct;
135  }
136  if (highPct) {
137  *highPct = curPct;
138  }
139  return idx;
140 }
std::vector< BucketType > buckets_
Definition: Histogram.h:227
template<typename T, typename BucketT>
template<typename CountFn , typename AvgFn >
T folly::detail::HistogramBuckets< T, BucketT >::getPercentileEstimate ( double  pct,
CountFn  countFromBucket,
AvgFn  avgFromBucket 
) const

Definition at line 144 of file Histogram-defs.h.

References folly::detail::HistogramBuckets< T, BucketT >::buckets_, folly::detail::HistogramBuckets< T, BucketT >::getBucketMax(), folly::detail::HistogramBuckets< T, BucketT >::getBucketMin(), folly::detail::HistogramBuckets< T, BucketT >::getPercentileBucketIdx(), max, folly::detail::HistogramBuckets< T, BucketT >::max_, min, folly::detail::HistogramBuckets< T, BucketT >::min_, and folly::T.

147  {
148  // Find the bucket where this percentile falls
149  double lowPct;
150  double highPct;
151  size_t bucketIdx =
152  getPercentileBucketIdx(pct, countFromBucket, &lowPct, &highPct);
153  if (lowPct == 0.0 && highPct == 0.0) {
154  // Invalid range -- the buckets must all be empty
155  // Return the default value for ValueType.
156  return ValueType();
157  }
158  if (lowPct == highPct) {
159  // Unlikely to have exact equality,
160  // but just return the bucket average in this case.
161  // We handle this here to avoid division by 0 below.
162  return avgFromBucket(buckets_[bucketIdx]);
163  }
164 
165  CHECK_GE(pct, lowPct);
166  CHECK_LE(pct, highPct);
167  CHECK_LT(lowPct, highPct);
168 
169  // Compute information about this bucket
170  ValueType avg = avgFromBucket(buckets_[bucketIdx]);
171  ValueType low;
172  ValueType high;
173  if (bucketIdx == 0) {
174  if (avg > min_) {
175  // This normally shouldn't happen. This bucket is only supposed to track
176  // values less than min_. Most likely this means that integer overflow
177  // occurred, and the code in avgFromBucket() returned a huge value
178  // instead of a small one. Just return the minimum possible value for
179  // now.
180  //
181  // (Note that if the counter keeps being decremented, eventually it will
182  // wrap and become small enough that we won't detect this any more, and
183  // we will return bogus information.)
184  LOG(ERROR) << "invalid average value in histogram minimum bucket: " << avg
185  << " > " << min_ << ": possible integer overflow?";
186  return getBucketMin(bucketIdx);
187  }
188  // For the below-min bucket, just assume the lowest value ever seen is
189  // twice as far away from min_ as avg.
190  high = min_;
191  low = high - (2 * (high - avg));
192  // Adjust low in case it wrapped
193  if (low > avg) {
195  }
196  } else if (bucketIdx == buckets_.size() - 1) {
197  if (avg < max_) {
198  // Most likely this means integer overflow occurred. See the comments
199  // above in the minimum case.
200  LOG(ERROR) << "invalid average value in histogram maximum bucket: " << avg
201  << " < " << max_ << ": possible integer overflow?";
202  return getBucketMax(bucketIdx);
203  }
204  // Similarly for the above-max bucket, assume the highest value ever seen
205  // is twice as far away from max_ as avg.
206  low = max_;
207  high = low + (2 * (avg - low));
208  // Adjust high in case it wrapped
209  if (high < avg) {
211  }
212  } else {
213  low = getBucketMin(bucketIdx);
214  high = getBucketMax(bucketIdx);
215  if (avg < low || avg > high) {
216  // Most likely this means an integer overflow occurred.
217  // See the comments above. Return the midpoint between low and high
218  // as a best guess, since avg is meaningless.
219  LOG(ERROR) << "invalid average value in histogram bucket: " << avg
220  << " not in range [" << low << ", " << high
221  << "]: possible integer overflow?";
222  return (low + high) / 2;
223  }
224  }
225 
226  // Since we know the average value in this bucket, we can do slightly better
227  // than just assuming the data points in this bucket are uniformly
228  // distributed between low and high.
229  //
230  // Assume that the median value in this bucket is the same as the average
231  // value.
232  double medianPct = (lowPct + highPct) / 2.0;
233  if (pct < medianPct) {
234  // Assume that the data points lower than the median of this bucket
235  // are uniformly distributed between low and avg
236  double pctThroughSection = (pct - lowPct) / (medianPct - lowPct);
237  return T(low + ((avg - low) * pctThroughSection));
238  } else {
239  // Assume that the data points greater than the median of this bucket
240  // are uniformly distributed between avg and high
241  double pctThroughSection = (pct - medianPct) / (highPct - medianPct);
242  return T(avg + ((high - avg) * pctThroughSection));
243  }
244 }
ValueType getBucketMax(size_t idx) const
Definition: Histogram.h:142
LogLevel max
Definition: LogLevel.cpp:31
folly::std T
LogLevel min
Definition: LogLevel.cpp:30
ValueType getBucketMin(size_t idx) const
Definition: Histogram.h:124
std::vector< BucketType > buckets_
Definition: Histogram.h:227
size_t getPercentileBucketIdx(double pct, CountFn countFromBucket, double *lowPct=nullptr, double *highPct=nullptr) const
template<typename T, typename BucketT>
template<typename CountFn , typename AvgFn >
ValueType folly::detail::HistogramBuckets< T, BucketT >::getPercentileEstimate ( double  pct,
CountFn  countFromBucket,
AvgFn  avgFromBucket 
) const

Estimate the value at the specified percentile.

Parameters
pctThe desired percentile to find, as a value from 0.0 to 1.0.
countFnA function that takes a const BucketType&, and returns the number of values in that bucket.
avgFnA function that takes a const BucketType&, and returns the average of all the values in that bucket.
Returns
Returns an estimate for N, where N is the number where exactly pct percentage of the data points in the histogram are less than N.

Referenced by folly::detail::HistogramBuckets< ValueType, ContainerType >::getBucketMax(), and folly::TimeseriesHistogram< T, CT, C >::getPercentileEstimate().

Member Data Documentation

template<typename T, typename BucketT>
std::vector<BucketType> folly::detail::HistogramBuckets< T, BucketT >::buckets_
private

Definition at line 227 of file Histogram.h.

Referenced by folly::Histogram< T >::addRepeatedValue(), folly::Histogram< T >::addValue(), folly::detail::HistogramBuckets< ValueType, ContainerType >::begin(), folly::Histogram< T >::clear(), folly::detail::HistogramBuckets< T, BucketT >::computeTotalCount(), folly::Histogram< T >::computeTotalCount(), folly::Histogram< T >::copy(), folly::Histogram< T >::debugString(), folly::detail::HistogramBuckets< ValueType, ContainerType >::end(), folly::Histogram< T >::getBucketByIndex(), folly::detail::HistogramBuckets< T, BucketT >::getBucketIdx(), folly::detail::HistogramBuckets< ValueType, ContainerType >::getBucketMax(), folly::Histogram< T >::getBucketMax(), folly::detail::HistogramBuckets< ValueType, ContainerType >::getBucketMin(), folly::Histogram< T >::getBucketMin(), folly::Histogram< T >::getBucketSize(), folly::detail::HistogramBuckets< ValueType, ContainerType >::getByIndex(), folly::detail::HistogramBuckets< ValueType, ContainerType >::getByValue(), folly::Histogram< T >::getMax(), folly::Histogram< T >::getMin(), folly::detail::HistogramBuckets< ValueType, ContainerType >::getNumBuckets(), folly::Histogram< T >::getNumBuckets(), folly::detail::HistogramBuckets< T, BucketT >::getPercentileBucketIdx(), folly::Histogram< T >::getPercentileBucketIdx(), folly::detail::HistogramBuckets< T, BucketT >::getPercentileEstimate(), folly::Histogram< T >::getPercentileEstimate(), folly::detail::HistogramBuckets< T, BucketT >::HistogramBuckets(), folly::Histogram< T >::merge(), folly::Histogram< T >::removeRepeatedValue(), folly::Histogram< T >::removeValue(), folly::Histogram< T >::subtract(), and folly::Histogram< T >::toTSV().


The documentation for this class was generated from the following files: