From 6967960a726f74f3efc32ff3dec59ce27f048fef Mon Sep 17 00:00:00 2001 From: Benjamin Wang Date: Fri, 26 Apr 2024 15:41:43 +0100 Subject: [PATCH] Ensure a cursor can continue to iterate elements in reverse direction by call Next when it has already reached the beginning Signed-off-by: Benjamin Wang --- cursor.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cursor.go b/cursor.go index acd2216..0c1e28c 100644 --- a/cursor.go +++ b/cursor.go @@ -74,7 +74,7 @@ func (c *Cursor) Last() (key []byte, value []byte) { // If this is an empty page (calling Delete may result in empty pages) // we call prev to find the last page that is not empty - for len(c.stack) > 0 && c.stack[len(c.stack)-1].count() == 0 { + for len(c.stack) > 1 && c.stack[len(c.stack)-1].count() == 0 { c.prev() } @@ -257,6 +257,15 @@ func (c *Cursor) prev() (key []byte, value []byte, flags uint32) { elem.index-- break } + // If we've hit the beginning, we should stop moving the cursor, + // and stay at the first element, so that users can continue to + // iterate over the elements in reverse direction by calling `Next`. + // We should return nil in such case. + // Refer to https://github.com/etcd-io/bbolt/issues/733 + if len(c.stack) == 1 { + c.first() + return nil, nil, 0 + } c.stack = c.stack[:i] }