1 /* 2 * Copyright (c) 2021 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 UTILS_BASE_SAFE_MAP_H 17 #define UTILS_BASE_SAFE_MAP_H 18 19 #include <map> 20 #include <mutex> 21 22 namespace OHOS { 23 24 template <typename K, typename V> 25 class SafeMap { 26 public: SafeMap()27 SafeMap() {} 28 ~SafeMap()29 ~SafeMap() {} 30 SafeMap(const SafeMap & rhs)31 SafeMap(const SafeMap& rhs) 32 { 33 map_ = rhs.map_; 34 } 35 36 SafeMap& operator=(const SafeMap& rhs) 37 { 38 if (&rhs != this) { 39 map_ = rhs.map_; 40 } 41 42 return *this; 43 } 44 45 V& operator[](const K& key) 46 { 47 return map_[key]; 48 } 49 50 // when multithread calling size() return a tmp status, some threads may insert just after size() call Size()51 int Size() 52 { 53 std::lock_guard<std::mutex> lock(mutex_); 54 return map_.size(); 55 } 56 57 // when multithread calling Empty() return a tmp status, some threads may insert just after Empty() call IsEmpty()58 bool IsEmpty() 59 { 60 std::lock_guard<std::mutex> lock(mutex_); 61 return map_.empty(); 62 } 63 Insert(const K & key,const V & value)64 bool Insert(const K& key, const V& value) 65 { 66 std::lock_guard<std::mutex> lock(mutex_); 67 auto ret = map_.insert(std::pair<K, V>(key, value)); 68 return ret.second; 69 } 70 EnsureInsert(const K & key,const V & value)71 void EnsureInsert(const K& key, const V& value) 72 { 73 std::lock_guard<std::mutex> lock(mutex_); 74 auto ret = map_.insert(std::pair<K, V>(key, value)); 75 // find key and cannot insert 76 if (!ret.second) { 77 map_.erase(ret.first); 78 map_.insert(std::pair<K, V>(key, value)); 79 return; 80 } 81 return; 82 } 83 Find(const K & key,V & value)84 bool Find(const K& key, V& value) 85 { 86 bool ret = false; 87 std::lock_guard<std::mutex> lock(mutex_); 88 89 auto iter = map_.find(key); 90 if (iter != map_.end()) { 91 value = iter->second; 92 ret = true; 93 } 94 95 return ret; 96 } 97 FindOldAndSetNew(const K & key,V & oldValue,const V & newValue)98 bool FindOldAndSetNew(const K& key, V& oldValue, const V& newValue) 99 { 100 bool ret = false; 101 std::lock_guard<std::mutex> lock(mutex_); 102 if (map_.size() > 0) { 103 auto iter = map_.find(key); 104 if (iter != map_.end()) { 105 oldValue = iter->second; 106 map_.erase(iter); 107 map_.insert(std::pair<K, V>(key, newValue)); 108 ret = true; 109 } 110 } 111 112 return ret; 113 } 114 Erase(const K & key)115 void Erase(const K& key) 116 { 117 std::lock_guard<std::mutex> lock(mutex_); 118 map_.erase(key); 119 } 120 Clear()121 void Clear() 122 { 123 std::lock_guard<std::mutex> lock(mutex_); 124 map_.clear(); 125 return; 126 } 127 128 using SafeMapCallBack = std::function<void(const K, V&)>; 129 Iterate(const SafeMapCallBack & callback)130 void Iterate(const SafeMapCallBack& callback) 131 { 132 std::lock_guard<std::mutex> lock(mutex_); 133 if (!map_.empty()) { 134 for (auto it = map_.begin(); it != map_.end(); it++) { 135 callback(it -> first, it -> second); 136 } 137 } 138 } 139 140 private: 141 std::mutex mutex_; 142 std::map<K, V> map_; 143 }; 144 145 } // namespace OHOS 146 #endif 147