1 //
2 // Copyright (C) 2023 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 "include/Histogram.h"
18 
19 #define LOG_TAG "tex"
20 
21 #include <log/log.h>
22 #include <statslog_express.h>
23 #include <string.h>
24 #include <utils/hash/farmhash.h>
25 
26 namespace android {
27 namespace expresslog {
28 
create(int binCount,float minValue,float exclusiveMaxValue)29 std::shared_ptr<Histogram::UniformOptions> Histogram::UniformOptions::create(
30         int binCount, float minValue, float exclusiveMaxValue) {
31     if (binCount < 1) {
32         ALOGE("Bin count should be positive number");
33         return nullptr;
34     }
35 
36     if (exclusiveMaxValue <= minValue) {
37         ALOGE("Bins range invalid (maxValue < minValue)");
38         return nullptr;
39     }
40 
41     return std::shared_ptr<UniformOptions>(
42             new UniformOptions(binCount, minValue, exclusiveMaxValue));
43 }
44 
UniformOptions(int binCount,float minValue,float exclusiveMaxValue)45 Histogram::UniformOptions::UniformOptions(int binCount, float minValue, float exclusiveMaxValue)
46     :  // Implicitly add 2 for the extra undeflow & overflow bins
47       mBinCount(binCount + 2),
48       mMinValue(minValue),
49       mExclusiveMaxValue(exclusiveMaxValue),
50       mBinSize((exclusiveMaxValue - minValue) / binCount) {
51 }
52 
getBinForSample(float sample) const53 int Histogram::UniformOptions::getBinForSample(float sample) const {
54     if (sample < mMinValue) {
55         // goes to underflow
56         return 0;
57     } else if (sample >= mExclusiveMaxValue) {
58         // goes to overflow
59         return mBinCount - 1;
60     }
61     return (int)((sample - mMinValue) / mBinSize + 1);
62 }
63 
Histogram(const char * metricName,std::shared_ptr<BinOptions> binOptions)64 Histogram::Histogram(const char* metricName, std::shared_ptr<BinOptions> binOptions)
65     : mMetricIdHash(farmhash::Fingerprint64(metricName, strlen(metricName))),
66       mBinOptions(std::move(binOptions)) {
67 }
68 
logSample(float sample) const69 void Histogram::logSample(float sample) const {
70     const int binIndex = mBinOptions->getBinForSample(sample);
71     stats_write(EXPRESS_HISTOGRAM_SAMPLE_REPORTED, mMetricIdHash, /*count*/ 1, binIndex);
72 }
73 
logSampleWithUid(int32_t uid,float sample) const74 void Histogram::logSampleWithUid(int32_t uid, float sample) const {
75     const int binIndex = mBinOptions->getBinForSample(sample);
76     stats_write(EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED, mMetricIdHash, /*count*/ 1, binIndex, uid);
77 }
78 
79 }  // namespace expresslog
80 }  // namespace android
81