Next: Secondary Indices, Previous: Using BTrees, Up: Tutorial
You can traverse BTrees with cursors. Open one with
* (defvar curs (make-cursor *friends-birthdays*))
=> CURS
and close it with
* (cursor-close curs)
=> NIL
Typically one opens a cursor within an transaction. Cursors should be closed after they are done with, before the enclosing transaction is closed. This is encapsulated in the idiom
* (with-transaction ()
(with-btree-cursor (curs *friends-birthdays*)
...))
The cursor movement functions in general return three values: a boolean indicating whether a pair was found / available, the key, and the value. For example:
* (cursor-current curs) ; Not initialized!
=> NIL
* (cursor-first curs)
=> T
"Andrew"
2429071200
* (cursor-next curs)
=> T
"Ben"
2407298400
* (cursor-next curs) ; No more entries!
=> NIL
Other cursor-* functions include: prev, last, current,
set (set to a key), set-range (get the first key greater or
equal to the key), get-both (set to a key / value pair),
get-both-range (set to a key / value pair with value greater or
equal to a particular value), et cetera. Details can be found at
Cursors. In general if a movement command fails, the cursor is
invalidated, and has to be repositioned.
Internally, BTree keys and values are sorted by an ad-hoc C function. It is capable of sorting most numbers (floats are fine, integers up to 64 bits) and strings (case-insensitively, though Unicode users will find their strings sorted code-point-order which is case sensitive.) Other values it sorts byte-lexically, which is usually meaningless in Lisp.
Finally, one can also insert and delete by cursor, and there is a
map-btree function, which functions analogously to the
maphash CL function.