实现全量持久化:save操作落盘,启动时读取到内存
增量持久化:执行修改操作时将cmd追加到log中,启动时逐条取出顺序执行
This commit is contained in:
95
kvs_array.c
95
kvs_array.c
@@ -1,6 +1,8 @@
|
||||
|
||||
|
||||
#include "kvstore.h"
|
||||
#include "kvs_rw_tools.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
// singleton
|
||||
@@ -40,7 +42,7 @@ void kvs_array_destroy(kvs_array_t *inst) {
|
||||
/**
|
||||
* 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) {
|
||||
int kvs_array_find_index(kvs_array_t *inst, const void *key, uint32_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];
|
||||
@@ -56,8 +58,8 @@ int kvs_array_find_index(kvs_array_t *inst, const void *key, size_t key_len) {
|
||||
* 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) {
|
||||
const void *key, uint32_t key_len,
|
||||
const void *value, uint32_t value_len) {
|
||||
if (!inst || !inst->table || !key || key_len == 0 || !value) return -1;
|
||||
if (inst->total >= KVS_ARRAY_SIZE) return -1;
|
||||
|
||||
@@ -109,9 +111,7 @@ int kvs_array_set_bin(kvs_array_t *inst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *kvs_array_get_bin(kvs_array_t *inst,
|
||||
const void *key, size_t key_len,
|
||||
size_t *out_value_len) {
|
||||
void *kvs_array_get_bin(kvs_array_t *inst, const void *key, uint32_t key_len, uint32_t *out_value_len) {
|
||||
if (out_value_len) *out_value_len = 0;
|
||||
if (!inst || !inst->table || !key || key_len == 0) return NULL;
|
||||
|
||||
@@ -123,7 +123,7 @@ void *kvs_array_get_bin(kvs_array_t *inst,
|
||||
return it->value; // 注意:由 store 持有
|
||||
}
|
||||
|
||||
int kvs_array_del_bin(kvs_array_t *inst, const void *key, size_t key_len) {
|
||||
int kvs_array_del_bin(kvs_array_t *inst, const void *key, uint32_t key_len) {
|
||||
if (!inst || !inst->table || !key || key_len == 0) return -1;
|
||||
|
||||
int idx = kvs_array_find_index(inst, key, key_len);
|
||||
@@ -148,8 +148,8 @@ int kvs_array_del_bin(kvs_array_t *inst, const void *key, size_t key_len) {
|
||||
}
|
||||
|
||||
int kvs_array_mod_bin(kvs_array_t *inst,
|
||||
const void *key, size_t key_len,
|
||||
const void *value, size_t value_len) {
|
||||
const void *key, uint32_t key_len,
|
||||
const void *value, uint32_t value_len) {
|
||||
if (!inst || !inst->table || !key || key_len == 0 || !value) return -1;
|
||||
|
||||
int idx = kvs_array_find_index(inst, key, key_len);
|
||||
@@ -174,12 +174,87 @@ int kvs_array_mod_bin(kvs_array_t *inst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvs_array_exist_bin(kvs_array_t *inst, const void *key, size_t key_len) {
|
||||
int kvs_array_exist_bin(kvs_array_t *inst, const void *key, uint32_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;
|
||||
}
|
||||
|
||||
// return: 0 success, <0 error
|
||||
int kvs_array_save(kvs_array_t *inst, const char* filename){
|
||||
if(!inst || !filename) return -1;
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if(!fp) return -2;
|
||||
|
||||
|
||||
for(int i = 0;i < inst->total; ++ i){
|
||||
kvs_array_item_t *it = &inst->table[i];
|
||||
if(!it->key || it->key_len == 0) continue; // 跳过空槽
|
||||
if(it->value_len > 0 && !it->value) { fclose(fp); return -3; }
|
||||
|
||||
uint32_t klen = htonl(it->key_len);
|
||||
uint32_t vlen = htonl(it->value_len);
|
||||
|
||||
if (kvs_write_file(fp, &klen, 4) < 0) { fclose(fp); return -4; }
|
||||
if (kvs_write_file(fp, &vlen, 4) < 0) { fclose(fp); return -4; }
|
||||
|
||||
if (kvs_write_file(fp, it->key, it->key_len) < 0) { fclose(fp); return -4; }
|
||||
if (it->value_len > 0) {
|
||||
if (kvs_write_file(fp, it->value, it->value_len) < 0) { fclose(fp); return -4; }
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvs_array_load(kvs_array_t *inst, const char* filename) {
|
||||
if (!inst || !filename) return -1;
|
||||
if (!inst->table) return -1;
|
||||
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (!fp) return -2;
|
||||
|
||||
int idx = 0;
|
||||
while(1){
|
||||
uint32_t klen = 0, vlen = 0;
|
||||
|
||||
if (kvs_read_file(fp, &klen, 4) < 0) { fclose(fp); return -3; }
|
||||
if (kvs_read_file(fp, &vlen, 4) < 0) { fclose(fp); return -3; }
|
||||
|
||||
klen = ntohl(klen);
|
||||
vlen = ntohl(vlen);
|
||||
|
||||
if (klen == 0) { fclose(fp); return -3; }
|
||||
|
||||
kvs_array_item_t *it = &inst->table[idx];
|
||||
memset(it, 0, sizeof(*it));
|
||||
|
||||
it->key = (uint8_t *)kvs_malloc(klen);
|
||||
if (!it->key) { fclose(fp); return -3; }
|
||||
it->key_len = klen;
|
||||
if (kvs_read_file(fp, it->key, klen) < 0) { fclose(fp); return -3; }
|
||||
|
||||
if (vlen > 0) {
|
||||
it->value = (uint8_t *)kvs_malloc(vlen);
|
||||
if (!it->value) { fclose(fp); return -4; }
|
||||
it->value_len = vlen;
|
||||
|
||||
if (kvs_read_file(fp, it->value, vlen) < 0) { fclose(fp); return -3; }
|
||||
} else {
|
||||
it->value = NULL;
|
||||
it->value_len = 0;
|
||||
}
|
||||
|
||||
inst->total ++;
|
||||
idx++;
|
||||
if(idx >= KVS_ARRAY_SIZE){ break; }
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
/*
|
||||
* @return: <0, error; =0, success; >0, exist
|
||||
|
||||
Reference in New Issue
Block a user