Add constructor for MultiLevelTimeSeries class that uses initializer_list and add...
[folly.git] / folly / stats / MultiLevelTimeSeries-defs.h
1 /*
2  * Copyright 2016 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 TT>
25 MultiLevelTimeSeries<VT, TT>::MultiLevelTimeSeries(
26   size_t nBuckets,
27   size_t nLevels,
28   const TimeType levelDurations[])
29     : cachedTime_(0),
30       cachedSum_(0),
31       cachedCount_(0) {
32     CHECK_GT(nLevels, 0);
33     CHECK(levelDurations);
34
35     levels_.reserve(nLevels);
36     for (size_t i = 0; i < nLevels; ++i) {
37       if (levelDurations[i] == TT(0)) {
38         CHECK_EQ(i, nLevels - 1);
39       } else if (i > 0) {
40         CHECK(levelDurations[i-1] < levelDurations[i]);
41       }
42       levels_.emplace_back(nBuckets, levelDurations[i]);
43     }
44 }
45
46 template <typename VT, typename TT>
47 MultiLevelTimeSeries<VT, TT>::MultiLevelTimeSeries(
48     size_t nBuckets,
49     std::initializer_list<TimeType> durations)
50     : cachedTime_(0), cachedSum_(0), cachedCount_(0) {
51   CHECK_GT(durations.size(), 0);
52
53   levels_.reserve(durations.size());
54   int i = 0;
55   TimeType prev;
56   for (auto dur : durations) {
57     if (dur == TT(0)) {
58       CHECK_EQ(i, durations.size() - 1);
59     } else if (i > 0) {
60       CHECK(prev < dur);
61     }
62     levels_.emplace_back(nBuckets, dur);
63     prev = dur;
64     i++;
65   }
66 }
67
68 template <typename VT, typename TT>
69 void MultiLevelTimeSeries<VT, TT>::addValue(
70     TimeType now,
71     const ValueType& val) {
72   addValueAggregated(now, val, 1);
73 }
74
75 template <typename VT, typename TT>
76 void MultiLevelTimeSeries<VT, TT>::addValue(TimeType now,
77                                             const ValueType& val,
78                                             int64_t times) {
79   addValueAggregated(now, val * times, times);
80 }
81
82 template <typename VT, typename TT>
83 void MultiLevelTimeSeries<VT, TT>::addValueAggregated(TimeType now,
84                                                       const ValueType& total,
85                                                       int64_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 TT>
95 void MultiLevelTimeSeries<VT, TT>::update(TimeType 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 TT>
103 void MultiLevelTimeSeries<VT, TT>::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 TT>
115 void MultiLevelTimeSeries<VT, TT>::clear() {
116   for (auto & level : levels_) {
117     level.clear();
118   }
119
120   cachedTime_ = TimeType(0);
121   cachedSum_ = 0;
122   cachedCount_ = 0;
123 }
124
125 }  // folly