github.com/Finschia/finschia-sdk@v0.48.1/store/cachekv/memiterator.go (about)

     1  package cachekv
     2  
     3  import (
     4  	"bytes"
     5  
     6  	dbm "github.com/tendermint/tm-db"
     7  
     8  	"github.com/Finschia/finschia-sdk/store/types"
     9  )
    10  
    11  // Iterates over iterKVCache items.
    12  // if key is nil, means it was deleted.
    13  // Implements Iterator.
    14  type memIterator struct {
    15  	types.Iterator
    16  
    17  	lastKey []byte
    18  	deleted map[string]struct{}
    19  }
    20  
    21  func IsKeyInDomain(key, start, end []byte) bool {
    22  	if bytes.Compare(key, start) < 0 {
    23  		return false
    24  	}
    25  	if end != nil && bytes.Compare(end, key) <= 0 {
    26  		return false
    27  	}
    28  	return true
    29  }
    30  
    31  func newMemIterator(start, end []byte, items *dbm.MemDB, deleted map[string]struct{}, ascending bool) *memIterator {
    32  	var iter types.Iterator
    33  	var err error
    34  
    35  	if ascending {
    36  		iter, err = items.Iterator(start, end)
    37  	} else {
    38  		iter, err = items.ReverseIterator(start, end)
    39  	}
    40  
    41  	if err != nil {
    42  		panic(err)
    43  	}
    44  
    45  	return &memIterator{
    46  		Iterator: iter,
    47  
    48  		lastKey: nil,
    49  		deleted: deleted,
    50  	}
    51  }
    52  
    53  func (mi *memIterator) Value() []byte {
    54  	key := mi.Iterator.Key()
    55  	// We need to handle the case where deleted is modified and includes our current key
    56  	// We handle this by maintaining a lastKey object in the iterator.
    57  	// If the current key is the same as the last key (and last key is not nil / the start)
    58  	// then we are calling value on the same thing as last time.
    59  	// Therefore we don't check the mi.deleted to see if this key is included in there.
    60  	reCallingOnOldLastKey := (mi.lastKey != nil) && bytes.Equal(key, mi.lastKey)
    61  	if _, ok := mi.deleted[string(key)]; ok && !reCallingOnOldLastKey {
    62  		return nil
    63  	}
    64  	mi.lastKey = key
    65  	return mi.Iterator.Value()
    66  }