Bläddra i källkod

补充了一些

pull/1/head
augurier 9 månader sedan
förälder
incheckning
de6d67f12b
1 ändrade filer med 5 tillägg och 3 borttagningar
  1. +5
    -3
      设计文档.md

+ 5
- 3
设计文档.md Visa fil

@ -10,7 +10,7 @@ leveldb中的存储原本只支持简单的字节序列,在这个项目中我
实现思路:设计之初有考虑增加一些元数据(例如过滤器、字段偏移支持二分)来加速查询。但考虑到在数据库中kv的数量是十分庞大的,新加数据结构会带来巨大的空间开销。因此我们决定在这里牺牲时间换取空间,而将时间的加速放在索引中。
在这一基础上,我们对序列化进行了简单的优化:将字段名排序后,一一调用leveldb中原本的编码方法`PutLengthPrefixedSlice`存入value。这样不会有额外的空间开销,而好处在于遍历一个value的字段时,如果得到的字段名比目标大,就可以提前结束遍历。
最终db类提供了新接口`putFields`, `getFields`,分别对传入的字段序列化后调用原来的`put`, `get`接口。
**`FindKeysByField`调用`NewIterator`遍历所有数据,field名和值符合则加入返回的key中。这里的问题在于遍历中可能符合条件的key之前已经被删了,所以还要维护一个被删的key数组?总感觉这个玩意性能有点太差了**
`FindKeysByField`调用`NewIterator`遍历所有数据,field名和值符合则加入返回的key中。
## 2.2 二级索引
设计目标:对某个字段或属性建立索引,提高对该字段的查询效率。需考虑索引的创建、删除、维护。
@ -32,15 +32,17 @@ class FieldDb {
//原db所有对外接口,下面没提就调用kvDb相应函数
}
```
4. 一个创建/删除索引任务开始时,先修改`nowTask`,再对`kvDb`调用`FindKvsByField`(类似lab1的`FindKeysByField`但也要返回field对应的值),对返回的数组(合并上5中提到的tmpAddKvs、tmpDeleteKvs)中每个元素一一与字段名编码成新key,调用`indexDb`中的put或delete。
4. 一个创建/删除索引任务开始时,先修改`nowTask`,再对`kvDb`调用`FindKvsByField`(类似lab1的`FindKeysByField`但也要返回field对应的值),对返回的数组(合并上5中提到的tmpAddKvs、tmpDeleteKvs)中每个元素一一与字段名编码成新key,调用`indexDb`中的put或delete。当`indexdb`把所有操作执行完后,`FieldDb`把一个` class="p"><indexStatus, fieldName>`写入一个文件`IndexLog`,并在`fieldWithIndex`中添加/删除这个`fieldName`。**这样分离了两个数据库的写,只有indexDb全写完才能读这个索引,在这之前崩溃了就回滚不要了。在数据库恢复时,先用kvdb的日志把kvdb恢复了,再根据IndexLog的内容重新创建索引,indexdb里的恢复就不需要了。另外这个地方的测试感觉也不好做**
5. fieldDb也提供了`put`, `get`,`getFields`, `putFields`,`delete`接口。对前三者,简单调用`kvDb`中的对应接口(不涉及索引)。对`putFields`,先调用`kvDb`中的`putFields`,写完后如果写入的字段名中:
有`nowTask.fieldName`,则加入`tmpAddkvs`,保证创建删除索引时,新来的数据也被记录。
有`fieldWithIndex`中有的字段,则直接对`kvDb`调用一个(多个)`put`。
`delete`也是如此,创建删除索引时新来的要delete的数据由`tmpDeletekvs`维护。
**只考虑到这,理论上每个数据库内部的日志、快照、合并等模块不会互相影响(创建的那些current、manifest文件名好像会冲突)**
6. 对两个数据库的其他部分,理论上每个数据库内部的其他模块不会互相影响(注意创建的那些current、manifest文件名会冲突)
# 3. 数据结构设计
`indexDb`的kv编码:**暂时考虑助教文档那种**
`IndexLog`的编码:字段名 加 类型(创/删)
# 4. 接口/函数设计
# 5. 功能测试

Laddar…
Avbryt
Spara