Added more complete hashtable test; fixed incorrect return value in LH_ENTRY(find)
This commit is contained in:
parent
6138c77306
commit
fd19036843
2 changed files with 116 additions and 3 deletions
|
@ -78,15 +78,15 @@ static LH_ENTRY(value_t) * removeFromLinkedList(struct LH_ENTRY(table) * table,
|
||||||
} else {
|
} else {
|
||||||
// Freeing item in table->bucketList. Copy its next pair to
|
// Freeing item in table->bucketList. Copy its next pair to
|
||||||
// bucketList, and free that item.
|
// bucketList, and free that item.
|
||||||
|
ret = thePair->value;
|
||||||
struct LH_ENTRY(pair_t) * oldNext = thePair->next;
|
struct LH_ENTRY(pair_t) * oldNext = thePair->next;
|
||||||
*thePair = *(thePair->next);
|
*thePair = *(thePair->next);
|
||||||
ret = thePair->value;
|
|
||||||
free(oldNext);
|
free(oldNext);
|
||||||
}
|
}
|
||||||
} else { // Found, in spillover bucket.
|
} else { // Found, in spillover bucket.
|
||||||
|
ret = thePair->value;
|
||||||
free((void*)thePair->key);
|
free((void*)thePair->key);
|
||||||
predecessor->next = thePair->next;
|
predecessor->next = thePair->next;
|
||||||
ret = thePair->value;
|
|
||||||
free(thePair);
|
free(thePair);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -42,7 +42,8 @@ terms specified in this license.
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <check.h>
|
#include <check.h>
|
||||||
|
|
||||||
|
@ -101,6 +102,117 @@ START_TEST(lhtableTest)
|
||||||
|
|
||||||
} END_TEST
|
} END_TEST
|
||||||
|
|
||||||
|
long myrandom(long x) {
|
||||||
|
double xx = x;
|
||||||
|
double r = random();
|
||||||
|
double max = RAND_MAX;
|
||||||
|
|
||||||
|
return (long)(xx * (r/max));
|
||||||
|
}
|
||||||
|
|
||||||
|
//#define myrandom(x)(
|
||||||
|
// (long) ( ((double)x) * ((double)random()) / ((double)RAND_MAX) ) )
|
||||||
|
|
||||||
|
#define MAXSETS 1000
|
||||||
|
#define MAXSETLEN 10000
|
||||||
|
#define NUM_ITERS 10
|
||||||
|
char * itoa(int i) {
|
||||||
|
char * ret;
|
||||||
|
asprintf(&ret, "%d", i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(lhtableRandomized) {
|
||||||
|
for(int jjj = 0; jjj < NUM_ITERS; jjj++) {
|
||||||
|
time_t seed = time(0);
|
||||||
|
printf("\nSeed = %ld\n", seed);
|
||||||
|
srandom(seed);
|
||||||
|
|
||||||
|
struct LH_ENTRY(table) * t = LH_ENTRY(create)(myrandom(10000));
|
||||||
|
int numSets = myrandom(MAXSETS);
|
||||||
|
int* setLength = malloc(numSets * sizeof(int));
|
||||||
|
int** sets = malloc(numSets * sizeof(int*));
|
||||||
|
long nextVal = 1;
|
||||||
|
long eventCount = 0;
|
||||||
|
|
||||||
|
int* setNextAlloc = calloc(numSets, sizeof(int));
|
||||||
|
int* setNextDel = calloc(numSets, sizeof(int));
|
||||||
|
int* setNextRead = calloc(numSets, sizeof(int));
|
||||||
|
|
||||||
|
for(int i =0; i < numSets; i++) {
|
||||||
|
setLength[i] = myrandom(MAXSETLEN);
|
||||||
|
sets[i] = malloc(setLength[i] * sizeof(int));
|
||||||
|
eventCount += setLength[i];
|
||||||
|
for(int j =0; j < setLength[i]; j++) {
|
||||||
|
sets[i][j] = nextVal;
|
||||||
|
nextVal++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eventCount = myrandom(eventCount * 4);
|
||||||
|
printf("Running %ld events.\n", eventCount);
|
||||||
|
|
||||||
|
for(int iii = 0; iii < eventCount; iii++) {
|
||||||
|
int eventType = myrandom(3); // 0 = insert; 1 = read; 2 = delete.
|
||||||
|
int set = myrandom(numSets);
|
||||||
|
switch(eventType) {
|
||||||
|
case 0: // insert
|
||||||
|
if(setNextAlloc[set] != setLength[set]) {
|
||||||
|
int keyInt = sets[set][setNextAlloc[set]];
|
||||||
|
char * key = itoa(keyInt);
|
||||||
|
assert(!LH_ENTRY(find)(t, key, strlen(key)+1));
|
||||||
|
LH_ENTRY(insert)(t, key, strlen(key)+1, (void*)(long)keyInt);
|
||||||
|
// printf("i %d\n", keyInt);
|
||||||
|
assert(LH_ENTRY(find)(t, key, strlen(key)+1));
|
||||||
|
free(key);
|
||||||
|
setNextAlloc[set]++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: // read
|
||||||
|
if(setNextAlloc[set] != setNextDel[set]) {
|
||||||
|
setNextRead[set]++;
|
||||||
|
if(setNextRead[set] < setNextDel[set]) {
|
||||||
|
setNextRead[set] = setNextDel[set];
|
||||||
|
} else if(setNextRead[set] == setNextAlloc[set]) {
|
||||||
|
setNextRead[set] = setNextDel[set];
|
||||||
|
}
|
||||||
|
assert(setNextRead[set] < setNextAlloc[set] && setNextRead[set] >= setNextDel[set]);
|
||||||
|
long keyInt = sets[set][setNextRead[set]];
|
||||||
|
char * key = itoa(keyInt);
|
||||||
|
long fret = (long)LH_ENTRY(find)(t, key, strlen(key)+1);
|
||||||
|
assert(keyInt == fret);
|
||||||
|
assert(keyInt == (long)LH_ENTRY(insert)(t, key, strlen(key)+1, (void*)(keyInt+1)));
|
||||||
|
assert(keyInt+1 == (long)LH_ENTRY(insert)(t, key, strlen(key)+1, (void*)keyInt));
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // delete
|
||||||
|
if(setNextAlloc[set] != setNextDel[set]) {
|
||||||
|
int keyInt = sets[set][setNextDel[set]];
|
||||||
|
char * key = itoa(keyInt);
|
||||||
|
assert((long)keyInt == (long)LH_ENTRY(find) (t, key, strlen(key)+1));
|
||||||
|
assert((long)keyInt == (long)LH_ENTRY(remove)(t, key, strlen(key)+1));
|
||||||
|
assert((long)0 == (long)LH_ENTRY(find)(t, key, strlen(key)+1));
|
||||||
|
// printf("d %d\n", keyInt);
|
||||||
|
free(key);
|
||||||
|
setNextDel[set]++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < numSets; i++) {
|
||||||
|
free(sets[i]);
|
||||||
|
}
|
||||||
|
free(setNextAlloc);
|
||||||
|
free(setNextDel);
|
||||||
|
free(setNextRead);
|
||||||
|
free(setLength);
|
||||||
|
LH_ENTRY(destroy)(t);
|
||||||
|
}
|
||||||
|
} END_TEST
|
||||||
|
|
||||||
Suite * check_suite(void) {
|
Suite * check_suite(void) {
|
||||||
Suite *s = suite_create("lhtable");
|
Suite *s = suite_create("lhtable");
|
||||||
|
@ -113,6 +225,7 @@ Suite * check_suite(void) {
|
||||||
/* Sub tests are added, one per line, here */
|
/* Sub tests are added, one per line, here */
|
||||||
|
|
||||||
tcase_add_test(tc, lhtableTest);
|
tcase_add_test(tc, lhtableTest);
|
||||||
|
tcase_add_test(tc, lhtableRandomized);
|
||||||
|
|
||||||
/* --------------------------------------------- */
|
/* --------------------------------------------- */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue