Skip to content

Tx-filter history views and Datahike-style purge API - #3

Draft
tiensonqin wants to merge 9 commits into
logseq/non-pss-lmdb-fe5dfrom
logseq/tx-filter-history-fe5d
Draft

Tx-filter history views and Datahike-style purge API#3
tiensonqin wants to merge 9 commits into
logseq/non-pss-lmdb-fe5dfrom
logseq/tx-filter-history-fe5d

Conversation

@tiensonqin

@tiensonqin tiensonqin commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Completes the tx-filter / append-only LMDB index migration: overlay model removed, temporal views (history / as_of / since) are O(1) db handle copies with tx-visibility + datoms-filter applied on read.

Storage architecture

  • storage_kind is an extensible string ("memory", "lmdb", "sqlite", or custom names like "pg").
  • Backends register via Datascript_storage_protocol.register_backend.
  • Default package datascript-ocaml-native — memory only.
  • Optional packages: datascript-ocaml-native-lmdb, datascript-ocaml-native-sqlite.

Tx-filter / history

  • Append-only LMDB writes (add + retract records); no overlay merge or sync_merged_to_lmdb.
  • fold_datoms on temporal views routes through datoms() so tx-filter applies to full-index scans.
  • Public API: history, is_history, as_of, since, basis_tx, as_of_tx, since_tx.

Platform parity

  • Melange: in-memory Hashtbl LMDB db backend (same API as native, no open Lmdb).
  • jsoo: uses melange lmdb/storage libraries in byte mode.

Tests

All tx-filter gate tests pass: test_core, test_db, test_tx_visibility, test_tx_history, test_storage, test_purge, test_lmdb_package, test_sqlite_package.

Benchmark (20k entities)

benchmark pss lmdb ratio
build-all-init 174ms 324ms 1.86x
query-name-ivan 2.92ms 1.63ms 0.56x
scan-aevt-name 0.14ms 0.07ms 0.50x
add-one-tx 0.03ms 0.04ms 1.33x
storage-roundtrip 693ms 633ms 0.91x

LMDB is competitive or faster on query/scan/storage at 20k; init remains slower (expected for append-only history store).

Design doc

See docs/design-tx-filter-history.md.

Open in Web Open in Cursor 

cursoragent and others added 3 commits August 27, 2026 08:30
Introduce tx visibility filtering and public history/time-travel API matching
dbval.core: basis_tx, as_of/as_of_t, since/since_t, history, temporal_view.

- db fields: max_tx (basis), store_max_tx, as_of_tx, since_tx, history
- tx_visibility module with datoms_filter matching dbval semantics
- transact rejects temporal views with dbval-compatible error message
- design doc for overlay removal and append-only migration

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Replace overlay merge model with append-only LMDB writes and dbval-style
tx visibility on all read paths.

- Simplify Index.t to { db, which }; remove additions/removals/bulk
- append_tx_data: single LMDB txn for EAVT/AEVT/AVET on transact
- init via of_eavt_datoms (one txn); snapshot_db is O(1) shared handle
- refresh_indexes_with_tx_data appends full tx_data (add + retract)
- apply_db_view on datoms/eavt/attr caches for datoms-filter + basis
- test_tx_history: as_of, since, history integration tests

Known regression: add-one-tx ~1.4ms vs ~0.01ms overlay (LMDB write cost).
Store still copies full index when session/storage envs differ.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Defer LMDB writes for incremental transacts on databases without attached
storage into db.pending_datoms. Bulk init still writes session LMDB directly.
Store flushes pending via flush_pending_datoms before syncing indexes.

Read paths merge pending_overlay with LMDB cursors without forcing full
list materialization when only duplicates are absent. Fix find_eavt/find_avet
and exact-prefix/seek paths to include pending datoms.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
@cursor cursor Bot changed the title Phase 1: dbval-aligned temporal db API (tx filter foundation) Tx-filter index migration: remove LMDB overlay, dbval history API Aug 27, 2026
cursoragent and others added 2 commits August 27, 2026 08:58
Add sync_append_since_tx to copy only datoms with tx > stored meta max_tx
when session and storage LMDB envs differ. Skip index copy when envs are
shared (storage-attached dbs).

Add test_storage multi-tx incremental store with as_of/history after restore.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Implement :db/purge, :db.purge/attribute, and :db.purge/entity transaction
operations that physically remove datoms from current and history views,
matching Datahike purge semantics. Purge searches the history stream, deletes
keys from append-only LMDB indexes, and syncs removals to persistent storage.

Also includes tx-filter history fixes (codec added flag, transact read ceiling,
public temporal API) and test_purge regression coverage.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
@cursor cursor Bot changed the title Tx-filter index migration: remove LMDB overlay, dbval history API Tx-filter history views and Datahike-style purge API Aug 27, 2026
cursoragent and others added 4 commits August 27, 2026 09:29
Cover basis_tx, as_of/since bounds, history retractions, entity retraction
trails, temporal view transact guards, view immutability, index parity, and
public API aliases.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
- Replace fixed storage_kind variants with extensible string labels
  (storage_kind_memory/lmdb/sqlite constants for built-in names)
- Unify all backends behind storage_backend callbacks registered via
  Datascript_storage_protocol.register_backend
- Default datascript-ocaml-native.storage package: memory only
- Optional opam packages: datascript-ocaml-native-lmdb and
  datascript-ocaml-native-sqlite with plugin modules
- Migrate storage/history/purge tests to Alcotest

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Since tx is exclusive (tx > since_tx), post-bootstrap age updates appear
in since tx0 history, not since tx1 where age 30 was asserted.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
- Delete dead sync_merged_to_lmdb and stale lmdb root copies; storage lives
  under lmdb/native and storage/native only.
- Route fold_datoms through datoms() on temporal views so tx-filter/history
  apply to full-index scans.
- Replace melange LMDB db with in-memory Hashtbl backend matching native API;
  enable byte mode for jsoo via melange lmdb/storage libraries.
- Add sqlite/datascript_sqlite_db.ml and tidy codec imports.
- Update design doc and bench row_count after list_addresses removal.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants