myxce/src/lib/kvmgr.c

191 lines
3.4 KiB
C

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "htab.h"
#include "kvmgr.h"
#include "objmgr.h"
#include "utils.h"
#include "xce/types.h"
#include "zarray.h"
int kvmgr_init(kvmgr_t* mgr, hash_key_fn_t keyfn, int nslots, int delta,
zarray_item_killer_t killer)
{
ht_init(&(mgr->htab), nslots, keyfn);
zarray_init(&(mgr->data), delta, killer);
mylock_init(&(mgr->lock));
return 0;
}
void kvmgr_fini(kvmgr_t* mgr)
{
ht_fini(&(mgr->htab));
zarray_fini(&(mgr->data));
mylock_fini(&(mgr->lock));
}
static void* kvmgr_lock_(kvmgr_t* mgr, void* key, int op)
{
hent_t* e = NULL;
int32_t idx;
void* ptr;
e = ht_get(&(mgr->htab), key);
if (e == NULL) {
SET_ERROR(ENOENT);
return NULL;
}
idx = e->data;
if (idx < 0) {
SET_ERROR(ENOENT);
return NULL;
}
ptr = (void*)zarray_get(&(mgr->data), idx);
return obj_ref(ptr, op);
}
void* kvmgr_lock(kvmgr_t* mgr, void* key, int op)
{
void* ptr = NULL;
if (mgr == NULL) {
SET_ERROR(EINVAL);
return NULL;
}
/* clang-format off */
if ((op != OBJREF_NOP) &&
(op != OBJREF_READ) &&
(op != OBJREF_UPDATE)) {
SET_ERROR(EINVAL);
return NULL;
}
/* clang-format on */
mylock_lock(&(mgr->lock));
ptr = kvmgr_lock_(mgr, key, op);
mylock_unlock(&(mgr->lock));
return ptr;
}
static int32_t kvmgr_add_(kvmgr_t* mgr, void* key, void* p)
{
hent_t* e = NULL;
int idx;
e = ht_get(&(mgr->htab), key);
if (e != NULL) {
return -EEXIST;
}
idx = zarray_store(&(mgr->data), p);
if (idx < 0) {
return idx;
}
e = ht_add(&(mgr->htab), (void*)key);
if (e == NULL) {
zarray_del(&(mgr->data), idx);
return -errno;
}
e->data = idx;
return idx;
}
int32_t kvmgr_add(kvmgr_t* mgr, void* key, void* p)
{
int32_t idx;
if ((mgr == NULL) || (p == NULL)) {
return -EINVAL;
}
mylock_lock(&(mgr->lock));
idx = kvmgr_add_(mgr, key, p);
mylock_unlock(&(mgr->lock));
return idx;
}
static void kvmgr_del_(kvmgr_t* mgr, void* key)
{
hent_t* e = NULL;
int idx;
e = ht_get(&(mgr->htab), key);
if (e == NULL) {
return;
}
idx = e->data;
if (idx < 0) {
return;
}
zarray_del(&(mgr->data), idx);
return;
}
void kvmgr_del(kvmgr_t* mgr, void* key)
{
if (mgr == NULL) {
return;
}
mylock_lock(&(mgr->lock));
kvmgr_del_(mgr, key);
mylock_unlock(&(mgr->lock));
}
static int add_config_(xlist_t* l, void* data)
{
xce_config_t* config;
if (data == NULL) {
return -EINVAL;
}
config = (xce_config_t*)obj_ref(data, OBJREF_READ);
return xlist_store(l, config);
}
int kvmgr_publish(kvmgr_t* mgr, xlist_action_fn_t fn, void* arg)
{
xlist_t l;
int rc = 0;
int i;
xlist_init(&l, 128);
mylock_lock(&(mgr->lock));
zarray_iter(&(mgr->data), (zarray_iter_fn_t)add_config_, &l);
mylock_unlock(&(mgr->lock));
rc = (*fn)(&l, arg);
for (i = 0; i < l.count; i++) {
xce_config_t* config = l.data[i];
DEREF_OBJ(config);
}
xlist_fini(&l);
return rc;
}
int kvmgr_iter(kvmgr_t* mgr, xlist_t* l, void* arg)
{
int rc = 0;
mylock_lock(&(mgr->lock));
rc = zarray_iter_ex(&(mgr->data), l, arg);
mylock_unlock(&(mgr->lock));
return rc;
}