blob: 695ccb8a31c2f5ff54af0764eedd9eb970b8c92d [file] [log] [blame]
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001//===- HashTableTest.cpp --------------------------------------------------===//
2//
3// The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "HashTableTest.h"
Stephen Hines37b74a32014-11-26 18:48:20 -080011#include "mcld/ADT/HashEntry.h"
12#include "mcld/ADT/HashTable.h"
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070013#include <cstdlib>
14
15using namespace std;
16using namespace mcld;
17using namespace mcldtest;
18
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070019// Constructor can do set-up work for all test here.
Stephen Hines37b74a32014-11-26 18:48:20 -080020HashTableTest::HashTableTest() {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070021}
22
23// Destructor can do clean-up work that doesn't throw exceptions here.
Stephen Hines37b74a32014-11-26 18:48:20 -080024HashTableTest::~HashTableTest() {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070025}
26
27// SetUp() will be called immediately before each test.
Stephen Hines37b74a32014-11-26 18:48:20 -080028void HashTableTest::SetUp() {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070029}
30
31// TearDown() will be called immediately after each test.
Stephen Hines37b74a32014-11-26 18:48:20 -080032void HashTableTest::TearDown() {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070033}
34
35//==========================================================================//
36// Testcases
37//
Stephen Hines37b74a32014-11-26 18:48:20 -080038struct IntCompare {
39 bool operator()(int X, int Y) const { return (X == Y); }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070040};
41
Stephen Hines37b74a32014-11-26 18:48:20 -080042struct PtrCompare {
43 bool operator()(const int* X, const int* Y) const { return (X == Y); }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070044};
45
Stephen Hines37b74a32014-11-26 18:48:20 -080046struct PtrHash {
47 size_t operator()(const int* pKey) const {
48 return (unsigned((uintptr_t)pKey) >> 4) ^ (unsigned((uintptr_t)pKey) >> 9);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070049 }
50};
51
Stephen Hines37b74a32014-11-26 18:48:20 -080052struct IntHash {
53 size_t operator()(int pKey) const { return pKey; }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070054};
55
Stephen Hines37b74a32014-11-26 18:48:20 -080056struct IntMod3Hash {
57 size_t operator()(int pKey) const { return pKey % 3; }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070058};
59
Stephen Hines37b74a32014-11-26 18:48:20 -080060TEST_F(HashTableTest, ptr_entry) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070061 int A = 1;
62 int* pA = &A;
63
64 typedef HashEntry<int*, int, PtrCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -080065 typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> >
66 HashTableTy;
67 HashTableTy* hashTable = new HashTableTy(0);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070068
69 bool exist;
Pirama Arumuga Nainar2bf3f882015-04-21 10:33:13 -070070 hashTable->insert(pA, exist);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070071
72 EXPECT_FALSE(hashTable->empty());
73
74 HashTableTy::iterator iter;
75 iter = hashTable->find(NULL);
Stephen Hines37b74a32014-11-26 18:48:20 -080076 EXPECT_TRUE(iter == hashTable->end());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070077 delete hashTable;
78}
79
Stephen Hines37b74a32014-11-26 18:48:20 -080080TEST_F(HashTableTest, constructor) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070081 typedef HashEntry<int, int, IntCompare> HashEntryType;
82 HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > hashTable(16);
Shih-wei Liao22add6f2012-12-15 17:21:00 -080083 EXPECT_TRUE(17 == hashTable.numOfBuckets());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070084 EXPECT_TRUE(hashTable.empty());
Shih-wei Liao22add6f2012-12-15 17:21:00 -080085 EXPECT_TRUE(0 == hashTable.numOfEntries());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070086}
87
Stephen Hines37b74a32014-11-26 18:48:20 -080088TEST_F(HashTableTest, allocattion) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070089 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -080090 typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> >
91 HashTableTy;
92 HashTableTy* hashTable = new HashTableTy(22);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070093
94 bool exist;
95 int key = 100;
96 HashTableTy::entry_type* val = hashTable->insert(key, exist);
97 val->setValue(999);
98 EXPECT_FALSE(hashTable->empty());
99 EXPECT_FALSE(exist);
100 EXPECT_FALSE(NULL == val);
101 HashTableTy::iterator entry = hashTable->find(key);
102 EXPECT_EQ(999, entry.getEntry()->value());
103 delete hashTable;
104}
105
Stephen Hines37b74a32014-11-26 18:48:20 -0800106TEST_F(HashTableTest, alloc100) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700107 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800108 typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> >
109 HashTableTy;
110 HashTableTy* hashTable = new HashTableTy(22);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700111
112 bool exist;
113 HashTableTy::entry_type* entry = 0;
Stephen Hines37b74a32014-11-26 18:48:20 -0800114 for (int key = 0; key < 100; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700115 entry = hashTable->insert(key, exist);
116 EXPECT_FALSE(hashTable->empty());
117 EXPECT_FALSE(exist);
118 EXPECT_FALSE(NULL == entry);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800119 EXPECT_TRUE(key == entry->key());
Stephen Hines37b74a32014-11-26 18:48:20 -0800120 entry->setValue(key + 10);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700121 }
122
123 EXPECT_FALSE(hashTable->empty());
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800124 EXPECT_TRUE(100 == hashTable->numOfEntries());
125 EXPECT_TRUE(197 == hashTable->numOfBuckets());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700126 delete hashTable;
127}
128
Stephen Hines37b74a32014-11-26 18:48:20 -0800129TEST_F(HashTableTest, erase100) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700130 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800131 typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> >
132 HashTableTy;
133 HashTableTy* hashTable = new HashTableTy(0);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700134
135 bool exist;
Stephen Hines37b74a32014-11-26 18:48:20 -0800136 for (unsigned int key = 0; key < 100; ++key)
Pirama Arumuga Nainar2bf3f882015-04-21 10:33:13 -0700137 hashTable->insert(key, exist);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700138
139 EXPECT_FALSE(hashTable->empty());
140
141 int count;
142 HashTableTy::iterator iter;
Stephen Hines37b74a32014-11-26 18:48:20 -0800143 for (unsigned int key = 0; key < 100; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700144 count = hashTable->erase(key);
145 EXPECT_EQ(1, count);
146 iter = hashTable->find(key);
147 EXPECT_TRUE(iter == hashTable->end());
148 }
149
150 EXPECT_TRUE(hashTable->empty());
151 delete hashTable;
152}
153
Stephen Hines37b74a32014-11-26 18:48:20 -0800154TEST_F(HashTableTest, clear) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700155 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800156 typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> >
157 HashTableTy;
158 HashTableTy* hashTable = new HashTableTy(22);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700159
160 bool exist;
Stephen Hines37b74a32014-11-26 18:48:20 -0800161 for (unsigned int key = 0; key < 100; ++key) {
Pirama Arumuga Nainar2bf3f882015-04-21 10:33:13 -0700162 hashTable->insert(key, exist);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700163 }
164
165 hashTable->clear();
166
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700167 HashTableTy::iterator iter;
Stephen Hines37b74a32014-11-26 18:48:20 -0800168 for (unsigned int key = 0; key < 100; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700169 iter = hashTable->find(key);
170 EXPECT_TRUE(iter == hashTable->end());
171 }
172
173 EXPECT_TRUE(hashTable->empty());
174 delete hashTable;
175}
176
Stephen Hines37b74a32014-11-26 18:48:20 -0800177TEST_F(HashTableTest, tombstone) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700178 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800179 typedef HashTable<HashEntryType, IntMod3Hash, EntryFactory<HashEntryType> >
180 HashTableTy;
181 HashTableTy* hashTable = new HashTableTy();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700182
183 bool exist;
Stephen Hines37b74a32014-11-26 18:48:20 -0800184 for (unsigned int key = 0; key < 100; ++key) {
Pirama Arumuga Nainar2bf3f882015-04-21 10:33:13 -0700185 hashTable->insert(key, exist);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700186 }
187 EXPECT_FALSE(hashTable->empty());
188
189 int count;
190 HashTableTy::iterator iter;
Stephen Hines37b74a32014-11-26 18:48:20 -0800191 for (unsigned int key = 0; key < 20; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700192 count = hashTable->erase(key);
193 EXPECT_EQ(1, count);
194 iter = hashTable->find(key);
195 EXPECT_TRUE(iter == hashTable->end());
196 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800197 EXPECT_TRUE(80 == hashTable->numOfEntries());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700198
Stephen Hines37b74a32014-11-26 18:48:20 -0800199 for (unsigned int key = 20; key < 100; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700200 iter = hashTable->find(key);
201 EXPECT_TRUE(iter != hashTable->end());
202 }
203
Stephen Hines37b74a32014-11-26 18:48:20 -0800204 for (unsigned int key = 0; key < 20; ++key) {
Pirama Arumuga Nainar2bf3f882015-04-21 10:33:13 -0700205 hashTable->insert(key, exist);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700206 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800207 EXPECT_TRUE(100 == hashTable->numOfEntries());
208 EXPECT_TRUE(197 == hashTable->numOfBuckets());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700209
210 delete hashTable;
211}
212
Stephen Hines37b74a32014-11-26 18:48:20 -0800213TEST_F(HashTableTest, rehash_test) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700214 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800215 typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> >
216 HashTableTy;
217 HashTableTy* hashTable = new HashTableTy(0);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700218
219 bool exist;
220 HashTableTy::entry_type* entry = 0;
Stephen Hines37b74a32014-11-26 18:48:20 -0800221 for (unsigned int key = 0; key < 400000; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700222 entry = hashTable->insert(key, exist);
Stephen Hines37b74a32014-11-26 18:48:20 -0800223 entry->setValue(key + 10);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700224 }
225
226 HashTableTy::iterator iter;
Stephen Hines37b74a32014-11-26 18:48:20 -0800227 for (int key = 0; key < 400000; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700228 iter = hashTable->find(key);
Stephen Hines37b74a32014-11-26 18:48:20 -0800229 EXPECT_EQ((key + 10), iter.getEntry()->value());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700230 }
231
232 delete hashTable;
233}
234
Stephen Hines37b74a32014-11-26 18:48:20 -0800235TEST_F(HashTableTest, bucket_iterator) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700236 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800237 typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> >
238 HashTableTy;
239 HashTableTy* hashTable = new HashTableTy(0);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700240
241 bool exist;
242 HashTableTy::entry_type* entry = 0;
Stephen Hines37b74a32014-11-26 18:48:20 -0800243 for (unsigned int key = 0; key < 400000; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700244 entry = hashTable->insert(key, exist);
Stephen Hines37b74a32014-11-26 18:48:20 -0800245 entry->setValue(key + 10);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700246 }
247
248 HashTableTy::iterator iter, iEnd = hashTable->end();
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800249 int counter = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700250 for (iter = hashTable->begin(); iter != iEnd; ++iter) {
Stephen Hines37b74a32014-11-26 18:48:20 -0800251 EXPECT_EQ(iter.getEntry()->key() + 10, iter.getEntry()->value());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700252 ++counter;
253 }
254 EXPECT_EQ(400000, counter);
255 delete hashTable;
256}
257
Stephen Hines37b74a32014-11-26 18:48:20 -0800258TEST_F(HashTableTest, chain_iterator_single) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700259 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800260 typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> >
261 HashTableTy;
262 HashTableTy* hashTable = new HashTableTy();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700263
264 bool exist;
265 HashTableTy::entry_type* entry = 0;
Stephen Hines37b74a32014-11-26 18:48:20 -0800266 for (int key = 0; key < 16; ++key) {
267 entry = hashTable->insert(key * 37, exist);
268 entry->setValue(key + 10);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700269 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800270 for (int key = 0; key < 16; ++key) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800271 int counter = 0;
Stephen Hines37b74a32014-11-26 18:48:20 -0800272 HashTableTy::chain_iterator iter, iEnd = hashTable->end(key * 37);
273 for (iter = hashTable->begin(key * 37); iter != iEnd; ++iter) {
274 EXPECT_EQ(key + 10, iter.getEntry()->value());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700275 ++counter;
276 }
277 EXPECT_EQ(1, counter);
278 }
279 delete hashTable;
280}
281
Stephen Hines37b74a32014-11-26 18:48:20 -0800282struct FixHash {
283 size_t operator()(int pKey) const { return 10; }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700284};
285
Stephen Hines37b74a32014-11-26 18:48:20 -0800286TEST_F(HashTableTest, chain_iterator_list) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700287 typedef HashEntry<int, int, IntCompare> HashEntryType;
Stephen Hines37b74a32014-11-26 18:48:20 -0800288 typedef HashTable<HashEntryType, FixHash, EntryFactory<HashEntryType> >
289 HashTableTy;
290 HashTableTy* hashTable = new HashTableTy();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700291
292 bool exist;
293 HashTableTy::entry_type* entry = 0;
Stephen Hines37b74a32014-11-26 18:48:20 -0800294 for (unsigned int key = 0; key < 16; ++key) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700295 entry = hashTable->insert(key, exist);
296 ASSERT_FALSE(exist);
297 entry->setValue(key);
298 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800299 ASSERT_TRUE(16 == hashTable->numOfEntries());
300 ASSERT_TRUE(37 == hashTable->numOfBuckets());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700301
302 unsigned int key = 0;
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800303 int count = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700304 HashTableTy::chain_iterator iter, iEnd = hashTable->end(key);
305 for (iter = hashTable->begin(key); iter != iEnd; ++iter) {
306 count++;
307 }
308 ASSERT_EQ(16, count);
309 delete hashTable;
310}