rbtree和hash的全量持久化操作。rbtree的二进制安全。
粗略测试。
This commit is contained in:
100
kvs_cmd_log.c
Normal file
100
kvs_cmd_log.c
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "kvstore.h"
|
||||
#include "kvs_rw_tools.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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 kvs_save_cmd_to_logfile(const uint8_t *cmd, size_t len, int logfd){
|
||||
if (logfd < 0 || !cmd || len == 0)
|
||||
return -1;
|
||||
|
||||
if (len > UINT32_MAX)
|
||||
return -2;
|
||||
|
||||
uint32_t nlen = htonl((uint32_t)len);
|
||||
|
||||
if (write_full(logfd, &nlen, sizeof(nlen)) < 0)
|
||||
return -3;
|
||||
|
||||
if (write_full(logfd, cmd, len) < 0)
|
||||
return -4;
|
||||
|
||||
if (fsync(logfd) < 0)
|
||||
return -5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvs_replay_log(const char *logfile, int logfd){
|
||||
if (!logfile|| logfd<0) return -1;
|
||||
|
||||
for (;;) {
|
||||
uint32_t nlen = 0;
|
||||
|
||||
int hr = read_full(logfd, &nlen, sizeof(nlen));
|
||||
if (hr == 0) break; /* EOF:正常结束 */
|
||||
if (hr < 0) { return -2; } /* 半截头 */
|
||||
|
||||
uint32_t len = ntohl(nlen);
|
||||
if (len == 0) { return -3; }
|
||||
|
||||
uint8_t *cmd = (uint8_t *)kvs_malloc(len);
|
||||
if (!cmd) { return -5; }
|
||||
|
||||
int pr = read_full(logfd, cmd, len);
|
||||
if (pr <= 0) { /* 半截 payload */
|
||||
kvs_free(cmd);
|
||||
return -6;
|
||||
}
|
||||
|
||||
kvs_req_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
int clen = kvs_parse_one_cmd(cmd, (int)len, &req);
|
||||
if (clen <= 0 || clen != (int)len) {
|
||||
kvs_free_request(&req);
|
||||
kvs_free(cmd);
|
||||
return -7;
|
||||
}
|
||||
|
||||
kvs_rsp_t rsp;
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
|
||||
if (kvs_execute_one_cmd(&req, &rsp) < 0) {
|
||||
kvs_free_request(&req);
|
||||
kvs_free(cmd);
|
||||
return -8;
|
||||
}
|
||||
|
||||
kvs_free_request(&req);
|
||||
kvs_free(cmd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear log file not close
|
||||
*/
|
||||
int ksv_clear_log(int logfd){
|
||||
if(logfd < 0) return -1;
|
||||
ftruncate(logfd, 0);
|
||||
lseek(logfd, 0, SEEK_SET);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user