Roux.Revision (roux v0.2.2)

Copy Markdown View Source

Global revision counter and per-durability-level change tracking.

The revision is a monotonically increasing integer representing a version of the world. It increments every time any input changes. Durability tracking enables skipping validation of subgraphs rooted in high-durability inputs (see D6).

Durability levels

Durability classifies how often an input changes:

  • :high — almost never (standard library, language definitions)
  • :medium — occasionally (project source files not being edited)
  • :low — constantly (the file currently open in the editor)

During validation, if a query's entire dependency subgraph has minimum durability :high and last_changed(rev, :high) < query.verified_at, the query can skip graph traversal entirely.

Concurrency

All operations are lock-free. advance/2 uses :atomics.add_get/3 for the global counter and :atomics.put/3 for durability tracking. last_changed_at_or_above/2 reads multiple atomics slots without cross-slot atomicity — the worst case is a spurious validation (conservative, not incorrect).

Summary

Functions

Increments the global revision counter and records which durability level changed. Returns the new revision number.

Reads the current global revision. Lock-free.

Returns the revision at which the given durability level last had an input change. Returns 0 if no input at that level has ever changed.

Returns the maximum revision across all durability levels at or above the given level. Used for the durability optimization during validation.

Creates a new revision tracker. Initial revision is 0 (no inputs set yet).

Restores atomics state from a snapshot produced by snapshot/1.

Captures the current state of all atomics for manifest persistence.

Types

durability()

@type durability() :: :high | :medium | :low

revision()

@type revision() :: non_neg_integer()

t()

@type t() :: %Roux.Revision{
  counter: :atomics.atomics_ref(),
  durability: :atomics.atomics_ref()
}

Functions

advance(revision, level)

@spec advance(t(), durability()) :: revision()

Increments the global revision counter and records which durability level changed. Returns the new revision number.

Called when an input is set or modified.

current(revision)

@spec current(t()) :: revision()

Reads the current global revision. Lock-free.

last_changed(revision, level)

@spec last_changed(t(), durability()) :: revision()

Returns the revision at which the given durability level last had an input change. Returns 0 if no input at that level has ever changed.

Used during validation to skip subgraphs.

last_changed_at_or_above(revision, atom)

@spec last_changed_at_or_above(t(), durability()) :: revision()

Returns the maximum revision across all durability levels at or above the given level. Used for the durability optimization during validation.

Higher durability means more stable (changes less often):

  • :low includes :low + :medium + :high changes (all levels).
  • :medium includes :medium + :high changes.
  • :high includes only :high changes.

new()

@spec new() :: t()

Creates a new revision tracker. Initial revision is 0 (no inputs set yet).

restore(revision, state)

@spec restore(t(), %{
  counter: revision(),
  high: revision(),
  medium: revision(),
  low: revision()
}) :: :ok

Restores atomics state from a snapshot produced by snapshot/1.

Used during manifest loading to resume the revision timeline across VM restarts.

snapshot(revision)

@spec snapshot(t()) :: %{
  counter: revision(),
  high: revision(),
  medium: revision(),
  low: revision()
}

Captures the current state of all atomics for manifest persistence.

Returns a plain map that can be serialized with :erlang.term_to_binary/1.