correct usage of namespace std for coroutines_trait specialization
[folly.git] / folly / stats / TimeseriesHistogram-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/Conv.h>
20 #include <folly/stats/BucketedTimeSeries-defs.h>
21 #include <folly/stats/Histogram-defs.h>
22 #include <folly/stats/MultiLevelTimeSeries-defs.h>
23 #include <folly/stats/TimeseriesHistogram.h>
24
25 namespace folly {
26
27 template <typename T, typename CT, typename C>
28 TimeseriesHistogram<T, CT, C>::TimeseriesHistogram(
29     ValueType bucketSize,
30     ValueType min,
31     ValueType max,
32     const ContainerType& copyMe)
33     : buckets_(bucketSize, min, max, copyMe),
34       haveNotSeenValue_(true),
35       singleUniqueValue_(false) {}
36
37 template <typename T, typename CT, typename C>
38 void TimeseriesHistogram<T, CT, C>::addValue(
39     TimePoint now,
40     const ValueType& value) {
41   buckets_.getByValue(value).addValue(now, value);
42   maybeHandleSingleUniqueValue(value);
43 }
44
45 template <typename T, typename CT, typename C>
46 void TimeseriesHistogram<T, CT, C>::addValue(
47     TimePoint now,
48     const ValueType& value,
49     uint64_t times) {
50   buckets_.getByValue(value).addValue(now, value, times);
51   maybeHandleSingleUniqueValue(value);
52 }
53
54 template <typename T, typename CT, typename C>
55 void TimeseriesHistogram<T, CT, C>::addValues(
56     TimePoint now,
57     const folly::Histogram<ValueType>& hist) {
58   CHECK_EQ(hist.getMin(), getMin());
59   CHECK_EQ(hist.getMax(), getMax());
60   CHECK_EQ(hist.getBucketSize(), getBucketSize());
61   CHECK_EQ(hist.getNumBuckets(), getNumBuckets());
62
63   for (size_t n = 0; n < hist.getNumBuckets(); ++n) {
64     const typename folly::Histogram<ValueType>::Bucket& histBucket =
65         hist.getBucketByIndex(n);
66     Bucket& myBucket = buckets_.getByIndex(n);
67     myBucket.addValueAggregated(now, histBucket.sum, histBucket.count);
68   }
69
70   // We don't bother with the singleUniqueValue_ tracking.
71   haveNotSeenValue_ = false;
72   singleUniqueValue_ = false;
73 }
74
75 template <typename T, typename CT, typename C>
76 void TimeseriesHistogram<T, CT, C>::maybeHandleSingleUniqueValue(
77     const ValueType& value) {
78   if (haveNotSeenValue_) {
79     firstValue_ = value;
80     singleUniqueValue_ = true;
81     haveNotSeenValue_ = false;
82   } else if (singleUniqueValue_) {
83     if (value != firstValue_) {
84       singleUniqueValue_ = false;
85     }
86   }
87 }
88
89 template <typename T, typename CT, typename C>
90 T TimeseriesHistogram<T, CT, C>::getPercentileEstimate(double pct, size_t level)
91     const {
92   if (singleUniqueValue_) {
93     return firstValue_;
94   }
95
96   return buckets_.getPercentileEstimate(
97       pct / 100.0, CountFromLevel(level), AvgFromLevel(level));
98 }
99
100 template <typename T, typename CT, typename C>
101 T TimeseriesHistogram<T, CT, C>::getPercentileEstimate(
102     double pct,
103     TimePoint start,
104     TimePoint end) const {
105   if (singleUniqueValue_) {
106     return firstValue_;
107   }
108
109   return buckets_.getPercentileEstimate(
110       pct / 100.0,
111       CountFromInterval(start, end),
112       AvgFromInterval<T>(start, end));
113 }
114
115 template <typename T, typename CT, typename C>
116 size_t TimeseriesHistogram<T, CT, C>::getPercentileBucketIdx(
117     double pct,
118     size_t level) const {
119   return buckets_.getPercentileBucketIdx(pct / 100.0, CountFromLevel(level));
120 }
121
122 template <typename T, typename CT, typename C>
123 size_t TimeseriesHistogram<T, CT, C>::getPercentileBucketIdx(
124     double pct,
125     TimePoint start,
126     TimePoint end) const {
127   return buckets_.getPercentileBucketIdx(
128       pct / 100.0, CountFromInterval(start, end));
129 }
130
131 template <typename T, typename CT, typename C>
132 void TimeseriesHistogram<T, CT, C>::clear() {
133   for (size_t i = 0; i < buckets_.getNumBuckets(); i++) {
134     buckets_.getByIndex(i).clear();
135   }
136 }
137
138 template <typename T, typename CT, typename C>
139 void TimeseriesHistogram<T, CT, C>::update(TimePoint now) {
140   for (size_t i = 0; i < buckets_.getNumBuckets(); i++) {
141     buckets_.getByIndex(i).update(now);
142   }
143 }
144
145 template <typename T, typename CT, typename C>
146 std::string TimeseriesHistogram<T, CT, C>::getString(size_t level) const {
147   std::string result;
148
149   for (size_t i = 0; i < buckets_.getNumBuckets(); i++) {
150     if (i > 0) {
151       toAppend(",", &result);
152     }
153     const ContainerType& cont = buckets_.getByIndex(i);
154     toAppend(
155         buckets_.getBucketMin(i),
156         ":",
157         cont.count(level),
158         ":",
159         cont.template avg<ValueType>(level),
160         &result);
161   }
162
163   return result;
164 }
165
166 template <typename T, typename CT, typename C>
167 std::string TimeseriesHistogram<T, CT, C>::getString(
168     TimePoint start,
169     TimePoint end) const {
170   std::string result;
171
172   for (size_t i = 0; i < buckets_.getNumBuckets(); i++) {
173     if (i > 0) {
174       toAppend(",", &result);
175     }
176     const ContainerType& cont = buckets_.getByIndex(i);
177     toAppend(
178         buckets_.getBucketMin(i),
179         ":",
180         cont.count(start, end),
181         ":",
182         cont.avg(start, end),
183         &result);
184   }
185
186   return result;
187 }
188
189 template <class T, class CT, class C>
190 void TimeseriesHistogram<T, CT, C>::computeAvgData(
191     ValueType* total,
192     uint64_t* nsamples,
193     size_t level) const {
194   for (size_t b = 0; b < buckets_.getNumBuckets(); ++b) {
195     const auto& levelObj = buckets_.getByIndex(b).getLevel(level);
196     *total += levelObj.sum();
197     *nsamples += levelObj.count();
198   }
199 }
200
201 template <class T, class CT, class C>
202 void TimeseriesHistogram<T, CT, C>::computeAvgData(
203     ValueType* total,
204     uint64_t* nsamples,
205     TimePoint start,
206     TimePoint end) const {
207   for (size_t b = 0; b < buckets_.getNumBuckets(); ++b) {
208     const auto& levelObj = buckets_.getByIndex(b).getLevel(start);
209     *total += levelObj.sum(start, end);
210     *nsamples += levelObj.count(start, end);
211   }
212 }
213
214 template <typename T, typename CT, typename C>
215 void TimeseriesHistogram<T, CT, C>::computeRateData(
216     ValueType* total,
217     Duration* elapsed,
218     size_t level) const {
219   for (size_t b = 0; b < buckets_.getNumBuckets(); ++b) {
220     const auto& levelObj = buckets_.getByIndex(b).getLevel(level);
221     *total += levelObj.sum();
222     *elapsed = std::max(*elapsed, levelObj.elapsed());
223   }
224 }
225
226 template <class T, class CT, class C>
227 void TimeseriesHistogram<T, CT, C>::computeRateData(
228     ValueType* total,
229     Duration* elapsed,
230     TimePoint start,
231     TimePoint end) const {
232   for (size_t b = 0; b < buckets_.getNumBuckets(); ++b) {
233     const auto& level = buckets_.getByIndex(b).getLevel(start);
234     *total += level.sum(start, end);
235     *elapsed = std::max(*elapsed, level.elapsed(start, end));
236   }
237 }
238
239 } // namespace folly