#include #include #include "ds.h" ds_sll_t *ds_sll_new_node(void *data) { ds_sll_t *node; node = calloc(1, sizeof(ds_sll_t)); node->data = data; node->next = NULL; return node; } ds_dll_t *ds_dll_new_node(void *data) { ds_dll_t *node; node = calloc(1, sizeof(ds_dll_t)); node->data = data; node->next = node->prev = NULL; return node; } void ds_sll_insert(ds_sll_t *ll, void *data) { ds_ll_foreach(ds_sll_t, ll) { if (!cur->data) { cur->data = data; return; } else if (!cur->next) { cur->next = ds_sll_new_node(data); return; } } } void ds_dll_insert(ds_dll_t *ll, void *data) { ds_ll_foreach(ds_dll_t, ll) { if (!cur->data) { cur->data = data; return; } else if (!cur->next) { cur->next = ds_dll_new_node(data); cur->next->prev = cur; return; } } } void *ds_sll_remove(ds_sll_t **ll, unsigned idx) { int i; void *data; ds_sll_t *cur, *rm; if (!ll || !*ll) { return NULL; } for (i = -1, cur = *ll;; i++, cur = cur->next) { if (i + 1 == idx) { if (idx == 0) { rm = cur; if (!rm) { return NULL; } *ll = cur->next; } else { rm = cur->next; if (!rm) { return NULL; } cur->next = cur->next->next; } break; } } data = rm->data; free(rm); return data; } void *ds_dll_remove(ds_dll_t **ll, unsigned idx) { int i; void *data; ds_dll_t *cur, *rm; if (!ll || !*ll) { return NULL; } for (i = -1, cur = *ll;; i++, cur = cur->next) { if (i + 1 == idx) { if (idx == 0) { rm = cur; if (!rm) { return NULL; } if (cur->next) { cur->next->prev = NULL; *ll = cur->next; } } else { rm = cur->next; if (!rm) { return NULL; } cur->next = cur->next->next; if (cur->next) { cur->next->prev = cur; } } break; } } data = rm->data; free(rm); return data; } ds_hmp_t *ds_hmp_init(int data_len) { ds_hmp_t *hmp; hmp = calloc(1, sizeof(ds_hmp_t)); hmp->data_len = data_len; hmp->data = calloc(data_len, sizeof(ds_sll_t **)); return hmp; } void ds_hmp_free(ds_hmp_t **hmp) { int i; _ds_hmp_kv_t *kv; ds_sll_t *ll; if (!hmp || !*hmp) { return; } for (i = 0; i < (*hmp)->data_len; i++) { ll = (*hmp)->data[i]; while (ll && ll->data) { if ((kv = ds_sll_remove(&ll, 0))) { free(kv); } } if (ll) { free(ll); } } free((*hmp)->data); free(*hmp); } int _ds_hmp_gen_hash(char *str) { unsigned long hash = 5381; int c; while ((c = *str++)) { hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ } return hash; } void ds_hmp_insert(ds_hmp_t *hmp, char *key, void *data) { _ds_hmp_kv_t *kv; ds_sll_t *ll; unsigned hash_pos; kv = malloc(sizeof(_ds_hmp_kv_t)); kv->key = key; kv->val = data; hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len; if (!hmp->data[hash_pos]) { hmp->data[hash_pos] = calloc(1, sizeof(ds_sll_t)); } /* get the ll and put the data into it */ ll = hmp->data[hash_pos]; ds_sll_insert(ll, kv); } void *ds_hmp_get(ds_hmp_t *hmp, char *key) { ds_sll_t *cur, *ll; unsigned hash_pos; hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len; ll = hmp->data[hash_pos]; if (!ll) { return NULL; } ds_ll_foreach(ds_sll_t, ll) { if (strcmp(((_ds_hmp_kv_t *)cur->data)->key, key) == 0) { return ((_ds_hmp_kv_t *)cur->data)->val; } } return NULL; } void *ds_hmp_remove(ds_hmp_t *hmp, char *key) { int i; void *data; unsigned hash_pos; ds_sll_t *ll, *cur; _ds_hmp_kv_t *kv; hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len; ll = hmp->data[hash_pos]; if (!ll) { return NULL; } for (i = 0, cur = ll; cur; i++, cur = cur->next) { if (strcmp(((_ds_hmp_kv_t *)cur->data)->key, key) == 0) { kv = ds_sll_remove(&ll, i); hmp->data[hash_pos] = ll; if (!kv) { return NULL; } data = kv->val; free(kv); return data; } } return NULL; }