OSTEP Projects:KV

2024-05-11 06:04
文章标签 projects kv ostep

本文主要是介绍OSTEP Projects:KV,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文将介绍操作系统导论(Operating Systems: Three Easy Pieces)作者所开源的操作系统相关课程项目 的 KV 部分,包含个人的代码实现和设计思路。

思路

题目要求实现一个最简单的数据库,以支持数据的持久化。

每个操作由格式为 op,[arg1],[arg2] 的命令给出,那么首先要解决的问题就是参数的分离,再根据操作符 op 来对不同的操作进行特殊处理。字符串划分这里采用的是 strsep() 函数:该函数接收两个参数 char** stringpconst char* delimstringp 是指向待分割字符串 string 的指针,delim 则是指定的分隔符,该函数的操作是查找 string 中第一个 delim 的位置 it,并将 stringp 指向 stringit + 1 的位置,同时返回string 开头到 it 所有字符所构成的子串(加上 '\0' 终结符)。

插入操作没什么好说的,直接使用 fprintf() 写入文件即可。对于查找和删除,则需要将数据从文件(数据库)中读取到内存,存储在特定的数据结构中,例如哈希表、红黑树等,但为了代码实现的简单,我使用的是最简单的链表。对于查找,先将所有数据读取到一个链表中,然后按顺序逐个进行查找;对于删除,将所有数据读取到一个链表中,然后逐个遍历链表,如果当前结点的键(key)与参数不同,则写入文件中,否则,不写入(相当于删除)。最后,为了防止内存的泄露,需要在每次结束查找和删除操作之后,将存储数据内容的链表结点的内存空间释放。

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define DATA_BASE "./database.txt"typedef struct LineNode {char* line_buf;struct LineNode* next;
} line_node;// 从文件fp中读取数据
line_node* read_from_file(FILE* fp) {line_node* dummy = (line_node*)malloc(sizeof(line_node)); // 哨兵结点line_node* p = dummy;size_t sz = 0;while (1) {p->next = (line_node*)malloc(sizeof(line_node));p = p->next;if (getline(&(p->line_buf), &sz, fp) == -1) {p->next = NULL;break;}}return dummy->next;
}// 释放链表内存空间
void free_list_mem(line_node* data) {while (data != NULL) {line_node* temp = data;data = data->next;free(temp);}
}int main(int argc, char* argv[]) {for (int i = 1; i < argc; ++i) {char* op = strsep(&argv[i], ","); // 操作符if (!strcmp(op, "p")) {char* key = strsep(&argv[i], ",");char* value = strsep(&argv[i], ",");if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "a");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}fprintf(fp, "%s,%s\n", key, value);fclose(fp);}else if (!strcmp(op, "g")) {char* key = strsep(&argv[i], ",");if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "r");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}line_node* data = read_from_file(fp);line_node* p = data;int flag = 0;while (p != NULL) {char* entry = strdup(p->line_buf); // 条目备份(line_buf会被strsep()修改)char* token = strsep(&(p->line_buf), ",");if (!strcmp(token, key)) { // 找到keyflag = 1;printf("%s", entry);break;}p = p->next;}if (!flag) {printf("%s not found\n", key);}free_list_mem(data);fclose(fp);}else if (!strcmp(op, "d")) {char* key = strsep(&argv[i], ",");if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "r");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}line_node* data = read_from_file(fp);fclose(fp);// 清空文件fp = fopen(DATA_BASE, "w");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}fclose(fp);fp = fopen(DATA_BASE, "a");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}line_node* p = data;while (p != NULL) {char* entry = strdup(p->line_buf); // 条目备份char* token = strsep(&(p->line_buf), ",");if (strcmp(token, key)) { // 当前条目键值为key,不写入(相当于删除)fprintf(fp, "%s", entry);}p = p->next;}free_list_mem(data);fclose(fp);}else if (!strcmp(op, "c")) {if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "w");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}fclose(fp);}else if (!strcmp(op, "a")) {if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "r");line_node* data = read_from_file(fp);line_node* p = data;while (p != NULL) {printf("%s", p->line_buf);p = p->next;}free_list_mem(data);fclose(fp);}else {printf("bad command\n");continue;}}return 0;
}

这篇关于OSTEP Projects:KV的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/978706

相关文章

C++笔记17•数据结构:二叉搜索树(K模型/KV模型实现)•

二叉搜索树 1.二叉搜索树 1. 二叉搜索树的查找 a 、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。 b 、最多查找高度次,走到到空,还没找到,这个值不存在。2. 二叉搜索树的插入 插入的具体过程如下: a. 树为空,则直接新增节点,赋值给 root 指针 b. 树不空,按二叉搜索树性质查找插入位置,插入新节点3.二叉搜索树的删除 首先查找元素是否在二叉搜索树中,如果不

【二叉搜索树】K型与KV型二叉搜索树简单实现

关于我: 睡觉待开机:个人主页 个人专栏: 《优选算法》《C语言》《CPP》 生活的理想,就是为了理想的生活! 作者留言 PDF版免费提供:倘若有需要,想拿我写的博客进行学习和交流,可以私信我将免费提供PDF版。 留下你的建议:倘若你发现本文中的内容和配图有任何错误或改进建议,请直接评论或者私信。 倡导提问与交流:关于本文任何不明之处,请及时评论和私信,看到即回

Eclipse导入项目报错:No projects are found to import

项目文件夹内需要有两个文件:   .classpath <?xml version="1.0" encoding="UTF-8"?><classpath><classpathentry kind="src" path="src"/><classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.e

书生大模型实战营闯关记录----第十一关:LMDeploy 量化部署进阶实践 KV cache量化部署,W4A16 模型量化和部署

文章目录 1 配置LMDeploy环境1.1 环境搭建1.2 InternStudio环境获取模型1.3 LMDeploy验证启动模型文件 2 LMDeploy与InternLM2.5 2.1 LMDeploy API部署InternLM2.52.1.1 启动API服务器 2.1.2 以命令行形式连接API服务器 2.1.3 以Gradio**网页形式连接API服务器** 2.2 LMDe

LLM - GPT(Decoder Only) 类模型的 KV Cache 公式与原理 教程

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/141605718 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 在 GPT 类模型中,KV Cache (键值缓存) 是用于优化推理效率的重要技术,基本思想是通过缓存先

LMDeploy的KV Cache管理器可以通过设置--cache-max-entry-count参数 TurboMind理解

参考https://blog.csdn.net/m0_65719612/article/details/138634868 模型在运行时,占用的显存可大致分为三部分:模型参数本身占用的显存、KV Cache占用的显存,以及中间运算结果占用的显存。LMDeploy的KV Cache管理器可以通过设置–cache-max-entry-count参数,控制KV缓存占用剩余显存的最大比例。默认的比例为0

Kivy tutorial 008: More kv language

Kivy tutorial 008: More kv language – Kivy Blog Central themes: Event binding and canvas instructions in kv language 中心主题: 事件绑定 和 kv语言里的画布结构 This tutorial directly follows on from the previous, so s

移植案例与原理 - utils子系统之KV存储部件 (2)

3、KV存储部件对外接口 在文件utils\native\lite\include\kv_store.h中定义了KV存储部件对外接口,如下,支持从键值对缓存里读取键值,设置键值,删除键值,清除缓存等等。 int UtilsGetValue(const char* key, char* value, unsigned int len);int UtilsSetValue(const char*

大模型KV Cache节省神器MLA学习笔记(包含推理时的矩阵吸收分析)

首先,本文回顾了MHA的计算方式以及KV Cache的原理,然后深入到了DeepSeek V2的MLA的原理介绍,同时对MLA节省的KV Cache比例做了详细的计算解读。接着,带着对原理的理解理清了HuggingFace MLA的全部实现,每行代码都去对应了完整公式中的具体行并且对每个操作前后的Tensor Shape变化也进行了解析。我们可以看到目前的官方实现在存储KV Cache的时候并不

Protected and unprotected Meilisearch projects(/health)

Elasticsearch 做为老牌搜索引擎,功能基本满足,但复杂,重量级,适合大数据量。 MeiliSearch 设计目标针对数据在 500GB 左右的搜索需求,极快,单文件,超轻量。 所以,对于中小型项目来说,我们可以考虑另一种搜索引擎:MeiliSearch。 调用 /health 接口,检查健康状况。可以配置成定时任务,作为健康检查,配置一个策略(比如5分钟内有3次