aboutsummaryrefslogtreecommitdiff
path: root/src/hash.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-12-25 17:28:09 -0500
committerFranklin Wei <git@fwei.tk>2015-12-25 17:28:09 -0500
commitf7041112f179aa79b6e315e7d57afbf76d3cd8bb (patch)
treec1c419845c0838ae15afe1da0cc54bf6447a760e /src/hash.c
parent2a81620aa5b740d7f77aff8177a983b7492b8ea0 (diff)
downloadnetcosm-f7041112f179aa79b6e315e7d57afbf76d3cd8bb.zip
netcosm-f7041112f179aa79b6e315e7d57afbf76d3cd8bb.tar.gz
netcosm-f7041112f179aa79b6e315e7d57afbf76d3cd8bb.tar.bz2
netcosm-f7041112f179aa79b6e315e7d57afbf76d3cd8bb.tar.xz
implement child lookup via hash table
Diffstat (limited to 'src/hash.c')
-rw-r--r--src/hash.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/hash.c b/src/hash.c
index 52a5b93..8e4888a 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -63,6 +63,49 @@ void hash_free(void *ptr)
free(map);
}
+void *hash_iterate(void *map, void **saveptr, void **keyptr)
+{
+ struct iterstate_t {
+ struct hash_map *map;
+ struct hash_node *node;
+ unsigned bucket;
+ };
+
+ struct iterstate_t *saved;
+
+ if(map)
+ {
+ *saveptr = malloc(sizeof(struct iterstate_t));
+ saved = *saveptr;
+
+ saved->map = map;
+ saved->bucket = 0;
+ saved->node = NULL;
+ }
+ else
+ saved = *saveptr;
+
+ for(;saved->bucket < saved->map->table_sz; ++(saved->bucket))
+ {
+ do {
+ if(!saved->node)
+ saved->node = saved->map->table[saved->bucket];
+ else
+ saved->node = saved->node->next;
+ if(saved->node)
+ {
+ if(keyptr)
+ *keyptr = saved->node->key;
+ return (void*)saved->node->data;
+ }
+ } while(saved->node);
+ }
+
+ free(saved);
+
+ return NULL;
+}
+
void *hash_insert(void *ptr, const void *key, const void *data)
{
struct hash_map *map = ptr;
@@ -119,3 +162,44 @@ void hash_insert_pairs(void *ptr, const struct hash_pair *pairs,
iter += pairsize;
}
}
+
+bool hash_remove(void *ptr, void *key)
+{
+ struct hash_map *map = ptr;
+ unsigned hash = map->hash(key) % map->table_sz;
+
+ struct hash_node *iter = map->table[hash], *last = NULL;
+
+ while(iter)
+ {
+ if(map->compare(key, iter->key) == 0)
+ {
+ if(last)
+ last->next = iter->next;
+ else
+ map->table[hash] = iter->next;
+ free(iter);
+ return true;
+ }
+ last = iter;
+ iter = iter->next;
+ }
+
+ return false;
+}
+
+void *hash_getkeyptr(void *ptr, const void *key)
+{
+ struct hash_map *map = ptr;
+ unsigned hash = map->hash(key) % map->table_sz;
+
+ struct hash_node *iter = map->table[hash];
+
+ while(iter)
+ {
+ if(map->compare(key, iter->key) == 0)
+ return (void*)(iter->key);
+ iter = iter->next;
+ }
+ return NULL;
+}