248 bool operator()(uintptr_t* val) {
249 EXPECT_EQ(*val, (uintptr_t)0x2) << "Got an unknown value.";
250 EXPECT_EQ(_count, 0u) << "Only one value should be in table.";
251 _count++;
252 return true; /* continue scan */
253 }
254 };
255
256 static void cht_scan(Thread* thr) {
257 uintptr_t val = 0x2;
258 SimpleTestLookup stl(val);
259 ChtScan scan;
260 SimpleTestTable* cht = new SimpleTestTable();
261 EXPECT_TRUE(cht->insert(thr, stl, val)) << "Insert unique value failed.";
262 EXPECT_EQ(cht->try_scan(thr, scan), true) << "Scanning an non-growing/shrinking table should work.";
263 EXPECT_TRUE(cht->remove(thr, stl)) << "Removing a pre-existing value failed.";
264 EXPECT_FALSE(cht->get_copy(thr, stl) == val) << "Got a removed value.";
265 delete cht;
266 }
267
268 static void cht_grow(Thread* thr) {
269 uintptr_t val = 0x2;
270 uintptr_t val2 = 0x22;
271 uintptr_t val3 = 0x222;
272 SimpleTestLookup stl(val), stl2(val2), stl3(val3);
273 SimpleTestTable* cht = new SimpleTestTable();
274
275 EXPECT_TRUE(cht->insert(thr, stl, val)) << "Insert unique value failed.";
276 EXPECT_TRUE(cht->insert(thr, stl2, val2)) << "Insert unique value failed.";
277 EXPECT_TRUE(cht->insert(thr, stl3, val3)) << "Insert unique value failed.";
278 EXPECT_FALSE(cht->insert(thr, stl3, val3)) << "Insert duplicate value should have failed.";
279 EXPECT_TRUE(cht->get_copy(thr, stl) == val) << "Getting an inserted value should work.";
280 EXPECT_TRUE(cht->get_copy(thr, stl2) == val2) << "Getting an inserted value should work.";
281 EXPECT_TRUE(cht->get_copy(thr, stl3) == val3) << "Getting an inserted value should work.";
282
283 EXPECT_TRUE(cht->remove(thr, stl2)) << "Removing an inserted value should work.";
284
285 EXPECT_TRUE(cht->get_copy(thr, stl) == val) << "Getting an inserted value should work.";
286 EXPECT_FALSE(cht->get_copy(thr, stl2) == val2) << "Getting a removed value should have failed.";
287 EXPECT_TRUE(cht->get_copy(thr, stl3) == val3) << "Getting an inserted value should work.";
352 }
353
354 TEST_VM(ConcurrentHashTable, basic_get_insert) {
355 nomt_test_doer(cht_get_insert);
356 }
357
358 TEST_VM(ConcurrentHashTable, basic_scope) {
359 nomt_test_doer(cht_scope);
360 }
361
362 TEST_VM(ConcurrentHashTable, basic_get_insert_bulk_delete) {
363 nomt_test_doer(cht_getinsert_bulkdelete);
364 }
365
366 TEST_VM(ConcurrentHashTable, basic_get_insert_bulk_delete_task) {
367 nomt_test_doer(cht_getinsert_bulkdelete_task);
368 }
369
370 TEST_VM(ConcurrentHashTable, basic_scan) {
371 nomt_test_doer(cht_scan);
372 }
373
374 TEST_VM(ConcurrentHashTable, basic_grow) {
375 nomt_test_doer(cht_grow);
376 }
377
378 TEST_VM(ConcurrentHashTable, task_grow) {
379 nomt_test_doer(cht_task_grow);
380 }
381
382 //#############################################################################################
383
384 class TestInterface;
385
386 typedef ConcurrentHashTable<uintptr_t, TestInterface, mtInternal> TestTable;
387 typedef ConcurrentHashTable<uintptr_t, TestInterface, mtInternal>::MultiGetHandle TestGetHandle;
388
389 class TestInterface : public TestTable::BaseConfig {
390 public:
391 static uintx get_hash(const uintptr_t& value, bool* dead_hash) {
|
248 bool operator()(uintptr_t* val) {
249 EXPECT_EQ(*val, (uintptr_t)0x2) << "Got an unknown value.";
250 EXPECT_EQ(_count, 0u) << "Only one value should be in table.";
251 _count++;
252 return true; /* continue scan */
253 }
254 };
255
256 static void cht_scan(Thread* thr) {
257 uintptr_t val = 0x2;
258 SimpleTestLookup stl(val);
259 ChtScan scan;
260 SimpleTestTable* cht = new SimpleTestTable();
261 EXPECT_TRUE(cht->insert(thr, stl, val)) << "Insert unique value failed.";
262 EXPECT_EQ(cht->try_scan(thr, scan), true) << "Scanning an non-growing/shrinking table should work.";
263 EXPECT_TRUE(cht->remove(thr, stl)) << "Removing a pre-existing value failed.";
264 EXPECT_FALSE(cht->get_copy(thr, stl) == val) << "Got a removed value.";
265 delete cht;
266 }
267
268 struct ChtCountScan {
269 size_t _count;
270 ChtCountScan() : _count(0) {}
271 bool operator()(uintptr_t* val) {
272 _count++;
273 return true; /* continue scan */
274 }
275 };
276
277 static void cht_move_to(Thread* thr) {
278 uintptr_t val1 = 0x2;
279 uintptr_t val2 = 0xe0000002;
280 uintptr_t val3 = 0x3;
281 SimpleTestLookup stl1(val1), stl2(val2), stl3(val3);
282 SimpleTestTable* from_cht = new SimpleTestTable();
283 EXPECT_TRUE(from_cht->insert(thr, stl1, val1)) << "Insert unique value failed.";
284 EXPECT_TRUE(from_cht->insert(thr, stl2, val2)) << "Insert unique value failed.";
285 EXPECT_TRUE(from_cht->insert(thr, stl3, val3)) << "Insert unique value failed.";
286
287 SimpleTestTable* to_cht = new SimpleTestTable();
288 EXPECT_TRUE(from_cht->try_move_nodes_to(thr, to_cht)) << "Moving nodes to new table failed";
289
290 ChtCountScan scan_old;
291 EXPECT_TRUE(from_cht->try_scan(thr, scan_old)) << "Scanning table should work.";
292 EXPECT_EQ(scan_old._count, (size_t)0) << "All items should be moved";
293
294 ChtCountScan scan_new;
295 EXPECT_TRUE(to_cht->try_scan(thr, scan_new)) << "Scanning table should work.";
296 EXPECT_EQ(scan_new._count, (size_t)3) << "All items should be moved";
297 EXPECT_TRUE(to_cht->get_copy(thr, stl1) == val1) << "Getting an inserted value should work.";
298 EXPECT_TRUE(to_cht->get_copy(thr, stl2) == val2) << "Getting an inserted value should work.";
299 EXPECT_TRUE(to_cht->get_copy(thr, stl3) == val3) << "Getting an inserted value should work.";
300 }
301
302 static void cht_grow(Thread* thr) {
303 uintptr_t val = 0x2;
304 uintptr_t val2 = 0x22;
305 uintptr_t val3 = 0x222;
306 SimpleTestLookup stl(val), stl2(val2), stl3(val3);
307 SimpleTestTable* cht = new SimpleTestTable();
308
309 EXPECT_TRUE(cht->insert(thr, stl, val)) << "Insert unique value failed.";
310 EXPECT_TRUE(cht->insert(thr, stl2, val2)) << "Insert unique value failed.";
311 EXPECT_TRUE(cht->insert(thr, stl3, val3)) << "Insert unique value failed.";
312 EXPECT_FALSE(cht->insert(thr, stl3, val3)) << "Insert duplicate value should have failed.";
313 EXPECT_TRUE(cht->get_copy(thr, stl) == val) << "Getting an inserted value should work.";
314 EXPECT_TRUE(cht->get_copy(thr, stl2) == val2) << "Getting an inserted value should work.";
315 EXPECT_TRUE(cht->get_copy(thr, stl3) == val3) << "Getting an inserted value should work.";
316
317 EXPECT_TRUE(cht->remove(thr, stl2)) << "Removing an inserted value should work.";
318
319 EXPECT_TRUE(cht->get_copy(thr, stl) == val) << "Getting an inserted value should work.";
320 EXPECT_FALSE(cht->get_copy(thr, stl2) == val2) << "Getting a removed value should have failed.";
321 EXPECT_TRUE(cht->get_copy(thr, stl3) == val3) << "Getting an inserted value should work.";
386 }
387
388 TEST_VM(ConcurrentHashTable, basic_get_insert) {
389 nomt_test_doer(cht_get_insert);
390 }
391
392 TEST_VM(ConcurrentHashTable, basic_scope) {
393 nomt_test_doer(cht_scope);
394 }
395
396 TEST_VM(ConcurrentHashTable, basic_get_insert_bulk_delete) {
397 nomt_test_doer(cht_getinsert_bulkdelete);
398 }
399
400 TEST_VM(ConcurrentHashTable, basic_get_insert_bulk_delete_task) {
401 nomt_test_doer(cht_getinsert_bulkdelete_task);
402 }
403
404 TEST_VM(ConcurrentHashTable, basic_scan) {
405 nomt_test_doer(cht_scan);
406 }
407
408 TEST_VM(ConcurrentHashTable, basic_move_to) {
409 nomt_test_doer(cht_move_to);
410 }
411
412 TEST_VM(ConcurrentHashTable, basic_grow) {
413 nomt_test_doer(cht_grow);
414 }
415
416 TEST_VM(ConcurrentHashTable, task_grow) {
417 nomt_test_doer(cht_task_grow);
418 }
419
420 //#############################################################################################
421
422 class TestInterface;
423
424 typedef ConcurrentHashTable<uintptr_t, TestInterface, mtInternal> TestTable;
425 typedef ConcurrentHashTable<uintptr_t, TestInterface, mtInternal>::MultiGetHandle TestGetHandle;
426
427 class TestInterface : public TestTable::BaseConfig {
428 public:
429 static uintx get_hash(const uintptr_t& value, bool* dead_hash) {
|