1 /* 2 * Copyright (c) 2022 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 NETMANAGER_BASE_LRU_CACHE_H 17 #define NETMANAGER_BASE_LRU_CACHE_H 18 19 #include <list> 20 #include <mutex> 21 #include <string> 22 #include <unordered_map> 23 #include <vector> 24 25 namespace OHOS::NetManagerStandard { 26 static constexpr const size_t DEFAULT_CAPABILITY = 100; 27 template <typename T> class LRUCache { 28 public: LRUCache()29 LRUCache() : capacity_(DEFAULT_CAPABILITY) {} 30 Get(const std::string & key)31 std::vector<T> Get(const std::string &key) 32 { 33 std::lock_guard<std::mutex> guard(mutex_); 34 35 if (cache_.find(key) == cache_.end()) { 36 return {}; 37 } 38 auto it = cache_[key]; 39 auto value = it->value; 40 MoveNodeToHead(it); 41 return value; 42 } 43 Put(const std::string & key,const T & value)44 void Put(const std::string &key, const T &value) 45 { 46 std::lock_guard<std::mutex> guard(mutex_); 47 48 if (cache_.find(key) == cache_.end()) { 49 AddNode(Node(key, {value})); 50 if (cache_.size() > capacity_) { 51 EraseTailNode(); 52 } 53 return; 54 } 55 56 auto it = cache_[key]; 57 it->value.emplace_back(value); 58 MoveNodeToHead(it); 59 if (cache_.size() > capacity_) { 60 EraseTailNode(); 61 } 62 } 63 Delete(const std::string & key)64 void Delete(const std::string &key) 65 { 66 std::lock_guard<std::mutex> guard(mutex_); 67 68 if (cache_.find(key) == cache_.end()) { 69 return; 70 } 71 72 auto it = cache_[key]; 73 cache_.erase(key); 74 nodeList_.erase(it); 75 } 76 Clear()77 void Clear() 78 { 79 std::lock_guard<std::mutex> guard(mutex_); 80 81 cache_.clear(); 82 nodeList_.clear(); 83 } 84 85 private: 86 struct Node { 87 std::string key; 88 std::vector<T> value; 89 90 Node() = delete; 91 NodeNode92 Node(std::string key, std::vector<T> value) : key(std::move(key)), value(std::move(value)) {} 93 }; 94 AddNode(const Node & node)95 void AddNode(const Node &node) 96 { 97 nodeList_.emplace_front(node); 98 cache_[node.key] = nodeList_.begin(); 99 } 100 MoveNodeToHead(const typename std::list<Node>::iterator & it)101 void MoveNodeToHead(const typename std::list<Node>::iterator &it) 102 { 103 std::string key = it->key; 104 auto value = it->value; 105 nodeList_.erase(it); 106 nodeList_.emplace_front(key, value); 107 cache_[key] = nodeList_.begin(); 108 } 109 EraseTailNode()110 void EraseTailNode() 111 { 112 if (nodeList_.empty()) { 113 return; 114 } 115 Node node = nodeList_.back(); 116 nodeList_.pop_back(); 117 cache_.erase(node.key); 118 } 119 120 std::mutex mutex_; 121 std::unordered_map<std::string, typename std::list<Node>::iterator> cache_; 122 std::list<Node> nodeList_; 123 size_t capacity_; 124 }; 125 } // namespace OHOS::NetManagerStandard 126 #endif // NETMANAGER_BASE_LRU_CACHE_H 127