graphrecords_query/optimizer/
estimate.rs1use 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}