March Docs

Vault

Vault module: ETS-like in-memory key-value store.

Vault tables are mutable, process-global hash tables. They are created once (typically at app startup) and shared across all actors without message passing — every actor that holds the same VaultTable handle sees the same data.

Keys can be any plain value: Int, String, Bool, Atom, Tuple, or Ctor. Function values, Pids, and Tasks cannot be used as keys.

Values are arbitrary March values.

Basic operations: Vault.new(name) — create a named table Vault.set(table, key, value) — insert or overwrite Vault.set_ttl(table, key, value, s) — insert with TTL in seconds Vault.get(table, key) — returns Some(value) or None Vault.drop(table, key) — remove a key (no-op if absent) Vault.update(table, key, fn) — apply fn to existing value Vault.size(table) — number of live entries

TTL semantics: expiry is checked lazily on get/update/size. There is no background sweeper thread; expired entries are evicted on access.

Functions

fnallall(table)#

Return all key-value pairs in the table as a list of (String, a) tuples.

fnclearclear(table)#

Remove all entries from the table, leaving it empty.

fndeletedelete(table, key)#

Remove a key from the table. Alias for drop. No-op if the key does not exist.

fndropdrop(table, key)#

Remove a key from the table. No-op if the key does not exist.

fngetget(table, key)#

Look up a key. Returns Some(value) if present and not expired, None otherwise.

fnget_orget_or(table, key, default)#

Return the value at key, or default if absent or expired.

fnhashas(table, key) : Bool#

Return true if key exists in the table and has not expired.

fnincrincr(table, key, delta) : Int#

Atomically add delta to the integer stored at key and return the new value. A missing or non-integer entry is treated as 0. Any existing TTL on the key is preserved. Concurrent increments do not lose updates (unlike a get + set pair).

fnkeyskeys(table)#

Return all live (non-expired) keys in the table as a List(String).

    let t = Vault.new("ex")
    Vault.set(t, "a", 1)
    Vault.set(t, "b", 2)
    List.length(Vault.keys(t))  -- 2

Cost: O(n) where n is the number of entries in the table.
fnnewnew(name)#

Create a new named vault table. Returns an opaque table handle.

fnns_dropns_drop(ns, key)#

Remove a key from a named vault namespace. No-op if the namespace or key is absent.

fnns_getns_get(ns, key)#

Look up a key using a string namespace name. Returns None if the namespace does not exist or the key is absent.

    Vault.ns_get("my_ns", "key")  -- Some(42) or None
fnns_setns_set(ns, key, value)#

Insert or overwrite a key-value pair using a string namespace name. Auto-creates the named vault if it does not yet exist. Useful when you store a namespace string rather than a vault handle.

    Vault.ns_set("my_ns", "key", 42)
fnopenopen(name)#

Open (or create) a named vault table. Returns an existing table if one with this name already exists; otherwise creates a new empty table.

    let rate_table = Vault.open("rate_limits")
fnpush_cappedpush_capped(table, key, value, max) : Unit#

Atomically append value to the list stored at key (newest at the tail) and keep only the last max elements. The whole read-append-trim-write runs under the shard lock, so concurrent pushes to the same bounded buffer do not clobber each other (unlike a get + List.append + set). A missing or non-list entry starts from the empty list; max <= 0 keeps everything. Any existing TTL is preserved. Ideal for fixed-size ring buffers and inboxes.

fnputput(table, key, value)#

Insert or overwrite a key-value pair. Alias for set. Removes any previous TTL.

fnput_newput_new(table, key, value) : Bool#

Atomically insert value at key only if no live entry already exists. Returns true if this call inserted the value, false if a live entry was already present.

Unlike `set`, the check-and-insert is a single atomic step under the shard
lock, so concurrent callers racing on the same key cannot both succeed —
exactly one receives `true`. Use it as a lock or an idempotency claim.
fnput_new_ttlput_new_ttl(table, key, value, ttl_secs) : Bool#

Like put_new, but the claimed entry expires after ttl_secs seconds so a caller that crashes after claiming the key does not hold it forever.

fnsetset(table, key, value)#

Insert or overwrite a key-value pair. Removes any previous TTL.

fnset_ttlset_ttl(table, key, value, ttl_secs)#

Insert or overwrite a key-value pair with a TTL (time-to-live). The entry expires automatically after ttl_secs seconds. Expiry is checked lazily — no background thread required.

fnsizesize(table) : Int#

Return the number of live (non-expired) entries in the table.

fnupdateupdate(table, key, f)#

Apply f to the current value stored at key and replace it with the result. No-op if the key is absent or expired.

fnwhereiswhereis(name)#

Look up a vault table by its registered name. Returns Some(table) if a table with that name exists, None otherwise. Any actor can call this — no handle required.