From de21fe94ec3ff14f6d036f727d01da45e0dbd024 Mon Sep 17 00:00:00 2001 From: 1iaan Date: Thu, 8 Jan 2026 16:20:00 +0800 Subject: [PATCH] =?UTF-8?q?bugfix:=20reactor=E7=BD=91=E7=BB=9C=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E7=9A=84=E5=8D=8A=E5=8C=85=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98=E3=80=82=20=E5=85=A8?= =?UTF-8?q?=E9=87=8F=E6=8C=81=E4=B9=85=E5=8C=96=E6=97=B6=E6=B8=85=E9=99=A4?= =?UTF-8?q?=E5=A2=9E=E9=87=8F=E6=8C=81=E4=B9=85=E5=8C=96=E7=9A=84=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- kvs_rw_tools.c | 19 ++++++ kvs_rw_tools.h | 16 ++--- kvstore.c | 48 +++++++-------- kvstore.h | 2 +- reactor.c | 45 ++++++++++++--- server.h | 2 +- test/test_client.c | 92 ++++++++++++++--------------- test/test_client.h | 36 +++++++----- test/testcase.c | 141 +++++++++++++++++++++++++++++++++++++++++---- 10 files changed, 282 insertions(+), 121 deletions(-) diff --git a/.gitignore b/.gitignore index 22a7c70..2519e0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ NtyCo/ .vscode/ - +*.db proactor copy.c ntyco copy.c diff --git a/kvs_rw_tools.c b/kvs_rw_tools.c index 9b44ddb..227ac4f 100644 --- a/kvs_rw_tools.c +++ b/kvs_rw_tools.c @@ -15,6 +15,8 @@ extern kvs_rbtree_t global_rbtree; extern kvs_hash_t global_hash; #endif +extern int global_cmd_log_fd; + // 0 suc, -1 err int kvs_need(const uint8_t *p, const uint8_t *end, size_t n) { return (p + n <= end) ? 0 : -1; @@ -202,6 +204,7 @@ void kvs_free_request(kvs_req_t *req) { /** * 输入: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; @@ -382,6 +385,10 @@ void kvs_free_request(kvs_req_t *req) { return -1; } +/** + * 构建单条响应 + * 返回:-1 失败,>=0 响应长度 + */ int kvs_build_one_rsp(const kvs_rsp_t *results, uint8_t *response, size_t response_cap){ if (!results || !response) return -1; @@ -420,6 +427,8 @@ int kvs_save_to_file(){ #endif + ksv_clear_log(global_cmd_log_fd); + return ret; } @@ -533,4 +542,14 @@ int kvs_replay_log(const char *logfile, int logfd){ } 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; } \ No newline at end of file diff --git a/kvs_rw_tools.h b/kvs_rw_tools.h index b2ae6ee..b3ad90d 100644 --- a/kvs_rw_tools.h +++ b/kvs_rw_tools.h @@ -25,12 +25,11 @@ int kvs_read_file(FILE *fp, void *buf, size_t n); * Rsp: | OP(1) | status(1) | datalen(4) | data | */ -#define KVS_MAX_CMDS_PER_CALL 64 // 1MB -#define KVS_MAX_RESPONSE (1024u * 1024u) -#define KVS_MAX_ARGC 4 -#define KVS_MAX_ARGLEN (1024u * 1024u) -#define KVS_MAX_CMD_BYTES (4u * 1024u * 1024u) +#define KVS_MAX_RESPONSE (65536) +#define KVS_MAX_ARGLEN (507) +#define KVS_MAX_CMD_BYTES (1024) +#define KVS_MAX_ARGC 3 enum { KVS_STATUS_OK = 0, @@ -65,12 +64,6 @@ enum { KVS_CMD_COUNT, }; -typedef enum { - KVS_OK = 1, - KVS_NEED_MORE = 0, - KVS_ERROR = -1 -}kvs_rc_t; - typedef struct kvs_arg_s{ uint32_t len; const uint8_t *data; @@ -97,5 +90,6 @@ int kvs_save_to_file(); int kvs_save_cmd_to_logfile(const uint8_t *cmd, size_t len, int logfd); int kvs_replay_log(const char *logfile, int logfd); +int ksv_clear_log(int logfd); #endif diff --git a/kvstore.c b/kvstore.c index 21cf39f..021ee2b 100644 --- a/kvstore.c +++ b/kvstore.c @@ -249,16 +249,23 @@ int kvs_filter_protocol(char **tokens, int count, char *response) { #if NEW_KVSTORE /** * input : request request_length - * output : response response_length consumed_out + * output : response response_length * return : -1 error, =0 半包, 1 成功 */ -int kvs_protocol(char *request, int request_length, int *consumed_out, char *response, int *response_length){ - if (!request || request_length <= 0 || !consumed_out || !response || !response_length) return KVS_NEED_MORE; +int kvs_protocol(char *request, int request_length, char *response, int *response_length){ + if (!request || request_length <= 0 || !response || !response_length) return -1; int consumed = 0; int out_len = 0; - int budget = KVS_MAX_CMDS_PER_CALL; - while(consumed < request_length && (budget-- > 0)){ + static int i = 0; + while(consumed < request_length ){ + if(i > 33){ + i = i+1; + i = i-1; + } + if(i == 47) i = 0; + ++i; + kvs_req_t req; memset(&req, 0, sizeof(kvs_req_t)); @@ -267,12 +274,13 @@ int kvs_protocol(char *request, int request_length, int *consumed_out, char *res int len = kvs_parse_one_cmd(p, remain, &req); if(len < 0){ + // 解析失败 kvs_free_request(&req); - *consumed_out = consumed; *response_length = out_len; - return KVS_ERROR; + return -1; } else if(len == 0){ + // 半包 kvs_free_request(&req); break; } @@ -280,32 +288,26 @@ int kvs_protocol(char *request, int request_length, int *consumed_out, char *res kvs_rsp_t rsp; memset(&rsp, 0, sizeof(kvs_rsp_t)); + // 执行失败 if (kvs_execute_one_cmd(&req, &rsp) < 0){ kvs_free_request(&req); - *consumed_out = consumed; *response_length = out_len; - return KVS_ERROR; + return -1; }else{ // 执行成功,在这里保存到日志中。 - if(req.op == KVS_CMD_SET || req.op == KVS_CMD_MOD || req.op == KVS_CMD_DEL){ - printf("%d:%d\n", req.op, req.argc); - kvs_save_cmd_to_logfile(p, len, global_cmd_log_fd); + if(rsp.status == KVS_STATUS_OK){ + if(req.op == KVS_CMD_SET || req.op == KVS_CMD_MOD || req.op == KVS_CMD_DEL){ + kvs_save_cmd_to_logfile(p, len, global_cmd_log_fd); + } } } - if (out_len >= KVS_MAX_RESPONSE) { - kvs_free_request(&req); - *consumed_out = consumed; - *response_length = out_len; - return KVS_ERROR; - } - int resp_len = kvs_build_one_rsp(&rsp, (uint8_t *)response+out_len, KVS_MAX_RESPONSE-out_len); + // 构建响应 <0 构建失败 kvs_free_request(&req); if (resp_len < 0) { - *consumed_out = consumed; *response_length = out_len; - return KVS_ERROR; + return -1; } // printf("resp_len:%d\n", resp_len); @@ -314,10 +316,8 @@ int kvs_protocol(char *request, int request_length, int *consumed_out, char *res consumed += len; } - *consumed_out = consumed; *response_length = out_len; - if (consumed == 0 && out_len == 0) return KVS_NEED_MORE; - return KVS_OK; + return consumed; } #else /* diff --git a/kvstore.h b/kvstore.h index 7f23244..7b2f73e 100644 --- a/kvstore.h +++ b/kvstore.h @@ -35,7 +35,7 @@ // typedef int (*msg_handler)(char *msg, int length, char *response); -typedef int (*msg_handler)(char *request, int request_length, int *consumed_out, char *response, int *response_length); +typedef int (*msg_handler)(char *request, int request_length, char *response, int *response_length); extern int reactor_start(unsigned short port, msg_handler handler); extern int proactor_start(unsigned short port, msg_handler handler); diff --git a/reactor.c b/reactor.c index 1bc9e52..3d9b13f 100644 --- a/reactor.c +++ b/reactor.c @@ -28,15 +28,15 @@ #if ENABLE_KVSTORE // typedef int (*msg_handler)(char *msg, int length, char *response); -typedef int (*msg_handler)(char *request, int request_length, int *consumed_out, char *response, int *response_length); +typedef int (*msg_handler)(char *request, int request_length, char *response, int *response_length); static msg_handler kvs_handler; +// 0 need more, -1 error, =1 suc int kvs_request(struct conn *c) { - int consumed_out; - int ret = kvs_handler(c->rbuffer, c->rlength, &consumed_out, c->wbuffer, &c->wlength); - + int consumed_out = kvs_handler(c->rbuffer, c->rlength, c->wbuffer, &c->wlength); + return consumed_out; } int kvs_response(struct conn *c) { @@ -137,9 +137,17 @@ int accept_cb(int fd) { int recv_cb(int fd) { + struct conn *c = &conn_list[fd]; + int avail = BUFFER_LENGTH - c->rlength; + printf("avail: %d\n", avail); + if (avail <= 0) { + // 缓冲满了还没解析出来:协议异常或包过大 + close(fd); + epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); + return 0; + } - memset(conn_list[fd].rbuffer, 0, BUFFER_LENGTH ); - int count = recv(fd, conn_list[fd].rbuffer, BUFFER_LENGTH, 0); + int count = recv(fd, c->rbuffer + c->rlength, avail, 0); if (count == 0) { // disconnect //printf("client disconnect: %d\n", fd); close(fd); @@ -157,7 +165,7 @@ int recv_cb(int fd) { } - conn_list[fd].rlength = count; + c->rlength += count; //printf("RECV: %s\n", conn_list[fd].rbuffer); #if 0 // echo @@ -176,8 +184,27 @@ int recv_cb(int fd) { ws_request(&conn_list[fd]); #elif ENABLE_KVSTORE + int consumed = kvs_request(c); + if(consumed < 0){ + close(fd); + epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); + return 0; + } - kvs_request(&conn_list[fd]); + // 清理 buffer + if (consumed > 0 && consumed < c->rlength) { + // 有剩余未处理数据,搬移到 buffer 头部 + int left = c->rlength - consumed; + if (left > 0) memmove(c->rbuffer, c->rbuffer + consumed, left); + c->rlength = left; + if (c->wlength > 0) set_event(fd, EPOLLOUT, 0); + return count; + + }else{ + c->rlength = 0; + if(c->wlength > 0) set_event(fd, EPOLLOUT, 0); + return count; + } #endif @@ -222,7 +249,7 @@ int send_cb(int fd) { set_event(fd, EPOLLIN, 0); } #else - + // printf("wlength: %d\n", conn_list[fd].wlength); if (conn_list[fd].wlength != 0) { count = send(fd, conn_list[fd].wbuffer, conn_list[fd].wlength, 0); } diff --git a/server.h b/server.h index 271a05a..78e9462 100644 --- a/server.h +++ b/server.h @@ -5,7 +5,7 @@ #ifndef __SERVER_H__ #define __SERVER_H__ -#define BUFFER_LENGTH 1024 +#define BUFFER_LENGTH 4096 #define ENABLE_HTTP 0 #define ENABLE_WEBSOCKET 0 diff --git a/test/test_client.c b/test/test_client.c index f56f0b5..906d9a7 100644 --- a/test/test_client.c +++ b/test/test_client.c @@ -138,59 +138,55 @@ int parse_response(const uint8_t *buf, int buflen, kvs_response_t *rsp) { void print_response(const char *cmd_name, const kvs_response_t *rsp) { - printf("\n=== %s Response ===\n", cmd_name); - printf("OP: %u\n", rsp->op); - printf("Status: %u ", rsp->status); - - switch (rsp->status) { - case KVS_STATUS_OK: - printf("(OK)\n"); - break; - case KVS_STATUS_ERROR: - printf("(ERROR)\n"); - break; - case KVS_STATUS_NO_EXIST: - printf("(NO_EXIST)\n"); - break; - case KVS_STATUS_EXIST: - printf("(EXISTS)\n"); - break; - default: - printf("(UNKNOWN)\n"); - break; - } - - printf("Data Length: %u\n", rsp->datalen); - - if (rsp->datalen > 0 && rsp->data != NULL) { - printf("Data: "); - // 尝试以字符串形式打印(如果是可打印字符) - int is_printable = 1; - for (uint32_t i = 0; i < rsp->datalen; i++) { - if (rsp->data[i] < 32 || rsp->data[i] > 126) { - is_printable = 0; - break; - } - } - - if (is_printable) { - printf("\""); + printf("%s ", cmd_name); + if(rsp->op == KVS_CMD_GET){ + if (rsp->datalen > 0 && rsp->data != NULL) { + printf("Data: "); + // 尝试以字符串形式打印(如果是可打印字符) + int is_printable = 1; for (uint32_t i = 0; i < rsp->datalen; i++) { - printf("%c", rsp->data[i]); + if (rsp->data[i] < 32 || rsp->data[i] > 126) { + is_printable = 0; + break; + } + } + + if (is_printable) { + printf("\""); + for (uint32_t i = 0; i < rsp->datalen; i++) { + printf("%c", rsp->data[i]); + } + printf("\"\n"); + } else { + // 以十六进制打印 + printf("0x"); + for (uint32_t i = 0; i < rsp->datalen; i++) { + printf("%02x", rsp->data[i]); + } + printf("\n"); } - printf("\"\n"); } else { - // 以十六进制打印 - printf("0x"); - for (uint32_t i = 0; i < rsp->datalen; i++) { - printf("%02x", rsp->data[i]); - } - printf("\n"); + printf("Data: (empty)\n"); + } + }else { + switch (rsp->status) { + case KVS_STATUS_OK: + printf("(OK)\n"); + break; + case KVS_STATUS_ERROR: + printf("(ERROR)\n"); + break; + case KVS_STATUS_NO_EXIST: + printf("(NO_EXIST)\n"); + break; + case KVS_STATUS_EXIST: + printf("(EXISTS)\n"); + break; + default: + printf("(UNKNOWN)\n"); + break; } - } else { - printf("Data: (empty)\n"); } - printf("==================\n"); } int verify_response(const kvs_response_t *rsp, uint8_t expected_op, diff --git a/test/test_client.h b/test/test_client.h index 6709ad6..9ab644f 100644 --- a/test/test_client.h +++ b/test/test_client.h @@ -14,8 +14,9 @@ #include #include -#define CMD_SIZE (4096) +#define CMD_SIZE (1024) #define BATCH_SIZE (65536) +#define KVS_BATCH_MAX 64 #define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000) #define PRESP print_response @@ -81,7 +82,6 @@ int verify_response(const kvs_response_t *rsp, uint8_t expected_op, -#define KVS_BATCH_MAX 64 typedef struct { uint8_t buf[BATCH_SIZE]; @@ -101,10 +101,8 @@ static void kvs_batch_init(kvs_batch_t *b) * 用 getcmd() 生成单条命令,然后 append 到 batch buffer * 返回:0 成功,-1 失败(太多条 or buffer 不够) */ -static int kvs_batch_add(kvs_batch_t *b, uint8_t op, const char *key, const char *value) -{ +static int kvs_batch_add(kvs_batch_t *b, uint8_t op, const char *key, const char *value){ if (b->cnt >= KVS_BATCH_MAX) return -1; - uint8_t tmp[CMD_SIZE]; int n = getcmd(op, key, value, tmp); // 你提供的函数 if (n <= 0) return -1; @@ -124,6 +122,7 @@ static int kvs_batch_add(kvs_batch_t *b, uint8_t op, const char *key, const char */ static int kvs_batch_send(int fd, const kvs_batch_t *b) { + printf("send : %d\n", b->len); return (int)send(fd, b->buf, b->len, 0); } @@ -138,19 +137,26 @@ static int kvs_batch_recv_parse(int fd, uint8_t *recvbuf, int recvbuf_cap) { - int nrecv = (int)recv(fd, recvbuf, recvbuf_cap, 0); - if (nrecv <= 0) return -1; - - int off = 0; int parsed = 0; + int used = 0; - while (parsed < b->cnt && off < nrecv) { - int consumed = parse_response(recvbuf + off, nrecv - off, &rsps[parsed]); - if (consumed <= 0) break; // 不够解析/失败,简单处理:直接退出 + while(parsed < b->cnt){ + printf("recv loop: parsed=%d\n", parsed); + int nrecv = (int)recv(fd, recvbuf+used, recvbuf_cap, 0); + printf("recv nrecv=%d\n", nrecv); + if (nrecv <= 0) return -1; - off += consumed; - parsed++; + int off = 0; + + while (parsed < b->cnt) { + int consumed = parse_response(recvbuf + used, nrecv - off, &rsps[parsed]); + if (consumed <= 0) break; // 不够解析/失败,简单处理:直接退出 + + off += consumed; + used+= consumed; + parsed++; + } + printf("after parse: parsed=%d, used=%d\n", parsed, used); } - return parsed; } \ No newline at end of file diff --git a/test/testcase.c b/test/testcase.c index 617ac54..3426a35 100644 --- a/test/testcase.c +++ b/test/testcase.c @@ -95,7 +95,67 @@ void array_testcase_1w(int connfd) { } -void do_batch_example(int fd) +void rbtree_testcase_1w(int connfd) { + + int count = 1000; + int i = 0; + + struct timeval tv_begin; + gettimeofday(&tv_begin, NULL); + + for (i = 0;i < count;i ++) { + testcase(connfd, KVS_CMD_RSET, "name", "lian", KVS_STATUS_OK, NULL, "SET NAME"); + testcase(connfd, KVS_CMD_RGET, "name", NULL, KVS_STATUS_OK, "lian", "GET NAME"); + testcase(connfd, KVS_CMD_RMOD, "name", "liu", KVS_STATUS_OK, NULL, "MOD NAME"); + testcase(connfd, KVS_CMD_RGET, "name", NULL, KVS_STATUS_OK, "liu", "GET NAME"); + testcase(connfd, KVS_CMD_REXIST, "name", NULL, KVS_STATUS_EXIST, NULL, "EXIST NAME"); + testcase(connfd, KVS_CMD_RDEL, "name", NULL, KVS_STATUS_OK, NULL, "DEL NAME"); + testcase(connfd, KVS_CMD_REXIST, "name", NULL, KVS_STATUS_NO_EXIST, NULL, "NOT EXIST NAME"); + + testcase(connfd, KVS_CMD_RMOD, "stu", "liu", KVS_STATUS_NO_EXIST, NULL, "MOD NAME"); + testcase(connfd, KVS_CMD_RDEL, "stu", NULL, KVS_STATUS_NO_EXIST, NULL, "DEL SUT"); + } + + struct timeval tv_end; + gettimeofday(&tv_end, NULL); + + int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms + + printf("array testcase --> time_used: %d, qps: %d\n", time_used, 9000 * 1000 / time_used); + +} + +void hash_testcase_1w(int connfd) { + + int count = 1000; + int i = 0; + + struct timeval tv_begin; + gettimeofday(&tv_begin, NULL); + + for (i = 0;i < count;i ++) { + testcase(connfd, KVS_CMD_HSET, "name", "lian", KVS_STATUS_OK, NULL, "SET NAME"); + testcase(connfd, KVS_CMD_HGET, "name", NULL, KVS_STATUS_OK, "lian", "GET NAME"); + testcase(connfd, KVS_CMD_HMOD, "name", "liu", KVS_STATUS_OK, NULL, "MOD NAME"); + testcase(connfd, KVS_CMD_HGET, "name", NULL, KVS_STATUS_OK, "liu", "GET NAME"); + testcase(connfd, KVS_CMD_HEXIST, "name", NULL, KVS_STATUS_EXIST, NULL, "EXIST NAME"); + testcase(connfd, KVS_CMD_HDEL, "name", NULL, KVS_STATUS_OK, NULL, "DEL NAME"); + testcase(connfd, KVS_CMD_HEXIST, "name", NULL, KVS_STATUS_NO_EXIST, NULL, "NOT EXIST NAME"); + + testcase(connfd, KVS_CMD_HMOD, "stu", "liu", KVS_STATUS_NO_EXIST, NULL, "MOD NAME"); + testcase(connfd, KVS_CMD_HDEL, "stu", NULL, KVS_STATUS_NO_EXIST, NULL, "DEL SUT"); + } + + struct timeval tv_end; + gettimeofday(&tv_end, NULL); + + int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms + + printf("array testcase --> time_used: %d, qps: %d\n", time_used, 9000 * 1000 / time_used); + +} + +void do_batch_SET_example(int fd) { kvs_batch_t batch; kvs_batch_init(&batch); @@ -103,7 +163,7 @@ void do_batch_example(int fd) char key[10]={0}, val[10]={0}; // 组 batch(最多 64 条) - for(int i = 0;i < 24; ++ i){ + for(int i = 0;i < 48; ++ i){ int len = sprintf(key, "k%d", i); len = sprintf(val, "v%d", i); kvs_batch_add(&batch, KVS_CMD_SET, key, val); @@ -120,16 +180,67 @@ void do_batch_example(int fd) // 打印/处理 for (int i = 0; i < nrsp; i++) { - PRESP("BATCH", &rsps[i]); - } + int len = sprintf(key, "SET%d", i); + PRESP(key, &rsps[i]); + } +} +void do_batch_GET_example(int fd) +{ + kvs_batch_t batch; + kvs_batch_init(&batch); - // for(int i = 0;i < 24; ++ i){ - // int len = sprintf(key, "k%d", i); - // len = sprintf(val, "v%d", i); - // testcase(fd, KVS_CMD_GET, key, NULL, KVS_STATUS_OK, val, "GET K"); - // } + char key[10]={0}, val[10]={0}; + // 组 batch(最多 64 条) + for(int i = 0;i < 48; ++ i){ + int len = sprintf(key, "k%d", i); + kvs_batch_add(&batch, KVS_CMD_GET, key, NULL); + } + + // 一次性发送 + kvs_batch_send(fd, &batch); + + // 一次性 recv + parse + uint8_t recvbuf[BATCH_SIZE]; + kvs_response_t rsps[KVS_BATCH_MAX]; + + int nrsp = kvs_batch_recv_parse(fd, &batch, rsps, recvbuf, sizeof(recvbuf)); + + // 打印/处理 + for (int i = 0; i < nrsp; i++) { + int len = sprintf(key, "GET%d", i); + PRESP(key, &rsps[i]); + } +} + +void do_batch_DEL_example(int fd) +{ + kvs_batch_t batch; + kvs_batch_init(&batch); + + char key[10]={0}, val[10]={0}; + + // 组 batch(最多 64 条) + for(int i = 0;i < 48; ++ i){ + int len = sprintf(key, "k%d", i); + kvs_batch_add(&batch, KVS_CMD_DEL, key, NULL); + } + + // 一次性发送 + kvs_batch_send(fd, &batch); + + // 一次性 recv + parse + uint8_t recvbuf[BATCH_SIZE]; + kvs_response_t rsps[KVS_BATCH_MAX]; + + int nrsp = kvs_batch_recv_parse(fd, &batch, rsps, recvbuf, sizeof(recvbuf)); + + // 打印/处理 + for (int i = 0; i < nrsp; i++) { + int len = sprintf(key, "DEL%d", i); + PRESP(key, &rsps[i]); + } } void save(int connfd){ @@ -150,10 +261,18 @@ int main(int argc, char *argv[]) { int connfd = connect_tcpserver(ip, port); if(mode == 0){ - do_batch_example(connfd); + do_batch_SET_example(connfd); }else if(mode == 1){ - array_testcase_1w(connfd); + do_batch_GET_example(connfd); }else if(mode == 2){ + do_batch_DEL_example(connfd); + }else if(mode == 10){ + array_testcase_1w(connfd); + }else if(mode == 11){ + rbtree_testcase_1w(connfd); + }else if(mode == 12){ + hash_testcase_1w(connfd); + }else if(mode == -1){ save(connfd); } return 0;