1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  * Android BPF library - public API
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 "LongArrayMultiStateCounter.h"
19 #include <log/log.h>
20 
21 namespace android {
22 namespace battery {
23 
24 template <>
delta(const std::vector<uint64_t> & previousValue,const std::vector<uint64_t> & newValue,std::vector<uint64_t> * outValue) const25 bool LongArrayMultiStateCounter::delta(const std::vector<uint64_t>& previousValue,
26                                        const std::vector<uint64_t>& newValue,
27                                        std::vector<uint64_t>* outValue) const {
28     size_t size = previousValue.size();
29     if (newValue.size() != size) {
30         ALOGE("Incorrect array size: %d, should be %d", (int)newValue.size(), (int)size);
31         return false;
32     }
33 
34     bool is_delta_valid = true;
35     for (int i = size - 1; i >= 0; i--) {
36         if (newValue[i] >= previousValue[i]) {
37             (*outValue)[i] = newValue[i] - previousValue[i];
38         } else {
39             (*outValue)[i] = 0;
40             is_delta_valid = false;
41         }
42     }
43     return is_delta_valid;
44 }
45 
46 template <>
add(std::vector<uint64_t> * value1,const std::vector<uint64_t> & value2,const uint64_t numerator,const uint64_t denominator) const47 void LongArrayMultiStateCounter::add(std::vector<uint64_t>* value1,
48                                      const std::vector<uint64_t>& value2, const uint64_t numerator,
49                                      const uint64_t denominator) const {
50     if (numerator != denominator) {
51         for (int i = value2.size() - 1; i >= 0; i--) {
52             // The caller ensures that denominator != 0
53             (*value1)[i] += value2[i] * numerator / denominator;
54         }
55     } else {
56         for (int i = value2.size() - 1; i >= 0; i--) {
57             (*value1)[i] += value2[i];
58         }
59     }
60 }
61 
62 template <>
valueToString(const std::vector<uint64_t> & v) const63 std::string LongArrayMultiStateCounter::valueToString(const std::vector<uint64_t>& v) const {
64     std::stringstream s;
65     s << "{";
66     bool first = true;
67     for (uint64_t n : v) {
68         if (!first) {
69             s << ", ";
70         }
71         s << n;
72         first = false;
73     }
74     s << "}";
75     return s.str();
76 }
77 
78 } // namespace battery
79 } // namespace android
80