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
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
An existing cursors can also be duplicated within the same transaction
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-last: initialize the cursor to the first and last element of the btree, respectively.
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:
value). The first argument tells whether or not the cursor is
initialized and pointing at a proper value. The second two arguments
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-prev move the cursor a single step
forward or back across the sorted key-value pairs.
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
(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.