1 /*
2  * Copyright (c) 2024-2024 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 DEFERRED_PROCCESSING_LRU_CACHE_H
17 #define DEFERRED_PROCCESSING_LRU_CACHE_H
18 
19 #include <list>
20 #include <unordered_map>
21 
22 namespace OHOS {
23 namespace Media {
24 
25 template<class KeyT, class ValueT>
26 class LruCache {
27 public:
LruCache(size_t cacheSize)28     explicit LruCache(size_t cacheSize) : cacheSize_(cacheSize)
29     {
30         if (cacheSize == 0) {
31             cacheSize_ = 1;
32         }
33     }
34 
ReCacheSize(size_t cacheSize)35     void ReCacheSize(size_t cacheSize)
36     {
37         if (cacheSize == 0) {
38             return;
39         }
40         cacheSize_ = cacheSize;
41         Clean();
42     }
43 
Refer(const KeyT & key,const ValueT & val)44     void Refer(const KeyT& key, const ValueT& val)
45     {
46         auto it = itemMap_.find(key);
47         if (it != itemMap_.end()) {
48             itemList_.erase(it->second);
49             itemMap_.erase(it);
50         }
51 
52         itemList_.push_front(make_pair(key, val));
53         itemMap_.insert(make_pair(key, itemList_.begin()));
54         Clean();
55     }
56 
Exist(const KeyT & key)57     bool Exist(const KeyT& key)
58     {
59         return itemMap_.find(key) != itemMap_.end();
60     }
61 
Update(const KeyT & keyOld,const KeyT & keyNew,const ValueT & val)62     void Update(const KeyT& keyOld, const KeyT& keyNew, const ValueT& val)
63     {
64         auto it = itemMap_.find(keyOld);
65         if (it == itemMap_.end()) {
66             return;
67         }
68         auto listPos = it->second;
69         listPos->first = keyNew;
70         listPos->second = val;
71         it->second->first = keyNew;
72         itemMap_.erase(it);
73         itemMap_.insert(make_pair(keyNew, listPos));
74     }
75 
Delete(const KeyT & key)76     void Delete(const KeyT& key)
77     {
78         auto it = itemMap_.find(key);
79         if (it == itemMap_.end()) {
80             return;
81         }
82         itemList_.erase(it->second);
83         itemMap_.erase(it);
84     }
85 
GetLruNode(KeyT & key,ValueT & value)86     bool GetLruNode(KeyT& key, ValueT& value)
87     {
88         if (itemList_.empty()) {
89             return false;
90         }
91         auto& back = itemList_.back();
92         key = back.first;
93         value = back.second;
94         return true;
95     }
96 
Reset()97     void Reset()
98     {
99         itemList_.clear();
100         itemMap_.clear();
101     }
102 
Display(std::function<void (const KeyT & key,const ValueT & value)> showInfo)103     void Display(std::function<void(const KeyT& key, const ValueT& value)> showInfo)
104     {
105         for (auto& item : itemList_) {
106             showInfo(item.first, item.second);
107         }
108     }
109 
Check()110     bool Check()
111     {
112         if (itemList_.size() != itemMap_.size()) {
113             return false;
114         }
115         for (auto& item : itemList_) {
116             auto it = itemMap_.find(item.first);
117             if (it == itemMap_.end()) {
118                 return false;
119             }
120             if (it->second == itemList_.end()) {
121                 return false;
122             }
123             if (item != *it->second) {
124                 return false;
125             }
126         }
127         return true;
128     }
129 
130 private:
Clean()131     void Clean()
132     {
133         while (itemMap_.size() > cacheSize_) {
134             auto last_it = itemList_.end();
135             last_it--;
136             itemMap_.erase(last_it->first);
137             itemList_.pop_back();
138         }
139     }
140 
141 private:
142     std::list<std::pair<KeyT, ValueT>> itemList_;
143     std::unordered_map<KeyT, decltype(itemList_.begin())> itemMap_;
144     size_t cacheSize_;
145 };
146 } // namespace Media
147 } // namespace OHOS
148 #endif //DEFERRED_PROCCESSING_LRU_CACHE_H