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

Unified Diff: src/core/SkTDynamicHash.h

Issue 20344002: use dynamic hash to speed up scaledimagecache (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkScaledImageCache.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkTDynamicHash.h
diff --git a/src/core/SkTDynamicHash.h b/src/core/SkTDynamicHash.h
index 665028abaa398cd25700237316122d47ca6b91e7..b4787fb89e361ec793ab13cf25181795e5978789 100644
--- a/src/core/SkTDynamicHash.h
+++ b/src/core/SkTDynamicHash.h
@@ -14,19 +14,22 @@ 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[1];
+ T* fStorage[4];
T** fArray;
int fCapacity;
int fCountUsed;
int fCountDeleted;
- unsigned hashMask() const { return fCapacity - 1; }
const T* deletedValue() const { return reinterpret_cast<const T*>(-1); }
-
+ uint32_t hashMask() const { return fCapacity - 1; }
+ int hashToIndex(uint32_t hash) const {
+ return ((hash >> 16) ^ hash) & (fCapacity - 1);
+ }
public:
SkTDynamicHash() {
+ sk_bzero(fStorage, sizeof(fStorage));
fArray = fStorage;
- fCapacity = 1;
+ fCapacity = SK_ARRAY_COUNT(fStorage);
fCountUsed = fCountDeleted = 0;
}
~SkTDynamicHash() {
@@ -38,8 +41,7 @@ public:
T* find(const KEY& key) {
const T* const deleted = this->deletedValue();
const unsigned mask = this->hashMask();
- int index = HASH_FROM_KEY(key) & mask;
- const int origIndex = index;
+ int index = this->hashToIndex(HASH_FROM_KEY(key));
int delta = 1;
do {
@@ -52,7 +54,7 @@ public:
}
index = (index + delta) & mask;
delta <<= 1;
- } while (index != origIndex);
+ } while (delta <= fCapacity);
return NULL;
}
@@ -60,8 +62,7 @@ public:
const T* const deleted = this->deletedValue();
for (;;) {
const unsigned mask = this->hashMask();
- int index = HASH_FROM_KEY(key) & mask;
- const int origIndex = index;
+ int index = this->hashToIndex(HASH_FROM_KEY(key));
int delta = 1;
do {
@@ -77,7 +78,7 @@ public:
}
index = (index + delta) & mask;
delta <<= 1;
- } while (index != origIndex);
+ } while (delta <= fCapacity);
if (autoGrow) {
this->grow();
} else {
@@ -91,9 +92,7 @@ public:
void remove(const KEY& key) {
const T* const deleted = this->deletedValue();
const unsigned mask = this->hashMask();
- const uint32_t hash = HASH_FROM_KEY(key);
- int index = hash & mask;
- SkDEBUGCODE(const int origIndex = index;)
+ int index = this->hashToIndex(HASH_FROM_KEY(key));
int delta = 1;
for (;;) {
@@ -101,20 +100,51 @@ public:
SkASSERT(candidate);
if (deleted != candidate && EQ_T_KEY(*candidate, key)) {
fArray[index] = const_cast<T*>(deleted);
+ fCountUsed -= 1;
fCountDeleted += 1;
break;
}
index = (index + delta) & mask;
delta <<= 1;
- SkASSERT(index != origIndex);
+ SkASSERT(delta <= fCapacity);
}
this->checkStrink();
}
private:
+ 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));
+ int delta = 1;
+ int collisionCount = 0;
+
+ for (;;) {
+ const T* candidate = fArray[index];
+ SkASSERT(candidate);
+ if (deleted != candidate && EQ_T_KEY(*candidate, key)) {
+ break;
+ }
+ index = (index + delta) & mask;
+ delta <<= 1;
+ collisionCount += 1;
+ SkASSERT(delta <= fCapacity);
+ }
+ return collisionCount;
+ }
+
void grow() {
const T* const deleted = this->deletedValue();
-
+#if 0
+ SkDebugf("growing from %d: used=%d\n", fCapacity, fCountUsed);
+ for (int i = 0; i < fCapacity; ++i) {
+ T* elem = fArray[i];
+ if (NULL == elem || deleted == elem) {
+ continue;
+ }
+ SkDebugf(" entry[%d] had %d collisions\n", i, countCollisions(KEY_FROM_T(*elem)));
+ }
+#endif
int oldCapacity = fCapacity;
T** oldArray = fArray;
@@ -137,10 +167,16 @@ private:
SkASSERT(success);
}
SkASSERT(oldCountUsed == fCountUsed);
- sk_free(oldArray);
+
+ if (oldArray != fStorage) {
+ sk_free(oldArray);
+ }
}
- void checkStrink() {}
+ void checkStrink() {
+ // todo: based on density and deadspace (fCountDeleted), consider
+ // shrinking fArray and repopulating it.
+ }
};
#endif
« no previous file with comments | « src/core/SkScaledImageCache.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698