Skip to main content

graphrecords_query/optimizer/
estimate.rs

1use super::stats::Stats;
2
3#[derive(Clone, Debug)]
4pub struct Estimate {
5    pub elements: Option<usize>,
6    pub distinct: Option<usize>,
7    pub selectivity: Option<f64>,
8    pub per_group: Option<Box<Self>>,
9}
10
11impl Estimate {
12    pub const UNKNOWN: Self = Self {
13        elements: None,
14        distinct: None,
15        selectivity: None,
16        per_group: None,
17    };
18
19    #[must_use]
20    pub fn values(elements: usize, distinct: usize) -> Self {
21        Self {
22            elements: Some(elements),
23            distinct: Some(distinct.min(elements)),
24            selectivity: None,
25            per_group: None,
26        }
27    }
28
29    #[must_use]
30    pub fn singleton() -> Self {
31        Self::values(1, 1)
32    }
33
34    #[must_use]
35    pub fn with_unknown_distinct(self) -> Self {
36        Self {
37            distinct: None,
38            ..self
39        }
40    }
41
42    #[must_use]
43    pub fn zero_or_one(self) -> Self {
44        Self {
45            elements: self.elements.map(|elements| elements.min(1)),
46            distinct: None,
47            selectivity: None,
48            per_group: None,
49        }
50    }
51
52    #[must_use]
53    pub fn scaled(self, selectivity: f64) -> Self {
54        let elements = self
55            .elements
56            .map(|elements| (elements as f64 * selectivity).round() as usize);
57        let distinct = match (self.distinct, elements) {
58            (Some(distinct), Some(elements)) => Some(distinct.min(elements)),
59            (distinct, _) => distinct,
60        };
61
62        Self {
63            elements,
64            distinct,
65            ..self
66        }
67    }
68}
69
70pub trait Estimated {
71    fn estimate(&self, stats: &Stats) -> Estimate;
72}