la_rete/core/facts_table/
facts_table_stats.rs1use 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}