/work/obj-fuzz/dist/include/mozilla/MruCache.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef mozilla_MruCache_h |
8 | | #define mozilla_MruCache_h |
9 | | |
10 | | #include <cstdint> |
11 | | #include <type_traits> |
12 | | #include <utility> |
13 | | |
14 | | #include "mozilla/Attributes.h" |
15 | | #include "mozilla/HashFunctions.h" |
16 | | |
17 | | namespace mozilla { |
18 | | |
19 | | namespace detail { |
20 | | |
21 | | // Helper struct for checking if a value is empty. |
22 | | // |
23 | | // `IsNotEmpty` will return true if `Value` is not a pointer type or if the |
24 | | // pointer value is not null. |
25 | | template <typename Value, bool IsPtr = std::is_pointer<Value>::value> |
26 | | struct EmptyChecker |
27 | | { |
28 | 0 | static bool IsNotEmpty(const Value&) { return true; } Unexecuted instantiation: mozilla::detail::EmptyChecker<nsEffectiveTLDService::TLDCacheEntry, false>::IsNotEmpty(nsEffectiveTLDService::TLDCacheEntry const&) Unexecuted instantiation: mozilla::detail::EmptyChecker<int, false>::IsNotEmpty(int const&) Unexecuted instantiation: mozilla::detail::EmptyChecker<StringStruct, false>::IsNotEmpty(StringStruct const&) |
29 | | }; |
30 | | // Template specialization for the `IsPtr == true` case. |
31 | | template <typename Value> |
32 | | struct EmptyChecker<Value, true> |
33 | | { |
34 | 0 | static bool IsNotEmpty(const Value& aVal) { return aVal != nullptr; } Unexecuted instantiation: mozilla::detail::EmptyChecker<PtrInfo*, true>::IsNotEmpty(PtrInfo* const&) Unexecuted instantiation: mozilla::detail::EmptyChecker<nsAtom*, true>::IsNotEmpty(nsAtom* const&) Unexecuted instantiation: mozilla::detail::EmptyChecker<nsContentList*, true>::IsNotEmpty(nsContentList* const&) Unexecuted instantiation: mozilla::detail::EmptyChecker<mozilla::dom::NodeInfo*, true>::IsNotEmpty(mozilla::dom::NodeInfo* const&) Unexecuted instantiation: mozilla::detail::EmptyChecker<char const*, true>::IsNotEmpty(char const* const&) Unexecuted instantiation: mozilla::detail::EmptyChecker<int*, true>::IsNotEmpty(int* const&) |
35 | | }; |
36 | | |
37 | | } // namespace detail |
38 | | |
39 | | // Provides a most recently used cache that can be used as a layer on top of |
40 | | // a larger container where lookups can be expensive. The default size is 31, |
41 | | // which as a prime number provides a better distrubution of cached entries. |
42 | | // |
43 | | // Users are expected to provide a `Cache` class that defines two required |
44 | | // methods: |
45 | | // - A method for providing the hash of a key: |
46 | | // |
47 | | // static HashNumber Hash(const KeyType& aKey) |
48 | | // |
49 | | // - A method for matching a key to a value, for pointer types the value |
50 | | // is guaranteed not to be null. |
51 | | // |
52 | | // static bool Match(const KeyType& aKey, const ValueType& aVal) |
53 | | // |
54 | | // For example: |
55 | | // class MruExample : public MruCache<void*, PtrInfo*, MruExample> |
56 | | // { |
57 | | // static HashNumber Hash(const KeyType& aKey) |
58 | | // { |
59 | | // return HashGeneric(aKey); |
60 | | // } |
61 | | // static Match(const KeyType& aKey, const ValueType& aVal) |
62 | | // { |
63 | | // return aVal->mPtr == aKey; |
64 | | // } |
65 | | // }; |
66 | | template <class Key, class Value, class Cache, size_t Size=31> |
67 | | class MruCache |
68 | | { |
69 | | // Best distribution is achieved with a prime number. Ideally the closest |
70 | | // to a power of two will be the most efficient use of memory. This |
71 | | // assertion is pretty weak, but should catch the common inclination to |
72 | | // use a power-of-two. |
73 | | static_assert(Size % 2 != 0, "Use a prime number"); |
74 | | |
75 | | // This is a stronger assertion but significantly limits the values to just |
76 | | // those close to a power-of-two value. |
77 | | //static_assert(Size == 7 || Size == 13 || Size == 31 || Size == 61 || |
78 | | // Size == 127 || Size == 251 || Size == 509 || Size == 1021, |
79 | | // "Use a prime number less than 1024"); |
80 | | |
81 | | public: |
82 | | using KeyType = Key; |
83 | | using ValueType = Value; |
84 | | |
85 | 0 | MruCache() = default; Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::MruCache() Unexecuted instantiation: mozilla::MruCache<nsTSubstring<char>, nsEffectiveTLDService::TLDCacheEntry, nsEffectiveTLDService::TldCache, 31ul>::MruCache() Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::MruCache() Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::MruCache() Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::MruCache() Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::MruCache() |
86 | | MruCache(const MruCache&) = delete; |
87 | | MruCache(const MruCache&&) = delete; |
88 | | |
89 | | // Inserts the given value into the cache. Potentially overwrites an |
90 | | // existing entry. |
91 | | template <typename U> |
92 | | void Put(const KeyType& aKey, U&& aVal) |
93 | 0 | { |
94 | 0 | *RawEntry(aKey) = std::forward<U>(aVal); |
95 | 0 | } Unexecuted instantiation: void mozilla::MruCache<int, int, IntMap, 31ul>::Put<int&>(int const&, int&) Unexecuted instantiation: void mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Put<Convertable<int*>&>(unsigned long const&, Convertable<int*>&) Unexecuted instantiation: void mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Put<int*>(unsigned long const&, int*&&) Unexecuted instantiation: void mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Put<StringStruct>(nsTString<char> const&, StringStruct&&) Unexecuted instantiation: void mozilla::MruCache<int, int, IntMap, 31ul>::Put<int>(int const&, int&&) |
96 | | |
97 | | // Removes the given entry if it is in the cache. |
98 | | void Remove(const KeyType& aKey) |
99 | 0 | { |
100 | 0 | Lookup(aKey).Remove(); |
101 | 0 | } Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::Remove(void* const&) Unexecuted instantiation: mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::Remove(nsContentListKey const&) Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::Remove(mozilla::dom::NodeInfo::NodeInfoInner const&) Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::Remove(int const&) Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Remove(unsigned long const&) Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Remove(nsTString<char> const&) |
102 | | |
103 | | // Clears all cached entries and resets them to a default value. |
104 | | void Clear() |
105 | 0 | { |
106 | 0 | for (ValueType& val : mCache) { |
107 | 0 | val = ValueType{}; |
108 | 0 | } |
109 | 0 | } Unexecuted instantiation: mozilla::MruCache<AtomTableKey, nsAtom*, AtomCache, 31ul>::Clear() Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::Clear() |
110 | | |
111 | | // Helper that holds an entry that matched a lookup key. Usage: |
112 | | // |
113 | | // auto p = mCache.Lookup(aKey); |
114 | | // if (p) { |
115 | | // return p.Data(); |
116 | | // } |
117 | | // |
118 | | // auto foo = new Foo(); |
119 | | // mTable.Insert(aKey, foo); |
120 | | // p.Set(foo); |
121 | | // return foo; |
122 | | class Entry |
123 | | { |
124 | | public: |
125 | | Entry(ValueType* aEntry, bool aMatch) |
126 | | : mEntry(aEntry) |
127 | | , mMatch(aMatch) |
128 | 0 | { |
129 | 0 | MOZ_ASSERT(mEntry); |
130 | 0 | } Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::Entry::Entry(PtrInfo**, bool) Unexecuted instantiation: mozilla::MruCache<AtomTableKey, nsAtom*, AtomCache, 31ul>::Entry::Entry(nsAtom**, bool) Unexecuted instantiation: mozilla::MruCache<nsTSubstring<char>, nsEffectiveTLDService::TLDCacheEntry, nsEffectiveTLDService::TldCache, 31ul>::Entry::Entry(nsEffectiveTLDService::TLDCacheEntry*, bool) Unexecuted instantiation: mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::Entry::Entry(nsContentList**, bool) Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::Entry::Entry(mozilla::dom::NodeInfo**, bool) Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::Entry::Entry(int*, bool) Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Entry::Entry(int**, bool) Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Entry::Entry(StringStruct*, bool) |
131 | | |
132 | 0 | explicit operator bool() const { return mMatch; } Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::Entry::operator bool() const Unexecuted instantiation: mozilla::MruCache<AtomTableKey, nsAtom*, AtomCache, 31ul>::Entry::operator bool() const Unexecuted instantiation: mozilla::MruCache<nsTSubstring<char>, nsEffectiveTLDService::TLDCacheEntry, nsEffectiveTLDService::TldCache, 31ul>::Entry::operator bool() const Unexecuted instantiation: mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::Entry::operator bool() const Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::Entry::operator bool() const Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::Entry::operator bool() const Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Entry::operator bool() const Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Entry::operator bool() const |
133 | | |
134 | | ValueType& Data() const |
135 | 0 | { |
136 | 0 | MOZ_ASSERT(mMatch); |
137 | 0 | return *mEntry; |
138 | 0 | } Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::Entry::Data() const Unexecuted instantiation: mozilla::MruCache<AtomTableKey, nsAtom*, AtomCache, 31ul>::Entry::Data() const Unexecuted instantiation: mozilla::MruCache<nsTSubstring<char>, nsEffectiveTLDService::TLDCacheEntry, nsEffectiveTLDService::TldCache, 31ul>::Entry::Data() const Unexecuted instantiation: mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::Entry::Data() const Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::Entry::Data() const Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::Entry::Data() const Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Entry::Data() const Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Entry::Data() const |
139 | | |
140 | | template<typename U> |
141 | | void Set(U&& aValue) |
142 | 0 | { |
143 | 0 | mMatch = true; |
144 | 0 | Data() = std::forward<U>(aValue); |
145 | 0 | } Unexecuted instantiation: void mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::Entry::Set<PtrInfo*&>(PtrInfo*&) Unexecuted instantiation: void mozilla::MruCache<AtomTableKey, nsAtom*, AtomCache, 31ul>::Entry::Set<RefPtr<nsAtom>&>(RefPtr<nsAtom>&) Unexecuted instantiation: void mozilla::MruCache<nsTSubstring<char>, nsEffectiveTLDService::TLDCacheEntry, nsEffectiveTLDService::TldCache, 31ul>::Entry::Set<nsEffectiveTLDService::TLDCacheEntry>(nsEffectiveTLDService::TLDCacheEntry&&) Unexecuted instantiation: void mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::Entry::Set<RefPtr<nsContentList>&>(RefPtr<nsContentList>&) Unexecuted instantiation: void mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::Entry::Set<RefPtr<mozilla::dom::NodeInfo>&>(RefPtr<mozilla::dom::NodeInfo>&) Unexecuted instantiation: void mozilla::MruCache<int, int, IntMap, 31ul>::Entry::Set<int>(int&&) Unexecuted instantiation: void mozilla::MruCache<int, int, IntMap, 31ul>::Entry::Set<Convertable<int>&>(Convertable<int>&) Unexecuted instantiation: void mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Entry::Set<StringStruct>(StringStruct&&) |
146 | | |
147 | | void Remove() |
148 | 0 | { |
149 | 0 | if (mMatch) { |
150 | 0 | Data() = ValueType{}; |
151 | 0 | mMatch = false; |
152 | 0 | } |
153 | 0 | } Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::Entry::Remove() Unexecuted instantiation: mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::Entry::Remove() Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::Entry::Remove() Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Entry::Remove() Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Entry::Remove() Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::Entry::Remove() |
154 | | |
155 | | private: |
156 | | ValueType* mEntry; // Location of the entry in the cache. |
157 | | bool mMatch; // Whether the value matched. |
158 | | }; |
159 | | |
160 | | // Retrieves an entry from the cache. Can be used to test if an entry is |
161 | | // present, update the entry to a new value, or remove the entry if one was |
162 | | // matched. |
163 | | Entry Lookup(const KeyType& aKey) |
164 | 0 | { |
165 | 0 | using EmptyChecker = detail::EmptyChecker<ValueType>; |
166 | 0 |
|
167 | 0 | auto entry = RawEntry(aKey); |
168 | 0 | bool match = EmptyChecker::IsNotEmpty(*entry) && Cache::Match(aKey, *entry); |
169 | 0 | return Entry(entry, match); |
170 | 0 | } Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::Lookup(void* const&) Unexecuted instantiation: mozilla::MruCache<AtomTableKey, nsAtom*, AtomCache, 31ul>::Lookup(AtomTableKey const&) Unexecuted instantiation: mozilla::MruCache<nsTSubstring<char>, nsEffectiveTLDService::TLDCacheEntry, nsEffectiveTLDService::TldCache, 31ul>::Lookup(nsTSubstring<char> const&) Unexecuted instantiation: mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::Lookup(nsContentListKey const&) Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::Lookup(mozilla::dom::NodeInfo::NodeInfoInner const&) Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::Lookup(int const&) Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::Lookup(unsigned long const&) Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::Lookup(nsTString<char> const&) |
171 | | |
172 | | private: |
173 | | MOZ_ALWAYS_INLINE ValueType* RawEntry(const KeyType& aKey) |
174 | 0 | { |
175 | 0 | return &mCache[Cache::Hash(aKey) % Size]; |
176 | 0 | } Unexecuted instantiation: mozilla::MruCache<void*, PtrInfo*, CCGraphBuilder::PtrInfoCache, 491ul>::RawEntry(void* const&) Unexecuted instantiation: mozilla::MruCache<AtomTableKey, nsAtom*, AtomCache, 31ul>::RawEntry(AtomTableKey const&) Unexecuted instantiation: mozilla::MruCache<nsTSubstring<char>, nsEffectiveTLDService::TLDCacheEntry, nsEffectiveTLDService::TldCache, 31ul>::RawEntry(nsTSubstring<char> const&) Unexecuted instantiation: mozilla::MruCache<nsContentListKey, nsContentList*, ContentListCache, 31ul>::RawEntry(nsContentListKey const&) Unexecuted instantiation: mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, mozilla::dom::NodeInfo*, nsNodeInfoManager::NodeInfoCache, 31ul>::RawEntry(mozilla::dom::NodeInfo::NodeInfoInner const&) Unexecuted instantiation: mozilla::MruCache<int, int, IntMap, 31ul>::RawEntry(int const&) Unexecuted instantiation: mozilla::MruCache<unsigned long, int*, UintPtrMap, 31ul>::RawEntry(unsigned long const&) Unexecuted instantiation: mozilla::MruCache<nsTString<char>, StringStruct, StringStructMap, 31ul>::RawEntry(nsTString<char> const&) |
177 | | |
178 | | ValueType mCache[Size] = {}; |
179 | | }; |
180 | | |
181 | | } // namespace mozilla |
182 | | |
183 | | #endif // mozilla_mrucache_h |