内存设计
根据之前论文之中所写,我们在内存中需要存储一份key所对应value的映射位置便于以后读出,在内存中存储的数据结构有许多,例如hash、跳表和b tree等。 在教程中我们使用的是b tree便于以后很方便的遍历key。
数据结构的话直接拿现成的包直接用就行了
btree库: https://github.com/google/btree
首先定义一个数据结构用于表示key存储在文件的位置信息
// LogRecordPos 数据内存索引信息 主要是根据key找到指定文件的指定位置读取指定数据
type LogRecordPos struct {
FileId uint32 // 文件id
Pos int64 // 数据偏移
}
然后根据面向对象的思想定义一个接口,该接口用于操作内存索引,如果之后需要实现其他数据结构,直接实现该接口就行了。
type Indexer interface {
Put(key []byte, pos *data.LogRecordPos) bool // 设置值
Get(key []byte) *data.LogRecordPos // 获取数据的位置信息
Delete(key []byte) bool // 删除kv数据
}
// Item 表示 btree中的数据结构,需要实现了该type才能在Btree中添加数据
type Item struct {
key []byte
pos *data.LogRecordPos
}
func (item *Item) Less(than btree.Item) bool {
// (*Item).key表示断言 如果than实现了btree.Item那么就转换成Item
return bytes.Compare(item.key, than.(*Item).key) == -1
}
采用Btree数据结构实现了Indexer接口
type Btree struct {
tree *btree.BTree
lock *sync.RWMutex
}
func NewBtree() *Btree {
return &Btree{
tree: btree.New(64),
lock: new(sync.RWMutex),
}
}
func (btree *Btree) Put(key []byte, pos *data.LogRecordPos) bool {
btree.lock.Lock()
item := &Item{
key: key,
pos: pos,
}
btree.tree.ReplaceOrInsert(item)
btree.lock.Unlock()
return true
}
func (btree *Btree) Get(key []byte) *data.LogRecordPos {
item := &Item{key: key}
getItem := btree.tree.Get(item)
if getItem == nil {
return nil
}
return getItem.(*Item).pos
}
func (btree *Btree) Delete(key []byte) bool {
btree.lock.Lock()
item := &Item{
key: key,
}
btree.tree.Delete(item)
btree.lock.Unlock()
return true
}
磁盘
磁盘一样使用一个抽象的接口,如果以后需要实现自己的文件引擎直接实现该接口就行。
type IOManagement interface {
// Read 文件读取 读取的内容会存储到buffer中并返回读取字节数
Read(offset int64, buffer []byte) (int, error)
// Write 写数据到文件中 buffer表示写入内容 返回写入字节数
Write(buffer []byte) (int, error)
// Sync 将缓存区内容同步到文件中
Sync() error
// Close 关闭文件
Close() error
}
使用最简单的go的库文件即可。
type FileIO struct {
file *os.File
}
func CreateFileIo(filePath string) (*FileIO, error) {
file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
return nil, err
}
return &FileIO{
file: file,
}, nil
}
func (fileIo *FileIO) Read(offset int64, buffer []byte) (int, error) {
_, err := fileIo.file.Seek(offset, 0)
if err != nil {
return 0, err
}
return fileIo.file.Read(buffer)
}
func (fileIo *FileIO) Write(buffer []byte) (int, error) {
return fileIo.file.Write(buffer)
}
func (fileIo *FileIO) Sync() error {
return fileIo.file.Sync()
}
func (fileIo *FileIO) Close() error {
return fileIo.file.Close()
}
标签:return,func,Item,内存,key,设计,磁盘,byte,btree
From: https://www.cnblogs.com/lyraHeartstrings/p/18239632