1use super::types::{
6 AnnotationTable, BeforeAfter, BiMap, DiagMeta, EventCounter, FrequencyTable, Generation,
7 IdDispenser, IntervalSet, LoopClock, MemoSlot, Name, NameGenerator, NameGeneratorExt, NameMap,
8 NameMapping, NamePool, NameResolver, NameSet, NameSetExt, NameTrie, NameTrieExt, QualifiedName,
9 QualifiedNameExt, RingBuffer, ScopeStack, SeqNum, SimpleLruCache, Slot, SparseBitSet,
10 StringInterner, Timestamp, TypedId, WorkQueue, WorkStack,
11};
12
13pub fn direct_children<'a>(ns: &Name, names: &'a NameSet) -> Vec<&'a Name> {
17 let ns_str = ns.to_string();
18 names
19 .iter()
20 .filter(|n| {
21 let s = n.to_string();
22 if ns.is_anonymous() {
23 !s.contains('.') && s != "_"
24 } else {
25 s.starts_with(&format!("{ns_str}.")) && !s[ns_str.len() + 1..].contains('.')
26 }
27 })
28 .collect()
29}
30pub fn longest_common_prefix(a: &Name, b: &Name) -> Name {
32 let comps_a = a.components();
33 let comps_b = b.components();
34 let prefix: Vec<String> = comps_a
35 .iter()
36 .zip(comps_b.iter())
37 .take_while(|(x, y)| x == y)
38 .map(|(x, _)| x.clone())
39 .collect();
40 Name::from_components(&prefix)
41}
42pub fn share_namespace(a: &Name, b: &Name) -> bool {
44 let lcp = longest_common_prefix(a, b);
45 !lcp.is_anonymous()
46}
47#[macro_export]
55macro_rules! name {
56 ($s:expr) => {
57 $crate::Name::str($s)
58 };
59 ($first:expr, $($rest:expr),+) => {
60 { let mut n = $crate::Name::str($first); $(n = n.append_str($rest);)+ n }
61 };
62}
63#[cfg(test)]
64mod tests {
65 use super::*;
66 #[test]
67 fn test_name_display() {
68 let n1 = Name::Anonymous;
69 let n2 = Name::str("Nat");
70 let n3 = Name::str("Nat").append_str("add");
71 let n4 = Name::str("x").append_num(42);
72 assert_eq!(n1.to_string(), "_");
73 assert_eq!(n2.to_string(), "Nat");
74 assert_eq!(n3.to_string(), "Nat.add");
75 assert_eq!(n4.to_string(), "x.42");
76 }
77 #[test]
78 fn test_name_macro() {
79 let n1 = name!("Nat");
80 let n2 = name!("Nat", "add", "comm");
81 assert_eq!(n1.to_string(), "Nat");
82 assert_eq!(n2.to_string(), "Nat.add.comm");
83 }
84 #[test]
85 fn test_name_from_str() {
86 let n = Name::from_str("Nat.add.comm");
87 assert_eq!(n.to_string(), "Nat.add.comm");
88 let n2 = Name::from_str("foo");
89 assert_eq!(n2.to_string(), "foo");
90 }
91 #[test]
92 fn test_name_depth() {
93 assert_eq!(Name::Anonymous.depth(), 0);
94 assert_eq!(Name::str("Nat").depth(), 1);
95 assert_eq!(Name::str("Nat").append_str("add").depth(), 2);
96 }
97 #[test]
98 fn test_name_last_str() {
99 let n = Name::str("Nat").append_str("add");
100 assert_eq!(n.last_str(), Some("add"));
101 assert_eq!(Name::Anonymous.last_str(), None);
102 }
103 #[test]
104 fn test_name_root() {
105 let n = Name::str("Nat").append_str("add").append_str("comm");
106 assert_eq!(n.root(), Some("Nat"));
107 }
108 #[test]
109 fn test_name_has_prefix() {
110 let ns = Name::str("Nat");
111 let n = Name::str("Nat").append_str("add");
112 assert!(n.has_prefix(&ns));
113 assert!(!ns.has_prefix(&ns));
114 }
115 #[test]
116 fn test_name_components() {
117 let n = Name::str("Nat").append_str("add").append_str("comm");
118 assert_eq!(n.components(), vec!["Nat", "add", "comm"]);
119 }
120 #[test]
121 fn test_name_from_components() {
122 let comps = vec!["Nat".to_string(), "add".to_string()];
123 let n = Name::from_components(&comps);
124 assert_eq!(n.to_string(), "Nat.add");
125 }
126 #[test]
127 fn test_name_replace_last() {
128 let n = Name::str("Nat").append_str("add");
129 let n2 = n.replace_last("sub");
130 assert_eq!(n2.to_string(), "Nat.sub");
131 }
132 #[test]
133 fn test_name_freshen() {
134 let n = Name::str("x");
135 let n2 = n.freshen(3);
136 assert_eq!(n2.to_string(), "x.3");
137 }
138 #[test]
139 fn test_name_set() {
140 let mut s = NameSet::new();
141 s.insert(Name::str("Nat"));
142 s.insert(Name::str("Int"));
143 assert_eq!(s.len(), 2);
144 assert!(s.contains(&Name::str("Nat")));
145 assert!(!s.contains(&Name::str("Bool")));
146 }
147 #[test]
148 fn test_name_set_union() {
149 let mut a = NameSet::new();
150 a.insert(Name::str("Nat"));
151 let mut b = NameSet::new();
152 b.insert(Name::str("Int"));
153 let u = a.union(&b);
154 assert_eq!(u.len(), 2);
155 }
156 #[test]
157 fn test_name_map() {
158 let mut m: NameMap<u32> = NameMap::new();
159 m.insert(Name::str("a"), 1);
160 m.insert(Name::str("b"), 2);
161 assert_eq!(m.get(&Name::str("a")), Some(&1));
162 assert_eq!(m.len(), 2);
163 }
164 #[test]
165 fn test_name_map_remove() {
166 let mut m: NameMap<u32> = NameMap::new();
167 m.insert(Name::str("x"), 99);
168 let v = m.remove(&Name::str("x"));
169 assert_eq!(v, Some(99));
170 assert!(m.is_empty());
171 }
172 #[test]
173 fn test_name_generator() {
174 let mut gen = NameGenerator::with_base("_fresh");
175 let n1 = gen.next();
176 let n2 = gen.next();
177 assert_eq!(n1.to_string(), "_fresh.0");
178 assert_eq!(n2.to_string(), "_fresh.1");
179 assert_eq!(gen.count(), 2);
180 }
181 #[test]
182 fn test_name_ord() {
183 let mut names = [Name::str("Nat"), Name::str("Bool"), Name::str("Int")];
184 names.sort();
185 assert_eq!(names[0].to_string(), "Bool");
186 }
187 #[test]
188 fn test_longest_common_prefix() {
189 let a = Name::str("Nat").append_str("add").append_str("comm");
190 let b = Name::str("Nat").append_str("add").append_str("assoc");
191 let lcp = longest_common_prefix(&a, &b);
192 assert_eq!(lcp.to_string(), "Nat.add");
193 }
194 #[test]
195 fn test_share_namespace() {
196 let a = Name::str("Nat").append_str("add");
197 let b = Name::str("Nat").append_str("sub");
198 assert!(share_namespace(&a, &b));
199 let c = Name::str("Int").append_str("add");
200 assert!(!share_namespace(&a, &c));
201 }
202}
203#[cfg(test)]
204mod trie_tests {
205 use super::*;
206 #[test]
207 fn test_name_trie_insert_lookup() {
208 let mut trie: NameTrie<u32> = NameTrie::new();
209 let n = Name::str("Nat").append_str("add");
210 trie.insert(&n, 42);
211 assert_eq!(trie.lookup(&n), Some(&42));
212 assert_eq!(trie.lookup(&Name::str("Nat")), None);
213 }
214 #[test]
215 fn test_name_trie_count() {
216 let mut trie: NameTrie<u32> = NameTrie::new();
217 trie.insert(&Name::str("a"), 1);
218 trie.insert(&Name::str("b"), 2);
219 trie.insert(&Name::str("a").append_str("x"), 3);
220 assert_eq!(trie.count(), 3);
221 }
222 #[test]
223 fn test_name_trie_to_vec() {
224 let mut trie: NameTrie<u32> = NameTrie::new();
225 trie.insert(&Name::str("a"), 1);
226 trie.insert(&Name::str("b"), 2);
227 let v = trie.to_vec();
228 assert_eq!(v.len(), 2);
229 }
230 #[test]
231 fn test_qualified_name() {
232 let canonical = Name::str("Nat").append_str("add");
233 let alias = Name::str("add");
234 let qn = QualifiedName::with_alias(canonical.clone(), alias.clone());
235 assert_eq!(qn.preferred(), &alias);
236 let qn2 = QualifiedName::new(canonical.clone());
237 assert_eq!(qn2.preferred(), &canonical);
238 }
239 #[test]
240 fn test_name_set_in_namespace() {
241 let mut ns_set = NameSet::new();
242 ns_set.insert(Name::str("Nat").append_str("add"));
243 ns_set.insert(Name::str("Nat").append_str("sub"));
244 ns_set.insert(Name::str("Int").append_str("add"));
245 let nat_names = ns_set.in_namespace(&Name::str("Nat"));
246 assert_eq!(nat_names.len(), 2);
247 }
248 #[test]
249 fn test_name_set_to_sorted_vec() {
250 let mut s = NameSet::new();
251 s.insert(Name::str("z_name"));
252 s.insert(Name::str("a_name"));
253 s.insert(Name::str("m_name"));
254 let sorted = s.to_sorted_vec();
255 assert_eq!(sorted[0].to_string(), "a_name");
256 assert_eq!(sorted[2].to_string(), "z_name");
257 }
258 #[test]
259 fn test_name_map_filter_by_namespace() {
260 let mut m: NameMap<u32> = NameMap::new();
261 m.insert(Name::str("Nat").append_str("add"), 1);
262 m.insert(Name::str("Nat").append_str("sub"), 2);
263 m.insert(Name::str("Int").append_str("add"), 3);
264 let nat_entries = m.filter_by_namespace(&Name::str("Nat"));
265 assert_eq!(nat_entries.len(), 2);
266 }
267 #[test]
268 fn test_name_generator_reset() {
269 let mut gen = NameGenerator::with_base("x");
270 gen.next();
271 gen.next();
272 assert_eq!(gen.count(), 2);
273 gen.reset();
274 assert_eq!(gen.count(), 0);
275 let n = gen.next();
276 assert_eq!(n.to_string(), "x.0");
277 }
278 #[test]
279 fn test_direct_children() {
280 let mut names = NameSet::new();
281 names.insert(Name::str("Nat"));
282 names.insert(Name::str("Nat").append_str("add"));
283 names.insert(Name::str("Nat").append_str("add").append_str("comm"));
284 let children = direct_children(&Name::str("Nat"), &names);
285 assert_eq!(children.len(), 1);
286 assert_eq!(children[0].to_string(), "Nat.add");
287 }
288 #[test]
289 fn test_name_prepend() {
290 let n = Name::str("add");
291 let ns = Name::str("Nat");
292 let full = n.prepend(ns);
293 assert_eq!(full.to_string(), "Nat.add");
294 }
295 #[test]
296 fn test_name_to_ident_string() {
297 let n = Name::str("Nat").append_str("add");
298 let s = n.to_ident_string();
299 assert!(!s.contains('.'));
300 }
301}
302#[cfg(test)]
303mod tests_name_extra {
304 use super::*;
305 #[test]
306 fn test_name_pool() {
307 let mut pool = NamePool::new();
308 let id1 = pool.intern("Nat");
309 let id2 = pool.intern("Nat");
310 assert_eq!(id1, id2);
311 let id3 = pool.intern("Bool");
312 assert_ne!(id1, id3);
313 assert_eq!(pool.get(id1), Some("Nat"));
314 assert_eq!(pool.len(), 2);
315 }
316 #[test]
317 fn test_qualified_name() {
318 let qn = QualifiedNameExt::from_dot_str("Nat.succ");
319 assert_eq!(qn.unqualified(), "succ");
320 assert_eq!(qn.depth(), 2);
321 let ns = qn.namespace().expect("ns should be present");
322 assert_eq!(ns.to_string(), "Nat");
323 let child = QualifiedNameExt::from_dot_str("Nat.succ.aux");
324 let parent = QualifiedNameExt::from_dot_str("Nat.succ");
325 assert!(child.is_sub_of(&parent));
326 }
327 #[test]
328 fn test_name_mapping() {
329 let mut nm = NameMapping::new();
330 let id = nm.register("Foo");
331 assert_eq!(nm.id_of("Foo"), Some(id));
332 assert_eq!(nm.name_of(id), Some("Foo"));
333 assert_eq!(nm.register("Foo"), id);
334 assert_eq!(nm.len(), 1);
335 }
336 #[test]
337 fn test_name_trie() {
338 let mut trie = NameTrieExt::new();
339 trie.insert("Nat.succ");
340 trie.insert("Nat.zero");
341 trie.insert("Bool.true");
342 assert!(trie.contains("Nat.succ"));
343 assert!(!trie.contains("Nat.pred"));
344 let nat_names = trie.with_prefix("Nat");
345 assert_eq!(nat_names.len(), 2);
346 }
347 #[test]
348 fn test_name_resolver() {
349 let mut resolver = NameResolver::new();
350 resolver.register("Nat.succ");
351 resolver.enter("Nat");
352 let resolved = resolver.resolve("succ");
353 assert_eq!(resolved, "Nat.succ");
354 resolver.exit();
355 assert_eq!(resolver.current_ns(), "");
356 }
357}
358#[cfg(test)]
359mod tests_name_extra2 {
360 use super::*;
361 #[test]
362 fn test_name_generator() {
363 let mut gen = NameGeneratorExt::new("_x");
364 assert_eq!(gen.next(), "_x0");
365 assert_eq!(gen.next(), "_x1");
366 assert_eq!(gen.count(), 2);
367 gen.reset();
368 assert_eq!(gen.next(), "_x0");
369 }
370 #[test]
371 fn test_name_set() {
372 let mut s = NameSetExt::new();
373 s.insert("Foo");
374 s.insert("Bar");
375 assert!(s.contains("Foo"));
376 s.remove("Foo");
377 assert!(!s.contains("Foo"));
378 let mut t = NameSetExt::new();
379 t.insert("Bar");
380 t.insert("Baz");
381 let u = s.union(&t);
382 assert!(u.contains("Bar"));
383 assert!(u.contains("Baz"));
384 let inter = s.intersect(&t);
385 assert!(inter.contains("Bar"));
386 assert!(!inter.contains("Baz"));
387 }
388}
389#[cfg(test)]
390mod tests_common_infra {
391 use super::*;
392 #[test]
393 fn test_event_counter() {
394 let mut ec = EventCounter::new();
395 ec.inc("hit");
396 ec.inc("hit");
397 ec.inc("miss");
398 assert_eq!(ec.get("hit"), 2);
399 assert_eq!(ec.get("miss"), 1);
400 assert_eq!(ec.total(), 3);
401 ec.reset();
402 assert_eq!(ec.total(), 0);
403 }
404 #[test]
405 fn test_diag_meta() {
406 let mut m = DiagMeta::new();
407 m.add("os", "linux");
408 m.add("arch", "x86_64");
409 assert_eq!(m.get("os"), Some("linux"));
410 assert_eq!(m.len(), 2);
411 let s = m.to_string();
412 assert!(s.contains("os=linux"));
413 }
414 #[test]
415 fn test_scope_stack() {
416 let mut ss = ScopeStack::new();
417 ss.push("Nat");
418 ss.push("succ");
419 assert_eq!(ss.current(), Some("succ"));
420 assert_eq!(ss.depth(), 2);
421 assert_eq!(ss.path(), "Nat.succ");
422 ss.pop();
423 assert_eq!(ss.current(), Some("Nat"));
424 }
425 #[test]
426 fn test_annotation_table() {
427 let mut tbl = AnnotationTable::new();
428 tbl.annotate("doc", "first line");
429 tbl.annotate("doc", "second line");
430 assert_eq!(tbl.get_all("doc").len(), 2);
431 assert!(tbl.has("doc"));
432 assert!(!tbl.has("other"));
433 }
434 #[test]
435 fn test_work_stack() {
436 let mut ws = WorkStack::new();
437 ws.push(1u32);
438 ws.push(2u32);
439 assert_eq!(ws.pop(), Some(2));
440 assert_eq!(ws.len(), 1);
441 }
442 #[test]
443 fn test_work_queue() {
444 let mut wq = WorkQueue::new();
445 wq.enqueue(1u32);
446 wq.enqueue(2u32);
447 assert_eq!(wq.dequeue(), Some(1));
448 assert_eq!(wq.len(), 1);
449 }
450 #[test]
451 fn test_sparse_bit_set() {
452 let mut bs = SparseBitSet::new(128);
453 bs.set(5);
454 bs.set(63);
455 bs.set(64);
456 assert!(bs.get(5));
457 assert!(bs.get(63));
458 assert!(bs.get(64));
459 assert!(!bs.get(0));
460 assert_eq!(bs.count_ones(), 3);
461 bs.clear(5);
462 assert!(!bs.get(5));
463 }
464 #[test]
465 fn test_loop_clock() {
466 let mut clk = LoopClock::start();
467 for _ in 0..10 {
468 clk.tick();
469 }
470 assert_eq!(clk.iters(), 10);
471 assert!(clk.elapsed_us() >= 0.0);
472 }
473}
474#[cfg(test)]
475mod tests_extra_data_structures {
476 use super::*;
477 #[test]
478 fn test_simple_lru_cache() {
479 let mut cache: SimpleLruCache<&str, u32> = SimpleLruCache::new(3);
480 cache.put("a", 1);
481 cache.put("b", 2);
482 cache.put("c", 3);
483 assert_eq!(cache.get(&"a"), Some(&1));
484 cache.put("d", 4);
485 assert!(cache.len() <= 3);
486 }
487 #[test]
488 fn test_string_interner() {
489 let mut si = StringInterner::new();
490 let id1 = si.intern("hello");
491 let id2 = si.intern("hello");
492 assert_eq!(id1, id2);
493 let id3 = si.intern("world");
494 assert_ne!(id1, id3);
495 assert_eq!(si.get(id1), Some("hello"));
496 assert_eq!(si.len(), 2);
497 }
498 #[test]
499 fn test_frequency_table() {
500 let mut ft = FrequencyTable::new();
501 ft.record("a");
502 ft.record("b");
503 ft.record("a");
504 ft.record("a");
505 assert_eq!(ft.freq(&"a"), 3);
506 assert_eq!(ft.freq(&"b"), 1);
507 assert_eq!(ft.most_frequent(), Some((&"a", 3)));
508 assert_eq!(ft.total(), 4);
509 assert_eq!(ft.distinct(), 2);
510 }
511 #[test]
512 fn test_bimap() {
513 let mut bm: BiMap<u32, &str> = BiMap::new();
514 bm.insert(1, "one");
515 bm.insert(2, "two");
516 assert_eq!(bm.get_b(&1), Some(&"one"));
517 assert_eq!(bm.get_a(&"two"), Some(&2));
518 assert_eq!(bm.len(), 2);
519 }
520}
521#[cfg(test)]
522mod tests_interval_set {
523 use super::*;
524 #[test]
525 fn test_interval_set() {
526 let mut s = IntervalSet::new();
527 s.add(1, 5);
528 s.add(3, 8);
529 assert_eq!(s.num_intervals(), 1);
530 assert_eq!(s.cardinality(), 8);
531 assert!(s.contains(4));
532 assert!(!s.contains(9));
533 s.add(10, 15);
534 assert_eq!(s.num_intervals(), 2);
535 }
536}
537#[allow(dead_code)]
539pub fn now_us() -> Timestamp {
540 let us = std::time::SystemTime::UNIX_EPOCH
541 .elapsed()
542 .map(|d| d.as_micros() as u64)
543 .unwrap_or(0);
544 Timestamp::from_us(us)
545}
546#[cfg(test)]
547mod tests_typed_utilities {
548 use super::*;
549 #[test]
550 fn test_timestamp() {
551 let t1 = Timestamp::from_us(1000);
552 let t2 = Timestamp::from_us(1500);
553 assert_eq!(t2.elapsed_since(t1), 500);
554 assert!(t1 < t2);
555 }
556 #[test]
557 fn test_typed_id() {
558 struct Foo;
559 let id: TypedId<Foo> = TypedId::new(42);
560 assert_eq!(id.raw(), 42);
561 assert_eq!(format!("{id}"), "#42");
562 }
563 #[test]
564 fn test_id_dispenser() {
565 struct Bar;
566 let mut disp: IdDispenser<Bar> = IdDispenser::new();
567 let a = disp.next();
568 let b = disp.next();
569 assert_eq!(a.raw(), 0);
570 assert_eq!(b.raw(), 1);
571 assert_eq!(disp.count(), 2);
572 }
573 #[test]
574 fn test_slot() {
575 let mut slot: Slot<u32> = Slot::empty();
576 assert!(!slot.is_filled());
577 slot.fill(99);
578 assert!(slot.is_filled());
579 assert_eq!(slot.get(), Some(&99));
580 let v = slot.take();
581 assert_eq!(v, Some(99));
582 assert!(!slot.is_filled());
583 }
584 #[test]
585 #[should_panic]
586 fn test_slot_double_fill() {
587 let mut slot: Slot<u32> = Slot::empty();
588 slot.fill(1);
589 slot.fill(2);
590 }
591 #[test]
592 fn test_memo_slot() {
593 let mut ms: MemoSlot<u32> = MemoSlot::new();
594 assert!(!ms.is_cached());
595 let val = ms.get_or_compute(|| 42);
596 assert_eq!(*val, 42);
597 assert!(ms.is_cached());
598 ms.invalidate();
599 assert!(!ms.is_cached());
600 }
601}
602#[cfg(test)]
603mod tests_ring_buffer {
604 use super::*;
605 #[test]
606 fn test_ring_buffer() {
607 let mut rb = RingBuffer::new(3);
608 rb.push(1u32);
609 rb.push(2u32);
610 rb.push(3u32);
611 assert!(rb.is_full());
612 rb.push(4u32);
613 assert_eq!(rb.pop(), Some(2));
614 assert_eq!(rb.len(), 2);
615 }
616 #[test]
617 fn test_before_after() {
618 let ba = BeforeAfter::new(10u32, 10u32);
619 assert!(ba.unchanged());
620 let ba2 = BeforeAfter::new(10u32, 20u32);
621 assert!(!ba2.unchanged());
622 }
623 #[test]
624 fn test_seq_num() {
625 let s = SeqNum::ZERO;
626 assert_eq!(s.value(), 0);
627 let s2 = s.next();
628 assert_eq!(s2.value(), 1);
629 assert!(s < s2);
630 }
631 #[test]
632 fn test_generation() {
633 let g0 = Generation::INITIAL;
634 let g1 = g0.advance();
635 assert_eq!(g0.number(), 0);
636 assert_eq!(g1.number(), 1);
637 assert_ne!(g0, g1);
638 }
639}