add kvs_array.c

This commit is contained in:
King
2024-05-21 14:16:44 +00:00
parent 5a7fa95d2c
commit 1b865836df
5 changed files with 3763 additions and 18 deletions

177
kvs_array.c Normal file
View File

@@ -0,0 +1,177 @@
#include "kvstore.h"
// singleton
kvs_array_t global_array = {0};
int kvs_array_create(kvs_array_t *inst) {
if (!inst) return -1;
if (inst->table) {
printf("table has alloc\n");
return -1;
}
inst->table = kvs_malloc(KVS_ARRAY_SIZE * sizeof(kvs_array_item_t));
if (!inst->table) {
return -1;
}
inst->total = 0;
return 0;
}
void kvs_array_destory(kvs_array_t *inst) {
if (!inst) return ;
if (inst->table) {
kvs_free(inst->table);
}
}
/*
* @return: <0, error; =0, success; >0, exist
*/
int kvs_array_set(kvs_array_t *inst, char *key, char *value) {
if (inst == NULL || key == NULL || value == NULL) return -1;
if (inst->total == KVS_ARRAY_SIZE) return -1;
char *str = kvs_array_get(inst, key);
if (str) {
return 1; //
}
char *kcopy = kvs_malloc(strlen(key) + 1);
if (kcopy == NULL) return -2;
memset(kcopy, 0, strlen(key) + 1);
strncpy(kcopy, key, strlen(key));
char *kvalue = kvs_malloc(strlen(value) + 1);
if (kvalue == NULL) return -2;
memset(kvalue, 0, strlen(value) + 1);
strncpy(kvalue, value, strlen(value));
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (inst->table[i].key == NULL) {
inst->table[i].key = kcopy;
inst->table[i].value = kvalue;
inst->total ++;
return 0;
}
}
if (i == inst->total && i < KVS_ARRAY_SIZE) {
inst->table[i].key = kcopy;
inst->table[i].value = kvalue;
inst->total ++;
}
return 0;
}
char* kvs_array_get(kvs_array_t *inst, char *key) {
if (inst == NULL || key == NULL) return NULL;
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (inst->table[i].key == NULL) {
continue;
}
if (strcmp(inst->table[i].key, key) == 0) {
return inst->table[i].value;
}
}
return NULL;
}
/*
* @return < 0, error; =0, success; >0, no exist
*/
int kvs_array_del(kvs_array_t *inst, char *key) {
if (inst == NULL || key == NULL) return -1;
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (strcmp(inst->table[i].key, key) == 0) {
kvs_free(inst->table[i].key);
inst->table[i].key = NULL;
kvs_free(inst->table[i].value);
inst->table[i].value = NULL;
return 0;
}
}
return i;
}
/*
* @return : < 0, error; =0, success; >0, no exist
*/
int kvs_array_mod(kvs_array_t *inst, char *key, char *value) {
if (inst == NULL || key == NULL || value == NULL) return -1;
int i = 0;
for (i = 0;i < inst->total;i ++) {
if (inst->table[i].key == NULL) {
continue;
}
if (strcmp(inst->table[i].key, key) == 0) {
kvs_free(inst->table[i].value);
char *kvalue = kvs_malloc(strlen(value) + 1);
if (kvalue == NULL) return -2;
memset(kvalue, 0, strlen(value) + 1);
strncpy(kvalue, value, strlen(value));
inst->table[i].value = kvalue;
return 0;
}
}
return i;
}
/*
* @return 0: exist, 1: no exist
*/
int kvs_array_exist(kvs_array_t *inst, char *key) {
char *str = kvs_array_get(inst, key);
if (!str) {
return 1; //
}
return 0;
}

165
kvstore.c
View File

@@ -1,12 +1,142 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "kvstore.h" #include "kvstore.h"
#if ENABLE_ARRAY
extern kvs_array_t global_array;
#endif
void *kvs_malloc(size_t size) {
return malloc(size);
}
void kvs_free(void *ptr) {
return free(ptr);
}
const char *command[] = {
"SET", "GET", "DEL", "MOD", "EXIST"
};
enum {
KVS_CMD_START = 0,
KVS_CMD_SET = KVS_CMD_START,
KVS_CMD_GET,
KVS_CMD_DEL,
KVS_CMD_MOD,
KVS_CMD_EXIST,
KVS_CMD_COUNT,
};
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, " ");
while (token != NULL) {
printf("idx: %d, %s\n", idx, token);
tokens[idx ++] = token;
token = strtok(NULL, " ");
}
return idx;
}
// SET Key Value
// tokens[0] : SET
// tokens[1] : Key
// tokens[2] : Value
int kvs_filter_protocol(char **tokens, int count, char *response) {
if (tokens[0] == NULL || count == 0 || response == NULL) return -1;
int cmd = KVS_CMD_START;
for (cmd = KVS_CMD_START;cmd < KVS_CMD_COUNT;cmd ++) {
if (strcmp(tokens[0], command[cmd]) == 0) {
break;
}
}
int length = 0;
int ret = 0;
char *key = tokens[1];
char *value = tokens[2];
switch(cmd) {
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;
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;
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;
case KVS_CMD_EXIST:
ret = kvs_array_exist(&global_array ,key);
if (ret == 0) {
length = sprintf(response, "EXIST\n");
} else {
length = sprintf(response, "NO EXIST\r\n");
}
break;
}
return length;
}
/* /*
* msg: request message * msg: request message
* length: length of request message * length: length of request message
@@ -14,22 +144,45 @@
* @return : length of response * @return : length of response
*/ */
int kvs_protocol(char *msg, int length, char *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); printf("recv %d : %s\n", length, msg);
memcpy(response, msg, length); char *tokens[KVS_MAX_TOKENS] = {0};
return strlen(response); int count = kvs_split_token(msg, tokens);
if (count == -1) return -1;
//memcpy(response, msg, length);
return kvs_filter_protocol(tokens, count, response);
} }
int init_kvengine(void) {
#if ENABLE_ARRAY
memset(&global_array, 0, sizeof(kvs_array_t));
kvs_array_create(&global_array);
#endif
return 0;
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc != 2) return -1; if (argc != 2) return -1;
int port = atoi(argv[1]); int port = atoi(argv[1]);
init_kvengine();
#if (NETWORK_SELECT == NETWORK_REACTOR) #if (NETWORK_SELECT == NETWORK_REACTOR)
reactor_start(port, kvs_protocol); // reactor_start(port, kvs_protocol); //

3380
kvstore.excalidraw Executable file

File diff suppressed because one or more lines are too long

View File

@@ -5,11 +5,26 @@
#define __KV_STORE_H__ #define __KV_STORE_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#define NETWORK_REACTOR 0 #define NETWORK_REACTOR 0
#define NETWORK_PROACTOR 1 #define NETWORK_PROACTOR 1
#define NETWORK_NTYCO 2 #define NETWORK_NTYCO 2
#define NETWORK_SELECT NETWORK_REACTOR #define NETWORK_SELECT NETWORK_PROACTOR
#define KVS_MAX_TOKENS 128
#define ENABLE_ARRAY 1
typedef int (*msg_handler)(char *msg, int length, char *response); typedef int (*msg_handler)(char *msg, int length, char *response);
@@ -21,13 +36,37 @@ extern int ntyco_start(unsigned short port, msg_handler handler);
const char *command[] = { #if ENABLE_ARRAY
"SET", "GET", "DEL", "MOD", "EXIST"
};
const char *response[] = { typedef struct kvs_array_item_s {
char *key;
char *value;
} kvs_array_item_t;
#define KVS_ARRAY_SIZE 1024
typedef struct kvs_array_s {
kvs_array_item_t *table;
int idx;
int total;
} kvs_array_t;
int kvs_array_create(kvs_array_t *inst);
void kvs_array_destory(kvs_array_t *inst);
int kvs_array_set(kvs_array_t *inst, char *key, char *value);
char* kvs_array_get(kvs_array_t *inst, char *key);
int kvs_array_del(kvs_array_t *inst, char *key);
int kvs_array_mod(kvs_array_t *inst, char *key, char *value);
int kvs_array_exist(kvs_array_t *inst, char *key);
#endif
void *kvs_malloc(size_t size);
void kvs_free(void *ptr);
};

View File

@@ -33,8 +33,6 @@ static msg_handler kvs_handler;
int kvs_request(struct conn *c) { int kvs_request(struct conn *c) {
printf("recv %d : %s\n", c->rlength, c->rbuffer);
c->wlength = kvs_handler(c->rbuffer, c->rlength, c->wbuffer); c->wlength = kvs_handler(c->rbuffer, c->rlength, c->wbuffer);
} }
@@ -112,7 +110,6 @@ int accept_cb(int fd) {
socklen_t len = sizeof(clientaddr); socklen_t len = sizeof(clientaddr);
int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len); int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len);
printf("accept finshed: %d, fd: %d\n", clientfd, fd);
if (clientfd < 0) { if (clientfd < 0) {
printf("accept errno: %d --> %s\n", errno, strerror(errno)); printf("accept errno: %d --> %s\n", errno, strerror(errno));
return -1; return -1;
@@ -129,7 +126,7 @@ int accept_cb(int fd) {
memcpy(&begin, &current, sizeof(struct timeval)); memcpy(&begin, &current, sizeof(struct timeval));
printf("accept finshed: %d, time_used: %d\n", clientfd, time_used); //printf("accept finshed: %d, time_used: %d\n", clientfd, time_used);
} }
@@ -142,7 +139,7 @@ int recv_cb(int fd) {
memset(conn_list[fd].rbuffer, 0, BUFFER_LENGTH ); memset(conn_list[fd].rbuffer, 0, BUFFER_LENGTH );
int count = recv(fd, conn_list[fd].rbuffer, BUFFER_LENGTH, 0); int count = recv(fd, conn_list[fd].rbuffer, BUFFER_LENGTH, 0);
if (count == 0) { // disconnect if (count == 0) { // disconnect
printf("client disconnect: %d\n", fd); //printf("client disconnect: %d\n", fd);
close(fd); close(fd);
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); // unfinished epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); // unfinished
@@ -262,7 +259,6 @@ int reactor_start(unsigned short port, msg_handler handler) {
//unsigned short port = 2000; //unsigned short port = 2000;
kvs_handler = handler; kvs_handler = handler;
printf("reactor_entry: %d\n", port);
epfd = epoll_create(1); epfd = epoll_create(1);