• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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