/*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/*
* Get the latest time that has ever been passed to update() or addValue().
+ *
+ * If no data has ever been added to this timeseries, 0 will be returned.
*/
TimeType getLatestTime() const {
return latestTime_;
}
+ /*
+ * Get the time of the earliest data point stored in this timeseries.
+ *
+ * If no data has ever been added to this timeseries, 0 will be returned.
+ *
+ * If isAllTime() is true, this is simply the time when the first data point
+ * was recorded.
+ *
+ * For non-all-time data, the timestamp reflects the first data point still
+ * remembered. As new data points are added, old data will be expired.
+ * getEarliestTime() returns the timestamp of the oldest bucket still present
+ * in the timeseries. This will never be older than (getLatestTime() -
+ * duration()).
+ */
+ TimeType getEarliestTime() const;
+
/*
* Return the number of buckets.
*/
*/
TimeType elapsed() const;
+ /*
+ * Get the amount of time tracked by this timeseries, between the specified
+ * start and end times.
+ *
+ * If the timeseries contains data for the entire time range specified, this
+ * simply returns (end - start). However, if start is earlier than
+ * getEarliestTime(), this returns (end - getEarliestTime()).
+ */
+ TimeType elapsed(TimeType start, TimeType end) const;
+
/*
* Return the sum of all the data points currently tracked by this
* BucketedTimeSeries.
*/
template <typename ReturnType=double>
ReturnType avg() const {
- return total_.avg<ReturnType>();
+ return total_.template avg<ReturnType>();
}
/*
*
* Note that data outside of the timeseries duration will no longer be
* available for use in the estimation. Specifying a start time earlier than
- * (getLatestTime() - elapsed()) will not have much effect, since only data
- * points after that point in time will be counted.
+ * getEarliestTime() will not have much effect, since only data points after
+ * that point in time will be counted.
*
* Note that the value returned is an estimate, and may not be precise.
*/
template <typename ReturnType=double, typename Interval=TimeType>
ReturnType rate(TimeType start, TimeType end) const {
ValueType intervalSum = sum(start, end);
- return rateHelper<ReturnType, Interval>(intervalSum, end - start);
+ TimeType interval = elapsed(start, end);
+ return rateHelper<ReturnType, Interval>(intervalSum, interval);
}
/*
template <typename ReturnType=double, typename Interval=TimeType>
ReturnType countRate(TimeType start, TimeType end) const {
uint64_t intervalCount = count(start, end);
- return rateHelper<ReturnType, Interval>(intervalCount, end - start);
+ TimeType interval = elapsed(start, end);
+ return rateHelper<ReturnType, Interval>(intervalCount, interval);
}
/*
private:
template <typename ReturnType=double, typename Interval=TimeType>
ReturnType rateHelper(ReturnType numerator, TimeType elapsed) const {
- if (elapsed == TimeType(0)) {
- return 0;
- }
-
- // Use std::chrono::duration_cast to convert between the native
- // duration and the desired interval. However, convert the rates,
- // rather than just converting the elapsed duration. Converting the
- // elapsed time first may collapse it down to 0 if the elapsed interval
- // is less than the desired interval, which will incorrectly result in
- // an infinite rate.
- typedef std::chrono::duration<
- ReturnType, std::ratio<TimeType::period::den,
- TimeType::period::num>> NativeRate;
- typedef std::chrono::duration<
- ReturnType, std::ratio<Interval::period::den,
- Interval::period::num>> DesiredRate;
-
- NativeRate native(numerator / elapsed.count());
- DesiredRate desired = std::chrono::duration_cast<DesiredRate>(native);
- return desired.count();
+ return detail::rateHelper<ReturnType, TimeType, Interval>(numerator,
+ elapsed);
}
ValueType rangeAdjust(TimeType bucketStart, TimeType nextBucketStart,