1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 Couchbase, Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 #include <platform/histogram.h>
19 
20 /*
21  * Histogram<> definitions of large methods which we prefer to not inline.
22  */
23 
24 template <typename T, template <class> class Limits>
add(T amount, size_t count)25 void Histogram<T, Limits>::add(T amount, size_t count) {
26     (*findBin(amount))->incr(count);
27 }
28 
29 template <typename T, template <class> class Limits>
reset()30 void Histogram<T, Limits>::reset() {
31     std::for_each(bins.begin(), bins.end(),
32                   [](value_type& val){val->set(0);});
33 }
34 
35 template <typename T, template <class> class Limits>
total()36 size_t Histogram<T, Limits>::total() {
37     HistogramBinSampleAdder<T, Limits> a;
38     return std::accumulate(begin(), end(), 0, a);
39 }
40 
41 template <typename T, template <class> class Limits>
verify()42 bool Histogram<T, Limits>::verify() {
43     T prev = Limits<T>::min();
44     int pos(0);
45     for (const auto& bin : bins) {
46         if (bin->start() != prev) {
47             std::cerr << "Expected " << bin->start() << " == " << prev
48                       << " at pos " << pos << std::endl;
49             return false;
50         }
51         if (bin->start() != prev) {
52             return false;
53         }
54         prev = bin->end();
55         ++pos;
56     }
57     if (prev != Limits<T>::max()) {
58         return false;
59     }
60     return true;
61 }
62 
63 template <typename T, template <class> class Limits>
findBin( T amount)64 typename Histogram<T, Limits>::iterator Histogram<T, Limits>::findBin(
65         T amount) {
66     if (amount == Limits<T>::max()) {
67         return bins.end() - 1;
68     } else {
69         iterator it;
70         it = std::upper_bound(bins.begin(),
71                               bins.end(),
72                               amount,
73                               [](T t, Histogram<T, Limits>::value_type& b) {
74                                   return t < b->end();
75                               });
76         if (!(*it)->accepts(amount)) {
77             return bins.end();
78         }
79         return it;
80     }
81 }
82 
83 // Explicit template instantiations for all classes which we specialise
84 // Histogram<> for.
85 template class PLATFORM_PUBLIC_API Histogram<uint16_t>;
86 template class PLATFORM_PUBLIC_API Histogram<uint32_t>;
87 template class PLATFORM_PUBLIC_API Histogram<size_t>;
88 template class PLATFORM_PUBLIC_API Histogram<int>;
89 template class PLATFORM_PUBLIC_API Histogram<UnsignedMicroseconds, cb::duration_limits>;
90