uint32_t feature_hash(void *f) { uint32_t prime = 31; uint32_t result = 1; FeatureKey feat = (FeatureKey) f; result = prime * result + feat->grp; result = prime * result + default_hash(feat->value); return result; }
/** * @brief Unit test function. */ bool HASH_test () { // return value bool result = true; /* test 1: create the hash table, delete the hash table */ hashTable_s* table = HASH_NewTable(true, true, true); HASH_DeleteTable (&table); /* check table pointer is correctly set to nil */ result = result && (table == NULL); if (!result) return false; /* check alloc total */ result = result && (_num_allocs == 0); if (!result) return false; /* test 2: create the hash table, insert 3 values, delete the hash table */ table = HASH_NewTable(true, true, true); HASH_Insert (table, "AAA", 4, "AAA", 4); HASH_Insert (table, "BBB", 4, "BBB", 4); HASH_Insert (table, "CCC", 4, "CCC", 4); if (HASH_Count(table) != 3) return false; HASH_Clear (table); if (HASH_Count(table) != 0) return false; HASH_DeleteTable (&table); /* check table pointer is correctly set to nil */ result = result && (table == NULL); if (!result) return false; /* check alloc total */ result = result && (_num_allocs == 0); if (!result) return false; /* test 3: create the hash table, insert/remove 3 values, delete the hash table */ table = HASH_NewTable(true, true, true); HASH_Insert (table, "AAA", 4, "AAA", 4); HASH_Remove (table, "AAA", 4); HASH_Insert (table, "BBB", 4, "BBB", 4); HASH_Remove (table, "BBB", 4); HASH_Insert (table, "CCC", 4, "CCC", 4); HASH_Remove (table, "CCC", 4); HASH_DeleteTable (&table); /* check table pointer is correctly set to nil */ result = result && (table == NULL); if (!result) return false; /* check alloc total */ result = result && (_num_allocs == 0); if (!result) return false; /* test 4: create the hash table, insert/count/search/delete 3 values, delete the hash table */ table = HASH_NewTable(true, true, true); HASH_Insert (table, "AAA", 4, "AAA", 4); HASH_Insert (table, "BBB", 4, "BBB", 4); HASH_Insert (table, "CCC", 4, "CCC", 4); /* check count items */ if (HASH_Count(table) != 3) return false; char* aaa = (char*)HASH_Get(table, "AAA", 4); if (strncmp (aaa, "AAA", 4) != 0) return false; char* bbb = (char*)HASH_Get(table, "BBB", 4); if (strncmp (bbb, "BBB", 4) != 0) return false; char* ccc = (char*)HASH_Get(table, "CCC", 4); if (strncmp (ccc, "CCC", 4) != 0) return false; HASH_Remove (table, "AAA", 4); HASH_Remove (table, "BBB", 4); HASH_Remove (table, "CCC", 4); if (HASH_Count(table) != 0) return false; HASH_DeleteTable (&table); /* check table pointer is correctly set to nil */ result = result && (table == NULL); if (!result) return false; /* check alloc total */ result = result && (_num_allocs == 0); if (!result) return false; /* test 5: hash function test */ const char AZ[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; char buffer[26]; /* compute the averag of the hash index of 400 random keys */ int total = 0; srand(time(NULL)); for(int i=0; i < 4000; i++) { /* create random key of random length between 4..23 charachters */ int len = 4 + (rand() % 20); memset (buffer, 0, sizeof(buffer)); for (int j=0; j < len; j++) { int v = rand() % sizeof(AZ); buffer[j]=AZ[v]; } /* compute the hash index */ int idx = default_hash (buffer, len); /* sum index */ total += idx; } /* now compute the average of the indices */ int avg = (total / 4000); /* the average idx should be somewhere halfway, allow a %10 error margin */ int idx_low = (HASH_TABLE_SIZE/2) - (HASH_TABLE_SIZE/10); int idx_high = (HASH_TABLE_SIZE/2) + (HASH_TABLE_SIZE/10); if ( !((idx_low <= avg) && (idx_high >= avg)) ) return false; /* test 6: hash table without ownership test */ table = HASH_NewTable(true, false, true); char item1[] = "AAA"; char item2[] = "BBB"; char item3[] = "CCC"; HASH_Insert (table, item1, 4, item1, 4); HASH_Insert (table, item2, 4, item2, 4); HASH_Insert (table, item3, 4, item3, 4); /* check if we get the correct value pointers */ aaa = (char*)HASH_Get(table, "AAA", 4); if (aaa != item1) return false; bbb = (char*)HASH_Get(table, "BBB", 4); if (bbb != item2) return false; ccc = (char*)HASH_Get(table, "CCC", 4); if (ccc != item3) return false; HASH_DeleteTable (&table); /* check table pointer is correctly set to nil */ result = result && (table == NULL); if (!result) return false; /* check alloc total */ result = result && (_num_allocs == 0); if (!result) return false; /* end of unit test, everything OK */ return true; }