la_rete/core/facts_table/
facts_table_stats.rs

1use std::collections::HashMap;
2use std::collections::HashSet;
3
4use super::FactsTable;
5
6pub struct FactsTableStats {
7    selectivity: HashMap<String, usize>,
8}
9
10impl FactsTableStats {
11    pub fn calculate<In>(facts_table: &FactsTable<In>) -> Self {
12        let mut selectivity = HashMap::<String, HashSet<u64>>::new();
13
14        for row in &facts_table.rows {
15            for cell in &row.cells {
16                let prop_id = cell.property_id();
17                if let Some(value_hash) = cell.value_hash() {
18                    let mut hashes = selectivity.remove(&prop_id).unwrap_or(HashSet::new());
19                    hashes.insert(value_hash);
20                    selectivity.insert(prop_id, hashes);
21                }
22            }
23        }
24
25        let selectivity = selectivity
26            .into_iter()
27            .map(|(k, hs)| (k, hs.len()))
28            .collect();
29        Self { selectivity }
30    }
31
32    pub fn optimize_table<In>(&self, facts_table: &mut FactsTable<In>) -> () {
33        for row in &mut facts_table.rows {
34            let mut cells = row.cells.iter().cloned().collect::<Vec<_>>();
35            cells.sort_by(|left, right| {
36                let left = self.selectivity.get(&left.property_id()).unwrap_or(&0);
37                let right = self.selectivity.get(&right.property_id()).unwrap_or(&0);
38
39                right.cmp(left)
40            });
41            row.cells = cells.into_iter().collect();
42        }
43    }
44}