Compare commits

...

2 Commits

Author SHA1 Message Date
34f7eaea19 Make it possible to pass "clojures" into hashtable_forall 2024-07-29 15:11:21 +05:00
43089c57de Some changes 2024-07-29 01:22:58 +05:00
2 changed files with 16 additions and 12 deletions

View File

@ -4,15 +4,14 @@
#include "sdbm.h" #include "sdbm.h"
#include "hashtable.h" #include "hashtable.h"
bool hashtable_expand(hashtable* table) { bool hashtable_recreate(hashtable* table) {
size_t oldcapacity = table->capacity; size_t oldcapacity = table->capacity;
size_t newcapacity = oldcapacity << 1;
hashtable_item* olditems = table->items; hashtable_item* olditems = table->items;
hashtable_item* newitems = calloc(newcapacity, sizeof(hashtable_item)); hashtable_item* newitems = calloc(16, sizeof(hashtable_item));
if (newitems == NULL) if (newitems == NULL)
return false; return false;
hashtable temptable; hashtable temptable;
temptable.capacity = newcapacity; temptable.capacity = 16;
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++) {
@ -23,11 +22,12 @@ bool hashtable_expand(hashtable* table) {
hashtable_item* array = temptable.items; hashtable_item* array = temptable.items;
for (size_t i = 0; i < temptable.capacity; i++) for (size_t i = 0; i < temptable.capacity; i++)
free(array[i].name); free(array[i].name);
free(newitems);
return false; return false;
} }
newitems[index.sizet].data = olditems[i].data; newitems[index.sizet].data = olditems[i].data;
} }
table->capacity = newcapacity; table->capacity = temptable.capacity;
table->filled = temptable.filled; table->filled = temptable.filled;
table->items = newitems; table->items = newitems;
return true; return true;
@ -59,7 +59,7 @@ 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_recreate(table);
} }
while (1) { while (1) {
if (array[index].name == NULL || array[index].name == (void*)1) { if (array[index].name == NULL || array[index].name == (void*)1) {
@ -96,17 +96,19 @@ void hashtable_set(hashtable* table, char* name, void* data) {
table->items[index.sizet].data = data; table->items[index.sizet].data = data;
} }
void hashtable_delete(hashtable* table, char* name) { bool hashtable_delete(hashtable* table, char* name) {
size_t_optional index = hashtable_key(table, name); size_t_optional index = hashtable_key(table, name);
if (index.exists) { if (index.exists) {
table->items[index.sizet].name = (void*)1; table->items[index.sizet].name = (void*)1;
table->filled--; table->filled--;
} return true;
} else
return false;
} }
void hashtable_forall(hashtable* table, void (*callback)(char*, void*)) { void hashtable_forall(hashtable* table, void (*callback)(char*, void*, void*), void* userdata) {
size_t capacity = table->capacity; size_t capacity = table->capacity;
hashtable_item* items = table->items; hashtable_item* items = table->items;
for (size_t i = 0; i < capacity; i++) for (size_t i = 0; i < capacity; i++)
callback(items[i].name, items[i].data); callback(items[i].name, items[i].data, userdata);
} }

View File

@ -17,6 +17,8 @@ typedef struct {
hashtable_item* items; hashtable_item* items;
} hashtable; } hashtable;
bool hashtable_recreate(hashtable* table);
hashtable* hashtable_create(void); hashtable* hashtable_create(void);
void hashtable_destroy(hashtable*); void hashtable_destroy(hashtable*);
@ -29,6 +31,6 @@ 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*); bool hashtable_delete(hashtable*, char*);
void hashtable_forall(hashtable*, void (*)(char*, void*)); void hashtable_forall(hashtable*, void (*)(char*, void*, void*), void*);