github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/mainchain/storages/member_store.go (about)

     1  package storages
     2  
     3  import (
     4  	"bytes"
     5  
     6  	"encoding/binary"
     7  
     8  	"github.com/sixexorg/magnetic-ring/common"
     9  	"github.com/sixexorg/magnetic-ring/errors"
    10  	"github.com/sixexorg/magnetic-ring/store/db"
    11  	mcom "github.com/sixexorg/magnetic-ring/store/mainchain/common"
    12  	"github.com/sixexorg/magnetic-ring/store/mainchain/states"
    13  )
    14  
    15  //prototype pattern
    16  type MemberStore struct {
    17  	enableCache bool
    18  	dbDir       string
    19  	store       *db.LevelDBStore
    20  }
    21  
    22  func NewMemberStore(dbDir string) (*MemberStore, error) {
    23  	var err error
    24  	store, err := db.NewLevelDBStore(dbDir)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	memberStore := &MemberStore{
    29  		dbDir: dbDir,
    30  		store: store,
    31  	}
    32  	return memberStore, nil
    33  }
    34  
    35  //NewBatch start a commit batch
    36  func (this *MemberStore) NewBatch() {
    37  	this.store.NewBatch()
    38  }
    39  func (this *MemberStore) CommitTo() error {
    40  	return this.store.BatchCommit()
    41  }
    42  
    43  func (this *MemberStore) GetPrev(height uint64, leagueId, account common.Address) (*states.LeagueMember, error) {
    44  	key := this.getKey(height, leagueId, account)
    45  	iter := this.store.NewIterator(nil)
    46  	buff := bytes.NewBuffer(nil)
    47  	flag := true
    48  	if iter.Seek(key) {
    49  		if bytes.Compare(iter.Key(), key) == 0 {
    50  			buff.Write(iter.Key())
    51  			buff.Write(iter.Value())
    52  			flag = false
    53  		}
    54  	}
    55  	if flag && iter.Prev() {
    56  		buff.Write(iter.Key())
    57  		buff.Write(iter.Value())
    58  	}
    59  	iter.Release()
    60  	err := iter.Error()
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	if buff.Len() == 0 {
    65  		return nil, errors.ERR_DB_NOT_FOUND
    66  	}
    67  	as := &states.LeagueMember{}
    68  	err = as.Deserialize(buff)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	if as.LeagueId.Equals(leagueId) && as.Data.Account.Equals(account) {
    73  		return as, nil
    74  	}
    75  	return nil, errors.ERR_DB_NOT_FOUND
    76  }
    77  
    78  //SaveBlock persist block to store
    79  func (this *MemberStore) Save(member *states.LeagueMember) error {
    80  	key := this.getKey(member.Height, member.LeagueId, member.Data.Account)
    81  	err := this.store.Put(key, []byte{byte(member.Data.Status)})
    82  	if err != nil {
    83  		return err
    84  
    85  	}
    86  	return nil
    87  }
    88  
    89  func (this *MemberStore) BatchSave(lmstates states.LeagueMembers) error {
    90  	for _, v := range lmstates {
    91  		key := this.getKey(v.Height, v.LeagueId, v.Data.Account)
    92  		this.store.BatchPut(key, []byte{byte(v.Data.Status)})
    93  	}
    94  	return nil
    95  }
    96  func (this *MemberStore) getKey(height uint64, leagueId, account common.Address) []byte {
    97  	buff := make([]byte, 1+common.AddrLength*2+8)
    98  	buff[0] = byte(mcom.ST_MEMBER)
    99  	copy(buff[1:common.AddrLength+1], leagueId[:])
   100  	copy(buff[common.AddrLength+1:common.AddrLength*2+1], account[:])
   101  	binary.LittleEndian.PutUint64(buff[common.AddrLength*2+1:], height)
   102  	return buff
   103  }