1 // Copyright (C) 2018 The Android Open Source Project
2 //
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 #include "aemu/base/Optional.h"
16 #include "aemu/base/synchronization/Lock.h"
17 
18 #include <functional>
19 #include <unordered_map>
20 
21 namespace android {
22 namespace base {
23 
24 // Static map class for use with LazyInstance or in global structures
25 // as a process-wide registry of something. Safe for concurrent accress.
26 template <class K, class V>
27 class StaticMap {
28 public:
29     StaticMap() = default;
30 
set(const K & key,const V & value)31     void set(const K& key, const V& value) {
32         AutoLock lock(mLock);
33         mItems.emplace(key, value);
34     }
35 
erase(const K & key)36     void erase(const K& key) {
37         AutoLock lock(mLock);
38         mItems.erase(key);
39     }
40 
isPresent(const K & key)41     bool isPresent(const K& key) const {
42         AutoLock lock(mLock);
43         auto it = mItems.find(key);
44         return it != mItems.end();
45     }
46 
get(const K & key)47     android::base::Optional<V> get(const K& key) const {
48         AutoLock lock(mLock);
49         auto it = mItems.find(key);
50         if (it == mItems.end()) {
51             return android::base::kNullopt;
52         }
53         return it->second;
54     }
55 
56     using ErasePredicate = std::function<bool(K, V)>;
57 
eraseIf(ErasePredicate p)58     void eraseIf(ErasePredicate p) {
59         AutoLock lock(mLock);
60         auto it = mItems.begin();
61         for (; it != mItems.end();) {
62             if (p(it->first, it->second)) {
63                 it = mItems.erase(it);
64             } else {
65                 ++it;
66             }
67         }
68     }
69 
clear()70     void clear() {
71         AutoLock lock(mLock);
72         mItems.clear();
73     }
74 private:
75     using AutoLock = android::base::AutoLock;
76     using Lock = android::base::Lock;
77 
78     mutable android::base::Lock mLock;
79     std::unordered_map<K, V> mItems;
80 };
81 
82 } // namespace base
83 } // namespace android
84