Open an existing tree (create=.false.) or create a fresh empty
one (create=.true., file truncated). writable=.false. opens
read-only. On a non-create open key_len must match the value
stored in the file or BT_CORRUPT is returned.
Flush the meta page (read-write opens) and close the unit. Safe
to call on an already-closed handle.
Re-read the mutable meta fields (root, free_head, npages,
first_leaf, nentries) from the on-disk meta page into the open
handle, discarding the cached in-memory copies. This re-syncs a
tree whose file was changed underneath it — specifically after a
journal rollback restores the meta page, the cached fields are
stale and must be reloaded before the tree is touched again. The
unit stays open; page_size/key_len are immutable and a mismatch
(or a failed geometry self-check) is reported as BT_CORRUPT.
Push a writable tree's buffered page writes out to the operating
system so a subsequent fsync of the file makes them durable. Every
mutator already writes the meta page last, so the on-disk image is
coherent; this only drains the open unit's buffer and performs no
fsync itself (the journal layer owns durability, by path). A no-op
on a closed or read-only handle.
Insert (key, payload). Duplicate keys are allowed; the pair
is ordered by key then payload so the entry is uniquely
addressable for bt_remove.
Remove the entry matching (key, payload) exactly. found
is .false. (with stat == BT_OK) if no such entry exists.
Lazy: an emptied leaf is left in place, not merged.
Rebuild the whole tree from keys/payloads: sort (key,payload)
then write perfectly-packed leaves and the internal levels
bottom-up. O(N log N) — the proper replacement for per-row
reinsertion. keys is a rank-1 array of key_len byte strings,
payloads(i) the payload for keys(i).
Note: this resets the logical page count and rewrites from page 2,
but does NOT shrink the underlying file — pages above the new high
water remain allocated on disk (harmless; never read). To actually
reclaim space (e.g. repacking after many lazy deletes), recreate the
file with bt_open(create=.true.) and load into the fresh tree.
Position cur at the first entry whose key is not ordered
before key (lower bound). Callers iterate with bt_next and
stop themselves once the yielded key compares greater.
Position cur at the leftmost entry (whole-tree ascending
iteration). The cursor is exhausted immediately for an empty
tree.
Yield the entry at the cursor and advance. ok is .false.
when the cursor is exhausted (no entry returned).
key must be exactly key_len bytes: only key(1:key_len) is
assigned, so a longer buffer keeps undefined trailing bytes.
Install (or, called with no hook, remove) the pre-write journal
hook on an open writable tree. Installing records the current page
high-water as the new-page boundary for the transaction about to
run; clearing it returns the tree to un-journalled writes. ctx
must be supplied whenever hook is, and must out-live the tree.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(btree_t), | intent(out) | :: | bt |
Tree handle (overwritten) |
||
| character(len=*), | intent(in) | :: | path |
Paged-file path |
||
| integer, | intent(in) | :: | key_len |
Fixed key length in bytes |
||
| logical, | intent(in) | :: | writable |
Open read-write |
||
| logical, | intent(in) | :: | create |
Truncate + initialise empty |
||
| integer, | intent(out) | :: | stat |
|