Skip to main content

ruvector_dag/mincut/
redundancy.rs

1//! Redundancy Suggestions for reliability
2
3use super::bottleneck::Bottleneck;
4use crate::dag::{OperatorType, QueryDag};
5
6/// Suggestion for adding redundancy
7#[derive(Debug, Clone)]
8pub struct RedundancySuggestion {
9    pub target_node: usize,
10    pub strategy: RedundancyStrategy,
11    pub expected_improvement: f64,
12    pub cost_increase: f64,
13}
14
15#[derive(Debug, Clone)]
16pub enum RedundancyStrategy {
17    /// Duplicate the node's computation
18    Replicate,
19    /// Add alternative path
20    AlternativePath,
21    /// Cache intermediate results
22    Materialize,
23    /// Pre-compute during idle time
24    Prefetch,
25}
26
27impl RedundancySuggestion {
28    pub fn generate(dag: &QueryDag, bottlenecks: &[Bottleneck]) -> Vec<Self> {
29        let mut suggestions = Vec::new();
30
31        for bottleneck in bottlenecks {
32            let node = dag.get_node(bottleneck.node_id);
33            if node.is_none() {
34                continue;
35            }
36            let node = node.unwrap();
37
38            // Determine best strategy based on operator type
39            let strategy = match &node.op_type {
40                OperatorType::SeqScan { .. }
41                | OperatorType::IndexScan { .. }
42                | OperatorType::IvfFlatScan { .. } => RedundancyStrategy::Materialize,
43                OperatorType::HnswScan { .. } => RedundancyStrategy::Prefetch,
44                _ => RedundancyStrategy::Replicate,
45            };
46
47            suggestions.push(RedundancySuggestion {
48                target_node: bottleneck.node_id,
49                strategy,
50                expected_improvement: bottleneck.impact_estimate * 0.3,
51                cost_increase: node.estimated_cost * 0.1,
52            });
53        }
54
55        suggestions
56    }
57}