Implement key deletion

This commit is contained in:
bʰedoh₂ swé 2024-07-29 00:57:08 +05:00
parent e172298e1e
commit 5f539552ee
2 changed files with 42 additions and 14 deletions

View File

@ -16,10 +16,16 @@ bool hashtable_expand(hashtable* table) {
temptable.filled = 0; temptable.filled = 0;
temptable.items = newitems; temptable.items = newitems;
for (size_t i = 0; i < oldcapacity; i++) { for (size_t i = 0; i < oldcapacity; i++) {
if (olditems[i].name == NULL) if (olditems[i].name == NULL || olditems[i].name == (void*)1)
continue; continue;
size_t index = hashtable_insert(&temptable, olditems[i].name); size_t_optional index = hashtable_insert(&temptable, olditems[i].name);
newitems[index].data = olditems[i].data; if (!index.exists) {
hashtable_item* array = temptable.items;
for (size_t i = 0; i < temptable.capacity; i++)
free(array[i].name);
return false;
}
newitems[index.sizet].data = olditems[i].data;
} }
table->capacity = newcapacity; table->capacity = newcapacity;
table->filled = temptable.filled; table->filled = temptable.filled;
@ -29,6 +35,8 @@ bool hashtable_expand(hashtable* table) {
hashtable* hashtable_create(void) { hashtable* hashtable_create(void) {
hashtable* table = malloc(sizeof(hashtable)); hashtable* table = malloc(sizeof(hashtable));
if (table == NULL)
return NULL;
table->capacity = 16; table->capacity = 16;
table->items = calloc(16, sizeof(hashtable_item)); table->items = calloc(16, sizeof(hashtable_item));
return table; return table;
@ -40,29 +48,29 @@ size_t_optional hashtable_key(hashtable* table, char* name) {
while (1) { while (1) {
if (array[index].name == NULL) if (array[index].name == NULL)
return (size_t_optional) { false, 0 }; return (size_t_optional) { false, 0 };
if (array[index].name != (void*)(1))
if (!strcmp(name, array[index].name)) if (!strcmp(name, array[index].name))
return (size_t_optional) { true, index }; return (size_t_optional) { true, index };
else
index = (index + 1) & (table->capacity - 1); index = (index + 1) & (table->capacity - 1);
} }
} }
size_t hashtable_insert(hashtable* table, char* name) { size_t_optional hashtable_insert(hashtable* table, char* name) {
size_t index = sdbm(name) & (table->capacity - 1); size_t index = sdbm(name) & (table->capacity - 1);
hashtable_item* array = table->items; hashtable_item* array = table->items;
if ((table->capacity >> 2) * 3 < table->filled) { if ((table->capacity >> 2) * 3 < table->filled) {
hashtable_expand(table); hashtable_expand(table);
} }
while (1) { while (1) {
if (array[index].name == NULL) { if (array[index].name == NULL || array[index].name == (void*)1) {
array[index].name = malloc(strlen(name) + sizeof(name)); array[index].name = malloc(strlen(name) + sizeof(name));
strcpy(array[index].name, name); strcpy(array[index].name, name);
table->filled++; table->filled++;
return index; return (size_t_optional) {true, index};
} }
else else
if (!strcmp(array[index].name, name)) if (!strcmp(array[index].name, name))
return index; return (size_t_optional) {true, index};
else else
index = (index + 1) & (table->capacity - 1); index = (index + 1) & (table->capacity - 1);
} }
@ -83,6 +91,22 @@ void* hashtable_get(hashtable* table, char* name) {
} }
void hashtable_set(hashtable* table, char* name, void* data) { void hashtable_set(hashtable* table, char* name, void* data) {
size_t index = hashtable_insert(table, name); size_t_optional index = hashtable_insert(table, name);
table->items[index].data = data; if (index.exists)
table->items[index.sizet].data = data;
}
void hashtable_delete(hashtable* table, char* name) {
size_t_optional index = hashtable_key(table, name);
if (index.exists) {
table->items[index.sizet].name = (void*)1;
table->filled--;
}
}
void hashtable_forall(hashtable* table, void (*callback)(char*, void*)) {
size_t capacity = table->capacity;
hashtable_item* items = table->items;
for (size_t i = 0; i < capacity; i++)
callback(items[i].name, items[i].data);
} }

View File

@ -23,8 +23,12 @@ void hashtable_destroy(hashtable*);
size_t_optional hashtable_key(hashtable*, char*); size_t_optional hashtable_key(hashtable*, char*);
size_t hashtable_insert(hashtable*, char*); size_t_optional hashtable_insert(hashtable*, char*);
void* hashtable_get(hashtable* table, char* name); void* hashtable_get(hashtable* table, char* name);
void hashtable_set(hashtable* table, char* name, void* data); void hashtable_set(hashtable* table, char* name, void* data);
void hashtable_delete(hashtable*, char*);
void hashtable_forall(hashtable*, void (*)(char*, void*));