Coverage Report

Created: 2018-09-25 14:53

/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_