reckon_db_index (reckon_db v5.1.0)

View Source

Generic write-maintained secondary index (opt-in per store).

Turns cross-cutting lookups — "all events with tag X", "all events of type Y", "all events whose metadata key K = V" — from O(total events) scans into O(matches) subtree reads, by maintaining reference entries keyed by the indexed value. This module owns the index layout; nothing else constructs idx paths.

Layout

  [idx, tag,        Tag,       OrderKey] -> EventRef
  [idx, event_type, EventType, OrderKey] -> EventRef
  [idx, meta, Key,  Value,     OrderKey] -> EventRef

OrderKey = pad(epoch_us) | stream_id | pad(version) — globally ordered (subtree iteration yields event/time order) and unique (no two events share stream+version). EventRef = #{stream_id := binary(), version := non_neg_integer()} points at the primary event under the Model C layout; resolution is a point khepri:get via reckon_db_stream_path:event_path/2.

Maintenance

entries/2 returns the {Path, EventRef} pairs an event produces under a store's declared indexes; the append path writes them transactionally with the event (so the index is never partially populated). This module performs no writes itself — it builds paths and reads.

Reads

lookup_* read the relevant subtree, resolve refs to events (dropping refs whose event has since been removed, e.g. by scavenge), and sort by epoch_us. Compound tag all intersects ref sets across tags.

See plans/DESIGN_SECONDARY_INDEX.md.

Summary

Functions

The index entries an event produces under a store's declared indexes. Each entry is a {Path, EventRef} the caller writes transactionally with the event. Empty when no declared index applies.

The reference stored at an index leaf — enough to point-get the primary event under the Model C layout.

Events of any of the given types (union).

Events whose metadata key = value. The sanctioned primitive apps build causation/correlation/saga read models on; the store does not interpret the key.

Events carrying the given tags. any = union, all = intersection. Empty tag list returns [] (no criteria, no results — matches the pre-index scan semantics).

The unique, time-orderable leaf key for an event's index entries.

Types

event/0

-type event() ::
          #event{event_id :: binary(),
                 event_type :: binary(),
                 stream_id :: binary(),
                 version :: non_neg_integer(),
                 data :: map() | binary(),
                 metadata :: map(),
                 tags :: [binary()] | undefined,
                 timestamp :: integer(),
                 epoch_us :: integer(),
                 data_content_type :: binary(),
                 metadata_content_type :: binary(),
                 prev_event_hash :: binary() | undefined,
                 mac :: {KeyId :: non_neg_integer(), MacBytes :: binary()} | undefined,
                 signature :: binary() | undefined}.

event_ref/0

-type event_ref() :: #{stream_id := binary(), version := non_neg_integer()}.

index_decl/0

-type index_decl() :: tags | event_type | {meta, Key :: binary()}.

Functions

entries(Event, Declared)

-spec entries(event(), [index_decl()]) -> [{khepri_path:native_path(), event_ref()}].

The index entries an event produces under a store's declared indexes. Each entry is a {Path, EventRef} the caller writes transactionally with the event. Empty when no declared index applies.

event_ref(Event)

-spec event_ref(event()) -> event_ref().

The reference stored at an index leaf — enough to point-get the primary event under the Model C layout.

lookup_event_types(StoreId, Types)

-spec lookup_event_types(atom(), [binary()]) -> {ok, [event()]} | {error, term()}.

Events of any of the given types (union).

lookup_meta(StoreId, Key, Value)

-spec lookup_meta(atom(), binary(), binary()) -> {ok, [event()]} | {error, term()}.

Events whose metadata key = value. The sanctioned primitive apps build causation/correlation/saga read models on; the store does not interpret the key.

lookup_tags(StoreId, Tags, Match)

-spec lookup_tags(atom(), [binary()], any | all) -> {ok, [event()]} | {error, term()}.

Events carrying the given tags. any = union, all = intersection. Empty tag list returns [] (no criteria, no results — matches the pre-index scan semantics).

order_key(Event)

-spec order_key(event()) -> nonempty_binary().

The unique, time-orderable leaf key for an event's index entries.