Counterproposal to 182733007: Add iterator to SkTDynamicHash

BUG=skia:
R=egdaniel@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/177263005

git-svn-id: http://skia.googlecode.com/svn/trunk@13663 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2014-03-05 01:00:50 +00:00
parent e492ac4fb6
commit 1f6cf695b3
2 changed files with 78 additions and 9 deletions

View File

@ -28,6 +28,33 @@ public:
sk_free(fArray); sk_free(fArray);
} }
class Iter {
public:
explicit Iter(SkTDynamicHash* hash) : fHash(hash), fCurrentIndex(-1) {
SkASSERT(hash);
++(*this);
}
bool done() const {
SkASSERT(fCurrentIndex <= fHash->fCapacity);
return fCurrentIndex == fHash->fCapacity;
}
T& operator*() const {
SkASSERT(!this->done());
return *this->current();
}
void operator++() {
do {
fCurrentIndex++;
} while (!this->done() && (this->current() == Empty() || this->current() == Deleted()));
}
private:
T* current() const { return fHash->fArray[fCurrentIndex]; }
SkTDynamicHash* fHash;
int fCurrentIndex;
};
int count() const { return fCount; } int count() const { return fCount; }
// Return the entry with this key if we have it, otherwise NULL. // Return the entry with this key if we have it, otherwise NULL.

View File

@ -35,7 +35,7 @@ private:
#define ASSERT(x) REPORTER_ASSERT(reporter, x) #define ASSERT(x) REPORTER_ASSERT(reporter, x)
static void test_growth(skiatest::Reporter* reporter) { DEF_TEST(DynamicHash_growth, reporter) {
Entry a = { 1, 2.0 }; Entry a = { 1, 2.0 };
Entry b = { 2, 3.0 }; Entry b = { 2, 3.0 };
Entry c = { 3, 4.0 }; Entry c = { 3, 4.0 };
@ -63,7 +63,7 @@ static void test_growth(skiatest::Reporter* reporter) {
ASSERT(hash.count() == 5); ASSERT(hash.count() == 5);
} }
static void test_add(skiatest::Reporter* reporter) { DEF_TEST(DynamicHash_add, reporter) {
Hash hash; Hash hash;
Entry a = { 1, 2.0 }; Entry a = { 1, 2.0 };
Entry b = { 2, 3.0 }; Entry b = { 2, 3.0 };
@ -75,7 +75,7 @@ static void test_add(skiatest::Reporter* reporter) {
ASSERT(hash.count() == 2); ASSERT(hash.count() == 2);
} }
static void test_lookup(skiatest::Reporter* reporter) { DEF_TEST(DynamicHash_lookup, reporter) {
Hash hash; Hash hash;
// These collide. // These collide.
@ -110,7 +110,7 @@ static void test_lookup(skiatest::Reporter* reporter) {
ASSERT(hash.find(9) == NULL); ASSERT(hash.find(9) == NULL);
} }
static void test_remove(skiatest::Reporter* reporter) { DEF_TEST(DynamicHash_remove, reporter) {
Hash hash; Hash hash;
// These collide. // These collide.
@ -136,9 +136,51 @@ static void test_remove(skiatest::Reporter* reporter) {
ASSERT(hash.find(5)->value == 3.0); ASSERT(hash.find(5)->value == 3.0);
} }
DEF_TEST(DynamicHash, reporter) { DEF_TEST(DynamicHash_iterator, reporter) {
test_growth(reporter); Hash hash;
test_add(reporter);
test_lookup(reporter); int count = 0;
test_remove(reporter); // this should fall out of loop immediately
for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
++count;
}
ASSERT(0 == count);
// These collide.
Entry a = { 1, 2.0 };
Entry b = { 5, 3.0 };
Entry c = { 9, 4.0 };
hash.add(&a);
hash.add(&b);
hash.add(&c);
// should see all 3 unique keys when iterating over hash
count = 0;
int keys[3] = {0, 0, 0};
for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
int key = (*iter).key;
keys[count] = key;
ASSERT(hash.find(key) != NULL);
++count;
}
ASSERT(3 == count);
ASSERT(keys[0] != keys[1]);
ASSERT(keys[0] != keys[2]);
ASSERT(keys[1] != keys[2]);
// should see 2 unique keys when iterating over hash that aren't 1
hash.remove(1);
count = 0;
memset(keys,0,sizeof(keys));
for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
int key = (*iter).key;
keys[count] = key;
ASSERT(key != 1);
ASSERT(hash.find(key) != NULL);
++count;
}
ASSERT(2 == count);
ASSERT(keys[0] != keys[1]);
} }