1#[cfg(test)]
3mod tests {
4 use std::collections::HashSet;
5 use std::vec;
6 use std::vec::Vec;
7
8 #[test]
9 fn basic_test() {
10 use variadics::var_expr;
11
12 use crate::GhtType;
13 use crate::ght::GeneralizedHashTrieNode;
14
15 type MyTrie1 = GhtType!(u32, u32 => &'static str: VariadicCountedHashSetStd);
17
18 fn ght_type<T: GeneralizedHashTrieNode>() {}
19 ght_type::<MyTrie1>();
20
21 let htrie1 = MyTrie1::new_from(vec![var_expr!(42, 314, "hello")]);
22 assert!(htrie1.contains(var_expr!(&42, &314, &"hello")));
23 assert_eq!(htrie1.recursive_iter().count(), 1);
24
25 type MyTrie2 = GhtType!(u32 => u32: VariadicCountedHashSetStd);
26 let htrie2 = MyTrie2::new_from(vec![var_expr!(42, 314)]);
27 assert!(htrie2.contains(var_expr!(&42, &314)));
28 assert_eq!(htrie1.recursive_iter().count(), 1);
29
30 type MyTrie3 = GhtType!(u32, u64, u16 => &'static str: VariadicCountedHashSetStd);
31 let htrie3 = MyTrie3::new_from(vec![
32 var_expr!(123, 2, 5, "hello"),
33 var_expr!(50, 1, 1, "hi"),
34 var_expr!(5, 1, 7, "hi"),
35 var_expr!(5, 1, 7, "bye"),
36 ]);
37 assert!(htrie3.contains(var_expr!(&50, &1, &1, &"hi")));
38 assert_eq!(htrie3.recursive_iter().count(), 4);
39 }
40 #[test]
41 fn test_ght_node_type_macro() {
42 use variadics::var_expr;
43
44 use crate::GhtType;
45 use crate::ght::GeneralizedHashTrieNode;
46
47 type LilTrie = GhtType!(() => u32: VariadicCountedHashSetStd);
49 let _j = LilTrie::default();
50 let _l = LilTrie::new_from(vec![var_expr!(1)]);
51
52 type LilTrie2 = GhtType!(() => u32, u64: VariadicCountedHashSetStd);
54 let _l = LilTrie2::default();
55 let _l = LilTrie2::new_from(vec![var_expr!(1, 1)]);
56
57 type KeyNoValTrie = GhtType!(u32 => (): VariadicCountedHashSetStd);
59 let l = KeyNoValTrie::new_from(vec![var_expr!(1)]);
60 let _: KeyNoValTrie = l;
61
62 type SmallTrie = GhtType!(u32 => &'static str: VariadicCountedHashSetStd);
64 type SmallKeyedTrie = GhtType!(u32 => &'static str: VariadicCountedHashSetStd);
65 let l = SmallTrie::new_from(vec![var_expr!(1, "hello")]);
66 let _: SmallKeyedTrie = l;
67
68 type SmallKeyLongValTrie =
70 GhtType!(u32 => u64, u16, &'static str: VariadicCountedHashSetStd);
71 let _x = SmallKeyLongValTrie::new_from(vec![var_expr!(1, 999, 222, "hello")]);
72
73 type LongKeyNoValTrie = GhtType!(u32, u64 => (): VariadicCountedHashSetStd);
75 let l = LongKeyNoValTrie::new_from(vec![var_expr!(1, 999)]);
76 let _: LongKeyNoValTrie = l;
77
78 type LongKeySmallValTrie = GhtType!(u32, u16 => &'static str: VariadicCountedHashSetStd);
80 type LongKeySmallValKeyedTrie =
81 GhtType!(u32, u16 => &'static str: VariadicCountedHashSetStd);
82 let x = LongKeySmallValTrie::new_from(vec![var_expr!(1, 314, "hello")]);
83 let _: LongKeySmallValKeyedTrie = x;
84 let _ = LongKeySmallValTrie::new_from(vec![var_expr!(1, 314, "hello")]);
85
86 type LongKeyLongValTrie =
88 GhtType!(u32, u64 => u16, &'static str: VariadicCountedHashSetStd);
89 let _x = LongKeyLongValTrie::new_from(vec![var_expr!(1, 999, 222, "hello")]);
90 }
91
92 #[test]
93 fn test_insert() {
94 use variadics::var_expr;
95
96 use crate::GhtType;
97 use crate::ght::GeneralizedHashTrieNode;
98
99 type MyGht = GhtType!(u16, u32 => u64: VariadicCountedHashSetStd);
100 let mut htrie = MyGht::default();
101 htrie.insert(var_expr!(42, 314, 43770));
102 assert_eq!(htrie.recursive_iter().count(), 1);
103 assert_eq!(MyGht::HEIGHT, 2);
104 htrie.insert(var_expr!(42, 315, 43770));
105 assert_eq!(htrie.recursive_iter().count(), 2);
106 htrie.insert(var_expr!(42, 314, 30619));
107 assert_eq!(htrie.recursive_iter().count(), 3);
108 htrie.insert(var_expr!(43, 10, 600));
109 assert_eq!(htrie.recursive_iter().count(), 4);
110 assert!(htrie.contains(var_expr!(&42, &314, &30619)));
111 assert!(htrie.contains(var_expr!(&42, &315, &43770)));
112 assert!(htrie.contains(var_expr!(&43, &10, &600)));
113
114 type LongKeyLongValTrie =
115 GhtType!(u32, u64 => u16, &'static str: VariadicCountedHashSetStd);
116 let mut htrie = LongKeyLongValTrie::new_from(vec![var_expr!(1, 999, 222, "hello")]);
117 htrie.insert(var_expr!(1, 999, 111, "bye"));
118 htrie.insert(var_expr!(1, 1000, 123, "cya"));
119 assert!(htrie.contains(var_expr!(&1, &999, &222, &"hello")));
120 assert!(htrie.contains(var_expr!(&1, &999, &111, &"bye")));
121 assert!(htrie.contains(var_expr!(&1, &1000, &123, &"cya")));
122 }
123
124 #[test]
125 fn test_scale() {
126 use variadics::var_expr;
127
128 use crate::GhtType;
129 use crate::ght::GeneralizedHashTrieNode;
130
131 type MyGht = GhtType!(bool, usize, &'static str => i32: VariadicCountedHashSetStd);
132 let mut htrie = MyGht::new_from(vec![var_expr!(true, 1, "hello", -5)]);
133 assert_eq!(htrie.recursive_iter().count(), 1);
134 for i in 1..1000000 {
135 htrie.insert(var_expr!(true, 1, "hello", i));
136 }
137 assert_eq!(htrie.recursive_iter().count(), 1000000);
138 }
139
140 #[test]
141 fn test_contains() {
142 use variadics::{VariadicExt, var_expr};
143
144 use crate::GhtType;
145 use crate::ght::GeneralizedHashTrieNode;
146
147 type MyGht = GhtType!(u16, u32 => u64: VariadicCountedHashSetStd);
148 let htrie = MyGht::new_from(vec![var_expr!(42_u16, 314_u32, 43770_u64)]);
149 let x = var_expr!(&42, &314, &43770);
150 assert!(htrie.contains(x));
151 assert!(htrie.contains(var_expr!(42, 314, 43770).as_ref_var()));
152 assert!(htrie.contains(var_expr!(&42, &314, &43770)));
153 assert!(!htrie.contains(var_expr!(42, 314, 30619).as_ref_var()));
154 assert!(!htrie.contains(var_expr!(&42, &315, &43770)));
155 assert!(!htrie.contains(var_expr!(&43, &314, &43770)));
156 }
157
158 #[test]
159 fn test_get() {
160 use variadics::{VariadicExt, var_expr};
161
162 use crate::GhtType;
163 use crate::ght::{GeneralizedHashTrieNode, GhtGet};
164
165 type MyGht = GhtType!(u32, u32 => u32: VariadicCountedHashSetStd);
166 let ht_root = MyGht::new_from(vec![var_expr!(42, 314, 43770)]);
167
168 let inner = ht_root.get(&42).unwrap();
169 let t = inner.recursive_iter().next().unwrap();
170 assert_eq!(t, var_expr!(&42, &314, &43770));
171
172 let leaf = inner.get(&314).unwrap();
173 let t = leaf.recursive_iter().next().unwrap();
174 assert_eq!(t, var_expr!(42, 314, 43770).as_ref_var());
175 }
176
177 #[test]
178 fn test_iter() {
179 use variadics::var_expr;
180
181 use crate::GhtType;
182 use crate::ght::{GeneralizedHashTrieNode, GhtGet};
183 type MyGht = GhtType!(u32, u32 => u32: VariadicCountedHashSetStd);
184 let ht_root = MyGht::new_from(vec![var_expr!(42, 314, 43770)]);
185 let inner_key = ht_root.iter().next().unwrap();
186 let inner = ht_root.get(&inner_key).unwrap();
187 let t = inner.recursive_iter().next().unwrap();
188 assert_eq!(t, var_expr!(&42, &314, &43770));
189
190 let leaf_key = inner.iter().next().unwrap();
191 let leaf = inner.get(&leaf_key).unwrap();
192 let t = leaf.iter().next();
194 assert!(t.is_none());
195 }
196
197 #[test]
198 fn test_recursive_iter() {
199 use variadics::{VariadicExt, var_expr, var_type};
200
201 use crate::GhtType;
202 use crate::ght::GeneralizedHashTrieNode;
203
204 type MyGht = GhtType!(u32, u32 => u32: VariadicCountedHashSetStd);
205 type InputType = var_type!(u32, u32, u32);
206 type ResultType<'a> = var_type!(&'a u32, &'a u32, &'a u32);
207 let input: HashSet<InputType> = HashSet::from_iter(
208 [
209 (42, 314, 30619),
210 (42, 314, 43770),
211 (42, 315, 43770),
212 (43, 10, 600),
213 ]
214 .iter()
215 .map(|&(a, b, c)| var_expr!(a, b, c)),
216 );
217 let htrie = MyGht::new_from(input.clone());
218 #[expect(
219 clippy::disallowed_methods,
220 reason = "nondeterministic iteration order, fine to collect into set"
221 )]
222 let result = input.iter().map(|v| v.as_ref_var()).collect();
223 let v: HashSet<ResultType<'_>> = htrie.recursive_iter().collect();
224 assert_eq!(v, result);
225 }
226
227 #[test]
228 fn test_prefix_iter_leaf() {
229 use variadics::variadic_collections::VariadicCountedHashSetStd;
230 use variadics::{var_expr, var_type};
231
232 use crate::ght::{GeneralizedHashTrieNode, GhtLeaf, GhtPrefixIter};
233
234 type InputType = var_type!(u8, u16, u32);
235 type ResultType<'a> = var_type!(&'a u8, &'a u16, &'a u32);
236
237 let input: HashSet<InputType> = HashSet::from_iter(
238 [
239 (42, 314, 30619),
240 (42, 314, 43770),
241 (42, 315, 43770),
242 (43, 10, 600),
243 ]
244 .iter()
245 .map(|&(a, b, c)| var_expr!(a, b, c)),
246 );
247 let leaf =
248 GhtLeaf::<InputType, var_type!(u16, u32), VariadicCountedHashSetStd<InputType>>::new_from(
249 input.clone(),
250 );
251 let key = (); let v: HashSet<ResultType<'_>> = leaf.prefix_iter(key).collect();
254 #[expect(
255 clippy::disallowed_methods,
256 reason = "nondeterministic iteration order, fine to collect into set"
257 )]
258 let result = input
259 .iter()
260 .map(|t: &InputType| var_expr!(&t.0, &t.1.0, &t.1.1.0))
262 .collect();
263 assert_eq!(v, result);
264 }
265
266 #[test]
267 fn test_prefix_iter() {
268 use variadics::{VariadicExt, var_expr, var_type};
269
270 use crate::GhtType;
271 use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter};
272
273 type MyGht = GhtType!(u8, u16 => u32: VariadicCountedHashSetStd);
274 type InputType = var_type!(u8, u16, u32);
275 type ResultType<'a> = var_type!(&'a u8, &'a u16, &'a u32);
276 let input: HashSet<InputType> = HashSet::from_iter(
277 [
278 (42, 314, 30619),
279 (42, 314, 43770),
280 (42, 315, 43770),
281 (43, 10, 600),
282 ]
283 .iter()
284 .map(|&(a, b, c)| var_expr!(a, b, c)),
285 );
286 let htrie = MyGht::new_from(input.clone());
287
288 let v: HashSet<ResultType<'_>> =
289 htrie.prefix_iter(var_expr!(42, 315).as_ref_var()).collect();
290 let result = HashSet::from_iter([var_expr!(&42, &315, &43770)].iter().copied());
291 assert_eq!(v, result);
292
293 let v: HashSet<ResultType<'_>> = htrie.prefix_iter(var_expr!(42u8).as_ref_var()).collect();
294 #[expect(
295 clippy::disallowed_methods,
296 reason = "nondeterministic iteration order, fine to collect into set"
297 )]
298 let result = input
299 .iter()
300 .filter(|t: &&InputType| t.0 == 42)
301 .map(|t: &InputType| var_expr!(&t.0, &t.1.0, &t.1.1.0))
302 .collect();
303 assert_eq!(v, result);
304
305 for row in htrie.prefix_iter(var_expr!(42, 315, 43770).as_ref_var()) {
306 assert_eq!(row, var_expr!(&42, &315, &43770));
307 }
308 }
309
310 #[test]
311 fn test_prefix_iter_complex() {
312 use variadics::{VariadicExt, var_expr, var_type};
313
314 use crate::GhtType;
315 use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter};
316
317 type MyGht = GhtType!(bool, u32, &'static str => i32: VariadicCountedHashSetStd);
318 type InputType = var_type!(bool, u32, &'static str, i32);
319 type ResultType<'a> = var_type!(&'a bool, &'a u32, &'a &'static str, &'a i32);
320 let input: HashSet<InputType> = HashSet::from_iter(
321 [
322 (true, 1, "hello", -5),
323 (true, 1, "hi", -2),
324 (true, 1, "hi", -3),
325 (true, 1, "hi", -4),
326 (true, 1, "hi", -5),
327 (true, 2, "hello", 1),
328 (false, 10, "bye", 5),
329 ]
330 .iter()
331 .map(|&(a, b, c, d)| var_expr!(a, b, c, d)),
332 );
333
334 let htrie = MyGht::new_from(input.clone());
335
336 let v: HashSet<ResultType<'_>> = htrie
337 .prefix_iter(var_expr!(true, 1, "hi").as_ref_var())
338 .collect();
339 #[expect(
340 clippy::disallowed_methods,
341 reason = "nondeterministic iteration order, fine to collect into set"
342 )]
343 let result = input
344 .iter()
345 .filter(|t: &&InputType| t.0 && t.1.0 == 1 && t.1.1.0 == "hi")
346 .map(|t| t.as_ref_var())
348 .collect();
349 assert_eq!(v, result);
350
351 let v: HashSet<ResultType<'_>> = htrie.prefix_iter(var_expr!(true).as_ref_var()).collect();
352 #[expect(
353 clippy::disallowed_methods,
354 reason = "nondeterministic iteration order, fine to collect into set"
355 )]
356 let result = input
357 .iter()
358 .filter(|t: &&InputType| t.0)
359 .map(|t: &InputType| t.as_ref_var())
360 .collect();
361 assert_eq!(v, result);
362 }
363
364 #[test]
365 fn test_merge() {
366 use variadics::{var_expr, var_type};
367
368 use crate::ght::GeneralizedHashTrieNode;
369 use crate::{GhtType, Merge};
370
371 type MyGht = GhtType!(u32, u64 => u16, &'static str: VariadicHashSetStd);
372
373 let mut test_ght1 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]);
374 let test_ght2 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]);
375
376 assert_eq!(
377 test_ght1
378 .recursive_iter()
379 .collect::<Vec<var_type!(&u32, &u64, &u16, &&'static str)>>()
380 .len(),
381 1
382 );
383 test_ght1.merge(test_ght2.clone());
384 assert_eq!(
386 test_ght1
387 .recursive_iter()
388 .collect::<Vec<var_type!(&u32, &u64, &u16, &&'static str)>>()
389 .len(),
390 1
391 );
392 assert!(!test_ght1.merge(test_ght2.clone()));
393
394 let mut test_ght1 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]);
395 let mut test_ght2 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]);
396 test_ght1.merge(test_ght2.clone());
397
398 test_ght1.insert(var_expr!(42, 314, 20, "goodbye"));
399 test_ght2.insert(var_expr!(42, 314, 20, "again"));
400
401 assert!(test_ght1.merge(test_ght2.clone()));
403 for k in test_ght2.recursive_iter() {
404 assert!(test_ght1.contains(k))
405 }
406 }
407
408 #[test]
409 fn test_node_lattice() {
410 use variadics::var_expr;
411
412 use crate::ght::GeneralizedHashTrieNode;
413 use crate::{GhtType, NaiveLatticeOrd};
414
415 type MyGht = GhtType!(u32, u64 => u16, &'static str: VariadicHashSetStd);
416 type MyGhtNode = GhtType!(u32, u64 => u16, &'static str: VariadicHashSetStd);
417
418 let mut test_vec: Vec<MyGhtNode> = Vec::new();
419
420 let empty_ght = MyGht::new_from(vec![]);
421 let test_ght1 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]);
422 let mut test_ght2 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]);
423 test_ght2.insert(var_expr!(42, 314, 20, "again"));
424 let mut test_ght3 = test_ght2.clone();
425 test_ght3.insert(var_expr!(42, 400, 1, "level 2"));
426 let mut test_ght4 = test_ght3.clone();
427 test_ght4.insert(var_expr!(43, 1, 1, "level 1"));
428
429 let test_vec_wrap = [empty_ght, test_ght1, test_ght2, test_ght3, test_ght4];
430
431 for ght in test_vec_wrap.iter().cloned() {
432 ght.naive_cmp(&ght.clone());
433 test_vec.push(ght);
434 }
435 crate::test::check_all(&test_vec);
436 crate::test::check_all(&test_vec_wrap);
437 }
438
439 #[test]
440 fn test_partial_cmp_incomparable_children() {
441 use std::cmp::Ordering::{Equal, Greater, Less};
442
443 use variadics::var_expr;
444
445 use crate::GhtType;
446 use crate::ght::GeneralizedHashTrieNode;
447
448 type MyGht = GhtType!(u32 => u32: VariadicHashSetStd);
450
451 let left = MyGht::new_from(vec![var_expr!(1, 10)]);
453 let right = MyGht::new_from(vec![var_expr!(2, 20)]);
454 assert_eq!(left.partial_cmp(&right), None);
455 assert_eq!(right.partial_cmp(&left), None);
456
457 let left = MyGht::new_from(vec![var_expr!(1, 10), var_expr!(1, 11), var_expr!(2, 20)]);
459 let right = MyGht::new_from(vec![var_expr!(1, 10), var_expr!(2, 20), var_expr!(2, 21)]);
460 assert_eq!(left.partial_cmp(&right), None);
461 assert_eq!(right.partial_cmp(&left), None);
462
463 let smaller = MyGht::new_from(vec![var_expr!(1, 10)]);
465 let larger = MyGht::new_from(vec![var_expr!(1, 10), var_expr!(1, 11)]);
466 assert_eq!(smaller.partial_cmp(&larger), Some(Less));
467 assert_eq!(larger.partial_cmp(&smaller), Some(Greater));
468
469 let same = MyGht::new_from(vec![var_expr!(1, 10), var_expr!(2, 20)]);
470 let same_again = MyGht::new_from(vec![var_expr!(2, 20), var_expr!(1, 10)]);
471 assert_eq!(same.partial_cmp(&same_again), Some(Equal));
472
473 let empty = MyGht::default();
474 assert_eq!(empty.partial_cmp(&MyGht::default()), Some(Equal));
475 assert_eq!(empty.partial_cmp(&smaller), Some(Less));
476 assert_eq!(smaller.partial_cmp(&empty), Some(Greater));
477 }
478
479 #[test]
480 fn test_cartesian_bimorphism() {
481 use variadics::var_expr;
482
483 use crate::ght::GeneralizedHashTrieNode;
484 use crate::ght::lattice::GhtCartesianProductBimorphism;
485 use crate::{GhtType, LatticeBimorphism};
486
487 type MyGhtA = GhtType!(u32, u64 => u16, &'static str: VariadicHashSetStd);
488 type MyGhtB = GhtType!(u32, u64, u16 => &'static str: VariadicHashSetStd);
489
490 let mut ght_a = MyGhtA::default();
491 let mut ght_b = MyGhtB::default();
492
493 ght_a.insert(var_expr!(123, 2, 5, "hello"));
494 ght_a.insert(var_expr!(50, 1, 1, "hi"));
495 ght_a.insert(var_expr!(5, 1, 7, "hi"));
496 ght_b.insert(var_expr!(5, 1, 8, "hi"));
497 ght_b.insert(var_expr!(10, 1, 2, "hi"));
498 ght_b.insert(var_expr!(12, 10, 98, "bye"));
499
500 type MyGhtAb = GhtType!(u32, u64, u16, &'static str, u32, u64 => u16, &'static str: VariadicCountedHashSetStd);
501
502 let mut bim = GhtCartesianProductBimorphism::<MyGhtAb>::default();
503 let ght_out = bim.call(&ght_a, &ght_b);
504 assert_eq!(
505 ght_out.recursive_iter().count(),
506 ght_a.recursive_iter().count() * ght_b.recursive_iter().count()
507 );
508 }
509
510 #[test]
511 fn test_join_bimorphism() {
512 use variadics::variadic_collections::{VariadicCountedHashSetStd, VariadicHashSetStd};
513 use variadics::{var_expr, var_type};
514
515 use crate::ght::lattice::{
516 DeepJoinLatticeBimorphism, GhtNodeKeyedBimorphism, GhtValTypeProductBimorphism,
517 };
518 use crate::ght::{GeneralizedHashTrieNode, GhtInner, GhtLeaf};
519 use crate::{GhtType, LatticeBimorphism};
520
521 type ResultSchemaType = var_type!(u32, u64, u16, &'static str, &'static str);
522 type ResultSchemaRefType<'a> = var_type!(
523 &'a u32,
524 &'a u64,
525 &'a u16,
526 &'a &'static str,
527 &'a &'static str
528 );
529 type MyGhtATrie = GhtType!(u32, u64, u16 => &'static str: VariadicHashSetStd);
530 type MyGhtBTrie = GhtType!(u32, u64, u16 => &'static str: VariadicHashSetStd);
531
532 let mut ght_a = MyGhtATrie::default();
533 let mut ght_b = MyGhtBTrie::default();
534
535 ght_a.insert(var_expr!(123, 2, 5, "hello"));
536 ght_a.insert(var_expr!(50, 1, 1, "hi"));
537 ght_a.insert(var_expr!(5, 1, 7, "hi"));
538
539 ght_b.insert(var_expr!(5, 1, 8, "hi"));
540 ght_b.insert(var_expr!(5, 1, 7, "world"));
541 ght_b.insert(var_expr!(10, 1, 2, "hi"));
542 ght_b.insert(var_expr!(12, 10, 98, "bye"));
543
544 let result: HashSet<ResultSchemaRefType<'_>> = [var_expr!(&5, &1, &7, &"hi", &"world")]
545 .iter()
546 .copied()
547 .collect();
548 {
549 type MyGhtOut = GhtInner<
554 &'static str,
555 GhtLeaf<
556 ResultSchemaType,
557 var_type!(&'static str),
558 VariadicCountedHashSetStd<ResultSchemaType>,
559 >,
560 >;
561 let mut bim = GhtNodeKeyedBimorphism::new(GhtNodeKeyedBimorphism::new(
565 GhtNodeKeyedBimorphism::new(GhtValTypeProductBimorphism::<MyGhtOut>::default()),
566 ));
567 let out = bim.call(&ght_a, &ght_b);
568 let out: HashSet<ResultSchemaRefType<'_>> = out.recursive_iter().collect();
569 assert_eq!(out, result);
570 }
571 {
572 type MyNodeBim<'a> = <(MyGhtATrie, MyGhtBTrie) as DeepJoinLatticeBimorphism<
575 VariadicHashSetStd<ResultSchemaType>,
576 >>::DeepJoinLatticeBimorphism;
577 let mut bim = <MyNodeBim<'_> as Default>::default();
578 let out = bim.call(&ght_a, &ght_b);
579 let out: HashSet<ResultSchemaRefType<'_>> = out.recursive_iter().collect();
580 assert_eq!(out, result);
581 }
582 }
583
584 #[test]
585 fn test_ght_with_tuple_macro() {
586 use variadics::{VariadicExt, var_expr};
587 use variadics_macro::tuple;
588
589 use crate::GhtType;
590 use crate::ght::GeneralizedHashTrieNode;
591
592 type MyRoot = GhtType!(u16, u32 => u64: VariadicCountedHashSetStd);
593
594 let mut trie1 = MyRoot::default();
595 assert_eq!(3, <<MyRoot as GeneralizedHashTrieNode>::Schema>::LEN);
596 trie1.insert(var_expr!(1, 2, 3));
597 let t = trie1.recursive_iter().next().unwrap();
598 let tup = tuple!(t, 3);
599 assert_eq!(tup, (&1, &2, &3));
600 }
601
602 #[test]
603 fn test_triangle_generic_join() {
604 use std::hash::{BuildHasherDefault, DefaultHasher};
605
606 use variadics::var_expr;
607
608 use crate::GhtType;
609 use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter};
610
611 const MATCHES: u32 = 1000;
612 type MyGht = GhtType!(u32 => u32: VariadicCountedHashSetStd);
613
614 let r_iter = (0..MATCHES)
615 .map(|i| (0, i))
616 .chain((1..MATCHES).map(|i| (i, 0)));
617
618 let s_iter = (0..MATCHES)
619 .map(|i| (0, i))
620 .chain((1..MATCHES).map(|i| (i, 0)));
621
622 let t_iter = (0..MATCHES)
623 .map(|i| (0, i))
624 .chain((1..MATCHES).map(|i| (i, 0)));
625
626 let rx_ght = MyGht::new_from(r_iter.clone().map(|(x, y)| var_expr!(x, y)));
627 let sb_ght = MyGht::new_from(s_iter.clone().map(|(y, b)| var_expr!(b, y)));
628 let tx_ght = MyGht::new_from(t_iter.map(|(z, x)| var_expr!(x, z)));
629
630 let r_x = r_iter
631 .map(|(x, _y)| x)
632 .collect::<HashSet<_, BuildHasherDefault<DefaultHasher>>>();
633 let t_x = s_iter
634 .clone()
635 .map(|(_z, x)| x)
636 .collect::<HashSet<_, BuildHasherDefault<DefaultHasher>>>();
637 let x_inter = r_x.intersection(&t_x);
638 let len = x_inter.clone().count();
639 if len > 1 {
640 assert_eq!(1000, len);
641 }
642
643 let mut output: Vec<(u32, u32, u32)> = Vec::new();
644 let mut x_iters = 0usize;
645 let mut y_iters = 0usize;
646 let mut z_iters = 0usize;
647 for a in x_inter {
648 x_iters += 1;
649 let r = rx_ght
650 .prefix_iter(var_expr!(a))
651 .map(|(_x, (y, ()))| *y)
652 .collect::<HashSet<_, BuildHasherDefault<DefaultHasher>>>();
653 let s_y = s_iter
654 .clone()
655 .map(|(y, _z)| y)
656 .collect::<HashSet<_, BuildHasherDefault<DefaultHasher>>>();
657 let y_inter = r.intersection(&s_y);
658 let len = y_inter.clone().count();
659 if len > 1 {
660 assert_eq!(1000, len);
661 }
662 for b in y_inter {
663 y_iters += 1;
664 let s = sb_ght
665 .prefix_iter(var_expr!(b))
666 .map(|(_b, (z, ()))| *z)
667 .collect::<HashSet<_, BuildHasherDefault<DefaultHasher>>>();
668 let t = tx_ght
669 .prefix_iter(var_expr!(a))
670 .map(|(_x, (z, ()))| *z)
671 .collect::<HashSet<_, BuildHasherDefault<DefaultHasher>>>();
672 let z_inter = s.intersection(&t);
673 let len = z_inter.clone().count();
674 if len > 1 {
675 assert_eq!(1000, len);
676 }
677 for c in z_inter {
678 z_iters += 1;
679 output.push((*a, *b, *c));
680 }
681 }
682 }
683
684 assert_eq!(1000, x_iters);
685 assert_eq!(1999, y_iters);
686 assert_eq!(2998, z_iters);
687 assert_eq!(2998, output.len());
688 }
689
690 fn clover_setup(
691 matches: usize,
692 ) -> (
693 impl Iterator<Item = (u32, u32)>,
694 impl Iterator<Item = (u32, u32)>,
695 impl Iterator<Item = (u32, u32)>,
696 ) {
697 let r_iter = (1..matches)
698 .map(|i| (1u32, i as u32))
699 .chain((1..matches).map(|i| (2, i as u32)))
700 .chain([(0, 0)]);
701
702 let s_iter = (1..matches)
703 .map(|i| (2u32, i as u32))
704 .chain((1..matches).map(|i| (3, i as u32)))
705 .chain([(0, 0)]);
706
707 let t_iter = (1..matches)
708 .map(|i| (3u32, i as u32))
709 .chain((1..matches).map(|i| (1, i as u32)))
710 .chain([(0, 0)]);
711 (r_iter, s_iter, t_iter)
712 }
713
714 #[test]
715 fn clover_generic_join() {
716 use variadics::var_expr;
717
718 use crate::GhtType;
719 use crate::ght::{GeneralizedHashTrieNode, GhtGet};
720
721 const MATCHES: usize = 1000;
722 let (r_iter, s_iter, t_iter) = clover_setup(MATCHES);
723
724 type MyGht = GhtType!(u32 => u32: VariadicCountedHashSetStd);
725 let rx_ght = MyGht::new_from(r_iter.map(|(x, a)| var_expr!(x, a)));
726 let sx_ght = MyGht::new_from(s_iter.map(|(x, b)| var_expr!(x, b)));
727 let tx_ght = MyGht::new_from(t_iter.map(|(x, c)| var_expr!(x, c)));
728 for x in rx_ght.iter() {
729 if let (Some(r), Some(s), Some(t)) = (rx_ght.get(&x), sx_ght.get(&x), tx_ght.get(&x)) {
730 for a in r.iter() {
732 for b in s.iter() {
733 for c in t.iter() {
734 assert_eq!((x, a, b, c), (0, 0, 0, 0));
735 }
736 }
737 }
738 } else {
739 continue;
741 }
742 }
743 }
744
745 #[test]
746 fn clover_factorized_join() {
747 use variadics::var_expr;
748
749 use crate::GhtType;
750 use crate::ght::{GeneralizedHashTrieNode, GhtGet};
751
752 const MATCHES: usize = 1000;
753 let (r_iter, s_iter, t_iter) = clover_setup(MATCHES);
754
755 type Ght1 = GhtType!(() => u32, u32: VariadicCountedHashSetStd);
756 type Ght2 = GhtType!(u32 => u32: VariadicCountedHashSetStd);
757 let rx_ght = Ght1::new_from(r_iter.map(|(x, a)| var_expr!(x, a)));
758 let sx_ght = Ght2::new_from(s_iter.map(|(x, b)| var_expr!(x, b)));
759 let tx_ght = Ght2::new_from(t_iter.map(|(x, c)| var_expr!(x, c)));
760
761 for t in rx_ght.recursive_iter() {
762 let (x, (a, ())): (&u32, (&u32, _)) = t;
763 if let (Some(s), Some(t)) = (sx_ght.get(x), tx_ght.get(x)) {
764 for b in s.iter() {
766 for c in t.iter() {
767 assert_eq!((x, a, b, c), (&0, &0, 0, 0));
768 }
769 }
770 } else {
771 continue;
773 }
774 }
775 }
776
777 #[test]
778 fn test_force() {
779 use variadics::var_expr;
780
781 use crate::GhtType;
782 use crate::ght::GeneralizedHashTrieNode;
783 use crate::ght::colt::ColtForestNode;
784
785 type LeafType = GhtType!(() => u16, u32, u64: VariadicCountedHashSetStd);
786 let n = LeafType::new_from(vec![
787 var_expr!(1, 1, 1),
788 var_expr!(1, 2, 2),
789 var_expr!(1, 3, 3),
790 var_expr!(2, 4, 4),
791 ]);
792 let out = n.force().unwrap();
793 assert_eq!(out.height(), 1);
794 }
795
796 #[test]
797 fn test_forest_macro() {
798 use crate::ColtType;
799
800 type Forest4 = ColtType!(u8, u16, u32, u64);
801 let _f4 = Forest4::default();
802
803 type Forest3 = ColtType!(u8, u16, u32);
804 let _f3 = Forest3::default();
805
806 type Forest2 = ColtType!(u8, u16);
807 let _f2 = Forest2::default();
808
809 type Forest1 = ColtType!(u8);
810 let _f2 = Forest1::default();
811
812 type Forest01 = ColtType!(() => u16);
813 let _f01 = Forest01::default();
814
815 type Forest02 = ColtType!(() => u8, u16);
816 let _f02 = Forest02::default();
817
818 type Forest10 = ColtType!(u8 => ());
819 let _f10 = Forest10::default();
820
821 type Forest11 = ColtType!(u8 => u16);
822 let _f11 = Forest11::default();
823
824 type Forest12 = ColtType!(u8 => u16, u32);
825 let _f12 = Forest12::default();
826
827 type Forest20 = ColtType!(u8, u16 => ());
828 let _f20 = Forest20::default();
829
830 type Forest21 = ColtType!(u8, u16 => u32);
831 let _f21 = Forest21::default();
832
833 type Forest22 = ColtType!(u8, u16 => u32, u64);
834 let _f22 = Forest22::default();
835 }
836
837 #[test]
838 fn test_colt_little_get() {
839 use variadics::variadic_collections::VariadicCollection;
840 use variadics::{VariadicExt, var_expr};
841
842 use crate::ColtType;
843 use crate::ght::GeneralizedHashTrieNode;
844 use crate::ght::colt::ColtGet;
845
846 type MyForest = ColtType!(u8);
847
848 let mut forest = MyForest::default();
849
850 forest.0.insert(var_expr!(1));
851 forest.0.insert(var_expr!(2));
852 forest.0.insert(var_expr!(3));
853
854 assert_eq!(2, forest.len());
855 assert_eq!(3, forest.0.elements.len());
856
857 let result = ColtGet::get(forest.as_mut_var(), &3);
858 assert_eq!(1, result.len());
859 assert_eq!(0, forest.0.elements.len());
860 assert!(forest.0.forced);
861 }
862
863 #[test]
864 fn test_colt_get() {
865 use variadics::variadic_collections::VariadicCollection;
866 use variadics::{VariadicExt, var_expr};
867
868 use crate::ColtType;
869 use crate::ght::colt::ColtGet;
870 use crate::ght::{GeneralizedHashTrieNode, GhtGet};
871
872 type MyForest = ColtType!(u8, u16, u32, u64);
873 let mut forest = MyForest::default();
874 forest.0.insert(var_expr!(1, 1, 1, 1));
875 forest.0.insert(var_expr!(2, 2, 2, 2));
876 forest.0.insert(var_expr!(3, 3, 3, 3));
877
878 let len = forest.len();
879 assert_eq!(5, len);
880 {
881 let get_result = ColtGet::get(forest.as_mut_var(), &1);
882 assert_eq!(get_result.len(), len - 1);
883 assert_eq!(get_result.0.height(), 0);
884 let get_result2 = ColtGet::get(get_result, &1);
885 assert_eq!(get_result2.len(), len - 2);
886 let get_result3 = ColtGet::get(get_result2, &1);
887 assert_eq!(get_result3.len(), len - 3);
888 assert_eq!(
889 get_result3.0.elements.iter().next(),
890 Some(var_expr!(1, 1, 1, 1).as_ref_var())
891 );
892 assert_eq!(get_result3.1.0.children.len(), 0);
893 }
894 {
895 let get_result = ColtGet::get(forest.as_mut_var(), &3);
896 assert_eq!(get_result.len(), len - 1);
897 let get_result2 = ColtGet::get(get_result, &3);
898 assert_eq!(get_result2.len(), len - 2);
899 assert_eq!(
900 get_result2.0.elements.iter().next(),
901 Some(var_expr!(3, 3, 3, 3).as_ref_var())
902 );
903 assert_eq!(get_result2.1.0.children.len(), 0);
904 }
905 assert!(forest.0.forced);
906 assert_eq!(3, forest.1.0.children.len()); assert_eq!(0, forest.1.0.get(&1).unwrap().elements.len());
908 assert_eq!(1, forest.1.0.get(&2).unwrap().elements.len());
909 assert_eq!(0, forest.1.0.get(&3).unwrap().elements.len());
910 assert_eq!(2, forest.1.1.0.children.len()); assert_eq!(
912 0,
913 forest
914 .1
915 .1
916 .0
917 .get(&1)
918 .unwrap()
919 .get(&1)
920 .unwrap()
921 .elements
922 .len()
923 );
924 assert!(forest.1.1.0.get(&2).is_none());
925 assert_eq!(
926 1,
927 forest
928 .1
929 .1
930 .0
931 .get(&3)
932 .unwrap()
933 .get(&3)
934 .unwrap()
935 .elements
936 .len()
937 );
938 assert_eq!(
939 1,
940 forest
941 .1
942 .1
943 .1
944 .0
945 .get(&1)
946 .unwrap()
947 .get(&1)
948 .unwrap()
949 .get(&1)
950 .unwrap()
951 .elements
952 .len()
953 );
954 }
955
956 #[test]
957 fn test_colt_scale() {
958 use variadics::variadic_collections::VariadicCollection;
959 use variadics::{VariadicExt, var_expr};
960
961 use crate::ght::colt::ColtGet;
962 use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter};
963
964 type MyColt = crate::ColtType!(i32, bool, usize, &'static str);
965 let mut forest = MyColt::default();
966 for i in 1..100000 {
967 forest.0.insert(var_expr!(i, true, 1, "hello"));
968 }
969 {
970 let result = forest.as_mut_var().get(&3);
971 assert_eq!(result.len(), 4);
972 }
973 assert!(forest.0.forced);
975 assert_eq!(forest.0.elements.len(), 0);
976 {
977 let result = forest.as_mut_var().get(&3);
978 let result2 = result.get(&true);
979 assert_eq!(result2.len(), 3);
980 }
981 {
982 let result = forest.as_mut_var().get(&3);
984 assert!(result.0.forced);
985 assert_eq!(result.0.elements.len(), 0);
986 }
987 assert!(
989 forest
990 .1
991 .1
992 .0
993 .prefix_iter(var_expr!(3, true).as_ref_var())
994 .next()
995 .is_some()
996 );
997 {
998 let result = forest.as_mut_var().get(&3);
999 let result2 = result.get(&true);
1000 assert_eq!(result2.len(), 3);
1001 let result3 = result2.get(&1);
1002 assert_eq!(result3.len(), 2);
1003 let result4 = result3.get(&"hello");
1004 assert_eq!(result4.0.elements.len(), 1);
1005 assert_eq!(
1006 result4.0.elements.iter().next(),
1007 Some(var_expr!(3, true, 1, "hello").as_ref_var())
1008 );
1009 }
1010 }
1011}