add kvs_array.c
This commit is contained in:
177
kvs_array.c
Normal file
177
kvs_array.c
Normal 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
165
kvstore.c
@@ -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,16 +144,36 @@
|
|||||||
* @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[]) {
|
||||||
|
|
||||||
@@ -31,6 +181,9 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
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); //
|
||||||
#elif (NETWORK_SELECT == NETWORK_PROACTOR)
|
#elif (NETWORK_SELECT == NETWORK_PROACTOR)
|
||||||
|
|||||||
3380
kvstore.excalidraw
Executable file
3380
kvstore.excalidraw
Executable file
File diff suppressed because one or more lines are too long
51
kvstore.h
51
kvstore.h
@@ -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);
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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, ¤t, sizeof(struct timeval));
|
memcpy(&begin, ¤t, 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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user