xref: /haiku/src/tests/system/kernel/util/BOpenHashTableTest.cpp (revision aa7ac127f80b67b3b4fa0efae312f39f782e00a2)
1*aa7ac127SKyle Ambroff-Kao #include <cppunit/TestAssert.h>
2*aa7ac127SKyle Ambroff-Kao #include <cppunit/TestCaller.h>
3*aa7ac127SKyle Ambroff-Kao #include <cppunit/TestSuite.h>
4*aa7ac127SKyle Ambroff-Kao #include <TestShell.h>
5*aa7ac127SKyle Ambroff-Kao 
6*aa7ac127SKyle Ambroff-Kao #include <os/support/ObjectList.h>
7*aa7ac127SKyle Ambroff-Kao #include <shared/AutoDeleter.h>
8*aa7ac127SKyle Ambroff-Kao #include <util/OpenHashTable.h>
9*aa7ac127SKyle Ambroff-Kao 
10*aa7ac127SKyle Ambroff-Kao #include "BOpenHashTableTest.h"
11*aa7ac127SKyle Ambroff-Kao 
12*aa7ac127SKyle Ambroff-Kao 
13*aa7ac127SKyle Ambroff-Kao namespace {
14*aa7ac127SKyle Ambroff-Kao 
15*aa7ac127SKyle Ambroff-Kao class Entry {
16*aa7ac127SKyle Ambroff-Kao public:
17*aa7ac127SKyle Ambroff-Kao 	Entry(uint32_t value)
18*aa7ac127SKyle Ambroff-Kao 		:
19*aa7ac127SKyle Ambroff-Kao 		fValue(value),
20*aa7ac127SKyle Ambroff-Kao 		fNext(NULL)
21*aa7ac127SKyle Ambroff-Kao 	{
22*aa7ac127SKyle Ambroff-Kao 	}
23*aa7ac127SKyle Ambroff-Kao 
24*aa7ac127SKyle Ambroff-Kao 	const uint32_t Value() const
25*aa7ac127SKyle Ambroff-Kao 	{
26*aa7ac127SKyle Ambroff-Kao 		return fValue;
27*aa7ac127SKyle Ambroff-Kao 	}
28*aa7ac127SKyle Ambroff-Kao 
29*aa7ac127SKyle Ambroff-Kao 	Entry* Next() const
30*aa7ac127SKyle Ambroff-Kao 	{
31*aa7ac127SKyle Ambroff-Kao 		return fNext;
32*aa7ac127SKyle Ambroff-Kao 	}
33*aa7ac127SKyle Ambroff-Kao 
34*aa7ac127SKyle Ambroff-Kao private:
35*aa7ac127SKyle Ambroff-Kao 	uint32_t	fValue;
36*aa7ac127SKyle Ambroff-Kao 	Entry		*fNext;
37*aa7ac127SKyle Ambroff-Kao 
38*aa7ac127SKyle Ambroff-Kao 	friend class EntryDefinition;
39*aa7ac127SKyle Ambroff-Kao };
40*aa7ac127SKyle Ambroff-Kao 
41*aa7ac127SKyle Ambroff-Kao 
42*aa7ac127SKyle Ambroff-Kao class EntryDefinition {
43*aa7ac127SKyle Ambroff-Kao public:
44*aa7ac127SKyle Ambroff-Kao 	typedef uint32_t KeyType;
45*aa7ac127SKyle Ambroff-Kao 	typedef Entry ValueType;
46*aa7ac127SKyle Ambroff-Kao 
47*aa7ac127SKyle Ambroff-Kao 	size_t HashKey(const KeyType& key) const
48*aa7ac127SKyle Ambroff-Kao 	{
49*aa7ac127SKyle Ambroff-Kao 		return key;
50*aa7ac127SKyle Ambroff-Kao 	}
51*aa7ac127SKyle Ambroff-Kao 
52*aa7ac127SKyle Ambroff-Kao 	size_t Hash(Entry* entry) const
53*aa7ac127SKyle Ambroff-Kao 	{
54*aa7ac127SKyle Ambroff-Kao 		return entry->fValue;
55*aa7ac127SKyle Ambroff-Kao 	}
56*aa7ac127SKyle Ambroff-Kao 
57*aa7ac127SKyle Ambroff-Kao 	bool Compare(const KeyType& key, Entry* entry) const
58*aa7ac127SKyle Ambroff-Kao 	{
59*aa7ac127SKyle Ambroff-Kao 		return key == entry->fValue;
60*aa7ac127SKyle Ambroff-Kao 	}
61*aa7ac127SKyle Ambroff-Kao 
62*aa7ac127SKyle Ambroff-Kao 	Entry*& GetLink(Entry* entry) const
63*aa7ac127SKyle Ambroff-Kao 	{
64*aa7ac127SKyle Ambroff-Kao 		return entry->fNext;
65*aa7ac127SKyle Ambroff-Kao 	}
66*aa7ac127SKyle Ambroff-Kao };
67*aa7ac127SKyle Ambroff-Kao 
68*aa7ac127SKyle Ambroff-Kao }
69*aa7ac127SKyle Ambroff-Kao 
70*aa7ac127SKyle Ambroff-Kao 
71*aa7ac127SKyle Ambroff-Kao CppUnit::Test* BOpenHashTableTest::Suite()
72*aa7ac127SKyle Ambroff-Kao {
73*aa7ac127SKyle Ambroff-Kao 	CppUnit::TestSuite* suite = new CppUnit::TestSuite("BOpenHashTable");
74*aa7ac127SKyle Ambroff-Kao 
75*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
76*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Insert test",
77*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::InsertTest));
78*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
79*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Iterate and count test",
80*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::IterateAndCountTest));
81*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
82*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Lookup test",
83*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::LookupTest));
84*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
85*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Resize test",
86*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::ResizeTest));
87*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
88*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Remove test",
89*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::RemoveTest));
90*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
91*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Duplicate insert test",
92*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::DuplicateInsertTest));
93*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
94*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Disable auto expand",
95*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::DisableAutoExpandTest));
96*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
97*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Init with zero size",
98*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::InitWithZeroSizeTest));
99*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
100*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Clear test",
101*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::ClearTest));
102*aa7ac127SKyle Ambroff-Kao 	suite->addTest(new CppUnit::TestCaller<BOpenHashTableTest>(
103*aa7ac127SKyle Ambroff-Kao 					   "BOpenHashTable::Clear and return test",
104*aa7ac127SKyle Ambroff-Kao 					   &BOpenHashTableTest::ClearAndReturnTest));
105*aa7ac127SKyle Ambroff-Kao 
106*aa7ac127SKyle Ambroff-Kao 	return suite;
107*aa7ac127SKyle Ambroff-Kao }
108*aa7ac127SKyle Ambroff-Kao 
109*aa7ac127SKyle Ambroff-Kao 
110*aa7ac127SKyle Ambroff-Kao BOpenHashTableTest::BOpenHashTableTest(std::string name)
111*aa7ac127SKyle Ambroff-Kao 	: BTestCase(name)
112*aa7ac127SKyle Ambroff-Kao {
113*aa7ac127SKyle Ambroff-Kao }
114*aa7ac127SKyle Ambroff-Kao 
115*aa7ac127SKyle Ambroff-Kao 
116*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::InsertTest()
117*aa7ac127SKyle Ambroff-Kao {
118*aa7ac127SKyle Ambroff-Kao 	Entry entry(123);
119*aa7ac127SKyle Ambroff-Kao 
120*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
121*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK);
122*aa7ac127SKyle Ambroff-Kao 
123*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK);
124*aa7ac127SKyle Ambroff-Kao }
125*aa7ac127SKyle Ambroff-Kao 
126*aa7ac127SKyle Ambroff-Kao 
127*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::IterateAndCountTest() {
128*aa7ac127SKyle Ambroff-Kao 	const size_t kEntryCount = 20;
129*aa7ac127SKyle Ambroff-Kao 
130*aa7ac127SKyle Ambroff-Kao 	BObjectList<Entry> entries(20, true);
131*aa7ac127SKyle Ambroff-Kao 
132*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
133*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(kEntryCount * 2), B_OK);
134*aa7ac127SKyle Ambroff-Kao 
135*aa7ac127SKyle Ambroff-Kao 	for (uint32_t i = 0; i < kEntryCount; ++i) {
136*aa7ac127SKyle Ambroff-Kao 		Entry* entry = new Entry(i);
137*aa7ac127SKyle Ambroff-Kao 		entries.AddItem(entry);
138*aa7ac127SKyle Ambroff-Kao 		CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK);
139*aa7ac127SKyle Ambroff-Kao 	}
140*aa7ac127SKyle Ambroff-Kao 
141*aa7ac127SKyle Ambroff-Kao 	// Verify that the table contains the expected values.
142*aa7ac127SKyle Ambroff-Kao 	uint64_t map = 0;
143*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition>::Iterator iterator = table.GetIterator();
144*aa7ac127SKyle Ambroff-Kao 	while (iterator.HasNext()) {
145*aa7ac127SKyle Ambroff-Kao 		Entry* entry = iterator.Next();
146*aa7ac127SKyle Ambroff-Kao 		CPPUNIT_ASSERT_EQUAL(0, map & (1 << entry->Value()));
147*aa7ac127SKyle Ambroff-Kao 	}
148*aa7ac127SKyle Ambroff-Kao 
149*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(map, (1 << kEntryCount) - 1);
150*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(kEntryCount, table.CountElements());
151*aa7ac127SKyle Ambroff-Kao }
152*aa7ac127SKyle Ambroff-Kao 
153*aa7ac127SKyle Ambroff-Kao 
154*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::ResizeTest()
155*aa7ac127SKyle Ambroff-Kao {
156*aa7ac127SKyle Ambroff-Kao 	// This is the same as IterateAndCountTest, except that the table will
157*aa7ac127SKyle Ambroff-Kao 	// be resized mid insertion.
158*aa7ac127SKyle Ambroff-Kao 	const size_t kEntryCount = 20;
159*aa7ac127SKyle Ambroff-Kao 	BObjectList<Entry> entries(20, true);
160*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
161*aa7ac127SKyle Ambroff-Kao 
162*aa7ac127SKyle Ambroff-Kao 	// Start off with capacity for 8 elements. This will mean that the table
163*aa7ac127SKyle Ambroff-Kao 	// will be resized in the loop below since we are inserting 20 elements.
164*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(8), B_OK);
165*aa7ac127SKyle Ambroff-Kao 
166*aa7ac127SKyle Ambroff-Kao 	for (uint32_t i = 0; i < kEntryCount; ++i) {
167*aa7ac127SKyle Ambroff-Kao 		Entry* entry = new Entry(i);
168*aa7ac127SKyle Ambroff-Kao 		entries.AddItem(entry);
169*aa7ac127SKyle Ambroff-Kao 		CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK);
170*aa7ac127SKyle Ambroff-Kao 	}
171*aa7ac127SKyle Ambroff-Kao 
172*aa7ac127SKyle Ambroff-Kao 	// Verify that after resize the expected elements are present within
173*aa7ac127SKyle Ambroff-Kao 	// the table.
174*aa7ac127SKyle Ambroff-Kao 	uint64_t map = 0;
175*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition>::Iterator iterator = table.GetIterator();
176*aa7ac127SKyle Ambroff-Kao 	while (iterator.HasNext()) {
177*aa7ac127SKyle Ambroff-Kao 		Entry* entry = iterator.Next();
178*aa7ac127SKyle Ambroff-Kao 		CPPUNIT_ASSERT_EQUAL(0, map & (1 << entry->Value()));
179*aa7ac127SKyle Ambroff-Kao 		map |= (1 << entry->Value());
180*aa7ac127SKyle Ambroff-Kao 	}
181*aa7ac127SKyle Ambroff-Kao 
182*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(map, (1 << kEntryCount) - 1);
183*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(kEntryCount, table.CountElements());
184*aa7ac127SKyle Ambroff-Kao }
185*aa7ac127SKyle Ambroff-Kao 
186*aa7ac127SKyle Ambroff-Kao 
187*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::LookupTest() {
188*aa7ac127SKyle Ambroff-Kao 	Entry entry(123);
189*aa7ac127SKyle Ambroff-Kao 
190*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
191*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK);
192*aa7ac127SKyle Ambroff-Kao 
193*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK);
194*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry);
195*aa7ac127SKyle Ambroff-Kao }
196*aa7ac127SKyle Ambroff-Kao 
197*aa7ac127SKyle Ambroff-Kao 
198*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::RemoveTest() {
199*aa7ac127SKyle Ambroff-Kao 	Entry entry(123);
200*aa7ac127SKyle Ambroff-Kao 
201*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
202*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK);
203*aa7ac127SKyle Ambroff-Kao 
204*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK);
205*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry);
206*aa7ac127SKyle Ambroff-Kao 
207*aa7ac127SKyle Ambroff-Kao 	table.Remove(&entry);
208*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), NULL);
209*aa7ac127SKyle Ambroff-Kao }
210*aa7ac127SKyle Ambroff-Kao 
211*aa7ac127SKyle Ambroff-Kao 
212*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::DuplicateInsertTest()
213*aa7ac127SKyle Ambroff-Kao {
214*aa7ac127SKyle Ambroff-Kao 	Entry entry(123);
215*aa7ac127SKyle Ambroff-Kao 
216*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition, true, true> table;
217*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK);
218*aa7ac127SKyle Ambroff-Kao 
219*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK);
220*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry);
221*aa7ac127SKyle Ambroff-Kao 
222*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_DEBUGGER(table.Insert(&entry));
223*aa7ac127SKyle Ambroff-Kao 
224*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry);
225*aa7ac127SKyle Ambroff-Kao 
226*aa7ac127SKyle Ambroff-Kao 	// The item can basically never be removed now since there is a cycle,
227*aa7ac127SKyle Ambroff-Kao 	// but we'll break into the debugger on remove when that happens as well.
228*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_DEBUGGER(table.Remove(&entry));
229*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry);
230*aa7ac127SKyle Ambroff-Kao 
231*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_DEBUGGER(table.Remove(&entry));
232*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry);
233*aa7ac127SKyle Ambroff-Kao }
234*aa7ac127SKyle Ambroff-Kao 
235*aa7ac127SKyle Ambroff-Kao 
236*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::DisableAutoExpandTest()
237*aa7ac127SKyle Ambroff-Kao {
238*aa7ac127SKyle Ambroff-Kao 	// Insert multiple items into a table with a fixed size of 1. This
239*aa7ac127SKyle Ambroff-Kao 	// essentially turns this BOpenHashTable into a linked list, since resize
240*aa7ac127SKyle Ambroff-Kao 	// will never occur.
241*aa7ac127SKyle Ambroff-Kao 	Entry entry1(123);
242*aa7ac127SKyle Ambroff-Kao 	Entry entry2(456);
243*aa7ac127SKyle Ambroff-Kao 
244*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition, false> table;
245*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(1), B_OK);
246*aa7ac127SKyle Ambroff-Kao 
247*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Insert(&entry1), B_OK);
248*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Insert(&entry2), B_OK);
249*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.CountElements(), 2);
250*aa7ac127SKyle Ambroff-Kao }
251*aa7ac127SKyle Ambroff-Kao 
252*aa7ac127SKyle Ambroff-Kao 
253*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::InitWithZeroSizeTest()
254*aa7ac127SKyle Ambroff-Kao {
255*aa7ac127SKyle Ambroff-Kao 	Entry entry(123);
256*aa7ac127SKyle Ambroff-Kao 
257*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
258*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK);
259*aa7ac127SKyle Ambroff-Kao 
260*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK);
261*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry);
262*aa7ac127SKyle Ambroff-Kao }
263*aa7ac127SKyle Ambroff-Kao 
264*aa7ac127SKyle Ambroff-Kao 
265*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::ClearTest()
266*aa7ac127SKyle Ambroff-Kao {
267*aa7ac127SKyle Ambroff-Kao 	const size_t kEntryCount = 3;
268*aa7ac127SKyle Ambroff-Kao 
269*aa7ac127SKyle Ambroff-Kao 	BObjectList<Entry> entries(20, true);
270*aa7ac127SKyle Ambroff-Kao 
271*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
272*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK);
273*aa7ac127SKyle Ambroff-Kao 
274*aa7ac127SKyle Ambroff-Kao 	for (uint32_t i = 0; i < kEntryCount; ++i) {
275*aa7ac127SKyle Ambroff-Kao 		Entry* entry = new Entry(i);
276*aa7ac127SKyle Ambroff-Kao 		entries.AddItem(entry);
277*aa7ac127SKyle Ambroff-Kao 		CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK);
278*aa7ac127SKyle Ambroff-Kao 	}
279*aa7ac127SKyle Ambroff-Kao 
280*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.CountElements(), kEntryCount);
281*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT(table.Lookup(2) != NULL);
282*aa7ac127SKyle Ambroff-Kao 
283*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Clear(false), NULL);
284*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.CountElements(), 0);
285*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(2), NULL);
286*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.GetIterator().HasNext(), false);
287*aa7ac127SKyle Ambroff-Kao }
288*aa7ac127SKyle Ambroff-Kao 
289*aa7ac127SKyle Ambroff-Kao 
290*aa7ac127SKyle Ambroff-Kao void BOpenHashTableTest::ClearAndReturnTest()
291*aa7ac127SKyle Ambroff-Kao {
292*aa7ac127SKyle Ambroff-Kao 	// Same as ClearTest(), except that Clear(true) is called, which tells
293*aa7ac127SKyle Ambroff-Kao 	// the BOpenHashTable<T> to return a linked list of entries before clearing
294*aa7ac127SKyle Ambroff-Kao 	// the table.
295*aa7ac127SKyle Ambroff-Kao 	const size_t kEntryCount = 3;
296*aa7ac127SKyle Ambroff-Kao 	BOpenHashTable<EntryDefinition> table;
297*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK);
298*aa7ac127SKyle Ambroff-Kao 
299*aa7ac127SKyle Ambroff-Kao 	for (uint32_t i = 0; i < kEntryCount; ++i) {
300*aa7ac127SKyle Ambroff-Kao 		Entry* entry = new Entry(i);
301*aa7ac127SKyle Ambroff-Kao 		CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK);
302*aa7ac127SKyle Ambroff-Kao 	}
303*aa7ac127SKyle Ambroff-Kao 
304*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.CountElements(), kEntryCount);
305*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT(table.Lookup(2) != NULL);
306*aa7ac127SKyle Ambroff-Kao 
307*aa7ac127SKyle Ambroff-Kao 	Entry* head = table.Clear(true);
308*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT(head != NULL);
309*aa7ac127SKyle Ambroff-Kao 
310*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.CountElements(), 0);
311*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.Lookup(2), NULL);
312*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(table.GetIterator().HasNext(), false);
313*aa7ac127SKyle Ambroff-Kao 
314*aa7ac127SKyle Ambroff-Kao 	size_t items_returned = 0;
315*aa7ac127SKyle Ambroff-Kao 	while (head != NULL) {
316*aa7ac127SKyle Ambroff-Kao 		Entry* next = head->Next();
317*aa7ac127SKyle Ambroff-Kao 		delete head;
318*aa7ac127SKyle Ambroff-Kao 		head = next;
319*aa7ac127SKyle Ambroff-Kao 
320*aa7ac127SKyle Ambroff-Kao 		++items_returned;
321*aa7ac127SKyle Ambroff-Kao 	}
322*aa7ac127SKyle Ambroff-Kao 
323*aa7ac127SKyle Ambroff-Kao 	CPPUNIT_ASSERT_EQUAL(items_returned, kEntryCount);
324*aa7ac127SKyle Ambroff-Kao }
325