• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #define STATSD_DEBUG false  // STOPSHIP if true
18 
19 #include "Log.h"
20 
21 #include "LoggingRate.h"
22 
23 #include <algorithm>
24 
25 using namespace std;
26 
27 namespace android {
28 namespace os {
29 namespace statsd {
30 
LoggingRate(int maxStatsNum,int64_t logFrequencyWindowNs)31 LoggingRate::LoggingRate(int maxStatsNum, int64_t logFrequencyWindowNs)
32     : mMaxRateInfoSize(maxStatsNum), mLogFrequencyWindowNs(logFrequencyWindowNs) {
33 }
34 
noteLogEvent(uint32_t atomId,int64_t eventTimestampNs)35 void LoggingRate::noteLogEvent(uint32_t atomId, int64_t eventTimestampNs) {
36     auto rateInfoIt = mRateInfo.find(atomId);
37 
38     if (rateInfoIt != mRateInfo.end()) {
39         RateInfo& rateInfo = rateInfoIt->second;
40         if (eventTimestampNs - rateInfo.intervalStartNs >= mLogFrequencyWindowNs) {
41             rateInfo.intervalStartNs = eventTimestampNs;
42             rateInfo.rate = 1;
43         } else {
44             // update rateInfo
45             rateInfo.rate++;
46 #ifdef STATSD_DEBUG
47             if (rateInfo.maxRate < rateInfo.rate) {
48                 VLOG("For Atom %d new maxRate is %d", atomId, rateInfo.rate);
49             }
50 #endif
51             rateInfo.maxRate = max(rateInfo.maxRate, rateInfo.rate);
52         }
53     } else if (mRateInfo.size() < mMaxRateInfoSize) {
54         // atomId not found, add it to the map with initial frequency
55         mRateInfo[atomId] = {eventTimestampNs, 1, 1};
56     }
57 }
58 
getMaxRate(uint32_t atomId) const59 int32_t LoggingRate::getMaxRate(uint32_t atomId) const {
60     const auto rateInfoIt = mRateInfo.find(atomId);
61     if (rateInfoIt != mRateInfo.end()) {
62         return rateInfoIt->second.maxRate;
63     }
64     return 0;
65 }
66 
getMaxRates(size_t topN) const67 std::vector<LoggingRate::PeakRatePerAtomId> LoggingRate::getMaxRates(size_t topN) const {
68     std::vector<PeakRatePerAtomId> result;
69     result.reserve(mRateInfo.size());
70 
71     for (auto& [atomId, rateInfo] : mRateInfo) {
72         result.emplace_back(atomId, rateInfo.maxRate);
73     }
74 
75     std::sort(result.begin(), result.end(),
76               [](const PeakRatePerAtomId& a, const PeakRatePerAtomId& b) {
77                   return a.second > b.second;
78               });
79 
80     if (topN < result.size()) {
81         result.erase(result.begin() + topN, result.end());
82     }
83 
84     return result;
85 }
86 
reset()87 void LoggingRate::reset() {
88     mRateInfo.clear();
89 }
90 
91 }  // namespace statsd
92 }  // namespace os
93 }  // namespace android
94