blob: bb9367b46df5c4d0a23000341c61a68c529afe81 [file] [log] [blame]
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +00008#include "SkTDynamicHash.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +00009#include "Test.h"
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000010
11namespace {
12
13struct Entry {
14 int key;
mtklein@google.com0d9f5f72013-08-05 23:08:19 +000015 double value;
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000016};
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +000017
mtklein@google.com0d9f5f72013-08-05 23:08:19 +000018const int& GetKey(const Entry& entry) { return entry.key; }
19uint32_t GetHash(const int& key) { return key; }
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000020
commit-bot@chromium.org158f6462014-04-02 17:03:09 +000021class Hash : public SkTDynamicHash<Entry, int, GetKey, GetHash> {
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000022public:
23 Hash() : INHERITED() {}
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000024
25 // Promote protected methods to public for this test.
26 int capacity() const { return this->INHERITED::capacity(); }
27 int countCollisions(const int& key) const { return this->INHERITED::countCollisions(key); }
28
29private:
commit-bot@chromium.org158f6462014-04-02 17:03:09 +000030 typedef SkTDynamicHash<Entry, int, GetKey, GetHash> INHERITED;
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000031};
32
33} // namespace
34
35#define ASSERT(x) REPORTER_ASSERT(reporter, x)
36
commit-bot@chromium.org1f6cf692014-03-05 01:00:50 +000037DEF_TEST(DynamicHash_growth, reporter) {
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000038 Entry a = { 1, 2.0 };
39 Entry b = { 2, 3.0 };
40 Entry c = { 3, 4.0 };
41 Entry d = { 4, 5.0 };
42 Entry e = { 5, 6.0 };
43
commit-bot@chromium.org7a4b9fa2014-01-13 18:28:14 +000044 Hash hash;
45 ASSERT(hash.capacity() == 0);
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000046
47 hash.add(&a);
mtklein@google.comc9ab2b72013-08-12 14:51:25 +000048 ASSERT(hash.capacity() == 4);
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000049
50 hash.add(&b);
51 ASSERT(hash.capacity() == 4);
52
53 hash.add(&c);
mtklein@google.comc9ab2b72013-08-12 14:51:25 +000054 ASSERT(hash.capacity() == 4);
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000055
56 hash.add(&d);
57 ASSERT(hash.capacity() == 8);
58
59 hash.add(&e);
mtklein@google.comc9ab2b72013-08-12 14:51:25 +000060 ASSERT(hash.capacity() == 8);
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000061
62 ASSERT(hash.count() == 5);
63}
64
commit-bot@chromium.org1f6cf692014-03-05 01:00:50 +000065DEF_TEST(DynamicHash_add, reporter) {
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000066 Hash hash;
67 Entry a = { 1, 2.0 };
68 Entry b = { 2, 3.0 };
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000069
70 ASSERT(hash.count() == 0);
71 hash.add(&a);
72 ASSERT(hash.count() == 1);
73 hash.add(&b);
74 ASSERT(hash.count() == 2);
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000075}
76
commit-bot@chromium.org1f6cf692014-03-05 01:00:50 +000077DEF_TEST(DynamicHash_lookup, reporter) {
commit-bot@chromium.org7a4b9fa2014-01-13 18:28:14 +000078 Hash hash;
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +000079
80 // These collide.
81 Entry a = { 1, 2.0 };
82 Entry b = { 5, 3.0 };
83
84 // Before we insert anything, nothing can collide.
85 ASSERT(hash.countCollisions(1) == 0);
86 ASSERT(hash.countCollisions(5) == 0);
87 ASSERT(hash.countCollisions(9) == 0);
88
89 // First is easy.
90 hash.add(&a);
91 ASSERT(hash.countCollisions(1) == 0);
92 ASSERT(hash.countCollisions(5) == 1);
93 ASSERT(hash.countCollisions(9) == 1);
94
95 // Second is one step away.
96 hash.add(&b);
97 ASSERT(hash.countCollisions(1) == 0);
98 ASSERT(hash.countCollisions(5) == 1);
99 ASSERT(hash.countCollisions(9) == 2);
100
101 // We can find our data right?
102 ASSERT(hash.find(1) != NULL);
103 ASSERT(hash.find(1)->value == 2.0);
104 ASSERT(hash.find(5) != NULL);
105 ASSERT(hash.find(5)->value == 3.0);
106
107 // These aren't in the hash.
108 ASSERT(hash.find(2) == NULL);
109 ASSERT(hash.find(9) == NULL);
110}
111
commit-bot@chromium.org1f6cf692014-03-05 01:00:50 +0000112DEF_TEST(DynamicHash_remove, reporter) {
commit-bot@chromium.org7a4b9fa2014-01-13 18:28:14 +0000113 Hash hash;
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +0000114
115 // These collide.
116 Entry a = { 1, 2.0 };
117 Entry b = { 5, 3.0 };
118 Entry c = { 9, 4.0 };
119
120 hash.add(&a);
121 hash.add(&b);
122 hash.remove(1);
123 // a should be marked deleted, and b should still be findable.
124
125 ASSERT(hash.find(1) == NULL);
126 ASSERT(hash.find(5) != NULL);
127 ASSERT(hash.find(5)->value == 3.0);
128
129 // This will go in the same slot as 'a' did before.
130 ASSERT(hash.countCollisions(9) == 0);
131 hash.add(&c);
132 ASSERT(hash.find(9) != NULL);
133 ASSERT(hash.find(9)->value == 4.0);
134 ASSERT(hash.find(5) != NULL);
135 ASSERT(hash.find(5)->value == 3.0);
136}
137
commit-bot@chromium.org1f6cf692014-03-05 01:00:50 +0000138DEF_TEST(DynamicHash_iterator, reporter) {
139 Hash hash;
140
141 int count = 0;
142 // this should fall out of loop immediately
143 for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
144 ++count;
145 }
146 ASSERT(0 == count);
147
148 // These collide.
149 Entry a = { 1, 2.0 };
150 Entry b = { 5, 3.0 };
151 Entry c = { 9, 4.0 };
152
153 hash.add(&a);
154 hash.add(&b);
155 hash.add(&c);
156
157 // should see all 3 unique keys when iterating over hash
158 count = 0;
159 int keys[3] = {0, 0, 0};
160 for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
161 int key = (*iter).key;
162 keys[count] = key;
163 ASSERT(hash.find(key) != NULL);
164 ++count;
165 }
166 ASSERT(3 == count);
167 ASSERT(keys[0] != keys[1]);
168 ASSERT(keys[0] != keys[2]);
169 ASSERT(keys[1] != keys[2]);
170
171 // should see 2 unique keys when iterating over hash that aren't 1
172 hash.remove(1);
173 count = 0;
174 memset(keys,0,sizeof(keys));
175 for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
176 int key = (*iter).key;
177 keys[count] = key;
178 ASSERT(key != 1);
179 ASSERT(hash.find(key) != NULL);
180 ++count;
181 }
182 ASSERT(2 == count);
183 ASSERT(keys[0] != keys[1]);
commit-bot@chromium.orgf916f9e2013-08-05 22:31:20 +0000184}