rbtree和hash的全量持久化操作。rbtree的二进制安全。
粗略测试。
This commit is contained in:
531
kvstore.c
531
kvstore.c
@@ -42,211 +42,350 @@ const char *response[] = {
|
||||
|
||||
};
|
||||
|
||||
|
||||
int kvs_split_token(char *msg, char *tokens[]) {
|
||||
|
||||
if (msg == NULL || tokens == NULL) return -1;
|
||||
|
||||
int idx = 0;
|
||||
char *token = strtok(msg, " ");
|
||||
// return: -1 fail, 0 half, >0 consumed
|
||||
int kvs_parse_one_cmd(const uint8_t *request, int request_length, kvs_req_t *req_out){
|
||||
if (!request || request_length <= 0 || !req_out) return -1;
|
||||
|
||||
while (token != NULL) {
|
||||
//printf("idx: %d, %s\n", idx, token);
|
||||
|
||||
tokens[idx ++] = token;
|
||||
token = strtok(NULL, " ");
|
||||
req_out->op = KVS_CMD_COUNT;
|
||||
req_out->argc = 0;
|
||||
req_out->args = NULL;
|
||||
|
||||
const uint8_t *p = request;
|
||||
const uint8_t *end = request + (size_t)request_length;
|
||||
|
||||
// OP + ARGC
|
||||
if (kvs_need(p, end, 2)) {
|
||||
return 0; // NEED_MORE
|
||||
}
|
||||
|
||||
uint8_t op = 0, argc = 0;
|
||||
if (kvs_read_u8(&p, end, &op) < 0) return -1;
|
||||
if (kvs_read_u8(&p, end, &argc) < 0) return -1;
|
||||
|
||||
if (argc > KVS_MAX_ARGC) return -1;
|
||||
|
||||
// 先扫描一遍确认整条命令数据都在 buffer 里
|
||||
const uint8_t *scan = p;
|
||||
uint32_t lens[KVS_MAX_ARGC];
|
||||
if (argc > 0) {
|
||||
for (uint8_t i = 0; i < argc; i++) {
|
||||
if (kvs_need(scan, end, 4)) {
|
||||
return 0; // NEED_MORE
|
||||
}
|
||||
uint32_t alen = 0;
|
||||
if (kvs_read_u32(&scan, end, &alen) < 0) return -1;
|
||||
|
||||
// 防御:单个参数长度限制
|
||||
if (alen > KVS_MAX_ARGLEN) return -1;
|
||||
|
||||
// 防御:scan + alen 越界 / 半包
|
||||
if (kvs_need(scan, end, (size_t)alen)) {
|
||||
return 0; // NEED_MORE
|
||||
}
|
||||
lens[i] = alen;
|
||||
scan += alen;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
size_t total_len = (size_t)(scan - request);
|
||||
if (total_len > KVS_MAX_CMD_BYTES) return -1;
|
||||
|
||||
req_out->op = op;
|
||||
req_out->argc = argc;
|
||||
|
||||
if (argc == 0) {
|
||||
return (int)total_len;
|
||||
}
|
||||
|
||||
kvs_arg_t *args = (kvs_arg_t *)kvs_malloc((size_t)argc * sizeof(kvs_arg_t));
|
||||
if (!args) {
|
||||
kvs_free_request(req_out);
|
||||
return -1;
|
||||
}
|
||||
memset(args, 0, (size_t)argc * sizeof(kvs_arg_t));
|
||||
|
||||
for (uint8_t i = 0; i < argc; i++) {
|
||||
uint32_t alen = 0;
|
||||
if (kvs_read_u32(&p, end, &alen) < 0) {
|
||||
kvs_free(args);
|
||||
kvs_free_request(req_out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// alen 与 lens[i] 应当一致(扫描时读过),不一致说明解析器/输入异常
|
||||
if (alen != lens[i]) {
|
||||
kvs_free(args);
|
||||
kvs_free_request(req_out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
args[i].len = alen;
|
||||
args[i].data = p; // 直接指向输入 buffer(零拷贝)
|
||||
p += alen;
|
||||
}
|
||||
|
||||
|
||||
req_out->args = args;
|
||||
|
||||
return (int)(p - request);
|
||||
}
|
||||
|
||||
void kvs_free_request(kvs_req_t *req) {
|
||||
if (!req) return;
|
||||
if (req->args) {
|
||||
kvs_free(req->args);
|
||||
req->args = NULL;
|
||||
}
|
||||
req->op = KVS_CMD_COUNT;
|
||||
req->argc = 0;
|
||||
}
|
||||
|
||||
// SET Key Value
|
||||
// tokens[0] : SET
|
||||
// tokens[1] : Key
|
||||
// tokens[2] : Value
|
||||
/**
|
||||
* 输入:req
|
||||
* 输出:rsp
|
||||
* 返回:-1 失败,参数错误,0 成功
|
||||
*/
|
||||
int kvs_execute_one_cmd(const kvs_req_t *req, kvs_rsp_t *rsp_out) {
|
||||
if(!req || !rsp_out) return -1;
|
||||
rsp_out->op = req->op;
|
||||
rsp_out->status = KVS_STATUS_ERROR;
|
||||
rsp_out->data = NULL;
|
||||
rsp_out->dlen = 0;
|
||||
|
||||
#if !BIN_SAFE
|
||||
int kvs_filter_protocol(char **tokens, int count, char *response) {
|
||||
int argc = req->argc;
|
||||
kvs_cmd_t op = req->op;
|
||||
kvs_arg_t *argv = req->args;
|
||||
|
||||
if (tokens[0] == NULL || count == 0 || response == NULL) return -1;
|
||||
uint32_t key_len = 0;
|
||||
const void *key = NULL;
|
||||
uint32_t value_len = 0;
|
||||
const void *val = NULL;
|
||||
|
||||
int cmd = KVS_CMD_START;
|
||||
for (cmd = KVS_CMD_START;cmd < KVS_CMD_COUNT;cmd ++) {
|
||||
if (strcmp(tokens[0], command[cmd]) == 0) {
|
||||
break;
|
||||
}
|
||||
if(argc == 1){
|
||||
key_len = argv[0].len;
|
||||
key = argv[0].data;
|
||||
}else if(argc == 2){
|
||||
key_len = argv[0].len;
|
||||
key = argv[0].data;
|
||||
value_len = argv[1].len;
|
||||
val = argv[1].data;
|
||||
}
|
||||
|
||||
int length = 0;
|
||||
int ret = 0;
|
||||
char *key = tokens[1];
|
||||
char *value = tokens[2];
|
||||
// 基本参数校验(按你原有命令语义)
|
||||
switch (op) {
|
||||
case KVS_CMD_SET:
|
||||
case KVS_CMD_MOD:
|
||||
case KVS_CMD_RSET:
|
||||
case KVS_CMD_RMOD:
|
||||
case KVS_CMD_HSET:
|
||||
case KVS_CMD_HMOD:
|
||||
if (argc != 2 || !key || !val) { rsp_out->status = KVS_STATUS_BADREQ; return -1; }
|
||||
break;
|
||||
case KVS_CMD_GET:
|
||||
case KVS_CMD_DEL:
|
||||
case KVS_CMD_EXIST:
|
||||
case KVS_CMD_RGET:
|
||||
case KVS_CMD_RDEL:
|
||||
case KVS_CMD_REXIST:
|
||||
case KVS_CMD_HGET:
|
||||
case KVS_CMD_HDEL:
|
||||
case KVS_CMD_HEXIST:
|
||||
if (argc != 1 || !key) { rsp_out->status = KVS_STATUS_BADREQ; return -1; }
|
||||
break;
|
||||
case KVS_CMD_SAVE:
|
||||
if(argc != 0) { rsp_out->status = KVS_STATUS_BADREQ; return -1; }
|
||||
break;
|
||||
default:
|
||||
rsp_out->status = KVS_STATUS_BADREQ;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(cmd) {
|
||||
int ret = 0;
|
||||
const char *result = NULL;
|
||||
|
||||
switch (op) {
|
||||
#if ENABLE_ARRAY
|
||||
case KVS_CMD_SET:
|
||||
ret = kvs_array_set(&global_array ,key, value);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "EXIST\r\n");
|
||||
}
|
||||
|
||||
break;
|
||||
case KVS_CMD_GET: {
|
||||
char *result = kvs_array_get(&global_array, key);
|
||||
if (result == NULL) {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "%s\r\n", result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ret = kvs_array_set_bin(&global_array, key, key_len, val, value_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_GET:
|
||||
result = kvs_array_get_bin(&global_array, key, key_len, &value_len);
|
||||
if (!result) { rsp_out->status = KVS_STATUS_NO_EXIST; return 0; }
|
||||
rsp_out->status = KVS_STATUS_OK;
|
||||
rsp_out->data = (uint8_t*)result;
|
||||
rsp_out->dlen = (uint32_t)value_len;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_DEL:
|
||||
ret = kvs_array_del(&global_array ,key);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
ret = kvs_array_del_bin(&global_array, key, key_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_MOD:
|
||||
ret = kvs_array_mod(&global_array ,key, value);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
ret = kvs_array_mod_bin(&global_array, key, key_len, val, value_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_EXIST:
|
||||
ret = kvs_array_exist(&global_array ,key);
|
||||
if (ret == 0) {
|
||||
length = sprintf(response, "EXIST\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
ret = kvs_array_exist_bin(&global_array, key, key_len);
|
||||
rsp_out->status = (ret == 0) ? KVS_STATUS_EXIST : KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
#endif
|
||||
// rbtree
|
||||
|
||||
#if ENABLE_RBTREE
|
||||
case KVS_CMD_RSET:
|
||||
ret = kvs_rbtree_set(&global_rbtree ,key, value);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "EXIST\r\n");
|
||||
}
|
||||
|
||||
break;
|
||||
case KVS_CMD_RGET: {
|
||||
char *result = kvs_rbtree_get(&global_rbtree, key);
|
||||
if (result == NULL) {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "%s\r\n", result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ret = kvs_rbtree_set(&global_rbtree, key, key_len, val, value_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_RGET:
|
||||
result = kvs_rbtree_get(&global_rbtree, key, key_len, &value_len);
|
||||
if (!result) { rsp_out->status = KVS_STATUS_NO_EXIST; return 0; }
|
||||
rsp_out->status = KVS_STATUS_OK;
|
||||
rsp_out->data = (uint8_t*)result;
|
||||
rsp_out->dlen = (uint32_t)value_len;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_RDEL:
|
||||
ret = kvs_rbtree_del(&global_rbtree ,key);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
ret = kvs_rbtree_del(&global_rbtree, key, key_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_RMOD:
|
||||
ret = kvs_rbtree_mod(&global_rbtree ,key, value);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
ret = kvs_rbtree_mod(&global_rbtree, key, key_len, val, value_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_REXIST:
|
||||
ret = kvs_rbtree_exist(&global_rbtree ,key);
|
||||
if (ret == 0) {
|
||||
length = sprintf(response, "EXIST\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
ret = kvs_rbtree_exist(&global_rbtree, key, key_len);
|
||||
rsp_out->status = (ret == 0) ? KVS_STATUS_EXIST : KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if ENABLE_HASH
|
||||
case KVS_CMD_HSET:
|
||||
ret = kvs_hash_set(&global_hash ,key, value);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "EXIST\r\n");
|
||||
}
|
||||
|
||||
break;
|
||||
case KVS_CMD_HGET: {
|
||||
char *result = kvs_hash_get(&global_hash, key);
|
||||
if (result == NULL) {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "%s\r\n", result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ret = kvs_hash_set_bin(&global_hash, key, key_len, val, value_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_HGET:
|
||||
result = kvs_hash_get_bin(&global_hash, key, key_len, &value_len);
|
||||
if (!result) { rsp_out->status = KVS_STATUS_NO_EXIST; return 0; }
|
||||
rsp_out->status = KVS_STATUS_OK;
|
||||
rsp_out->data = (uint8_t*)result;
|
||||
rsp_out->dlen = (uint32_t)value_len;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_HDEL:
|
||||
ret = kvs_hash_del(&global_hash ,key);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
case KVS_CMD_HMOD:
|
||||
ret = kvs_hash_mod(&global_hash ,key, value);
|
||||
if (ret < 0) {
|
||||
length = sprintf(response, "ERROR\r\n");
|
||||
} else if (ret == 0) {
|
||||
length = sprintf(response, "OK\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
case KVS_CMD_HEXIST:
|
||||
ret = kvs_hash_exist(&global_hash ,key);
|
||||
if (ret == 0) {
|
||||
length = sprintf(response, "EXIST\r\n");
|
||||
} else {
|
||||
length = sprintf(response, "NO EXIST\r\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
ret = kvs_hash_del_bin(&global_hash, key, key_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
case KVS_CMD_HMOD:
|
||||
ret = kvs_hash_mod_bin(&global_hash, key, key_len, val, value_len);
|
||||
if (ret < 0) rsp_out->status = KVS_STATUS_ERROR;
|
||||
else if (ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
|
||||
case KVS_CMD_HEXIST:
|
||||
ret = kvs_hash_exist_bin(&global_hash, key, key_len);
|
||||
rsp_out->status = (ret == 0) ? KVS_STATUS_EXIST : KVS_STATUS_NO_EXIST;
|
||||
return 0;
|
||||
#endif
|
||||
case KVS_CMD_SAVE:
|
||||
ret = kvs_save_to_file();
|
||||
if(ret == 0) rsp_out->status = KVS_STATUS_OK;
|
||||
else rsp_out->status = KVS_STATUS_ERROR;
|
||||
return 0;
|
||||
default:
|
||||
rsp_out->status = KVS_STATUS_BADREQ;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return length;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* 构建单条响应
|
||||
* 返回:-1 失败,>=0 响应长度
|
||||
*/
|
||||
int kvs_build_one_rsp(const kvs_rsp_t *results, uint8_t *response, size_t response_cap){
|
||||
if (!results || !response) return -1;
|
||||
|
||||
const uint8_t *end = response + response_cap;
|
||||
uint8_t *p = response;
|
||||
|
||||
// 计算所需长度:1 + 1 + 4 + dlen
|
||||
// 注意防止 size_t 溢出
|
||||
size_t need = 1u + 1u + 4u + (size_t)results->dlen;
|
||||
if (need > response_cap) return -1;
|
||||
|
||||
if (kvs_write_u8(&p, end, (uint8_t)results->op) < 0) return -1;
|
||||
if (kvs_write_u8(&p, end, results->status) < 0) return -1;
|
||||
if (kvs_write_u32(&p, end, results->dlen) < 0) return -1;
|
||||
|
||||
if (results->dlen > 0) {
|
||||
if (!results->data) return -1; // 有长度却没指针,视为错误
|
||||
if (kvs_need(p, end, (size_t)results->dlen) < 0) return -1;
|
||||
memcpy(p, results->data, results->dlen);
|
||||
p += results->dlen;
|
||||
}
|
||||
|
||||
return (int)(p - response);
|
||||
}
|
||||
|
||||
int kvs_save_to_file(){
|
||||
int ret = 0;
|
||||
int rc = 0;
|
||||
#if ENABLE_ARRAY
|
||||
rc = kvs_array_save(&global_array, KVS_ARRAY_FILE);
|
||||
if(rc < 0){
|
||||
printf("kvs_engine_array save error\n");
|
||||
ret = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_RBTREE
|
||||
rc = kvs_rbtree_save(&global_rbtree, KVS_RBTREE_FILE);
|
||||
if(rc < 0){
|
||||
printf("kvs_engine_rbtree save error\n");
|
||||
ret = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_HASH
|
||||
rc = kvs_hash_save(&global_hash, KVS_HASH_FILE);
|
||||
if(rc < 0){
|
||||
printf("kvs_engine_hash save error\n");
|
||||
ret = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
ksv_clear_log(global_cmd_log_fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if NEW_KVSTORE
|
||||
/**
|
||||
* input : request request_length
|
||||
* output : response response_length
|
||||
@@ -296,7 +435,9 @@ int kvs_protocol(char *request, int request_length, char *response, int *respons
|
||||
}else{
|
||||
// 执行成功,在这里保存到日志中。
|
||||
if(rsp.status == KVS_STATUS_OK){
|
||||
if(req.op == KVS_CMD_SET || req.op == KVS_CMD_MOD || req.op == KVS_CMD_DEL){
|
||||
if(req.op != KVS_CMD_GET && req.op != KVS_CMD_EXIST
|
||||
&& req.op != KVS_CMD_RGET && req.op != KVS_CMD_REXIST
|
||||
&& req.op != KVS_CMD_HGET && req.op != KVS_CMD_HEXIST ){
|
||||
kvs_save_cmd_to_logfile(p, len, global_cmd_log_fd);
|
||||
}
|
||||
}
|
||||
@@ -319,48 +460,6 @@ int kvs_protocol(char *request, int request_length, char *response, int *respons
|
||||
*response_length = out_len;
|
||||
return consumed;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* msg: request message
|
||||
* length: length of request message
|
||||
* response: need to send
|
||||
* @return : length of response
|
||||
*/
|
||||
|
||||
int kvs_protocol(char *msg, int length, char *response) { //
|
||||
|
||||
// SET Key Value
|
||||
// GET Key
|
||||
// DEL Key
|
||||
if (msg == NULL || length <= 0 || response == NULL) return -1;
|
||||
|
||||
//printf("recv %d : %s\n", length, msg);
|
||||
|
||||
char *tokens[KVS_MAX_TOKENS] = {0};
|
||||
|
||||
int count = kvs_split_token(msg, tokens);
|
||||
if (count == -1) return -1;
|
||||
|
||||
//memcpy(response, msg, length);
|
||||
|
||||
return kvs_filter_protocol(tokens, count, response);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int init_cmd_log(const char *file, int *logfd){
|
||||
if(!file) return -1;
|
||||
int fd = open(file, O_RDWR | O_CREAT | O_APPEND, 0644);
|
||||
if(fd < 0) return -2;
|
||||
|
||||
*logfd = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int destroy_cmd_log(int logfd){
|
||||
close(logfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_kvengine(void) {
|
||||
|
||||
@@ -374,11 +473,15 @@ int init_kvengine(void) {
|
||||
#if ENABLE_RBTREE
|
||||
memset(&global_rbtree, 0, sizeof(kvs_rbtree_t));
|
||||
kvs_rbtree_create(&global_rbtree);
|
||||
|
||||
kvs_rbtree_load(&global_rbtree, KVS_RBTREE_FILE);
|
||||
#endif
|
||||
|
||||
#if ENABLE_HASH
|
||||
memset(&global_hash, 0, sizeof(kvs_hash_t));
|
||||
kvs_hash_create(&global_hash);
|
||||
|
||||
kvs_hash_load(&global_hash, KVS_HASH_FILE);
|
||||
#endif
|
||||
|
||||
init_cmd_log(KVS_CMD_LOG_FILE, &global_cmd_log_fd);
|
||||
|
||||
Reference in New Issue
Block a user