reckon_db_dcb_filter (reckon_db v3.1.1)

View Source

DCB tag-filter evaluation inside Khepri transactions.

Evaluates a tag_filter() against the tag index (/by_tag/Tag/SeqKey subtree) and returns either the set of matching seqs OR an answer to "does any matching event have seq above Cutoff?".

Two layers: - match_seqs/2: pure-by-construction set algebra over seqs. The only side effect is the seqs-provider function, which the caller supplies. Test with a hardcoded mock provider. - match_any_above_cutoff/2: wraps match_seqs with the cutoff comparison and the production seqs-provider that reads from Khepri via khepri_tx:get_many/1. Must be called from inside a khepri:transaction/2 body.

The tag_filter() type is defined here for now. P3.3 will move it to reckon-gater/include/reckon_gater_types.hrl as the canonical home; this module will then re-export from there.

Summary

Functions

"Does any matching event have seq > Cutoff?" using the production Khepri-backed seqs provider. Call from inside khepri:transaction/2.

Pure-testable variant: the caller supplies the seqs provider.

Set of seqs whose events match the filter, per-event semantics.

The production seqs provider. Reads the tag index inside a transaction. MUST be called from inside khepri:transaction/2.

Types

match_result/0

-type match_result() :: false | {true, MaxSeq :: non_neg_integer()}.

seqs_provider/0

-type seqs_provider() :: fun((binary()) -> [non_neg_integer()]).

Functions

match_any_above_cutoff(Filter, Cutoff)

-spec match_any_above_cutoff(reckon_gater_types:tag_filter(), reckon_gater_types:seq_cutoff()) ->
                                match_result().

"Does any matching event have seq > Cutoff?" using the production Khepri-backed seqs provider. Call from inside khepri:transaction/2.

Cutoff = -1 means "I saw nothing yet" — ANY matching event triggers a conflict. Cutoff = N (>= 0) means "I saw events through seq N" — only seqs > N trigger a conflict.

match_any_above_cutoff(Filter, Cutoff, Provider)

-spec match_any_above_cutoff(reckon_gater_types:tag_filter(),
                             reckon_gater_types:seq_cutoff(),
                             seqs_provider()) ->
                                match_result().

Pure-testable variant: the caller supplies the seqs provider.

match_seqs(_, Provider)

-spec match_seqs(reckon_gater_types:tag_filter(), seqs_provider()) -> sets:set(non_neg_integer()).

Set of seqs whose events match the filter, per-event semantics.

Algebra: any_of(Tags) = union(seqs_for_tag(T) | T in Tags) all_of(Tags) = intersection(seqs_for_tag(T) | T in Tags) or_(Filters) = union(match_seqs(F) | F in Filters) and_(Filters) = intersection(match_seqs(F) | F in Filters)

Empty tag/filter lists yield the empty set (no event matches "nothing").

seqs_for_tag(Tag)

-spec seqs_for_tag(binary()) -> [non_neg_integer()].

The production seqs provider. Reads the tag index inside a transaction. MUST be called from inside khepri:transaction/2.

Returns the list of seqs indexed under Tag. Empty list if the tag has no entries (the path doesn't exist).