✨ feat(define kv.h): include in .stellar/
This commit is contained in:
100
include/stellar/kv.h
Normal file
100
include/stellar/kv.h
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <uuid/uuid.h>
|
||||||
|
|
||||||
|
struct kv
|
||||||
|
{
|
||||||
|
char *key;
|
||||||
|
size_t key_sz;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
KV_VALUE_TYPE_INTEGER,
|
||||||
|
KV_VALUE_TYPE_DOUBLE,
|
||||||
|
KV_VALUE_TYPE_STRING,
|
||||||
|
KV_VALUE_TYPE_UUID,
|
||||||
|
KV_VALUE_TYPE_INTERGE_ARRAY,
|
||||||
|
KV_VALUE_TYPE_DOUBLE_ARRAY,
|
||||||
|
KV_VALUE_TYPE_STRING_ARRAY,
|
||||||
|
KV_VALUE_TYPE_UUID_ARRAY
|
||||||
|
}vtype;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
long long value_longlong;
|
||||||
|
double value_double;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
size_t sz;
|
||||||
|
}value_str;
|
||||||
|
uuid_t value_uuid;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
long long *elems;
|
||||||
|
size_t n_elems;
|
||||||
|
}value_interger_array;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
double *elems;
|
||||||
|
size_t n_elems;
|
||||||
|
}value_double_array;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char **elems;
|
||||||
|
size_t *sz;
|
||||||
|
size_t n_elems;
|
||||||
|
}value_str_array;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uuid_t *elems;
|
||||||
|
size_t n_elems;
|
||||||
|
}value_uuid_array;
|
||||||
|
/*
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct kv *elems;
|
||||||
|
size_t n_elems;
|
||||||
|
}value_list;
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kv *kv_new_with_interger(const char *key, size_t key_sz, long long value);
|
||||||
|
struct kv *kv_new_with_double(const char *key, size_t key_sz, double value);
|
||||||
|
struct kv *kv_new_with_string(const char *key, size_t key_sz, const char *value, size_t value_sz);
|
||||||
|
struct kv *kv_new_with_uuid(const char *key, size_t key_sz, const uuid_t value);
|
||||||
|
struct kv *kv_new_with_interger_array(const char *key, size_t key_sz, long long value[], size_t n_value);
|
||||||
|
struct kv *kv_new_with_double_array(const char *key, size_t key_sz, double value[], size_t n_value);
|
||||||
|
struct kv *kv_new_with_string_array(const char *key, size_t key_sz, const char* value[], size_t value_sz[], size_t n_value);
|
||||||
|
struct kv *kv_new_with_uuid_array(const char *key, size_t key_sz, const uuid_t value[], size_t n_value);
|
||||||
|
|
||||||
|
struct kv *kv_duplicate(const struct kv *kv);
|
||||||
|
|
||||||
|
void kv_free(struct kv *kv);
|
||||||
|
|
||||||
|
struct kv_table;
|
||||||
|
|
||||||
|
struct kv_table *kv_table_new(size_t initial_size);
|
||||||
|
void kv_table_free(struct kv_table *table);
|
||||||
|
|
||||||
|
//struct kv_table *kv_table_new_by_indexing(struct kv *kv);
|
||||||
|
|
||||||
|
int kv_table_add(struct kv_table *table, const struct kv *kv);
|
||||||
|
int kv_table_del(struct kv_table *table, const char *key, size_t key_sz);
|
||||||
|
|
||||||
|
typedef void (kv_ref_cleanup_cb)(const struct kv *kv, void *arg);
|
||||||
|
int kv_table_add_reference(struct kv_table *table, const struct kv *kv, kv_ref_cleanup_cb *cleanup_cb, void *arg);
|
||||||
|
|
||||||
|
const struct kv *kv_table_get0(struct kv_table *table, const char *key, size_t key_sz);
|
||||||
|
|
||||||
|
void kv_table_reset_iter(struct kv_table *table);
|
||||||
|
const struct kv *kv_table_next(struct kv_table *table);
|
||||||
|
|
||||||
|
struct kv_table *kv_table_duplicate(const struct kv_table *table);
|
||||||
|
int kv_table_union(struct kv_table *dst, const struct kv_table *src);
|
||||||
|
|
||||||
|
void kv_table_serialize(const struct kv_table *table, char **blob, size_t *blob_len);
|
||||||
|
struct kv_table *kv_table_deserialize(const char *blob, size_t blob_len);
|
||||||
|
|
||||||
|
int kv_table_export_json(const struct kv_table *table, char **blob, size_t *blob_len);
|
||||||
|
int kv_table_export_msgpack(const struct kv_table *table, char **blob, size_t *blob_len);
|
||||||
@@ -13,7 +13,7 @@ typedef void mq_msg_free_cb_func(void *msg, void *msg_free_arg);
|
|||||||
typedef void on_msg_cb_func(int topic_id, void *msg, void *on_msg_arg);
|
typedef void on_msg_cb_func(int topic_id, void *msg, void *on_msg_arg);
|
||||||
typedef void on_msg_dispatch_cb_func(int topic_id,
|
typedef void on_msg_dispatch_cb_func(int topic_id,
|
||||||
void *msg,
|
void *msg,
|
||||||
on_msg_cb_func* on_msg_cb,
|
on_msg_cb_func *on_msg_cb,
|
||||||
void *on_msg_cb_arg,
|
void *on_msg_cb_arg,
|
||||||
void *dispatch_arg);
|
void *dispatch_arg);
|
||||||
|
|
||||||
|
|||||||
236
infra/kv/kv.c
Normal file
236
infra/kv/kv.c
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
#include "stellar/kv.h"
|
||||||
|
|
||||||
|
#include "uthash/uthash.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct kv *kv_new_with_interger(const char *key, size_t key_sz, long long value)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_INTEGER;
|
||||||
|
kv->value_longlong = value;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kv *kv_new_with_double(const char *key, size_t key_sz, double value)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_DOUBLE;
|
||||||
|
kv->value_double = value;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kv *kv_new_with_string(const char *key, size_t key_sz, const char *value, size_t value_sz)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_STRING;
|
||||||
|
kv->value_str.str = malloc(value_sz);
|
||||||
|
memcpy(kv->value_str.str, value, value_sz);
|
||||||
|
kv->value_str.sz = value_sz;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kv *kv_new_with_uuid(const char *key, size_t key_sz, const uuid_t value)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_UUID;
|
||||||
|
memcpy(kv->value_uuid, value, sizeof(uuid_t));
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kv *kv_new_with_interger_array(const char *key, size_t key_sz, long long value[], size_t n_value)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_INTERGE_ARRAY;
|
||||||
|
kv->value_interger_array.elems = malloc(sizeof(long long) * n_value);
|
||||||
|
memcpy(kv->value_interger_array.elems, value, sizeof(long long) * n_value);
|
||||||
|
kv->value_interger_array.n_elems = n_value;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
struct kv *kv_new_with_double_array(const char *key, size_t key_sz, double value[], size_t n_value)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_DOUBLE_ARRAY;
|
||||||
|
kv->value_double_array.elems = malloc(sizeof(double) * n_value);
|
||||||
|
memcpy(kv->value_double_array.elems, value, sizeof(double) * n_value);
|
||||||
|
kv->value_double_array.n_elems = n_value;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
struct kv *kv_new_with_string_array(const char *key, size_t key_sz, const char* value[], size_t value_sz[], size_t n_value)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_STRING_ARRAY;
|
||||||
|
kv->value_str_array.elems = malloc(sizeof(char*) * n_value);
|
||||||
|
kv->value_str_array.sz = malloc(sizeof(size_t) * n_value);
|
||||||
|
for (size_t i = 0; i < n_value; i++)
|
||||||
|
{
|
||||||
|
kv->value_str_array.elems[i] = malloc(value_sz[i]);
|
||||||
|
memcpy(kv->value_str_array.elems[i], value[i], value_sz[i]);
|
||||||
|
kv->value_str_array.sz[i] = value_sz[i];
|
||||||
|
}
|
||||||
|
kv->value_str_array.n_elems = n_value;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kv *kv_new_with_uuid_array(const char *key, size_t key_sz, const uuid_t value[], size_t n_value)
|
||||||
|
{
|
||||||
|
struct kv *kv = malloc(sizeof(struct kv));
|
||||||
|
kv->key = malloc(key_sz);
|
||||||
|
memcpy(kv->key, key, key_sz);
|
||||||
|
kv->key_sz = key_sz;
|
||||||
|
kv->vtype = KV_VALUE_TYPE_UUID_ARRAY;
|
||||||
|
kv->value_uuid_array.elems = malloc(sizeof(uuid_t) * n_value);
|
||||||
|
memcpy(kv->value_uuid_array.elems, value, sizeof(uuid_t) * n_value);
|
||||||
|
kv->value_uuid_array.n_elems = n_value;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kv *kv_duplicate(const struct kv *kv)
|
||||||
|
{
|
||||||
|
if(kv == NULL)return NULL;
|
||||||
|
struct kv *new_kv = malloc(sizeof(struct kv));
|
||||||
|
new_kv->key = malloc(kv->key_sz);
|
||||||
|
memcpy(new_kv->key, kv->key, kv->key_sz);
|
||||||
|
new_kv->key_sz = kv->key_sz;
|
||||||
|
new_kv->vtype = kv->vtype;
|
||||||
|
switch (kv->vtype)
|
||||||
|
{
|
||||||
|
case KV_VALUE_TYPE_STRING:
|
||||||
|
new_kv->value_str.str = malloc(kv->value_str.sz);
|
||||||
|
memcpy(new_kv->value_str.str, kv->value_str.str, kv->value_str.sz);
|
||||||
|
new_kv->value_str.sz = kv->value_str.sz;
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_INTERGE_ARRAY:
|
||||||
|
new_kv->value_interger_array.elems = malloc(sizeof(long long) * kv->value_interger_array.n_elems);
|
||||||
|
memcpy(new_kv->value_interger_array.elems, kv->value_interger_array.elems, sizeof(long long) * kv->value_interger_array.n_elems);
|
||||||
|
new_kv->value_interger_array.n_elems = kv->value_interger_array.n_elems;
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_DOUBLE_ARRAY:
|
||||||
|
new_kv->value_double_array.elems = malloc(sizeof(double) * kv->value_double_array.n_elems);
|
||||||
|
memcpy(new_kv->value_double_array.elems, kv->value_double_array.elems, sizeof(double) * kv->value_double_array.n_elems);
|
||||||
|
new_kv->value_double_array.n_elems = kv->value_double_array.n_elems;
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_STRING_ARRAY:
|
||||||
|
new_kv->value_str_array.elems = malloc(sizeof(char*) * kv->value_str_array.n_elems);
|
||||||
|
new_kv->value_str_array.sz = malloc(sizeof(size_t) * kv->value_str_array.n_elems);
|
||||||
|
for (size_t i = 0; i < kv->value_str_array.n_elems; i++)
|
||||||
|
{
|
||||||
|
new_kv->value_str_array.elems[i] = malloc(kv->value_str_array.sz[i]);
|
||||||
|
memcpy(new_kv->value_str_array.elems[i], kv->value_str_array.elems[i], kv->value_str_array.sz[i]);
|
||||||
|
new_kv->value_str_array.sz[i] = kv->value_str_array.sz[i];
|
||||||
|
}
|
||||||
|
new_kv->value_str_array.n_elems = kv->value_str_array.n_elems;
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_UUID_ARRAY:
|
||||||
|
new_kv->value_uuid_array.elems = malloc(sizeof(uuid_t) * kv->value_uuid_array.n_elems);
|
||||||
|
memcpy(new_kv->value_uuid_array.elems, kv->value_uuid_array.elems, sizeof(uuid_t) * kv->value_uuid_array.n_elems);
|
||||||
|
new_kv->value_uuid_array.n_elems = kv->value_uuid_array.n_elems;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new_kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kv_free(struct kv *kv)
|
||||||
|
{
|
||||||
|
if(kv == NULL)return;
|
||||||
|
|
||||||
|
if(kv->key)free(kv->key);
|
||||||
|
switch (kv->vtype)
|
||||||
|
{
|
||||||
|
case KV_VALUE_TYPE_STRING:
|
||||||
|
if(kv->value_str.str)free(kv->value_str.str);
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_INTERGE_ARRAY:
|
||||||
|
if(kv->value_interger_array.elems)free(kv->value_interger_array.elems);
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_DOUBLE_ARRAY:
|
||||||
|
if(kv->value_double_array.elems)free(kv->value_double_array.elems);
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_STRING_ARRAY:
|
||||||
|
for (size_t i = 0; i < kv->value_str_array.n_elems; i++)
|
||||||
|
{
|
||||||
|
if(kv->value_str_array.elems[i])free(kv->value_str_array.elems[i]);
|
||||||
|
}
|
||||||
|
if(kv->value_str_array.elems)free(kv->value_str_array.elems);
|
||||||
|
if(kv->value_str_array.sz)free(kv->value_str_array.sz);
|
||||||
|
break;
|
||||||
|
case KV_VALUE_TYPE_UUID_ARRAY:
|
||||||
|
if(kv->value_uuid_array.elems)free(kv->value_uuid_array.elems);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(kv);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kv_table_elem
|
||||||
|
{
|
||||||
|
struct kv *kv;
|
||||||
|
kv_ref_cleanup_cb *ref_cleanup_cb;
|
||||||
|
void *cleanup_cb_arg;
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kv_table
|
||||||
|
{
|
||||||
|
struct kv_table_elem *elems;
|
||||||
|
struct kv_table_elem *iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kv_table *kv_table_new(size_t n_reserved __attribute__((unused)))
|
||||||
|
{
|
||||||
|
struct kv_table *table = malloc(sizeof(struct kv_table));
|
||||||
|
table->elems = NULL;
|
||||||
|
table->iter = NULL;
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kv_table_free(struct kv_table *table)
|
||||||
|
{
|
||||||
|
if(table == NULL)return;
|
||||||
|
struct kv_table_elem *elem, *tmp;
|
||||||
|
HASH_ITER(hh, table->elems, elem, tmp)
|
||||||
|
{
|
||||||
|
HASH_DEL(table->elems, elem);
|
||||||
|
if(elem->ref_cleanup_cb)elem->ref_cleanup_cb(elem->kv, elem->cleanup_cb_arg);
|
||||||
|
free(elem);
|
||||||
|
}
|
||||||
|
free(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
int kv_table_add(struct kv_table *table, const struct kv *kv)
|
||||||
|
{
|
||||||
|
if(table == NULL || kv == NULL)return -1;
|
||||||
|
struct kv_table_elem *elem = malloc(sizeof(struct kv_table_elem));
|
||||||
|
elem->kv = kv_duplicate(kv);
|
||||||
|
elem->ref_cleanup_cb = NULL;
|
||||||
|
elem->cleanup_cb_arg = NULL;
|
||||||
|
HASH_ADD_KEYPTR(hh, table->elems, kv->key, kv->key_sz, elem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int kv_table_del(struct kv_table *table, const char *key, size_t key_sz);
|
||||||
Reference in New Issue
Block a user