github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/mainchain/extstorages/account_txhash_store.go (about) 1 package extstorages 2 3 import ( 4 "encoding/binary" 5 6 "bytes" 7 8 "github.com/syndtr/goleveldb/leveldb/util" 9 "github.com/sixexorg/magnetic-ring/common" 10 "github.com/sixexorg/magnetic-ring/store/db" 11 mcom "github.com/sixexorg/magnetic-ring/store/mainchain/common" 12 ) 13 14 type AccountHashStore struct { 15 dbDir string 16 store *db.LevelDBStore 17 } 18 19 type AccountHash struct { 20 TxHash common.Hash 21 Index uint32 22 } 23 24 func NewAccountHashStore(dbDir string) (*AccountHashStore, error) { 25 var err error 26 store, err := db.NewLevelDBStore(dbDir) 27 if err != nil { 28 return nil, err 29 } 30 accoutHashStore := &AccountHashStore{ 31 dbDir: dbDir, 32 store: store, 33 } 34 return accoutHashStore, nil 35 } 36 37 func (this *AccountHashStore) BatchSave(account common.Address, txHashes common.HashArray) { 38 idx := this.getIndex(account) 39 for _, v := range txHashes { 40 key := this.getKey(account, idx) 41 this.store.BatchPut(key, v.ToBytes()) 42 idx++ 43 } 44 } 45 func (this *AccountHashStore) GetRangeHashes(account common.Address, pageSize uint32, prevIndex uint32, esc bool) []*AccountHash { 46 var start, end uint32 47 48 if esc { 49 start = prevIndex + 1 50 end = prevIndex + pageSize 51 } else { 52 end = prevIndex - 1 53 if prevIndex < pageSize { 54 end = 0 55 } else { 56 start = prevIndex - pageSize 57 } 58 } 59 prefixS := this.getKey(account, start) 60 prefixE := this.getKey(account, end) 61 62 iter := this.store.NewSeniorIterator(&util.Range{Start: prefixS, Limit: prefixE}) 63 ahs := make([]*AccountHash, 0, pageSize) 64 for iter.Next() { 65 key := iter.Key() 66 value := iter.Value() 67 index := key[1+common.AddrLength:] 68 txHash, _ := common.ParseHashFromBytes(value) 69 ahs = append(ahs, &AccountHash{Index: binary.LittleEndian.Uint32(index), TxHash: txHash}) 70 } 71 return ahs 72 } 73 74 func (this *AccountHashStore) getIndex(address common.Address) uint32 { 75 prefix := bytes.NewBuffer(nil) 76 prefix.WriteByte(byte(mcom.ACCOUNT_HASHES)) 77 prefix.Write(address[:]) 78 iter := this.store.NewIterator(prefix.Bytes()) 79 if iter.Last() { 80 key := iter.Key() 81 l := len(key) 82 idxbyte := key[l-4 : l] 83 idx := binary.LittleEndian.Uint32(idxbyte) 84 return idx 85 } 86 return 0 87 } 88 89 func (this *AccountHashStore) getKey(address common.Address, index uint32) []byte { 90 buff := make([]byte, 1+common.AddrLength+4) 91 buff[0] = byte(mcom.ACCOUNT_HASHES) 92 copy(buff[1:common.AddrLength+1], address[:]) 93 binary.LittleEndian.PutUint32(buff[common.AddrLength+1:], index) 94 return buff 95 }