1use crate::Expr;
6use std::collections::{HashMap, HashSet};
7
8use super::types::{
9 AnnotationTable, BeforeAfter, BiMap, CheckedEquiv, DiagMeta, EquivClass, EquivManager,
10 EquivManagerStats, EquivProofTerm, EquivQuery, EquivStats, EquivalenceTable, EventCounter,
11 ExprEquivCache, FrequencyTable, Generation, IdDispenser, IndexEquivManager,
12 InstrumentedEquivManager, IntervalSet, LoopClock, MemoSlot, PersistentEquivManager, RingBuffer,
13 ScopeStack, ScopedEquivManager, SeqNum, SimpleLruCache, Slot, SparseBitSet, StringInterner,
14 SymmetricRelation, Timestamp, TypedId, UnionFind, WorkQueue, WorkStack,
15};
16
17pub(super) fn canonicalize_pair(a: Expr, b: Expr) -> (Expr, Expr) {
22 if format!("{:?}", a) <= format!("{:?}", b) {
23 (a, b)
24 } else {
25 (b, a)
26 }
27}
28#[cfg(test)]
29mod tests {
30 use super::*;
31 use crate::{Level, Name};
32 fn nat() -> Expr {
33 Expr::Const(Name::str("Nat"), vec![])
34 }
35 fn bool_expr() -> Expr {
36 Expr::Const(Name::str("Bool"), vec![])
37 }
38 fn int() -> Expr {
39 Expr::Const(Name::str("Int"), vec![])
40 }
41 #[test]
42 fn test_equiv_reflexive() {
43 let mut mgr = EquivManager::new();
44 assert!(mgr.is_equiv(&nat(), &nat()));
45 }
46 #[test]
47 fn test_add_and_check_equiv() {
48 let mut mgr = EquivManager::new();
49 mgr.add_equiv(&nat(), &bool_expr());
50 assert!(mgr.is_equiv(&nat(), &bool_expr()));
51 assert!(mgr.is_equiv(&bool_expr(), &nat()));
52 }
53 #[test]
54 fn test_equiv_transitivity() {
55 let mut mgr = EquivManager::new();
56 mgr.add_equiv(&nat(), &bool_expr());
57 mgr.add_equiv(&bool_expr(), &int());
58 assert!(mgr.is_equiv(&nat(), &int()));
59 }
60 #[test]
61 fn test_failure_cache() {
62 let mut mgr = EquivManager::new();
63 mgr.add_failure(&nat(), &bool_expr());
64 assert!(mgr.is_failure(&nat(), &bool_expr()));
65 assert!(mgr.is_failure(&bool_expr(), &nat()));
66 assert!(!mgr.is_failure(&nat(), &int()));
67 }
68 #[test]
69 fn test_not_equiv() {
70 let mut mgr = EquivManager::new();
71 assert!(!mgr.is_equiv(&nat(), &bool_expr()));
72 }
73 #[test]
74 fn test_clear() {
75 let mut mgr = EquivManager::new();
76 mgr.add_equiv(&nat(), &bool_expr());
77 mgr.add_failure(&nat(), &int());
78 assert_eq!(mgr.num_equiv(), 1);
79 assert_eq!(mgr.num_failures(), 1);
80 mgr.clear();
81 assert_eq!(mgr.num_equiv(), 0);
82 assert_eq!(mgr.num_failures(), 0);
83 assert!(!mgr.is_equiv(&nat(), &bool_expr()));
84 }
85 #[test]
86 fn test_many_equivalences() {
87 let mut mgr = EquivManager::new();
88 let exprs: Vec<Expr> = (0..10)
89 .map(|i| Expr::Const(Name::str(format!("T{}", i)), vec![]))
90 .collect();
91 for i in 0..9 {
92 mgr.add_equiv(&exprs[i], &exprs[i + 1]);
93 }
94 assert!(mgr.is_equiv(&exprs[0], &exprs[9]));
95 assert!(mgr.is_equiv(&exprs[3], &exprs[7]));
96 }
97 #[test]
98 fn test_sort_equivalence() {
99 let mut mgr = EquivManager::new();
100 let s0 = Expr::Sort(Level::zero());
101 let s1 = Expr::Sort(Level::succ(Level::zero()));
102 mgr.add_equiv(&s0, &s1);
103 assert!(mgr.is_equiv(&s0, &s1));
104 }
105}
106#[cfg(test)]
107mod equiv_extended_tests {
108 use super::*;
109 use crate::Name;
110 fn nat() -> Expr {
111 Expr::Const(Name::str("Nat"), vec![])
112 }
113 fn bool_expr() -> Expr {
114 Expr::Const(Name::str("Bool"), vec![])
115 }
116 fn int() -> Expr {
117 Expr::Const(Name::str("Int"), vec![])
118 }
119 fn str_ty() -> Expr {
120 Expr::Const(Name::str("String"), vec![])
121 }
122 #[test]
123 fn test_scoped_manager_basic() {
124 let mut mgr = ScopedEquivManager::new();
125 mgr.add_equiv(&nat(), &bool_expr());
126 assert!(mgr.is_equiv(&nat(), &bool_expr()));
127 assert_eq!(mgr.scope_depth(), 1);
128 }
129 #[test]
130 fn test_scoped_manager_push_pop() {
131 let mut mgr = ScopedEquivManager::new();
132 mgr.add_equiv(&nat(), &bool_expr());
133 mgr.push_scope();
134 assert_eq!(mgr.scope_depth(), 2);
135 mgr.add_equiv(&nat(), &int());
136 assert!(mgr.is_equiv(&nat(), &int()));
137 mgr.pop_scope();
138 assert_eq!(mgr.scope_depth(), 1);
139 assert!(mgr.is_equiv(&nat(), &bool_expr()));
140 }
141 #[test]
142 fn test_scoped_manager_total_equivs() {
143 let mut mgr = ScopedEquivManager::new();
144 mgr.add_equiv(&nat(), &bool_expr());
145 mgr.push_scope();
146 mgr.add_equiv(&int(), &str_ty());
147 assert_eq!(mgr.total_equivs(), 2);
148 }
149 #[test]
150 fn test_equiv_stats_default() {
151 let stats = EquivStats::new();
152 assert_eq!(stats.total_queries, 0);
153 assert_eq!(stats.hit_rate(), 1.0);
154 }
155 #[test]
156 fn test_equiv_stats_recording() {
157 let mut stats = EquivStats::new();
158 stats.record_equiv_hit();
159 stats.record_equiv_hit();
160 stats.record_miss();
161 assert_eq!(stats.total_queries, 3);
162 assert_eq!(stats.equiv_hits, 2);
163 assert!((stats.hit_rate() - 2.0 / 3.0).abs() < 1e-9);
164 }
165 #[test]
166 fn test_instrumented_manager() {
167 let mut mgr = InstrumentedEquivManager::new();
168 mgr.add_equiv(&nat(), &bool_expr());
169 let result = mgr.is_equiv(&nat(), &bool_expr());
170 assert!(result);
171 assert_eq!(mgr.stats().equiv_additions, 1);
172 assert_eq!(mgr.stats().total_queries, 1);
173 }
174 #[test]
175 fn test_instrumented_manager_clear() {
176 let mut mgr = InstrumentedEquivManager::new();
177 mgr.add_equiv(&nat(), &bool_expr());
178 mgr.clear();
179 assert_eq!(mgr.stats().total_queries, 0);
180 assert_eq!(mgr.stats().equiv_additions, 0);
181 }
182 #[test]
183 fn test_equiv_query() {
184 let mut mgr = EquivManager::new();
185 mgr.add_failure(&nat(), &bool_expr());
186 let query = EquivQuery::new(&mgr);
187 assert!(query.is_known_failure(&nat(), &bool_expr()));
188 assert!(!query.is_known_failure(&nat(), &int()));
189 assert_eq!(query.num_failures(), 1);
190 }
191 #[test]
192 fn test_scoped_manager_pop_at_root() {
193 let mut mgr = ScopedEquivManager::new();
194 mgr.pop_scope();
195 assert_eq!(mgr.scope_depth(), 1);
196 }
197 #[test]
198 fn test_instrumented_add_failure() {
199 let mut mgr = InstrumentedEquivManager::new();
200 mgr.add_failure(&nat(), &bool_expr());
201 assert!(mgr.is_failure(&nat(), &bool_expr()));
202 assert_eq!(mgr.stats().failure_additions, 1);
203 }
204}
205pub fn compute_equiv_classes(exprs: &[Expr], pairs: &[(Expr, Expr)]) -> Vec<Vec<usize>> {
210 let n = exprs.len();
211 let mut parent: Vec<usize> = (0..n).collect();
212 fn find(parent: &mut Vec<usize>, x: usize) -> usize {
213 if parent[x] != x {
214 parent[x] = find(parent, parent[x]);
215 }
216 parent[x]
217 }
218 fn union(parent: &mut Vec<usize>, x: usize, y: usize) {
219 let rx = find(parent, x);
220 let ry = find(parent, y);
221 if rx != ry {
222 parent[rx] = ry;
223 }
224 }
225 for (a, b) in pairs {
226 let ia = exprs.iter().position(|e| e == a);
227 let ib = exprs.iter().position(|e| e == b);
228 if let (Some(i), Some(j)) = (ia, ib) {
229 union(&mut parent, i, j);
230 }
231 }
232 let mut classes: std::collections::HashMap<usize, Vec<usize>> =
233 std::collections::HashMap::new();
234 for i in 0..n {
235 let root = find(&mut parent, i);
236 classes.entry(root).or_default().push(i);
237 }
238 classes.into_values().collect()
239}
240#[cfg(test)]
241mod persistent_equiv_tests {
242 use super::*;
243 use crate::Name;
244 fn nat() -> Expr {
245 Expr::Const(Name::str("Nat"), vec![])
246 }
247 fn bool_expr() -> Expr {
248 Expr::Const(Name::str("Bool"), vec![])
249 }
250 fn int() -> Expr {
251 Expr::Const(Name::str("Int"), vec![])
252 }
253 #[test]
254 fn test_persistent_manager_basic() {
255 let mut mgr = PersistentEquivManager::new();
256 mgr.add_equiv(&nat(), &bool_expr());
257 assert!(mgr.is_equiv(&nat(), &bool_expr()));
258 assert!(mgr.is_equiv(&bool_expr(), &nat()));
259 assert!(!mgr.is_equiv(&nat(), &int()));
260 }
261 #[test]
262 fn test_persistent_manager_reflexive() {
263 let mgr = PersistentEquivManager::new();
264 assert!(mgr.is_equiv(&nat(), &nat()));
265 }
266 #[test]
267 fn test_persistent_manager_no_dups() {
268 let mut mgr = PersistentEquivManager::new();
269 mgr.add_equiv(&nat(), &bool_expr());
270 mgr.add_equiv(&nat(), &bool_expr());
271 assert_eq!(mgr.len(), 1);
272 }
273 #[test]
274 fn test_persistent_manager_serialize() {
275 let mut mgr = PersistentEquivManager::new();
276 mgr.add_equiv(&nat(), &bool_expr());
277 let serialized = mgr.serialize();
278 assert_eq!(serialized.len(), 1);
279 }
280 #[test]
281 fn test_compute_equiv_classes_basic() {
282 let exprs = vec![
283 Expr::Const(Name::str("A"), vec![]),
284 Expr::Const(Name::str("B"), vec![]),
285 Expr::Const(Name::str("C"), vec![]),
286 ];
287 let pairs = vec![(exprs[0].clone(), exprs[1].clone())];
288 let classes = compute_equiv_classes(&exprs, &pairs);
289 assert_eq!(classes.len(), 2);
290 let sizes: std::collections::HashSet<usize> = classes.iter().map(|c| c.len()).collect();
291 assert!(sizes.contains(&2));
292 assert!(sizes.contains(&1));
293 }
294 #[test]
295 fn test_compute_equiv_classes_all_separate() {
296 let exprs = vec![
297 Expr::Const(Name::str("A"), vec![]),
298 Expr::Const(Name::str("B"), vec![]),
299 ];
300 let classes = compute_equiv_classes(&exprs, &[]);
301 assert_eq!(classes.len(), 2);
302 assert!(classes.iter().all(|c| c.len() == 1));
303 }
304 #[test]
305 fn test_compute_equiv_classes_all_same() {
306 let nat = Expr::Const(Name::str("A"), vec![]);
307 let bool_e = Expr::Const(Name::str("B"), vec![]);
308 let int_e = Expr::Const(Name::str("C"), vec![]);
309 let exprs = vec![nat.clone(), bool_e.clone(), int_e.clone()];
310 let pairs = vec![
311 (nat.clone(), bool_e.clone()),
312 (bool_e.clone(), int_e.clone()),
313 ];
314 let classes = compute_equiv_classes(&exprs, &pairs);
315 assert_eq!(classes.len(), 1);
316 assert_eq!(classes[0].len(), 3);
317 }
318 #[test]
319 fn test_persistent_manager_is_empty() {
320 let mgr = PersistentEquivManager::new();
321 assert!(mgr.is_empty());
322 let mut mgr2 = PersistentEquivManager::new();
323 mgr2.add_equiv(&nat(), &bool_expr());
324 assert!(!mgr2.is_empty());
325 }
326 #[test]
327 fn test_persistent_manager_sorted_output() {
328 let mut mgr = PersistentEquivManager::new();
329 mgr.add_equiv(&int(), &nat());
330 mgr.add_equiv(&bool_expr(), &nat());
331 let serialized = mgr.serialize();
332 for i in 0..serialized.len().saturating_sub(1) {
333 assert!(serialized[i] <= serialized[i + 1]);
334 }
335 }
336}
337#[allow(dead_code)]
342pub fn transitive_closure(pairs: &[(usize, usize)], n: usize) -> Vec<(usize, usize)> {
343 let mut parent: Vec<usize> = (0..n).collect();
344 fn find(parent: &mut Vec<usize>, x: usize) -> usize {
345 if parent[x] != x {
346 parent[x] = find(parent, parent[x]);
347 }
348 parent[x]
349 }
350 for &(a, b) in pairs {
351 if a < n && b < n {
352 let ra = find(&mut parent, a);
353 let rb = find(&mut parent, b);
354 if ra != rb {
355 parent[ra] = rb;
356 }
357 }
358 }
359 let mut result = Vec::new();
360 for i in 0..n {
361 for j in (i + 1)..n {
362 if find(&mut parent, i) == find(&mut parent, j) {
363 result.push((i, j));
364 }
365 }
366 }
367 result
368}
369#[allow(dead_code)]
373pub fn compute_representatives(pairs: &[(usize, usize)], n: usize) -> Vec<usize> {
374 let mut parent: Vec<usize> = (0..n).collect();
375 fn find(parent: &mut Vec<usize>, x: usize) -> usize {
376 if parent[x] != x {
377 parent[x] = find(parent, parent[x]);
378 }
379 parent[x]
380 }
381 for &(a, b) in pairs {
382 if a < n && b < n {
383 let ra = find(&mut parent, a);
384 let rb = find(&mut parent, b);
385 if ra != rb {
386 parent[ra] = rb;
387 }
388 }
389 }
390 (0..n).map(|i| find(&mut parent, i)).collect()
391}
392#[allow(dead_code)]
396pub fn find_classes(pairs: &[(usize, usize)], n: usize) -> Vec<Vec<usize>> {
397 let repr = compute_representatives(pairs, n);
398 let mut classes: std::collections::HashMap<usize, Vec<usize>> =
399 std::collections::HashMap::new();
400 for (i, r) in repr.into_iter().enumerate() {
401 classes.entry(r).or_default().push(i);
402 }
403 classes.into_values().collect()
404}
405#[cfg(test)]
406mod extra_equiv_tests {
407 use super::*;
408 use crate::Name;
409 #[test]
410 fn test_transitive_closure_basic() {
411 let pairs = vec![(0, 1), (1, 2)];
412 let closure = transitive_closure(&pairs, 3);
413 assert!(closure.contains(&(0, 2)));
414 }
415 #[test]
416 fn test_transitive_closure_empty() {
417 let closure = transitive_closure(&[], 3);
418 assert!(closure.is_empty());
419 }
420 #[test]
421 fn test_compute_representatives_basic() {
422 let pairs = vec![(0, 1)];
423 let repr = compute_representatives(&pairs, 3);
424 assert_eq!(repr[0], repr[1]);
425 assert_ne!(repr[0], repr[2]);
426 }
427 #[test]
428 fn test_find_classes_two_classes() {
429 let pairs = vec![(0, 1), (2, 3)];
430 let classes = find_classes(&pairs, 4);
431 assert_eq!(classes.len(), 2);
432 }
433 #[test]
434 fn test_index_equiv_manager_basic() {
435 let mut mgr = IndexEquivManager::new(5);
436 mgr.union(0, 1);
437 mgr.union(1, 2);
438 assert!(mgr.same_class(0, 2));
439 assert!(!mgr.same_class(0, 3));
440 }
441 #[test]
442 fn test_index_equiv_manager_num_classes() {
443 let mut mgr = IndexEquivManager::new(5);
444 assert_eq!(mgr.num_classes(), 5);
445 mgr.union(0, 1);
446 mgr.union(2, 3);
447 assert_eq!(mgr.num_classes(), 3);
448 }
449 #[test]
450 fn test_index_equiv_manager_find_self() {
451 let mut mgr = IndexEquivManager::new(3);
452 assert_eq!(mgr.find(0), 0);
453 }
454 #[test]
455 fn test_equiv_manager_default() {
456 let mgr = EquivManager::default();
457 assert_eq!(mgr.num_equiv(), 0);
458 assert_eq!(mgr.num_failures(), 0);
459 }
460 #[test]
461 fn test_persistent_equiv_manager_clone() {
462 let mut mgr = PersistentEquivManager::new();
463 mgr.add_equiv(
464 &Expr::Const(Name::str("A"), vec![]),
465 &Expr::Const(Name::str("B"), vec![]),
466 );
467 let cloned = mgr.clone();
468 assert_eq!(cloned.len(), 1);
469 }
470 #[test]
471 fn test_scoped_manager_reflexive() {
472 let mut mgr = ScopedEquivManager::new();
473 let e = Expr::Const(Name::str("A"), vec![]);
474 assert!(mgr.is_equiv(&e, &e));
475 }
476 #[test]
477 fn test_union_find_all_separate() {
478 let pairs: Vec<(usize, usize)> = vec![];
479 let repr = compute_representatives(&pairs, 4);
480 let classes: std::collections::HashSet<_> = repr.into_iter().collect();
481 assert_eq!(classes.len(), 4);
482 }
483 #[test]
484 fn test_find_classes_all_same() {
485 let pairs = vec![(0, 1), (1, 2), (2, 3)];
486 let classes = find_classes(&pairs, 4);
487 assert_eq!(classes.len(), 1);
488 assert_eq!(classes[0].len(), 4);
489 }
490}
491#[cfg(test)]
492mod tests_equiv_extra {
493 use super::*;
494 #[test]
495 fn test_equiv_class() {
496 let mut ec = EquivClass::singleton(0);
497 ec.members.push(1);
498 assert!(ec.contains(0));
499 assert!(ec.contains(1));
500 assert!(!ec.contains(2));
501 assert_eq!(ec.size(), 2);
502 }
503 #[test]
504 fn test_union_find() {
505 let mut uf = UnionFind::new(5);
506 assert_eq!(uf.num_classes(), 5);
507 assert!(uf.union(0, 1));
508 assert!(uf.union(2, 3));
509 assert_eq!(uf.num_classes(), 3);
510 assert!(uf.same(0, 1));
511 assert!(!uf.same(0, 2));
512 uf.union(1, 2);
513 assert!(uf.same(0, 3));
514 }
515 #[test]
516 fn test_equivalence_table() {
517 let mut tbl = EquivalenceTable::new(8);
518 tbl.register(100);
519 tbl.register(200);
520 assert!(!tbl.equiv(100, 200));
521 tbl.merge(100, 200);
522 assert!(tbl.equiv(100, 200));
523 }
524 #[test]
525 fn test_expr_equiv_cache() {
526 let mut cache = ExprEquivCache::new();
527 assert_eq!(cache.query(1, 2), None);
528 cache.mark_equal(1, 2);
529 assert_eq!(cache.query(1, 2), Some(true));
530 assert_eq!(cache.query(2, 1), Some(true));
531 cache.mark_unequal(3, 4);
532 assert_eq!(cache.query(3, 4), Some(false));
533 assert_eq!(cache.proven_count(), 1);
534 }
535 #[test]
536 fn test_equiv_manager_stats() {
537 let mut stats = EquivManagerStats::new();
538 stats.checks = 100;
539 stats.hits = 80;
540 assert!((stats.hit_rate() - 0.8).abs() < 1e-9);
541 }
542}
543#[cfg(test)]
544mod tests_equiv_proof {
545 use super::*;
546 #[test]
547 fn test_equiv_proof_term() {
548 let refl = EquivProofTerm::Refl(42);
549 assert_eq!(refl.depth(), 0);
550 assert!(refl.is_refl());
551 let symm = EquivProofTerm::Symm(Box::new(EquivProofTerm::Axiom("h".into())));
552 assert_eq!(symm.depth(), 1);
553 assert!(!symm.is_refl());
554 }
555 #[test]
556 fn test_checked_equiv() {
557 let eq = CheckedEquiv::refl(99);
558 assert!(eq.is_trivial());
559 assert!(eq.proof().is_refl());
560 let ax = CheckedEquiv::by_axiom(1, 2, "comm");
561 assert!(!ax.is_trivial());
562 assert_eq!(ax.lhs(), 1);
563 assert_eq!(ax.rhs(), 2);
564 }
565}
566#[cfg(test)]
567mod tests_symmetric_relation {
568 use super::*;
569 #[test]
570 fn test_symmetric_relation() {
571 let mut rel = SymmetricRelation::new();
572 rel.add(1, 2);
573 assert!(rel.contains(1, 2));
574 assert!(rel.contains(2, 1));
575 assert!(!rel.contains(1, 3));
576 assert_eq!(rel.len(), 1);
577 }
578}
579#[cfg(test)]
580mod tests_common_infra {
581 use super::*;
582 #[test]
583 fn test_event_counter() {
584 let mut ec = EventCounter::new();
585 ec.inc("hit");
586 ec.inc("hit");
587 ec.inc("miss");
588 assert_eq!(ec.get("hit"), 2);
589 assert_eq!(ec.get("miss"), 1);
590 assert_eq!(ec.total(), 3);
591 ec.reset();
592 assert_eq!(ec.total(), 0);
593 }
594 #[test]
595 fn test_diag_meta() {
596 let mut m = DiagMeta::new();
597 m.add("os", "linux");
598 m.add("arch", "x86_64");
599 assert_eq!(m.get("os"), Some("linux"));
600 assert_eq!(m.len(), 2);
601 let s = m.to_string();
602 assert!(s.contains("os=linux"));
603 }
604 #[test]
605 fn test_scope_stack() {
606 let mut ss = ScopeStack::new();
607 ss.push("Nat");
608 ss.push("succ");
609 assert_eq!(ss.current(), Some("succ"));
610 assert_eq!(ss.depth(), 2);
611 assert_eq!(ss.path(), "Nat.succ");
612 ss.pop();
613 assert_eq!(ss.current(), Some("Nat"));
614 }
615 #[test]
616 fn test_annotation_table() {
617 let mut tbl = AnnotationTable::new();
618 tbl.annotate("doc", "first line");
619 tbl.annotate("doc", "second line");
620 assert_eq!(tbl.get_all("doc").len(), 2);
621 assert!(tbl.has("doc"));
622 assert!(!tbl.has("other"));
623 }
624 #[test]
625 fn test_work_stack() {
626 let mut ws = WorkStack::new();
627 ws.push(1u32);
628 ws.push(2u32);
629 assert_eq!(ws.pop(), Some(2));
630 assert_eq!(ws.len(), 1);
631 }
632 #[test]
633 fn test_work_queue() {
634 let mut wq = WorkQueue::new();
635 wq.enqueue(1u32);
636 wq.enqueue(2u32);
637 assert_eq!(wq.dequeue(), Some(1));
638 assert_eq!(wq.len(), 1);
639 }
640 #[test]
641 fn test_sparse_bit_set() {
642 let mut bs = SparseBitSet::new(128);
643 bs.set(5);
644 bs.set(63);
645 bs.set(64);
646 assert!(bs.get(5));
647 assert!(bs.get(63));
648 assert!(bs.get(64));
649 assert!(!bs.get(0));
650 assert_eq!(bs.count_ones(), 3);
651 bs.clear(5);
652 assert!(!bs.get(5));
653 }
654 #[test]
655 fn test_loop_clock() {
656 let mut clk = LoopClock::start();
657 for _ in 0..10 {
658 clk.tick();
659 }
660 assert_eq!(clk.iters(), 10);
661 assert!(clk.elapsed_us() >= 0.0);
662 }
663}
664#[cfg(test)]
665mod tests_extra_data_structures {
666 use super::*;
667 #[test]
668 fn test_simple_lru_cache() {
669 let mut cache: SimpleLruCache<&str, u32> = SimpleLruCache::new(3);
670 cache.put("a", 1);
671 cache.put("b", 2);
672 cache.put("c", 3);
673 assert_eq!(cache.get(&"a"), Some(&1));
674 cache.put("d", 4);
675 assert!(cache.len() <= 3);
676 }
677 #[test]
678 fn test_string_interner() {
679 let mut si = StringInterner::new();
680 let id1 = si.intern("hello");
681 let id2 = si.intern("hello");
682 assert_eq!(id1, id2);
683 let id3 = si.intern("world");
684 assert_ne!(id1, id3);
685 assert_eq!(si.get(id1), Some("hello"));
686 assert_eq!(si.len(), 2);
687 }
688 #[test]
689 fn test_frequency_table() {
690 let mut ft = FrequencyTable::new();
691 ft.record("a");
692 ft.record("b");
693 ft.record("a");
694 ft.record("a");
695 assert_eq!(ft.freq(&"a"), 3);
696 assert_eq!(ft.freq(&"b"), 1);
697 assert_eq!(ft.most_frequent(), Some((&"a", 3)));
698 assert_eq!(ft.total(), 4);
699 assert_eq!(ft.distinct(), 2);
700 }
701 #[test]
702 fn test_bimap() {
703 let mut bm: BiMap<u32, &str> = BiMap::new();
704 bm.insert(1, "one");
705 bm.insert(2, "two");
706 assert_eq!(bm.get_b(&1), Some(&"one"));
707 assert_eq!(bm.get_a(&"two"), Some(&2));
708 assert_eq!(bm.len(), 2);
709 }
710}
711#[cfg(test)]
712mod tests_interval_set {
713 use super::*;
714 #[test]
715 fn test_interval_set() {
716 let mut s = IntervalSet::new();
717 s.add(1, 5);
718 s.add(3, 8);
719 assert_eq!(s.num_intervals(), 1);
720 assert_eq!(s.cardinality(), 8);
721 assert!(s.contains(4));
722 assert!(!s.contains(9));
723 s.add(10, 15);
724 assert_eq!(s.num_intervals(), 2);
725 }
726}
727#[allow(dead_code)]
729pub fn now_us() -> Timestamp {
730 let us = std::time::SystemTime::UNIX_EPOCH
731 .elapsed()
732 .map(|d| d.as_micros() as u64)
733 .unwrap_or(0);
734 Timestamp::from_us(us)
735}
736#[cfg(test)]
737mod tests_typed_utilities {
738 use super::*;
739 #[test]
740 fn test_timestamp() {
741 let t1 = Timestamp::from_us(1000);
742 let t2 = Timestamp::from_us(1500);
743 assert_eq!(t2.elapsed_since(t1), 500);
744 assert!(t1 < t2);
745 }
746 #[test]
747 fn test_typed_id() {
748 struct Foo;
749 let id: TypedId<Foo> = TypedId::new(42);
750 assert_eq!(id.raw(), 42);
751 assert_eq!(format!("{id}"), "#42");
752 }
753 #[test]
754 fn test_id_dispenser() {
755 struct Bar;
756 let mut disp: IdDispenser<Bar> = IdDispenser::new();
757 let a = disp.next();
758 let b = disp.next();
759 assert_eq!(a.raw(), 0);
760 assert_eq!(b.raw(), 1);
761 assert_eq!(disp.count(), 2);
762 }
763 #[test]
764 fn test_slot() {
765 let mut slot: Slot<u32> = Slot::empty();
766 assert!(!slot.is_filled());
767 slot.fill(99);
768 assert!(slot.is_filled());
769 assert_eq!(slot.get(), Some(&99));
770 let v = slot.take();
771 assert_eq!(v, Some(99));
772 assert!(!slot.is_filled());
773 }
774 #[test]
775 #[should_panic]
776 fn test_slot_double_fill() {
777 let mut slot: Slot<u32> = Slot::empty();
778 slot.fill(1);
779 slot.fill(2);
780 }
781 #[test]
782 fn test_memo_slot() {
783 let mut ms: MemoSlot<u32> = MemoSlot::new();
784 assert!(!ms.is_cached());
785 let val = ms.get_or_compute(|| 42);
786 assert_eq!(*val, 42);
787 assert!(ms.is_cached());
788 ms.invalidate();
789 assert!(!ms.is_cached());
790 }
791}
792#[cfg(test)]
793mod tests_ring_buffer {
794 use super::*;
795 #[test]
796 fn test_ring_buffer() {
797 let mut rb = RingBuffer::new(3);
798 rb.push(1u32);
799 rb.push(2u32);
800 rb.push(3u32);
801 assert!(rb.is_full());
802 rb.push(4u32);
803 assert_eq!(rb.pop(), Some(2));
804 assert_eq!(rb.len(), 2);
805 }
806 #[test]
807 fn test_before_after() {
808 let ba = BeforeAfter::new(10u32, 10u32);
809 assert!(ba.unchanged());
810 let ba2 = BeforeAfter::new(10u32, 20u32);
811 assert!(!ba2.unchanged());
812 }
813 #[test]
814 fn test_seq_num() {
815 let s = SeqNum::ZERO;
816 assert_eq!(s.value(), 0);
817 let s2 = s.next();
818 assert_eq!(s2.value(), 1);
819 assert!(s < s2);
820 }
821 #[test]
822 fn test_generation() {
823 let g0 = Generation::INITIAL;
824 let g1 = g0.advance();
825 assert_eq!(g0.number(), 0);
826 assert_eq!(g1.number(), 1);
827 assert_ne!(g0, g1);
828 }
829}