lora_store/memory/
stats.rs1use std::collections::{hash_map::DefaultHasher, BTreeMap, BTreeSet};
15use std::hash::{Hash, Hasher};
16
17#[derive(Debug, Default, Clone, PartialEq, Eq)]
20pub struct GraphStats {
21 pub node_count: usize,
23 pub relationship_count: usize,
25 pub nodes_by_label: BTreeMap<String, usize>,
27 pub relationships_by_type: BTreeMap<String, usize>,
29 pub node_distinct_values: BTreeMap<(String, String), usize>,
33 pub relationship_distinct_values: BTreeMap<(String, String), usize>,
34 pub node_range_indexes: BTreeSet<(String, String)>,
36 pub relationship_range_indexes: BTreeSet<(String, String)>,
37 pub node_text_indexes: BTreeSet<(String, String)>,
39 pub relationship_text_indexes: BTreeSet<(String, String)>,
40 pub node_point_indexes: BTreeSet<(String, String)>,
42 pub relationship_point_indexes: BTreeSet<(String, String)>,
43 pub node_vector_indexes: BTreeSet<(String, String)>,
48 pub relationship_vector_indexes: BTreeSet<(String, String)>,
49}
50
51impl GraphStats {
52 pub fn estimate_node_property_equality(&self, label: &str, property: &str) -> Option<u64> {
56 let total = self.nodes_by_label.get(label).copied()? as u64;
57 let distinct = self
58 .node_distinct_values
59 .get(&(label.to_string(), property.to_string()))
60 .copied()
61 .unwrap_or(1)
62 .max(1) as u64;
63 Some(total.div_ceil(distinct))
66 }
67
68 pub fn label_count(&self, label: &str) -> Option<u64> {
69 self.nodes_by_label.get(label).copied().map(|c| c as u64)
70 }
71
72 pub fn relationship_type_count(&self, rel_type: &str) -> Option<u64> {
73 self.relationships_by_type
74 .get(rel_type)
75 .copied()
76 .map(|c| c as u64)
77 }
78
79 pub fn fingerprint(&self) -> u64 {
80 let mut hasher = DefaultHasher::new();
81 self.node_count.hash(&mut hasher);
82 self.relationship_count.hash(&mut hasher);
83 self.nodes_by_label.hash(&mut hasher);
84 self.relationships_by_type.hash(&mut hasher);
85 self.node_distinct_values.hash(&mut hasher);
86 self.relationship_distinct_values.hash(&mut hasher);
87 self.node_range_indexes.hash(&mut hasher);
88 self.relationship_range_indexes.hash(&mut hasher);
89 self.node_text_indexes.hash(&mut hasher);
90 self.relationship_text_indexes.hash(&mut hasher);
91 self.node_point_indexes.hash(&mut hasher);
92 self.relationship_point_indexes.hash(&mut hasher);
93 self.node_vector_indexes.hash(&mut hasher);
94 self.relationship_vector_indexes.hash(&mut hasher);
95 hasher.finish()
96 }
97
98 pub fn has_node_range_index(&self, label: &str, property: &str) -> bool {
99 self.node_range_indexes
100 .contains(&(label.to_owned(), property.to_owned()))
101 }
102
103 pub fn has_node_text_index(&self, label: &str, property: &str) -> bool {
104 self.node_text_indexes
105 .contains(&(label.to_owned(), property.to_owned()))
106 }
107
108 pub fn has_node_point_index(&self, label: &str, property: &str) -> bool {
109 self.node_point_indexes
110 .contains(&(label.to_owned(), property.to_owned()))
111 }
112
113 pub fn has_relationship_range_index(&self, rel_type: &str, property: &str) -> bool {
114 self.relationship_range_indexes
115 .contains(&(rel_type.to_owned(), property.to_owned()))
116 }
117
118 pub fn has_relationship_text_index(&self, rel_type: &str, property: &str) -> bool {
119 self.relationship_text_indexes
120 .contains(&(rel_type.to_owned(), property.to_owned()))
121 }
122
123 pub fn has_relationship_point_index(&self, rel_type: &str, property: &str) -> bool {
124 self.relationship_point_indexes
125 .contains(&(rel_type.to_owned(), property.to_owned()))
126 }
127
128 pub fn has_node_vector_index(&self, label: &str, property: &str) -> bool {
129 self.node_vector_indexes
130 .contains(&(label.to_owned(), property.to_owned()))
131 }
132
133 pub fn has_relationship_vector_index(&self, rel_type: &str, property: &str) -> bool {
134 self.relationship_vector_indexes
135 .contains(&(rel_type.to_owned(), property.to_owned()))
136 }
137}