Overview
project1主要是对单机接口storage的实现(封装了kv存储,Badger 采用的也是 LSM-tree 结构,但是它参考了 WiscKey 的设计,可以参考我的blogwiscKey论文--------对LSM-tree的优化_boring_111的博客-CSDN博客)
和server的rawPut, rawGet, rawDelete, rawScan的实现。
storage部分
实际上就是根据配置文件的路径起一个wisckey优化的lsm-tree的kv存储。
type StandAloneStorage struct {
// Your Data Here (1).
db *badger.DB
dbpath string
}
func NewStandAloneStorage(conf *config.Config) *StandAloneStorage {
// Your Code Here (1).
return &StandAloneStorage{dbpath: conf.DBPath}
}
对于cf(colum family) 就是做一个拼接,比如我们要的是姓名为boring的密码,key :name_boring
value : xxxxxxxx。
reader部分
一种是单点get,一个用于scan。
func (reader *AloneReader) GetCF(cf string, key []byte) ([]byte, error) {
val, err := engine_util.GetCFFromTxn(reader.txn, cf, key)
if err != nil {
return nil, nil
}
return val, err
}
func (reader *AloneReader) IterCF(cf string) engine_util.DBIterator {
return engine_util.NewCFIterator(cf, reader.txn)
}
write部分
分为put和delete,以事务的形式批处理。
func (s *StandAloneStorage) Write(ctx *kvrpcpb.Context, batch []storage.Modify) error {
// Your Code Here (1).
txn := s.db.NewTransaction(true)
for _, m := range batch {
var err error = nil
switch m.Data.(type) {
case storage.Delete:
err = txn.Delete(engine_util.KeyWithCF(m.Cf(), m.Key()))
case storage.Put:
err = txn.Set(engine_util.KeyWithCF(m.Cf(), m.Key()), m.Value())
}
if err != nil {
return err
}
}
err := txn.Commit()
log.Debugf("success commit txn batch[%v]", batch)
return err
}
server raw api
主要这个scan是从startkey开始,然后scan limit_num个元素
func (server *Server) RawScan(_ context.Context, req *kvrpcpb.RawScanRequest) (*kvrpcpb.RawScanResponse, error) {
// Your Code Here (1).
// Hint: Consider using reader.IterCF
responce := &kvrpcpb.RawScanResponse{}
reader, err1 := server.storage.Reader(req.GetContext())
if err1 != nil {
return responce, err1
}
iter := reader.IterCF(req.Cf)
iter.Seek(req.StartKey)
var nums uint32 = 0
for ; iter.Valid(); iter.Next() {
if nums == req.GetLimit() {
break
}
value, err := iter.Item().Value()
if err != nil {
return responce, err
}
responce.Kvs = append(responce.Kvs, &kvrpcpb.KvPair{Key: iter.Item().Key(), Value: value})
nums++
}
return responce, nil
}
Summary
第一个project还是很简单的,没什么太多要说的,希望下一个project不要太虐。