/src/mozilla-central/dom/canvas/CacheMap.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 13; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* vim: set ts=13 sts=4 et sw=4 tw=90: */ |
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_CACHE_MAP_H_ |
8 | | #define MOZILLA_CACHE_MAP_H_ |
9 | | |
10 | | #include "mozilla/UniquePtr.h" |
11 | | #include <map> |
12 | | #include <unordered_set> |
13 | | #include <vector> |
14 | | |
15 | | namespace mozilla { |
16 | | |
17 | | namespace detail { |
18 | | class CacheMapUntypedEntry; |
19 | | } |
20 | | |
21 | | class CacheMapInvalidator |
22 | | { |
23 | | friend class detail::CacheMapUntypedEntry; |
24 | | |
25 | | mutable std::unordered_set<const detail::CacheMapUntypedEntry*> mCacheEntries; |
26 | | |
27 | | public: |
28 | 0 | ~CacheMapInvalidator() { |
29 | 0 | InvalidateCaches(); |
30 | 0 | } |
31 | | |
32 | | void InvalidateCaches() const; |
33 | | }; |
34 | | |
35 | | namespace detail { |
36 | | |
37 | | class CacheMapUntypedEntry |
38 | | { |
39 | | template<typename, typename> friend class CacheMap; |
40 | | |
41 | | private: |
42 | | const std::vector<const CacheMapInvalidator*> mInvalidators; |
43 | | |
44 | | protected: |
45 | | CacheMapUntypedEntry(std::vector<const CacheMapInvalidator*>&& invalidators); |
46 | | ~CacheMapUntypedEntry(); |
47 | | |
48 | | public: |
49 | | virtual void Invalidate() const = 0; |
50 | | }; |
51 | | |
52 | | struct DerefLess final { |
53 | | template<typename T> |
54 | 0 | bool operator ()(const T* const a, const T* const b) const { |
55 | 0 | return *a < *b; |
56 | 0 | } |
57 | | }; |
58 | | |
59 | | } // namespace detail |
60 | | |
61 | | |
62 | | template<typename KeyT, typename ValueT> |
63 | | class CacheMap final |
64 | | { |
65 | | class Entry final : public detail::CacheMapUntypedEntry { |
66 | | public: |
67 | | CacheMap& mParent; |
68 | | const KeyT mKey; |
69 | | const ValueT mValue; |
70 | | |
71 | | Entry(std::vector<const CacheMapInvalidator*>&& invalidators, CacheMap& parent, |
72 | | KeyT&& key, ValueT&& value) |
73 | | : detail::CacheMapUntypedEntry(std::move(invalidators)) |
74 | | , mParent(parent) |
75 | | , mKey(std::move(key)) |
76 | | , mValue(std::move(value)) |
77 | 0 | { } |
78 | | |
79 | 0 | void Invalidate() const override { |
80 | 0 | const auto erased = mParent.mMap.erase(&mKey); |
81 | 0 | MOZ_ALWAYS_TRUE( erased == 1 ); |
82 | 0 | } |
83 | | |
84 | | bool operator <(const Entry& x) const { |
85 | | return mKey < x.mKey; |
86 | | } |
87 | | }; |
88 | | |
89 | | typedef std::map<const KeyT*, UniquePtr<const Entry>, detail::DerefLess> MapT; |
90 | | MapT mMap; |
91 | | |
92 | | public: |
93 | | const ValueT* Insert(KeyT&& key, ValueT&& value, |
94 | | std::vector<const CacheMapInvalidator*>&& invalidators) |
95 | 0 | { |
96 | 0 | UniquePtr<const Entry> entry( new Entry(std::move(invalidators), *this, std::move(key), |
97 | 0 | std::move(value)) ); |
98 | 0 |
|
99 | 0 | typename MapT::value_type insertable{ |
100 | 0 | &entry->mKey, |
101 | 0 | nullptr |
102 | 0 | }; |
103 | 0 | insertable.second = std::move(entry); |
104 | 0 |
|
105 | 0 | const auto res = mMap.insert(std::move(insertable)); |
106 | 0 | const auto& didInsert = res.second; |
107 | 0 | MOZ_ALWAYS_TRUE( didInsert ); |
108 | 0 |
|
109 | 0 | const auto& itr = res.first; |
110 | 0 | return &itr->second->mValue; |
111 | 0 | } |
112 | | |
113 | 0 | const ValueT* Find(const KeyT& key) const { |
114 | 0 | const auto itr = mMap.find(&key); |
115 | 0 | if (itr == mMap.end()) |
116 | 0 | return nullptr; |
117 | 0 | |
118 | 0 | return &itr->second->mValue; |
119 | 0 | } |
120 | | |
121 | | void Invalidate() { |
122 | | while (mMap.size()) { |
123 | | const auto& itr = mMap.begin(); |
124 | | itr->second->Invalidate(); |
125 | | } |
126 | | } |
127 | | }; |
128 | | |
129 | | } // namespace mozilla |
130 | | |
131 | | #endif // MOZILLA_CACHE_MAP_H_ |