diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dad2cd4 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ + + +CC = gcc +TARGET = kvstore +SRCS = kvstore.c ntyco.c proactor.c kvs_array.c kvs_rbtree.c +INC = -I ./NtyCo/core/ +LIBS = -L ./NtyCo/ -lntyco -luring + + +all: + $(CC) -o $(TARGET) $(SRCS) $(INC) $(LIBS) + +clean: + rm -rf kvstore + diff --git a/kvs_array.c b/kvs_array.c index 4a1ed18..88259c2 100644 --- a/kvs_array.c +++ b/kvs_array.c @@ -119,6 +119,8 @@ int kvs_array_del(kvs_array_t *inst, char *key) { kvs_free(inst->table[i].value); inst->table[i].value = NULL; + inst->idx = i; + return 0; } } @@ -166,6 +168,8 @@ int kvs_array_mod(kvs_array_t *inst, char *key, char *value) { * @return 0: exist, 1: no exist */ int kvs_array_exist(kvs_array_t *inst, char *key) { + + if (!inst || !key) return -1; char *str = kvs_array_get(inst, key); if (!str) { diff --git a/kvs_rbtree.c b/kvs_rbtree.c new file mode 100755 index 0000000..f215e43 --- /dev/null +++ b/kvs_rbtree.c @@ -0,0 +1,550 @@ + + + +#include +#include +#include + + +#include "kvstore.h" + +rbtree_node *rbtree_mini(rbtree *T, rbtree_node *x) { + while (x->left != T->nil) { + x = x->left; + } + return x; +} + +rbtree_node *rbtree_maxi(rbtree *T, rbtree_node *x) { + while (x->right != T->nil) { + x = x->right; + } + return x; +} + +rbtree_node *rbtree_successor(rbtree *T, rbtree_node *x) { + rbtree_node *y = x->parent; + + if (x->right != T->nil) { + return rbtree_mini(T, x->right); + } + + while ((y != T->nil) && (x == y->right)) { + x = y; + y = y->parent; + } + return y; +} + + +void rbtree_left_rotate(rbtree *T, rbtree_node *x) { + + rbtree_node *y = x->right; // x --> y , y --> x, right --> left, left --> right + + x->right = y->left; //1 1 + if (y->left != T->nil) { //1 2 + y->left->parent = x; + } + + y->parent = x->parent; //1 3 + if (x->parent == T->nil) { //1 4 + T->root = y; + } else if (x == x->parent->left) { + x->parent->left = y; + } else { + x->parent->right = y; + } + + y->left = x; //1 5 + x->parent = y; //1 6 +} + + +void rbtree_right_rotate(rbtree *T, rbtree_node *y) { + + rbtree_node *x = y->left; + + y->left = x->right; + if (x->right != T->nil) { + x->right->parent = y; + } + + x->parent = y->parent; + if (y->parent == T->nil) { + T->root = x; + } else if (y == y->parent->right) { + y->parent->right = x; + } else { + y->parent->left = x; + } + + x->right = y; + y->parent = x; +} + +void rbtree_insert_fixup(rbtree *T, rbtree_node *z) { + + while (z->parent->color == RED) { //z ---> RED + if (z->parent == z->parent->parent->left) { + rbtree_node *y = z->parent->parent->right; + if (y->color == RED) { + z->parent->color = BLACK; + y->color = BLACK; + z->parent->parent->color = RED; + + z = z->parent->parent; //z --> RED + } else { + + if (z == z->parent->right) { + z = z->parent; + rbtree_left_rotate(T, z); + } + + z->parent->color = BLACK; + z->parent->parent->color = RED; + rbtree_right_rotate(T, z->parent->parent); + } + }else { + rbtree_node *y = z->parent->parent->left; + if (y->color == RED) { + z->parent->color = BLACK; + y->color = BLACK; + z->parent->parent->color = RED; + + z = z->parent->parent; //z --> RED + } else { + if (z == z->parent->left) { + z = z->parent; + rbtree_right_rotate(T, z); + } + + z->parent->color = BLACK; + z->parent->parent->color = RED; + rbtree_left_rotate(T, z->parent->parent); + } + } + + } + + T->root->color = BLACK; +} + + +void rbtree_insert(rbtree *T, rbtree_node *z) { + + rbtree_node *y = T->nil; + rbtree_node *x = T->root; + + while (x != T->nil) { + y = x; +#if ENABLE_KEY_CHAR + + if (strcmp(z->key, x->key) < 0) { + x = x->left; + } else if (strcmp(z->key, x->key) > 0) { + x = x->right; + } else { + return ; + } + +#else + if (z->key < x->key) { + x = x->left; + } else if (z->key > x->key) { + x = x->right; + } else { //Exist + return ; + } +#endif + } + + z->parent = y; + if (y == T->nil) { + T->root = z; +#if ENABLE_KEY_CHAR + } else if (strcmp(z->key, y->key) < 0) { +#else + } else if (z->key < y->key) { +#endif + y->left = z; + } else { + y->right = z; + } + + z->left = T->nil; + z->right = T->nil; + z->color = RED; + + rbtree_insert_fixup(T, z); +} + +void rbtree_delete_fixup(rbtree *T, rbtree_node *x) { + + while ((x != T->root) && (x->color == BLACK)) { + if (x == x->parent->left) { + + rbtree_node *w= x->parent->right; + if (w->color == RED) { + w->color = BLACK; + x->parent->color = RED; + + rbtree_left_rotate(T, x->parent); + w = x->parent->right; + } + + if ((w->left->color == BLACK) && (w->right->color == BLACK)) { + w->color = RED; + x = x->parent; + } else { + + if (w->right->color == BLACK) { + w->left->color = BLACK; + w->color = RED; + rbtree_right_rotate(T, w); + w = x->parent->right; + } + + w->color = x->parent->color; + x->parent->color = BLACK; + w->right->color = BLACK; + rbtree_left_rotate(T, x->parent); + + x = T->root; + } + + } else { + + rbtree_node *w = x->parent->left; + if (w->color == RED) { + w->color = BLACK; + x->parent->color = RED; + rbtree_right_rotate(T, x->parent); + w = x->parent->left; + } + + if ((w->left->color == BLACK) && (w->right->color == BLACK)) { + w->color = RED; + x = x->parent; + } else { + + if (w->left->color == BLACK) { + w->right->color = BLACK; + w->color = RED; + rbtree_left_rotate(T, w); + w = x->parent->left; + } + + w->color = x->parent->color; + x->parent->color = BLACK; + w->left->color = BLACK; + rbtree_right_rotate(T, x->parent); + + x = T->root; + } + + } + } + + x->color = BLACK; +} + +rbtree_node *rbtree_delete(rbtree *T, rbtree_node *z) { + + rbtree_node *y = T->nil; + rbtree_node *x = T->nil; + + if ((z->left == T->nil) || (z->right == T->nil)) { + y = z; + } else { + y = rbtree_successor(T, z); + } + + if (y->left != T->nil) { + x = y->left; + } else if (y->right != T->nil) { + x = y->right; + } + + x->parent = y->parent; + if (y->parent == T->nil) { + T->root = x; + } else if (y == y->parent->left) { + y->parent->left = x; + } else { + y->parent->right = x; + } + + if (y != z) { +#if ENABLE_KEY_CHAR + + void *tmp = z->key; + z->key = y->key; + y->key = tmp; + + tmp = z->value; + z->value= y->value; + y->value = tmp; + +#else + z->key = y->key; + z->value = y->value; +#endif + } + + if (y->color == BLACK) { + rbtree_delete_fixup(T, x); + } + + return y; +} + +rbtree_node *rbtree_search(rbtree *T, KEY_TYPE key) { + + rbtree_node *node = T->root; + while (node != T->nil) { +#if ENABLE_KEY_CHAR + + if (strcmp(key, node->key) < 0) { + node = node->left; + } else if (strcmp(key, node->key) > 0) { + node = node->right; + } else { + return node; + } + +#else + if (key < node->key) { + node = node->left; + } else if (key > node->key) { + node = node->right; + } else { + return node; + } +#endif + } + return T->nil; +} + + +void rbtree_traversal(rbtree *T, rbtree_node *node) { + if (node != T->nil) { + rbtree_traversal(T, node->left); +#if ENABLE_KEY_CHAR + printf("key:%s, value:%s\n", node->key, (char *)node->value); +#else + printf("key:%d, color:%d\n", node->key, node->color); +#endif + rbtree_traversal(T, node->right); + } +} + + +#if 0 + +int main() { + +#if ENABLE_KEY_CHAR + + char* keyArray[10] = {"King", "Darren", "Mark", "Vico", "Nick", "qiuxiang", "youzi", "taozi", "123", "234"}; + char* valueArray[10] = {"1King", "2Darren", "3Mark", "4Vico", "5Nick", "6qiuxiang", "7youzi", "8taozi", "9123", "10234"}; + + rbtree *T = (rbtree *)malloc(sizeof(rbtree)); + if (T == NULL) { + printf("malloc failed\n"); + return -1; + } + + T->nil = (rbtree_node*)malloc(sizeof(rbtree_node)); + T->nil->color = BLACK; + T->root = T->nil; + + rbtree_node *node = T->nil; + int i = 0; + for (i = 0;i < 10;i ++) { + node = (rbtree_node*)malloc(sizeof(rbtree_node)); + + node->key = malloc(strlen(keyArray[i]) + 1); + memset(node->key, 0, strlen(keyArray[i]) + 1); + strcpy(node->key, keyArray[i]); + + node->value = malloc(strlen(valueArray[i]) + 1); + memset(node->value, 0, strlen(valueArray[i]) + 1); + strcpy(node->value, valueArray[i]); + + rbtree_insert(T, node); + + } + + rbtree_traversal(T, T->root); + printf("----------------------------------------\n"); + + for (i = 0;i < 10;i ++) { + + rbtree_node *node = rbtree_search(T, keyArray[i]); + rbtree_node *cur = rbtree_delete(T, node); + free(cur); + + rbtree_traversal(T, T->root); + printf("----------------------------------------\n"); + } + +#else + + + int keyArray[20] = {24,25,13,35,23, 26,67,47,38,98, 20,19,17,49,12, 21,9,18,14,15}; + + rbtree *T = (rbtree *)malloc(sizeof(rbtree)); + if (T == NULL) { + printf("malloc failed\n"); + return -1; + } + + T->nil = (rbtree_node*)malloc(sizeof(rbtree_node)); + T->nil->color = BLACK; + T->root = T->nil; + + rbtree_node *node = T->nil; + int i = 0; + for (i = 0;i < 20;i ++) { + node = (rbtree_node*)malloc(sizeof(rbtree_node)); + node->key = keyArray[i]; + node->value = NULL; + + rbtree_insert(T, node); + + } + + rbtree_traversal(T, T->root); + printf("----------------------------------------\n"); + + for (i = 0;i < 20;i ++) { + + rbtree_node *node = rbtree_search(T, keyArray[i]); + rbtree_node *cur = rbtree_delete(T, node); + free(cur); + + rbtree_traversal(T, T->root); + printf("----------------------------------------\n"); + } +#endif + + +} + +#endif + + +typedef struct _rbtree kvs_rbtree_t; + +kvs_rbtree_t global_rbtree; + +// 5 + 2 +int kvs_rbtree_create(kvs_rbtree_t *inst) { + + if (inst == NULL) return 1; + + inst->nil = (rbtree_node*)kvs_malloc(sizeof(rbtree_node)); + inst->nil->color = BLACK; + inst->root = inst->nil; + + return 0; + +} + +void kvs_rbtree_destory(kvs_rbtree_t *inst) { + + if (inst == NULL) return ; + + rbtree_node *node = NULL; + + while (!(node = inst->root)) { + + rbtree_node *mini = rbtree_mini(inst, node); + + rbtree_node *cur = rbtree_delete(inst, mini); + kvs_free(cur); + + } + + kvs_free(inst->nil); + + return ; + +} + + +int kvs_rbtree_set(kvs_rbtree_t *inst, char *key, char *value) { + + if (!inst || !key || !value) return -1; + + rbtree_node *node = (rbtree_node*)kvs_malloc(sizeof(rbtree_node)); + + node->key = kvs_malloc(strlen(key) + 1); + if (!node->key) return -2; + memset(node->key, 0, strlen(key) + 1); + strcpy(node->key, key); + + node->value = kvs_malloc(strlen(value) + 1); + if (!node->value) return -2; + memset(node->value, 0, strlen(value) + 1); + strcpy(node->value, value); + + rbtree_insert(inst, node); + + return 0; +} + + +char* kvs_rbtree_get(kvs_rbtree_t *inst, char *key) { + + if (!inst || !key) return NULL; + + rbtree_node *node = rbtree_search(inst, key); + + return node->value; + +} + +int kvs_rbtree_del(kvs_rbtree_t *inst, char *key) { + + if (!inst || !key) return -1; + + rbtree_node *node = rbtree_search(inst, key); + if (!node) return 1; // no exist + + rbtree_node *cur = rbtree_delete(inst, node); + free(cur); + + return 0; +} + +int kvs_rbtree_mod(kvs_rbtree_t *inst, char *key, char *value) { + + if (!inst || !key || !value) return -1; + + rbtree_node *node = rbtree_search(inst, key); + if (!node) return 1; // no exist + + kvs_free(node->value); + + node->value = kvs_malloc(strlen(value) + 1); + if (!node->value) return -2; + + memset(node->value, 0, strlen(value) + 1); + strcpy(node->value, value); + + return 0; + +} + +int kvs_rbtree_exist(kvs_rbtree_t *inst, char *key) { + + if (!inst || !key) return -1; + + rbtree_node *node = rbtree_search(inst, key); + if (!node) return 1; // no exist + + return 0; +} + + diff --git a/kvstore.c b/kvstore.c index 74498e5..4d51cc1 100644 --- a/kvstore.c +++ b/kvstore.c @@ -9,6 +9,9 @@ extern kvs_array_t global_array; #endif +#if ENABLE_RBTREE +extern kvs_rbtree_t global_rbtree; +#endif @@ -22,16 +25,25 @@ void kvs_free(void *ptr) { const char *command[] = { - "SET", "GET", "DEL", "MOD", "EXIST" + "SET", "GET", "DEL", "MOD", "EXIST", + "RSET", "RGET", "RDEL", "RMOD", "REXIST" }; enum { KVS_CMD_START = 0, + // array KVS_CMD_SET = KVS_CMD_START, KVS_CMD_GET, KVS_CMD_DEL, KVS_CMD_MOD, KVS_CMD_EXIST, + // rbtree + KVS_CMD_RSET, + KVS_CMD_RGET, + KVS_CMD_RDEL, + KVS_CMD_RMOD, + KVS_CMD_REXIST, + KVS_CMD_COUNT, }; @@ -50,7 +62,7 @@ int kvs_split_token(char *msg, char *tokens[]) { char *token = strtok(msg, " "); while (token != NULL) { - printf("idx: %d, %s\n", idx, token); + //printf("idx: %d, %s\n", idx, token); tokens[idx ++] = token; token = strtok(NULL, " "); @@ -82,7 +94,7 @@ int kvs_filter_protocol(char **tokens, int count, char *response) { char *value = tokens[2]; switch(cmd) { - +#if ENABLE_ARRAY case KVS_CMD_SET: ret = kvs_array_set(&global_array ,key, value); if (ret < 0) { @@ -94,7 +106,7 @@ int kvs_filter_protocol(char **tokens, int count, char *response) { } break; - case KVS_CMD_GET: + case KVS_CMD_GET: { char *result = kvs_array_get(&global_array, key); if (result == NULL) { length = sprintf(response, "NO EXIST\r\n"); @@ -102,6 +114,7 @@ int kvs_filter_protocol(char **tokens, int count, char *response) { length = sprintf(response, "%s\r\n", result); } break; + } case KVS_CMD_DEL: ret = kvs_array_del(&global_array ,key); if (ret < 0) { @@ -125,12 +138,66 @@ int kvs_filter_protocol(char **tokens, int count, char *response) { case KVS_CMD_EXIST: ret = kvs_array_exist(&global_array ,key); if (ret == 0) { - length = sprintf(response, "EXIST\n"); + length = sprintf(response, "EXIST\r\n"); } else { length = sprintf(response, "NO EXIST\r\n"); } break; +#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; + } + 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; + 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; + 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; +#endif + default: + assert(0); } return length; @@ -151,7 +218,7 @@ int kvs_protocol(char *msg, int length, char *response) { // // DEL Key if (msg == NULL || length <= 0 || response == NULL) return -1; - printf("recv %d : %s\n", length, msg); + //printf("recv %d : %s\n", length, msg); char *tokens[KVS_MAX_TOKENS] = {0}; @@ -171,9 +238,25 @@ int init_kvengine(void) { kvs_array_create(&global_array); #endif +#if ENABLE_RBTREE + memset(&global_rbtree, 0, sizeof(kvs_rbtree_t)); + kvs_rbtree_create(&global_rbtree); +#endif + return 0; } +void dest_kvengine(void) { +#if ENABLE_ARRAY + kvs_array_destory(&global_array); +#endif +#if ENABLE_RBTREE + kvs_rbtree_destory(&global_rbtree); +#endif + +} + + int main(int argc, char *argv[]) { @@ -191,6 +274,9 @@ int main(int argc, char *argv[]) { #elif (NETWORK_SELECT == NETWORK_NTYCO) proactor_start(port, kvs_protocol); #endif + + dest_kvengine(); + } diff --git a/kvstore.h b/kvstore.h index 243dc9c..be89820 100644 --- a/kvstore.h +++ b/kvstore.h @@ -8,7 +8,7 @@ #include #include #include - +#include #include @@ -23,7 +23,7 @@ #define KVS_MAX_TOKENS 128 #define ENABLE_ARRAY 1 - +#define ENABLE_RBTREE 1 @@ -61,6 +61,49 @@ int kvs_array_mod(kvs_array_t *inst, char *key, char *value); int kvs_array_exist(kvs_array_t *inst, char *key); +#endif + + +#if ENABLE_RBTREE + +#define RED 1 +#define BLACK 2 + +#define ENABLE_KEY_CHAR 1 + +#if ENABLE_KEY_CHAR +typedef char* KEY_TYPE; +#else +typedef int KEY_TYPE; // key +#endif + +typedef struct _rbtree_node { + unsigned char color; + struct _rbtree_node *right; + struct _rbtree_node *left; + struct _rbtree_node *parent; + KEY_TYPE key; + void *value; +} rbtree_node; + +typedef struct _rbtree { + rbtree_node *root; + rbtree_node *nil; +} rbtree; + + +typedef struct _rbtree kvs_rbtree_t; + +int kvs_rbtree_create(kvs_rbtree_t *inst); +void kvs_rbtree_destory(kvs_rbtree_t *inst); +int kvs_rbtree_set(kvs_rbtree_t *inst, char *key, char *value); +char* kvs_rbtree_get(kvs_rbtree_t *inst, char *key); +int kvs_rbtree_del(kvs_rbtree_t *inst, char *key); +int kvs_rbtree_mod(kvs_rbtree_t *inst, char *key, char *value); +int kvs_rbtree_exist(kvs_rbtree_t *inst, char *key); + + + #endif diff --git a/testcase.c b/testcase.c new file mode 100755 index 0000000..69b1a29 --- /dev/null +++ b/testcase.c @@ -0,0 +1,162 @@ + + +#include +#include +#include +#include +#include + + +#define MAX_MSG_LENGTH 1024 +#define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000) + + +int send_msg(int connfd, char *msg, int length) { + + int res = send(connfd, msg, length, 0); + if (res < 0) { + perror("send"); + exit(1); + } + return res; +} + +int recv_msg(int connfd, char *msg, int length) { + + int res = recv(connfd, msg, length, 0); + if (res < 0) { + perror("recv"); + exit(1); + } + return res; + +} + + + + +void testcase(int connfd, char *msg, char *pattern, char *casename) { + + if (!msg || !pattern || !casename) return ; + + send_msg(connfd, msg, strlen(msg)); + + char result[MAX_MSG_LENGTH] = {0}; + recv_msg(connfd, result, MAX_MSG_LENGTH); + + if (strcmp(result, pattern) == 0) { + printf("==> PASS -> %s\n", casename); + } else { + printf("==> FAILED -> %s, '%s' != '%s' \n", casename, result, pattern); + exit(1); + } + +} + + + +int connect_tcpserver(const char *ip, unsigned short port) { + + int connfd = socket(AF_INET, SOCK_STREAM, 0); + + struct sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(struct sockaddr_in)); + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(ip); + server_addr.sin_port = htons(port); + + if (0 != connect(connfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in))) { + perror("connect"); + return -1; + } + + return connfd; + +} + + +void array_testcase(int connfd) { + + testcase(connfd, "SET Teacher King", "OK\r\n", "SET-Teacher"); + testcase(connfd, "GET Teacher", "King\r\n", "GET-Teacher"); + testcase(connfd, "MOD Teacher Darren", "OK\r\n", "MOD-Teacher"); + testcase(connfd, "GET Teacher", "Darren\r\n", "GET-Teacher"); + testcase(connfd, "EXIST Teacher", "EXIST\r\n", "GET-Teacher"); + testcase(connfd, "DEL Teacher", "OK\r\n", "DEL-Teacher"); + testcase(connfd, "GET Teacher", "NO EXIST\r\n", "GET-Teacher"); + testcase(connfd, "MOD Teacher KING", "NO EXIST\r\n", "MOD-Teacher"); + testcase(connfd, "EXIST Teacher", "NO EXIST\r\n", "GET-Teacher"); + +} + +void array_testcase_10w(int connfd) { + + int count = 1000; + int i = 0; + + struct timeval tv_begin; + gettimeofday(&tv_begin, NULL); + + for (i = 0;i < count;i ++) { + + testcase(connfd, "SET Teacher King", "OK\r\n", "SET-Teacher"); + testcase(connfd, "GET Teacher", "King\r\n", "GET-Teacher"); + testcase(connfd, "MOD Teacher Darren", "OK\r\n", "MOD-Teacher"); + testcase(connfd, "GET Teacher", "Darren\r\n", "GET-Teacher"); + testcase(connfd, "EXIST Teacher", "EXIST\r\n", "GET-Teacher"); + testcase(connfd, "DEL Teacher", "OK\r\n", "DEL-Teacher"); + testcase(connfd, "GET Teacher", "NO EXIST\r\n", "GET-Teacher"); + testcase(connfd, "MOD Teacher KING", "NO EXIST\r\n", "MOD-Teacher"); + testcase(connfd, "EXIST Teacher", "NO EXIST\r\n", "GET-Teacher"); + + } + + 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 rbtree_testcase(int connfd) { + + testcase(connfd, "RSET Teacher King", "OK\r\n", "RSET-Teacher"); + testcase(connfd, "RGET Teacher", "King\r\n", "RGET-Teacher"); + testcase(connfd, "RMOD Teacher Darren", "OK\r\n", "RMOD-Teacher"); + testcase(connfd, "RGET Teacher", "Darren\r\n", "RGET-Teacher"); + testcase(connfd, "REXIST Teacher", "EXIST\r\n", "RGET-Teacher"); + testcase(connfd, "RDEL Teacher", "OK\r\n", "RDEL-Teacher"); + testcase(connfd, "RGET Teacher", "NO EXIST\r\n", "RGET-Teacher"); + testcase(connfd, "RMOD Teacher KING", "NO EXIST\r\n", "RMOD-Teacher"); + testcase(connfd, "REXIST Teacher", "NO EXIST\r\n", "RGET-Teacher"); + +} + + + +// testcase 192.168.243.131 2000 +int main(int argc, char *argv[]) { + + if (argc != 3) { + printf("arg error\n"); + return -1; + } + + char *ip = argv[1]; + int port = atoi(argv[2]); + + int connfd = connect_tcpserver(ip, port); + + rbtree_testcase(connfd); + //array_testcase_10w(connfd); + + return 0; + +} + + +