use nix build & meson & zlog
This commit is contained in:
parent
0123623742
commit
346768a144
60 changed files with 13739 additions and 0 deletions
215
src/lib/htab.c
Normal file
215
src/lib/htab.c
Normal 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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue