• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef WRITE_CONTROLLER_H
17 #define WRITE_CONTROLLER_H
18 
19 #include <list>
20 #include <mutex>
21 #include <sys/time.h>
22 #include <unordered_map>
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 static constexpr size_t DEFAULT_CACHE_CAPACITY = 30;
27 static constexpr size_t HISYSEVENT_DEFAULT_PERIOD = 5;
28 static constexpr size_t HISYSEVENT_DEFAULT_THRESHOLD = 10;
29 
30 using ControlParam = struct {
31     size_t period;
32     size_t threshold;
33 };
34 
35 template<typename K, typename V>
36 class LruCache {
37 public:
capacity(capacity)38     LruCache(int capacity = DEFAULT_CACHE_CAPACITY): capacity(capacity) {}
39 
Get(K key)40     V Get(K key)
41     {
42         V v;
43         if (key2Index.count(key) == 0) {
44             return v;
45         }
46         Modify(key);
47         return key2Index[key].value;
48     }
49 
Put(K key,V value)50     void Put(K key, V value)
51     {
52         if (key2Index.count(key) > 0) {
53             key2Index[key].value = value;
54             Modify(key);
55             return;
56         }
57         if (keyCache.size() == capacity) {
58             key2Index.erase(keyCache.back());
59             keyCache.pop_back();
60         }
61         keyCache.push_front(key);
62         key2Index[key] = {
63             .iter = keyCache.cbegin(),
64             .value = value
65         };
66     }
67 
68 private:
69     template<typename K_, typename V_>
70     struct CacheNode {
71         typename std::list<K_>::const_iterator iter;
72         V_ value;
73     };
74 
75 private:
Modify(K key)76     void Modify(K key)
77     {
78         keyCache.splice(keyCache.begin(), keyCache, key2Index[key].iter);
79         key2Index[key].iter = keyCache.cbegin();
80     }
81 
82 private:
83     size_t capacity;
84     std::unordered_map<K, CacheNode<K, V>> key2Index;
85     std::list<K> keyCache;
86 };
87 
88 class WriteController {
89 public:
90     bool CheckLimitWritingEvent(const ControlParam& param, const char* domain, const char* eventName,
91         const char* func, int64_t line);
92 
93 private:
94     struct EventLimitStat {
95         size_t count;
96         timeval begin;
97 
98     public:
EventLimitStatEventLimitStat99         EventLimitStat()
100         {
101             count = 0;
102             gettimeofday(&begin, nullptr);
103         }
104 
105     public:
IsValidEventLimitStat106         bool IsValid()
107         {
108             return count > 0;
109         }
110     };
111 
112 private:
113     std::string ConcatenateInfoAsKey(const char* eventName, const char* func, int64_t line) const;
114 
115 private:
116     std::mutex lmtMutex;
117     LruCache<std::string, EventLimitStat> lruCache;
118 };
119 } // HiviewDFX
120 } // OHOS
121 
122 #endif // WRITE_CONTROLLER_H