tendermint/db/util.go

83 lines
1.5 KiB
Go
Raw Normal View History

package db
import "bytes"
// A wrapper around itr that tries to keep the iterator
// within the bounds as defined by `prefix`
type prefixIterator struct {
itr Iterator
prefix []byte
invalid bool
}
func (pi *prefixIterator) Seek(key []byte) {
if !bytes.HasPrefix(key, pi.prefix) {
pi.invalid = true
return
}
pi.itr.Seek(key)
pi.checkInvalid()
}
func (pi *prefixIterator) checkInvalid() {
if !pi.itr.Valid() {
pi.invalid = true
}
}
func (pi *prefixIterator) Valid() bool {
if pi.invalid {
return false
}
key := pi.itr.Key()
ok := bytes.HasPrefix(key, pi.prefix)
if !ok {
pi.invalid = true
return false
}
return true
}
func (pi *prefixIterator) Next() {
if pi.invalid {
panic("prefixIterator Next() called when invalid")
}
pi.itr.Next()
pi.checkInvalid()
}
func (pi *prefixIterator) Prev() {
if pi.invalid {
panic("prefixIterator Prev() called when invalid")
}
pi.itr.Prev()
pi.checkInvalid()
}
func (pi *prefixIterator) Key() []byte {
if pi.invalid {
panic("prefixIterator Key() called when invalid")
}
return pi.itr.Key()
}
func (pi *prefixIterator) Value() []byte {
if pi.invalid {
panic("prefixIterator Value() called when invalid")
}
return pi.itr.Value()
}
func (pi *prefixIterator) Close() { pi.itr.Close() }
func (pi *prefixIterator) GetError() error { return pi.itr.GetError() }
func IteratePrefix(db DB, prefix []byte) Iterator {
itr := db.Iterator()
pi := &prefixIterator{
itr: itr,
prefix: prefix,
}
pi.Seek(prefix)
return pi
}