2017
[folly.git] / folly / stats / MultiLevelTimeSeries-defs.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <folly/stats/MultiLevelTimeSeries.h>
20 #include <glog/logging.h>
21
22 namespace folly {
23
24 template <typename VT, typename CT>
25 MultiLevelTimeSeries<VT, CT>::MultiLevelTimeSeries(
26     size_t nBuckets,
27     size_t nLevels,
28     const Duration levelDurations[])
29     : cachedTime_(), cachedSum_(0), cachedCount_(0) {
30   CHECK_GT(nLevels, 0u);
31   CHECK(levelDurations);
32
33   levels_.reserve(nLevels);
34   for (size_t i = 0; i < nLevels; ++i) {
35     if (levelDurations[i] == Duration(0)) {
36       CHECK_EQ(i, nLevels - 1);
37     } else if (i > 0) {
38       CHECK(levelDurations[i - 1] < levelDurations[i]);
39     }
40     levels_.emplace_back(nBuckets, levelDurations[i]);
41   }
42 }
43
44 template <typename VT, typename CT>
45 MultiLevelTimeSeries<VT, CT>::MultiLevelTimeSeries(
46     size_t nBuckets,
47     std::initializer_list<Duration> durations)
48     : cachedTime_(), cachedSum_(0), cachedCount_(0) {
49   CHECK_GT(durations.size(), 0u);
50
51   levels_.reserve(durations.size());
52   size_t i = 0;
53   Duration prev{0};
54   for (auto dur : durations) {
55     if (dur == Duration(0)) {
56       CHECK_EQ(i, durations.size() - 1);
57     } else if (i > 0) {
58       CHECK(prev < dur);
59     }
60     levels_.emplace_back(nBuckets, dur);
61     prev = dur;
62     i++;
63   }
64 }
65
66 template <typename VT, typename CT>
67 void MultiLevelTimeSeries<VT, CT>::addValue(
68     TimePoint now,
69     const ValueType& val) {
70   addValueAggregated(now, val, 1);
71 }
72
73 template <typename VT, typename CT>
74 void MultiLevelTimeSeries<VT, CT>::addValue(
75     TimePoint now,
76     const ValueType& val,
77     uint64_t times) {
78   addValueAggregated(now, val * times, times);
79 }
80
81 template <typename VT, typename CT>
82 void MultiLevelTimeSeries<VT, CT>::addValueAggregated(
83     TimePoint now,
84     const ValueType& total,
85     uint64_t nsamples) {
86   if (cachedTime_ != now) {
87     flush();
88     cachedTime_ = now;
89   }
90   cachedSum_ += total;
91   cachedCount_ += nsamples;
92 }
93
94 template <typename VT, typename CT>
95 void MultiLevelTimeSeries<VT, CT>::update(TimePoint now) {
96   flush();
97   for (size_t i = 0; i < levels_.size(); ++i) {
98     levels_[i].update(now);
99   }
100 }
101
102 template <typename VT, typename CT>
103 void MultiLevelTimeSeries<VT, CT>::flush() {
104   // update all the underlying levels
105   if (cachedCount_ > 0) {
106     for (size_t i = 0; i < levels_.size(); ++i) {
107       levels_[i].addValueAggregated(cachedTime_, cachedSum_, cachedCount_);
108     }
109     cachedCount_ = 0;
110     cachedSum_ = 0;
111   }
112 }
113
114 template <typename VT, typename CT>
115 void MultiLevelTimeSeries<VT, CT>::clear() {
116   for (auto & level : levels_) {
117     level.clear();
118   }
119
120   cachedTime_ = TimePoint();
121   cachedSum_ = 0;
122   cachedCount_ = 0;
123 }
124
125 }  // folly