proxygen
folly::BucketedTimeSeries< VT, CT > Class Template Reference

#include <BucketedTimeSeries.h>

Public Types

using ValueType = VT
 
using Clock = CT
 
using Duration = typename Clock::duration
 
using TimePoint = typename Clock::time_point
 
using Bucket = detail::Bucket< ValueType >
 

Public Member Functions

 BucketedTimeSeries (size_t numBuckets, Duration duration)
 
 BucketedTimeSeries (TimePoint theFirstTime, TimePoint theLatestTime, Duration maxDuration, const std::vector< Bucket > &bucketsList)
 
bool addValue (TimePoint now, const ValueType &val)
 
bool addValue (TimePoint now, const ValueType &val, uint64_t times)
 
bool addValueAggregated (TimePoint now, const ValueType &total, uint64_t nsamples)
 
size_t update (TimePoint now)
 
void clear ()
 
TimePoint getLatestTime () const
 
TimePoint getEarliestTime () const
 
size_t numBuckets () const
 
Duration duration () const
 
bool isAllTime () const
 
bool empty () const
 
TimePoint firstTime () const
 
TimePoint latestTime () const
 
const std::vector< Bucket > & buckets () const
 
Duration elapsed () const
 
Duration elapsed (TimePoint start, TimePoint end) const
 
const ValueTypesum () const
 
uint64_t count () const
 
template<typename ReturnType = double>
ReturnType avg () const
 
template<typename ReturnType = double, typename Interval = Duration>
ReturnType rate () const
 
template<typename ReturnType = double, typename Interval = Duration>
ReturnType countRate () const
 
ValueType sum (TimePoint start, TimePoint end) const
 
uint64_t count (TimePoint start, TimePoint end) const
 
template<typename ReturnType = double>
ReturnType avg (TimePoint start, TimePoint end) const
 
template<typename ReturnType = double, typename Interval = Duration>
ReturnType rate (TimePoint start, TimePoint end) const
 
template<typename ReturnType = double, typename Interval = Duration>
ReturnType countRate (TimePoint start, TimePoint end) const
 
template<typename Function >
void forEachBucket (Function fn) const
 
size_t getBucketIdx (TimePoint time) const
 
const BucketgetBucketByIndex (size_t idx) const
 
void getBucketInfo (TimePoint time, size_t *bucketIdx, TimePoint *bucketStart, TimePoint *nextBucketStart) const
 
bool addValue (Duration now, const ValueType &val)
 
bool addValue (Duration now, const ValueType &val, uint64_t times)
 
bool addValueAggregated (Duration now, const ValueType &total, uint64_t nsamples)
 
size_t update (Duration now)
 

Private Member Functions

template<typename ReturnType = double, typename Interval = Duration>
ReturnType rateHelper (ReturnType numerator, Duration elapsedTime) const
 
TimePoint getEarliestTimeNonEmpty () const
 
size_t updateBuckets (TimePoint now)
 
ValueType rangeAdjust (TimePoint bucketStart, TimePoint nextBucketStart, TimePoint start, TimePoint end, ValueType input) const
 
template<typename Function >
void forEachBucket (TimePoint start, TimePoint end, Function fn) const
 

Private Attributes

TimePoint firstTime_
 
TimePoint latestTime_
 
Duration duration_
 
Bucket total_
 
std::vector< Bucketbuckets_
 

Detailed Description

template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
class folly::BucketedTimeSeries< VT, CT >

Definition at line 64 of file BucketedTimeSeries.h.

Member Typedef Documentation

template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
using folly::BucketedTimeSeries< VT, CT >::Bucket = detail::Bucket<ValueType>

Definition at line 70 of file BucketedTimeSeries.h.

template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
using folly::BucketedTimeSeries< VT, CT >::Clock = CT

Definition at line 67 of file BucketedTimeSeries.h.

template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
using folly::BucketedTimeSeries< VT, CT >::Duration = typename Clock::duration

Definition at line 68 of file BucketedTimeSeries.h.

template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
using folly::BucketedTimeSeries< VT, CT >::TimePoint = typename Clock::time_point

Definition at line 69 of file BucketedTimeSeries.h.

template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
using folly::BucketedTimeSeries< VT, CT >::ValueType = VT

Definition at line 66 of file BucketedTimeSeries.h.

Constructor & Destructor Documentation

template<typename VT , typename CT >
folly::BucketedTimeSeries< VT, CT >::BucketedTimeSeries ( size_t  numBuckets,
Duration  duration 
)

Definition at line 28 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::buckets_, folly::BucketedTimeSeries< VT, CT >::duration_, and folly::BucketedTimeSeries< VT, CT >::isAllTime().

31  : firstTime_(Duration(1)), latestTime_(), duration_(maxDuration) {
32  // For tracking all-time data we only use total_, and don't need to bother
33  // with buckets_
34  if (!isAllTime()) {
35  // Round nBuckets down to duration_.count().
36  //
37  // There is no point in having more buckets than our timestamp
38  // granularity: otherwise we would have buckets that could never be used.
39  if (nBuckets > size_t(duration_.count())) {
40  nBuckets = size_t(duration_.count());
41  }
42 
43  buckets_.resize(nBuckets, Bucket());
44  }
45 }
std::vector< Bucket > buckets_
detail::Bucket< ValueType > Bucket
typename Clock::duration Duration
template<typename VT , typename CT >
folly::BucketedTimeSeries< VT, CT >::BucketedTimeSeries ( TimePoint  theFirstTime,
TimePoint  theLatestTime,
Duration  maxDuration,
const std::vector< Bucket > &  bucketsList 
)

Definition at line 48 of file BucketedTimeSeries-defs.h.

References folly::detail::Bucket< T >::add(), folly::BucketedTimeSeries< VT, CT >::buckets_, folly::detail::Bucket< T >::count, folly::BucketedTimeSeries< VT, CT >::duration_, folly::BucketedTimeSeries< VT, CT >::firstTime_, folly::BucketedTimeSeries< VT, CT >::latestTime_, folly::detail::Bucket< T >::sum, and folly::BucketedTimeSeries< VT, CT >::total_.

53  : firstTime_(theFirstTime),
54  latestTime_(theLatestTime),
55  duration_(maxDuration),
56  buckets_(bucketsList) {
57  // Come up with the total_ from buckets_ being passed in
58  for (auto const& bucket : buckets_) {
59  total_.add(bucket.sum, bucket.count);
60  }
61 
62  // Verify the integrity of the data
63 
64  // If firstTime is greater than latestTime, the total count should be 0.
65  // (firstTime being greater than latestTime means that no data points have
66  // ever been added to the time series.)
67  if (firstTime_ > latestTime_ && (total_.sum != 0 || total_.count != 0)) {
68  throw std::invalid_argument(
69  "The total should have been 0 "
70  "if firstTime is greater than lastestTime");
71  }
72 
73  // If firstTime is less than or equal to latestTime,
74  // latestTime - firstTime should be less than or equal to the duration.
75  if (firstTime_ <= latestTime_ && latestTime_ - firstTime_ > duration_) {
76  throw std::invalid_argument(
77  "The difference between firstTime and latestTime "
78  "should be less than or equal to the duration");
79  }
80 }
std::vector< Bucket > buckets_
void add(const ValueType &s, uint64_t c)
Definition: Bucket.h:102

Member Function Documentation

template<typename VT , typename CT >
bool folly::BucketedTimeSeries< VT, CT >::addValue ( TimePoint  now,
const ValueType val 
)

Definition at line 83 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::addValueAggregated().

Referenced by addValue(), TEST(), and testUpdate100x10().

83  {
84  return addValueAggregated(now, val, 1);
85 }
std::chrono::steady_clock::time_point now()
double val
Definition: String.cpp:273
bool addValueAggregated(TimePoint now, const ValueType &total, uint64_t nsamples)
template<typename VT , typename CT >
bool folly::BucketedTimeSeries< VT, CT >::addValue ( TimePoint  now,
const ValueType val,
uint64_t  times 
)

Definition at line 88 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::addValueAggregated().

91  {
93 }
std::chrono::steady_clock::time_point now()
double val
Definition: String.cpp:273
bool addValueAggregated(TimePoint now, const ValueType &total, uint64_t nsamples)
Future< Unit > times(const int n, F &&thunk)
Definition: Future-inl.h:2348
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
bool folly::BucketedTimeSeries< VT, CT >::addValue ( Duration  now,
const ValueType val 
)
inline

Definition at line 448 of file BucketedTimeSeries.h.

448  {
449  return addValueAggregated(TimePoint(now), val, 1);
450  }
std::chrono::steady_clock::time_point now()
double val
Definition: String.cpp:273
bool addValueAggregated(TimePoint now, const ValueType &total, uint64_t nsamples)
typename Clock::time_point TimePoint
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
bool folly::BucketedTimeSeries< VT, CT >::addValue ( Duration  now,
const ValueType val,
uint64_t  times 
)
inline

Definition at line 451 of file BucketedTimeSeries.h.

451  {
453  }
std::chrono::steady_clock::time_point now()
double val
Definition: String.cpp:273
bool addValueAggregated(TimePoint now, const ValueType &total, uint64_t nsamples)
Future< Unit > times(const int n, F &&thunk)
Definition: Future-inl.h:2348
typename Clock::time_point TimePoint
template<typename VT , typename CT >
bool folly::BucketedTimeSeries< VT, CT >::addValueAggregated ( TimePoint  now,
const ValueType total,
uint64_t  nsamples 
)

Definition at line 96 of file BucketedTimeSeries-defs.h.

References folly::detail::Bucket< T >::add(), folly::BucketedTimeSeries< VT, CT >::buckets_, folly::BucketedTimeSeries< VT, CT >::empty(), folly::BucketedTimeSeries< VT, CT >::firstTime_, folly::BucketedTimeSeries< VT, CT >::getBucketIdx(), folly::BucketedTimeSeries< VT, CT >::getEarliestTimeNonEmpty(), folly::BucketedTimeSeries< VT, CT >::isAllTime(), folly::BucketedTimeSeries< VT, CT >::latestTime_, LIKELY, now(), folly::BucketedTimeSeries< VT, CT >::total_, UNLIKELY, and folly::BucketedTimeSeries< VT, CT >::updateBuckets().

Referenced by folly::BucketedTimeSeries< VT, CT >::addValue(), and TEST().

99  {
100  if (isAllTime()) {
101  if (UNLIKELY(empty())) {
102  firstTime_ = now;
103  latestTime_ = now;
104  } else if (now > latestTime_) {
105  latestTime_ = now;
106  } else if (now < firstTime_) {
107  firstTime_ = now;
108  }
109  total_.add(total, nsamples);
110  return true;
111  }
112 
113  size_t bucketIdx;
114  if (UNLIKELY(empty())) {
115  // First data point we've ever seen
116  firstTime_ = now;
117  latestTime_ = now;
118  bucketIdx = getBucketIdx(now);
119  } else if (now > latestTime_) {
120  // More recent time. Need to update the buckets.
121  bucketIdx = updateBuckets(now);
122  } else if (LIKELY(now == latestTime_)) {
123  // Current time.
124  bucketIdx = getBucketIdx(now);
125  } else {
126  // An earlier time in the past. We need to check if this time still falls
127  // within our window.
128  if (now < getEarliestTimeNonEmpty()) {
129  return false;
130  }
131  bucketIdx = getBucketIdx(now);
132  }
133 
134  total_.add(total, nsamples);
135  buckets_[bucketIdx].add(total, nsamples);
136  return true;
137 }
std::chrono::steady_clock::time_point now()
#define LIKELY(x)
Definition: Likely.h:47
size_t updateBuckets(TimePoint now)
TimePoint getEarliestTimeNonEmpty() const
std::vector< Bucket > buckets_
void add(const ValueType &s, uint64_t c)
Definition: Bucket.h:102
size_t getBucketIdx(TimePoint time) const
#define UNLIKELY(x)
Definition: Likely.h:48
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
bool folly::BucketedTimeSeries< VT, CT >::addValueAggregated ( Duration  now,
const ValueType total,
uint64_t  nsamples 
)
inline

Definition at line 455 of file BucketedTimeSeries.h.

455  {
456  return addValueAggregated(TimePoint(now), total, nsamples);
457  }
std::chrono::steady_clock::time_point now()
bool addValueAggregated(TimePoint now, const ValueType &total, uint64_t nsamples)
typename Clock::time_point TimePoint
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
template<typename ReturnType = double>
ReturnType folly::BucketedTimeSeries< VT, CT >::avg ( ) const
inline

Definition at line 297 of file BucketedTimeSeries.h.

Referenced by TEST(), and testUpdate100x10().

297  {
298  return total_.template avg<ReturnType>();
299  }
template<typename VT , typename CT >
template<typename ReturnType >
ReturnType folly::BucketedTimeSeries< VT, CT >::avg ( TimePoint  start,
TimePoint  end 
) const

Definition at line 317 of file BucketedTimeSeries-defs.h.

References folly::detail::Bucket< T >::count, folly::BucketedTimeSeries< VT, CT >::forEachBucket(), folly::BucketedTimeSeries< VT, CT >::rangeAdjust(), folly::detail::Bucket< T >::sum, and uint64_t.

318  {
319  ValueType total = ValueType();
320  uint64_t sample_count = 0;
322  start,
323  end,
324  [&](const Bucket& bucket,
325  TimePoint bucketStart,
326  TimePoint nextBucketStart) -> bool {
327  total += this->rangeAdjust(
328  bucketStart, nextBucketStart, start, end, bucket.sum);
329  sample_count += this->rangeAdjust(
330  bucketStart, nextBucketStart, start, end, ValueType(bucket.count));
331  return true;
332  });
333 
334  if (sample_count == 0) {
335  return ReturnType(0);
336  }
337 
338  return detail::avgHelper<ReturnType>(total, sample_count);
339 }
ValueType rangeAdjust(TimePoint bucketStart, TimePoint nextBucketStart, TimePoint start, TimePoint end, ValueType input) const
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
StatsClock::time_point TimePoint
void forEachBucket(Function fn) const
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
const std::vector<Bucket>& folly::BucketedTimeSeries< VT, CT >::buckets ( ) const
inline

Definition at line 226 of file BucketedTimeSeries.h.

References folly::test::end(), and start.

Referenced by TEST().

226  {
227  return buckets_;
228  }
std::vector< Bucket > buckets_
template<typename VT , typename CT >
void folly::BucketedTimeSeries< VT, CT >::clear ( )

Definition at line 214 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::buckets_, folly::detail::Bucket< T >::clear(), folly::BucketedTimeSeries< VT, CT >::firstTime_, folly::BucketedTimeSeries< VT, CT >::latestTime_, and folly::BucketedTimeSeries< VT, CT >::total_.

Referenced by TEST(), and testUpdate100x10().

214  {
215  for (Bucket& bucket : buckets_) {
216  bucket.clear();
217  }
218  total_.clear();
219  // Set firstTime_ larger than latestTime_,
220  // to indicate that the timeseries is empty
223 }
std::vector< Bucket > buckets_
typename Clock::time_point TimePoint
typename Clock::duration Duration
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
uint64_t folly::BucketedTimeSeries< VT, CT >::count ( ) const
inline
template<typename VT , typename CT >
uint64_t folly::BucketedTimeSeries< VT, CT >::count ( TimePoint  start,
TimePoint  end 
) const

Definition at line 298 of file BucketedTimeSeries-defs.h.

References folly::detail::Bucket< T >::count, folly::BucketedTimeSeries< VT, CT >::forEachBucket(), folly::BucketedTimeSeries< VT, CT >::rangeAdjust(), and uint64_t.

299  {
300  uint64_t sample_count = 0;
302  start,
303  end,
304  [&](const Bucket& bucket,
305  TimePoint bucketStart,
306  TimePoint nextBucketStart) -> bool {
307  sample_count += this->rangeAdjust(
308  bucketStart, nextBucketStart, start, end, ValueType(bucket.count));
309  return true;
310  });
311 
312  return sample_count;
313 }
ValueType rangeAdjust(TimePoint bucketStart, TimePoint nextBucketStart, TimePoint start, TimePoint end, ValueType input) const
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
StatsClock::time_point TimePoint
void forEachBucket(Function fn) const
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
template<typename ReturnType = double, typename Interval = Duration>
ReturnType folly::BucketedTimeSeries< VT, CT >::countRate ( ) const
inline

Definition at line 325 of file BucketedTimeSeries.h.

References count, sum(), and uint64_t.

Referenced by TEST().

325  {
326  return rateHelper<ReturnType, Interval>(
327  ReturnType(total_.count), elapsed());
328  }
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
template<typename ReturnType = double, typename Interval = Duration>
ReturnType folly::BucketedTimeSeries< VT, CT >::countRate ( TimePoint  start,
TimePoint  end 
) const
inline

Definition at line 385 of file BucketedTimeSeries.h.

References count, folly::detail::distributed_mutex::time(), and uint64_t.

385  {
386  uint64_t intervalCount = count(start, end);
387  Duration interval = elapsed(start, end);
388  return rateHelper<ReturnType, Interval>(
389  ReturnType(intervalCount), interval);
390  }
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
StatsClock::duration Duration
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
Duration folly::BucketedTimeSeries< VT, CT >::duration ( ) const
inline

Definition at line 182 of file BucketedTimeSeries.h.

Referenced by TEST().

182  {
183  return duration_;
184  }
template<typename VT , typename CT >
CT::duration folly::BucketedTimeSeries< VT, CT >::elapsed ( ) const

Definition at line 258 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::empty(), folly::BucketedTimeSeries< VT, CT >::getEarliestTime(), and folly::BucketedTimeSeries< VT, CT >::latestTime_.

Referenced by TEST().

258  {
259  if (empty()) {
260  return Duration(0);
261  }
262 
263  // Add 1 since [latestTime_, earliestTime] is an inclusive interval.
264  return latestTime_ - getEarliestTime() + Duration(1);
265 }
typename Clock::duration Duration
template<typename VT , typename CT >
CT::duration folly::BucketedTimeSeries< VT, CT >::elapsed ( TimePoint  start,
TimePoint  end 
) const

Definition at line 268 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::empty(), folly::BucketedTimeSeries< VT, CT >::getEarliestTime(), folly::BucketedTimeSeries< VT, CT >::latestTime_, max, min, and start.

270  {
271  if (empty()) {
272  return Duration(0);
273  }
276  end = std::max(start, end);
277  return end - start;
278 }
LogLevel max
Definition: LogLevel.cpp:31
LogLevel min
Definition: LogLevel.cpp:30
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
typename Clock::duration Duration
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
bool folly::BucketedTimeSeries< VT, CT >::empty ( ) const
inline

Definition at line 198 of file BucketedTimeSeries.h.

Referenced by folly::BucketedTimeSeries< VT, CT >::addValueAggregated(), folly::BucketedTimeSeries< VT, CT >::elapsed(), folly::BucketedTimeSeries< VT, CT >::getEarliestTime(), and folly::BucketedTimeSeries< VT, CT >::update().

198  {
199  // We set firstTime_ greater than latestTime_ in the constructor and in
200  // clear, so we use this to distinguish if the timeseries is empty.
201  //
202  // Once a data point has been added, latestTime_ will always be greater
203  // than or equal to firstTime_.
204  return firstTime_ > latestTime_;
205  }
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
TimePoint folly::BucketedTimeSeries< VT, CT >::firstTime ( ) const
inline

Definition at line 211 of file BucketedTimeSeries.h.

Referenced by TEST().

211  {
212  return firstTime_;
213  }
template<typename VT , typename CT >
template<typename Function >
void folly::BucketedTimeSeries< VT, CT >::forEachBucket ( Function  fn) const

Definition at line 407 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::buckets_, folly::BucketedTimeSeries< VT, CT >::duration_, folly::BucketedTimeSeries< VT, CT >::firstTime_, folly::BucketedTimeSeries< VT, CT >::isAllTime(), folly::BucketedTimeSeries< VT, CT >::latestTime_, and folly::BucketedTimeSeries< VT, CT >::total_.

Referenced by folly::BucketedTimeSeries< VT, CT >::avg(), folly::BucketedTimeSeries< VT, CT >::count(), folly::BucketedTimeSeries< VT, CT >::forEachBucket(), folly::BucketedTimeSeries< VT, CT >::sum(), and TEST().

407  {
408  if (isAllTime()) {
410  return;
411  }
412 
413  typedef typename Duration::rep TimeInt;
414 
415  // Compute durationStart, latestBucketIdx, and scaledNextBucketStart,
416  // the same way as in getBucketInfo().
417  Duration timeMod = latestTime_.time_since_epoch() % duration_;
418  TimeInt numFullDurations = latestTime_.time_since_epoch() / duration_;
419  TimePoint durationStart(numFullDurations * duration_);
420  TimeInt scaledTime = timeMod.count() * TimeInt(buckets_.size());
421  size_t latestBucketIdx = size_t(scaledTime / duration_.count());
422  TimeInt scaledOffsetInBucket = scaledTime % duration_.count();
423  TimeInt scaledBucketStart = scaledTime - scaledOffsetInBucket;
424  TimeInt scaledNextBucketStart = scaledBucketStart + duration_.count();
425 
426  // Walk through the buckets, starting one past the current bucket.
427  // The next bucket is from the previous cycle, so subtract 1 duration
428  // from durationStart.
429  size_t idx = latestBucketIdx;
430  durationStart -= duration_;
431 
432  TimePoint nextBucketStart =
433  Duration(
434  (scaledNextBucketStart + buckets_.size() - 1) / buckets_.size()) +
435  durationStart;
436  while (true) {
437  ++idx;
438  if (idx >= buckets_.size()) {
439  idx = 0;
440  durationStart += duration_;
441  scaledNextBucketStart = duration_.count();
442  } else {
443  scaledNextBucketStart += duration_.count();
444  }
445 
446  TimePoint bucketStart = nextBucketStart;
447  nextBucketStart =
448  Duration(
449  (scaledNextBucketStart + buckets_.size() - 1) / buckets_.size()) +
450  durationStart;
451 
452  // Should we bother skipping buckets where firstTime_ >= nextBucketStart?
453  // For now we go ahead and invoke the function with these buckets.
454  // sum and count should always be 0 in these buckets.
455 
456  DCHECK_LE(
457  bucketStart.time_since_epoch().count(),
458  latestTime_.time_since_epoch().count());
459  bool ret = fn(buckets_[idx], bucketStart, nextBucketStart);
460  if (!ret) {
461  break;
462  }
463 
464  if (idx == latestBucketIdx) {
465  // all done
466  break;
467  }
468  }
469 }
std::vector< Bucket > buckets_
StatsClock::duration Duration
StatsClock::time_point TimePoint
typename Clock::duration Duration
template<typename VT , typename CT >
template<typename Function >
void folly::BucketedTimeSeries< VT, CT >::forEachBucket ( TimePoint  start,
TimePoint  end,
Function  fn 
) const
private

Definition at line 508 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::forEachBucket().

511  {
513  [&start, &end, &fn](
514  const Bucket& bucket,
515  TimePoint bucketStart,
516  TimePoint nextBucketStart) -> bool {
517  if (start >= nextBucketStart) {
518  return true;
519  }
520  if (end <= bucketStart) {
521  return false;
522  }
523  bool ret = fn(bucket, bucketStart, nextBucketStart);
524  return ret;
525  });
526 }
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
StatsClock::time_point TimePoint
void forEachBucket(Function fn) const
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
const Bucket& folly::BucketedTimeSeries< VT, CT >::getBucketByIndex ( size_t  idx) const
inline

Definition at line 425 of file BucketedTimeSeries.h.

Referenced by TEST().

425  {
426  return buckets_[idx];
427  }
std::vector< Bucket > buckets_
template<typename VT , typename CT >
size_t folly::BucketedTimeSeries< VT, CT >::getBucketIdx ( TimePoint  time) const

Definition at line 359 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::buckets_, folly::BucketedTimeSeries< VT, CT >::duration_, and folly::BucketedTimeSeries< VT, CT >::isAllTime().

Referenced by folly::BucketedTimeSeries< VT, CT >::addValueAggregated(), TEST(), folly::BucketedTimeSeries< VT, CT >::update(), and folly::BucketedTimeSeries< VT, CT >::updateBuckets().

359  {
360  // For all-time data we don't use buckets_. Everything is tracked in total_.
361  DCHECK(!isAllTime());
362 
363  auto timeIntoCurrentCycle = (time.time_since_epoch() % duration_);
364  return timeIntoCurrentCycle.count() * buckets_.size() / duration_.count();
365 }
std::vector< Bucket > buckets_
std::chrono::nanoseconds time()
template<typename VT , typename CT >
void folly::BucketedTimeSeries< VT, CT >::getBucketInfo ( TimePoint  time,
size_t *  bucketIdx,
TimePoint bucketStart,
TimePoint nextBucketStart 
) const

Definition at line 372 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::buckets_, folly::BucketedTimeSeries< VT, CT >::duration_, and folly::BucketedTimeSeries< VT, CT >::isAllTime().

Referenced by folly::BucketedTimeSeries< VT, CT >::getEarliestTimeNonEmpty(), TEST(), and folly::BucketedTimeSeries< VT, CT >::updateBuckets().

376  {
377  typedef typename Duration::rep TimeInt;
378  DCHECK(!isAllTime());
379 
380  // Keep these two lines together. The compiler should be able to compute
381  // both the division and modulus with a single operation.
382  Duration timeMod = time.time_since_epoch() % duration_;
383  TimeInt numFullDurations = time.time_since_epoch() / duration_;
384 
385  TimeInt scaledTime = timeMod.count() * TimeInt(buckets_.size());
386 
387  // Keep these two lines together. The compiler should be able to compute
388  // both the division and modulus with a single operation.
389  *bucketIdx = size_t(scaledTime / duration_.count());
390  TimeInt scaledOffsetInBucket = scaledTime % duration_.count();
391 
392  TimeInt scaledBucketStart = scaledTime - scaledOffsetInBucket;
393  TimeInt scaledNextBucketStart = scaledBucketStart + duration_.count();
394 
395  Duration bucketStartMod(
396  (scaledBucketStart + buckets_.size() - 1) / buckets_.size());
397  Duration nextBucketStartMod(
398  (scaledNextBucketStart + buckets_.size() - 1) / buckets_.size());
399 
400  TimePoint durationStart(numFullDurations * duration_);
401  *bucketStart = bucketStartMod + durationStart;
402  *nextBucketStart = nextBucketStartMod + durationStart;
403 }
std::vector< Bucket > buckets_
StatsClock::duration Duration
StatsClock::time_point TimePoint
std::chrono::nanoseconds time()
template<typename VT , typename CT >
CT::time_point folly::BucketedTimeSeries< VT, CT >::getEarliestTime ( ) const

Definition at line 226 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::empty(), folly::BucketedTimeSeries< VT, CT >::firstTime_, folly::BucketedTimeSeries< VT, CT >::getEarliestTimeNonEmpty(), folly::BucketedTimeSeries< VT, CT >::isAllTime(), and max.

Referenced by folly::BucketedTimeSeries< VT, CT >::elapsed(), and TEST().

226  {
227  if (empty()) {
228  return TimePoint();
229  }
230  if (isAllTime()) {
231  return firstTime_;
232  }
233 
234  // Compute the earliest time we can track
235  TimePoint earliestTime = getEarliestTimeNonEmpty();
236 
237  // We're never tracking data before firstTime_
238  earliestTime = std::max(earliestTime, firstTime_);
239 
240  return earliestTime;
241 }
LogLevel max
Definition: LogLevel.cpp:31
TimePoint getEarliestTimeNonEmpty() const
typename Clock::time_point TimePoint
StatsClock::time_point TimePoint
template<typename VT , typename CT >
CT::time_point folly::BucketedTimeSeries< VT, CT >::getEarliestTimeNonEmpty ( ) const
private

Definition at line 244 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::duration_, folly::BucketedTimeSeries< VT, CT >::getBucketInfo(), and folly::BucketedTimeSeries< VT, CT >::latestTime_.

Referenced by folly::BucketedTimeSeries< VT, CT >::addValueAggregated(), and folly::BucketedTimeSeries< VT, CT >::getEarliestTime().

245  {
246  size_t currentBucket;
247  TimePoint currentBucketStart;
248  TimePoint nextBucketStart;
250  latestTime_, &currentBucket, &currentBucketStart, &nextBucketStart);
251 
252  // Subtract 1 duration from the start of the next bucket to find the
253  // earliest possible data point we could be tracking.
254  return nextBucketStart - duration_;
255 }
void getBucketInfo(TimePoint time, size_t *bucketIdx, TimePoint *bucketStart, TimePoint *nextBucketStart) const
StatsClock::time_point TimePoint
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
TimePoint folly::BucketedTimeSeries< VT, CT >::getLatestTime ( ) const
inline

Definition at line 151 of file BucketedTimeSeries.h.

Referenced by TEST().

151  {
152  return latestTime_;
153  }
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
TimePoint folly::BucketedTimeSeries< VT, CT >::latestTime ( ) const
inline

Definition at line 219 of file BucketedTimeSeries.h.

Referenced by TEST().

219  {
220  return latestTime_;
221  }
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
size_t folly::BucketedTimeSeries< VT, CT >::numBuckets ( ) const
inline

Definition at line 174 of file BucketedTimeSeries.h.

174  {
175  return buckets_.size();
176  }
std::vector< Bucket > buckets_
template<typename VT , typename CT >
VT folly::BucketedTimeSeries< VT, CT >::rangeAdjust ( TimePoint  bucketStart,
TimePoint  nextBucketStart,
TimePoint  start,
TimePoint  end,
ValueType  input 
) const
private

Definition at line 479 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::latestTime_, max, and min.

Referenced by folly::BucketedTimeSeries< VT, CT >::avg(), folly::BucketedTimeSeries< VT, CT >::count(), and folly::BucketedTimeSeries< VT, CT >::sum().

484  {
485  // If nextBucketStart is greater than latestTime_, treat nextBucketStart as
486  // if it were latestTime_. This makes us more accurate when someone is
487  // querying for all of the data up to latestTime_. Even though latestTime_
488  // may only be partially through the bucket, we don't want to adjust
489  // downwards in this case, because the bucket really only has data up to
490  // latestTime_.
491  if (bucketStart <= latestTime_ && nextBucketStart > latestTime_) {
492  nextBucketStart = latestTime_ + Duration(1);
493  }
494 
495  if (start <= bucketStart && end >= nextBucketStart) {
496  // The bucket is wholly contained in the [start, end) interval
497  return input;
498  }
499 
500  TimePoint intervalStart = std::max(start, bucketStart);
501  TimePoint intervalEnd = std::min(end, nextBucketStart);
502  return input * (intervalEnd - intervalStart) /
503  (nextBucketStart - bucketStart);
504 }
LogLevel max
Definition: LogLevel.cpp:31
LogLevel min
Definition: LogLevel.cpp:30
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
StatsClock::time_point TimePoint
typename Clock::duration Duration
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
template<typename ReturnType = double, typename Interval = Duration>
ReturnType folly::BucketedTimeSeries< VT, CT >::rate ( ) const
inline

Definition at line 308 of file BucketedTimeSeries.h.

Referenced by TEST().

308  {
309  return rateHelper<ReturnType, Interval>(ReturnType(total_.sum), elapsed());
310  }
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
template<typename ReturnType = double, typename Interval = Duration>
ReturnType folly::BucketedTimeSeries< VT, CT >::rate ( TimePoint  start,
TimePoint  end 
) const
inline

Definition at line 371 of file BucketedTimeSeries.h.

References sum().

371  {
372  ValueType intervalSum = sum(start, end);
373  Duration interval = elapsed(start, end);
374  return rateHelper<ReturnType, Interval>(intervalSum, interval);
375  }
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
const ValueType & sum() const
auto start
StatsClock::duration Duration
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
template<typename ReturnType = double, typename Interval = Duration>
ReturnType folly::BucketedTimeSeries< VT, CT >::rateHelper ( ReturnType  numerator,
Duration  elapsedTime 
) const
inlineprivate

Definition at line 464 of file BucketedTimeSeries.h.

References now().

464  {
465  return detail::rateHelper<ReturnType, Duration, Interval>(
466  numerator, elapsedTime);
467  }
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
const ValueType& folly::BucketedTimeSeries< VT, CT >::sum ( ) const
inline

Definition at line 272 of file BucketedTimeSeries.h.

Referenced by folly::MultiLevelTimeSeries< VT, CT >::sum(), TEST(), and testUpdate100x10().

272  {
273  return total_.sum;
274  }
template<typename VT , typename CT >
VT folly::BucketedTimeSeries< VT, CT >::sum ( TimePoint  start,
TimePoint  end 
) const

Definition at line 281 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::forEachBucket(), folly::BucketedTimeSeries< VT, CT >::rangeAdjust(), and folly::detail::Bucket< T >::sum.

281  {
282  ValueType total = ValueType();
284  start,
285  end,
286  [&](const Bucket& bucket,
287  TimePoint bucketStart,
288  TimePoint nextBucketStart) -> bool {
289  total += this->rangeAdjust(
290  bucketStart, nextBucketStart, start, end, bucket.sum);
291  return true;
292  });
293 
294  return total;
295 }
ValueType rangeAdjust(TimePoint bucketStart, TimePoint nextBucketStart, TimePoint start, TimePoint end, ValueType input) const
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
StatsClock::time_point TimePoint
void forEachBucket(Function fn) const
template<typename VT , typename CT >
size_t folly::BucketedTimeSeries< VT, CT >::update ( TimePoint  now)

Definition at line 140 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::empty(), folly::BucketedTimeSeries< VT, CT >::firstTime_, folly::BucketedTimeSeries< VT, CT >::getBucketIdx(), folly::BucketedTimeSeries< VT, CT >::isAllTime(), folly::BucketedTimeSeries< VT, CT >::latestTime_, max, now(), and folly::BucketedTimeSeries< VT, CT >::updateBuckets().

Referenced by TEST(), and testUpdate100x10().

140  {
141  if (empty()) {
142  // This is the first data point.
143  firstTime_ = now;
144  }
145 
146  // For all-time data, all we need to do is update latestTime_
147  if (isAllTime()) {
149  return 0;
150  }
151 
152  // Make sure time doesn't go backwards.
153  // If the time is less than or equal to the latest time we have already seen,
154  // we don't need to do anything.
155  if (now <= latestTime_) {
156  return getBucketIdx(latestTime_);
157  }
158 
159  return updateBuckets(now);
160 }
LogLevel max
Definition: LogLevel.cpp:31
std::chrono::steady_clock::time_point now()
size_t updateBuckets(TimePoint now)
size_t getBucketIdx(TimePoint time) const
template<typename VT, typename CT = LegacyStatsClock<std::chrono::seconds>>
size_t folly::BucketedTimeSeries< VT, CT >::update ( Duration  now)
inline

Definition at line 458 of file BucketedTimeSeries.h.

458  {
459  return update(TimePoint(now));
460  }
std::chrono::steady_clock::time_point now()
typename Clock::time_point TimePoint
template<typename VT , typename CT >
size_t folly::BucketedTimeSeries< VT, CT >::updateBuckets ( TimePoint  now)
private

Definition at line 163 of file BucketedTimeSeries-defs.h.

References folly::BucketedTimeSeries< VT, CT >::buckets_, folly::detail::Bucket< T >::clear(), folly::BucketedTimeSeries< VT, CT >::duration_, folly::BucketedTimeSeries< VT, CT >::getBucketIdx(), folly::BucketedTimeSeries< VT, CT >::getBucketInfo(), folly::BucketedTimeSeries< VT, CT >::latestTime_, now(), and folly::BucketedTimeSeries< VT, CT >::total_.

Referenced by folly::BucketedTimeSeries< VT, CT >::addValueAggregated(), and folly::BucketedTimeSeries< VT, CT >::update().

163  {
164  // We could cache nextBucketStart as a member variable, so we don't have to
165  // recompute it each time update() is called with a new timestamp value.
166  // This makes things faster when update() (or addValue()) is called once
167  // per second, but slightly slower when update() is called multiple times a
168  // second. We care more about optimizing the cases where addValue() is being
169  // called frequently. If addValue() is only being called once every few
170  // seconds, it doesn't matter as much if it is fast.
171 
172  // Get info about the bucket that latestTime_ points at
173  size_t currentBucket;
174  TimePoint currentBucketStart;
175  TimePoint nextBucketStart;
177  latestTime_, &currentBucket, &currentBucketStart, &nextBucketStart);
178 
179  // Update latestTime_
180  latestTime_ = now;
181 
182  if (now < nextBucketStart) {
183  // We're still in the same bucket.
184  // We're done after updating latestTime_.
185  return currentBucket;
186  } else if (now >= currentBucketStart + duration_) {
187  // It's been a while. We have wrapped, and all of the buckets need to be
188  // cleared.
189  for (Bucket& bucket : buckets_) {
190  bucket.clear();
191  }
192  total_.clear();
193  return getBucketIdx(latestTime_);
194  } else {
195  // clear all the buckets between the last time and current time, meaning
196  // buckets in the range [(currentBucket+1), newBucket]. Note that
197  // the bucket (currentBucket+1) is always the oldest bucket we have. Since
198  // our array is circular, loop when we reach the end.
199  size_t newBucket = getBucketIdx(now);
200  size_t idx = currentBucket;
201  while (idx != newBucket) {
202  ++idx;
203  if (idx >= buckets_.size()) {
204  idx = 0;
205  }
206  total_ -= buckets_[idx];
207  buckets_[idx].clear();
208  }
209  return newBucket;
210  }
211 }
std::chrono::steady_clock::time_point now()
std::vector< Bucket > buckets_
void getBucketInfo(TimePoint time, size_t *bucketIdx, TimePoint *bucketStart, TimePoint *nextBucketStart) const
size_t getBucketIdx(TimePoint time) const
StatsClock::time_point TimePoint

Member Data Documentation


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