Skip to main content

ringkernel_procint/models/
patterns.rs

1//! Pattern definitions for process intelligence.
2//!
3//! Defines pattern types detected by GPU kernels.
4
5use super::ActivityId;
6use rkyv::{Archive, Deserialize, Serialize};
7
8/// Pattern type classification.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Archive, Serialize, Deserialize)]
10#[repr(u8)]
11pub enum PatternType {
12    /// Activities in strict sequence.
13    Sequential = 0,
14    /// Activities with overlapping execution.
15    Parallel = 1,
16    /// Repeated activity occurrence.
17    Loop = 2,
18    /// Decision point with multiple paths.
19    Conditional = 3,
20    /// Exclusive choice (XOR split).
21    XorSplit = 4,
22    /// Parallel execution (AND split).
23    AndSplit = 5,
24    /// Activity exceeding duration threshold.
25    LongRunning = 6,
26    /// Activity causing waiting time.
27    Bottleneck = 7,
28    /// Activity repeated due to quality issues.
29    Rework = 8,
30    /// Circular flow pattern (A → B → A).
31    Circular = 9,
32}
33
34impl PatternType {
35    /// Get display name.
36    pub fn name(&self) -> &'static str {
37        match self {
38            PatternType::Sequential => "Sequential Flow",
39            PatternType::Parallel => "Parallel Flow",
40            PatternType::Loop => "Loop",
41            PatternType::Conditional => "Conditional Branch",
42            PatternType::XorSplit => "XOR Split",
43            PatternType::AndSplit => "AND Split",
44            PatternType::LongRunning => "Long-Running",
45            PatternType::Bottleneck => "Bottleneck",
46            PatternType::Rework => "Rework",
47            PatternType::Circular => "Circular Flow",
48        }
49    }
50
51    /// Get icon for UI display.
52    pub fn icon(&self) -> &'static str {
53        match self {
54            PatternType::Sequential => "→",
55            PatternType::Parallel => "⇉",
56            PatternType::Loop => "↺",
57            PatternType::Conditional => "◇",
58            PatternType::XorSplit => "⊕",
59            PatternType::AndSplit => "⊗",
60            PatternType::LongRunning => "⏱",
61            PatternType::Bottleneck => "⚠",
62            PatternType::Rework => "↩",
63            PatternType::Circular => "⟳",
64        }
65    }
66
67    /// Get description.
68    pub fn description(&self) -> &'static str {
69        match self {
70            PatternType::Sequential => "Activities executed in strict order",
71            PatternType::Parallel => "Activities executed concurrently",
72            PatternType::Loop => "Activity repeated multiple times",
73            PatternType::Conditional => "Decision point with multiple paths",
74            PatternType::XorSplit => "Exclusive choice between paths",
75            PatternType::AndSplit => "Parallel execution of paths",
76            PatternType::LongRunning => "Activity duration exceeds threshold",
77            PatternType::Bottleneck => "Activity causing delays in the process",
78            PatternType::Rework => "Activity repeated due to issues",
79            PatternType::Circular => "Circular dependency between activities",
80        }
81    }
82}
83
84/// Pattern severity level.
85#[derive(
86    Debug,
87    Clone,
88    Copy,
89    PartialEq,
90    Eq,
91    PartialOrd,
92    Ord,
93    Hash,
94    Default,
95    Archive,
96    Serialize,
97    Deserialize,
98)]
99#[repr(u8)]
100pub enum PatternSeverity {
101    /// Informational pattern.
102    #[default]
103    Info = 0,
104    /// Warning - may indicate issue.
105    Warning = 1,
106    /// Critical - definite issue.
107    Critical = 2,
108}
109
110impl PatternSeverity {
111    /// Get color for UI (RGB).
112    pub fn color(&self) -> [u8; 3] {
113        match self {
114            PatternSeverity::Info => [100, 149, 237], // Cornflower blue
115            PatternSeverity::Warning => [255, 165, 0], // Orange
116            PatternSeverity::Critical => [220, 53, 69], // Red
117        }
118    }
119
120    /// Get display name.
121    pub fn name(&self) -> &'static str {
122        match self {
123            PatternSeverity::Info => "Info",
124            PatternSeverity::Warning => "Warning",
125            PatternSeverity::Critical => "Critical",
126        }
127    }
128}
129
130/// GPU-compatible pattern match (64 bytes, cache-line aligned).
131#[derive(Debug, Clone, Copy, Default, Archive, Serialize, Deserialize)]
132#[repr(C, align(64))]
133pub struct GpuPatternMatch {
134    /// Pattern type.
135    pub pattern_type: u8,
136    /// Severity level.
137    pub severity: u8,
138    /// Number of activities in the pattern.
139    pub activity_count: u8,
140    /// Status flags.
141    pub flags: u8,
142    /// Activity IDs involved (up to 8).
143    pub activity_ids: [u32; 8],
144    /// Detection confidence (0.0 - 1.0).
145    pub confidence: f32,
146    /// Pattern frequency (how many times detected).
147    pub frequency: u32,
148    /// Average duration of the pattern (ms).
149    pub avg_duration_ms: f32,
150    /// Impact score (0.0 - 1.0).
151    pub impact: f32,
152    /// Reserved.
153    pub _reserved: [u8; 4],
154}
155
156// Verify size
157const _: () = assert!(std::mem::size_of::<GpuPatternMatch>() == 64);
158
159impl GpuPatternMatch {
160    /// Create a new pattern match.
161    pub fn new(pattern_type: PatternType, severity: PatternSeverity) -> Self {
162        Self {
163            pattern_type: pattern_type as u8,
164            severity: severity as u8,
165            ..Default::default()
166        }
167    }
168
169    /// Get the pattern type.
170    pub fn get_pattern_type(&self) -> PatternType {
171        match self.pattern_type {
172            0 => PatternType::Sequential,
173            1 => PatternType::Parallel,
174            2 => PatternType::Loop,
175            3 => PatternType::Conditional,
176            4 => PatternType::XorSplit,
177            5 => PatternType::AndSplit,
178            6 => PatternType::LongRunning,
179            7 => PatternType::Bottleneck,
180            8 => PatternType::Rework,
181            9 => PatternType::Circular,
182            _ => PatternType::Sequential,
183        }
184    }
185
186    /// Get the severity level.
187    pub fn get_severity(&self) -> PatternSeverity {
188        match self.severity {
189            0 => PatternSeverity::Info,
190            1 => PatternSeverity::Warning,
191            2 => PatternSeverity::Critical,
192            _ => PatternSeverity::Info,
193        }
194    }
195
196    /// Add an activity to the pattern.
197    pub fn add_activity(&mut self, activity_id: ActivityId) {
198        if (self.activity_count as usize) < 8 {
199            self.activity_ids[self.activity_count as usize] = activity_id;
200            self.activity_count += 1;
201        }
202    }
203
204    /// Get activities involved in the pattern.
205    pub fn activities(&self) -> &[u32] {
206        &self.activity_ids[..self.activity_count as usize]
207    }
208
209    /// Set confidence and impact based on pattern type.
210    pub fn with_metrics(mut self, confidence: f32, frequency: u32, avg_duration: f32) -> Self {
211        self.confidence = confidence;
212        self.frequency = frequency;
213        self.avg_duration_ms = avg_duration;
214        self.impact = self.calculate_impact();
215        self
216    }
217
218    /// Calculate impact score based on pattern type and metrics.
219    fn calculate_impact(&self) -> f32 {
220        let base = match self.get_pattern_type() {
221            PatternType::Bottleneck => 0.8,
222            PatternType::Rework => 0.7,
223            PatternType::LongRunning => 0.6,
224            PatternType::Loop => 0.5,
225            PatternType::Circular => 0.9,
226            _ => 0.3,
227        };
228
229        let freq_factor = (self.frequency as f32 / 100.0).min(0.2);
230        (base + freq_factor).min(1.0) * self.confidence
231    }
232}
233
234/// High-level pattern definition for detection configuration.
235#[derive(Debug, Clone)]
236pub struct PatternDefinition {
237    /// Pattern type.
238    pub pattern_type: PatternType,
239    /// Default severity.
240    pub severity: PatternSeverity,
241    /// Minimum confidence threshold.
242    pub min_confidence: f32,
243    /// Minimum frequency to report.
244    pub min_frequency: u32,
245    /// Duration threshold for long-running detection (ms).
246    pub duration_threshold_ms: u32,
247    /// Is detection enabled?
248    pub enabled: bool,
249}
250
251impl PatternDefinition {
252    /// Create a new pattern definition.
253    pub fn new(pattern_type: PatternType) -> Self {
254        Self {
255            pattern_type,
256            severity: PatternSeverity::Info,
257            min_confidence: 0.5,
258            min_frequency: 1,
259            duration_threshold_ms: 60000, // 1 minute
260            enabled: true,
261        }
262    }
263
264    /// Set severity.
265    pub fn with_severity(mut self, severity: PatternSeverity) -> Self {
266        self.severity = severity;
267        self
268    }
269
270    /// Set minimum confidence.
271    pub fn with_min_confidence(mut self, confidence: f32) -> Self {
272        self.min_confidence = confidence;
273        self
274    }
275
276    /// Set duration threshold.
277    pub fn with_duration_threshold(mut self, threshold_ms: u32) -> Self {
278        self.duration_threshold_ms = threshold_ms;
279        self
280    }
281}
282
283/// Default pattern definitions for common patterns.
284pub fn default_pattern_definitions() -> Vec<PatternDefinition> {
285    vec![
286        PatternDefinition::new(PatternType::Bottleneck)
287            .with_severity(PatternSeverity::Critical)
288            .with_min_confidence(0.7),
289        PatternDefinition::new(PatternType::Loop)
290            .with_severity(PatternSeverity::Warning)
291            .with_min_confidence(0.6),
292        PatternDefinition::new(PatternType::Rework)
293            .with_severity(PatternSeverity::Warning)
294            .with_min_confidence(0.6),
295        PatternDefinition::new(PatternType::LongRunning)
296            .with_severity(PatternSeverity::Warning)
297            .with_duration_threshold(300000), // 5 minutes
298        PatternDefinition::new(PatternType::Circular)
299            .with_severity(PatternSeverity::Critical)
300            .with_min_confidence(0.8),
301    ]
302}
303
304#[cfg(test)]
305mod tests {
306    use super::*;
307
308    #[test]
309    fn test_pattern_match_size() {
310        assert_eq!(std::mem::size_of::<GpuPatternMatch>(), 64);
311    }
312
313    #[test]
314    fn test_pattern_match_activities() {
315        let mut pattern = GpuPatternMatch::new(PatternType::Bottleneck, PatternSeverity::Critical);
316        pattern.add_activity(1);
317        pattern.add_activity(2);
318        pattern.add_activity(3);
319
320        assert_eq!(pattern.activity_count, 3);
321        assert_eq!(pattern.activities(), &[1, 2, 3]);
322    }
323
324    #[test]
325    fn test_pattern_impact() {
326        let pattern = GpuPatternMatch::new(PatternType::Bottleneck, PatternSeverity::Critical)
327            .with_metrics(0.9, 50, 10000.0);
328
329        assert!(pattern.impact > 0.7);
330    }
331}