reckon_db_ccc_filter (reckon_db v5.5.1)
View SourceCCC (Command Context Consistency) filter evaluation inside Khepri transactions.
Evaluates a tag_filter() against the full set of CCC indexes — tags, event types, single-field payload, and composite payload hash — and returns either the set of matching seqs or an answer to "does any matching event have seq above Cutoff?".
This module supersedes reckon_db_dcb_filter (removed in 5.4.0). CCC is a superset of DCB: all tag/event_type filters still work; payload_match and payload_hash_match add CCC payload predicate support.
Two layers: - match_seqs/2: pure set algebra over seqs. Side effects are confined to 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 canonical in reckon_gater_types.hrl (reckon-gater 3.5.0+). Use it via the include; do NOT redefine here.
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.
Rewrite a tag_filter to replace {payload_hash_match, Keys, Values} with {payload_hash_match_pre, Hash}, where Hash is the pre-computed SHA-256 of the sorted [{Key,Value}] pair list.
Look up seqs by event type. Reads the event-type index inside a transaction. Returns the list of seqs for EventType. Empty list if none.
Look up seqs by single payload field value. Reads the payload index [by_payload, Key, Value, *] inside a transaction.
Look up seqs by pre-computed composite payload hash. Reads the payload hash index [by_payload_hash, Hash, *] inside a transaction.
Look up seqs by tag. Reads the tag index inside a transaction. Returns the list of seqs indexed under Tag. Empty list if no entries.
Types
-type match_result() :: false | {true, MaxSeq :: 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) event_type(Type) = seqs_for_event_type(Type) payload_match(K, V) = seqs_for_payload(K, V) payload_hash_match_pre(H)= seqs_for_payload_hash_pre(H) 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 preprocess_filter(reckon_gater_types:tag_filter()) -> reckon_gater_types:tag_filter().
Rewrite a tag_filter to replace {payload_hash_match, Keys, Values} with {payload_hash_match_pre, Hash}, where Hash is the pre-computed SHA-256 of the sorted [{Key,Value}] pair list.
MUST be called OUTSIDE a Khepri transaction. The hash computation calls crypto:hash/2 (a NIF); Horus cannot extract NIF calls into the portable transaction form that Ra replicates to all cluster members.
Filters without payload_hash_match are returned unchanged.
-spec seqs_for_event_type(binary()) -> [non_neg_integer()].
Look up seqs by event type. Reads the event-type index inside a transaction. Returns the list of seqs for EventType. Empty list if none.
-spec seqs_for_payload(binary(), binary()) -> [non_neg_integer()].
Look up seqs by single payload field value. Reads the payload index [by_payload, Key, Value, *] inside a transaction.
-spec seqs_for_payload_hash_pre(binary()) -> [non_neg_integer()].
Look up seqs by pre-computed composite payload hash. Reads the payload hash index [by_payload_hash, Hash, *] inside a transaction.
The Hash must be pre-computed OUTSIDE the transaction via reckon_db_ccc_paths:payload_combo_hash/2 — this function is called inside the transaction and must not perform any crypto calls.
-spec seqs_for_tag(binary()) -> [non_neg_integer()].
Look up seqs by tag. Reads the tag index inside a transaction. Returns the list of seqs indexed under Tag. Empty list if no entries.