Liking cljdoc? Tell your friends :D

vaelii.impl.caches

What this process holds beside the stores: one register every derived, droppable structure declares itself in at namespace load, and one read over it (rows). The register requires only config and the logger, so it has no require edge down to a namespace holding a cache. A row's :scope says what :entries counts and :counters says the same for :hits and :misses; a nil :entries marks a scope-bound cache that cannot be counted from outside. A read that throws is reported as a row carrying :error. See docs/caches.md.

What this process holds beside the stores: one register every derived, droppable
structure declares itself in at namespace load, and one read over it (`rows`). The
register requires only `config` and the logger, so it has no require edge down to a
namespace holding a cache. A row's `:scope` says what `:entries` counts and `:counters`
says the same for `:hits` and `:misses`; a nil `:entries` marks a scope-bound cache that
cannot be counted from outside. A read that throws is reported as a row carrying
`:error`. See docs/caches.md.
raw docstring

*open-mark*clj

nil outside a second-route search. Inside one (exc/route-answer), a fn of a thunk answering [value settled?]: the thunk's value, and false when its computation read a route question still open, which makes the value provisional.

nil outside a second-route search.  Inside one (`exc/route-answer`), a fn of a thunk
answering `[value settled?]`: the thunk's value, and false when its computation read a
route question still open, which makes the value provisional.
sourceraw docstring

arm-heap-mark!clj

(arm-heap-mark!)

Set the old generation's collection-usage threshold at pressure-critical and attach a listener that sets heap-critical? when a collection leaves the pool over it; answer the armed pool's name, or nil. kb/open-kb calls it unless vaelii.heap.mark is off. Arms once per JVM and is never disarmed; a collector with no old-generation pool arms nothing. ! because it sets a JVM-wide threshold. See docs/caches.md, "The heap mark".

Set the old generation's collection-usage threshold at `pressure-critical` and attach a
listener that sets `heap-critical?` when a collection leaves the pool over it; answer the
armed pool's name, or nil. `kb/open-kb` calls it unless `vaelii.heap.mark` is off. Arms
once per JVM and is never disarmed; a collector with no old-generation pool arms nothing.
`!` because it sets a JVM-wide threshold. See docs/caches.md, "The heap mark".
sourceraw docstring

assoc-boundedclj

(assoc-bounded m limit k v)

Store v at k in map m, clearing m wholesale when it already holds limit entries. The one bound policy of the plain-map caches; see docs/caches.md, "The bound".

Store `v` at `k` in map `m`, clearing `m` wholesale when it already holds `limit` entries.
The one bound policy of the plain-map caches; see docs/caches.md, "The bound".
sourceraw docstring

clear-cachesclj

(clear-caches kb)
(clear-caches kb {:keys [counters?]})

Drop every cache that offers a clear: {:cleared [{:cache :label :entries} …] :entries total}, ranked like rows. Bare, not !: every entry is derived and no belief moves. Scoped to kb. {:counters? true} also zeroes the process-wide hit and miss counters and kb's derived-state tallies (row-tally); the answer then carries :counters-reset and :tallies-reset ([{:row id …what it held}]). A cache with no :clear is not in the answer. A clear that throws gives its row :error and an entry count of zero.

Drop every cache that offers a clear: `{:cleared [{:cache :label :entries} …] :entries
total}`, ranked like `rows`. Bare, not `!`: every entry is derived and no belief moves.
Scoped to `kb`. `{:counters? true}` also zeroes the process-wide hit and miss counters
and `kb`'s derived-state tallies (`row-tally`); the answer then carries `:counters-reset`
and `:tallies-reset` (`[{:row id …what it held}]`). A cache with no `:clear` is not in the
answer. A clear that throws gives its row `:error` and an entry count of zero.
sourceraw docstring

codesclj

How an event retires a row's entries, the values of a row's :retired-by.

How an event retires a row's entries, the values of a row's `:retired-by`.
sourceraw docstring

compare-retiredclj

(compare-retired t k under v)

While the instrument runs, compare v, recomputed at key k of the row whose tally is t, with an earlier value there (compared). under nil compares with the entry an event retired at k, which the instrument keeps, and takes it: for a row whose entry is the value read. A non-nil under compares with the last value computed at k when that was computed under another value of under, and keeps v under under in its place: for a row whose entries are keyed by such a value. A value is kept as its hash and compared by it, so the instrument holds no closure the cache itself has evicted.

While the instrument runs, compare `v`, recomputed at key `k` of the row whose tally is
`t`, with an earlier value there (`compared`).  `under` nil compares with the entry an
event retired at `k`, which the instrument keeps, and takes it: for a row whose entry is
the value read.  A non-nil `under` compares with the last value computed at `k` when
that was computed under another value of `under`, and keeps `v` under `under` in its
place: for a row whose entries are keyed by such a value.  A value is kept as its hash
and compared by it, so the instrument holds no closure the cache itself has evicted.
sourceraw docstring

comparedclj

(compared t same?)

While the instrument runs, count on tally t a miss compared with the value it replaced, and a spurious one when same?.

While the instrument runs, count on tally `t` a miss compared with the value it
replaced, and a spurious one when `same?`.
sourceraw docstring

derived-stateclj

(derived-state)
(derived-state kb)

The register as data: {:rows [row …] :events [event …] :edges [[reader read] …]}. A row is its descriptor less :value, ordered by id. With kb, a row that is a registered cache also carries that cache's :entries.

The register as data: `{:rows [row …] :events [event …] :edges [[reader read] …]}`.
A row is its descriptor less `:value`, ordered by id.  With `kb`, a row that is a
registered cache also carries that cache's `:entries`.
sourceraw docstring

derived-valueclj

(derived-value kb id)

Row id's current value in kb: its :value called on kb, else the values at its :at locations. Nil for a row that cannot be read from outside its pass.

Row `id`'s current value in `kb`: its `:value` called on `kb`, else the values at its
`:at` locations.  Nil for a row that cannot be read from outside its pass.
sourceraw docstring

eventsclj

The closed set of write events that move derived state, {event {:n n :at [var-symbol …] :names what-the-event-names}}. :n numbers the event in the generated table, and :at names the vars the event passes through, each called through its var, so a test can wrap them (derived_state_test).

The closed set of write events that move derived state, `{event {:n n :at [var-symbol
…] :names what-the-event-names}}`.  `:n` numbers the event in the generated table, and
`:at` names the vars the event passes through, each called through its var, so a test
can wrap them (`derived_state_test`).
sourceraw docstring

get-or!clj

(get-or! memo k f)

The value at k in the map held by volatile memo, else (f), stored and returned. A computed nil or false counts as a hit.

The value at `k` in the map held by volatile `memo`, else `(f)`, stored and returned.
A computed nil or false counts as a hit.
sourceraw docstring

grow!clj

(grow!)

Raise pressure one step back toward the operator's scale, and answer the new pressure. No trim: growing a bound drops nothing, it only lets the next store hold more.

Raise pressure one step back toward the operator's scale, and answer the new pressure.  No
trim: growing a bound drops nothing, it only lets the next store hold more.
sourceraw docstring

heap-critical?clj

(heap-critical?)

Did the last collection read leave the old generation over pressure-critical? Set by the heap mark's threshold notification and by the memory guard's listener; false when neither is armed (docs/caches.md, "The heap mark").

One volatile read while the flag is clear. While it is set, the call reads the armed pool (pool-fraction) and clears the flag when the reading is under the mark, under the guard as without it. The guard sets the flag from a young collection's after-usage, which counts dead tenured objects, so the pool's own reading decides.

Did the last collection read leave the old generation over `pressure-critical`?  Set by
the heap mark's threshold notification and by the memory guard's listener; false when
neither is armed (docs/caches.md, "The heap mark").

One volatile read while the flag is clear.  While it is set, the call reads the armed
pool (`pool-fraction`) and clears the flag when the reading is under the mark, under the
guard as without it.  The guard sets the flag from a young collection's after-usage,
which counts dead tenured objects, so the pool's own reading decides.
sourceraw docstring

held-if-settledclj

(held-if-settled compute put!)

(compute), handed to put! (which answers the value it holds) unless its computation read a route question still open (*open-mark*): a provisional value is answered and not held, so no entry depends on which question a read asked first.

`(compute)`, handed to `put!` (which answers the value it holds) unless its computation
read a route question still open (`*open-mark*`): a provisional value is answered and
not held, so no entry depends on which question a read asked first.
sourceraw docstring

hitclj

(hit t)

Count a hit on tally t, when there is one.

Count a hit on tally `t`, when there is one.
sourceraw docstring

image-fieldsclj

(image-fields section)

The Reasoning fields a row imaged as section (:state or :cache) is located in by its first :at location, sorted.

The `Reasoning` fields a row imaged as `section` (`:state` or `:cache`) is located in
by its first `:at` location, sorted.
sourceraw docstring

install-memory-guard!clj

(install-memory-guard! {:keys [kbs]})

Attach a post-collection listener that moves the cache profile's :pressure with how full the old generation is: over pressure-high it shrinks the caches, under pressure-low it grows them back. :kbs is a thunk answering the live KB records whose per-KB caches the trim reaches. Idempotent: a second call replaces the :kbs thunk and arms no second listener (guard-lifecycle). A JVM whose collectors emit no such notification keeps pressure at 1.0. ! because it attaches to the process's collectors; uninstall-memory-guard! detaches.

Attach a post-collection listener that moves the cache profile's `:pressure` with how full
the old generation is: over `pressure-high` it shrinks the caches, under `pressure-low` it
grows them back. `:kbs` is a thunk answering the live KB records whose per-KB caches the
trim reaches. Idempotent: a second call replaces the `:kbs` thunk and arms no second
listener (`guard-lifecycle`). A JVM whose collectors emit no such notification keeps
pressure at 1.0. `!` because it attaches to the process's collectors;
`uninstall-memory-guard!` detaches.
sourceraw docstring

kindsclj

What a row is: :cache (droppable without moving a belief), :index (kept at the write, rebuilt only by recover), :journal, :queue, :counter, :pass.

What a row is: `:cache` (droppable without moving a belief), `:index` (kept at the
write, rebuilt only by recover), `:journal`, `:queue`, `:counter`, `:pass`.
sourceraw docstring

limit-ofclj

(limit-of id default)

The bound cache id enforces now, given its shipped default default. An override is an absolute limit that replaces default; :scale leaves it alone and :pressure still multiplies it. A default with no override is multiplied by :scale and :pressure. The result is floored at min-limit and saturates at Long/MAX_VALUE. A nil default with no override stays nil. Read on a cache's store path and by its rows entry, so the bound enforced and the bound reported are one number.

The bound cache `id` enforces now, given its shipped default `default`. An override is an
absolute limit that replaces `default`; `:scale` leaves it alone and `:pressure` still
multiplies it. A `default` with no override is multiplied by `:scale` and `:pressure`.
The result is floored at `min-limit` and saturates at `Long/MAX_VALUE`. A nil `default`
with no override stays nil. Read on a cache's store path and by its `rows` entry, so the
bound enforced and the bound reported are one number.
sourceraw docstring

limit-thunkclj

(limit-thunk id default)

#(limit-of id default), for a descriptor's :limit, so its rows entry reports the effective bound rather than the shipped default. A default that is a var, such as #'*a-dynamic-limit*, is dereferenced on each call, so the row reads the current binding. See register-cache.

`#(limit-of id default)`, for a descriptor's `:limit`, so its `rows` entry reports the
effective bound rather than the shipped default.  A `default` that is a var, such as
`#'*a-dynamic-limit*`, is dereferenced on each call, so the row reads the current
binding.  See `register-cache`.
sourceraw docstring

lru-clear!clj

(lru-clear! {:keys [map weight]})

Empty lru, and answer how many entries went.

Empty `lru`, and answer how many entries went.
sourceraw docstring

lru-evict!clj

(lru-evict! {:keys [map weight weigh]} ks)

Drop the entries of lru at the keys ks, and answer how many went.

Drop the entries of `lru` at the keys `ks`, and answer how many went.
sourceraw docstring

lru-evict-if!clj

(lru-evict-if! {:keys [map weight weigh]} pick? drop?)

Drop every entry of lru whose key both pick? and drop? hold of, and answer how many went. pick? runs under the map's monitor and must not read lru; drop? runs over the keys pick? kept, outside it, so it may.

Drop every entry of `lru` whose key both `pick?` and `drop?` hold of, and answer how many
went.  `pick?` runs under the map's monitor and must not read `lru`; `drop?` runs over
the keys `pick?` kept, outside it, so it may.
sourceraw docstring

lru-getclj

(lru-get {:keys [map tally]} k)

The value lru holds at k, or nil, marking it the most recently used; a hit or a miss on its tally.

The value `lru` holds at `k`, or nil, marking it the most recently used; a hit or a
miss on its tally.
sourceraw docstring

lru-put!clj

(lru-put! {:keys [map weight weigh limit] :as lru} k v)

Hold v at k in lru, evicting the least recently used entries until the weight is back under the bound, and answer v. A value heavier than the whole bound is evicted by its own insertion: answered, and not held.

Hold `v` at `k` in `lru`, evicting the least recently used entries until the weight is
back under the bound, and answer `v`.  A value heavier than the whole bound is evicted
by its own insertion: answered, and not held.
sourceraw docstring

lru-sizeclj

(lru-size {:keys [map]})

How many entries lru holds.

How many entries `lru` holds.
sourceraw docstring

lru-trim!clj

(lru-trim! {:keys [map] :as lru} target)

Evict from the cold end of lru until it weighs at most target; answer how many entries went. The weighted cache's :trim: the recent half survives a trim.

Evict from the cold end of `lru` until it weighs at most `target`; answer how many
entries went.  The weighted cache's `:trim`: the recent half survives a trim.
sourceraw docstring

lru-weightclj

(lru-weight {:keys [map weight]})

What lru holds, in its weight's unit.

What `lru` holds, in its weight's unit.
sourceraw docstring

memory-guardclj

(memory-guard)

Whether the guard is attached to the collectors, the pressure it currently holds, and the pool the heap mark armed: {:installed? bool :pressure p :heap-mark pool-name-or-nil}. Pressure below 1.0 says the guard has shrunk the caches under a heap it is watching fill.

Whether the guard is attached to the collectors, the pressure it currently holds, and the
pool the heap mark armed: `{:installed? bool :pressure p :heap-mark pool-name-or-nil}`.
Pressure below 1.0 says the guard has shrunk the caches under a heap it is watching fill.
sourceraw docstring

missclj

(miss t)

Count a miss on tally t, when there is one, whose time spent adds.

Count a miss on tally `t`, when there is one, whose time `spent` adds.
sourceraw docstring

missedclj

(missed t start)

Count a miss on tally t, when there is one, whose recompute started at start (System/nanoTime).

Count a miss on tally `t`, when there is one, whose recompute started at `start`
(`System/nanoTime`).
sourceraw docstring

on-everyclj

(on-every code)

{event code} for every event in events: the :retired-by of a row any write retires, such as one keyed by the change clock.

`{event code}` for every event in `events`: the `:retired-by` of a row any write
retires, such as one keyed by the change clock.
sourceraw docstring

override-problemclj

(override-problem id)

Why an override cannot move registered cache id's bound, as a phrase, or nil when it can. An override moves a bound exactly when the descriptor's :limit is the limit-thunk for id. A nil-bound cache and a bound outside the profile (the symbol pool's and the scoped-closure budget's dynamic vars) fail, and set-cache-limit refuses an override on either. Nil for an id nothing has registered (registered?).

Why an override cannot move registered cache `id`'s bound, as a phrase, or nil when it can.
An override moves a bound exactly when the descriptor's `:limit` is the `limit-thunk` for
`id`. A nil-bound cache and a bound outside the profile (the symbol pool's and the
scoped-closure budget's dynamic vars) fail, and `set-cache-limit` refuses an override on
either. Nil for an id nothing has registered (`registered?`).
sourceraw docstring

pressure-responseclj

(pressure-response frac pressure)

What a post-collection old-generation frac (used over max) asks of the caches at the current pressure: :shrink over pressure-high, :grow under pressure-low while pressure is still below the operator's ceiling of 1.0, else :hold. A pure function of the two readings, so the decision is tested without a heap that is actually full.

What a post-collection old-generation `frac` (used over max) asks of the caches at the
current `pressure`: `:shrink` over `pressure-high`, `:grow` under `pressure-low` while
pressure is still below the operator's ceiling of 1.0, else `:hold`.  A pure function of
the two readings, so the decision is tested without a heap that is actually full.
sourceraw docstring

profileclj

(profile)

The cache profile in force: {:scale <operator multiplier> :pressure <guard multiplier> :overrides {cache-id limit}}. A cache's effective bound is its shipped default times :scale times :pressure (an override replaces the default but the two multipliers still apply, so the guard can shrink an overridden cache under memory pressure).

The cache profile in force: `{:scale <operator multiplier> :pressure <guard multiplier>
:overrides {cache-id limit}}`.  A cache's effective bound is its shipped default times
`:scale` times `:pressure` (an override replaces the default but the two multipliers still
apply, so the guard can shrink an overridden cache under memory pressure).
sourceraw docstring

read-throughclj

(read-through cache limit k compute)

The value at k in the map held by atom cache, else (compute) — stored under assoc-bounded's bound, and returned.

find rather than get, so a computed nil is a hit rather than a miss recomputed forever. compute runs outside the swap! because it is the expensive half and a swap! retry must not run it twice: two callers racing one key both compute and both store, and the second store is a no-op — the trade a memo of derived values wants over holding a lock across the computation.

The value at `k` in the map held by atom `cache`, else `(compute)` — stored under
`assoc-bounded`'s bound, and returned.

`find` rather than `get`, so a computed `nil` is a hit rather than a miss recomputed
forever.  `compute` runs outside the `swap!` because it is the expensive half and a
`swap!` retry must not run it twice: two callers racing one key both compute and both
store, and the second store is a no-op — the trade a memo of derived values wants over
holding a lock across the computation.
sourceraw docstring

recomputedcljmacro

(recomputed t & body)

body's value, counted on tally t as a miss with the time body took.

`body`'s value, counted on tally `t` as a miss with the time `body` took.
sourceraw docstring

register-cacheclj

(register-cache {:keys [cache] :as descriptor})

Declare that this namespace holds a cache. Called at namespace load, once per cache. Bare, not !: it installs a descriptor the next load replaces. The descriptor (docs/caches.md, "The register"):

:cache keyword, unique across the process :label display name :scope :kb or :process, what :entries counts :unit what one entry is :limit entries held before a wholesale clear, nil for a cache bounded by something else (say what in :note); a thunk where the bound is a dynamic var or profile-scaled (limit-thunk) :counters :kb, :process, or nil :note one line: what it holds and what retires an entry :read (fn [kb]) -> {:entries n :hits h :misses m}, a key absent where there is no number. O(1). A :limit it answers replaces the descriptor's in the row. :clear (fn [kb]) -> entries dropped, or absent. Scoped to kb. :trim (fn [kb target]) -> entries dropped, or absent: the partial drop the memory-pressure guard uses (trim-map! for a plain map) :reset-counters (fn [kb]) -> the counters as they stood, or absent

Declare that this namespace holds a cache. Called at namespace load, once per cache. Bare,
not `!`: it installs a descriptor the next load replaces. The descriptor
(docs/caches.md, "The register"):

  :cache     keyword, unique across the process
  :label     display name
  :scope     :kb or :process, what `:entries` counts
  :unit      what one entry is
  :limit     entries held before a wholesale clear, nil for a cache bounded by something
             else (say what in `:note`); a thunk where the bound is a dynamic var or
             profile-scaled (`limit-thunk`)
  :counters  :kb, :process, or nil
  :note      one line: what it holds and what retires an entry
  :read      (fn [kb]) -> {:entries n :hits h :misses m}, a key absent where there is no
             number. O(1). A `:limit` it answers replaces the descriptor's in the row.
  :clear     (fn [kb]) -> entries dropped, or absent. Scoped to `kb`.
  :trim      (fn [kb target]) -> entries dropped, or absent: the partial drop the
             memory-pressure guard uses (`trim-map!` for a plain map)
  :reset-counters (fn [kb]) -> the counters as they stood, or absent
sourceraw docstring

register-derivedclj

(register-derived descriptor)

Declare a row of derived state. Called at namespace load, once per row; the loading namespace is recorded as its :owner. The descriptor (docs/caches.md, "The derived-state register"):

:id :label the row's id and name :kind one of kinds :holds-content? true when an entry holds a sentence the KB holds or would hold that no store holds; lein lint's derived check fails such a row unless its allowlist names it :keyed-by what an entry is keyed by :reads ids of the rows and stores it is computed from :retired-by {event code}: each event in events that retires entries, and how :computed :write, :settle, :read or :pass :imaged? which section of a reasoning image carries it, or false :at its locations, each [reasoning-field & keys]; a reader symbol in a key is written ::caches/reader :var :cache the var holding it; the register-cache id it is also registered under :bound its bound as a phrase, where :cache gives none :value (fn [kb]) -> its current value, where :at does not reach it :covered-by {:perf [check …] :perf-ab [probe …]} that fail when a recompute at the read replaces the row; the derived check requires it of the files it lists :live (fn [kb]) -> how many entries are current, for a row whose retired entries stay held until a read; start-tally! counts a retirement as a fall in it :note one line

Declare a row of derived state. Called at namespace load, once per row; the loading
namespace is recorded as its `:owner`. The descriptor (docs/caches.md, "The derived-state
register"):

  :id :label     the row's id and name
  :kind          one of `kinds`
  :holds-content? true when an entry holds a sentence the KB holds or would hold that no
                 store holds; `lein lint`'s `derived` check fails such a row unless its
                 allowlist names it
  :keyed-by      what an entry is keyed by
  :reads         ids of the rows and `stores` it is computed from
  :retired-by    `{event code}`: each event in `events` that retires entries, and how
  :computed      :write, :settle, :read or :pass
  :imaged?       which section of a reasoning image carries it, or false
  :at            its locations, each `[reasoning-field & keys]`; a reader symbol in a key
                 is written `::caches/reader`
  :var :cache    the var holding it; the `register-cache` id it is also registered under
  :bound         its bound as a phrase, where `:cache` gives none
  :value         `(fn [kb])` -> its current value, where `:at` does not reach it
  :covered-by    `{:perf [check …] :perf-ab [probe …]}` that fail when a recompute at the
                 read replaces the row; the `derived` check requires it of the files it lists
  :live          `(fn [kb])` -> how many entries are current, for a row whose retired entries
                 stay held until a read; `start-tally!` counts a retirement as a fall in it
  :note          one line
sourceraw docstring

registered?clj

(registered? id)

Is id a cache registered in this process now? A membership test rather than a refusal, because the register fills lazily: a cache is registered when its namespace loads, and a qualitative calculus or the metric-time reasoner may not be loaded yet. So set-limit reads this to warn on an id nothing has registered rather than to refuse it — a not-yet-loaded cache would take the override when it registers, where a refusal would reject the very configuration a bulk load sets up before touching the calculus.

Is `id` a cache registered in *this* process now?  A membership test rather than a
refusal, because the register fills lazily: a cache is registered when its namespace
loads, and a qualitative calculus or the metric-time reasoner may not be loaded yet.  So
`set-limit` reads this to *warn* on an id nothing has registered rather than to refuse
it — a not-yet-loaded cache would take the override when it registers, where a refusal would
reject the very configuration a bulk load sets up before touching the calculus.
sourceraw docstring

reset-profileclj

(reset-profile)

Restore the configured profile — the VAELII_CACHE_SCALE scale, pressure 1.0 and no overrides — and return it.

Restore the configured profile — the `VAELII_CACHE_SCALE` scale, pressure 1.0 and no
overrides — and return it.
sourceraw docstring

retired-entriesclj

(retired-entries before after)

The [key value] entries before held that after drops or replaces: a map's by key, a set's members, a vector of locations' per location, else [[nil before]] when the two differ. A nil before held no entry, so a structure made where none was retires nothing.

The `[key value]` entries `before` held that `after` drops or replaces: a map's by key,
a set's members, a vector of locations' per location, else `[[nil before]]` when the
two differ.  A nil `before` held no entry, so a structure made where none was retires
nothing.
sourceraw docstring

row-tallyclj

(row-tally kb id)

Row id's tally in kb, or nil: held by the structure at the row's first :at location, else by that location's Reasoning field. A row held by the process rather than by a KB has none, since its tally would count every KB's reads.

Row `id`'s tally in `kb`, or nil: held by the structure at the row's first `:at`
location, else by that location's `Reasoning` field.  A row held by the process rather
than by a KB has none, since its tally would count every KB's reads.
sourceraw docstring

rowsclj

(rows kb)

Every registered cache, read against kb, ranked by entries descending with ties on the cache's name; a row that cannot be counted sorts last. A row is the descriptor's static half (:cache :label :scope :unit :limit :counters :note) plus what its :read answered, :hit-rate and :clearable?; the function slots are dropped. A read that throws costs its own row, which carries :error. A cache a derived-state row counts (row-tally) reports that row's tally: :hits and :misses where its :read gives none, :recompute-ns, :retired, :compared, :spurious, :evicted, with :counters :kb.

Every registered cache, read against `kb`, ranked by entries descending with ties on the
cache's name; a row that cannot be counted sorts last. A row is the descriptor's static
half (`:cache :label :scope :unit :limit :counters :note`) plus what its `:read` answered,
`:hit-rate` and `:clearable?`; the function slots are dropped. A read that throws costs
its own row, which carries `:error`. A cache a derived-state row counts (`row-tally`)
reports that row's tally: `:hits` and `:misses` where its `:read` gives none,
`:recompute-ns`, `:retired`, `:compared`, `:spurious`, `:evicted`, with `:counters :kb`.
sourceraw docstring

set-limitclj

(set-limit id n)

Override cache id's bound with n regardless of scale, or clear the override when n is nil, and return the profile. A caller who names both a cache and a number has stated the bound it wants, so the scale does not then move it.

Override cache `id`'s bound with `n` regardless of scale, or clear the override when `n`
is nil, and return the profile.  A caller who names both a cache and a number has stated the bound it
wants, so the scale does not then move it.
sourceraw docstring

set-scaleclj

(set-scale x)

Multiply every count-bounded cache's shipped limit by x, and return the profile. Reversible — 1.0 restores the shipped bounds — so bare, not !, as set-solver is: it installs a setting the next cache store reads, and no belief moves.

Multiply every count-bounded cache's shipped limit by `x`, and return the profile.
Reversible — `1.0` restores the shipped bounds — so bare, not `!`, as `set-solver` is:
it installs a setting the next cache store reads, and no belief moves.
sourceraw docstring

shrink!clj

(shrink! kbs)

Lower pressure one step and trim the caches to the new, lower bound; answer {:pressure p :dropped n}. Public so the guard's response can be driven in a test without a heap that is actually full.

Lower pressure one step and trim the caches to the new, lower bound; answer
`{:pressure p :dropped n}`.  Public so the guard's response can be driven in a test without
a heap that is actually full.
sourceraw docstring

spentclj

(spent t start)

Add the time since start (System/nanoTime) to tally t's recompute time, for a miss counted already whose recompute ended later.

Add the time since `start` (`System/nanoTime`) to tally `t`'s recompute time, for a
miss counted already whose recompute ended later.
sourceraw docstring

start-tally!clj

(start-tally! kb)
(start-tally! kb {:keys [rows observe events]})

Run the event instrument over kb, or over the first KB an event is handed when kb is nil, until stop-tally!. Every var events names is wrapped process-wide; one instrument runs at a time, and a second start refuses. Each event's firings, and the entries it retired of each row, are counted: in derived-state's :events while it runs, and in each row's tally (:retired). A miss compares what it recomputed while it runs (compare-retired).

opts: :rows, the row ids to read (default every row not of kind :pass), for a KB whose rows are too large to read at every event; :observe, (fn [row charged]) called for each row that moved with the set of events it is charged to. Without :observe, a row with :live is counted by it alone and its value is not read. :events, the event ids to wrap (default every one): each wrapped call reads the rows twice, so a KB whose write fires an event a million times leaves that event out.

Run the event instrument over `kb`, or over the first KB an event is handed when `kb` is
nil, until `stop-tally!`.  Every var `events` names is wrapped process-wide; one
instrument runs at a time, and a second start refuses.  Each event's firings, and the
entries it retired of each row, are counted: in `derived-state`'s `:events` while it
runs, and in each row's tally (`:retired`).  A miss compares what it recomputed while
it runs (`compare-retired`).

`opts`: `:rows`, the row ids to read (default every row not of kind `:pass`), for a KB
whose rows are too large to read at every event; `:observe`, `(fn [row charged])`
called for each row that moved with the set of events it is charged to.  Without
`:observe`, a row with `:live` is counted by it alone and its value is not read.
`:events`, the event ids to wrap (default every one): each wrapped call reads the rows
twice, so a KB whose write fires an event a million times leaves that event out.
sourceraw docstring

stop-tally!clj

(stop-tally!)

Stop the instrument and restore every var it wrapped; answer {:kb :fired {event n} :retired {[event row] n}}, or nil when none runs.

Stop the instrument and restore every var it wrapped; answer `{:kb :fired {event n}
:retired {[event row] n}}`, or nil when none runs.
sourceraw docstring

storesclj

The ids a row's :reads may name beside other rows' ids.

The ids a row's `:reads` may name beside other rows' ids.
sourceraw docstring

talliedclj

(tallied r ids)

r, a reference, answered with a fresh tally for each row id of ids in its metadata.

`r`, a reference, answered with a fresh tally for each row id of `ids` in its metadata.
sourceraw docstring

tallyclj

(tally)

A zeroed tally.

A zeroed tally.
sourceraw docstring

tally-mapclj

(tally-map t)

Tally t as {slot n}, or nil for no tally.

Tally `t` as `{slot n}`, or nil for no tally.
sourceraw docstring

tally-ofclj

(tally-of x id)

Row id's tally held by x: a weighted LRU's own, or the one tallied put in x's metadata; nil when x holds none.

Row `id`'s tally held by `x`: a weighted LRU's own, or the one `tallied` put in `x`'s
metadata; nil when `x` holds none.
sourceraw docstring

tally-rankingclj

(tally-ranking kb)

The rows of kb that hold a tally, ranked for the consolidation plan, as {:by-spurious-cost [row …] :by-hit-rate [row …]}. A row is {:row :recompute-ns :hit-rate :spurious-fraction :spurious-cost}: :spurious-fraction is :spurious over :compared, nil when nothing was compared, and :spurious-cost is :recompute-ns times it. :by-spurious-cost is descending, a row with no fraction last; :by-hit-rate is ascending, a row with no lookup last. Ties are broken on the row's name.

The rows of `kb` that hold a tally, ranked for the consolidation plan, as `{:by-spurious-cost
[row …] :by-hit-rate [row …]}`.  A row is `{:row :recompute-ns :hit-rate
:spurious-fraction :spurious-cost}`: `:spurious-fraction` is `:spurious` over `:compared`,
nil when nothing was compared, and `:spurious-cost` is `:recompute-ns` times it.
`:by-spurious-cost` is descending, a row with no fraction last; `:by-hit-rate` is
ascending, a row with no lookup last.  Ties are broken on the row's name.
sourceraw docstring

tally-slotsclj

The slots of a tally, in order. :retired is filled by start-tally!, :compared and :spurious only while it runs, :evicted by a weighted LRU.

The slots of a tally, in order.  `:retired` is filled by `start-tally!`, `:compared` and
`:spurious` only while it runs, `:evicted` by a weighted LRU.
sourceraw docstring

tallying?clj

(tallying?)

Is the instrument running, so that a miss compares what it recomputed?

Is the instrument running, so that a miss compares what it recomputed?
sourceraw docstring

trim-map!clj

(trim-map! a target)

Drop entries from the plain map held by atom a until it holds at most target, keeping the target that iteration reaches first, and answer how many went. The kept set is arbitrary rather than the most recent — a plain map records no recency — which is the trade against a wholesale clear: half the entries survive a trim where none survive a clear, so the reads they serve are not all recomputed at once. A cache whose entries carry recency or a different shape supplies its own :trim rather than calling this.

Drop entries from the plain map held by atom `a` until it holds at most `target`, keeping
the `target` that iteration reaches first, and answer how many went.  The kept set is
arbitrary rather than the most recent — a plain map records no recency — which is the trade
against a wholesale clear: half the entries survive a trim where none survive a clear, so
the reads they serve are not all recomputed at once.  A cache whose entries carry recency
or a different shape supplies its own `:trim` rather than calling this.
sourceraw docstring

uninstall-memory-guard!clj

(uninstall-memory-guard!)

Detach the guard's listener from every collector it armed and restore pressure to 1.0; answer the guard state. Safe when nothing is installed.

Detach the guard's listener from every collector it armed and restore pressure to 1.0;
answer the guard state.  Safe when nothing is installed.
sourceraw docstring

value-atclj

(value-at kb [field & path])

The value at [field & keys] in kb's Reasoning value: the field's atom dereferenced, then keys followed into it.

The value at `[field & keys]` in `kb`'s `Reasoning` value: the field's atom
dereferenced, then `keys` followed into it.
sourceraw docstring

weighted-lruclj

(weighted-lru limit weigh)

An empty weighted LRU. limit is a thunk answering the most weight it holds — a limit-thunk, so the profile's scale and the memory guard's pressure move it — and weigh answers an entry's weight from its value. Read and written through lru-get and lru-put!; an access-ordered map reorders on a read, so every operation holds its monitor, uncontended on a single writer.

An empty weighted LRU.  `limit` is a thunk answering the most weight it holds — a
`limit-thunk`, so the profile's scale and the memory guard's pressure move it — and
`weigh` answers an entry's weight from its value.  Read and written through `lru-get`
and `lru-put!`; an access-ordered map reorders on a read, so every operation holds its
monitor, uncontended on a single writer.
sourceraw docstring

with-tallyclj

(with-tally kb opts f)

(f) run under the instrument over kb (start-tally! with opts); answers what stop-tally! answers.

`(f)` run under the instrument over `kb` (`start-tally!` with `opts`); answers what
`stop-tally!` answers.
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