#include #include #include #include #include "map.h" void *alloc(size_t nmemb, size_t size) { void *p; p = calloc(nmemb, size); if (p == NULL) { perror("calloc"); exit(1); } return p; } void *ralloc(void *p, size_t size) { p = realloc(p, size); if (p == NULL) { perror("realloc"); exit(1); } return p; } static size_t hash(const void *src, size_t len) { const unsigned char *d = (const unsigned char *)src; size_t h = 0xcbf29ce484222325; size_t i; for (i = 0; i < len; i++) { h ^= d[i]; h *= 0x100000001b3; } return h; } void map_init(MAP *m) { m->cap = 100; m->len = 0; m->list = alloc(m->cap, sizeof(NODE*)); } static NODE *mapn_new(const void *key, size_t ksize, const void *val, size_t vsize) { NODE *n; n = alloc(1, sizeof(NODE)); n->key = alloc(1, ksize); n->ksize = ksize; memcpy(n->key, key, ksize); n->val = alloc(1, vsize); n->vsize = vsize; memcpy(n->val, val, vsize); return n; } static void mapn_setv(NODE *n, const void *val, size_t vsize) { n->val = ralloc(n->val, vsize); n->vsize = vsize; memcpy(n->val, val, vsize); } void map_set(MAP *m, const void *key, size_t ksize, const void *val, size_t vsize) { size_t h; NODE *n, *next; h = hash(key, ksize); h = h % m->cap; n = m->list[h]; if (n != NULL) { if (n->ksize == ksize && memcmp(n->key, key, n->ksize) == 0) { mapn_setv(n, val, vsize); } else { next = mapn_new(key, ksize, val, vsize); n->next = next; m->len++; } return; } n = mapn_new(key, ksize, val, vsize); m->list[h] = n; m->len++; } int map_get(MAP *m, const void *key, size_t ksize, void **val, size_t *vsize) { size_t h; NODE *n; int ok; h = hash(key, ksize); h = h % m->cap; n = m->list[h]; if (n == NULL) return -1; ok = 0; while (1) { if (n->ksize == ksize && memcmp(n->key, key, n->ksize) == 0) { ok = 1; break; } if (n->next == NULL) { break; } n = n->next; } if (!ok) return -1; *val = n->val; *vsize = n->vsize; return 0; }