From 262e6ef9decdb89f1edece1a5c88745dcf1aa9ac Mon Sep 17 00:00:00 2001 From: herbglitch Date: Fri, 28 Feb 2025 18:54:56 -0700 Subject: [PATCH] still working on hashtable remove --- src/std/hashtable.c | 66 ++++++++++++++++++------------------------- tests/std/hashtable.c | 8 +++--- 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/src/std/hashtable.c b/src/std/hashtable.c index b4fa673..ff61f1b 100644 --- a/src/std/hashtable.c +++ b/src/std/hashtable.c @@ -1,7 +1,6 @@ #include "arc/std/hashtable.h" #include "arc/std/errno.h" -#include "arc/std/vector.h" #include #include @@ -214,62 +213,51 @@ void ARC_Hashtable_UnsetNodeAtIndexFromArray(ARC_HashtableNode *nodes, uint32_t //get the currently used next index uint32_t nextIndex = nodes[index].nextIndex; + //move the next node back + nodes[index] = nodes[nextIndex]; + //if the next index will be moved into the correct spot if(index == nodes[nextIndex].hashvalue % capacity){ - //NOTE: I couldn't figure out an elegant way of handling this, so for now we remove all clashing nodes, then add them back - //copy the next index back - nodes[index] = nodes[nextIndex]; + //NOTE: I couldn't figure out an elegant way of handling this, so for now we remove then readd clashing nodes + //reset the previous index's next index + nodes[previousIndex].nextIndex = previousIndex; - //create the temporary node vector - ARC_Vector *conflictingNodes; - ARC_Vector_DestroyDataFn destroyDataFn = ARC_Hashtable_VectorDestroyHashtableNodeFn; - ARC_Vector_Create(&conflictingNodes, NULL, &destroyDataFn); + //reset the last moved node's next index + nodes[index].nextIndex = index; - //start the loop at the empty to avoid using a do while loop + //get the starting conflict index index = nextIndex; - //the last index copied, used for clearing - uint32_t lastIndex = index; + //get the starting conflict node (the first one will only be used for its next index) + ARC_HashtableNode nodeCopy = nodes[index]; + + //clear the last moved node + nodes[index] = (ARC_HashtableNode){ NULL, NULL, 0, index }; + printf("move: %u -> %u\t%u\t%s\n", index, nodeCopy.nextIndex, nodeCopy.hashvalue % capacity, (char *)nodeCopy.key); //loop through remaining next nodes adding them to a temporary vector and clearing them from the nodes - while(nodes[index].nextIndex != index){ - lastIndex = index; + while(nodeCopy.nextIndex != index){ + //move to the next node + index = nodeCopy.nextIndex; + nodeCopy = nodes[index]; + printf("next: %u -> %u\t%u\t%s\n", index, nodeCopy.nextIndex, nodeCopy.hashvalue % capacity, (char *)nodeCopy.key); - //move to the nextIndex - index = nodes[index].nextIndex; + //copy and clear node + nodes[index] = (ARC_HashtableNode){ NULL, NULL, 0, index }; - //copy and add the nodes to the visted indexes - ARC_HashtableNode *nodeCopy = (ARC_HashtableNode *)malloc(sizeof(ARC_HashtableNode)); - *nodeCopy = nodes[index]; - printf("node: %u) %u\t%u\t%s\n", index, nodeCopy->nextIndex, nodeCopy->hashvalue % capacity, (char *)(nodeCopy->key)); - ARC_Vector_Add(conflictingNodes, nodeCopy); - - //clear the copied index - nodes[lastIndex] = (ARC_HashtableNode){ NULL, NULL, 0, lastIndex }; + //add back to the table + ARC_HashtableNode_SetNearestNodeToArray(nodes, capacity, nodeCopy); } - //clear the last copied node - nodes[index] = (ARC_HashtableNode){ NULL, NULL, 0, index }; - - //re add the nodes - for(uint32_t vectorIndex = 0; vectorIndex < ARC_Vector_GetSize(conflictingNodes); vectorIndex++){ - ARC_HashtableNode node = *(ARC_HashtableNode *)ARC_Vector_Get(conflictingNodes, vectorIndex); - printf("node: %u) %u\t%u\t%s\n", index, node.nextIndex, node.hashvalue % capacity, (char *)(node.key)); - ARC_HashtableNode_SetNearestNodeToArray(nodes, capacity, node); - } - - //cleanup - ARC_Vector_Destroy(conflictingNodes); - return; } - //move the next node back - nodes[index] = nodes[nextIndex]; - //moves the next index into the next used slot nodes[index].nextIndex = nextIndex; + //update the previousIndex + previousIndex = index; + //check the next index index = nextIndex; } diff --git a/tests/std/hashtable.c b/tests/std/hashtable.c index b81d1ea..fbbab78 100644 --- a/tests/std/hashtable.c +++ b/tests/std/hashtable.c @@ -148,12 +148,12 @@ ARC_TEST(Hashtable_Add_Get_Remove_100){ ARC_Hashtable_DestroyKeyValueFn destroyKeyValueFn = TEST_Hashtable_DestroyKeyValueFn; ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, &destroyKeyValueFn); - const char *keyCStr = "key%03u"; + const char *keyCStr = "key%09u"; uint32_t tempMaxVal = 10000; for(uint32_t maxVal = 0; maxVal < tempMaxVal; maxVal++){ for(uint32_t index = 0; index < maxVal; index++){ - char *key = (char *)malloc(strlen(keyCStr)); + char *key = (char *)malloc(strlen(keyCStr) + 12); sprintf(key, keyCStr, index); int32_t *val = (int32_t *)malloc(sizeof(int32_t)); @@ -163,7 +163,7 @@ ARC_TEST(Hashtable_Add_Get_Remove_100){ } for(uint32_t index = 0; index < maxVal; index++){ - char *key = (char *)malloc(strlen(keyCStr)); + char *key = (char *)malloc(strlen(keyCStr) + 12); sprintf(key, keyCStr, index); ARC_CHECK(index == *(int32_t *)ARC_Hashtable_Get(hashtable, key)); @@ -172,7 +172,7 @@ ARC_TEST(Hashtable_Add_Get_Remove_100){ } for(uint32_t index = 0; index < maxVal; index++){ - char *key = (char *)malloc(strlen(keyCStr)); + char *key = (char *)malloc(strlen(keyCStr) + 12); sprintf(key, keyCStr, index); TEST_Hashtable_Print(hashtable);