Liking cljdoc? Tell your friends :D

vaelii.impl.memory

The default in-memory backends for the two storage protocols, selected at KB construction. The engine above the protocols never touches a concrete store, so a KB built on these runs the whole engine with no external dependency; the on-disk backend (vaelii.impl.disk) is the durable alternative.

The record store implements RecordStore directly over maps. The index reuses vaelii.impl.kv/KvIndexStore — the one trie/roots/index implementation — over a MemoryKvBackend: one map keyed by the structured key vectors (equal vectors are equal keys), holding a Long at each counter key and a set at each set key. kv-intersect is a clojure.set/intersection; kv-members returns the stored set by reference (no serialization, no copy).

Durable-within-the-JVM semantics by space number. Two KBs constructed over the same :space number must share state, or the persistence/recovery tests (a second KB restarted over the same databases) would find an empty store. A process-global registry keyed by space number provides that: (memory-record-store {:space 15}) twice returns records backed by one state atom. clear-records! / clear-index! empty a space. (State lives only for the life of the JVM; the on-disk backend is what survives a process restart.)

Single-writer. Pure runs one writer (docs/storage.md, "The single-writer contract"), so each store is one atom mutated by swap!; reads deref a snapshot and are lock-free. Interleaved writers would not be serializable.

The default in-memory backends for the two storage protocols, selected at KB
construction.  The engine above the protocols never touches a concrete store, so a
KB built on these runs the whole engine with no external dependency; the on-disk
backend (`vaelii.impl.disk`) is the durable alternative.

The record store implements `RecordStore` directly over maps.  The index reuses
`vaelii.impl.kv/KvIndexStore` — the one trie/roots/index implementation — over a
`MemoryKvBackend`: one map keyed by the structured key vectors (equal vectors are
equal keys), holding a `Long` at each counter key and a set at each set key.
`kv-intersect` is a `clojure.set/intersection`; `kv-members` returns the stored set
by reference (no serialization, no copy).

**Durable-within-the-JVM semantics by space number.**  Two KBs constructed over the
same `:space` number must share state, or the persistence/recovery tests (a second KB
restarted over the same databases) would find an empty store.  A process-global
registry keyed by space number provides that: `(memory-record-store {:space 15})` twice
returns records backed by *one* state atom.  `clear-records!` / `clear-index!`
empty a space.  (State lives only for the life of the JVM; the on-disk backend is what
survives a process restart.)

**Single-writer.**  Pure runs one writer (docs/storage.md, "The single-writer
contract"), so each store is one atom mutated by `swap!`; reads deref a snapshot
and are lock-free.  Interleaved *writers* would not be serializable.
raw docstring

*bulk-txn*clj

During a bulk load, a volatile! holding a transient of one MemoryKvBackend's state map. While bound, this backend's writes land on that transient (assoc! — no per-op HAMT path copy) and the whole load is one persistent! at the end, instead of a swap! per fact. nil (the default) leaves every op on the persistent atom exactly as before, so nothing outside a bulk load pays for it — and reads are left untouched in both modes (they read the backing atom), so the query hot path is unchanged. The backing atom is therefore stale for the life of the load: correct only because the sole mid-load reader (note-opposed's [:false b] probe) reads the always -empty negative side, and every real read happens after the closing persistent!. Use with-bulk-writes for a positive/monotonic, distinct load; a corpus with (not …) facts must rebuild-opposed! after it (the atom the opposed set is derived from was stale during the load).

During a bulk load, a `volatile!` holding a **transient** of one MemoryKvBackend's
state map.  While bound, this backend's *writes* land on that transient (`assoc!` —
no per-op HAMT path copy) and the whole load is one `persistent!` at the end, instead
of a `swap!` per fact.  nil (the default) leaves every op on the persistent atom
exactly as before, so nothing outside a bulk load pays for it — and *reads* are left
untouched in both modes (they read the backing atom), so the query hot path is
unchanged.  The backing atom is therefore stale for the life of the load: correct only
because the sole mid-load reader (`note-opposed`'s `[:false b]` probe) reads the always
-empty negative side, and every real read happens after the closing `persistent!`.  Use
`with-bulk-writes` for a positive/monotonic, distinct load; a corpus with `(not …)`
facts must `rebuild-opposed!` after it (the atom the opposed set is derived from was
stale during the load).
raw docstring

memory-index-storeclj

(memory-index-store opts)

An in-memory IndexStoreKvIndexStore over a MemoryKvBackend.

An in-memory `IndexStore` — `KvIndexStore` over a `MemoryKvBackend`.
raw docstring

memory-kv-backendclj

(memory-kv-backend {:keys [space] :or {space 1}})

An in-memory KvBackend. Only :space in opts matters (it selects the shared state atom, so two index stores over the same space number share one map).

An in-memory `KvBackend`.  Only `:space` in `opts` matters (it selects the shared
state atom, so two index stores over the same space number share one map).
raw docstring

memory-record-storeclj

(memory-record-store {:keys [space] :or {space 0}})

An in-memory RecordStore. Only :space in opts matters (it selects the shared state atom).

An in-memory `RecordStore`.  Only `:space` in `opts` matters (it selects the shared
state atom).
raw docstring

with-bulk-writescljmacro

(with-bulk-writes backend & body)

Run body with backend's index writes accumulated on one TRANSIENT of its state map, persisted back in a single step at the end — the write-side fast path for a bulk load (millions of trie assoc!s with no per-op HAMT path copy, one persistent! instead of a swap! per fact). A no-op wrapper unless backend is a MemoryKvBackend, so a non-memory store (disk) just runs body on its own batched path. See *bulk-txn* for the read-staleness contract: a positive/monotonic, distinct load only; a corpus with (not …) facts must rebuild-opposed! after.

Run `body` with `backend`'s index writes accumulated on one TRANSIENT of its state
map, persisted back in a single step at the end — the write-side fast path for a bulk
load (millions of trie `assoc!`s with no per-op HAMT path copy, one `persistent!`
instead of a `swap!` per fact).  A no-op wrapper unless `backend` is a MemoryKvBackend,
so a non-memory store (disk) just runs `body` on its own batched path.  See `*bulk-txn*`
for the read-staleness contract: a positive/monotonic, distinct load only; a corpus
with `(not …)` facts must `rebuild-opposed!` after.
raw 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