xref: /aosp_15_r20/system/libhidl/transport/include/hidl/ConcurrentMap.h (revision 8222fbe171c3d6fadfe95119c180cf3010c392a8)
1*8222fbe1SAndroid Build Coastguard Worker /*
2*8222fbe1SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*8222fbe1SAndroid Build Coastguard Worker  *
4*8222fbe1SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8222fbe1SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8222fbe1SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8222fbe1SAndroid Build Coastguard Worker  *
8*8222fbe1SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8222fbe1SAndroid Build Coastguard Worker  *
10*8222fbe1SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8222fbe1SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8222fbe1SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8222fbe1SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8222fbe1SAndroid Build Coastguard Worker  * limitations under the License.
15*8222fbe1SAndroid Build Coastguard Worker  */
16*8222fbe1SAndroid Build Coastguard Worker #ifndef ANDROID_HIDL_CONCURRENT_MAP_H
17*8222fbe1SAndroid Build Coastguard Worker #define ANDROID_HIDL_CONCURRENT_MAP_H
18*8222fbe1SAndroid Build Coastguard Worker 
19*8222fbe1SAndroid Build Coastguard Worker #include <mutex>
20*8222fbe1SAndroid Build Coastguard Worker #include <map>
21*8222fbe1SAndroid Build Coastguard Worker 
22*8222fbe1SAndroid Build Coastguard Worker namespace android {
23*8222fbe1SAndroid Build Coastguard Worker namespace hardware {
24*8222fbe1SAndroid Build Coastguard Worker 
25*8222fbe1SAndroid Build Coastguard Worker template<typename K, typename V>
26*8222fbe1SAndroid Build Coastguard Worker class ConcurrentMap {
27*8222fbe1SAndroid Build Coastguard Worker private:
28*8222fbe1SAndroid Build Coastguard Worker     using size_type = typename std::map<K, V>::size_type;
29*8222fbe1SAndroid Build Coastguard Worker     using iterator = typename std::map<K, V>::iterator;
30*8222fbe1SAndroid Build Coastguard Worker     using const_iterator = typename std::map<K, V>::const_iterator;
31*8222fbe1SAndroid Build Coastguard Worker 
32*8222fbe1SAndroid Build Coastguard Worker public:
set(K && k,V && v)33*8222fbe1SAndroid Build Coastguard Worker     void set(K &&k, V &&v) {
34*8222fbe1SAndroid Build Coastguard Worker         std::unique_lock<std::mutex> _lock(mMutex);
35*8222fbe1SAndroid Build Coastguard Worker         mMap[std::forward<K>(k)] = std::forward<V>(v);
36*8222fbe1SAndroid Build Coastguard Worker     }
37*8222fbe1SAndroid Build Coastguard Worker 
38*8222fbe1SAndroid Build Coastguard Worker     // get with the given default value.
get(const K & k,const V & def)39*8222fbe1SAndroid Build Coastguard Worker     const V &get(const K &k, const V &def) const {
40*8222fbe1SAndroid Build Coastguard Worker         std::unique_lock<std::mutex> _lock(mMutex);
41*8222fbe1SAndroid Build Coastguard Worker         const_iterator iter = mMap.find(k);
42*8222fbe1SAndroid Build Coastguard Worker         if (iter == mMap.end()) {
43*8222fbe1SAndroid Build Coastguard Worker             return def;
44*8222fbe1SAndroid Build Coastguard Worker         }
45*8222fbe1SAndroid Build Coastguard Worker         return iter->second;
46*8222fbe1SAndroid Build Coastguard Worker     }
47*8222fbe1SAndroid Build Coastguard Worker 
erase(const K & k)48*8222fbe1SAndroid Build Coastguard Worker     size_type erase(const K &k) {
49*8222fbe1SAndroid Build Coastguard Worker         std::unique_lock<std::mutex> _lock(mMutex);
50*8222fbe1SAndroid Build Coastguard Worker         return mMap.erase(k);
51*8222fbe1SAndroid Build Coastguard Worker     }
52*8222fbe1SAndroid Build Coastguard Worker 
eraseIfEqual(const K & k,const V & v)53*8222fbe1SAndroid Build Coastguard Worker     size_type eraseIfEqual(const K& k, const V& v) {
54*8222fbe1SAndroid Build Coastguard Worker         std::unique_lock<std::mutex> _lock(mMutex);
55*8222fbe1SAndroid Build Coastguard Worker         const_iterator iter = mMap.find(k);
56*8222fbe1SAndroid Build Coastguard Worker         if (iter == mMap.end()) {
57*8222fbe1SAndroid Build Coastguard Worker             return 0;
58*8222fbe1SAndroid Build Coastguard Worker         }
59*8222fbe1SAndroid Build Coastguard Worker         if (iter->second == v) {
60*8222fbe1SAndroid Build Coastguard Worker             mMap.erase(iter);
61*8222fbe1SAndroid Build Coastguard Worker             return 1;
62*8222fbe1SAndroid Build Coastguard Worker         } else {
63*8222fbe1SAndroid Build Coastguard Worker             return 0;
64*8222fbe1SAndroid Build Coastguard Worker         }
65*8222fbe1SAndroid Build Coastguard Worker     }
66*8222fbe1SAndroid Build Coastguard Worker 
lock()67*8222fbe1SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock() { return std::unique_lock<std::mutex>(mMutex); }
68*8222fbe1SAndroid Build Coastguard Worker 
setLocked(const K & k,V && v)69*8222fbe1SAndroid Build Coastguard Worker     void setLocked(const K& k, V&& v) { mMap[k] = std::forward<V>(v); }
setLocked(const K & k,const V & v)70*8222fbe1SAndroid Build Coastguard Worker     void setLocked(const K& k, const V& v) { mMap[k] = v; }
71*8222fbe1SAndroid Build Coastguard Worker 
getLocked(const K & k,const V & def)72*8222fbe1SAndroid Build Coastguard Worker     const V& getLocked(const K& k, const V& def) const {
73*8222fbe1SAndroid Build Coastguard Worker         const_iterator iter = mMap.find(k);
74*8222fbe1SAndroid Build Coastguard Worker         if (iter == mMap.end()) {
75*8222fbe1SAndroid Build Coastguard Worker             return def;
76*8222fbe1SAndroid Build Coastguard Worker         }
77*8222fbe1SAndroid Build Coastguard Worker         return iter->second;
78*8222fbe1SAndroid Build Coastguard Worker     }
79*8222fbe1SAndroid Build Coastguard Worker 
eraseLocked(const K & k)80*8222fbe1SAndroid Build Coastguard Worker     size_type eraseLocked(const K& k) { return mMap.erase(k); }
81*8222fbe1SAndroid Build Coastguard Worker 
82*8222fbe1SAndroid Build Coastguard Worker     // the concurrent map must be locked in order to iterate over it
begin()83*8222fbe1SAndroid Build Coastguard Worker     iterator begin() { return mMap.begin(); }
end()84*8222fbe1SAndroid Build Coastguard Worker     iterator end() { return mMap.end(); }
begin()85*8222fbe1SAndroid Build Coastguard Worker     const_iterator begin() const { return mMap.begin(); }
end()86*8222fbe1SAndroid Build Coastguard Worker     const_iterator end() const { return mMap.end(); }
87*8222fbe1SAndroid Build Coastguard Worker 
88*8222fbe1SAndroid Build Coastguard Worker    private:
89*8222fbe1SAndroid Build Coastguard Worker     mutable std::mutex mMutex;
90*8222fbe1SAndroid Build Coastguard Worker     std::map<K, V> mMap;
91*8222fbe1SAndroid Build Coastguard Worker };
92*8222fbe1SAndroid Build Coastguard Worker 
93*8222fbe1SAndroid Build Coastguard Worker namespace details {
94*8222fbe1SAndroid Build Coastguard Worker 
95*8222fbe1SAndroid Build Coastguard Worker // TODO(b/69122224): remove this type and usages of it
96*8222fbe1SAndroid Build Coastguard Worker // DO NOT ADD USAGES
97*8222fbe1SAndroid Build Coastguard Worker template <typename T>
98*8222fbe1SAndroid Build Coastguard Worker class DoNotDestruct {
99*8222fbe1SAndroid Build Coastguard Worker   public:
DoNotDestruct()100*8222fbe1SAndroid Build Coastguard Worker     DoNotDestruct() { new (buffer) T(); }
get()101*8222fbe1SAndroid Build Coastguard Worker     T& get() { return *reinterpret_cast<T*>(buffer); }
102*8222fbe1SAndroid Build Coastguard Worker     T* operator->() { return reinterpret_cast<T*>(buffer); }
103*8222fbe1SAndroid Build Coastguard Worker 
104*8222fbe1SAndroid Build Coastguard Worker   private:
105*8222fbe1SAndroid Build Coastguard Worker     alignas(T) char buffer[sizeof(T)];
106*8222fbe1SAndroid Build Coastguard Worker };
107*8222fbe1SAndroid Build Coastguard Worker 
108*8222fbe1SAndroid Build Coastguard Worker }  // namespace details
109*8222fbe1SAndroid Build Coastguard Worker 
110*8222fbe1SAndroid Build Coastguard Worker }  // namespace hardware
111*8222fbe1SAndroid Build Coastguard Worker }  // namespace android
112*8222fbe1SAndroid Build Coastguard Worker 
113*8222fbe1SAndroid Build Coastguard Worker 
114*8222fbe1SAndroid Build Coastguard Worker #endif  // ANDROID_HIDL_CONCURRENT_MAP_H
115