reckon_db_dcb_filter (reckon_db v3.1.1)
View SourceDCB 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
-type match_result() :: false | {true, MaxSeq :: non_neg_integer()}.
-type seqs_provider() :: fun((binary()) -> [non_neg_integer()]).
Functions
-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.
-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.
-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").
-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).