0605: Log + SSTable
这一步加入 SSTable。查询时要合并 MemTable 跟 SSTable。增加 KV.Compact(),用来合并 MemTable(对应 log)和 SSTable,产生新的 SSTable。
type KV struct {
log Log
mem SortedArray
main SortedFile // 增加
}
func (file *SortedFile) Open() error
func (kv *KV) Compact() errorDeleted flag
有2层数据结构,删除的 key 要记录在上层,否则查询时会返回下层的 key。
type SortedArray struct {
keys [][]byte
vals [][]byte
deleted []bool // 增加
}
type SortedArrayIter struct {
keys [][]byte
vals [][]byte
deleted []bool // 增加
pos int
}
func (iter *SortedArrayIter) Deleted() bool { return iter.deleted[iter.pos] }需要修改 SortedArray 里相关的函数,包括 del、set。
func (arr *SortedArray) Clear()
func (arr *SortedArray) Push(key []byte, val []byte, deleted bool)
func (arr *SortedArray) Pop()
func (arr *SortedArray) Del(key []byte) (deleted bool, err error)
func (arr *SortedArray) Set(key []byte, val []byte) (updated bool, err error)合并范围查询
仿照 MergedSortedKV.Scan(),增加 Seek() 函数。也就是用各层的 Seek() 来初始化:
func (m MergedSortedKV) Seek(key []byte) (iter SortedKVIter, err error)合并后的范围查询,要过滤掉删除的 key:
func (kv *KV) Seek(key []byte) (SortedKVIter, error)修改 SSTable 格式
写入 SSTable 时,需要知道有多少 key 才能分配偏移量数组。然而合并 iterator 后,消灭掉了重复的 key,最终的数量小于各层 key 数量之和,同时还要忽略掉删除的 key,所以偏移量数组大小只是一个估计,但只要遍历结束后记录真实 key 数量就没有问题。要稍微修改下 SortedFile.CreateFromSorted()。另外 SortedKV.Size() 换一个函数名。
type SortedKV interface {
EstimatedSize() int // 改名
Iter() (SortedKVIter, error)
Seek(key []byte) (SortedKVIter, error) // 新增
}偏移量数组大小过多分配,造成文件中间有个未利用的空挡。
[ n个key | 偏移量1 | 偏移量2 | ... | 偏移量n | 空挡 | KV1 | KV2 | ... | KVn ]
转移 log 到 SSTable
KV.Compact() 将 MemTable 合并到 SSTable,有3个步骤:
func (kv *KV) Compact() error {
// 1. 合并 MemTable 跟 SSTable,输出到临时文件。
// 2. 替换掉原来的 SSTable(rename 原子操作)。
// 3. 清空 MemTable 和 log。
}您正在阅读免费版教程,从第4章起只有简单的指引,适合爱好挑战和自学的读者。
可以购买有详细指导+背景知识的完整版。