谭新宇的博客

谭新宇的博客

马上订阅 谭新宇的博客 RSS 更新: https://tanxinyu.work/atom.xml

Talent-Plan:用 Rust 实现简易 KV 引擎

2022年8月28日 22:48

版本

前期准备

Rust 学习

过关过程

Rust Project 1: The Rust toolbox

本 project 过关代码可参考该 commit

主要参照了 README 来完成本 project,具体过程比较 trivial 不再细述。主要工作如下:

  • 搭建项目基本目录结构。
  • 使用 clap 来解析命令行参数,根据官方文档学习 crate 的具体使用方法。
  • 使用 cargo.toml 中的若干参数,包括 dev-dependencies,条件编译等等。
  • 完成基于内存 hashmap 的 KvStore 的增删改查接口。
  • 增加包文档和函数文档并在文档中添加了文档测试
  • 使用 cargo fmt 和 cargo clippy 来提升代码质量

Rust Project 2: Log-structured file I/O

本 project 过关代码可参考该 commit

错误处理

在阅读 failure crate 的 文档 之后,在本 project 中采用了第二种错误处理方式——自定义错误结构。通过定义 KVStoreError 结构体并使用 failure crate 提供的能力,可以很轻易地捕捉不同的错误并列举他们的表示,调用者也可以直接通过模式匹配的方式得到错误类型。

此外,通过为 io:Error 和 serde_json:Error 添加转换到 KVStoreError 的函数,在主逻辑中可以轻松的使用 ? 来向上传递错误,从而避免对 Result 类型的暴力 unwrap。

此外,还定义了 Result 类型别名来统一本项目中所有的 Result 返回类型。

包结构

对于包含一个 lib 包和一个 bin 包的 crate ,在 lib 包中,需要引用所有新增文件的文件名当做其模块名将其引入,此外还需要使用 pub use 语法来将 bin 包会用到的结构公开导出。

在 lib 包的任何文件里,都可以通过 crate:: 的方式来引入本 lib 库被公开导出的结构。

在 bin 包中,需要通过实际 crate 名:: 的方式来引入同名 lib 库被公开导出的结构。

结果捕捉

结果捕捉中的正常/异常处理需要满足以上题意的要求,因而在 main 函数中原样实现了以上需求如下。

结构体

KvStore 结构体中各个变量含义如下:

  • Index :参照 bitcask 的模型,key 为 kv pair 的 key,value 并不存储对应的 value,而是存储该 value 在第 file_number 个文件的 offset 处,长度为 length。
  • current_readers:对于所有已经存在的文件,KvStore 都缓存了一个 BufReader 来便于 seek 到对应的 offset 去 read。实际上也可以没有该结构体每次需要 reader 时新建即可,但复用 reader 可以一定程度上减少资源的损耗。
  • current_writer...

剩余内容已隐藏

查看完整文章以阅读更多