Skip to content

Tags: init4tech/mdbx

Tags

v0.8.3

Toggle v0.8.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat: transparent cursor caching (ENG-2129) (#11)

* feat: add cursor caching methods to Cache trait

Extend DbCache with cursor pointer storage and add take_cursor,
return_cursor, drain_cursors to the Cache trait. Both RefCell<DbCache>
and SharedCache implement the new methods.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add cache field to Cursor, return pointer on drop

Cursor now holds a &'tx K::Cache reference. Drop returns the raw
pointer to the cache instead of calling mdbx_cursor_close. Add
from_raw constructor for cache-hit path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: cache-aware Tx::cursor() and drain on commit/drop

Tx::cursor() checks the cursor cache before allocating. Commit and
drop paths drain cached cursors inside with_txn_ptr to ensure all
FFI close calls are properly serialized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add cursor caching tests

Verify cursor reuse across open/drop cycles, multiple cursors on the
same DB, and repeated cycle stability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: document cursor caching Send/Sync and Drop constraint

Document the unsafe Send + Sync impls on DbCache in CLAUDE.md with
full justification. Add code comment explaining why Tx::Drop inlines
drain logic instead of calling drain_cached_cursors (type system
constraint: Drop is on Tx<K, U>, helper is on Tx<K>).

* fix: drain cached cursors on close_db and drop_db

Prevents use-after-free when a DBI is closed or dropped while stale
cursor pointers for it remain in the cursor cache.

* fix: prevent cache poisoning on mdbx_cursor_copy failure

Construct Cursor only after mdbx_cursor_copy succeeds. On failure,
close the raw pointer directly instead of letting Drop push an
unbound cursor into the cache.

* fix: renew cached cursors to reset B-tree position

Call mdbx_cursor_renew on the cache-hit path so reused cursors
start at a clean position rather than retaining stale state.

* docs: add keep-in-sync comments on duplicated drain logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add RO cursor-cache tests

Cover cursor caching in read-only transactions (reuse and repeated
cycles), complementing existing RW-only coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add cursor reuse across writes test

Verify cached cursors see updated data after B-tree COW from
interleaved put operations — the primary hot path for caching.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: route cursor FFI through ops, harden renew error path, add cache tests

Addresses Fraser's review on PR #11:

- Extract drain-and-close logic into `close_drained_cursors` helper, used
  by `close_db`, `drop_db`, `drain_cached_cursors`, and `Tx::Drop`.
- Move all cursor FFI calls into `ops` (`cursor_renew_raw`,
  `cursor_close_raw`, `cursor_close2_raw`), matching the crate convention.
- On `mdbx_cursor_renew` failure in `Tx::cursor`, defensively close the
  raw pointer via `mdbx_cursor_close2` instead of leaking it. Not
  re-cached: a subsequent call would hit the same failure.
- Add `#[cfg(test)]` `cursor_count` and `inject_cursor` to the `Cache`
  trait so tests can verify cache state directly.
- Add tests: cache-count assertions, `close_db` drains its DBI only,
  and a renew-failure test that injects a null pointer to exercise the
  error path and confirm no leak.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(clippy): use checked_div for remaining_in_page calc

Satisfies clippy::manual_checked_ops (new in Rust 1.95).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(clippy): use checked_div for remaining_in_page calc

Satisfies clippy::manual_checked_ops (new in Rust 1.95).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(cursor-cache): co-locate cache with txn pointer to fix clone-drop drain

`Tx::Drop` previously drained the shared cursor cache unconditionally.
For `TxSync`, the cache was `Arc<RwLock<DbCache>>` shared across clones,
so dropping any clone emptied the cache for all surviving clones. The
naive `Arc::strong_count == 1` gate would race on concurrent drops and
leak the cursor pointers (MDBX requires explicit `mdbx_cursor_close`
regardless of RO/RW).

Move the cache inside `PtrSync` (widening the existing `Mutex<()>` to
`Mutex<DbCache>`) and `PtrUnsync` (`RefCell<DbCache>`). The `Arc` that
controls the txn lifetime now also controls cache lifetime, so cursors
are drained-and-closed exactly once in the inner Drop when refcount
hits 0 — race-free by construction.

Removes `SharedCache`, drops `Clone+Default` from the `Cache` trait,
and trims the `cache` field/parameter from `Tx` and `Cursor`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: fix broken Tx::drop reference in close_drained_cursors

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: drop unresolvable intra-doc links on private PtrSync field

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: document deadlock risk of dropping Cursor inside with_txn_ptr

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: bump version to 0.8.3

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

v0.8.1

Toggle v0.8.1's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.8.1 - put_multiple

v0.8.0

Toggle v0.8.0's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.8.0 - iter refinement

v0.7.0

Toggle v0.7.0's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.7.0 -- dupfixed iterators and del_all_dups

v0.6.0

Toggle v0.6.0's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.6.0 -- remove read timeouts

v0.5.0

Toggle v0.5.0's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.5.0 - unsync api, debug checks, and so so so much more

v0.4.0

Toggle v0.4.0's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.4.0 - new mdbx-sys

v0.3.1

Toggle v0.3.1's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.3.1 -- doctest fix

v0.3.0

Toggle v0.3.0's commit message

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich
v0.3.0 - Database rework, caching, and checking

Verified

This tag was signed with the committer’s verified signature.
prestwich James Prestwich