uni_store/runtime/
vid_remapper.rs1use std::collections::HashMap;
11use uni_common::core::id::{DenseIdx, Vid};
12
13#[derive(Debug, Clone, Default)]
18pub struct VidRemapper {
19 vid_to_dense: HashMap<Vid, DenseIdx>,
21 dense_to_vid: Vec<Vid>,
23}
24
25impl VidRemapper {
26 pub fn new() -> Self {
28 Self {
29 vid_to_dense: HashMap::new(),
30 dense_to_vid: Vec::new(),
31 }
32 }
33
34 pub fn with_capacity(capacity: usize) -> Self {
36 Self {
37 vid_to_dense: HashMap::with_capacity(capacity),
38 dense_to_vid: Vec::with_capacity(capacity),
39 }
40 }
41
42 pub fn insert(&mut self, vid: Vid) -> DenseIdx {
47 if let Some(&idx) = self.vid_to_dense.get(&vid) {
48 return idx;
49 }
50 let idx = DenseIdx::new(self.dense_to_vid.len() as u32);
51 self.dense_to_vid.push(vid);
52 self.vid_to_dense.insert(vid, idx);
53 idx
54 }
55
56 pub fn insert_many(&mut self, vids: &[Vid]) -> Vec<DenseIdx> {
58 vids.iter().map(|&vid| self.insert(vid)).collect()
59 }
60
61 pub fn to_dense(&self, vid: Vid) -> Option<DenseIdx> {
65 self.vid_to_dense.get(&vid).copied()
66 }
67
68 pub fn to_dense_unchecked(&self, vid: Vid) -> DenseIdx {
72 self.vid_to_dense[&vid]
73 }
74
75 pub fn to_vid(&self, idx: DenseIdx) -> Vid {
79 self.dense_to_vid[idx.as_usize()]
80 }
81
82 pub fn to_vid_opt(&self, idx: DenseIdx) -> Option<Vid> {
84 self.dense_to_vid.get(idx.as_usize()).copied()
85 }
86
87 pub fn len(&self) -> usize {
89 self.dense_to_vid.len()
90 }
91
92 pub fn is_empty(&self) -> bool {
94 self.dense_to_vid.is_empty()
95 }
96
97 pub fn contains(&self, vid: Vid) -> bool {
99 self.vid_to_dense.contains_key(&vid)
100 }
101
102 pub fn iter(&self) -> impl Iterator<Item = (DenseIdx, Vid)> + '_ {
104 self.dense_to_vid
105 .iter()
106 .enumerate()
107 .map(|(i, &vid)| (DenseIdx::new(i as u32), vid))
108 }
109
110 pub fn vids(&self) -> impl Iterator<Item = Vid> + '_ {
112 self.dense_to_vid.iter().copied()
113 }
114
115 pub fn vids_slice(&self) -> &[Vid] {
117 &self.dense_to_vid
118 }
119
120 pub fn clear(&mut self) {
122 self.vid_to_dense.clear();
123 self.dense_to_vid.clear();
124 }
125
126 pub fn memory_usage(&self) -> usize {
128 self.vid_to_dense.capacity()
130 * (std::mem::size_of::<Vid>() + std::mem::size_of::<DenseIdx>())
131 + self.dense_to_vid.capacity() * std::mem::size_of::<Vid>()
132 }
133}
134
135#[derive(Debug, Clone, Default)]
139pub struct EidRemapper {
140 eid_to_dense: HashMap<uni_common::core::id::Eid, DenseIdx>,
141 dense_to_eid: Vec<uni_common::core::id::Eid>,
142}
143
144impl EidRemapper {
145 pub fn new() -> Self {
146 Self {
147 eid_to_dense: HashMap::new(),
148 dense_to_eid: Vec::new(),
149 }
150 }
151
152 pub fn with_capacity(capacity: usize) -> Self {
153 Self {
154 eid_to_dense: HashMap::with_capacity(capacity),
155 dense_to_eid: Vec::with_capacity(capacity),
156 }
157 }
158
159 pub fn insert(&mut self, eid: uni_common::core::id::Eid) -> DenseIdx {
160 if let Some(&idx) = self.eid_to_dense.get(&eid) {
161 return idx;
162 }
163 let idx = DenseIdx::new(self.dense_to_eid.len() as u32);
164 self.dense_to_eid.push(eid);
165 self.eid_to_dense.insert(eid, idx);
166 idx
167 }
168
169 pub fn to_dense(&self, eid: uni_common::core::id::Eid) -> Option<DenseIdx> {
170 self.eid_to_dense.get(&eid).copied()
171 }
172
173 pub fn to_eid(&self, idx: DenseIdx) -> uni_common::core::id::Eid {
174 self.dense_to_eid[idx.as_usize()]
175 }
176
177 pub fn len(&self) -> usize {
178 self.dense_to_eid.len()
179 }
180
181 pub fn is_empty(&self) -> bool {
182 self.dense_to_eid.is_empty()
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
191 fn test_vid_remapper_basic() {
192 let mut remapper = VidRemapper::new();
193
194 let vid1 = Vid::new(100);
195 let vid2 = Vid::new(500);
196 let vid3 = Vid::new(200);
197
198 let idx1 = remapper.insert(vid1);
199 let idx2 = remapper.insert(vid2);
200 let idx3 = remapper.insert(vid3);
201
202 assert_eq!(idx1.as_u32(), 0);
203 assert_eq!(idx2.as_u32(), 1);
204 assert_eq!(idx3.as_u32(), 2);
205
206 assert_eq!(remapper.to_vid(idx1), vid1);
207 assert_eq!(remapper.to_vid(idx2), vid2);
208 assert_eq!(remapper.to_vid(idx3), vid3);
209
210 assert_eq!(remapper.to_dense(vid1), Some(idx1));
211 assert_eq!(remapper.to_dense(vid2), Some(idx2));
212 assert_eq!(remapper.to_dense(Vid::new(999)), None);
213 }
214
215 #[test]
216 fn test_vid_remapper_duplicate_insert() {
217 let mut remapper = VidRemapper::new();
218 let vid = Vid::new(42);
219
220 let idx1 = remapper.insert(vid);
221 let idx2 = remapper.insert(vid);
222
223 assert_eq!(idx1, idx2);
224 assert_eq!(remapper.len(), 1);
225 }
226
227 #[test]
228 fn test_vid_remapper_insert_many() {
229 let mut remapper = VidRemapper::new();
230 let vids = vec![Vid::new(10), Vid::new(20), Vid::new(30)];
231
232 let indices = remapper.insert_many(&vids);
233
234 assert_eq!(indices.len(), 3);
235 assert_eq!(remapper.len(), 3);
236 for (idx, vid) in indices.iter().zip(vids.iter()) {
237 assert_eq!(remapper.to_vid(*idx), *vid);
238 }
239 }
240
241 #[test]
242 fn test_vid_remapper_iter() {
243 let mut remapper = VidRemapper::new();
244 remapper.insert(Vid::new(100));
245 remapper.insert(Vid::new(200));
246 remapper.insert(Vid::new(300));
247
248 let pairs: Vec<_> = remapper.iter().collect();
249 assert_eq!(pairs.len(), 3);
250 assert_eq!(pairs[0], (DenseIdx::new(0), Vid::new(100)));
251 assert_eq!(pairs[1], (DenseIdx::new(1), Vid::new(200)));
252 assert_eq!(pairs[2], (DenseIdx::new(2), Vid::new(300)));
253 }
254}