still working on hashtable remove

This commit is contained in:
herbglitch 2025-02-28 18:54:56 -07:00
parent 7977555021
commit 262e6ef9de
2 changed files with 31 additions and 43 deletions

View file

@ -1,7 +1,6 @@
#include "arc/std/hashtable.h" #include "arc/std/hashtable.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include "arc/std/vector.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -214,62 +213,51 @@ void ARC_Hashtable_UnsetNodeAtIndexFromArray(ARC_HashtableNode *nodes, uint32_t
//get the currently used next index //get the currently used next index
uint32_t nextIndex = nodes[index].nextIndex; 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 the next index will be moved into the correct spot
if(index == nodes[nextIndex].hashvalue % capacity){ 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 //NOTE: I couldn't figure out an elegant way of handling this, so for now we remove then readd clashing nodes
//copy the next index back //reset the previous index's next index
nodes[index] = nodes[nextIndex]; nodes[previousIndex].nextIndex = previousIndex;
//create the temporary node vector //reset the last moved node's next index
ARC_Vector *conflictingNodes; nodes[index].nextIndex = index;
ARC_Vector_DestroyDataFn destroyDataFn = ARC_Hashtable_VectorDestroyHashtableNodeFn;
ARC_Vector_Create(&conflictingNodes, NULL, &destroyDataFn);
//start the loop at the empty to avoid using a do while loop //get the starting conflict index
index = nextIndex; index = nextIndex;
//the last index copied, used for clearing //get the starting conflict node (the first one will only be used for its next index)
uint32_t lastIndex = 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 //loop through remaining next nodes adding them to a temporary vector and clearing them from the nodes
while(nodes[index].nextIndex != index){ while(nodeCopy.nextIndex != index){
lastIndex = 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 //copy and clear node
index = nodes[index].nextIndex; nodes[index] = (ARC_HashtableNode){ NULL, NULL, 0, index };
//copy and add the nodes to the visted indexes //add back to the table
ARC_HashtableNode *nodeCopy = (ARC_HashtableNode *)malloc(sizeof(ARC_HashtableNode)); ARC_HashtableNode_SetNearestNodeToArray(nodes, capacity, nodeCopy);
*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 };
} }
//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; return;
} }
//move the next node back
nodes[index] = nodes[nextIndex];
//moves the next index into the next used slot //moves the next index into the next used slot
nodes[index].nextIndex = nextIndex; nodes[index].nextIndex = nextIndex;
//update the previousIndex
previousIndex = index;
//check the next index //check the next index
index = nextIndex; index = nextIndex;
} }

View file

@ -148,12 +148,12 @@ ARC_TEST(Hashtable_Add_Get_Remove_100){
ARC_Hashtable_DestroyKeyValueFn destroyKeyValueFn = TEST_Hashtable_DestroyKeyValueFn; ARC_Hashtable_DestroyKeyValueFn destroyKeyValueFn = TEST_Hashtable_DestroyKeyValueFn;
ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, &destroyKeyValueFn); ARC_Hashtable_Create(&hashtable, NULL, &keyCompareFn, &destroyKeyValueFn);
const char *keyCStr = "key%03u"; const char *keyCStr = "key%09u";
uint32_t tempMaxVal = 10000; uint32_t tempMaxVal = 10000;
for(uint32_t maxVal = 0; maxVal < tempMaxVal; maxVal++){ for(uint32_t maxVal = 0; maxVal < tempMaxVal; maxVal++){
for(uint32_t index = 0; index < maxVal; index++){ 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); sprintf(key, keyCStr, index);
int32_t *val = (int32_t *)malloc(sizeof(int32_t)); 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++){ 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); sprintf(key, keyCStr, index);
ARC_CHECK(index == *(int32_t *)ARC_Hashtable_Get(hashtable, key)); 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++){ 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); sprintf(key, keyCStr, index);
TEST_Hashtable_Print(hashtable); TEST_Hashtable_Print(hashtable);