Index: src/core/SkTDynamicHash.h |
diff --git a/src/core/SkTDynamicHash.h b/src/core/SkTDynamicHash.h |
index 823fde8db1a0be681c47cc8e6457c574dff268e9..b3d4b26476b34ede5c39d9b6d2699da1cd2c4911 100644 |
--- a/src/core/SkTDynamicHash.h |
+++ b/src/core/SkTDynamicHash.h |
@@ -10,21 +10,32 @@ |
#include "SkTypes.h" |
-template <typename T, typename KEY, const KEY& (KEY_FROM_T)(const T&), |
-uint32_t (HASH_FROM_KEY)(const Key&), bool (EQ_T_KEY)(const T&, const Key&)> |
+template <typename T, |
+ typename KEY, |
+ const KEY& (KEY_FROM_T)(const T&), |
+ uint32_t (HASH_FROM_KEY)(const KEY&), |
+ bool (EQ_T_KEY)(const T&, const KEY&)> |
class SkTDynamicHash { |
private: |
- T* fStorage[4]; |
+ T* fStorage[4]; // cheap storage for small arrays |
T** fArray; |
- int fCapacity; |
- int fCountUsed; |
- int fCountDeleted; |
+ int fCapacity; // number of slots in fArray. Must be pow2 |
+ int fCountUsed; // number of valid entries in fArray |
+ int fCountDeleted; // number of deletedValue() entries in fArray |
+ // Need an illegal ptr value different from NULL (which we use to |
+ // signal empty/unused. |
mtklein
2013/07/29 18:51:22
add a ) ?
|
const T* deletedValue() const { return reinterpret_cast<const T*>(-1); } |
+ |
+ // fCapacity is a pow2, so that minus one is a clean mask to grab |
+ // the low bits of hash to use as an index. |
uint32_t hashMask() const { return fCapacity - 1; } |
+ |
int hashToIndex(uint32_t hash) const { |
- return ((hash >> 16) ^ hash) & (fCapacity - 1); |
+ // this 16bit fold may be overkill, if we trust that hash is good |
+ return ((hash >> 16) ^ hash) & this->hashMask(); |
} |
+ |
public: |
SkTDynamicHash() { |
sk_bzero(fStorage, sizeof(fStorage)); |
@@ -112,7 +123,7 @@ public: |
} |
private: |
- int countCollisions(const Key& key) const { |
+ int countCollisions(const KEY& key) const { |
const T* const deleted = this->deletedValue(); |
const unsigned mask = this->hashMask(); |
int index = this->hashToIndex(HASH_FROM_KEY(key)); |