diff --git a/README.md b/README.md index 05ee763..3bc814d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,49 @@ # 实验报告 仓库地址 https://gitea.shuishan.net.cn/10225501448/leveldb_proj2 -新建文件时 cmakelist 120行下面记得加进去 \ No newline at end of file +# 1. 项目概述 +leveldb中的存储原本只支持简单的字节序列,在这个项目中我们对其功能进行拓展,使其可以包含多个字段,并通过这些字段实现类似数据库列查询的功能。但如果仅通过字段查找数据,需要对整个数据库的遍历,不够高效,因此还要新增二级索引,提高对特定字段的查询效率。 + +# 2. 功能实现 +## 2.1 字段 +设计目标:对value存储读取时进行序列化编码,使其支持字段。 + +实现思路:设计之初有考虑增加一些元数据(例如过滤器、字段偏移支持二分)来加速查询。但考虑到在数据库中kv的数量是十分庞大的,新加数据结构会带来巨大的空间开销。因此我们决定在这里牺牲时间换取空间,而将时间的加速放在索引中。 +在这一基础上,我们对序列化进行了简单的优化:将字段名排序后,一一调用leveldb中原本的编码方法`PutLengthPrefixedSlice`存入value。这样不会有额外的空间开销,而好处在于遍历一个value的字段时,如果得到的字段名比目标大,就可以提前结束遍历。 +``` +std::string SerializeValue(const FieldArray& fields){ + std::sort(sortFields.begin(), sortFields.end(), compareByFirst); + for (const Field& pairs : sortFields) { + PutLengthPrefixedSlice(&result, pairs.first); + PutLengthPrefixedSlice(&result, pairs.second); + } + return result; +} +``` +最终db类提供了新接口`putFields`, `getFields`,分别对传入的字段序列化后调用原来的`put`, `get`接口。 +`FindKeysByField`调用`NewIterator`遍历所有数据,field名和值符合则加入返回的key中。 +**这一部分的具体代码在util/serialize_value.cc中** + +## 2.2 二级索引 +设计目标:对某个字段(属性)建立索引,提高对该字段的查询效率。 + +### 2.2.1 总体架构 +fielddb + +### 2.2.2 如何并发创删索引与读写 +request + +### 2.2.3 如何保证两个kv与index的一致性 +metadb + +## 3. 测试 +### 3.1 正确性测试 + +### 3.2 性能测试 +测试、分析、优化 + +## 4. 问题与解决 + +## 5. 潜在优化点 + +## 6. 分工