提供array和hashtable的存储引擎层的二进制安全支持,把入口函数修改为接收参数长度,将strlen、strcmp、strcpy替换。
This commit is contained in:
149
kvs_array.c
149
kvs_array.c
@@ -19,12 +19,13 @@ int kvs_array_create(kvs_array_t *inst) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(inst->table, 0, (size_t)KVS_ARRAY_SIZE * sizeof(kvs_array_item_t));
|
||||
inst->total = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvs_array_destory(kvs_array_t *inst) {
|
||||
void kvs_array_destroy(kvs_array_t *inst) {
|
||||
|
||||
if (!inst) return ;
|
||||
|
||||
@@ -35,6 +36,151 @@ void kvs_array_destory(kvs_array_t *inst) {
|
||||
}
|
||||
|
||||
|
||||
#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(长度0),value 指针置 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
|
||||
*/
|
||||
@@ -187,3 +333,4 @@ int kvs_array_exist(kvs_array_t *inst, char *key) {
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user