Add hashmap deinit
and get
functions
This commit is contained in:
parent
5d9c971060
commit
3c946d0a54
1 changed files with 59 additions and 8 deletions
67
hmap.c
67
hmap.c
|
@ -33,6 +33,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ typedef struct {
|
||||||
hmap_node *buckets;
|
hmap_node *buckets;
|
||||||
} hmap;
|
} hmap;
|
||||||
|
|
||||||
hmap_node* hmap_insert(hmap * map, void *key, size_t keysize, void *data);
|
void* hmap_insert(hmap * map, void *key, void *data);
|
||||||
|
|
||||||
hmap_node* hmap_node_init(void *key, size_t keysize, void *data) {
|
hmap_node* hmap_node_init(void *key, size_t keysize, void *data) {
|
||||||
hmap_node *node;
|
hmap_node *node;
|
||||||
|
@ -85,11 +86,20 @@ hmap_node* hmap_node_init(void *key, size_t keysize, void *data) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* hmap_node_attach(hmap_node *root, hmap_node *leaf) {
|
void hmap_node_deinit(hmap_node *node) {
|
||||||
|
hmap_node *current = node;
|
||||||
|
while (current != NULL) {
|
||||||
|
current = node->next;
|
||||||
|
free(node);
|
||||||
|
node = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* hmap_node_attach(hmap_node *root, hmap_node *leaf, size_t keysize) {
|
||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (root->key == leaf->key) {
|
if (memcmp(root->key, leaf->key, keysize) == 0) {
|
||||||
ret = root->data;
|
ret = root->data;
|
||||||
root->data = leaf->data;
|
root->data = leaf->data;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -104,6 +114,21 @@ void* hmap_node_attach(hmap_node *root, hmap_node *leaf) {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* hmap_node_search(hmap_node *root, void *key, size_t keysize) {
|
||||||
|
void *ret = NULL;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (memcmp(root->key, key, keysize) == 0) {
|
||||||
|
ret = root->data;
|
||||||
|
return ret;
|
||||||
|
} else if (root->next == NULL) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
root = root->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hmap* hmap_init(size_t keysize) {
|
hmap* hmap_init(size_t keysize) {
|
||||||
hmap* map;
|
hmap* map;
|
||||||
|
|
||||||
|
@ -120,6 +145,18 @@ hmap* hmap_init(size_t keysize) {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hmap_deinit(hmap *map) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < map->capacity; i++) {
|
||||||
|
if (map->buckets[i].next != NULL) {
|
||||||
|
hmap_node_deinit(map->buckets[i].next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(map->buckets);
|
||||||
|
free(map);
|
||||||
|
}
|
||||||
|
|
||||||
int hmap_expand(hmap *map) {
|
int hmap_expand(hmap *map) {
|
||||||
hmap_node *old;
|
hmap_node *old;
|
||||||
hmap_node *new;
|
hmap_node *new;
|
||||||
|
@ -133,7 +170,7 @@ int hmap_expand(hmap *map) {
|
||||||
for (i = 0; i < map->capacity; i++) {
|
for (i = 0; i < map->capacity; i++) {
|
||||||
current = &old[i];
|
current = &old[i];
|
||||||
while (current->key != NULL) {
|
while (current->key != NULL) {
|
||||||
hmap_insert(map, current->key, map->keysize, current->data);
|
hmap_insert(map, current->key, current->data);
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +178,7 @@ int hmap_expand(hmap *map) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hmap_node* hmap_insert(hmap * map, void *key, size_t keysize, void *data) {
|
void* hmap_insert(hmap *map, void *key, void *data) {
|
||||||
hmap_node *node;
|
hmap_node *node;
|
||||||
size_t idx;
|
size_t idx;
|
||||||
hmap_node *ret = NULL;
|
hmap_node *ret = NULL;
|
||||||
|
@ -149,14 +186,28 @@ hmap_node* hmap_insert(hmap * map, void *key, size_t keysize, void *data) {
|
||||||
if (map->len >= map->capacity / 2) {
|
if (map->len >= map->capacity / 2) {
|
||||||
if (hmap_expand(map)) return NULL;
|
if (hmap_expand(map)) return NULL;
|
||||||
}
|
}
|
||||||
node = hmap_node_init(key, keysize, data);
|
node = hmap_node_init(key, map->keysize, data);
|
||||||
if (node == NULL) return NULL;
|
if (node == NULL) return NULL;
|
||||||
idx = node->hash % map->capacity;
|
idx = node->hash % map->capacity;
|
||||||
if (map->buckets[idx].key == NULL) {
|
if (map->buckets[idx].key == NULL) {
|
||||||
map->buckets[idx] = *node;
|
map->buckets[idx] = *node;
|
||||||
} else {
|
} else {
|
||||||
ret = hmap_node_attach(&map->buckets[idx], node);
|
ret = hmap_node_attach(&map->buckets[idx], node, map->keysize);
|
||||||
}
|
}
|
||||||
// todo
|
map->len += 1;
|
||||||
|
if (ret == NULL)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return ret->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* hmap_get(hmap *map, void *key) {
|
||||||
|
uint64_t hash;
|
||||||
|
size_t idx;
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
hash = hash_fnv1a_64(key, map->keysize);
|
||||||
|
idx = hash % map->capacity;
|
||||||
|
ret = hmap_node_search(&map->buckets[idx], key, map->keysize);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue