/** test with long sequence of adds, removes and updates, and lookups */ static void test_long_table(struct lruhash* table) { /* assuming it all fits in the hastable, this check will work */ testdata_t* ref[HASHTESTMAX * 100]; size_t i; memset(ref, 0, sizeof(ref)); /* test assumption */ if(0) log_info(" size %d x %d < %d", (int)test_slabhash_sizefunc(NULL, NULL), (int)HASHTESTMAX, (int)table->space_max); unit_assert( test_slabhash_sizefunc(NULL, NULL)*HASHTESTMAX < table->space_max); if(0) lruhash_status(table, "unit test", 1); srandom(48); for(i=0; i<1000; i++) { /* what to do? */ if(i == 500) { lruhash_clear(table); memset(ref, 0, sizeof(ref)); continue; } switch(random() % 4) { case 0: case 3: testadd(table, ref); break; case 1: testremove(table, ref); break; case 2: testlookup(table, ref); break; default: unit_assert(0); } if(0) lruhash_status(table, "unit test", 1); check_table(table); unit_assert( table->num <= HASHTESTMAX ); } /* test more, but 'ref' assumption does not hold anymore */ for(i=0; i<1000; i++) { /* what to do? */ switch(random() % 4) { case 0: case 3: testadd_unlim(table, ref); break; case 1: testremove_unlim(table, ref); break; case 2: testlookup_unlim(table, ref); break; default: unit_assert(0); } if(0) lruhash_status(table, "unlim", 1); check_table(table); } }
/** main routine for threaded hash table test */ static void* test_thr_main(void* arg) { struct test_thr* t = (struct test_thr*)arg; int i; log_thread_set(&t->num); for(i=0; i<1000; i++) { switch(random() % 4) { case 0: case 3: testadd_unlim(t->table, NULL); break; case 1: testremove_unlim(t->table, NULL); break; case 2: testlookup_unlim(t->table, NULL); break; default: unit_assert(0); } if(0) lruhash_status(t->table, "hashtest", 1); if(i % 100 == 0) /* because of locking, not all the time */ check_table(t->table); } check_table(t->table); return NULL; }
void slabhash_status(struct slabhash* sl, const char* id, int extended) { size_t i; char num[17]; log_info("Slabhash %s: %u tables mask=%x shift=%d", id, (unsigned)sl->size, (unsigned)sl->mask, sl->shift); for(i=0; i<sl->size; i++) { snprintf(num, sizeof(num), "table %u", (unsigned)i); lruhash_status(sl->array[i], num, extended); } }
/** test hash table access by multiple threads */ static void test_threaded_table(struct lruhash* table) { int numth = 10; struct test_thr t[100]; int i; for(i=1; i<numth; i++) { t[i].num = i; t[i].table = table; ub_thread_create(&t[i].id, test_thr_main, &t[i]); } for(i=1; i<numth; i++) { ub_thread_join(t[i].id); } if(0) lruhash_status(table, "hashtest", 1); }