1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PANDA_RUNTIME_HISTOGRAM_H_
17 #define PANDA_RUNTIME_HISTOGRAM_H_
18 
19 #include "libpandabase/utils/type_converter.h"
20 #include "libpandabase/macros.h"
21 #include "mem/panda_containers.h"
22 #include "mem/panda_string.h"
23 
24 namespace ark {
25 
26 /**
27  * @brief Class for providing distribution statistics
28  * Minimum, maximum, count, average, sum, dispersion
29  */
30 template <class Value>
31 class SimpleHistogram {
32 public:
SimpleHistogram(helpers::ValueType typeOfValue = helpers::ValueType::VALUE_TYPE_OBJECT)33     explicit SimpleHistogram(helpers::ValueType typeOfValue = helpers::ValueType::VALUE_TYPE_OBJECT)
34         : typeOfValue_(typeOfValue)
35     {
36     }
37 
38     /**
39      *  @brief Add all element to statistics at the half-interval from @param start to @param finish
40      *  @param start begin of values inclusive
41      *  @param finish end of values ​​not inclusive
42      */
43     template <class ForwardIterator>
44     SimpleHistogram(ForwardIterator start, ForwardIterator finish,
45                     helpers::ValueType typeOfValue = helpers::ValueType::VALUE_TYPE_OBJECT);
46 
47     /**
48      *  @brief Output the General statistics of Histogram
49      *  @return PandaString with Sum, Avg, Max
50      */
51     PandaString GetGeneralStatistic() const;
52 
53     /**
54      *  @brief Add @param element to statistics @param number of times
55      *  @param element
56      *  @param count
57      */
58     void AddValue(const Value &element, size_t number = 1);
59 
GetCount() const60     size_t GetCount() const
61     {
62         return count_;
63     }
64 
GetSum() const65     Value GetSum() const
66     {
67         return sum_;
68     }
69 
GetMin() const70     Value GetMin() const
71     {
72         return min_;
73     }
74 
GetMax() const75     Value GetMax() const
76     {
77         return max_;
78     }
79 
GetAvg() const80     double GetAvg() const
81     {
82         if (count_ > 0U) {
83             return sum_ / static_cast<double>(count_);
84         }
85         return 0;
86     }
87 
GetDispersion() const88     double GetDispersion() const
89     {
90         return sumOfSquares_ / static_cast<double>(count_) - GetAvg() * GetAvg();
91     }
92 
93     ~SimpleHistogram() = default;
94 
95     DEFAULT_COPY_SEMANTIC(SimpleHistogram);
96     DEFAULT_NOEXCEPT_MOVE_SEMANTIC(SimpleHistogram);
97 
98 private:
99     size_t count_ = 0;
100     Value sum_ {};
101     Value sumOfSquares_ {};
102     Value min_ {};
103     Value max_ {};
104     helpers::ValueType typeOfValue_;
105 };
106 
107 /**
108  * @brief Class for providing distribution statistics
109  * Minimum, maximum, count, average, sum, dispersion
110  */
111 template <class Value>
112 class Histogram : public SimpleHistogram<Value> {
113 public:
Histogram(helpers::ValueType typeOfValue = helpers::ValueType::VALUE_TYPE_OBJECT)114     explicit Histogram(helpers::ValueType typeOfValue = helpers::ValueType::VALUE_TYPE_OBJECT)
115         : SimpleHistogram<Value>(typeOfValue)
116     {
117     }
118 
119     /**
120      *  @brief Add all element to statistics at the half-interval from @param start to @param finish
121      *  @param start begin of values inclusive
122      *  @param finish end of values ​​not inclusive
123      */
124     template <class ForwardIterator>
125     Histogram(ForwardIterator start, ForwardIterator finish,
126               helpers::ValueType typeOfValue = helpers::ValueType::VALUE_TYPE_OBJECT);
127 
128     /**
129      *  @brief Output the first @param count_top of the lowest values by key
130      *  with the number of their count
131      *  @param count_top Number of first values to output
132      *  @return PandaString with in format: "[key:count[,]]*"
133      */
134     PandaString GetTopDump(size_t countTop = DEFAULT_TOP_SIZE) const;
135 
136     /**
137      *  @brief Add @param element to statistics @param number of times
138      *  @param element
139      *  @param count
140      */
141     void AddValue(const Value &element, size_t number = 1);
142 
GetCountDifferent() const143     size_t GetCountDifferent() const
144     {
145         return frequency_.size();
146     }
147 
148 private:
149     PandaMap<Value, uint32_t> frequency_;
150 
151     static constexpr size_t DEFAULT_TOP_SIZE = 10;
152 };
153 
154 }  // namespace ark
155 
156 #endif  // PANDA_RUNTIME_HISTOGRAM_H_
157