1 /*
2  * Copyright (C) 2024 The Android Open Source Project
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 #include <android/util/ProtoOutputStream.h>
18 
19 #include <string>
20 #include <vector>
21 
22 #include "stats_util.h"
23 
24 #pragma once
25 
26 namespace android {
27 namespace os {
28 namespace statsd {
29 
30 size_t getCompactedBinCountsSize(const std::vector<int>& binCounts);
31 
32 // Encapsulates histogram bin counts. This class is not thread-safe.
33 class HistogramValue {
34 public:
35     // Default constructor
36     constexpr HistogramValue() noexcept = default;
37 
38     // Copy constructor for pre-aggregated bin counts.
HistogramValue(const std::vector<int> & binCounts)39     constexpr HistogramValue(const std::vector<int>& binCounts) : mBinCounts(binCounts) {
40     }
41 
42     // Move constructor for pre-aggregated bin counts.
HistogramValue(std::vector<int> && binCounts)43     constexpr HistogramValue(std::vector<int>&& binCounts) : mBinCounts(std::move(binCounts)) {
44     }
45 
46     std::string toString() const;
47 
48     bool isEmpty() const;
49 
50     size_t getSize() const;
51 
52     // Should only be called on HistogramValue instances returned by getCompactedHistogramValue().
53     // Also, this should be called to dump histogram data to proto.
54     void toProto(android::util::ProtoOutputStream& protoOutput) const;
55 
56     void addValue(float value, const BinStarts& binStarts);
57 
58     // Returns a new HistogramValue where mBinCounts is compressed as follows:
59     // For each entry in mBinCounts, n:
60     //  * n >= 0 represents the actual count
61     //  * n == -1 does not appear
62     //  * n <= -2 represents -n consecutive bins with count of 0
63     // Called on bucket flushes from NumericValueMetricProducer
64     HistogramValue getCompactedHistogramValue() const;
65 
66     bool isValid() const;
67 
68     HistogramValue& operator+=(const HistogramValue& rhs);
69 
70     // Returns a HistogramValue where each bin is the sum of the corresponding bins in lhs and rhs.
71     // If rhs has fewer bins, the remaining lhs bins are copied to the returned HistogramValue.
72     friend HistogramValue operator+(HistogramValue lhs, const HistogramValue& rhs);
73 
74     HistogramValue& operator-=(const HistogramValue& rhs);
75 
76     // Returns a HistogramValue where each bin in rhs is subtracted from the corresponding bin in
77     // lhs. If rhs has fewer bins, the remaining lhs bins are copied to the returned HistogramValue.
78     // For bins where the returned value would be less than 0, their values are set to 0 instead.
79     friend HistogramValue operator-(HistogramValue lhs, const HistogramValue& rhs);
80 
81     friend bool operator==(const HistogramValue& lhs, const HistogramValue& rhs);
82 
83     friend bool operator!=(const HistogramValue& lhs, const HistogramValue& rhs);
84 
85     friend bool operator<(const HistogramValue& lhs, const HistogramValue& rhs);
86 
87     friend bool operator>(const HistogramValue& lhs, const HistogramValue& rhs);
88 
89     friend bool operator<=(const HistogramValue& lhs, const HistogramValue& rhs);
90 
91     friend bool operator>=(const HistogramValue& lhs, const HistogramValue& rhs);
92 
93     // Error states encountered during binary operations.
94     static const HistogramValue ERROR_BINS_MISMATCH;
95     static const HistogramValue ERROR_BIN_COUNT_TOO_HIGH;
96 
97 private:
98     std::vector<int> mBinCounts;
99     bool mCompacted = false;
100 };
101 
102 }  // namespace statsd
103 }  // namespace os
104 }  // namespace android
105