Skip to content

Cursor.Prev() out of range issue v1.3.9 #733

@axww

Description

@axww

Hi, I met an issue during dev. Here's my sample code:

package main

import (
	"fmt"
	"log"

	bolt "go.etcd.io/bbolt"
)

func main() {

	aDb, dbErr := bolt.Open("a.db", 0600, nil)
	if dbErr != nil {
		log.Fatal(dbErr)
	}
	defer aDb.Close()

	aDb.Batch(func(tx *bolt.Tx) error {
		// Create data
		b, _ := tx.CreateBucketIfNotExists([]byte("test"))
		b.Put([]byte("1"), nil)
		b.Put([]byte("2"), nil)
		b.Put([]byte("3"), nil)
		// Next test
		fmt.Println("=== Next test ===")
		cn := b.Cursor()
		cn.Seek([]byte("2")) //2
		cn.Next()            // 3
		cn.Next()            // nil (Cursor stops at 3)
		kn, _ := cn.Prev()   // 2
		fmt.Println(string(kn))
		// Prev test
		fmt.Println("=== Prev test ===")
		cp := b.Cursor()
		cp.Seek([]byte("2")) //2
		cp.Prev()            // 1
		cp.Prev()            // nil (Cursor out of range)
		kp, _ := cp.Next()   // Should be 2 but nil
		fmt.Println(string(kp))
		// End
		return nil
	})
}

The output of the program:

=== Next test ===
2
=== Prev test ===

As you can see I put 3 rows "1", "2" and "3" into the bucket.
Both of "Next test" and "Prev test", I set cursor at "2" initially.

In "Next test", I move cursor to "3", then run Next() again, it returns nil.
Then I run Prev(), the cursor targets to "2".

In "Prev test", I move cursor to "1", then run Prev() again, it returns nil.
Then I run Next(), the cursor targets to nil.

Whatever how many Next() I added in "Prev test", the cursor still targes to nil.
It seems after Cursor.Prev() out of range, it stucks there and can not be use anymore.

I don't know if this is a bug or a correct design, but it's strange.
Do you consider make these 2 situations have similiar behavior?

Thank you very much!
Best

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions