kvstore.c
#include "kvstore.h" // 包含键值存储相关的头文件,可能定义了数据结构和接口// 根据编译选项启用不同的数据结构
#if ENABLE_ARRAY
extern kvs_array_t global_array; // 声明全局数组类型的键值存储
#endif#if ENABLE_RBTREE
extern kvs_rbtree_t global_rbtree; // 声明全局红黑树类型的键值存储
#endif#if ENABLE_HASH
extern kvs_hash_t global_hash; // 声明全局哈希表类型的键值存储
#endif// 自定义内存分配和释放函数,方便后续扩展
void *kvs_malloc(size_t size) {return malloc(size); // 使用标准库的 malloc 进行内存分配
}void kvs_free(void *ptr) {return free(ptr); // 使用标准库的 free 释放内存
}// 定义支持的命令字符串数组
const char *command[] = {"SET", "GET", "DEL", "MOD", "EXIST", // 数组相关的命令"RSET", "RGET", "RDEL", "RMOD", "REXIST", // 红黑树相关的命令"HSET", "HGET", "HDEL", "HMOD", "HEXIST" // 哈希表相关的命令
};// 定义命令的枚举值,用于快速匹配和处理
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_RSET,KVS_CMD_RGET,KVS_CMD_RDEL,KVS_CMD_RMOD,KVS_CMD_REXIST,// 哈希表相关的命令KVS_CMD_HSET,KVS_CMD_HGET,KVS_CMD_HDEL,KVS_CMD_HMOD,KVS_CMD_HEXIST,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, " "); // 使用 strtok 分割字符串while (token != NULL) {tokens[idx++] = token; // 保存分割后的令牌token = strtok(NULL, " "); // 继续分割}return idx; // 返回令牌数量
}// 根据协议解析命令并执行相应的操作
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) {
#if ENABLE_ARRAYcase 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\r\n"); // 键存在} else {length = sprintf(response, "NO EXIST\r\n"); // 键不存在}break;
#endif#if ENABLE_RBTREEcase 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#if ENABLE_HASHcase KVS_CMD_HSET: // 哈希表:设置键值对ret = kvs_hash_set(&global_hash, 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_HGET: // 哈希表:获取键对应的值{char *result = kvs_hash_get(&global_hash, key);if (result == NULL) {length = sprintf(response, "NO EXIST\r\n");} else {length = sprintf(response, "%s\r\n", result);}break;}case KVS_CMD_HDEL: // 哈希表:删除键ret = kvs_hash_del(&global_hash, 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_HMOD: // 哈希表:修改键对应的值ret = kvs_hash_mod(&global_hash, 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_HEXIST: // 哈希表:检查键是否存在ret = kvs_hash_exist(&global_hash, key);if (ret == 0) {length = sprintf(response, "EXIST\r\n");} else {length = sprintf(response, "NO EXIST\r\n");}break;
#endifdefault: assert(0); // 未知命令,断言失败}return length; // 返回响应字符串的长度
}// 处理客户端请求的协议
int kvs_protocol(char *msg, int length, char *response) {if (msg == NULL || length <= 0 || response == NULL) return -1; // 输入无效时返回错误char *tokens[KVS_MAX_TOKENS] = {0}; // 定义令牌数组int count = kvs_split_token(msg, tokens); // 分割请求消息为令牌if (count == -1) return -1; // 分割失败时返回错误return kvs_filter_protocol(tokens, count, response); // 解析并处理命令
}// 初始化键值存储引擎
int init_kvengine(void) {
#if ENABLE_ARRAYmemset(&global_array, 0, sizeof(kvs_array_t)); // 初始化数组存储kvs_array_create(&global_array); // 创建数组存储
#endif#if ENABLE_RBTREEmemset(&global_rbtree, 0, sizeof(kvs_rbtree_t)); // 初始化红黑树存储kvs_rbtree_create(&global_rbtree); // 创建红黑树存储
#endif#if ENABLE_HASHmemset(&global_hash, 0, sizeof(kvs_hash_t)); // 初始化哈希表存储kvs_hash_create(&global_hash); // 创建哈希表存储
#endifreturn 0; // 初始化成功
}// 销毁键值存储引擎
void dest_kvengine(void) {
#if ENABLE_ARRAYkvs_array_destory(&global_array); // 销毁数组存储
#endif
#if ENABLE_RBTREEkvs_rbtree_destory(&global_rbtree); // 销毁红黑树存储
#endif
#if ENABLE_HASHkvs_hash_destory(&global_hash); // 销毁哈希表存储
#endif
}// 主函数:启动键值存储服务器
int main(int argc, char *argv[]) {if (argc != 2) return -1; // 参数数量错误int port = atoi(argv[1]); // 获取端口号init_kvengine(); // 初始化键值存储引擎// 根据编译选项选择网络模型
#if (NETWORK_SELECT == NETWORK_REACTOR)reactor_start(port, kvs_protocol); // 使用 Reactor 模型启动
#elif (NETWORK_SELECT == NETWORK_PROACTOR)ntyco_start(port, kvs_protocol); // 使用 Proactor 模型启动
#elif (NETWORK_SELECT == NETWORK_NTYCO)proactor_start(port, kvs_protocol); // 使用另一种 Proactor 模型启动
#endifdest_kvengine(); // 销毁键值存储引擎return 0; // 程序结束
}