Files
ldb/kvs_array.c

336 lines
7.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "kvstore.h"
// singleton
kvs_array_t global_array = {0};
int kvs_array_create(kvs_array_t *inst) {
if (!inst) return -1;
if (inst->table) {
printf("table has alloc\n");
return -1;
}
inst->table = kvs_malloc(KVS_ARRAY_SIZE * sizeof(kvs_array_item_t));
if (!inst->table) {
return -1;
}
memset(inst->table, 0, (size_t)KVS_ARRAY_SIZE * sizeof(kvs_array_item_t));
inst->total = 0;
return 0;
}
void kvs_array_destroy(kvs_array_t *inst) {
if (!inst) return ;
if (inst->table) {
kvs_free(inst->table);
}
}
#if BIN_SAFE
/**
* return: ==-2 not exist, == -1 error, >= 0 exist idx
*/
int kvs_array_find_index(kvs_array_t *inst, const void *key, size_t key_len) {
if (!inst || !inst->table || !key) return -1;
for (int i = 0; i < inst->total; i++) {
kvs_array_item_t *it = &inst->table[i];
if (!it->key) continue;
if (it->key_len == key_len && memcmp(it->key, key, key_len) == 0) {
return i;
}
}
return -2; // not found
}
/*
* return: <0 error; 0 success; 1 exist
*/
int kvs_array_set_bin(kvs_array_t *inst,
const void *key, size_t key_len,
const void *value, size_t value_len) {
if (!inst || !inst->table || !key || key_len == 0 || !value) return -1;
if (inst->total >= KVS_ARRAY_SIZE) return -1;
int idx = kvs_array_find_index(inst, key, key_len);
// -2 not exist
if (idx >= 0) return 1; // exist
if (idx == -1) return -1; // error
uint8_t *kcopy = (uint8_t *)kvs_malloc(key_len);
if (!kcopy) return -2;
memcpy(kcopy, key, key_len);
uint8_t *vcopy = NULL;
if (value_len > 0) {
vcopy = (uint8_t *)kvs_malloc(value_len);
if (!vcopy) {
kvs_free(kcopy);
return -2;
}
memcpy(vcopy, value, value_len);
} else {
// 允许空 value长度0value 指针置 NULL
vcopy = NULL;
}
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (inst->table[i].key == NULL) {
inst->table[i].key = kcopy;
inst->table[i].key_len = key_len;
inst->table[i].value = vcopy;
inst->table[i].value_len = value_len;
inst->total ++;
return 0;
}
}
if (i == inst->total && i < KVS_ARRAY_SIZE) {
inst->table[i].key = kcopy;
inst->table[i].key_len = key_len;
inst->table[i].value = vcopy;
inst->table[i].value_len = value_len;
inst->total ++;
}
return 0;
}
void *kvs_array_get_bin(kvs_array_t *inst,
const void *key, size_t key_len,
size_t *out_value_len) {
if (out_value_len) *out_value_len = 0;
if (!inst || !inst->table || !key || key_len == 0) return NULL;
int idx = kvs_array_find_index(inst, key, key_len);
if (idx < 0) return NULL;
kvs_array_item_t *it = &inst->table[idx];
if (out_value_len) *out_value_len = it->value_len;
return it->value; // 注意:由 store 持有
}
int kvs_array_del_bin(kvs_array_t *inst, const void *key, size_t key_len) {
if (!inst || !inst->table || !key || key_len == 0) return -1;
int idx = kvs_array_find_index(inst, key, key_len);
if (idx == -2) return 1; // not exist
if (idx < 0) return -1;
kvs_array_item_t *it = &inst->table[idx];
if (it->key) kvs_free(it->key);
if (it->value) kvs_free(it->value);
// 用末尾元素填洞,保证 total 连续,避免 “total 只增不减” 问题
int last = inst->total - 1;
if (idx != last) {
inst->table[idx] = inst->table[last];
}
// 清理末尾(已被移动或删除)
memset(&inst->table[last], 0, sizeof(kvs_array_item_t));
inst->total--;
return 0;
}
int kvs_array_mod_bin(kvs_array_t *inst,
const void *key, size_t key_len,
const void *value, size_t value_len) {
if (!inst || !inst->table || !key || key_len == 0 || !value) return -1;
int idx = kvs_array_find_index(inst, key, key_len);
if (idx == -2) return 1; // not exist
if (idx < 0) return -1;
kvs_array_item_t *it = &inst->table[idx];
uint8_t *vcopy = NULL;
if (value_len > 0) {
vcopy = (uint8_t *)kvs_malloc(value_len);
if (!vcopy) return -2;
memcpy(vcopy, value, value_len);
} else {
vcopy = NULL;
}
if (it->value) kvs_free(it->value);
it->value = vcopy;
it->value_len = value_len;
return 0;
}
int kvs_array_exist_bin(kvs_array_t *inst, const void *key, size_t key_len) {
if (!inst || !inst->table || !key || key_len == 0) return -1;
int idx = kvs_array_find_index(inst, key, key_len);
return (idx >= 0) ? 0 : 1;
}
#else
/*
* @return: <0, error; =0, success; >0, exist
*/
int kvs_array_set(kvs_array_t *inst, char *key, char *value) {
if (inst == NULL || key == NULL || value == NULL) return -1;
if (inst->total == KVS_ARRAY_SIZE) return -1;
char *str = kvs_array_get(inst, key);
if (str) {
return 1; //
}
char *kcopy = kvs_malloc(strlen(key) + 1);
if (kcopy == NULL) return -2;
memset(kcopy, 0, strlen(key) + 1);
strncpy(kcopy, key, strlen(key));
char *kvalue = kvs_malloc(strlen(value) + 1);
if (kvalue == NULL) return -2;
memset(kvalue, 0, strlen(value) + 1);
strncpy(kvalue, value, strlen(value));
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (inst->table[i].key == NULL) {
inst->table[i].key = kcopy;
inst->table[i].value = kvalue;
inst->total ++;
return 0;
}
}
if (i == inst->total && i < KVS_ARRAY_SIZE) {
inst->table[i].key = kcopy;
inst->table[i].value = kvalue;
inst->total ++;
}
return 0;
}
char* kvs_array_get(kvs_array_t *inst, char *key) {
if (inst == NULL || key == NULL) return NULL;
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (inst->table[i].key == NULL) {
continue;
}
if (strcmp(inst->table[i].key, key) == 0) {
return inst->table[i].value;
}
}
return NULL;
}
/*
* @return < 0, error; =0, success; >0, no exist
*/
int kvs_array_del(kvs_array_t *inst, char *key) {
if (inst == NULL || key == NULL) return -1;
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (strcmp(inst->table[i].key, key) == 0) {
kvs_free(inst->table[i].key);
inst->table[i].key = NULL;
kvs_free(inst->table[i].value);
inst->table[i].value = NULL;
// error: > 1024
if (inst->total-1 == i) {
inst->total --;
}
return 0;
}
}
return i;
}
/*
* @return : < 0, error; =0, success; >0, no exist
*/
int kvs_array_mod(kvs_array_t *inst, char *key, char *value) {
if (inst == NULL || key == NULL || value == NULL) return -1;
// error: > 1024
if (inst->total == 0) {
return KVS_ARRAY_SIZE;
}
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (inst->table[i].key == NULL) {
continue;
}
if (strcmp(inst->table[i].key, key) == 0) {
kvs_free(inst->table[i].value);
char *kvalue = kvs_malloc(strlen(value) + 1);
if (kvalue == NULL) return -2;
memset(kvalue, 0, strlen(value) + 1);
strncpy(kvalue, value, strlen(value));
inst->table[i].value = kvalue;
return 0;
}
}
return i;
}
/*
* @return 0: exist, 1: no exist
*/
int kvs_array_exist(kvs_array_t *inst, char *key) {
if (!inst || !key) return -1;
char *str = kvs_array_get(inst, key);
if (!str) {
return 1; //
}
return 0;
}
#endif