Skip to content

Commit

Permalink
rm iterator logic
Browse files Browse the repository at this point in the history
  • Loading branch information
mconcat committed Oct 19, 2021
1 parent c0cc052 commit ade8511
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 160 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/cosmos/btcutil v1.0.4
github.com/cosmos/cosmos-proto v0.0.0-20210914142853-23ed61ac79ce
github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/iavl v0.17.1
github.com/cosmos/iavl v0.17.2-0.20211019083829-a33fa2e01412
github.com/cosmos/ledger-cosmos-go v0.11.1
github.com/gogo/gateway v1.1.0
github.com/gogo/protobuf v1.3.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ github.com/cosmos/iavl v0.15.0-rc5/go.mod h1:WqoPL9yPTQ85QBMT45OOUzPxG/U/JcJoN7u
github.com/cosmos/iavl v0.15.3/go.mod h1:OLjQiAQ4fGD2KDZooyJG9yz+p2ao2IAYSbke8mVvSA4=
github.com/cosmos/iavl v0.17.1 h1:b/Cl8h1PRMvsu24+TYNlKchIu7W6tmxIBGe6E9u2Ybw=
github.com/cosmos/iavl v0.17.1/go.mod h1:7aisPZK8yCpQdy3PMvKeO+bhq1NwDjUwjzxwwROUxFk=
github.com/cosmos/iavl v0.17.2-0.20211019083829-a33fa2e01412 h1:yEFnh7YYR2JsB4tDX4wRVi/qWXHbozQFaBubMpTyxbY=
github.com/cosmos/iavl v0.17.2-0.20211019083829-a33fa2e01412/go.mod h1:nEyKvca8rpXDwVoO305EBafOr3TAxdbrxxfVCwlaFf8=
github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 h1:DdzS1m6o/pCqeZ8VOAit/gyATedRgjvkVI+UCrLpyuU=
github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76/go.mod h1:0mkLWIoZuQ7uBoospo5Q9zIpqq6rYCPJDSUdeCJvPM8=
github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
Expand Down
161 changes: 2 additions & 159 deletions store/iavl/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"io"
"sync"
"time"

ics23 "github.com/confio/ics23/go"
Expand All @@ -18,7 +17,6 @@ import (
"github.com/cosmos/cosmos-sdk/store/tracekv"
"github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/kv"
)
Expand Down Expand Up @@ -378,29 +376,7 @@ func getProofFromTree(tree *iavl.MutableTree, key []byte, exists bool) *tmcrypto

// Implements types.Iterator.
type iavlIterator struct {
// Domain
start, end []byte

key []byte // The current key (mutable)
value []byte // The current value (mutable)

// Underlying store
tree *iavl.ImmutableTree

// Channel to push iteration values.
iterCh chan kv.Pair

// Close this to release goroutine.
quitCh chan struct{}

// Close this to signal that state is initialized.
initCh chan struct{}

mtx sync.Mutex

ascending bool // Iteration order

invalid bool // True once, true forever (mutable)
*iavl.Iterator
}

var _ types.Iterator = (*iavlIterator)(nil)
Expand All @@ -410,140 +386,7 @@ var _ types.Iterator = (*iavlIterator)(nil)
// goroutine.
func newIAVLIterator(tree *iavl.ImmutableTree, start, end []byte, ascending bool) *iavlIterator {
iter := &iavlIterator{
tree: tree,
start: sdk.CopyBytes(start),
end: sdk.CopyBytes(end),
ascending: ascending,
iterCh: make(chan kv.Pair), // Set capacity > 0?
quitCh: make(chan struct{}),
initCh: make(chan struct{}),
Iterator: tree.Iterator(start, end, ascending),
}
go iter.iterateRoutine()
go iter.initRoutine()
return iter
}

// Run this to funnel items from the tree to iterCh.
func (iter *iavlIterator) iterateRoutine() {
iter.tree.IterateRange(
iter.start, iter.end, iter.ascending,
func(key, value []byte) bool {
select {
case <-iter.quitCh:
return true // done with iteration.
case iter.iterCh <- kv.Pair{Key: key, Value: value}:
return false // yay.
}
},
)
close(iter.iterCh) // done.
}

// Run this to fetch the first item.
func (iter *iavlIterator) initRoutine() {
iter.receiveNext()
close(iter.initCh)
}

// Implements types.Iterator.
func (iter *iavlIterator) Domain() (start, end []byte) {
return iter.start, iter.end
}

// Implements types.Iterator.
func (iter *iavlIterator) Valid() bool {
iter.waitInit()
iter.mtx.Lock()

validity := !iter.invalid
iter.mtx.Unlock()
return validity
}

// Implements types.Iterator.
func (iter *iavlIterator) Next() {
iter.waitInit()
iter.mtx.Lock()
iter.assertIsValid(true)

iter.receiveNext()
iter.mtx.Unlock()
}

// Implements types.Iterator.
func (iter *iavlIterator) Key() []byte {
iter.waitInit()
iter.mtx.Lock()
iter.assertIsValid(true)

key := iter.key
iter.mtx.Unlock()
return key
}

// Implements types.Iterator.
func (iter *iavlIterator) Value() []byte {
iter.waitInit()
iter.mtx.Lock()
iter.assertIsValid(true)

val := iter.value
iter.mtx.Unlock()
return val
}

// Close closes the IAVL iterator by closing the quit channel and waiting for
// the iterCh to finish/close.
func (iter *iavlIterator) Close() error {
close(iter.quitCh)
// wait iterCh to close
for range iter.iterCh {
}

return nil
}

// Error performs a no-op.
func (iter *iavlIterator) Error() error {
return nil
}

//----------------------------------------

func (iter *iavlIterator) setNext(key, value []byte) {
iter.assertIsValid(false)

iter.key = key
iter.value = value
}

func (iter *iavlIterator) setInvalid() {
iter.assertIsValid(false)

iter.invalid = true
}

func (iter *iavlIterator) waitInit() {
<-iter.initCh
}

func (iter *iavlIterator) receiveNext() {
kvPair, ok := <-iter.iterCh
if ok {
iter.setNext(kvPair.Key, kvPair.Value)
} else {
iter.setInvalid()
}
}

// assertIsValid panics if the iterator is invalid. If unlockMutex is true,
// it also unlocks the mutex before panicing, to prevent deadlocks in code that
// recovers from panics
func (iter *iavlIterator) assertIsValid(unlockMutex bool) {
if iter.invalid {
if unlockMutex {
iter.mtx.Unlock()
}
panic("invalid iterator")
}
}

0 comments on commit ade8511

Please sign in to comment.