kvstore项目

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_ARRAY
	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\r\n");  // 键存在
		} else {
			length = sprintf(response, "NO EXIST\r\n");  // 键不存在
		}
		break;
#endif

#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

#if ENABLE_HASH
	case 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;
#endif

	default: 
		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_ARRAY
	memset(&global_array, 0, sizeof(kvs_array_t));  // 初始化数组存储
	kvs_array_create(&global_array);  // 创建数组存储
#endif

#if ENABLE_RBTREE
	memset(&global_rbtree, 0, sizeof(kvs_rbtree_t));  // 初始化红黑树存储
	kvs_rbtree_create(&global_rbtree);  // 创建红黑树存储
#endif

#if ENABLE_HASH
	memset(&global_hash, 0, sizeof(kvs_hash_t));  // 初始化哈希表存储
	kvs_hash_create(&global_hash);  // 创建哈希表存储
#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
#if ENABLE_HASH
	kvs_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 模型启动
#endif

	dest_kvengine();  // 销毁键值存储引擎

	return 0;  // 程序结束
}
posted @ 2025-02-25 00:12  nakejimamiyuki  阅读(50)  评论(0)    收藏  举报