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  }