Files
ds/ds.c
2025-08-16 18:25:33 -04:00

258 lines
3.8 KiB
C

#include <stdlib.h>
#include <string.h>
#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;
}