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