Next: BTree Indexing, Previous: Persistent BTrees, Up: User Guide
Aside from getting, setting and dropping key-value pairs from the database, you can also traverse the BTree structure one key-value pair at a time.
Cursors must be created in the context of an active transaction
(i.e. a with/ensure-transaction
body). A cursor is made
through a call to the make-cursor
method of the BTree you wish
to traverse. You must ensure that the cursor gets closed when
the stack is unwound; it's best to use the convenience macro
with-btree-cursor
instead of make-cursor
.
An existing cursors can also be duplicated within the same transaction
by calling cursor-duplicate
which avoids the overhead of
setting a second cursor to the same location.
Cursors can be in two states: initialized and uninitialized. BTree Cursor API for details.
To initialize a cursor, you have to use one of the initializing functions to select a key-value pair in the btree.
cursor-first
and cursor-last
: initialize the
cursor to the first and last element of the btree, respectively.
cursor-set
and cursor-set-range
: Sets the cursor
to the first key-pair values according to the specified key. If the
set fails, the cursor will remain uninitialized. The ranged set will
set it to the first key-value pair where the key is equal to or
greater than the key argument.
A valid cursor will return multiple values: (exists? key
value)
. The first argument tells whether or not the cursor is
initialized and pointing at a proper value. The second two arguments
are self-explanatory.
cursor-current
returns the current state of the cursor, nil if
it is uninitialized.
Once a cursor is properly initialized, it can be incremented or decremented, a simple constant-time operation on BTrees.
cursor-next
and cursor-prev
move the cursor a single step
forward or back across the sorted key-value pairs. cursor-next
moves in ascending order, cursor-prev
in descending order.
Finally cursors can be used for side effects on the current key-value
pair. The function cursor-put
replaces the value (but does not
increment the current value) and cursor-delete
deletes the
key-value pair and become uninitialized. It is a valid operation to
use the (setf get-value)
method while the cursor is active to
change the value at the current cursor.
If cursors take place within a transaction, what happens when traversing a very large BTree? This depends on the data store policy regarding whether a cursor read locks its entire btree (or the subset that is being iterated over) or allows changes to any pairs its transaction has not changed. See your data store documentation for details.