kvstore项目

news/2025/2/25 0:14:50/文章来源:https://www.cnblogs.com/nakjima/p/18735243

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;  // 程序结束
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/889268.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软工作业1

作业相关信息这个作业属于哪个课程 软件工程 这个作业要求在哪里 自我介绍+软工5问 这个作业的目标 自我介绍,了解软件工程基本概念个人介绍 Im YiLaiL YiLaiL/YiLaiL is a ✨ special ✨ repository because its README.md (this file) appears on your GitHub profile.🔭 …

EmEdit设置缓存目录临时文件夹

前言全局说明一、说明 1.1 环境: Windows 11 家庭版 23H2 22631.3737 EmEditor Professional (64-bit) Version 17.2.4二、打开大文本控制器三、点击右边大文本控制器上 自定义四、选择比较大的磁盘空间作为缓存空间免责声明:本号所涉及内容仅供安全研究与教学使用,如出现其他…

谈谈 ES 6.8 到 7.10 的功能变迁(3)- 查询方法篇

上一篇咱们了解了 ES 7.10 相较于 ES 6.8 新增的字段类型,这一篇我们继续了解新增的查询方法。 Interval 间隔查询: 功能介绍 Interval 查询,词项间距查询,可以根据匹配词项的顺序、间距和接近度对文档进行排名。主要解决的查询场景“创建一个多搜索词匹配的查询,同时保留…

【蓝牙小程序】在微信小程序中使用 ECharts

echarts-for-weixin 项目提供了一个小程序组件,用这种方式可以方便地使用 ECharts。 使用方式下载该项目 如有必要,将 ec-canvas 目录下的 echarts.js 替换为最新版的 ECharts。如果希望减小包体积大小,可以使用自定义构建生成并替换 echarts.js pages 目录下是使用的示例文…

Virtual Box设置双网卡

一、硬件 1.为虚拟机添加网卡2.配置网卡二、软件 3.获取mac地址 命令:ip link [root@vbox network-scripts]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd…

简单逆向Java程序

前置 来源 这个程序是我同学编写的一个学生分数管理系统,我将对这个已经编译的程序进行测试、逆向,找出其中的问题,并进行改进。 运行环境macOS 15.4 IntelliJ IDEA 2024.2.3 OpenJDK 23.0.2 TomCat 11.0.4 Safari 15.4运行结果主要问题 在使用了这个程序之后,我发现了以下…

信息论概述

1 信息与消息 1.1 信息 1.1.1 信息的定义 信息是信息论中最基本、最重要的概念 香农信息的定义:信息是事物运动状态或存在方式的不确定描述 1.1.2 (香农)信息的度量样本空间:对于我们需要描述的事物中,事物可能存在不同的状态,即事物展现出来的多种状态。那么为了便于形容事…

JUC并发—12.ThreadLocal源码分析

大纲 1.ThreadLocal的特点介绍 2.ThreadLocal的使用案例 3.ThreadLocal的内部结构 4.ThreadLocal的核心方法源码 5.ThreadLocalMap的核心方法源码 6.ThreadLocalMap的原理总结1.ThreadLocal的特点介绍 (1)ThreadLocal的注释说明 (2)ThreadLocal的常用方法 (3)ThreadLocal的使用…

前端Vue创建

一、创建Vue项目二、导入idea 复制景区 三、设置main.js点击查看代码 import Vue from vue import App from ./App.vue import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import ./assets/golbal.css; import axios from axios; // 正确的模块…

朋友说喊搞个简单的微信对接的封装搞外包,不要那么多的方法拿来就用的的那种,来看看Simple.Wechat吧

朋友说喊搞个简单的微信对接的封装搞外包,不要那么多的方法拿来就用的的那种,来看看Simple.Wechat吧😂不知道大家有没有和我朋友一样,很多时候做外包总免不了去对接微信,最简单的微信用户信息获取、微信支付、微信模板消息发送,要是不熟悉总是要去找这个那个的包,但是人…