Liking cljdoc? Tell your friends :D

vaelii.impl.overlay.mount

Mounting a fork: freeze a base, compose a private writable overlay over it, and hand back the two stores a KB is built from.

A base is any pair of stores mounted read-only (vaelii.impl.overlay.frozen); a fork is a fresh writable pair composed over it. Nothing is copied and nothing in the base is written, so any number of forks in one JVM share one base and each evolves its own — the sharing needs no protocol between them, and equally offers no coherence between them: a base that changes under a mounted fork is outside the contract.

A durable base is one JVM's, not several. Its directory takes the exclusive single-writer lock when it opens (vaelii.impl.disk.lock), and a fork's :disk base opens through the same per-directory registry — so a second process cannot mount it while the first holds it. Read-only composition is what the frozen decorator guarantees; read-only file access is a separate thing the disk backend does not offer.

Which index a fork can be taken over

The overlay is a KvBackend decorator, so it forks exactly the index path that is written over that protocol: KvIndexStore (vaelii.impl.kv) and therefore the :memory, :dense and :disk index axes. The :columnar index is a native IndexStore — its trie is int-id nodes in parallel arrays, with no keys and no backend underneath — so a KvBackend decorator would fork its roots and leave its trie behind. That is refused here rather than half-done. Forking a columnar index is a different construction: its compacted CSR mode is already an immutable base, so the natural shape is a mutable columnar head over a frozen CSR base, not a KV decorator.

Bookkeeping

The record half keeps tombstones and released premise marks in a small KvBackend beside the overlay (vaelii.impl.overlay.store). An in-RAM overlay gets an in-RAM one — the whole fork is ephemeral — and a disk overlay gets a durable one under <dir>/overlay-meta, so remounting that directory over the same base serves the merged view it was left in. The index half needs none: its bookkeeping lives in the overlay index itself, under reserved keys, and so is exactly as durable as the fork is.

Mounting a fork: freeze a base, compose a private writable overlay over it, and hand
back the two stores a KB is built from.

A **base** is any pair of stores mounted read-only (`vaelii.impl.overlay.frozen`); a
**fork** is a fresh writable pair composed over it.  Nothing is copied and nothing in
the base is written, so any number of forks in **one JVM** share one base and each
evolves its own — the sharing needs no protocol between them, and equally offers no
coherence between them: a base that changes under a mounted fork is outside the
contract.

A durable base is one JVM's, not several.  Its directory takes the exclusive
single-writer lock when it opens (`vaelii.impl.disk.lock`), and a fork's `:disk` base
opens through the same per-directory registry — so a second process cannot mount it
while the first holds it.  Read-only *composition* is what the frozen decorator
guarantees; read-only *file access* is a separate thing the disk backend does not
offer.

## Which index a fork can be taken over

The overlay is a `KvBackend` decorator, so it forks exactly the index path that is
written over that protocol: `KvIndexStore` (`vaelii.impl.kv`) and therefore the
`:memory`, `:dense` and `:disk` index axes.  The `:columnar` index is a **native**
`IndexStore` — its trie is int-id nodes in parallel arrays, with no keys and no backend
underneath — so a `KvBackend` decorator would fork its roots and leave its trie behind.
That is refused here rather than half-done.  Forking a columnar index is a different
construction: its compacted CSR mode is already an immutable base, so the natural shape
is a mutable columnar head over a frozen CSR base, not a KV decorator.

## Bookkeeping

The record half keeps tombstones and released premise marks in a small `KvBackend`
beside the overlay (`vaelii.impl.overlay.store`).  An in-RAM overlay gets an in-RAM one
— the whole fork is ephemeral — and a disk overlay gets a durable one under
`<dir>/overlay-meta`, so remounting that directory over the same base serves the merged
view it was left in.  The index half needs none: its bookkeeping lives in the overlay
index itself, under reserved keys, and so is exactly as durable as the fork is.
raw docstring

forked?clj

(forked? {:keys [records index]})

Is either half of this {:records :index} store pair already a fork's own?

A stack of forks is not built (docs/overlay.md): the overlay is a two-store decorator, and stacking it would make every read walk one more layer per level while the id watermark, the tombstone sets and the copy-on-write counters would each have to merge across all of them. open-kb refuses an :overlay half that is itself declared :overlay, which catches the opts spelling; this catches the other road in — a live fork's stores handed straight to open-kb as :base-stores, which is exactly what core/fork passes.

Is either half of this `{:records :index}` store pair already a **fork's own**?

A stack of forks is not built (docs/overlay.md): the overlay is a two-store decorator,
and stacking it would make every read walk one more layer per level while the id
watermark, the tombstone sets and the copy-on-write counters would each have to merge
across all of them.  `open-kb` refuses an `:overlay` half that is itself declared
`:overlay`, which catches the opts spelling; this catches the other road in — a live
fork's stores handed straight to `open-kb` as `:base-stores`, which is exactly what
`core/fork` passes.
sourceraw docstring

fresh-overlay-optsclj

(fresh-overlay-opts)

Storage opts for an ephemeral fork: an in-RAM overlay on a space pair nothing else names, so two forks taken with no opts are independent rather than accidentally the same one. Naming the spaces explicitly is how a caller asks for the other behaviour — a remount of a fork it took earlier.

Storage opts for an **ephemeral** fork: an in-RAM overlay on a space pair nothing else
names, so two forks taken with no opts are independent rather than accidentally the same
one.  Naming the spaces explicitly is how a caller asks for the other behaviour — a
remount of a fork it took earlier.
sourceraw docstring

kv-backend-ofclj

(kv-backend-of index-store)

The KvBackend an IndexStore is written over, or nil when it is not written over one at all. A KvIndexStore holds it as :backend; a native index (the columnar one) has no such seam and answers nil.

The `KvBackend` an `IndexStore` is written over, or nil when it is not written over one
at all.  A `KvIndexStore` holds it as `:backend`; a native index (the columnar one) has
no such seam and answers nil.
sourceraw docstring

meta-kvclj

(meta-kv kind opts)

The bookkeeping KvBackend for a fork whose record overlay is kind (:memory or :disk) under opts — in RAM for an ephemeral fork, durable beside the records for a disk one, so the two are exactly as recoverable as each other.

The bookkeeping `KvBackend` for a fork whose *record* overlay is `kind` (`:memory` or
`:disk`) under `opts` — in RAM for an ephemeral fork, durable beside the records for a
disk one, so the two are exactly as recoverable as each other.
sourceraw docstring

mount-indexclj

(mount-index overlay base)

A KvIndexStore over an OverlayKv: overlay's backend (writable) over base's (frozen). Both arguments are IndexStores, and both must be KvIndexStores — see the namespace docstring on why the columnar index is not forkable this way.

A `KvIndexStore` over an `OverlayKv`: `overlay`'s backend (writable) over `base`'s
(frozen).  Both arguments are `IndexStore`s, and both must be `KvIndexStore`s — see the
namespace docstring on why the columnar index is not forkable this way.
sourceraw docstring

mount-recordsclj

(mount-records overlay base meta)

An OverlayRecordStore: overlay (writable) over base (frozen), with meta holding the record-level bookkeeping.

An `OverlayRecordStore`: `overlay` (writable) over `base` (frozen), with `meta` holding
the record-level bookkeeping.
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