| Index: src/core/SkTDynamicHash.h
|
| diff --git a/src/core/SkTDynamicHash.h b/src/core/SkTDynamicHash.h
|
| index 4cb44204c85f61130354d25c78c7924249fe66f8..4893fb384ff7e6b13a3fea8a814cb523fb2ae33d 100644
|
| --- a/src/core/SkTDynamicHash.h
|
| +++ b/src/core/SkTDynamicHash.h
|
| @@ -16,13 +16,10 @@ template <typename T,
|
| const Key& (GetKey)(const T&),
|
| uint32_t (Hash)(const Key&),
|
| bool (Equal)(const T&, const Key&),
|
| - int kGrowPercent = 75, // Larger -> more memory efficient, but slower.
|
| - int kShrinkPercent = 25>
|
| + int kGrowPercent = 75> // Larger -> more memory efficient, but slower.
|
| class SkTDynamicHash {
|
| - static const int kMinCapacity = 4; // Smallest capacity we allow.
|
| public:
|
| - SkTDynamicHash(int initialCapacity=64/sizeof(T*)) {
|
| - this->reset(SkNextPow2(initialCapacity > kMinCapacity ? initialCapacity : kMinCapacity));
|
| + SkTDynamicHash() : fCount(0), fDeleted(0), fCapacity(0), fArray(NULL) {
|
| SkASSERT(this->validate());
|
| }
|
|
|
| @@ -45,7 +42,7 @@ public:
|
| }
|
| index = this->nextIndex(index, round);
|
| }
|
| - SkASSERT(0); // find: should be unreachable
|
| + SkASSERT(fCapacity == 0);
|
| return NULL;
|
| }
|
|
|
| @@ -63,8 +60,6 @@ public:
|
| SkASSERT(NULL != this->find(key));
|
| this->innerRemove(key);
|
| SkASSERT(this->validate());
|
| - this->maybeShrink();
|
| - SkASSERT(this->validate());
|
| }
|
|
|
| protected:
|
| @@ -82,8 +77,8 @@ protected:
|
| }
|
| index = this->nextIndex(index, round);
|
| }
|
| - SkASSERT(0); // countCollisions: should be unreachable
|
| - return -1;
|
| + SkASSERT(fCapacity == 0);
|
| + return 0;
|
| }
|
|
|
| private:
|
| @@ -91,23 +86,11 @@ private:
|
| static T* Empty() { return reinterpret_cast<T*>(0); } // i.e. NULL
|
| static T* Deleted() { return reinterpret_cast<T*>(1); } // Also an invalid pointer.
|
|
|
| - static T** AllocArray(int capacity) {
|
| - return (T**)sk_calloc_throw(sizeof(T*) * capacity); // All cells == Empty().
|
| - }
|
| -
|
| - void reset(int capacity) {
|
| - fCount = 0;
|
| - fDeleted = 0;
|
| - fCapacity = capacity;
|
| - fArray = AllocArray(fCapacity);
|
| - }
|
| -
|
| bool validate() const {
|
| #define SKTDYNAMICHASH_CHECK(x) SkASSERT((x)); if (!(x)) return false
|
|
|
| // Is capacity sane?
|
| SKTDYNAMICHASH_CHECK(SkIsPow2(fCapacity));
|
| - SKTDYNAMICHASH_CHECK(fCapacity >= kMinCapacity);
|
|
|
| // Is fCount correct?
|
| int count = 0;
|
| @@ -168,7 +151,7 @@ private:
|
| }
|
| index = this->nextIndex(index, round);
|
| }
|
| - SkASSERT(0); // add: should be unreachable
|
| + SkASSERT(fCapacity == 0);
|
| }
|
|
|
| void innerRemove(const Key& key) {
|
| @@ -184,37 +167,31 @@ private:
|
| }
|
| index = this->nextIndex(index, round);
|
| }
|
| - SkASSERT(0); // innerRemove: should be unreachable
|
| + SkASSERT(fCapacity == 0);
|
| }
|
|
|
| void maybeGrow() {
|
| - if (fCount + fDeleted + 1 > (fCapacity * kGrowPercent) / 100) {
|
| - resize(fCapacity * 2);
|
| - }
|
| - }
|
| -
|
| - void maybeShrink() {
|
| - if (fCount < (fCapacity * kShrinkPercent) / 100 && fCapacity / 2 > kMinCapacity) {
|
| - resize(fCapacity / 2);
|
| + if (100 * (fCount + fDeleted + 1) > fCapacity * kGrowPercent) {
|
| + this->resize(fCapacity > 0 ? fCapacity * 2 : 4);
|
| }
|
| }
|
|
|
| void resize(int newCapacity) {
|
| SkDEBUGCODE(int oldCount = fCount;)
|
| int oldCapacity = fCapacity;
|
| - T** oldArray = fArray;
|
| + SkAutoTMalloc<T*> oldArray(fArray);
|
|
|
| - reset(newCapacity);
|
| + fCount = fDeleted = 0;
|
| + fCapacity = newCapacity;
|
| + fArray = (T**)sk_calloc_throw(sizeof(T*) * fCapacity);
|
|
|
| for (int i = 0; i < oldCapacity; i++) {
|
| T* entry = oldArray[i];
|
| if (Empty() != entry && Deleted() != entry) {
|
| - this->add(entry);
|
| + this->innerAdd(entry);
|
| }
|
| }
|
| SkASSERT(oldCount == fCount);
|
| -
|
| - sk_free(oldArray);
|
| }
|
|
|
| // fCapacity is always a power of 2, so this masks the correct low bits to index into our hash.
|
|
|