use nix build & meson & zlog

This commit is contained in:
Rongsong Shen 2025-11-03 18:19:59 +08:00
parent 0123623742
commit 346768a144
60 changed files with 13739 additions and 0 deletions

215
src/lib/htab.c Normal file
View file

@ -0,0 +1,215 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "htab.h"
#include "utils.h"
#define HASH_KEY_HASH(t, key) \
(((t)->fn.hash != NULL) ? ((t)->fn.hash)(key) : (unsigned long)key)
#define HASH_KEY_CMP(t, k1, k2) \
(((t)->fn.cmp != NULL) ? ((t)->fn.cmp)((k1), (k2)) : ((k1) != (k2)))
#define HASH_KEY_COPY(t, key) \
(((t)->fn.copy != NULL) ? ((t)->fn.copy)(key) : (key))
#define HASH_KEY_FREE(t, key) \
do { \
if (((t)->fn.free != NULL) && ((key) != NULL)) { \
(t)->fn.free(key); \
} \
} while (0)
static unsigned int hash_code(const char* key)
{
unsigned int hc = 5381;
int c;
while ((c = *key++)) {
hc = ((hc << 5) + hc) + c;
}
return hc;
}
static unsigned int string_hash(void* data)
{
return hash_code((const char*)data);
}
static int string_cmp(void* d1,
void* d2)
{
return (int)strcmp((char*)d1, (char*)d2);
}
static void* string_dup(void* data)
{
return (void*)strdup((char*)data);
}
static void string_free(void* data)
{
if (data != NULL) {
free(data);
}
}
hash_key_fn_t string_hash_key = {
.hash = (hash_key_hash_fn_t)string_hash,
.cmp = (hash_key_cmp_fn_t)string_cmp,
.copy = (hash_key_copy_fn_t)string_dup,
.free = (hash_key_free_fn_t)string_free
};
hash_key_fn_t int_hash_key = {
.hash = NULL,
.cmp = NULL,
.copy = NULL,
.free = NULL
};
int ht_init(htab_t* t,
int nslots,
hash_key_fn_t fn)
{
if ((t == NULL) || (nslots <= 1)) {
return -EINVAL;
}
mylock_init(&(t->lock));
t->slots = (hent_t**)calloc(nslots, sizeof(hent_t*));
if (t->slots == NULL) {
return -ENOMEM;
}
t->nslots = nslots;
t->fn = fn;
return 0;
}
void ht_fini(htab_t* t)
{
int i;
hent_t* e;
if (t == NULL) {
return;
}
for (i = 0; i < t->nslots; i++) {
while ((e = t->slots[i]) != NULL) {
t->slots[i] = e->next;
e->next = NULL;
HASH_KEY_FREE(t, e->key);
free(e);
}
}
free(t->slots);
return;
}
hent_t* ht_get(htab_t* t,
void* key)
{
unsigned int hc;
hent_t* e;
if (t == NULL) {
SET_ERROR(EINVAL);
return NULL;
}
hc = HASH_KEY_HASH(t, key) % (t->nslots);
mylock_lock(&(t->lock));
e = t->slots[hc];
while (e != NULL) {
if (HASH_KEY_CMP(t, e->key, key) == 0) {
break;
}
e = e->next;
}
mylock_unlock(&(t->lock));
return e;
}
hent_t* ht_add(htab_t* t,
void* key)
{
unsigned int hc;
hent_t* e;
if ((t == NULL) || (key == NULL)) {
return NULL;
}
e = ht_get(t, key);
if (e != NULL) {
return e;
}
e = (hent_t*)calloc(1, sizeof(*e));
if (e == NULL) {
return NULL;
}
e->key = HASH_KEY_COPY(t, key);
if (e->key == NULL) {
free(e);
return NULL;
}
e->data = -1;
hc = HASH_KEY_HASH(t, key) % (t->nslots);
mylock_init(&(t->lock));
e->next = t->slots[hc];
t->slots[hc] = e;
mylock_unlock(&(t->lock));
return e;
}
int ht_del(htab_t* t,
void* key)
{
unsigned int hc;
hent_t** e;
int deleted = 0;
if ((t == NULL) || (key == NULL)) {
return -EINVAL;
}
hc = HASH_KEY_HASH(t, key) % (t->nslots);
mylock_init(&(t->lock));
e = &(t->slots[hc]);
while ((*e) != NULL) {
if (HASH_KEY_CMP(t, (*e)->key, key) == 0) {
hent_t* e1 = *e;
*e = e1->next;
HASH_KEY_FREE(t, e1->key);
free(e1);
deleted = 1;
break;
}
e = &((*e)->next);
}
mylock_unlock(&(t->lock));
if (deleted) {
return 1;
}
return -ENOENT;
}