diff --git a/src/std/hashtable.c b/src/std/hashtable.c index 74351bc..f1e3a27 100644 --- a/src/std/hashtable.c +++ b/src/std/hashtable.c @@ -196,42 +196,42 @@ void ARC_Hashtable_Add(ARC_Hashtable *hashtable, void *key, void *value){ hashtable->currentSize++; } -void ARC_Hashtable_MoveNextBack(ARC_HashtableNode *nodes, uint32_t capacity, uint32_t *index){ - //get the currently used next index - uint32_t nextIndex = nodes[*index].nextIndex; +void ARC_Hashtable_UnsetNodeAtIndexFromArray(ARC_HashtableNode *nodes, uint32_t capacity, uint32_t index){ + while(nodes[index].nextIndex != index){ + //get the currently used next index + uint32_t nextIndex = nodes[index].nextIndex; - //if the next index is an end, but it is in the right place this should break - uint32_t hashIndex = nodes[nextIndex].hashvalue % capacity; + //if the next index is an end, but it is in the right place this should break + uint32_t hashIndex = nodes[nextIndex].hashvalue % capacity; - printf("%02u -> %2u\t%2u\n", *index, nextIndex, hashIndex); + printf("%02u -> %2u\t%2u\n", index, nextIndex, hashIndex); - //if the end has been reached, set index to the end - if(*index == nextIndex){ - //if the next index is already in the right place return out - if(nodes->nextIndex == hashIndex){ - return; + //move the current node back one + nodes[index] = nodes[nextIndex]; + + //if the end has been reached, set index to the end + if(nodes[nextIndex].nextIndex == hashIndex){ + //fix if moved back but next index not updated + nodes[nextIndex].nextIndex = hashIndex; + break; } - //set the last index - *index = nextIndex; - return; + //move set the current index to the end + if(nodes[index].nextIndex == nextIndex){ + nodes[index].nextIndex = index; + index = nextIndex; + break; + } + + //moves the next index into the next used slot + nodes[index].nextIndex = nextIndex; + + //get the next index to move back + index = nextIndex; } - //run a next index to be used if the last index is this index - uint32_t testIndex = nextIndex; - ARC_Hashtable_MoveNextBack(nodes, capacity, &testIndex); - - if(testIndex != nextIndex){ - //move the current node back one - nodes[*index] = nodes[nextIndex]; - } - - //moves the next index into the next used slot - nodes[*index].nextIndex = nextIndex; - - //get the next index to move back - *index = nextIndex; - + //set the current value to an empty node + nodes[index] = (ARC_HashtableNode){ NULL, NULL, 0, index }; } void ARC_Hashtable_Remove(ARC_Hashtable *hashtable, void *key){ @@ -251,7 +251,7 @@ void ARC_Hashtable_Remove(ARC_Hashtable *hashtable, void *key){ } //check the last index if the others could not find the node - if(nodeFound == ARC_False && hashtable->keyCompareFn(hashtable->nodes[index].key, key) == ARC_True){ + if(nodeFound == ARC_False && hashtable->nodes[index].key != NULL && hashtable->keyCompareFn(hashtable->nodes[index].key, key) == ARC_True){ nodeFound = ARC_True; } @@ -272,10 +272,7 @@ void ARC_Hashtable_Remove(ARC_Hashtable *hashtable, void *key){ printf("MOVE:\n"); //move all next items back - ARC_Hashtable_MoveNextBack(hashtable->nodes, hashtable->currentCapacity, &index); - - //set the current value to an empty node - hashtable->nodes[index] = (ARC_HashtableNode){ NULL, NULL, 0, index }; + ARC_Hashtable_UnsetNodeAtIndexFromArray(hashtable->nodes, hashtable->currentCapacity, index); //we have removed the item so we can decrease the current size hashtable->currentSize--; @@ -350,24 +347,16 @@ void *ARC_Hashtable_Get(ARC_Hashtable *hashtable, void *key){ ARC_HashtableNode node = hashtable->nodes[index]; //check each available node for a match - for(uint32_t nextIndex = index; node.key != NULL; node = hashtable->nodes[nextIndex]){ + while(node.nextIndex != index){ //if the key is found, return its value if(hashtable->keyCompareFn(node.key, key) == ARC_True){ return node.value; } - //up the current index by one - nextIndex++; + //up the current index to the next available index + index = node.nextIndex; - //cycle back to the first index if it is above the array's capacity - if(nextIndex >= hashtable->currentCapacity){ - nextIndex = 0; - } - - //check if the loop has circled back to the starting index to stop checking - if(index == nextIndex){ - break; - } + node = hashtable->nodes[index]; } //if the key is found, return its value diff --git a/tests/std/hashtable.c b/tests/std/hashtable.c index 9cff201..b81d1ea 100644 --- a/tests/std/hashtable.c +++ b/tests/std/hashtable.c @@ -20,6 +20,7 @@ void TEST_Hashtable_Print(void *hashtable){ } ARC_Bool TEST_Hashtable_KeyCompareDataFn(void *dataA, void *dataB){ + printf("%s : %s\n", (char *)dataA, (char *)dataB); return (ARC_Bool)strcmp((const char *)dataA, (const char *)dataB) == 0; } @@ -38,107 +39,108 @@ ARC_TEST(Hashtable_Init){ ARC_Hashtable_Destroy(hashtable); } -ARC_TEST(Hashtable_Add_Get_Remove){ - ARC_Hashtable *hashtable; - ARC_Hashtable_KeyCompareFn keyCompareFn = TEST_Hashtable_KeyCompareDataFn; - ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, NULL); - - char *key0 = (char *)"key0"; - char *key1 = (char *)"key1"; - char *key2 = (char *)"key2"; - char *key3 = (char *)"key3"; - char *key4 = (char *)"key4"; - char *key5 = (char *)"key5"; - char *key6 = (char *)"key6"; - char *key7 = (char *)"key7"; - char *key8 = (char *)"key8"; - - int32_t val0 = 2; - int32_t val1 = 7; - int32_t val2 = 4; - int32_t val3 = 9; - int32_t val4 = 0; - int32_t val5 = 1; - int32_t val6 = 3; - int32_t val7 = 5; - int32_t val8 = 6; - - ARC_Hashtable_Add(hashtable, key0, &val0); - ARC_Hashtable_Add(hashtable, key1, &val1); - ARC_Hashtable_Add(hashtable, key2, &val2); - ARC_Hashtable_Add(hashtable, key3, &val3); - ARC_Hashtable_Add(hashtable, key4, &val4); - ARC_Hashtable_Add(hashtable, key5, &val5); - ARC_Hashtable_Add(hashtable, key6, &val6); - ARC_Hashtable_Add(hashtable, key7, &val7); - ARC_Hashtable_Add(hashtable, key8, &val8); - - ARC_CHECK(2 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key0")); - ARC_CHECK(7 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key1")); - ARC_CHECK(4 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key2")); - ARC_CHECK(9 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key3")); - ARC_CHECK(0 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key4")); - ARC_CHECK(1 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key5")); - ARC_CHECK(3 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key6")); - ARC_CHECK(5 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key7")); - ARC_CHECK(6 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key8")); - - ARC_Hashtable_Remove(hashtable, (void *)"key2"); - - ARC_CHECK(2 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key0")); - ARC_CHECK(7 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key1")); - ARC_CHECK(9 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key3")); - ARC_CHECK(0 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key4")); - ARC_CHECK(1 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key5")); - ARC_CHECK(3 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key6")); - ARC_CHECK(5 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key7")); - ARC_CHECK(6 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key8")); - - ARC_Hashtable_Remove(hashtable, (void *)"key0"); - ARC_Hashtable_Remove(hashtable, (void *)"key4"); - ARC_Hashtable_Remove(hashtable, (void *)"key3"); - ARC_Hashtable_Remove(hashtable, (void *)"key8"); - ARC_Hashtable_Remove(hashtable, (void *)"key6"); - ARC_Hashtable_Remove(hashtable, (void *)"key7"); - - ARC_CHECK(7 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key1")); - ARC_CHECK(1 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key5")); - - ARC_Hashtable_Remove(hashtable, (void *)"key1"); - ARC_Hashtable_Remove(hashtable, (void *)"key5"); - - ARC_Hashtable_Destroy(hashtable); -} - -ARC_TEST(Hashtable_Add_Get_100){ - ARC_Hashtable *hashtable; - ARC_Hashtable_KeyCompareFn keyCompareFn = TEST_Hashtable_KeyCompareDataFn; - ARC_Hashtable_DestroyKeyValueFn destroyKeyValueFn = TEST_Hashtable_DestroyKeyValueFn; - ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, &destroyKeyValueFn); - - const char *keyCStr = "key%03u"; - - for(uint32_t index = 0; index < 100; index++){ - char *key = (char *)malloc(strlen(keyCStr)); - sprintf(key, keyCStr, index); - - int32_t *val = (int32_t *)malloc(sizeof(int32_t)); - *val = index; - - ARC_Hashtable_Add(hashtable, key, val); - } - - for(uint32_t index = 0; index < 100; index++){ - char *key = (char *)malloc(strlen(keyCStr)); - sprintf(key, keyCStr, index); - - ARC_CHECK(index == *(int32_t *)ARC_Hashtable_Get(hashtable, key)); - - free(key); - } - - ARC_Hashtable_Destroy(hashtable); -} +//ARC_TEST(Hashtable_Add_Get_Remove){ +// ARC_Hashtable *hashtable; +// ARC_Hashtable_KeyCompareFn keyCompareFn = TEST_Hashtable_KeyCompareDataFn; +// ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, NULL); +// +// char *key0 = (char *)"key0"; +// char *key1 = (char *)"key1"; +// char *key2 = (char *)"key2"; +// char *key3 = (char *)"key3"; +// char *key4 = (char *)"key4"; +// char *key5 = (char *)"key5"; +// char *key6 = (char *)"key6"; +// char *key7 = (char *)"key7"; +// char *key8 = (char *)"key8"; +// +// int32_t val0 = 2; +// int32_t val1 = 7; +// int32_t val2 = 4; +// int32_t val3 = 9; +// int32_t val4 = 0; +// int32_t val5 = 1; +// int32_t val6 = 3; +// int32_t val7 = 5; +// int32_t val8 = 6; +// +// ARC_Hashtable_Add(hashtable, key0, &val0); +// ARC_Hashtable_Add(hashtable, key1, &val1); +// ARC_Hashtable_Add(hashtable, key2, &val2); +// ARC_Hashtable_Add(hashtable, key3, &val3); +// ARC_Hashtable_Add(hashtable, key4, &val4); +// ARC_Hashtable_Add(hashtable, key5, &val5); +// ARC_Hashtable_Add(hashtable, key6, &val6); +// ARC_Hashtable_Add(hashtable, key7, &val7); +// ARC_Hashtable_Add(hashtable, key8, &val8); +// +// ARC_CHECK(2 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key0")); +// ARC_CHECK(7 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key1")); +// ARC_CHECK(4 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key2")); +// ARC_CHECK(9 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key3")); +// ARC_CHECK(0 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key4")); +// ARC_CHECK(1 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key5")); +// ARC_CHECK(3 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key6")); +// ARC_CHECK(5 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key7")); +// ARC_CHECK(6 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key8")); +// +// TEST_Hashtable_Print(hashtable); +// ARC_Hashtable_Remove(hashtable, (void *)"key2"); +// +// ARC_CHECK(2 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key0")); +// ARC_CHECK(7 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key1")); +// ARC_CHECK(9 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key3")); +// ARC_CHECK(0 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key4")); +// ARC_CHECK(1 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key5")); +// ARC_CHECK(3 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key6")); +// ARC_CHECK(5 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key7")); +// ARC_CHECK(6 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key8")); +// +// ARC_Hashtable_Remove(hashtable, (void *)"key0"); +// ARC_Hashtable_Remove(hashtable, (void *)"key4"); +// ARC_Hashtable_Remove(hashtable, (void *)"key3"); +// ARC_Hashtable_Remove(hashtable, (void *)"key8"); +// ARC_Hashtable_Remove(hashtable, (void *)"key6"); +// ARC_Hashtable_Remove(hashtable, (void *)"key7"); +// +// ARC_CHECK(7 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key1")); +// ARC_CHECK(1 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key5")); +// +// ARC_Hashtable_Remove(hashtable, (void *)"key1"); +// ARC_Hashtable_Remove(hashtable, (void *)"key5"); +// +// ARC_Hashtable_Destroy(hashtable); +//} +// +//ARC_TEST(Hashtable_Add_Get_100){ +// ARC_Hashtable *hashtable; +// ARC_Hashtable_KeyCompareFn keyCompareFn = TEST_Hashtable_KeyCompareDataFn; +// ARC_Hashtable_DestroyKeyValueFn destroyKeyValueFn = TEST_Hashtable_DestroyKeyValueFn; +// ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, &destroyKeyValueFn); +// +// const char *keyCStr = "key%03u"; +// +// for(uint32_t index = 0; index < 100; index++){ +// char *key = (char *)malloc(strlen(keyCStr)); +// sprintf(key, keyCStr, index); +// +// int32_t *val = (int32_t *)malloc(sizeof(int32_t)); +// *val = index; +// +// ARC_Hashtable_Add(hashtable, key, val); +// } +// +// for(uint32_t index = 0; index < 100; index++){ +// char *key = (char *)malloc(strlen(keyCStr)); +// sprintf(key, keyCStr, index); +// +// ARC_CHECK(index == *(int32_t *)ARC_Hashtable_Get(hashtable, key)); +// +// free(key); +// } +// +// ARC_Hashtable_Destroy(hashtable); +//} ARC_TEST(Hashtable_Add_Get_Remove_100){ ARC_Hashtable *hashtable; @@ -147,35 +149,40 @@ ARC_TEST(Hashtable_Add_Get_Remove_100){ ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, &destroyKeyValueFn); const char *keyCStr = "key%03u"; - uint32_t maxVal = 15; + uint32_t tempMaxVal = 10000; - for(uint32_t index = 0; index < maxVal; index++){ - char *key = (char *)malloc(strlen(keyCStr)); - sprintf(key, keyCStr, index); + for(uint32_t maxVal = 0; maxVal < tempMaxVal; maxVal++){ + for(uint32_t index = 0; index < maxVal; index++){ + char *key = (char *)malloc(strlen(keyCStr)); + sprintf(key, keyCStr, index); - int32_t *val = (int32_t *)malloc(sizeof(int32_t)); - *val = index; + int32_t *val = (int32_t *)malloc(sizeof(int32_t)); + *val = index; - ARC_Hashtable_Add(hashtable, key, val); - } + ARC_Hashtable_Add(hashtable, key, val); + } - for(uint32_t index = 0; index < maxVal; index++){ - char *key = (char *)malloc(strlen(keyCStr)); - sprintf(key, keyCStr, index); + for(uint32_t index = 0; index < maxVal; index++){ + char *key = (char *)malloc(strlen(keyCStr)); + sprintf(key, keyCStr, index); - ARC_CHECK(index == *(int32_t *)ARC_Hashtable_Get(hashtable, key)); + ARC_CHECK(index == *(int32_t *)ARC_Hashtable_Get(hashtable, key)); - free(key); - } + free(key); + } - for(uint32_t index = 0; index < maxVal; index++){ - char *key = (char *)malloc(strlen(keyCStr)); - sprintf(key, keyCStr, index); + for(uint32_t index = 0; index < maxVal; index++){ + char *key = (char *)malloc(strlen(keyCStr)); + sprintf(key, keyCStr, index); - TEST_Hashtable_Print(hashtable); - ARC_Hashtable_Remove(hashtable, key); + TEST_Hashtable_Print(hashtable); + ARC_CHECK(index == *(int32_t *)ARC_Hashtable_Get(hashtable, key)); + ARC_Hashtable_Remove(hashtable, key); - free(key); + free(key); + } + + printf("%u\n", maxVal); } ARC_Hashtable_Destroy(hashtable);