SimpleMap.h (2932B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef mozilla_SimpleMap_h 6 #define mozilla_SimpleMap_h 7 8 #include <utility> 9 10 #include "mozilla/Maybe.h" 11 #include "mozilla/Mutex.h" 12 #include "nsTArray.h" 13 14 namespace mozilla { 15 16 struct ThreadSafePolicy { 17 struct PolicyLock { 18 explicit PolicyLock(const char* aName) : mMutex(aName) {} 19 Mutex mMutex MOZ_UNANNOTATED; 20 }; 21 PolicyLock& mPolicyLock; 22 explicit ThreadSafePolicy(PolicyLock& aPolicyLock) 23 : mPolicyLock(aPolicyLock) { 24 mPolicyLock.mMutex.Lock(); 25 } 26 ~ThreadSafePolicy() { mPolicyLock.mMutex.Unlock(); } 27 }; 28 29 struct NoOpPolicy { 30 struct PolicyLock { 31 explicit PolicyLock(const char*) {} 32 }; 33 explicit NoOpPolicy(PolicyLock&) {} 34 ~NoOpPolicy() = default; 35 }; 36 37 // An map employing an array instead of a hash table to optimize performance, 38 // particularly beneficial when the number of expected items in the map is 39 // small. 40 template <typename K, typename V, typename Policy = NoOpPolicy> 41 class SimpleMap { 42 using ElementType = std::pair<K, V>; 43 using MapType = AutoTArray<ElementType, 16>; 44 45 public: 46 SimpleMap() : mLock("SimpleMap") {}; 47 48 // Check if aKey is in the map. 49 bool Contains(const K& aKey) { 50 struct Comparator { 51 bool Equals(const ElementType& aElement, const K& aKey) const { 52 return aElement.first == aKey; 53 } 54 }; 55 Policy guard(mLock); 56 return mMap.Contains(aKey, Comparator()); 57 } 58 // Insert Key and Value pair at the end of our map. 59 void Insert(const K& aKey, const V& aValue) { 60 Policy guard(mLock); 61 mMap.AppendElement(std::make_pair(aKey, aValue)); 62 } 63 // Sets aValue matching aKey and remove it from the map if found. 64 // The element returned is the first one found. 65 // Returns true if found, false otherwise. 66 bool Find(const K& aKey, V& aValue) { 67 if (Maybe<V> v = Take(aKey)) { 68 aValue = v.extract(); 69 return true; 70 } 71 return false; 72 } 73 // Take the value matching aKey and remove it from the map if found. 74 Maybe<V> Take(const K& aKey) { 75 Policy guard(mLock); 76 for (uint32_t i = 0; i < mMap.Length(); i++) { 77 ElementType& element = mMap[i]; 78 if (element.first == aKey) { 79 Maybe<V> value = Some(element.second); 80 mMap.RemoveElementAt(i); 81 return value; 82 } 83 } 84 return Nothing(); 85 } 86 // Remove all elements of the map. 87 void Clear() { 88 Policy guard(mLock); 89 mMap.Clear(); 90 } 91 // Iterate through all elements of the map and call the function F. 92 template <typename F> 93 void ForEach(F&& aCallback) { 94 Policy guard(mLock); 95 for (const auto& element : mMap) { 96 aCallback(element.first, element.second); 97 } 98 } 99 100 private: 101 typename Policy::PolicyLock mLock; 102 MapType mMap; 103 }; 104 105 } // namespace mozilla 106 107 #endif // mozilla_SimpleMap_h