use librtti for worker/queue/resource
This commit is contained in:
parent
532c68e6e1
commit
2ee87d4ee6
23 changed files with 1078 additions and 396 deletions
460
src/lib/kv.c
460
src/lib/kv.c
|
|
@ -8,6 +8,72 @@
|
|||
|
||||
typedef struct kvent_ kvent_t;
|
||||
|
||||
static uint32_t hash_int_key(void* key)
|
||||
{
|
||||
uint64_t intkey = (uint64_t)(long)key;
|
||||
|
||||
return hash64(intkey);
|
||||
}
|
||||
|
||||
static int assign_int_key(void** dst, void* src)
|
||||
{
|
||||
*dst = src;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmp_int_key(void* key1, void* key2)
|
||||
{
|
||||
uint64_t intkey1 = (uint64_t)(long)key1;
|
||||
uint64_t intkey2 = (uint64_t)(long)key2;
|
||||
|
||||
if (intkey1 > intkey2) {
|
||||
return 1;
|
||||
} else if (intkey2 > intkey1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
kv_key_ops_t int_key_ops = { .hash = (kv_key_hash_fn_t)hash_int_key,
|
||||
.assign = (kv_key_assign_fn_t)assign_int_key,
|
||||
.cmp = (kv_key_cmp_fn_t)cmp_int_key };
|
||||
|
||||
static uint32_t hash_string_key(void* key) { return hash_string((char*)key); }
|
||||
|
||||
static int cmp_string_key(void* key1, void* key2)
|
||||
{
|
||||
return strcmp((char*)key1, (char*)key2);
|
||||
}
|
||||
|
||||
static int assign_string_key(char** dst, char* src)
|
||||
{
|
||||
char* p = strdup(src);
|
||||
|
||||
if (p == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*dst = p;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void destroy_string_key(char* s)
|
||||
{
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
kv_key_ops_t string_key_ops
|
||||
= { .hash = (kv_key_hash_fn_t)hash_string_key,
|
||||
.cmp = (kv_key_cmp_fn_t)cmp_string_key,
|
||||
.assign = (kv_key_assign_fn_t)assign_string_key,
|
||||
.destroy = (kv_key_destroy_fn_t)destroy_string_key };
|
||||
|
||||
struct kvent_ {
|
||||
kvent_t* next;
|
||||
void* key;
|
||||
|
|
@ -15,9 +81,10 @@ struct kvent_ {
|
|||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t nslots;
|
||||
destroy_fn_t val_killer;
|
||||
kvent_t** slots;
|
||||
uint32_t nslots;
|
||||
kv_key_ops_t* keyops;
|
||||
destroy_fn_t val_killer;
|
||||
kvent_t** slots;
|
||||
} kvtab_t;
|
||||
|
||||
static size_t kvtab_datasize(va_list ap)
|
||||
|
|
@ -29,143 +96,26 @@ static size_t kvtab_datasize(va_list ap)
|
|||
static int kvtab_init(meta_obj_t* obj, va_list ap)
|
||||
{
|
||||
kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
uint32_t nslots = va_arg(ap, uint32_t);
|
||||
destroy_fn_t killer = va_arg(ap, destroy_fn_t);
|
||||
kv_params_t* params = va_arg(ap, kv_params_t*);
|
||||
|
||||
if (nslots <= 1) {
|
||||
if ((params == NULL) || (params->nslots <= 1) || (params->keyops == NULL)
|
||||
|| (params->keyops->hash == NULL) || (params->keyops->cmp == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kvtab->slots = (kvent_t**)calloc(nslots, sizeof(*(kvtab->slots)));
|
||||
kvtab->slots = (kvent_t**)calloc(params->nslots, sizeof(*(kvtab->slots)));
|
||||
if (kvtab->slots == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
kvtab->nslots = nslots;
|
||||
kvtab->val_killer = killer;
|
||||
kvtab->nslots = params->nslots;
|
||||
kvtab->keyops = params->keyops;
|
||||
kvtab->val_killer = params->datakiller;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void kvtab_int64_destroy(meta_obj_t* obj)
|
||||
{
|
||||
kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < kvtab->nslots; i++) {
|
||||
kvent_t* e = NULL;
|
||||
while ((e = kvtab->slots[i]) != NULL) {
|
||||
kvtab->slots[i] = e->next;
|
||||
e->next = NULL;
|
||||
if (kvtab->val_killer != NULL) {
|
||||
kvtab->val_killer(e->value);
|
||||
}
|
||||
|
||||
FREEUP(e);
|
||||
}
|
||||
}
|
||||
|
||||
FREEUP(kvtab->slots);
|
||||
}
|
||||
|
||||
static kvent_t* kvtab_int64_get(kvtab_t* t, uint64_t key)
|
||||
{
|
||||
uint32_t hc;
|
||||
kvent_t* e = NULL;
|
||||
|
||||
hc = hash_block((char*)&key, sizeof(key)) % t->nslots;
|
||||
e = t->slots[hc];
|
||||
|
||||
while (e != NULL) {
|
||||
if (((uint64_t)(long)e->key) == key) {
|
||||
break;
|
||||
}
|
||||
|
||||
e = e->next;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
static int kvtab_int64_add(meta_obj_t* obj, void* key, void* value)
|
||||
{
|
||||
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
kvent_t* e = NULL;
|
||||
uint32_t hc;
|
||||
uint64_t keyint;
|
||||
|
||||
e = kvtab_int64_get(t, (uint64_t)(long)key);
|
||||
if (e != NULL) {
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
e = (kvent_t*)calloc(1, sizeof(*e));
|
||||
if (e == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
e->key = key;
|
||||
e->value = value;
|
||||
|
||||
keyint = (uint64_t)(long)key;
|
||||
hc = hash_block((char*)&keyint, sizeof(keyint)) % t->nslots;
|
||||
|
||||
e->next = t->slots[hc];
|
||||
t->slots[hc] = e;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kvtab_int64_del(meta_obj_t* obj, void* key)
|
||||
{
|
||||
uint64_t keyint = (uint64_t)(long)key;
|
||||
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
kvent_t** e = NULL;
|
||||
uint32_t hc;
|
||||
|
||||
hc = hash_block((char*)&keyint, sizeof(keyint)) % t->nslots;
|
||||
e = &(t->slots[hc]);
|
||||
while ((*e) != NULL) {
|
||||
if ((uint64_t)(long)(*e)->key == keyint) {
|
||||
kvent_t* e1 = *e;
|
||||
|
||||
*e = e1->next;
|
||||
|
||||
if (t->val_killer != NULL) {
|
||||
t->val_killer(e1->value);
|
||||
}
|
||||
|
||||
FREEUP(e1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
e = &((*e)->next);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvtab_int64_find(meta_obj_t* obj, void* key, void** value)
|
||||
{
|
||||
uint64_t keyint = (uint64_t)(long)key;
|
||||
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
kvent_t* e = NULL;
|
||||
|
||||
if (value == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
e = kvtab_int64_get(t, keyint);
|
||||
if (e == NULL) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
*value = e->value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void kvtab_string_destroy(meta_obj_t* obj)
|
||||
static void kvtab_destroy(meta_obj_t* obj)
|
||||
{
|
||||
kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
int i;
|
||||
|
|
@ -176,12 +126,15 @@ static void kvtab_string_destroy(meta_obj_t* obj)
|
|||
while ((e = kvtab->slots[i]) != NULL) {
|
||||
kvtab->slots[i] = e->next;
|
||||
e->next = NULL;
|
||||
FREEUP(e->key);
|
||||
|
||||
if (kvtab->val_killer != NULL) {
|
||||
kvtab->val_killer(e->value);
|
||||
}
|
||||
|
||||
if (kvtab->keyops->destroy != NULL) {
|
||||
kvtab->keyops->destroy(e->key);
|
||||
}
|
||||
|
||||
FREEUP(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -189,16 +142,16 @@ static void kvtab_string_destroy(meta_obj_t* obj)
|
|||
FREEUP(kvtab->slots);
|
||||
}
|
||||
|
||||
static kvent_t* kvtab_string_get(kvtab_t* t, char* key)
|
||||
static kvent_t* kvtab_get(kvtab_t* t, void* key)
|
||||
{
|
||||
uint32_t hc;
|
||||
kvent_t* e = NULL;
|
||||
|
||||
hc = hash_string(key) % t->nslots;
|
||||
hc = t->keyops->hash(key) % t->nslots;
|
||||
e = t->slots[hc];
|
||||
|
||||
while (e != NULL) {
|
||||
if (strcmp((char*)e->key, key) == 0) {
|
||||
if (t->keyops->cmp(e->key, key) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -208,13 +161,13 @@ static kvent_t* kvtab_string_get(kvtab_t* t, char* key)
|
|||
return e;
|
||||
}
|
||||
|
||||
static int kvtab_string_add(meta_obj_t* obj, void* key, void* value)
|
||||
static int kvtab_add(meta_obj_t* obj, void* key, void* value)
|
||||
{
|
||||
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
kvent_t* e = NULL;
|
||||
uint32_t hc;
|
||||
|
||||
e = kvtab_string_get(t, (char*)key);
|
||||
e = kvtab_get(t, key);
|
||||
if (e != NULL) {
|
||||
return -EEXIST;
|
||||
}
|
||||
|
|
@ -224,15 +177,20 @@ static int kvtab_string_add(meta_obj_t* obj, void* key, void* value)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
e->key = strdup((char*)key);
|
||||
if (e->key == NULL) {
|
||||
FREEUP(e);
|
||||
return -ENOMEM;
|
||||
if (t->keyops->assign == NULL) {
|
||||
e->key = key;
|
||||
} else {
|
||||
int rc;
|
||||
|
||||
rc = t->keyops->assign(&(e->key), key);
|
||||
if (rc < 0) {
|
||||
free(e);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
e->value = value;
|
||||
|
||||
hc = hash_string((char*)key) % t->nslots;
|
||||
hc = t->keyops->hash(key) % t->nslots;
|
||||
|
||||
e->next = t->slots[hc];
|
||||
t->slots[hc] = e;
|
||||
|
|
@ -240,26 +198,27 @@ static int kvtab_string_add(meta_obj_t* obj, void* key, void* value)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int kvtab_string_del(meta_obj_t* obj, void* key)
|
||||
static int kvtab_del(meta_obj_t* obj, void* key)
|
||||
{
|
||||
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
kvent_t** e = NULL;
|
||||
uint32_t hc;
|
||||
|
||||
hc = hash_string((char*)key) % t->nslots;
|
||||
hc = t->keyops->hash(key) % t->nslots;
|
||||
e = &(t->slots[hc]);
|
||||
|
||||
while ((*e) != NULL) {
|
||||
if (strcmp((char*)(*e)->key, (char*)key) == 0) {
|
||||
if (t->keyops->cmp((*e)->key, key) == 0) {
|
||||
kvent_t* e1 = *e;
|
||||
|
||||
*e = e1->next;
|
||||
FREEUP(e1->key);
|
||||
|
||||
if (t->val_killer != NULL) {
|
||||
t->val_killer(e1->value);
|
||||
}
|
||||
|
||||
if (t->keyops->destroy != NULL) {
|
||||
t->keyops->destroy(e1->key);
|
||||
}
|
||||
|
||||
FREEUP(e1);
|
||||
|
||||
return 1;
|
||||
|
|
@ -271,7 +230,7 @@ static int kvtab_string_del(meta_obj_t* obj, void* key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int kvtab_string_find(meta_obj_t* obj, void* key, void** value)
|
||||
static int kvtab_find(meta_obj_t* obj, void* key, void** value)
|
||||
{
|
||||
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||
kvent_t* e = NULL;
|
||||
|
|
@ -280,7 +239,7 @@ static int kvtab_string_find(meta_obj_t* obj, void* key, void** value)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
e = kvtab_string_get(t, (char*)key);
|
||||
e = kvtab_get(t, key);
|
||||
if (e == NULL) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
|
@ -289,204 +248,13 @@ static int kvtab_string_find(meta_obj_t* obj, void* key, void** value)
|
|||
return 1;
|
||||
}
|
||||
|
||||
typeinfo_t kvtab_int64_type
|
||||
= { .name = "kvtab_int",
|
||||
typeinfo_t kvtab_type
|
||||
= { .name = "kvtab",
|
||||
.privateSize = 0,
|
||||
.dataSize = (datasize_fn_t)kvtab_datasize,
|
||||
.init = (obj_init_fn_t)kvtab_init,
|
||||
.destroy = (obj_destroy_fn_t)kvtab_int64_destroy,
|
||||
.interfaces = { .kv = &(intf_kv_t) {
|
||||
.add_key = (key_add_fn_t)kvtab_int64_add,
|
||||
.del_key = (key_del_fn_t)kvtab_int64_del,
|
||||
.find_key = (key_find_fn_t)kvtab_int64_find } } };
|
||||
|
||||
typeinfo_t kvtab_string_type
|
||||
= { .name = "kvtab_int",
|
||||
.privateSize = 0,
|
||||
.dataSize = (datasize_fn_t)kvtab_datasize,
|
||||
.init = (obj_init_fn_t)kvtab_init,
|
||||
.destroy = (obj_destroy_fn_t)kvtab_string_destroy,
|
||||
.interfaces = { .kv = &(intf_kv_t) {
|
||||
.add_key = (key_add_fn_t)kvtab_string_add,
|
||||
.del_key = (key_del_fn_t)kvtab_string_del,
|
||||
.find_key = (key_find_fn_t)kvtab_string_find } } };
|
||||
|
||||
typedef struct {
|
||||
uint32_t nslots;
|
||||
size_t keylen;
|
||||
destroy_fn_t val_killer;
|
||||
comp_fn_t cmp;
|
||||
kvent_t** slots;
|
||||
} kvtab_generic_t;
|
||||
|
||||
static size_t kvtab_generic_datasize(va_list ap)
|
||||
{
|
||||
size_t sz = sizeof(kvtab_generic_t);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int kvtab_generic_init(meta_obj_t* obj, va_list ap)
|
||||
{
|
||||
uint32_t nslots = va_arg(ap, uint32_t);
|
||||
destroy_fn_t killer = va_arg(ap, destroy_fn_t);
|
||||
size_t keylen = va_arg(ap, size_t);
|
||||
comp_fn_t cmp = va_arg(ap, comp_fn_t);
|
||||
kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj);
|
||||
|
||||
if (nslots <= 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kvtab->slots = (kvent_t**)calloc(nslots, sizeof(*(kvtab->slots)));
|
||||
if (kvtab->slots == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kvtab->nslots = nslots;
|
||||
kvtab->val_killer = killer;
|
||||
kvtab->cmp = cmp;
|
||||
kvtab->keylen = keylen;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void kvtab_generic_destroy(meta_obj_t* obj)
|
||||
{
|
||||
kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < kvtab->nslots; i++) {
|
||||
kvent_t* e = NULL;
|
||||
while ((e = kvtab->slots[i]) != NULL) {
|
||||
kvtab->slots[i] = e->next;
|
||||
e->next = NULL;
|
||||
FREEUP(e->key);
|
||||
if (kvtab->val_killer != NULL) {
|
||||
kvtab->val_killer(e->value);
|
||||
}
|
||||
|
||||
FREEUP(e);
|
||||
}
|
||||
}
|
||||
|
||||
FREEUP(kvtab->slots);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static kvent_t* kvtab_generic_get(kvtab_generic_t* kvtab, void* key)
|
||||
{
|
||||
uint32_t hc;
|
||||
kvent_t* e = NULL;
|
||||
|
||||
hc = hash_block((char*)key, kvtab->keylen) % kvtab->nslots;
|
||||
e = kvtab->slots[hc];
|
||||
|
||||
while (e != NULL) {
|
||||
if (kvtab->cmp(e->key, key, kvtab->keylen) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
e = e->next;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static int kvtab_generic_add(meta_obj_t* obj, void* key, void* value)
|
||||
{
|
||||
kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj);
|
||||
kvent_t* e = NULL;
|
||||
uint32_t hc;
|
||||
|
||||
e = kvtab_generic_get(kvtab, key);
|
||||
if (e != NULL) {
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
e = (kvent_t*)calloc(1, sizeof(*e));
|
||||
if (e == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
e->key = (void*)calloc(1, kvtab->keylen);
|
||||
if (e->key == NULL) {
|
||||
FREEUP(e);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(e->key, key, kvtab->keylen);
|
||||
e->value = value;
|
||||
|
||||
hc = hash_block((char*)key, kvtab->keylen) % kvtab->nslots;
|
||||
e->next = kvtab->slots[hc];
|
||||
kvtab->slots[hc] = e;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kvtab_generic_del(meta_obj_t* obj, void* key)
|
||||
{
|
||||
kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj);
|
||||
kvent_t** e = NULL;
|
||||
uint32_t hc;
|
||||
|
||||
hc = hash_block((char*)key, kvtab->keylen) % kvtab->nslots;
|
||||
e = &(kvtab->slots[hc]);
|
||||
|
||||
while ((*e) != NULL) {
|
||||
if (kvtab->cmp((*e)->key, key, kvtab->keylen) == 0) {
|
||||
kvent_t* e1 = *e;
|
||||
|
||||
*e = e1->next;
|
||||
FREEUP(e1->key);
|
||||
if (kvtab->val_killer != NULL) {
|
||||
kvtab->val_killer(e1->value);
|
||||
}
|
||||
|
||||
FREEUP(e1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
e = &((*e)->next);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvtab_generic_find(meta_obj_t* obj, void* key, void** value)
|
||||
{
|
||||
kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj);
|
||||
kvent_t* e = NULL;
|
||||
|
||||
if (value == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
e = kvtab_generic_get(kvtab, key);
|
||||
if (e == NULL) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
*value = e->value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
typeinfo_t kvtab_generic_type
|
||||
= { .name = "kvtab_generic",
|
||||
.privateSize = 0,
|
||||
.dataSize = (datasize_fn_t)kvtab_generic_datasize,
|
||||
.init = (obj_init_fn_t)kvtab_generic_init,
|
||||
.destroy = (obj_destroy_fn_t)kvtab_generic_destroy,
|
||||
.interfaces = { .kv = &(intf_kv_t) {
|
||||
.add_key = (key_add_fn_t)kvtab_generic_add,
|
||||
.del_key = (key_del_fn_t)kvtab_generic_del,
|
||||
.find_key = (key_find_fn_t)kvtab_generic_find } } };
|
||||
|
||||
int key_cmp_default(void* k1, void* k2, size_t len)
|
||||
{
|
||||
return memcmp(k1, k2, len);
|
||||
}
|
||||
.destroy = (obj_destroy_fn_t)kvtab_destroy,
|
||||
.interfaces
|
||||
= { .kv = &(intf_kv_t) { .add_key = (key_add_fn_t)kvtab_add,
|
||||
.del_key = (key_del_fn_t)kvtab_del,
|
||||
.find_key = (key_find_fn_t)kvtab_find } } };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue