2021-03-30 09:53:54 +00:00
|
|
|
package ethdb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
|
2021-07-29 11:53:13 +00:00
|
|
|
"github.com/ledgerwatch/erigon-lib/kv"
|
2021-03-30 09:53:54 +00:00
|
|
|
)
|
|
|
|
|
2021-07-28 02:47:38 +00:00
|
|
|
func Walk(c kv.Cursor, startkey []byte, fixedbits int, walker func(k, v []byte) (bool, error)) error {
|
2021-03-30 09:53:54 +00:00
|
|
|
fixedbytes, mask := Bytesmask(fixedbits)
|
|
|
|
k, v, err := c.Seek(startkey)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for k != nil && len(k) >= fixedbytes && (fixedbits == 0 || bytes.Equal(k[:fixedbytes-1], startkey[:fixedbytes-1]) && (k[fixedbytes-1]&mask) == (startkey[fixedbytes-1]&mask)) {
|
|
|
|
goOn, err := walker(k, v)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !goOn {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
k, v, err = c.Next()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-06-19 08:21:53 +00:00
|
|
|
func Bytesmask(fixedbits int) (fixedbytes int, mask byte) {
|
|
|
|
fixedbytes = (fixedbits + 7) / 8
|
|
|
|
shiftbits := fixedbits & 7
|
|
|
|
mask = byte(0xff)
|
|
|
|
if shiftbits != 0 {
|
|
|
|
mask = 0xff << (8 - shiftbits)
|
|
|
|
}
|
|
|
|
return fixedbytes, mask
|
|
|
|
}
|