Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(743)

Side by Side Diff: include/private/SkTHash.h

Issue 2253993002: SkPDF: cache metrics once. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/pdf/SkPDFCanon.h » ('j') | src/pdf/SkPDFCanon.cpp » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkTHash_DEFINED 8 #ifndef SkTHash_DEFINED
9 #define SkTHash_DEFINED 9 #define SkTHash_DEFINED
10 10
(...skipping 30 matching lines...) Expand all
41 // !!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!! !!!! 41 // !!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!! !!!!
42 // set(), find() and foreach() all allow mutable access to table entries. 42 // set(), find() and foreach() all allow mutable access to table entries.
43 // If you change an entry so that it no longer has the same key, all hell 43 // If you change an entry so that it no longer has the same key, all hell
44 // will break loose. Do not do that! 44 // will break loose. Do not do that!
45 // 45 //
46 // Please prefer to use SkTHashMap or SkTHashSet, which do not have this dan ger. 46 // Please prefer to use SkTHashMap or SkTHashSet, which do not have this dan ger.
47 47
48 // The pointers returned by set() and find() are valid only until the next c all to set(). 48 // The pointers returned by set() and find() are valid only until the next c all to set().
49 // The pointers you receive in foreach() are only valid for its duration. 49 // The pointers you receive in foreach() are only valid for its duration.
50 50
51 // Copy val into the hash table, returning a pointer to the copy now in the table. 51 // Move val into the hash table, returning a pointer to the copy now in the table.
52 // If there already is an entry in the table with the same key, we overwrite it. 52 // If there already is an entry in the table with the same key, we overwrite it.
53 T* set(const T& val) { 53 T* set(T val) {
54 if (4 * (fCount+fRemoved) >= 3 * fCapacity) { 54 if (4 * (fCount+fRemoved) >= 3 * fCapacity) {
55 this->resize(fCapacity > 0 ? fCapacity * 2 : 4); 55 this->resize(fCapacity > 0 ? fCapacity * 2 : 4);
56 } 56 }
57 return this->uncheckedSet(val); 57 return this->uncheckedSet(std::move(val));
58 } 58 }
59 59
60
60 // If there is an entry in the table with this key, return a pointer to it. If not, NULL. 61 // If there is an entry in the table with this key, return a pointer to it. If not, NULL.
61 T* find(const K& key) const { 62 T* find(const K& key) const {
62 uint32_t hash = Hash(key); 63 uint32_t hash = Hash(key);
63 int index = hash & (fCapacity-1); 64 int index = hash & (fCapacity-1);
64 for (int n = 0; n < fCapacity; n++) { 65 for (int n = 0; n < fCapacity; n++) {
65 Slot& s = fSlots[index]; 66 Slot& s = fSlots[index];
66 if (s.empty()) { 67 if (s.empty()) {
67 return NULL; 68 return NULL;
68 } 69 }
69 if (!s.removed() && hash == s.hash && key == Traits::GetKey(s.val)) { 70 if (!s.removed() && hash == s.hash && key == Traits::GetKey(s.val)) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 template <typename Fn> // f(T) or f(const T&) 110 template <typename Fn> // f(T) or f(const T&)
110 void foreach(Fn&& fn) const { 111 void foreach(Fn&& fn) const {
111 for (int i = 0; i < fCapacity; i++) { 112 for (int i = 0; i < fCapacity; i++) {
112 if (!fSlots[i].empty() && !fSlots[i].removed()) { 113 if (!fSlots[i].empty() && !fSlots[i].removed()) {
113 fn(fSlots[i].val); 114 fn(fSlots[i].val);
114 } 115 }
115 } 116 }
116 } 117 }
117 118
118 private: 119 private:
119 T* uncheckedSet(const T& val) { 120 T* uncheckedSet(T val) {
120 const K& key = Traits::GetKey(val); 121 const K& key = Traits::GetKey(val);
121 uint32_t hash = Hash(key); 122 uint32_t hash = Hash(key);
122 int index = hash & (fCapacity-1); 123 int index = hash & (fCapacity-1);
123 for (int n = 0; n < fCapacity; n++) { 124 for (int n = 0; n < fCapacity; n++) {
124 Slot& s = fSlots[index]; 125 Slot& s = fSlots[index];
125 if (s.empty() || s.removed()) { 126 if (s.empty() || s.removed()) {
126 // New entry. 127 // New entry.
127 if (s.removed()) { 128 if (s.removed()) {
128 fRemoved--; 129 fRemoved--;
129 } 130 }
130 s.val = val; 131 s.val = std::move(val);
131 s.hash = hash; 132 s.hash = hash;
132 fCount++; 133 fCount++;
133 return &s.val; 134 return &s.val;
134 } 135 }
135 if (hash == s.hash && key == Traits::GetKey(s.val)) { 136 if (hash == s.hash && key == Traits::GetKey(s.val)) {
136 // Overwrite previous entry. 137 // Overwrite previous entry.
137 // Note: this triggers extra copies when adding the same value r epeatedly. 138 // Note: this triggers extra copies when adding the same value r epeatedly.
138 s.val = val; 139 s.val = std::move(val);
139 return &s.val; 140 return &s.val;
140 } 141 }
141 index = this->next(index, n); 142 index = this->next(index, n);
142 } 143 }
143 SkASSERT(false); 144 SkASSERT(false);
144 return NULL; 145 return NULL;
145 } 146 }
146 147
147 void resize(int capacity) { 148 void resize(int capacity) {
148 int oldCapacity = fCapacity; 149 int oldCapacity = fCapacity;
149 SkDEBUGCODE(int oldCount = fCount); 150 SkDEBUGCODE(int oldCount = fCount);
150 151
151 fCount = fRemoved = 0; 152 fCount = fRemoved = 0;
152 fCapacity = capacity; 153 fCapacity = capacity;
153 SkAutoTArray<Slot> oldSlots(capacity); 154 SkAutoTArray<Slot> oldSlots(capacity);
154 oldSlots.swap(fSlots); 155 oldSlots.swap(fSlots);
155 156
156 for (int i = 0; i < oldCapacity; i++) { 157 for (int i = 0; i < oldCapacity; i++) {
157 const Slot& s = oldSlots[i]; 158 const Slot& s = oldSlots[i];
158 if (!s.empty() && !s.removed()) { 159 if (!s.empty() && !s.removed()) {
159 this->uncheckedSet(s.val); 160 this->uncheckedSet(std::move(s.val));
160 } 161 }
161 } 162 }
162 SkASSERT(fCount == oldCount); 163 SkASSERT(fCount == oldCount);
163 } 164 }
164 165
165 int next(int index, int n) const { 166 int next(int index, int n) const {
166 // A valid strategy explores all slots in [0, fCapacity) as n walks from 0 to fCapacity-1. 167 // A valid strategy explores all slots in [0, fCapacity) as n walks from 0 to fCapacity-1.
167 // Both of these strategies are valid: 168 // Both of these strategies are valid:
168 //return (index + 0 + 1) & (fCapacity-1); // Linear probing. 169 //return (index + 0 + 1) & (fCapacity-1); // Linear probing.
169 return (index + n + 1) & (fCapacity-1); // Quadratic probing. 170 return (index + n + 1) & (fCapacity-1); // Quadratic probing.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // How many key/value pairs are in the table? 203 // How many key/value pairs are in the table?
203 int count() const { return fTable.count(); } 204 int count() const { return fTable.count(); }
204 205
205 // Approximately how many bytes of memory do we use beyond sizeof(*this)? 206 // Approximately how many bytes of memory do we use beyond sizeof(*this)?
206 size_t approxBytesUsed() const { return fTable.approxBytesUsed(); } 207 size_t approxBytesUsed() const { return fTable.approxBytesUsed(); }
207 208
208 // N.B. The pointers returned by set() and find() are valid only until the n ext call to set(). 209 // N.B. The pointers returned by set() and find() are valid only until the n ext call to set().
209 210
210 // Set key to val in the table, replacing any previous value with the same k ey. 211 // Set key to val in the table, replacing any previous value with the same k ey.
211 // We copy both key and val, and return a pointer to the value copy now in t he table. 212 // We copy both key and val, and return a pointer to the value copy now in t he table.
212 V* set(const K& key, const V& val) { 213 V* set(const K& key, V val) {
213 Pair in = { key, val }; 214 Pair* out = fTable.set(Pair{ key, std::move(val) });
214 Pair* out = fTable.set(in);
215 return &out->val; 215 return &out->val;
216 } 216 }
217 217
218 // If there is key/value entry in the table with this key, return a pointer to the value. 218 // If there is key/value entry in the table with this key, return a pointer to the value.
219 // If not, return NULL. 219 // If not, return NULL.
220 V* find(const K& key) const { 220 V* find(const K& key) const {
221 if (Pair* p = fTable.find(key)) { 221 if (Pair* p = fTable.find(key)) {
222 return &p->val; 222 return &p->val;
223 } 223 }
224 return NULL; 224 return NULL;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 292
293 private: 293 private:
294 struct Traits { 294 struct Traits {
295 static const T& GetKey(const T& item) { return item; } 295 static const T& GetKey(const T& item) { return item; }
296 static uint32_t Hash(const T& item) { return HashT()(item); } 296 static uint32_t Hash(const T& item) { return HashT()(item); }
297 }; 297 };
298 SkTHashTable<T, T, Traits> fTable; 298 SkTHashTable<T, T, Traits> fTable;
299 }; 299 };
300 300
301 #endif//SkTHash_DEFINED 301 #endif//SkTHash_DEFINED
OLDNEW
« no previous file with comments | « no previous file | src/pdf/SkPDFCanon.h » ('j') | src/pdf/SkPDFCanon.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698