nodedb_graph/csr/index/
interning.rs1use std::collections::hash_map::Entry;
4
5use super::types::CsrIndex;
6
7impl CsrIndex {
8 pub(crate) fn ensure_node(&mut self, node: &str) -> u32 {
10 match self.node_to_id.entry(node.to_string()) {
11 Entry::Occupied(e) => *e.get(),
12 Entry::Vacant(e) => {
13 let id = self.id_to_node.len() as u32;
14 e.insert(id);
15 self.id_to_node.push(node.to_string());
16 self.out_offsets
18 .push(*self.out_offsets.last().unwrap_or(&0));
19 self.in_offsets.push(*self.in_offsets.last().unwrap_or(&0));
20 self.buffer_out.push(Vec::new());
22 self.buffer_in.push(Vec::new());
23 self.buffer_out_weights.push(Vec::new());
24 self.buffer_in_weights.push(Vec::new());
25 self.node_label_bits.push(0);
26 self.access_counts.push(std::cell::Cell::new(0));
27 id
28 }
29 }
30 }
31
32 pub(crate) fn ensure_label(&mut self, label: &str) -> Result<u32, crate::GraphError> {
41 match self.label_to_id.entry(label.to_string()) {
42 Entry::Occupied(e) => Ok(*e.get()),
43 Entry::Vacant(e) => {
44 let len = self.id_to_label.len();
45 if len >= crate::MAX_EDGE_LABELS {
46 return Err(crate::GraphError::LabelOverflow { used: len });
47 }
48 let id = len as u32;
49 e.insert(id);
50 self.id_to_label.push(label.to_string());
51 Ok(id)
52 }
53 }
54 }
55
56 fn ensure_node_label(&mut self, label: &str) -> Option<u8> {
60 if let Some(&id) = self.node_label_to_id.get(label) {
61 return Some(id);
62 }
63 let id = self.node_label_names.len();
64 if id >= 64 {
65 return None; }
67 let id = id as u8;
68 self.node_label_to_id.insert(label.to_string(), id);
69 self.node_label_names.push(label.to_string());
70 Some(id)
71 }
72
73 pub fn add_node_label(&mut self, node: &str, label: &str) -> bool {
75 let node_id = self.ensure_node(node);
76 let Some(label_id) = self.ensure_node_label(label) else {
77 return false;
78 };
79 self.node_label_bits[node_id as usize] |= 1u64 << label_id;
80 true
81 }
82
83 pub fn remove_node_label(&mut self, node: &str, label: &str) {
85 let Some(&node_id) = self.node_to_id.get(node) else {
86 return;
87 };
88 let Some(&label_id) = self.node_label_to_id.get(label) else {
89 return;
90 };
91 self.node_label_bits[node_id as usize] &= !(1u64 << label_id);
92 }
93
94 pub fn node_has_label(&self, node_id: u32, label: &str) -> bool {
96 let Some(&label_id) = self.node_label_to_id.get(label) else {
97 return false;
98 };
99 let bits = self
100 .node_label_bits
101 .get(node_id as usize)
102 .copied()
103 .unwrap_or(0);
104 bits & (1u64 << label_id) != 0
105 }
106
107 pub fn node_labels(&self, node_id: u32) -> Vec<&str> {
109 let bits = self
110 .node_label_bits
111 .get(node_id as usize)
112 .copied()
113 .unwrap_or(0);
114 if bits == 0 {
115 return Vec::new();
116 }
117 let mut labels = Vec::new();
118 for (i, name) in self.node_label_names.iter().enumerate() {
119 if bits & (1u64 << i) != 0 {
120 labels.push(name.as_str());
121 }
122 }
123 labels
124 }
125}