Liking cljdoc? Tell your friends :D

vaelii.impl.overlay.store

OverlayRecordStore — a composite RecordStore layering a private writable overlay over a shared read-only base. Reads resolve overlay-first, skipping tombstoned base handles; writes land only in the overlay; the base is never mutated. The record half of the :overlay backend (the index half is vaelii.impl.overlay.kv).

  • The id boundary. The overlay's handle counter is seeded above every handle the base holds, so a newly minted handle can never collide with a base one. A record written at a handle the base already uses is therefore an override — the same handle, a different record — and the overlay's copy wins every read. That is how a base record is edited without editing the base: mark-premise materializes an override before it writes, since the assumption strength lives on the record. The boundary holds over the base the handles were minted against, so a mount records the base's watermark and refuses a base that has grown since the fork wrote against it (check-base-overlap!).
  • Tombstones. Deleting a base handle cannot touch the base, so it is recorded and the read path filters it. They are sticky: a base record cannot come back through fall-through, only by being written again into the overlay (a revival, at the same handle).
  • Wholesale clear. clear-records! empties the overlay and marks the base hidden — one flag rather than a tombstone per base handle — so a fork can be reset to empty without walking what it inherited.
  • Durable bookkeeping. The tombstone sets, the released premise marks and the hidden flag live in a small KvBackend under reserved keys, mirrored in atoms for the read path. Every mutation writes through, and a mount rebuilds the atoms from it, so remounting a durable overlay over the same base serves the same merged contents: a deleted base record stays deleted, a released premise stays released. An ephemeral fork passes an in-RAM bookkeeping backend and pays nothing for the machinery.

Counts need no delta bookkeeping here. A RecordStore exposes handle sets rather than counts, and everything counted — sentex-count, count-in-context, count-with-functor — is read off the index, where the merge is the trie's own copy-on-write counters and the merged root sets (vaelii.impl.overlay.kv). So the counts a fork reports are exact by construction rather than by a second, parallel accounting that could drift from the records.

The fork's belief is rebuilt, not overlaid. The JTMS is not storage — it is a separate protocol (vaelii.impl.jtms) over derived state — and the engine already has the operation that computes it from records: recover. So a fork gets its own network by recovering over the merged contents, and nothing here layers one truth-maintenance graph over another.

`OverlayRecordStore` — a composite `RecordStore` layering a private **writable**
overlay over a shared **read-only** base.  Reads resolve overlay-first, skipping
tombstoned base handles; writes land only in the overlay; the base is never mutated.
The record half of the `:overlay` backend (the index half is
`vaelii.impl.overlay.kv`).

* **The id boundary.**  The overlay's handle counter is seeded above every handle the base
  holds, so a newly minted handle can never collide with a base one.  A record written
  at a handle the base *already* uses is therefore an **override** — the same handle,
  a different record — and the overlay's copy wins every read.  That is how a base
  record is edited without editing the base: `mark-premise` materializes an override
  before it writes, since the assumption strength lives on the record.  The boundary
  holds over the base the handles were minted against, so a mount records the base's
  watermark and refuses a base that has grown since the fork wrote against it
  (`check-base-overlap!`).
* **Tombstones.**  Deleting a base handle cannot touch the base, so it is recorded and
  the read path filters it.  They are sticky: a base record cannot come back through
  fall-through, only by being written again into the overlay (a revival, at the same
  handle).
* **Wholesale clear.**  `clear-records!` empties the overlay and marks the base
  hidden — one flag rather than a tombstone per base handle — so a fork can be reset
  to empty without walking what it inherited.
* **Durable bookkeeping.**  The tombstone sets, the released premise marks and the
  hidden flag live in a small `KvBackend` under reserved keys, mirrored in atoms for
  the read path.  Every mutation writes through, and a mount rebuilds the atoms from
  it, so remounting a durable overlay over the same base serves the same merged contents:
  a deleted base record stays deleted, a released premise stays released.  An
  ephemeral fork passes an in-RAM bookkeeping backend and pays nothing for the
  machinery.

**Counts need no delta bookkeeping here.**  A `RecordStore` exposes handle
*sets* rather than counts, and everything counted — `sentex-count`, `count-in-context`,
`count-with-functor` — is read off the index, where the merge is the trie's own
copy-on-write counters and the merged root sets (`vaelii.impl.overlay.kv`).  So the
counts a fork reports are exact by construction rather than by a second, parallel
accounting that could drift from the records.

**The fork's belief is rebuilt, not overlaid.**  The JTMS is not storage — it is a
separate protocol (`vaelii.impl.jtms`) over derived state — and the engine already has the
operation that computes it from records: `recover`.  So a fork gets its own network by
recovering over the merged contents, and nothing here layers one truth-maintenance graph
over another.
raw docstring

excluding-readersclj

(excluding-readers {:keys [rebase-lock]} f)

Call f holding the write side of fork store's rebase lock, and return what f returns. Every public read holds the read side (kb/reading), so a read on another thread waits for f to return, and the calling thread's own reads re-enter.

Call `f` holding the write side of fork `store`'s rebase lock, and return what `f`
returns.  Every public read holds the read side (`kb/reading`), so a read on another
thread waits for `f` to return, and the calling thread's own reads re-enter.
sourceraw docstring

overlay-record-storeclj

(overlay-record-store overlay base meta-kv)
(overlay-record-store overlay base meta-kv index-cleared?)
(overlay-record-store overlay base meta-kv index-cleared? base-opts)

Compose a writable overlay RecordStore over a read-only base one, with meta-kv holding the overlay's record-level bookkeeping.

The mount reads the bookkeeping back — so a durable overlay remounted over the same base serves the merged contents it was left in — and seeds the handle counter above both stores' watermarks, which is what keeps a minted handle out of the base's range even after a restart. It records the base's watermark in the bookkeeping, and refuses (:fork-base-overlap) a remount over a base that has changed since, once the fork has written anything (check-base-overlap!). index-cleared? says the fork's own index half has been rebuilt (reindex), which is state the record half cannot see. base-opts are the opts the base was opened from, or nil when it arrived as open stores; rebase! replaces a base that has them.

Compose a writable `overlay` `RecordStore` over a read-only `base` one, with `meta-kv`
holding the overlay's record-level bookkeeping.

The mount reads the bookkeeping back — so a durable overlay remounted over the same
base serves the merged contents it was left in — and seeds the handle counter above both
stores' watermarks, which is what keeps a minted handle out of the base's range even
after a restart.  It records the base's watermark in the bookkeeping, and refuses
(`:fork-base-overlap`) a remount over a base that has changed since, once the fork has
written anything (`check-base-overlap!`).  `index-cleared?` says the fork's own index
half has been rebuilt (`reindex`), which is state the record half cannot see.
`base-opts` are the opts the base was opened from, or nil when it arrived as open
stores; `rebase!` replaces a base that has them.
sourceraw docstring

overlay-record-store?clj

(overlay-record-store? store)

Is store one of these — i.e. is it already a fork's record half? Asked by vaelii.impl.overlay.mount, which refuses a base that is itself a fork.

Is `store` one of these — i.e. is it already a fork's record half?  Asked by
`vaelii.impl.overlay.mount`, which refuses a base that is itself a fork.
sourceraw docstring

rebase!clj

(rebase! {:keys [overlay base meta-kv counter base-top hidden? sx-tombstoned
                 jd-tombstoned pv-tombstoned released]}
         refill!)

Empty the fork store's own records and bookkeeping, call refill!, which replaces the contents of the base's stores, and mount the emptied half over the new base, returning what refill! returns. The handle counter and the watermark are seeded from the base's next-id, as a mount seeds them. Every record, tombstone, released mark and base digest the fork held is dropped, so nothing written against the old base is read against the new one. The base reads as hidden until refill! returns.

Empty the fork `store`'s own records and bookkeeping, call `refill!`, which replaces the
contents of the base's stores, and mount the emptied half over the new base, returning
what `refill!` returns.  The handle counter and the watermark are seeded from the
base's `next-id`, as a mount seeds them.  Every record, tombstone, released mark and
base digest the fork held is dropped, so nothing written against the old base is read
against the new one.  The base reads as hidden until `refill!` returns.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close