xref: /aosp_15_r20/system/chre/apps/nearby/location/lbs/contexthub/nanoapps/nearby/adv_report_cache.h (revision 84e339476a462649f82315436d70fd732297a399)
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 #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_ADV_REPORT_CACHE_H_
18 #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_ADV_REPORT_CACHE_H_
19 
20 #include "third_party/contexthub/chre/util/include/chre/util/time.h"
21 #ifdef NEARBY_PROFILE
22 #include <ash/profile.h>
23 #endif
24 
25 #include <limits>
26 #include <utility>
27 
28 #include "third_party/contexthub/chre/util/include/chre/util/dynamic_vector.h"
29 
30 namespace nearby {
31 
32 class AdvReportCache {
33  public:
34   // Constructs advertise report cache.
35 #ifdef NEARBY_PROFILE
AdvReportCache()36   AdvReportCache() {
37     ashProfileInit(
38         &profile_data_, "[NEARBY_ADV_CACHE_PERF]", 1000 /* print_interval_ms */,
39         false /* report_total_thread_cycles */, true /* printCsvFormat */);
40   }
41 #else
42   AdvReportCache() = default;
43 #endif
44 
45   // Deconstructs advertise report cache and releases all resources.
~AdvReportCache()46   ~AdvReportCache() {
47     Clear();
48   }
49 
50   // Move assignment operator
51   AdvReportCache &operator=(AdvReportCache &&other) {
52     if (&other == this) {
53       return *this;
54     }
55     Clear();
56     cache_reports_ = std::move(other.cache_reports_);
57     cache_expire_nanosec_ = other.cache_expire_nanosec_;
58     return *this;
59   }
60 
61   // Releases all resources {cache element, heap memory} in cache.
62   void Clear();
63 
64   // Adds advertise report to cache with deduplicating by
65   // unique key which is {advertiser address and data}.
66   // Among advertise report with the same key, latest one will be placed at the
67   // same index of existing report in advertise reports cache.
68   void Push(const chreBleAdvertisingReport &report);
69 
70   // Return advertise reports in cache after refreshing the cache elements.
GetAdvReports()71   chre::DynamicVector<chreBleAdvertisingReport> &GetAdvReports() {
72     Refresh();
73     return cache_reports_;
74   }
75 
76   // Computes moving average with previous average (previous) and a current data
77   // point (current). Returns the computed average.
ComputeMovingAverage(int8_t previous,int8_t current)78   int8_t ComputeMovingAverage(int8_t previous, int8_t current) const {
79     return static_cast<int8_t>(current * kMovingAverageWeight +
80                                previous * (1 - kMovingAverageWeight));
81   }
82 
83   // Sets current cache timeout value.
SetCacheTimeout(uint64_t cache_expire_millisec)84   void SetCacheTimeout(uint64_t cache_expire_millisec) {
85     cache_expire_nanosec_ =
86         cache_expire_millisec * chre::kOneMillisecondInNanoseconds;
87   }
88 
89   // Removes cached elements older than the cache timeout.
90   void Refresh();
91 
92   // Removes cached elements older than the cache timeout if cache count is
93   // larger than threshold.
94   void RefreshIfNeeded();
95 
96  private:
97   // Weight for a current data point in moving average.
98   static constexpr float kMovingAverageWeight = 0.3f;
99 
100   // Default value for advertise report cache to expire.
101   // Uses large enough value that it won't end soon.
102   static constexpr uint64_t kMaxExpireTimeNanoSec =
103       std::numeric_limits<uint64_t>::max();
104 
105   // Default value for threshold cache count to trigger refresh.
106   // At the worst case, roughly 2KB ( = 255 byte * 8) could be allocated for the
107   // cache elements exired.
108   static constexpr size_t kRefreshCacheCountThreshold = 8;
109 
110   chre::DynamicVector<chreBleAdvertisingReport> cache_reports_;
111   // Current cache timeout value.
112   uint64_t cache_expire_nanosec_ = kMaxExpireTimeNanoSec;
113 #ifdef NEARBY_PROFILE
114   ashProfileData profile_data_;
115 #endif
116 };
117 
118 }  // namespace nearby
119 
120 #endif  // LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_ADV_REPORT_CACHE_H_
121