ringkernel_procint/models/
patterns.rs1use super::ActivityId;
6use rkyv::{Archive, Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Archive, Serialize, Deserialize)]
10#[repr(u8)]
11pub enum PatternType {
12 Sequential = 0,
14 Parallel = 1,
16 Loop = 2,
18 Conditional = 3,
20 XorSplit = 4,
22 AndSplit = 5,
24 LongRunning = 6,
26 Bottleneck = 7,
28 Rework = 8,
30 Circular = 9,
32}
33
34impl PatternType {
35 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 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 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#[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 #[default]
103 Info = 0,
104 Warning = 1,
106 Critical = 2,
108}
109
110impl PatternSeverity {
111 pub fn color(&self) -> [u8; 3] {
113 match self {
114 PatternSeverity::Info => [100, 149, 237], PatternSeverity::Warning => [255, 165, 0], PatternSeverity::Critical => [220, 53, 69], }
118 }
119
120 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#[derive(Debug, Clone, Copy, Default, Archive, Serialize, Deserialize)]
132#[repr(C, align(64))]
133pub struct GpuPatternMatch {
134 pub pattern_type: u8,
136 pub severity: u8,
138 pub activity_count: u8,
140 pub flags: u8,
142 pub activity_ids: [u32; 8],
144 pub confidence: f32,
146 pub frequency: u32,
148 pub avg_duration_ms: f32,
150 pub impact: f32,
152 pub _reserved: [u8; 4],
154}
155
156const _: () = assert!(std::mem::size_of::<GpuPatternMatch>() == 64);
158
159impl GpuPatternMatch {
160 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 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 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 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 pub fn activities(&self) -> &[u32] {
206 &self.activity_ids[..self.activity_count as usize]
207 }
208
209 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 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#[derive(Debug, Clone)]
236pub struct PatternDefinition {
237 pub pattern_type: PatternType,
239 pub severity: PatternSeverity,
241 pub min_confidence: f32,
243 pub min_frequency: u32,
245 pub duration_threshold_ms: u32,
247 pub enabled: bool,
249}
250
251impl PatternDefinition {
252 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, enabled: true,
261 }
262 }
263
264 pub fn with_severity(mut self, severity: PatternSeverity) -> Self {
266 self.severity = severity;
267 self
268 }
269
270 pub fn with_min_confidence(mut self, confidence: f32) -> Self {
272 self.min_confidence = confidence;
273 self
274 }
275
276 pub fn with_duration_threshold(mut self, threshold_ms: u32) -> Self {
278 self.duration_threshold_ms = threshold_ms;
279 self
280 }
281}
282
283pub 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), 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}