good morning!!!!

Skip to content
Snippets Groups Projects
Unverified Commit f19bb0a3 authored by Alex Sharov's avatar Alex Sharov Committed by GitHub
Browse files

simplify cursor.Next and cursor.First implementation (#1019)

parent c06dbdad
Branches
Tags
No related merge requests found
......@@ -112,11 +112,9 @@ for k, v := cursor.Seek(key); k != nil; k, v = cursor.Next() {
Iterate over bucket with sub-buckets:
```
cursor := transaction.OpenCursor(bucketName)
for k1, _ := cursor.First(); k1 != nil; k1, _ = cursor.Next() {
for k, v := cursor.FirstInSubBucket(); k != nil; k, v = cursor.NextInSubBucket() {
for k, _ := cursor.SeekDup(subBucketName, keyInSubBucket); k != nil; k, _ = cursor.Next() {
// logic works with 'k1', 'k' and 'v' variables
}
}
```
Enough strait forward. No performance penalty (only profit from smaller database size).
......
......@@ -585,12 +585,6 @@ func (c *LmdbCursor) initCursor() error {
}
func (c *LmdbCursor) First() ([]byte, []byte, error) {
if c.cursor == nil {
if err := c.initCursor(); err != nil {
return []byte{}, nil, err
}
}
return c.Seek(c.prefix)
}
......@@ -614,17 +608,12 @@ func (c *LmdbCursor) Last() ([]byte, []byte, error) {
return []byte{}, nil, err
}
if c.bucketCfg.Flags&lmdb.DupSort != 0 {
if k == nil {
return k, v, nil
}
k, v, err = c.lastDup(k)
if err != nil {
if lmdb.IsNotFound(err) {
return nil, nil, nil
}
err = fmt.Errorf("failed LmdbKV cursor.Last(): %w, bucket: %s", err, c.bucketName)
return []byte{}, nil, err
b := c.bucketCfg
if b.Flags&lmdb.DupSort != 0 {
from, to := b.DupFromLen, b.DupToLen
if len(k) == to {
k = append(k, v[:from-to]...)
v = v[from-to:]
}
}
......@@ -643,7 +632,7 @@ func (c *LmdbCursor) Seek(seek []byte) (k, v []byte, err error) {
}
if len(seek) == 0 {
k, v, err = c.cursor.Get(nil, nil, lmdb.First)
k, v, err = c.first()
} else {
k, v, err = c.setRange(seek)
}
......@@ -665,7 +654,7 @@ func (c *LmdbCursor) seekDupSort(seek []byte) (k, v []byte, err error) {
b := c.bucketCfg
from, to := b.DupFromLen, b.DupToLen
if len(seek) == 0 {
k, v, err = c.cursor.Get(nil, nil, lmdb.First)
k, v, err = c.first()
if err != nil {
if lmdb.IsNotFound(err) {
return nil, nil, nil
......@@ -728,53 +717,34 @@ func (c *LmdbCursor) Next() (k, v []byte, err error) {
default:
}
if c.bucketCfg.Flags&lmdb.DupSort != 0 {
return c.nextDupSort()
}
// lmdb.Next method works automatically as expected with DupSort buckets
if c.cursor == nil {
if err = c.initCursor(); err != nil {
log.Error("init cursor", "err", err)
}
}
k, v, err = c.cursor.Get(nil, nil, lmdb.Next)
k, v, err = c.next()
if err != nil {
if lmdb.IsNotFound(err) {
return nil, nil, nil
}
return []byte{}, nil, fmt.Errorf("failed LmdbKV cursor.Next(): %w", err)
}
if c.prefix != nil && !bytes.HasPrefix(k, c.prefix) {
k, v = nil, nil
}
return k, v, nil
}
func (c *LmdbCursor) nextDupSort() (k, v []byte, err error) {
b := c.bucketCfg
if b.Flags&lmdb.DupSort != 0 {
from, to := b.DupFromLen, b.DupToLen
k, v, err = c.cursor.Get(nil, nil, lmdb.NextDup)
if err != nil && lmdb.IsNotFound(err) {
k, v, err = c.cursor.Get(nil, nil, lmdb.Next)
if err != nil {
if lmdb.IsNotFound(err) {
return nil, nil, nil
}
return []byte{}, nil, fmt.Errorf("failed LmdbKV cursor.Next(): %w", err)
}
} else if err != nil {
return nil, nil, err
}
if len(k) == to {
k = append(k, v[:from-to]...)
v = v[from-to:]
}
}
if c.prefix != nil && !bytes.HasPrefix(k, c.prefix) {
k, v = nil, nil
}
return k, v, nil
}
......@@ -1002,6 +972,10 @@ func (c *LmdbCursor) setRange(key []byte) ([]byte, []byte, error) {
return c.cursor.Get(key, nil, lmdb.SetRange)
}
func (c *LmdbCursor) first() ([]byte, []byte, error) {
return c.cursor.Get(nil, nil, lmdb.First)
}
func (c *LmdbCursor) next() ([]byte, []byte, error) {
return c.cursor.Get(nil, nil, lmdb.Next)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment