| OLD | NEW |
| 1 #ifndef SkTHash_DEFINED | 1 #ifndef SkTHash_DEFINED |
| 2 #define SkTHash_DEFINED | 2 #define SkTHash_DEFINED |
| 3 | 3 |
| 4 #include "SkTypes.h" | 4 #include "SkTypes.h" |
| 5 #include "SkTemplates.h" | 5 #include "SkTemplates.h" |
| 6 | 6 |
| 7 // Before trying to use SkTHashTable, look below to see if SkTHashMap or SkTHash
Set works for you. | 7 // Before trying to use SkTHashTable, look below to see if SkTHashMap or SkTHash
Set works for you. |
| 8 // They're easier to use, usually perform the same, and have fewer sharp edges. | 8 // They're easier to use, usually perform the same, and have fewer sharp edges. |
| 9 | 9 |
| 10 // T and K are treated as ordinary copyable C++ types. | 10 // T and K are treated as ordinary copyable C++ types. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 if (hash == s.hash && key == Traits::GetKey(s.val)) { | 58 if (hash == s.hash && key == Traits::GetKey(s.val)) { |
| 59 return &s.val; | 59 return &s.val; |
| 60 } | 60 } |
| 61 index = this->next(index, n); | 61 index = this->next(index, n); |
| 62 } | 62 } |
| 63 SkASSERT(fCapacity == 0); | 63 SkASSERT(fCapacity == 0); |
| 64 return NULL; | 64 return NULL; |
| 65 } | 65 } |
| 66 | 66 |
| 67 // Call fn on every entry in the table. You may mutate the entries, but be
very careful. | 67 // Call fn on every entry in the table. You may mutate the entries, but be
very careful. |
| 68 template <typename Arg> | 68 template <typename Fn> // f(T*) |
| 69 void foreach(void(*fn)(T*, Arg), Arg arg) { | 69 void foreach(Fn&& fn) { |
| 70 for (int i = 0; i < fCapacity; i++) { | 70 for (int i = 0; i < fCapacity; i++) { |
| 71 Slot& s = fSlots[i]; | 71 if (!fSlots[i].empty()) { |
| 72 if (!s.empty()) { | 72 fn(&fSlots[i].val); |
| 73 fn(&s.val, arg); | |
| 74 } | 73 } |
| 75 } | 74 } |
| 76 } | 75 } |
| 76 |
| 77 // Call fn on every entry in the table. You may not mutate anything. |
| 78 template <typename Fn> // f(T) or f(const T&) |
| 79 void foreach(Fn&& fn) const { |
| 80 for (int i = 0; i < fCapacity; i++) { |
| 81 if (!fSlots[i].empty()) { |
| 82 fn(fSlots[i].val); |
| 83 } |
| 84 } |
| 85 } |
| 77 | 86 |
| 78 private: | 87 private: |
| 79 T* uncheckedSet(const T& val) { | 88 T* uncheckedSet(const T& val) { |
| 80 const K& key = Traits::GetKey(val); | 89 const K& key = Traits::GetKey(val); |
| 81 uint32_t hash = Hash(key); | 90 uint32_t hash = Hash(key); |
| 82 int index = hash & (fCapacity-1); | 91 int index = hash & (fCapacity-1); |
| 83 for (int n = 0; n < fCapacity; n++) { | 92 for (int n = 0; n < fCapacity; n++) { |
| 84 Slot& s = fSlots[index]; | 93 Slot& s = fSlots[index]; |
| 85 if (s.empty()) { | 94 if (s.empty()) { |
| 86 // New entry. | 95 // New entry. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 T val; | 147 T val; |
| 139 uint32_t hash; | 148 uint32_t hash; |
| 140 }; | 149 }; |
| 141 | 150 |
| 142 int fCount, fCapacity; | 151 int fCount, fCapacity; |
| 143 SkAutoTArray<Slot> fSlots; | 152 SkAutoTArray<Slot> fSlots; |
| 144 }; | 153 }; |
| 145 | 154 |
| 146 // Maps K->V. A more user-friendly wrapper around SkTHashTable, suitable for mo
st use cases. | 155 // Maps K->V. A more user-friendly wrapper around SkTHashTable, suitable for mo
st use cases. |
| 147 // K and V are treated as ordinary copyable C++ types, with no assumed relations
hip between the two. | 156 // K and V are treated as ordinary copyable C++ types, with no assumed relations
hip between the two. |
| 148 template <typename K, typename V, uint32_t(*HashK)(const K&)> | 157 template <typename K, typename V, uint32_t(*HashK)(const K&) = &SkGoodHash> |
| 149 class SkTHashMap : SkNoncopyable { | 158 class SkTHashMap : SkNoncopyable { |
| 150 public: | 159 public: |
| 151 SkTHashMap() {} | 160 SkTHashMap() {} |
| 152 | 161 |
| 153 // Clear the map. | 162 // Clear the map. |
| 154 void reset() { fTable.reset(); } | 163 void reset() { fTable.reset(); } |
| 155 | 164 |
| 156 // How many key/value pairs are in the table? | 165 // How many key/value pairs are in the table? |
| 157 int count() const { return fTable.count(); } | 166 int count() const { return fTable.count(); } |
| 158 | 167 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 169 // If there is key/value entry in the table with this key, return a pointer
to the value. | 178 // If there is key/value entry in the table with this key, return a pointer
to the value. |
| 170 // If not, return NULL. | 179 // If not, return NULL. |
| 171 V* find(const K& key) const { | 180 V* find(const K& key) const { |
| 172 if (Pair* p = fTable.find(key)) { | 181 if (Pair* p = fTable.find(key)) { |
| 173 return &p->val; | 182 return &p->val; |
| 174 } | 183 } |
| 175 return NULL; | 184 return NULL; |
| 176 } | 185 } |
| 177 | 186 |
| 178 // Call fn on every key/value pair in the table. You may mutate the value b
ut not the key. | 187 // Call fn on every key/value pair in the table. You may mutate the value b
ut not the key. |
| 179 void foreach(void(*fn)(K, V*)) { fTable.foreach(ForEach, fn); } | 188 template <typename Fn> // f(K, V*) or f(const K&, V*) |
| 189 void foreach(Fn&& fn) { |
| 190 fTable.foreach([&fn](Pair* p){ fn(p->key, &p->val); }); |
| 191 } |
| 192 |
| 193 // Call fn on every key/value pair in the table. You may not mutate anythin
g. |
| 194 template <typename Fn> // f(K, V), f(const K&, V), f(K, const V&) or f(cons
t K&, const V&). |
| 195 void foreach(Fn&& fn) const { |
| 196 fTable.foreach([&fn](const Pair& p){ fn(p.key, p.val); }); |
| 197 } |
| 180 | 198 |
| 181 private: | 199 private: |
| 182 struct Pair { | 200 struct Pair { |
| 183 K key; | 201 K key; |
| 184 V val; | 202 V val; |
| 185 static const K& GetKey(const Pair& p) { return p.key; } | 203 static const K& GetKey(const Pair& p) { return p.key; } |
| 186 static uint32_t Hash(const K& key) { return HashK(key); } | 204 static uint32_t Hash(const K& key) { return HashK(key); } |
| 187 }; | 205 }; |
| 188 static void ForEach(Pair* p, void (*fn)(K, V*)) { fn(p->key, &p->val); } | |
| 189 | 206 |
| 190 SkTHashTable<Pair, K> fTable; | 207 SkTHashTable<Pair, K> fTable; |
| 191 }; | 208 }; |
| 192 | 209 |
| 193 // A set of T. T is treated as an ordiary copyable C++ type. | 210 // A set of T. T is treated as an ordiary copyable C++ type. |
| 194 template <typename T, uint32_t(*HashT)(const T&)> | 211 template <typename T, uint32_t(*HashT)(const T&) = &SkGoodHash> |
| 195 class SkTHashSet : SkNoncopyable { | 212 class SkTHashSet : SkNoncopyable { |
| 196 public: | 213 public: |
| 197 SkTHashSet() {} | 214 SkTHashSet() {} |
| 198 | 215 |
| 199 // Clear the set. | 216 // Clear the set. |
| 200 void reset() { fTable.reset(); } | 217 void reset() { fTable.reset(); } |
| 201 | 218 |
| 202 // How many items are in the set? | 219 // How many items are in the set? |
| 203 int count() const { return fTable.count(); } | 220 int count() const { return fTable.count(); } |
| 204 | 221 |
| 205 // Copy an item into the set. | 222 // Copy an item into the set. |
| 206 void add(const T& item) { fTable.set(item); } | 223 void add(const T& item) { fTable.set(item); } |
| 207 | 224 |
| 208 // Is this item in the set? | 225 // Is this item in the set? |
| 209 bool contains(const T& item) const { return SkToBool(fTable.find(item)); } | 226 bool contains(const T& item) const { return SkToBool(fTable.find(item)); } |
| 210 | 227 |
| 211 private: | 228 private: |
| 212 struct Traits { | 229 struct Traits { |
| 213 static const T& GetKey(const T& item) { return item; } | 230 static const T& GetKey(const T& item) { return item; } |
| 214 static uint32_t Hash(const T& item) { return HashT(item); } | 231 static uint32_t Hash(const T& item) { return HashT(item); } |
| 215 }; | 232 }; |
| 216 SkTHashTable<T, T, Traits> fTable; | 233 SkTHashTable<T, T, Traits> fTable; |
| 217 }; | 234 }; |
| 218 | 235 |
| 219 #endif//SkTHash_DEFINED | 236 #endif//SkTHash_DEFINED |
| OLD | NEW |