github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/mainchain/account_level/level_store.go (about) 1 package account_level 2 3 import ( 4 "encoding/binary" 5 6 "bytes" 7 8 "fmt" 9 10 "github.com/syndtr/goleveldb/leveldb/util" 11 "github.com/sixexorg/magnetic-ring/common" 12 "github.com/sixexorg/magnetic-ring/common/serialization" 13 "github.com/sixexorg/magnetic-ring/common/sink" 14 "github.com/sixexorg/magnetic-ring/store/db" 15 mcom "github.com/sixexorg/magnetic-ring/store/mainchain/common" 16 ) 17 18 //prototype pattern 19 type LevelStore struct { 20 dbDir string 21 store *db.LevelDBStore 22 //cache *AccountCache 23 } 24 25 func NewLevelStore(dbDir string) (*LevelStore, error) { 26 var err error 27 store, err := db.NewLevelDBStore(dbDir) 28 if err != nil { 29 return nil, err 30 } 31 levelStore := &LevelStore{ 32 dbDir: dbDir, 33 store: store, 34 } 35 return levelStore, nil 36 } 37 38 func (this *LevelStore) SaveLevels(height uint64, lvls map[common.Address]EasyLevel) error { 39 this.store.NewBatch() 40 for k, v := range lvls { 41 fmt.Printf("📈 📈 📈 levelUp account:%s level:%d\n", k.ToString(), v) 42 key := this.getKey(height, k) 43 sk := sink.NewZeroCopySink(nil) 44 sk.WriteUint8(uint8(v)) 45 this.store.BatchPut(key, sk.Bytes()) 46 } 47 err := this.store.BatchCommit() 48 return err 49 } 50 func (this *LevelStore) GetAccountLvlRange(start, end uint64, account common.Address) []common.FTreer { 51 s := this.getKey(start, account) 52 l := this.getKey(end, account) 53 iter := this.store.NewSeniorIterator(&util.Range{Start: s, Limit: l}) 54 lvls := []common.FTreer{} 55 for iter.Next() { 56 key := iter.Key() 57 val := iter.Value() 58 59 height := binary.LittleEndian.Uint64(key[1+common.AddrLength:]) 60 lvl := EasyLevel(val[0]) 61 lvls = append(lvls, &HeightLevel{Height: height, Lv: lvl}) 62 } 63 iter.Release() 64 return lvls 65 } 66 func (this *LevelStore) GetAccountLevel(height uint64, account common.Address) EasyLevel { 67 key := this.getKey(height, account) 68 iter := this.store.NewIterator(nil) 69 buff := bytes.NewBuffer(nil) 70 flag := true 71 if iter.Seek(key) { 72 if bytes.Compare(iter.Key(), key) == 0 { 73 buff.Write(iter.Key()) 74 buff.Write(iter.Value()) 75 flag = false 76 } 77 } 78 if flag && iter.Prev() { 79 buff.Write(iter.Key()) 80 buff.Write(iter.Value()) 81 } 82 iter.Release() 83 err := iter.Error() 84 if err != nil { 85 return lv0 86 } 87 if buff.Len() == 0 { 88 return lv0 89 } 90 91 buff.Next(1) 92 accBytes, err := serialization.ReadBytes(buff, common.AddrLength) 93 if err != nil { 94 return lv0 95 } 96 if !bytes.Equal(accBytes, account[:]) { 97 return lv0 98 } 99 buff.Next(8) 100 lvl, err := serialization.ReadUint8(buff) 101 if err != nil { 102 return lv0 103 } 104 return EasyLevel(lvl) 105 } 106 func (this *LevelStore) getKey(height uint64, account common.Address) []byte { 107 buff := make([]byte, 1+common.AddrLength+8) 108 buff[0] = byte(mcom.ST_ACCOUNT) 109 copy(buff[1:common.AddrLength+1], account[:]) 110 binary.LittleEndian.PutUint64(buff[common.AddrLength+1:], height) 111 return buff 112 }