Coverage Report

Created: 2024-09-14 07:19

/src/skia/src/core/SkTMultiMap.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2013 Google Inc.
3
 *
4
 * Use of this source code is governed by a BSD-style license that can be
5
 * found in the LICENSE file.
6
 */
7
8
#ifndef SkTMultiMap_DEFINED
9
#define SkTMultiMap_DEFINED
10
11
#include "src/core/SkTDynamicHash.h"
12
13
/** A set that contains pointers to instances of T. Instances can be looked up with key Key.
14
 * Multiple (possibly same) values can have the same key.
15
 */
16
template <typename T,
17
          typename Key,
18
          typename HashTraits=T>
19
class SkTMultiMap {
20
    struct ValueList {
21
455k
        explicit ValueList(T* value) : fValue(value), fNext(nullptr) {}
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList::ValueList(GrResourceAllocator::Register*)
Line
Count
Source
21
210k
        explicit ValueList(T* value) : fValue(value), fNext(nullptr) {}
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList::ValueList(GrGpuResource*)
Line
Count
Source
21
244k
        explicit ValueList(T* value) : fValue(value), fNext(nullptr) {}
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList::ValueList(skgpu::graphite::Resource*)
22
23
1.24M
        static const Key& GetKey(const ValueList& e) { return HashTraits::GetKey(*e.fValue); }
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList::GetKey(SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList const&)
Line
Count
Source
23
586k
        static const Key& GetKey(const ValueList& e) { return HashTraits::GetKey(*e.fValue); }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList::GetKey(SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList const&)
Line
Count
Source
23
661k
        static const Key& GetKey(const ValueList& e) { return HashTraits::GetKey(*e.fValue); }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList::GetKey(SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList const&)
24
1.74M
        static uint32_t Hash(const Key& key) { return HashTraits::Hash(key); }
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList::Hash(skgpu::ScratchKey const&)
Line
Count
Source
24
770k
        static uint32_t Hash(const Key& key) { return HashTraits::Hash(key); }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList::Hash(skgpu::ScratchKey const&)
Line
Count
Source
24
976k
        static uint32_t Hash(const Key& key) { return HashTraits::Hash(key); }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList::Hash(skgpu::graphite::GraphiteResourceKey const&)
25
        T* fValue;
26
        ValueList* fNext;
27
    };
28
public:
29
25.7k
    SkTMultiMap() : fCount(0) {}
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::SkTMultiMap()
Line
Count
Source
29
21.3k
    SkTMultiMap() : fCount(0) {}
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::SkTMultiMap()
Line
Count
Source
29
4.32k
    SkTMultiMap() : fCount(0) {}
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::SkTMultiMap()
30
31
25.7k
    ~SkTMultiMap() {
32
25.7k
        this->reset();
33
25.7k
    }
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::~SkTMultiMap()
Line
Count
Source
31
21.3k
    ~SkTMultiMap() {
32
21.3k
        this->reset();
33
21.3k
    }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::~SkTMultiMap()
Line
Count
Source
31
4.32k
    ~SkTMultiMap() {
32
4.32k
        this->reset();
33
4.32k
    }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::~SkTMultiMap()
34
35
44.9k
    void reset() {
36
44.9k
        fHash.foreach([&](ValueList* vl) {
37
15.0k
            ValueList* next;
38
45.0k
            for (ValueList* it = vl; it; it = next) {
39
29.9k
                HashTraits::OnFree(it->fValue);
40
29.9k
                next = it->fNext;
41
29.9k
                delete it;
42
29.9k
            }
43
15.0k
        });
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::reset()::{lambda(SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList*)#1}::operator()(SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList*) const
Line
Count
Source
36
15.0k
        fHash.foreach([&](ValueList* vl) {
37
15.0k
            ValueList* next;
38
45.0k
            for (ValueList* it = vl; it; it = next) {
39
29.9k
                HashTraits::OnFree(it->fValue);
40
29.9k
                next = it->fNext;
41
29.9k
                delete it;
42
29.9k
            }
43
15.0k
        });
Unexecuted instantiation: SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::reset()::{lambda(SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList*)#1}::operator()(SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList*) const
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::reset()::{lambda(SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList*)#1}::operator()(SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList*) const
44
44.9k
        fHash.reset();
45
44.9k
        fCount = 0;
46
44.9k
    }
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::reset()
Line
Count
Source
35
40.6k
    void reset() {
36
40.6k
        fHash.foreach([&](ValueList* vl) {
37
40.6k
            ValueList* next;
38
40.6k
            for (ValueList* it = vl; it; it = next) {
39
40.6k
                HashTraits::OnFree(it->fValue);
40
40.6k
                next = it->fNext;
41
40.6k
                delete it;
42
40.6k
            }
43
40.6k
        });
44
40.6k
        fHash.reset();
45
40.6k
        fCount = 0;
46
40.6k
    }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::reset()
Line
Count
Source
35
4.32k
    void reset() {
36
4.32k
        fHash.foreach([&](ValueList* vl) {
37
4.32k
            ValueList* next;
38
4.32k
            for (ValueList* it = vl; it; it = next) {
39
4.32k
                HashTraits::OnFree(it->fValue);
40
4.32k
                next = it->fNext;
41
4.32k
                delete it;
42
4.32k
            }
43
4.32k
        });
44
4.32k
        fHash.reset();
45
4.32k
        fCount = 0;
46
4.32k
    }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::reset()
47
48
455k
    void insert(const Key& key, T* value) {
49
455k
        ValueList* list = fHash.find(key);
50
455k
        if (list) {
51
            // The new ValueList entry is inserted as the second element in the
52
            // linked list, and it will contain the value of the first element.
53
223k
            ValueList* newEntry = new ValueList(list->fValue);
54
223k
            newEntry->fNext = list->fNext;
55
            // The existing first ValueList entry is updated to contain the
56
            // inserted value.
57
223k
            list->fNext = newEntry;
58
223k
            list->fValue = value;
59
231k
        } else {
60
231k
            fHash.add(new ValueList(value));
61
231k
        }
62
63
455k
        ++fCount;
64
455k
    }
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::insert(skgpu::ScratchKey const&, GrResourceAllocator::Register*)
Line
Count
Source
48
210k
    void insert(const Key& key, T* value) {
49
210k
        ValueList* list = fHash.find(key);
50
210k
        if (list) {
51
            // The new ValueList entry is inserted as the second element in the
52
            // linked list, and it will contain the value of the first element.
53
60.4k
            ValueList* newEntry = new ValueList(list->fValue);
54
60.4k
            newEntry->fNext = list->fNext;
55
            // The existing first ValueList entry is updated to contain the
56
            // inserted value.
57
60.4k
            list->fNext = newEntry;
58
60.4k
            list->fValue = value;
59
150k
        } else {
60
150k
            fHash.add(new ValueList(value));
61
150k
        }
62
63
210k
        ++fCount;
64
210k
    }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::insert(skgpu::ScratchKey const&, GrGpuResource*)
Line
Count
Source
48
244k
    void insert(const Key& key, T* value) {
49
244k
        ValueList* list = fHash.find(key);
50
244k
        if (list) {
51
            // The new ValueList entry is inserted as the second element in the
52
            // linked list, and it will contain the value of the first element.
53
163k
            ValueList* newEntry = new ValueList(list->fValue);
54
163k
            newEntry->fNext = list->fNext;
55
            // The existing first ValueList entry is updated to contain the
56
            // inserted value.
57
163k
            list->fNext = newEntry;
58
163k
            list->fValue = value;
59
163k
        } else {
60
81.4k
            fHash.add(new ValueList(value));
61
81.4k
        }
62
63
244k
        ++fCount;
64
244k
    }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::insert(skgpu::graphite::GraphiteResourceKey const&, skgpu::graphite::Resource*)
65
66
244k
    void remove(const Key& key, const T* value) {
67
244k
        ValueList* list = fHash.find(key);
68
        // Temporarily making this safe for remove entries not in the map because of
69
        // crbug.com/877915.
70
#if 0
71
        // Since we expect the caller to be fully aware of what is stored, just
72
        // assert that the caller removes an existing value.
73
        SkASSERT(list);
74
        ValueList* prev = nullptr;
75
        while (list->fValue != value) {
76
            prev = list;
77
            list = list->fNext;
78
        }
79
        this->internalRemove(prev, list, key);
80
#else
81
244k
        ValueList* prev = nullptr;
82
41.2M
        while (list && list->fValue != value) {
83
41.0M
            prev = list;
84
41.0M
            list = list->fNext;
85
41.0M
        }
86
        // Crash in Debug since it'd be great to detect a repro of 877915.
87
244k
        SkASSERT(list);
88
244k
        if (list) {
89
244k
            this->internalRemove(prev, list, key);
90
244k
        }
91
244k
#endif
92
244k
    }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::remove(skgpu::ScratchKey const&, GrGpuResource const*)
Line
Count
Source
66
244k
    void remove(const Key& key, const T* value) {
67
244k
        ValueList* list = fHash.find(key);
68
        // Temporarily making this safe for remove entries not in the map because of
69
        // crbug.com/877915.
70
#if 0
71
        // Since we expect the caller to be fully aware of what is stored, just
72
        // assert that the caller removes an existing value.
73
        SkASSERT(list);
74
        ValueList* prev = nullptr;
75
        while (list->fValue != value) {
76
            prev = list;
77
            list = list->fNext;
78
        }
79
        this->internalRemove(prev, list, key);
80
#else
81
244k
        ValueList* prev = nullptr;
82
41.2M
        while (list && list->fValue != value) {
83
41.0M
            prev = list;
84
41.0M
            list = list->fNext;
85
41.0M
        }
86
        // Crash in Debug since it'd be great to detect a repro of 877915.
87
244k
        SkASSERT(list);
88
244k
        if (list) {
89
244k
            this->internalRemove(prev, list, key);
90
244k
        }
91
244k
#endif
92
244k
    }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::remove(skgpu::graphite::GraphiteResourceKey const&, skgpu::graphite::Resource const*)
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::remove(skgpu::graphite::GraphiteResourceKey const&, skgpu::graphite::Resource const*)
93
94
279k
    T* find(const Key& key) const {
95
279k
        ValueList* list = fHash.find(key);
96
279k
        if (list) {
97
45.2k
            return list->fValue;
98
45.2k
        }
99
234k
        return nullptr;
100
279k
    }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::find(skgpu::ScratchKey const&) const
Line
Count
Source
94
279k
    T* find(const Key& key) const {
95
279k
        ValueList* list = fHash.find(key);
96
279k
        if (list) {
97
45.2k
            return list->fValue;
98
45.2k
        }
99
234k
        return nullptr;
100
279k
    }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::find(skgpu::graphite::GraphiteResourceKey const&) const
101
102
    template<class FindPredicate>
103
    T* find(const Key& key, const FindPredicate f) {
104
        ValueList* list = fHash.find(key);
105
        while (list) {
106
            if (f(list->fValue)){
107
                return list->fValue;
108
            }
109
            list = list->fNext;
110
        }
111
        return nullptr;
112
    }
113
114
    template<class FindPredicate>
115
214k
    T* findAndRemove(const Key& key, const FindPredicate f) {
116
214k
        ValueList* list = fHash.find(key);
117
118
214k
        ValueList* prev = nullptr;
119
214k
        while (list) {
120
181k
            if (f(list->fValue)){
121
181k
                T* value = list->fValue;
122
181k
                this->internalRemove(prev, list, key);
123
181k
                return value;
124
181k
            }
125
0
            prev = list;
126
0
            list = list->fNext;
127
0
        }
128
33.2k
        return nullptr;
129
214k
    }
130
131
0
    int count() const { return fCount; }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::count() const
Unexecuted instantiation: SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::count() const
132
133
#ifdef SK_DEBUG
134
    template <typename Fn>  // f(T) or f(const T&)
135
0
    void foreach(Fn&& fn) const {
136
0
        fHash.foreach([&](const ValueList& vl) {
137
0
            for (const ValueList* it = &vl; it; it = it->fNext) {
138
0
                fn(*it->fValue);
139
0
            }
140
0
        });
Unexecuted instantiation: GrResourceCache.cpp:SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::foreach<GrResourceCache::validate() const::$_0>(GrResourceCache::validate() const::$_0&&) const::{lambda(SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList const&)#1}::operator()(SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList const&) const
Unexecuted instantiation: ResourceCache.cpp:SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::foreach<skgpu::graphite::ResourceCache::validate() const::$_0>(skgpu::graphite::ResourceCache::validate() const::$_0&&) const::{lambda(SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList const&)#1}::operator()(SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList const&) const
141
0
    }
Unexecuted instantiation: GrResourceCache.cpp:void SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::foreach<GrResourceCache::validate() const::$_0>(GrResourceCache::validate() const::$_0&&) const
Unexecuted instantiation: ResourceCache.cpp:void SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::foreach<skgpu::graphite::ResourceCache::validate() const::$_0>(skgpu::graphite::ResourceCache::validate() const::$_0&&) const
142
143
0
    bool has(const T* value, const Key& key) const {
144
0
        for (ValueList* list = fHash.find(key); list; list = list->fNext) {
145
0
            if (list->fValue == value) {
146
0
                return true;
147
0
            }
148
0
        }
149
0
        return false;
150
0
    }
Unexecuted instantiation: SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::has(GrGpuResource const*, skgpu::ScratchKey const&) const
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::has(skgpu::graphite::Resource const*, skgpu::graphite::GraphiteResourceKey const&) const
151
152
    // This is not particularly fast and only used for validation, so debug only.
153
0
    int countForKey(const Key& key) const {
154
0
        int count = 0;
155
0
        ValueList* list = fHash.find(key);
156
0
        while (list) {
157
0
            list = list->fNext;
158
0
            ++count;
159
0
        }
160
0
        return count;
161
0
    }
162
#endif
163
164
private:
165
    SkTDynamicHash<ValueList, Key> fHash;
166
    int fCount;
167
168
425k
    void internalRemove(ValueList* prev, ValueList* elem, const Key& key) {
169
425k
        if (elem->fNext) {
170
76.8k
            ValueList* next = elem->fNext;
171
76.8k
            elem->fValue = next->fValue;
172
76.8k
            elem->fNext = next->fNext;
173
76.8k
            delete next;
174
348k
        } else if (prev) {
175
131k
            prev->fNext = nullptr;
176
131k
            delete elem;
177
216k
        } else {
178
216k
            fHash.remove(key);
179
216k
            delete elem;
180
216k
        }
181
182
425k
        --fCount;
183
425k
    }
SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::internalRemove(SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList*, SkTMultiMap<GrResourceAllocator::Register, skgpu::ScratchKey, GrResourceAllocator::FreePoolTraits>::ValueList*, skgpu::ScratchKey const&)
Line
Count
Source
168
181k
    void internalRemove(ValueList* prev, ValueList* elem, const Key& key) {
169
181k
        if (elem->fNext) {
170
45.5k
            ValueList* next = elem->fNext;
171
45.5k
            elem->fValue = next->fValue;
172
45.5k
            elem->fNext = next->fNext;
173
45.5k
            delete next;
174
135k
        } else if (prev) {
175
0
            prev->fNext = nullptr;
176
0
            delete elem;
177
135k
        } else {
178
135k
            fHash.remove(key);
179
135k
            delete elem;
180
135k
        }
181
182
181k
        --fCount;
183
181k
    }
SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::internalRemove(SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList*, SkTMultiMap<GrGpuResource, skgpu::ScratchKey, GrResourceCache::ScratchMapTraits>::ValueList*, skgpu::ScratchKey const&)
Line
Count
Source
168
244k
    void internalRemove(ValueList* prev, ValueList* elem, const Key& key) {
169
244k
        if (elem->fNext) {
170
31.2k
            ValueList* next = elem->fNext;
171
31.2k
            elem->fValue = next->fValue;
172
31.2k
            elem->fNext = next->fNext;
173
31.2k
            delete next;
174
213k
        } else if (prev) {
175
131k
            prev->fNext = nullptr;
176
131k
            delete elem;
177
131k
        } else {
178
81.4k
            fHash.remove(key);
179
81.4k
            delete elem;
180
81.4k
        }
181
182
244k
        --fCount;
183
244k
    }
Unexecuted instantiation: SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::internalRemove(SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList*, SkTMultiMap<skgpu::graphite::Resource, skgpu::graphite::GraphiteResourceKey, skgpu::graphite::ResourceCache::MapTraits>::ValueList*, skgpu::graphite::GraphiteResourceKey const&)
184
185
};
186
187
#endif