Chromium Code Reviews| Index: src/core/SkTHash.h |
| diff --git a/src/core/SkTHash.h b/src/core/SkTHash.h |
| index 5e317357ed8962b311bc8ea4cd7ec76c5fb00270..2c3b58e6248af5e550c632caf1fdad8749b67c84 100644 |
| --- a/src/core/SkTHash.h |
| +++ b/src/core/SkTHash.h |
| @@ -33,7 +33,7 @@ public: |
| // Copy val into the hash table, returning a pointer to the copy now in the table. |
| // If there already is an entry in the table with the same key, we overwrite it. |
| - T* set(T val) { |
| + T* set(const T& val) { |
| if (4 * fCount >= 3 * fCapacity) { |
| this->resize(fCapacity > 0 ? fCapacity * 2 : 4); |
| } |
| @@ -41,7 +41,7 @@ public: |
| } |
| // If there is an entry in the table with this key, return a pointer to it. If not, NULL. |
| - T* find(K key) const { |
| + T* find(const K& key) const { |
| uint32_t hash = Hash(key); |
| int index = hash & (fCapacity-1); |
| for (int n = 0; n < fCapacity; n++) { |
| @@ -70,8 +70,8 @@ public: |
| } |
| private: |
| - T* uncheckedSet(T val) { |
| - K key = Traits::GetKey(val); |
| + T* uncheckedSet(const T& val) { |
| + const K& key = Traits::GetKey(val); |
| uint32_t hash = Hash(key); |
| int index = hash & (fCapacity-1); |
| for (int n = 0; n < fCapacity; n++) { |
| @@ -84,8 +84,10 @@ private: |
| return &s.val; |
| } |
| if (hash == s.hash && key == Traits::GetKey(s.val)) { |
| - // Overwrite previous entry. |
| - s.val = val; |
| + if (s.val != val) { |
|
mtklein
2015/02/13 00:37:22
Interesting. Is this one mattering? We hadn't re
f(malita)
2015/02/13 00:47:30
It avoids copies when adding the same value repeat
f(malita)
2015/02/13 01:00:54
Done.
|
| + // Overwrite previous entry. |
| + s.val = val; |
| + } |
| return &s.val; |
| } |
| index = this->next(index, n); |
| @@ -119,7 +121,7 @@ private: |
| return (index + n + 1) & (fCapacity-1); // Quadratic probing. |
| } |
| - static uint32_t Hash(K key) { |
| + static uint32_t Hash(const K& key) { |
| uint32_t hash = Traits::Hash(key); |
| return hash == 0 ? 1 : hash; // We reserve hash == 0 to mark empty slots. |
| } |
| @@ -138,7 +140,7 @@ private: |
| // Maps K->V. A more user-friendly wrapper around SkTHashTable, suitable for most use cases. |
| // K and V are treated as ordinary copyable C++ types, with no assumed relationship between the two. |
| -template <typename K, typename V, uint32_t(*HashK)(K)> |
| +template <typename K, typename V, uint32_t(*HashK)(const K&)> |
| class SkTHashMap : SkNoncopyable { |
| public: |
| SkTHashMap() {} |
| @@ -150,7 +152,7 @@ public: |
| // Set key to val in the table, replacing any previous value with the same key. |
| // We copy both key and val, and return a pointer to the value copy now in the table. |
| - V* set(K key, V val) { |
| + V* set(const K& key, const V& val) { |
| Pair in = { key, val }; |
| Pair* out = fTable.set(in); |
| return &out->val; |
| @@ -158,7 +160,7 @@ public: |
| // If there is key/value entry in the table with this key, return a pointer to the value. |
| // If not, return NULL. |
| - V* find(K key) const { |
| + V* find(const K& key) const { |
| if (Pair* p = fTable.find(key)) { |
| return &p->val; |
| } |
| @@ -172,8 +174,11 @@ private: |
| struct Pair { |
| K key; |
| V val; |
| - static K GetKey(Pair p) { return p.key; } |
| - static uint32_t Hash(K key) { return HashK(key); } |
| + static const K& GetKey(const Pair& p) { return p.key; } |
| + static uint32_t Hash(const K& key) { return HashK(key); } |
| + bool operator!=(const Pair& other) { |
| + return key != other.key || val != other.val; |
| + } |
| }; |
| static void ForEach(Pair* p, void (*fn)(K, V*)) { fn(p->key, &p->val); } |
| @@ -181,7 +186,7 @@ private: |
| }; |
| // A set of T. T is treated as an ordiary copyable C++ type. |
| -template <typename T, uint32_t(*HashT)(T)> |
| +template <typename T, uint32_t(*HashT)(const T&)> |
| class SkTHashSet : SkNoncopyable { |
| public: |
| SkTHashSet() {} |
| @@ -190,15 +195,15 @@ public: |
| int count() const { return fTable.count(); } |
| // Copy an item into the set. |
| - void add(T item) { fTable.set(item); } |
| + void add(const T& item) { fTable.set(item); } |
| // Is this item in the set? |
| - bool contains(T item) const { return SkToBool(fTable.find(item)); } |
| + bool contains(const T& item) const { return SkToBool(fTable.find(item)); } |
| private: |
| struct Traits { |
| - static T GetKey(T item) { return item; } |
| - static uint32_t Hash(T item) { return HashT(item); } |
| + static const T& GetKey(const T& item) { return item; } |
| + static uint32_t Hash(const T& item) { return HashT(item); } |
| }; |
| SkTHashTable<T, T, Traits> fTable; |
| }; |