oxirs_federate/materialized_views/
types.rs

1//! Type definitions for materialized views
2//!
3//! This module contains all the core data structures used in the materialized views system.
4
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use std::time::Duration;
8
9use crate::planner::planning::{FilterExpression, TriplePattern};
10
11/// Configuration for materialized view management
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct MaterializedViewConfig {
14    pub max_views: usize,
15    pub default_refresh_interval: Duration,
16    pub enable_automatic_maintenance: bool,
17    pub freshness_threshold_hours: u64,
18    pub max_view_size_bytes: u64,
19    pub enable_incremental_refresh: bool,
20}
21
22impl Default for MaterializedViewConfig {
23    fn default() -> Self {
24        Self {
25            max_views: 100,
26            default_refresh_interval: Duration::from_secs(3600), // 1 hour
27            enable_automatic_maintenance: true,
28            freshness_threshold_hours: 24,
29            max_view_size_bytes: 1024 * 1024 * 1024, // 1GB
30            enable_incremental_refresh: true,
31        }
32    }
33}
34
35/// Materialized view definition
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ViewDefinition {
38    pub name: String,
39    pub description: Option<String>,
40    pub source_patterns: Vec<ServicePattern>,
41    pub query: String,
42    pub refresh_interval: Option<Duration>,
43    pub supports_incremental: bool,
44    pub partitioning_key: Option<String>,
45    pub dependencies: Vec<String>,
46}
47
48impl ViewDefinition {
49    /// Get query patterns from the view definition
50    pub fn query_patterns(&self) -> Vec<TriplePattern> {
51        // Extract patterns from the source patterns
52        self.source_patterns
53            .iter()
54            .flat_map(|sp| sp.patterns.clone())
55            .collect()
56    }
57
58    /// Get filter expressions from the view definition
59    pub fn filters(&self) -> Vec<FilterExpression> {
60        // Extract filters from source patterns
61        self.source_patterns
62            .iter()
63            .flat_map(|sp| sp.filters.clone())
64            .collect()
65    }
66
67    /// Check if the view can support the given query patterns
68    pub fn supports_patterns(&self, query_patterns: &[TriplePattern]) -> bool {
69        let view_patterns = self.query_patterns();
70        query_patterns
71            .iter()
72            .all(|qp| view_patterns.iter().any(|vp| patterns_match(qp, vp)))
73    }
74
75    /// Estimate the freshness requirement for this view
76    pub fn estimate_freshness_requirement(&self) -> Duration {
77        self.refresh_interval.unwrap_or(Duration::from_secs(3600))
78    }
79
80    /// Get the complexity score for this view
81    pub fn complexity_score(&self) -> f64 {
82        let pattern_count = self.query_patterns().len();
83        let filter_count = self.filters().len();
84        let dependency_count = self.dependencies.len();
85
86        (pattern_count * 2 + filter_count * 3 + dependency_count * 4) as f64
87    }
88}
89
90/// Pattern matching helper function
91fn patterns_match(query_pattern: &TriplePattern, view_pattern: &TriplePattern) -> bool {
92    // Simple pattern matching - in practice this would be more sophisticated
93    (query_pattern.subject.is_none() || query_pattern.subject == view_pattern.subject)
94        && (query_pattern.predicate.is_none() || query_pattern.predicate == view_pattern.predicate)
95        && (query_pattern.object.is_none() || query_pattern.object == view_pattern.object)
96}
97
98/// Service pattern for materialized views
99#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct ServicePattern {
101    pub service_id: String,
102    pub patterns: Vec<TriplePattern>,
103    pub filters: Vec<FilterExpression>,
104    pub estimated_selectivity: f64,
105}
106
107/// Materialized view instance
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct MaterializedView {
110    pub id: String,
111    pub definition: ViewDefinition,
112    pub creation_time: DateTime<Utc>,
113    pub last_refresh: Option<DateTime<Utc>>,
114    pub size_bytes: u64,
115    pub row_count: u64,
116    pub is_stale: bool,
117    pub refresh_in_progress: bool,
118    pub error_count: u32,
119    pub last_error: Option<String>,
120    pub access_count: u64,
121    pub last_access: Option<DateTime<Utc>>,
122    pub data_location: ViewDataLocation,
123}
124
125/// Location of materialized view data
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub enum ViewDataLocation {
128    Memory,
129    Disk { path: String },
130    Remote { url: String },
131    Distributed { nodes: Vec<String> },
132}
133
134/// Statistics for a materialized view
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct ViewStatistics {
137    pub view_id: String,
138    pub hit_count: u64,
139    pub miss_count: u64,
140    pub refresh_count: u64,
141    pub avg_refresh_time: Duration,
142    pub storage_efficiency: f64,
143    pub query_coverage: f64,
144    pub freshness_score: f64,
145    pub cost_savings: f64,
146    pub last_updated: DateTime<Utc>,
147}
148
149impl ViewStatistics {
150    /// Create new statistics for a view
151    pub fn new(view_id: String) -> Self {
152        Self {
153            view_id,
154            hit_count: 0,
155            miss_count: 0,
156            refresh_count: 0,
157            avg_refresh_time: Duration::from_secs(0),
158            storage_efficiency: 0.0,
159            query_coverage: 0.0,
160            freshness_score: 1.0,
161            cost_savings: 0.0,
162            last_updated: Utc::now(),
163        }
164    }
165
166    /// Calculate hit ratio
167    pub fn hit_ratio(&self) -> f64 {
168        let total = self.hit_count + self.miss_count;
169        if total == 0 {
170            0.0
171        } else {
172            self.hit_count as f64 / total as f64
173        }
174    }
175
176    /// Record a cache hit
177    pub fn record_hit(&mut self) {
178        self.hit_count += 1;
179        self.last_updated = Utc::now();
180    }
181
182    /// Record a cache miss
183    pub fn record_miss(&mut self) {
184        self.miss_count += 1;
185        self.last_updated = Utc::now();
186    }
187
188    /// Record a refresh operation
189    pub fn record_refresh(&mut self, duration: Duration) {
190        self.refresh_count += 1;
191
192        // Update rolling average
193        if self.refresh_count == 1 {
194            self.avg_refresh_time = duration;
195        } else {
196            let total_time = self.avg_refresh_time.as_secs_f64() * (self.refresh_count - 1) as f64
197                + duration.as_secs_f64();
198            self.avg_refresh_time = Duration::from_secs_f64(total_time / self.refresh_count as f64);
199        }
200
201        self.last_updated = Utc::now();
202    }
203}
204
205/// Maintenance operation types
206#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
207pub enum MaintenanceOperation {
208    Refresh,
209    Cleanup,
210    Optimize,
211    Validate,
212    Archive,
213}
214
215/// Maintenance schedule entry
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct MaintenanceSchedule {
218    pub view_id: String,
219    pub operation: MaintenanceOperation,
220    pub scheduled_time: DateTime<Utc>,
221    pub priority: MaintenancePriority,
222    pub estimated_duration: Duration,
223}
224
225/// Priority levels for maintenance operations
226#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
227pub enum MaintenancePriority {
228    Low,
229    Normal,
230    High,
231    Critical,
232}
233
234/// Query optimization recommendation
235#[derive(Debug, Clone)]
236pub struct ViewRecommendation {
237    pub view_id: String,
238    pub reason: RecommendationReason,
239    pub estimated_benefit: f64,
240    pub implementation_cost: f64,
241    pub confidence: f64,
242}
243
244/// Reasons for view recommendations
245#[derive(Debug, Clone)]
246pub enum RecommendationReason {
247    HighQueryFrequency,
248    ExpensiveJoins,
249    SlowServiceResponse,
250    DataLocalityBenefit,
251    ReducedNetworkTraffic,
252    ImprovedCacheHitRatio,
253}
254
255/// Change detection event
256#[derive(Debug, Clone)]
257pub struct ChangeEvent {
258    pub source_service: String,
259    pub timestamp: DateTime<Utc>,
260    pub change_type: ChangeType,
261    pub affected_patterns: Vec<TriplePattern>,
262    pub estimated_impact: f64,
263}
264
265/// Types of changes that can affect materialized views
266#[derive(Debug, Clone)]
267pub enum ChangeType {
268    DataInsert,
269    DataUpdate,
270    DataDelete,
271    SchemaChange,
272    ServiceUnavailable,
273}
274
275/// Delta processing result
276#[derive(Debug, Clone)]
277pub struct DeltaResult {
278    pub view_id: String,
279    pub changes_applied: u64,
280    pub processing_time: Duration,
281    pub new_data_size: u64,
282    pub success: bool,
283    pub error_message: Option<String>,
284}
285
286/// Cleanup configuration
287#[derive(Debug, Clone, Serialize, Deserialize)]
288pub struct CleanupConfig {
289    pub max_unused_days: u32,
290    pub max_error_count: u32,
291    pub min_hit_ratio: f64,
292    pub max_size_bytes: u64,
293}
294
295impl Default for CleanupConfig {
296    fn default() -> Self {
297        Self {
298            max_unused_days: 30,
299            max_error_count: 10,
300            min_hit_ratio: 0.1,
301            max_size_bytes: 10 * 1024 * 1024 * 1024, // 10GB
302        }
303    }
304}
305
306/// Validation configuration
307#[derive(Debug, Clone, Serialize, Deserialize)]
308pub struct ValidationConfig {
309    pub enable_syntax_validation: bool,
310    pub enable_semantic_validation: bool,
311    pub max_validation_time: Duration,
312    pub strict_mode: bool,
313}
314
315impl Default for ValidationConfig {
316    fn default() -> Self {
317        Self {
318            enable_syntax_validation: true,
319            enable_semantic_validation: true,
320            max_validation_time: Duration::from_secs(30),
321            strict_mode: false,
322        }
323    }
324}
325
326/// Dependency relationship between views
327#[derive(Debug, Clone)]
328pub struct ViewDependency {
329    pub dependent_view: String,
330    pub dependency_view: String,
331    pub dependency_type: DependencyType,
332    pub strength: f64, // 0.0 to 1.0
333}
334
335/// Types of dependencies between materialized views
336#[derive(Debug, Clone)]
337pub enum DependencyType {
338    DataDependency,
339    TemporalDependency,
340    ComputationalDependency,
341    StorageDependency,
342}
343
344/// Pattern features for machine learning analysis
345#[derive(Debug, Clone, Serialize, Deserialize)]
346pub struct PatternFeatures {
347    pub pattern_complexity: f64,
348    pub selectivity: f64,
349    pub join_complexity: f64,
350    pub data_freshness_requirement: f64,
351    pub access_frequency: f64,
352    pub computational_cost: f64,
353}
354
355/// Temporal range for data coverage
356#[derive(Debug, Clone, Serialize, Deserialize)]
357pub struct TemporalRange {
358    pub start_time: DateTime<Utc>,
359    pub end_time: DateTime<Utc>,
360    pub granularity: TemporalGranularity,
361}
362
363/// Granularity levels for temporal data
364#[derive(Debug, Clone, Serialize, Deserialize)]
365pub enum TemporalGranularity {
366    Second,
367    Minute,
368    Hour,
369    Day,
370    Week,
371    Month,
372    Year,
373}