Skip to main content

varpulis_sase/
types.rs

1//! Core SASE+ types and constants
2
3use std::sync::Arc;
4use std::time::Duration;
5
6use rustc_hash::FxHashMap;
7use varpulis_core::{Event, Value};
8
9use crate::clock::Timestamp;
10
11/// Shared event reference for efficient cloning in pattern matching.
12/// Using Arc allows multiple pattern runs to share the same event data
13/// without expensive deep copies.
14pub type SharedEvent = Arc<Event>;
15
16/// Safety cap on events accumulated in a single Kleene closure.
17/// With n events the ZDD enumerates up to 2^n - 1 combinations.
18/// 20 events → ~1 M combinations (safe); 30 → ~1 B (OOM risk).
19pub const MAX_KLEENE_EVENTS: u32 = 20;
20
21/// Safety cap on results emitted by `enumerate_with_filter`.
22/// Prevents unbounded memory growth when the deferred predicate
23/// passes most combinations of a large Kleene closure.
24pub const MAX_ENUMERATION_RESULTS: usize = 10_000;
25
26// ============================================================================
27// PATTERN EXPRESSION AST
28// ============================================================================
29
30/// A SASE+ pattern expression
31#[derive(Debug, Clone)]
32pub enum SasePattern {
33    /// Match a single event type with optional predicate.
34    Event {
35        /// The event type name to match.
36        event_type: String,
37        /// Optional filter predicate.
38        predicate: Option<Predicate>,
39        /// Optional alias for capturing the matched event.
40        alias: Option<String>,
41    },
42    /// Sequence: SEQ(A, B, C) - events must occur in order
43    Seq(Vec<SasePattern>),
44    /// Conjunction: AND(A, B) - both must occur (any order)
45    And(Box<SasePattern>, Box<SasePattern>),
46    /// Disjunction: OR(A, B) - either must occur
47    Or(Box<SasePattern>, Box<SasePattern>),
48    /// Negation: NOT(A) - event must NOT occur
49    Not(Box<SasePattern>),
50    /// Kleene plus: A+ (one or more occurrences)
51    KleenePlus(Box<SasePattern>),
52    /// Kleene star: A* (zero or more occurrences)
53    KleeneStar(Box<SasePattern>),
54    /// Temporal constraint: pattern within duration
55    Within(Box<SasePattern>, Duration),
56}
57
58/// Predicate for event filtering
59#[derive(Debug, Clone)]
60pub enum Predicate {
61    /// Field comparison: field op value
62    Compare {
63        /// Event field name to compare.
64        field: String,
65        /// Comparison operator.
66        op: CompareOp,
67        /// Constant value to compare against.
68        value: Value,
69    },
70    /// Field reference comparison: field op alias.field
71    CompareRef {
72        /// Event field name on the current event.
73        field: String,
74        /// Comparison operator.
75        op: CompareOp,
76        /// Alias of the previously captured event.
77        ref_alias: String,
78        /// Field name on the referenced captured event.
79        ref_field: String,
80    },
81    /// Logical AND
82    And(Box<Predicate>, Box<Predicate>),
83    /// Logical OR
84    Or(Box<Predicate>, Box<Predicate>),
85    /// Logical NOT
86    Not(Box<Predicate>),
87    /// Custom expression
88    Expr(Box<varpulis_core::ast::Expr>),
89}
90
91/// Comparison operators for predicate evaluation.
92///
93/// Used in SASE+ predicates to filter events based on field values.
94///
95/// # Example
96///
97/// ```rust,no_run
98/// use varpulis_sase::{CompareOp, Predicate};
99/// use varpulis_core::Value;
100///
101/// let pred = Predicate::Compare {
102///     field: "temperature".to_string(),
103///     op: CompareOp::Gt,
104///     value: Value::Float(100.0),
105/// };
106/// ```
107#[derive(Debug, Clone, Copy, PartialEq, Eq)]
108pub enum CompareOp {
109    /// Equality (`==`)
110    Eq,
111    /// Inequality (`!=`)
112    NotEq,
113    /// Less than (`<`)
114    Lt,
115    /// Less than or equal (`<=`)
116    Le,
117    /// Greater than (`>`)
118    Gt,
119    /// Greater than or equal (`>=`)
120    Ge,
121}
122
123/// A stack entry for Kleene closure handling
124#[derive(Debug, Clone)]
125pub struct StackEntry {
126    /// Captured event (Arc for efficient sharing across runs)
127    pub event: SharedEvent,
128    /// Alias for this capture
129    pub alias: Option<String>,
130    /// Timestamp of capture
131    pub timestamp: Timestamp,
132}
133
134/// Event selection strategy
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136pub enum SelectionStrategy {
137    /// Skip-till-any-match: most permissive, can skip irrelevant events
138    SkipTillAnyMatch,
139    /// Skip-till-next-match: contiguous matching for Kleene
140    SkipTillNextMatch,
141    /// Strict contiguous: no skipping allowed
142    StrictContiguous,
143}
144
145/// Result of pattern matching
146#[derive(Debug, Clone)]
147pub struct MatchResult {
148    /// All captured events by alias (Arc for zero-copy access)
149    pub captured: FxHashMap<String, SharedEvent>,
150    /// The event stack (ordered sequence of matches)
151    pub stack: Vec<StackEntry>,
152    /// Match duration
153    pub duration: Duration,
154}
155
156/// SASE+ Pattern Matching Engine
157/// Global negation condition for invalidating active runs
158#[derive(Debug, Clone)]
159pub struct GlobalNegation {
160    /// Event type that triggers negation
161    pub event_type: String,
162    /// Optional predicate (with access to captured events)
163    pub predicate: Option<Predicate>,
164}
165
166/// Time semantics for the engine
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
168pub enum TimeSemantics {
169    /// Processing time: use wall-clock time (no watermarks needed)
170    #[default]
171    ProcessingTime,
172    /// Event time: use event timestamps with watermark-based window completion
173    EventTime,
174}
175
176/// Engine statistics snapshot.
177#[derive(Debug, Clone)]
178pub struct SaseStats {
179    /// Number of currently active partial-match runs.
180    pub active_runs: usize,
181    /// Number of partition buckets in use.
182    pub partitions: usize,
183    /// Number of states in the compiled NFA.
184    pub nfa_states: usize,
185}
186
187/// Snapshot of an active SASE run for forecast computation.
188#[derive(Debug, Clone)]
189pub struct RunSnapshot {
190    /// Current NFA state index.
191    pub current_state: usize,
192    /// When this run started (nanoseconds since epoch).
193    pub started_at_ns: i64,
194}