KVStore 多行文章型键值扩展解析:切片存储与客户端多行交互

基于已有的 KV 引擎,本文详细解析文章型键值扩展的完整流程,包括多行正文解析、切片存储机制、增量日志绑定,以及客户端交互反馈示例。

一、文章型键值扩展概览

为了支持 大文本、多行正文 的存储,KVStore 引入了 article.c 扩展模块,提供如下能力:

多行 SET 命令:

SET key <多行正文>

...

END

支持正文超过 CHUNK_SIZE 的自动切片存储

切片存储绑定增量日志,实现持久化

提供 GET、MOD、DEL、EXIST 命令,兼容普通键值与切片键值

核心函数:article_protocol()(协议解析)、article_handler()(网络层接口)

二、切片存储机制(chunked storage)

1. 保存正文

核心函数 save_chunked_value():

cpp 复制代码
static void save_chunked_value(const char *key, const char *value) {
    int len = strlen(value);
    int chunks = (len + CHUNK_SIZE - 1) / CHUNK_SIZE;

    char subkey[512];
    char chunkbuf[CHUNK_SIZE + 1];

    for (int i = 0; i < chunks; i++) {
        snprintf(subkey, sizeof(subkey), "%s#%d", key, i);
        int start = i * CHUNK_SIZE;
        int size = (len - start > CHUNK_SIZE) ? CHUNK_SIZE : (len - start);
        strncpy(chunkbuf, value + start, size);
        chunkbuf[size] = '\0';
        kvs_set(subkey, chunkbuf);
        journal_append("SET", subkey, chunkbuf);
    }

    snprintf(subkey, sizeof(subkey), "%s#meta", key);
    char meta[32];
    sprintf(meta, "%d", chunks);
    kvs_set(subkey, meta);
    journal_append("SET", subkey, meta);
}

将正文拆分为若干片段,每片不超过 4KB

每片单独存储,键名为 key#0, key#1, ...

元信息存储在 key#meta,记录切片数量

每片写入 journal,保证增量持久化

2. 读取正文

核心函数 load_chunked_value():

cpp 复制代码
static char *load_chunked_value(const char *key) {
    char meta_key[512];
    snprintf(meta_key, sizeof(meta_key), "%s#meta", key);
    char *meta_val = kvs_get(meta_key);
    if (!meta_val) return NULL;

    int chunks = atoi(meta_val);
    char *result = malloc(chunks * CHUNK_SIZE + 1);
    result[0] = '\0';

    char subkey[512];
    for (int i = 0; i < chunks; i++) {
        snprintf(subkey, sizeof(subkey), "%s#%d", key, i);
        char *chunk = kvs_get(subkey);
        if (chunk) strcat(result, chunk);
    }
    return result;
}

根据 meta 信息获取切片数量

按序拼接每片正文,恢复完整内容

3. 删除正文

核心函数 delete_chunked_value():

cpp 复制代码
static void delete_chunked_value(const char *key) {
    char meta_key[512];
    snprintf(meta_key, sizeof(meta_key), "%s#meta", key);
    char *meta_val = kvs_get(meta_key);
    if (!meta_val) return;

    int chunks = atoi(meta_val);
    char subkey[512];
    for (int i = 0; i < chunks; i++) {
        snprintf(subkey, sizeof(subkey), "%s#%d", key, i);
        kvs_del(subkey);
        journal_append("DEL", subkey, "");
    }
    kvs_del(meta_key);
    journal_append("DEL", meta_key, "");
}

遍历删除所有切片和 meta

日志记录每条 DEL 操作

三、协议解析与客户端交互

核心函数 article_protocol() 解析客户端命令:

SET:

普通模式:SET key value

正文大于 CHUNK_SIZE 自动切片

写入 journal

多行模式:

SET key

<多行正文>

END

循环读取客户端发送的多行数据

超长正文切片保存

GET:

自动检测切片或普通键值

返回完整内容

MOD:

删除旧切片

保存新内容(切片或普通)

DEL / EXIST:

支持普通键值与切片键值

SAVE / LOAD:

调用 snapshot 持久化接口

SAVE 后清空日志

LOAD 后可回放 journal,保证数据完整性

1. SET 命令示例

客户端发送多行:

SET MESSAGE

The Digital Crossroads: Navigating Human Connection in the Age of Technological Ubiquity

We stand at an unprecedented juncture...

END

服务器处理:

cpp 复制代码
char buf[MAX_BODY_SIZE] = {0};
char line[1024];
while (fgets(line, sizeof(line), fp)) {
    if (strncmp(line, "END", 3) == 0) break;
    strcat(buf, line);
}
if (strlen(buf) > CHUNK_SIZE) save_chunked_value(key, buf);
else { kvs_set(key, buf); journal_append("SET", key, buf); }
sprintf(response, "OK\n");

自动累积多行内容

超长正文切片存储

日志记录每条操作

2. GET 命令示例

cpp 复制代码
char *val = load_chunked_value(key);
if (val) { sprintf(response, "%s\n", val); free(val); }
else { sprintf(response, "(nil)\n"); }

检测是否存在切片

返回完整正文

3. MOD / DEL / EXIST

MOD 自动删除旧片段,保存新内容

DEL 删除所有片段

EXIST 同时检查普通键值与切片键值

四、与持久化机制结合

切片操作 完全兼容 snapshot 和 journal

SAVE/LOAD 调用 snapshot 接口

journal_append 记录每片写入和删除

系统恢复时:

LOAD 恢复全量 snapshot

journal 回放切片 SET/MOD/DEL 操作

保证多行大文本数据完整恢复

五、总结

多行文章型键值扩展:

支持任意长度正文(64KB 上限)

自动切片存储,配合 journal 实现增量持久化

客户端交互:

SET/GET/MOD/DEL/EXIST 命令支持多行正文

超长正文自动切片,透明给客户端

数据恢复:

SAVE/LOAD + journal 回放保证完整性

与普通 KV 引擎兼容

文章型键值扩展,使 KVStore 不仅可以处理简单键值,还能高效存储大文本、多行数据,并确保持久化与恢复完整


根据零声教育教学写作https://github.com/0voice

相关推荐
星释2 小时前
Rust 练习册 :Luhn Trait与Trait实现
网络·算法·rust
爱编程的鱼2 小时前
ESLint 是什么?
开发语言·网络·人工智能·网络协议
njnu@liyong2 小时前
HTTP-大文件传输处理
网络·网络协议·http
qq_334466862 小时前
excel VBA应用
java·服务器·excel
春风霓裳3 小时前
ubuntu磁盘管理、磁盘扩容
linux·运维·ubuntu
广州服务器托管3 小时前
WIN11.26H1.27982.1中简优化版 45进程(2025.11.8)
运维·人工智能·计算机网络·云计算·可信计算技术
Kingsaj3 小时前
uni-app打包app -- 在用户首次启动 App 时,强制弹出一个“用户协议与隐私政策”的确认对话框。
服务器·ubuntu·uni-app
Mr_Xuhhh3 小时前
应用层协议HTTP(1)
网络·网络协议·http
笨鸟笃行3 小时前
英语学习——单词篇(第十七天)
学习