1use std::ptr;
5use std::string::String;
6use std::vec::Vec;
7
8mod tra;
9use tra::{tsdv, TraStrain};
10
11mod uc;
12use uc::UC;
13
14type Links = Vec<Box<Node>>;
15type NodeTrace = Vec<PathNode>;
16type EntryTrace = Vec<char>;
17
18#[derive(Clone, PartialEq, Debug)]
19struct PathNode(usize, *mut Node);
20
21impl PathNode {
22 fn n_mut<'a>(&self) -> &'a mut Node {
23 Node::as_mut(self.1)
24 }
25}
26
27pub type Entry<'a> = KeyEntry<'a>;
29pub type Key<'a> = KeyEntry<'a>;
31
32#[cfg_attr(test, derive(Clone))]
33struct Node {
34 c: char,
35 supernode: *const Node,
36 links: Option<Links>,
37 lrref: *const Node,
38 #[cfg(test)]
39 id: usize,
40}
41
42const NULL_CHAR: char = '\0';
43const NULL_NODE: *const Node = ptr::null();
44
45impl Node {
46 fn lrref(&self) -> bool {
47 self.lrref != NULL_NODE
48 }
49
50 const fn links(&self) -> bool {
51 self.links.is_some()
52 }
53
54 const fn empty() -> Self {
55 Node {
56 c: NULL_CHAR,
57 supernode: NULL_NODE,
58 links: None,
59 lrref: NULL_NODE,
60 #[cfg(test)]
61 id: 0,
62 }
63 }
64
65 const fn new(c: char, supernode: *const Node) -> Self {
66 Node {
67 c,
68 supernode,
69 links: None,
70 lrref: NULL_NODE,
71 #[cfg(test)]
72 id: 0,
73 }
74 }
75
76 fn empty_boxed() -> Box<Self> {
77 Box::new(Self::empty())
78 }
79
80 fn new_boxed(c: char, supernode: *const Node) -> Box<Self> {
81 Box::new(Self::new(c, supernode))
82 }
83
84 fn as_mut<'a>(n: *mut Self) -> &'a mut Self {
85 unsafe { n.as_mut().unwrap_unchecked() }
86 }
87
88 fn as_ref<'a>(n: *const Self) -> &'a Self {
89 unsafe { n.as_ref().unwrap_unchecked() }
90 }
91
92 const fn to_mut_ptr(&self) -> *mut Self {
93 (self as *const Self).cast_mut()
94 }
95}
96
97pub struct KeyEntry<'a>(&'a str);
99
100impl<'a> KeyEntry<'a> {
101 pub const fn new(key: &'a str) -> Option<Self> {
103 if key.len() == 0 {
104 None
105 } else {
106 Some(Self(key))
107 }
108 }
109}
110
111impl<'a> std::ops::Deref for KeyEntry<'a> {
112 type Target = str;
113
114 fn deref(&self) -> &str {
116 self.0
117 }
118}
119
120#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
122pub enum LeftRight {
123 Left = 0,
124 Right = 1,
125}
126
127fn insert_crux<'a>(mut supernode: &'a mut Node, e: &Entry) -> &'a mut Node {
128 let e = e.0;
129
130 let mut swap = Node::empty_boxed();
131 let mut sn_ptr: *const Node = supernode;
132 for c in e.chars() {
133 let links = supernode.links.get_or_insert_with(|| Links::new());
134
135 let ix = if let Some(i) = index_of_c(links, c) {
136 i
137 } else {
138 let boxed = Node::new_boxed(c, sn_ptr);
139 links.push(boxed);
140 links.len() - 1
141 };
142
143 let node = &mut links[ix];
144
145 std::mem::swap(&mut swap, node);
148 let n_raw = Box::into_raw(swap);
149 swap = unsafe { Box::from_raw(n_raw) };
150 std::mem::swap(&mut swap, node);
151
152 supernode = node;
153
154 sn_ptr = n_raw;
155 }
156
157 supernode
158}
159
160fn index_of_c(links: &Links, c: char) -> Option<usize> {
161 let links_len = links.len();
162 let mut ix = 0;
163
164 while ix < links_len {
165 let n = &links[ix];
166 if n.c == c {
167 return Some(ix);
168 }
169
170 ix += 1;
171 }
172
173 None
174}
175
176const fn cl_lrref(keyentry_n: &mut Node) -> bool {
177 if keyentry_n.links() {
178 keyentry_n.lrref = NULL_NODE;
179 true
180 } else {
181 false
182 }
183}
184
185fn delete_subnode(n: &mut Node, subnode_ix: usize) -> bool {
186 let n_links = n.links.as_mut().unwrap();
187 _ = n_links.swap_remove(subnode_ix);
188
189 if n_links.len() == 0 {
190 n.links = None;
191 } else {
192 return true;
193 }
194
195 if n.lrref() {
196 return true;
197 }
198
199 return false;
200}
201
202fn delete_key_side<'a>(path: &NodeTrace) {
203 let mut path = path.iter();
204 let epn = path.next_back();
205 let epn = unsafe { epn.unwrap_unchecked() };
206 let n = epn.n_mut();
207
208 if cl_lrref(n) {
209 return;
210 }
211
212 let mut sub_n_ix = epn.0;
213 while let Some(PathNode(n_ix, n)) = path.next_back() {
214 if delete_subnode(Node::as_mut(*n), sub_n_ix) {
215 break;
216 }
217
218 sub_n_ix = *n_ix;
219 }
220}
221
222fn delete_entry_side(key_side_entry_n: &Node) {
223 let lrref = key_side_entry_n.lrref.cast_mut();
224 let node = Node::as_mut(lrref);
225
226 if cl_lrref(node) {
227 return;
228 }
229
230 const NULL_MUT: *mut Node = ptr::null_mut();
231 let mut node: &mut Node = node;
232 loop {
233 let super_n = node.supernode.cast_mut();
234 if super_n == NULL_MUT {
235 break;
236 }
237
238 let super_n = Node::as_mut(super_n);
239 let sn_links = unsafe { super_n.links.as_ref().unwrap_unchecked() };
240 let n_ix = unsafe { index_of_c(sn_links, node.c).unwrap_unchecked() };
241
242 if delete_subnode(super_n, n_ix) {
243 break;
244 }
245
246 node = super_n;
247 }
248}
249
250fn set_cap<T>(buf: &UC<Vec<T>>, approx_cap: usize) -> usize {
251 let buf = buf.get_mut();
252 let cp = buf.capacity();
253
254 if cp < approx_cap {
255 buf.reserve(approx_cap);
256 } else if cp > approx_cap {
257 *buf = Vec::with_capacity(approx_cap);
258 }
259
260 buf.capacity()
261}
262
263fn ext(l: &Links, k_buf: &mut String, e_buf: &mut Vec<char>, o: &mut Vec<(String, String)>) {
264 for n in l {
265 k_buf.push(n.c);
266
267 let lrref = n.lrref;
268 if lrref != NULL_NODE {
269 let k = k_buf.clone();
270 let e = construct_e(lrref, e_buf);
271 o.push((k, e));
272 }
273
274 if let Some(l) = n.links.as_ref() {
275 ext(l, k_buf, e_buf, o);
276 }
277
278 _ = k_buf.pop();
279 }
280}
281
282fn construct_e(mut node: *const Node, e_buf: &mut Vec<char>) -> String {
283 loop {
284 let n = Node::as_ref(node);
285 let super_n = n.supernode;
286
287 if super_n == NULL_NODE {
288 break;
289 }
290
291 e_buf.push(n.c);
292 node = super_n;
293 }
294
295 let ret = e_buf.iter().rev().collect::<String>();
296 e_buf.clear();
297 ret
298}
299
300#[derive(Clone, PartialEq, Debug)]
302pub enum Buffer {
303 Delete = 0,
305 Member = 1,
307}
308
309#[cfg_attr(test, derive(PartialEq, Debug))]
324pub struct LrTrie {
325 left: Node,
326 right: Node,
327 trace: UC<NodeTrace>,
329 entry: UC<EntryTrace>,
330 count: usize,
331}
332
333#[cfg_attr(test, derive(PartialEq, Debug))]
334enum TraRes<'a> {
335 Ok,
336 OkRef(&'a Node),
337 UnknownForNotEntry,
338 UnknownForAbsentPathLinks,
339 UnknownForAbsentPathNode,
340}
341
342impl LrTrie {
343 pub const fn new() -> Self {
345 LrTrie {
346 left: Node::empty(),
347 right: Node::empty(),
348 trace: UC::new(Vec::new()),
349 entry: UC::new(Vec::new()),
350 count: 0,
351 }
352 }
353
354 pub fn insert(&mut self, l_entry: &Entry, r_entry: &Entry) {
358 let mut cntr = 0;
362 if self.delete_crux(l_entry, LeftRight::Left, false).is_ok() {
363 cntr += 1;
364 }
365 if self.delete_crux(r_entry, LeftRight::Right, false).is_ok() {
366 cntr += 1;
367 }
368
369 let l_en = insert_crux(&mut self.left, l_entry);
370 let r_en = insert_crux(&mut self.right, r_entry);
371
372 l_en.lrref = r_en as *const Node;
373 r_en.lrref = l_en as *const Node;
374
375 let count = self.count;
376 self.count = match cntr {
377 0 => count + 1,
378 1 => return,
379 2 => count - 1,
380 _ => panic!("Impossible value."),
381 }
382 }
383
384 fn track(&self, key: &Key, lr: LeftRight, ts: TraStrain) -> TraRes {
385 let root = self.root(lr);
386 let trace = self.trace.get_mut();
387
388 let tracing = TraStrain::has(ts.clone(), tsdv::TRA);
389 if tracing {
390 trace.push(PathNode(usize::MAX, root.to_mut_ptr()));
391 }
392
393 let mut key = key.chars();
394 let mut node = Node::as_ref(root);
395 while let Some(c) = key.next() {
396 if let Some(l) = &node.links {
397 if let Some(ix) = index_of_c(l, c) {
398 node = &l[ix];
399 if tracing {
400 trace.push(PathNode(ix, node.to_mut_ptr()));
401 }
402
403 continue;
404 }
405 return TraRes::UnknownForAbsentPathNode;
406 }
407 return TraRes::UnknownForAbsentPathLinks;
408 }
409
410 if node.lrref() {
411 match ts {
412 x if TraStrain::has(x.clone(), tsdv::REF) => TraRes::OkRef(node),
413 x if TraStrain::has(x.clone(), tsdv::EMP) => TraRes::Ok,
414 _ => panic!("Unsupported result scenario."),
415 }
416 } else {
417 TraRes::UnknownForNotEntry
418 }
419 }
420
421 pub fn member(&self, key: &Key, lr: LeftRight) -> Option<String> {
425 let res = self.track(key, lr, TraStrain::NonRef);
426
427 if let TraRes::OkRef(en) = res {
428 let entry = self.entry.get_mut();
429
430 let ret = construct_e(en.lrref, entry);
431 Some(ret)
432 } else {
433 None
434 }
435 }
436
437 const fn root(&self, lr: LeftRight) -> &Node {
438 match lr {
439 LeftRight::Left => &self.left,
440 LeftRight::Right => &self.right,
441 }
442 }
443
444 const fn links(&self, lr: LeftRight) -> Option<&Links> {
445 self.root(lr).links.as_ref()
446 }
447
448 pub fn delete(&mut self, key: &Key, lr: LeftRight) -> Result<(), ()> {
452 let res = self.delete_crux(key, lr, true);
453 self.trace.get_mut().clear();
454
455 if res.is_ok() {
456 self.count -= 1;
457 }
458
459 res
460 }
461
462 fn delete_crux(&mut self, key: &Key, lr: LeftRight, delete_ks: bool) -> Result<(), ()> {
463 let ts = if delete_ks {
464 TraStrain::TraRef
465 } else {
466 TraStrain::NonRef
467 };
468
469 if let TraRes::OkRef(en) = self.track(key, lr, ts) {
470 delete_entry_side(en);
471
472 if delete_ks {
473 delete_key_side(&*self.trace)
474 }
475
476 Ok(())
477 } else {
478 Err(())
479 }
480 }
481
482 pub fn put_buf_cap(&mut self, approx_cap: usize, buf: Buffer) -> usize {
512 if buf == Buffer::Delete {
513 set_cap(&self.trace, approx_cap)
514 } else {
515 #[cfg(test)]
516 assert_eq!(Buffer::Member, buf);
517
518 set_cap(&self.entry, approx_cap)
519 }
520 }
521
522 pub fn aq_buf_cap(&self, buf: Buffer) -> usize {
526 if buf == Buffer::Delete {
527 self.trace.capacity()
528 } else {
529 #[cfg(test)]
530 assert_eq!(Buffer::Member, buf);
531
532 self.entry.capacity()
533 }
534 }
535
536 pub fn clear(&mut self) -> usize {
542 self.left = Node::empty();
543 self.right = Node::empty();
544 let count = self.count;
545 self.count = 0;
546 count
547 }
548
549 pub const fn count(&self) -> usize {
551 self.count
552 }
553
554 pub fn extract(&self, lr: LeftRight) -> Option<Vec<(String, String)>> {
568 if let Some(l) = self.links(lr) {
569 let mut o = Vec::with_capacity(1000);
570 let mut e_buf = Vec::with_capacity(1000);
571 let mut k_buf = String::with_capacity(1000);
572
573 ext(l, &mut k_buf, &mut e_buf, &mut o);
574
575 Some(o)
576 } else {
577 None
578 }
579 }
580}
581
582#[cfg(test)]
583mod tests_of_units {
584
585 use crate::{LeftRight, LrTrie, Node};
586
587 impl PartialEq for Node {
588 fn eq(&self, other: &Self) -> bool {
589 self.c == other.c
590 && self.supernode == other.supernode
591 && self.links == other.links
592 && self.lrref == other.lrref
593 }
594 }
595
596 mod node_test_imp {
597 use crate::Node;
598
599 #[test]
600 fn eq() {
601 let sn = Node::empty();
602 let mut n1 = Node::new('x', &sn);
603 let links = vec![Node::new_boxed('y', &sn)];
604 n1.links = Some(links);
605 n1.lrref = &sn;
606
607 let n2 = n1.clone();
608
609 assert_eq!(true, n1.eq(&n2));
610 }
611 }
612
613 use std::fmt::{Debug, Formatter};
614
615 impl Debug for Node {
616 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
617 let links = if self.links() { "Some" } else { "None" };
618 let lrref = if self.lrref() { "Some" } else { "None" };
619 let sn = if self.supernode.is_null() {
620 "Null"
621 } else {
622 "Parent"
623 };
624
625 f.write_fmt(format_args!(
626 "Node {{\n c: {}\n sn: {}\n links: {}\n lrref: {}\n}}",
627 self.c, sn, links, lrref
628 ))
629 }
630 }
631
632 use crate::NodeTrace;
633 impl LrTrie {
634 fn cc_trace(&mut self) -> NodeTrace {
635 let trace = self.trace.get_mut();
636 let clone = trace.clone();
637 trace.clear();
638 clone
639 }
640 }
641
642 mod lrtrie_test_impl {
643 use std::ptr::NonNull;
644
645 use crate::{LrTrie, Node, PathNode};
646
647 #[test]
648 fn cc_trace() {
649 let n1 = NonNull::<Node>::dangling().as_ptr();
650 let n2 = NonNull::<Node>::dangling().as_ptr();
651
652 let mut trie = LrTrie::new();
653 let trace = trie.trace.get_mut();
654 trace.push(PathNode(usize::MIN, n1));
655 trace.push(PathNode(usize::MAX, n2));
656
657 let proof = trace.clone();
658 let test = trie.cc_trace();
659
660 assert_eq!(proof, test);
661 assert_eq!(0, trie.trace.len());
662 }
663 }
664
665 impl LeftRight {
666 fn invert(&self) -> Self {
667 match self {
668 LeftRight::Left => LeftRight::Right,
669 LeftRight::Right => LeftRight::Left,
670 }
671 }
672 }
673
674 mod leftright_test_impl {
675 use crate::LeftRight;
676
677 #[test]
678 fn invert() {
679 assert_eq!(LeftRight::Left, LeftRight::Right.invert());
680 assert_eq!(LeftRight::Right, LeftRight::Left.invert());
681 }
682 }
683
684 use crate::PathNode;
685 impl PathNode {
686 fn n_ref<'a>(&self) -> &'a Node {
687 Node::as_ref(self.1)
688 }
689 }
690
691 mod pathnode_test_impl {
692 use crate::{Node, PathNode};
693
694 #[test]
695 fn n_ref() {
696 let mut n = Node::empty();
697 let pn = PathNode(0, &mut n);
698 assert_eq!(
699 &n as *const Node as usize,
700 pn.n_ref() as *const Node as usize
701 );
702 }
703 }
704
705 mod pathnode {
706 use crate::{Node, PathNode};
707
708 #[test]
709 fn n_mut() {
710 let n = &mut Node::empty();
711 let pn = PathNode(0, n);
712 assert_eq!(
713 n as *const Node as usize,
714 pn.n_mut() as *const Node as usize
715 );
716 }
717 }
718
719 mod node {
720
721 use crate::{Links, Node, NULL_CHAR};
722 use std::ptr;
723
724 #[test]
725 fn lrref() {
726 let mut node = Node::empty();
727
728 assert_eq!(false, node.lrref());
729 node.lrref = &node;
730 assert!(node.lrref());
731 }
732
733 #[test]
734 fn links() {
735 let mut node = Node::empty();
736
737 assert_eq!(false, node.links());
738 node.links = Some(Links::new());
739 assert!(node.links());
740 }
741
742 #[test]
743 fn empty() {
744 let null_ptr = ptr::null();
745
746 let node = Node::empty();
747
748 assert_eq!(NULL_CHAR, node.c);
749 assert_eq!(null_ptr, node.supernode);
750 assert_eq!(None, node.links);
751 assert_eq!(null_ptr, node.lrref);
752 }
753
754 #[test]
755 fn new() {
756 let c = '🫀';
757 let sn = Node::empty();
758
759 let new = Node::new(c, &sn);
760
761 assert_eq!(c, new.c);
762 assert_eq!(&sn as *const Node, new.supernode);
763 assert_eq!(None, new.links);
764 assert_eq!(0, new.lrref as usize);
765 }
766
767 #[test]
768 fn as_mut() {
769 let n = &mut Node::empty() as *mut Node;
770 assert_eq!(n as usize, Node::as_mut(n) as *const Node as usize);
771 }
772
773 #[test]
774 fn as_ref() {
775 let n = &Node::empty() as *const Node;
776 assert_eq!(n as usize, Node::as_ref(n) as *const Node as usize);
777 }
778
779 #[test]
780 fn to_mut_ptr() {
781 let n = Node::empty();
782 let n_add = &n as *const Node as usize;
783 assert_eq!(n_add, n.to_mut_ptr() as usize);
784 }
785 }
786
787 mod keyentry {
788 use crate::KeyEntry;
789
790 mod new {
791 use crate::KeyEntry;
792
793 #[test]
794 fn some() {
795 const KEY: &str = "emoción";
796 let key = KeyEntry::new(KEY);
797 assert!(key.is_some());
798 let key = key.unwrap();
799 assert_eq!(KEY, key.0);
800 }
801
802 #[test]
803 fn none() {
804 let key = KeyEntry::new("");
805 assert!(key.is_none());
806 }
807 }
808
809 use std::ops::Deref;
810
811 #[test]
812 fn deref() {
813 const KEY: &str = "key";
814 let key = KeyEntry(KEY);
815 assert_eq!(KEY, key.deref());
816 }
817 }
818
819 mod insert_crux {
820 use std::ops::Deref;
821
822 use crate::{insert_crux, tra::TraStrain, Entry, KeyEntry, LeftRight, LrTrie, Node};
823
824 #[test]
825 fn basic_test() {
826 let mut root = Node::empty();
827
828 const ENTRY: &str = "lr_links_inserT";
829 let limit = ENTRY.len() - 1;
830
831 let entry: Entry = KeyEntry(ENTRY);
832 let node = insert_crux(&mut root, &entry);
833
834 assert_eq!('T', node.c);
835 assert_eq!(None, node.links);
836
837 assert!(root.links.is_some());
838
839 let mut links = root.links.as_ref().unwrap();
840 let mut super_n: *const Node = &root;
841 for (ix, c) in ENTRY.chars().enumerate() {
842 let node = links.get(0);
843
844 assert!(node.is_some());
845 let node = node.unwrap();
846
847 assert_eq!(c, node.c);
848 assert_eq!(super_n, node.supernode);
849 super_n = node.deref();
850
851 if ix < limit {
852 let temp = &node.links;
853 assert!(temp.is_some());
854 links = temp.as_ref().unwrap();
855 } else {
856 assert!(&node.links.is_none());
857 }
858 }
859 }
860
861 #[test]
862 fn existing_path_insert() {
863 const OLD: &str = "touchstone";
864 const NEW: &str = "touch";
865
866 let old = KeyEntry(OLD);
867 let new = KeyEntry(NEW);
868
869 let mut trie = LrTrie::new();
870
871 _ = insert_crux(&mut trie.left, &old);
872 _ = insert_crux(&mut trie.left, &new);
873
874 _ = trie.track(&old, LeftRight::Left, TraStrain::TraEmp);
875 let old_path = trie.cc_trace();
876
877 _ = trie.track(&new, LeftRight::Left, TraStrain::TraEmp);
878 let new_path = trie.cc_trace();
879
880 assert_eq!(OLD.len() + 1, old_path.len());
881 assert_eq!(new_path, old_path[..NEW.len() + 1]);
882 }
883 }
884
885 mod index_of_c {
886
887 use crate::{index_of_c, Links, Node};
888
889 fn links(cs: &[char]) -> Links {
890 cs.iter()
891 .map(|x| Node::new_boxed(*x, 0 as *const Node))
892 .collect::<Links>()
893 }
894
895 #[test]
896 fn some() {
897 let links = links(&['a', 'b', 'c']);
898
899 let index = index_of_c(&links, 'c');
900 assert!(index.is_some());
901 assert_eq!(2, index.unwrap());
902 }
903
904 #[test]
905 fn none() {
906 let links = links(&['a', 'b', 'c']);
907
908 let index = index_of_c(&links, 'd');
909 assert!(index.is_none());
910 }
911 }
912
913 mod cl_lrref {
914 use crate::{cl_lrref, Links, Node};
915 use std::ptr;
916
917 #[test]
918 fn has_to() {
919 let mut node = Node::empty();
920 node.lrref = &node;
921 node.links = Some(Links::new());
922
923 assert_eq!(true, cl_lrref(&mut node));
924 assert_eq!(ptr::null(), node.lrref);
925 }
926
927 #[test]
928 fn has_not_to() {
929 let mut node = Node::empty();
930 node.lrref = &node;
931
932 assert_eq!(false, cl_lrref(&mut node));
933 assert_eq!(&node as *const Node, node.lrref);
934 }
935 }
936
937 mod delete_subnode {
938 use crate::{delete_subnode, Links, Node};
939 use std::{ops::Deref, vec};
940
941 #[test]
945 fn deletion_continues() {
946 let mut node = Node::empty();
947 node.links = Some(vec![Node::empty_boxed()]);
948
949 assert_eq!(false, delete_subnode(&mut node, 0));
950 assert_eq!(None, node.links);
951 }
952
953 #[test]
956 fn node_with_links() {
957 let mut node = Node::empty();
958
959 #[rustfmt::skip]
960 let links = vec![
961 Node::empty_boxed(),
962 Node::new_boxed('a', 0 as *const Node),
963 Node::new_boxed('b', 0 as *const Node),
964 Node::new_boxed('c', 0 as *const Node),
965 ];
966
967 node.links = Some(links);
968 assert_eq!(true, delete_subnode(&mut node, 1));
969
970 let links = node.links.as_ref().unwrap();
971 assert_eq!(3, links.len());
972 assert_eq!(&Node::empty(), links[0].deref());
973 assert_eq!('c', links[1].c);
974 assert_eq!('b', links[2].c);
975 }
976
977 #[test]
981 fn key_node() {
982 let mut node = Node::empty();
983
984 node.links = Some(vec![Node::empty_boxed()]);
985 node.lrref = &node;
986
987 assert_eq!(true, delete_subnode(&mut node, 0));
988 assert_eq!(None, node.links);
989 }
990
991 #[test]
992 #[should_panic(expected = "swap_remove index (is 0) should be < len (is 0)")]
993 fn index_out_of_bounds() {
994 let mut node = Node::empty();
995 node.links = Some(Links::new());
996 delete_subnode(&mut node, 0);
997 }
998 }
999
1000 mod delete_key_side {
1001 use crate::{delete_key_side, Links, Node, PathNode};
1002 use std::{ops::DerefMut, ptr};
1003
1004 #[test]
1005 fn keynode_with_links() {
1006 let mut n = Node::empty();
1007 n.lrref = &n;
1008 n.links = Some(Links::new());
1009
1010 #[rustfmt::skip]
1011 let path = vec![
1012 PathNode(usize::MAX, &mut n),
1013 PathNode(usize::MAX, &mut n)
1014 ];
1015
1016 delete_key_side(&path);
1017
1018 assert_eq!(ptr::null(), n.lrref);
1019 }
1020
1021 #[test]
1022 fn node_with_links() {
1023 let mut empty_n = Node::empty();
1024
1025 let mut n = Node::empty();
1026 n.links = Some(vec![Node::empty_boxed(), Node::empty_boxed()]);
1027
1028 #[rustfmt::skip]
1029 let path = vec![
1030 PathNode(usize::MAX, &mut empty_n),
1031 PathNode(usize::MAX, &mut n),
1032 PathNode(1, &mut empty_n),
1033 ];
1034
1035 delete_key_side(&path);
1036
1037 assert_eq!(1, n.links.as_ref().unwrap().len());
1038 }
1039
1040 #[test]
1041 fn node_being_keyentry() {
1042 let mut empty_n = Node::empty();
1043
1044 let mut n1 = Node::empty();
1045 n1.lrref = &n1;
1046 n1.links = Some(vec![Node::empty_boxed()]);
1047
1048 let mut n2 = Node::empty();
1049 n2.links = Some(vec![Node::empty_boxed()]);
1050
1051 #[rustfmt::skip]
1052 let path = vec![
1053 PathNode(usize::MAX, &mut empty_n),
1054 PathNode(usize::MAX, &mut n1),
1055 PathNode(0, &mut n2),
1056 PathNode(0, &mut empty_n),
1057 ];
1058
1059 delete_key_side(&path);
1060
1061 assert_eq!(false, n1.links());
1062 assert_eq!(false, n2.links());
1063 }
1064
1065 #[test]
1066 fn root_escape() {
1067 let mut root = Node::empty();
1068 let node = Node::new_boxed('a', &root);
1069 root.links = Some(vec![node]);
1070
1071 #[rustfmt::skip]
1072 let path = vec![
1073 PathNode(usize::MAX, &mut root),
1074 PathNode(0, root.links.as_mut().unwrap()[0].deref_mut()),
1075 ];
1076
1077 delete_key_side(&path);
1078 assert_eq!(None, root.links);
1079 }
1080 }
1081
1082 mod delete_entry_side {
1083 use crate::{delete_entry_side, Links, Node};
1084 use std::{ops::Deref, ptr};
1085
1086 #[test]
1087 fn keynode_with_links() {
1088 let mut n = Node::empty();
1089 n.supernode = &n;
1090 n.lrref = &n;
1091 n.links = Some(Links::new());
1092
1093 delete_entry_side(&n);
1094
1095 assert_eq!(ptr::null(), n.lrref);
1096 }
1097
1098 #[test]
1099 fn node_with_links() {
1100 let mut n = Node::empty();
1101 n.supernode = &n;
1102 n.links = Some(vec![Node::new_boxed('a', &n), Node::empty_boxed()]);
1103
1104 let mut ks_en = Node::empty();
1105 ks_en.lrref = n.links.as_ref().unwrap()[0].deref();
1106
1107 delete_entry_side(&ks_en);
1108
1109 let links = n.links.as_ref();
1110 assert!(links.is_some());
1111 let links = links.unwrap();
1112
1113 assert_eq!(1, links.len());
1114 assert_eq!('\0', links[0].c);
1115 }
1116
1117 #[test]
1118 fn node_being_keyentry() {
1119 let mut n = Node::empty();
1120 n.supernode = &n;
1121 n.links = Some(vec![Node::new_boxed('a', &n)]);
1122 n.lrref = &n;
1123
1124 let mut ks_en = Node::empty();
1125 ks_en.lrref = n.links.as_ref().unwrap()[0].deref();
1126
1127 delete_entry_side(&ks_en);
1128
1129 assert_eq!(None, n.links);
1130 }
1131
1132 #[test]
1133 fn root_escape() {
1134 let mut root = Node::empty();
1135 let node = Node::new_boxed('a', &root);
1136 root.links = Some(vec![node]);
1137
1138 let mut ks_en = Node::empty();
1139 ks_en.lrref = root.links.as_ref().unwrap()[0].deref();
1140
1141 delete_entry_side(&ks_en);
1142 assert_eq!(None, root.links);
1143 }
1144 }
1145
1146 mod set_cap {
1147
1148 use crate::{set_cap, UC};
1149
1150 #[test]
1151 fn extend() {
1152 let new_cap = 10;
1153
1154 let buf = UC::new(Vec::<usize>::new());
1155 assert!(buf.capacity() < new_cap);
1156
1157 let size = set_cap(&buf, new_cap);
1158 assert!(size >= new_cap);
1159 assert!(buf.capacity() >= new_cap);
1160 }
1161
1162 #[test]
1163 fn shrink() {
1164 let new_cap = 10;
1165 let old_cap = 50;
1166
1167 let buf = UC::new(Vec::<usize>::with_capacity(old_cap));
1168
1169 let size = set_cap(&buf, new_cap);
1170 assert!(size >= new_cap && size < old_cap);
1171 let cap = buf.capacity();
1172 assert!(cap >= new_cap && cap < old_cap);
1173 }
1174
1175 #[test]
1176 fn same() {
1177 let cap = 10;
1178 let buf = UC::new(Vec::<usize>::new());
1179
1180 assert!(buf.capacity() < cap);
1181 buf.get_mut().reserve_exact(cap);
1182 let cap = buf.capacity();
1183
1184 let size = set_cap(&buf, cap);
1185 assert_eq!(cap, size);
1186 assert_eq!(cap, buf.capacity());
1187 }
1188 }
1189
1190 mod ext {
1191 use crate::{ext, KeyEntry, LrTrie};
1192
1193 #[test]
1194 fn basic_test() {
1195 let proof = [("opalescence", "black locust"), ("olivewood", "limehound")];
1196
1197 let mut trie = LrTrie::new();
1198 for es in proof {
1199 trie.insert(&KeyEntry(es.0), &KeyEntry(es.1));
1200 }
1201
1202 let mut k_buf = String::new();
1203 let mut e_buf = Vec::new();
1204 let mut res = Vec::new();
1205
1206 let links = trie.left.links.as_ref().unwrap();
1207
1208 ext(links, &mut k_buf, &mut e_buf, &mut res);
1209
1210 assert_eq!(2, res.len());
1211 for z in proof.iter().zip(res.iter()) {
1212 let p = z.0;
1213 let t = z.1;
1214
1215 assert_eq!(p.0, t.0);
1216 assert_eq!(p.1, t.1);
1217 }
1218
1219 assert_eq!(0, k_buf.len());
1220 assert_eq!(0, e_buf.len());
1221 }
1222
1223 #[test]
1224 fn load() {
1225 let proof = [
1226 ("olivenite", "limelight"),
1227 ("olivewood", "limehound"),
1228 ("olivary", "limestone"),
1229 ("oligotrophic", "limescale"),
1230 ("lemon", "bandoline"),
1231 ("lemonade", "podium"),
1232 ("lemon balm", "platina"),
1233 ("tapestry", "platform"),
1234 ("lemongrass", "rostrum"),
1235 ("temperate", "region"),
1236 ("tapis", "constituent"),
1237 ("cheque", "constellation"),
1238 ("season", "crops"),
1239 ("array", "formation"),
1240 ("glassware", "glasswork"),
1241 ];
1242
1243 let mut trie = LrTrie::new();
1244 for es in proof {
1245 trie.insert(&KeyEntry(es.0), &KeyEntry(es.1));
1246 }
1247
1248 let mut k_buf = String::new();
1249 let mut e_buf = Vec::new();
1250 let mut res = Vec::new();
1251
1252 let links = trie.right.links.as_ref().unwrap();
1253
1254 ext(links, &mut k_buf, &mut e_buf, &mut res);
1255
1256 assert_eq!(proof.len(), res.len());
1257 for z in proof.iter().zip(res.iter()) {
1258 let p = z.0;
1259 let t = z.1;
1260
1261 assert_eq!(p.1, t.0, "{}", p.0);
1262 assert_eq!(p.0, t.1, "{}", p.1);
1263 }
1264 }
1265 }
1266
1267 mod construct_e {
1268 use crate::{construct_e, Node};
1269
1270 #[test]
1271 fn construction() {
1272 let root = Node::empty();
1273 let n1 = Node::new('l', &root);
1274 let n2 = Node::new('r', &n1);
1275 let n3 = Node::new('_', &n2);
1276 let n4 = Node::new('t', &n3);
1277 let n5 = Node::new('r', &n4);
1278 let n6 = Node::new('i', &n5);
1279 let n7 = Node::new('e', &n6);
1280
1281 let mut buf = Vec::new();
1282
1283 let res = construct_e(&n7, &mut buf);
1284 assert_eq!("lr_trie", res.as_str());
1285 assert_eq!(0, buf.len());
1286 }
1287
1288 #[test]
1289 fn root_escape() {
1290 let mut root = Node::empty();
1291 root.c = 'r';
1292
1293 let mut buf = Vec::new();
1294
1295 let res = construct_e(&root, &mut buf);
1296 assert_eq!("", res.as_str());
1297 assert_eq!(0, buf.len());
1298 assert_eq!(0, buf.capacity());
1299 }
1300 }
1301
1302 mod trie {
1303
1304 use crate::{uc::UC, LeftRight, LrTrie, Node};
1305
1306 #[test]
1307 fn new() {
1308 let trie = LrTrie::new();
1309 let empty = Node::empty();
1310
1311 assert_eq!(empty, trie.left);
1312 assert_eq!(empty, trie.right);
1313 assert_eq!(UC::new(Vec::new()), trie.trace);
1314 assert_eq!(UC::new(Vec::new()), trie.entry);
1315 assert_eq!(0, trie.count);
1316 }
1317
1318 mod insert {
1319
1320 use crate::{Entry, Key, KeyEntry, LeftRight, Links, LrTrie, Node};
1321
1322 fn last_node(links: &Links) -> &Node {
1323 let node = links.get(0);
1324 assert!(node.is_some());
1325
1326 let mut node = node.unwrap();
1327 while let Some(l) = node.links.as_ref() {
1328 let n = l.get(0);
1329 assert!(n.is_some());
1330
1331 node = n.as_ref().unwrap();
1332 }
1333
1334 node
1335 }
1336
1337 fn insert(trie: &mut LrTrie, lke: &Entry, rke: &Entry) -> (*const Node, *const Node) {
1338 trie.insert(lke, rke);
1339
1340 let l_links = &trie.left.links.as_ref().unwrap();
1341 let r_links = &trie.right.links.as_ref().unwrap();
1342
1343 (last_node(l_links), last_node(r_links))
1344 }
1345
1346 fn put_id(node: *const Node, val: usize) {
1347 let node = node.cast_mut();
1348 Node::as_mut(node).id = val;
1349 }
1350
1351 #[test]
1352 fn basic_test() {
1353 let left_ke = &KeyEntry("LEFT");
1354 let right_ke = &KeyEntry("RIGHT");
1355
1356 let trie = &mut LrTrie::new();
1357 trie.insert(left_ke, right_ke);
1358
1359 assert_eq!(1, trie.count);
1360
1361 let left = verify(trie, left_ke, LeftRight::Left, right_ke);
1362 let right = verify(trie, right_ke, LeftRight::Right, left_ke);
1363
1364 assert_eq!(left.lrref, right as *const Node);
1365 assert_eq!(right.lrref, left as *const Node);
1366
1367 fn verify<'a>(trie: &'a LrTrie, key: &Key, lr: LeftRight, e: &Entry) -> &'a Node {
1368 let member = trie.member(key, lr.clone());
1369 assert!(member.is_some());
1370 assert_eq!(e.0, &member.unwrap());
1371
1372 last_node(trie.links(lr).unwrap())
1373 }
1374 }
1375
1376 #[test]
1377 fn reinsert_same() {
1378 #[rustfmt::skip]
1379 let duos = [
1380 ("LEFT", "RIGHT"),
1381 ("L", "R"),
1382 ("LEFT", "R"),
1383 ("L", "RIGHT")
1384 ];
1385
1386 for d in duos {
1387 let left_ke = &KeyEntry(d.0);
1388 let right_ke = &KeyEntry(d.1);
1389
1390 let trie = &mut LrTrie::new();
1391
1392 let (lln_a_ptr, rln_a_ptr) = insert(trie, left_ke, right_ke);
1393 assert_eq!(1, trie.count);
1394
1395 put_id(lln_a_ptr, 1);
1396 put_id(rln_a_ptr, 2);
1397
1398 let (lln_b_ptr, rln_b_ptr) = insert(trie, left_ke, right_ke);
1399 assert_eq!(1, trie.count);
1400
1401 let lln_b_ref = Node::as_ref(lln_b_ptr);
1402 let rln_b_ref = Node::as_ref(rln_b_ptr);
1403
1404 assert_eq!(1, lln_b_ref.id); assert_ne!(2, rln_b_ref.id); assert_eq!(0, rln_b_ref.id); verify(trie, left_ke, LeftRight::Left, right_ke);
1409 verify(trie, right_ke, LeftRight::Right, left_ke);
1410
1411 fn verify(trie: &LrTrie, key: &Key, lr: LeftRight, e: &Entry) {
1412 let member = trie.member(key, lr);
1413 assert!(member.is_some());
1414 assert_eq!(e.0, member.unwrap());
1415 }
1416 }
1417 }
1418
1419 #[test]
1420 fn reinsert_different() {
1421 #[rustfmt::skip]
1422 let triplets = [
1423 ("ONE", "ANOTHER", "REPLACEMENT"),
1424 ("ONE", "A", "R"),
1425 ("ONE", "ANOTHER", "R"),
1426 ("ONE", "A", "REPLACEMENT"),
1427
1428 ("O", "ANOTHER", "REPLACEMENT"),
1429 ("O", "A", "R"),
1430 ("O", "A", "REPLACEMENT"),
1431 ("O", "ANOTHER", "R"),
1432 ];
1433
1434 for t in triplets {
1435 let one = &KeyEntry(t.0);
1436 let another = &KeyEntry(t.1);
1437 let replacement = &KeyEntry(t.2);
1438
1439 for lr in [LeftRight::Left, LeftRight::Right] {
1440 let trie = &mut LrTrie::new();
1441
1442 let (lln_a_ptr, rln_a_ptr) = insert(trie, one, another);
1443 assert_eq!(1, trie.count);
1444
1445 put_id(lln_a_ptr, 97);
1446 put_id(rln_a_ptr, 98);
1447
1448 let (lln_b_ptr, rln_b_ptr) = if lr == LeftRight::Left {
1449 insert(trie, replacement, another)
1450 } else {
1451 insert(trie, one, replacement)
1452 };
1453
1454 assert_eq!(1, trie.count);
1455
1456 let (lln_b_ref, rln_b_ref) =
1457 (Node::as_ref(lln_b_ptr), Node::as_ref(rln_b_ptr));
1458
1459 let (kept, removed) = if lr == LeftRight::Left {
1460 assert_eq!(0, lln_b_ref.id);
1461 assert_eq!(98, rln_b_ref.id);
1462 (another, one)
1463 } else {
1464 assert_eq!(97, lln_b_ref.id);
1465 assert_eq!(0, rln_b_ref.id);
1466 (one, another)
1467 };
1468
1469 assert!(trie.member(replacement, lr.clone()).is_some());
1470 assert!(trie.member(kept, lr.clone().invert()).is_some());
1471 assert!(trie.member(removed, lr).is_none());
1472 }
1473 }
1474 }
1475
1476 #[test]
1477 fn entry_map_merge() {
1478 let mut trie = LrTrie::new();
1479
1480 let a1 = &KeyEntry("A1");
1481 let a2 = &KeyEntry("A2");
1482 let b1 = &KeyEntry("B1");
1483 let b2 = &KeyEntry("B2");
1484
1485 trie.insert(a1, b1);
1486 trie.insert(b2, a2);
1487
1488 assert_eq!(2, trie.count);
1489 trie.insert(a1, a2);
1490 assert_eq!(1, trie.count);
1491
1492 assert_eq!(Some(a2.0.to_string()), trie.member(a1, LeftRight::Left));
1493 assert_eq!(Some(a1.0.to_string()), trie.member(a2, LeftRight::Right));
1494
1495 assert_eq!(None, trie.member(b1, LeftRight::Right));
1496 assert_eq!(None, trie.member(b2, LeftRight::Left));
1497 }
1498 }
1499
1500 mod track {
1501
1502 use crate::{KeyEntry, LeftRight, LrTrie, Node, TraRes, TraStrain};
1503
1504 #[test]
1505 fn tracing() {
1506 let mut trie = LrTrie::new();
1507
1508 let entries = ["key", "keyword", "keyboard", "keyhole"];
1509 let entries = entries.map(|x| KeyEntry(x));
1510
1511 for e in entries.iter() {
1512 trie.insert(&e, &e);
1513 }
1514
1515 let keyword = &entries[1];
1516 _ = trie.track(keyword, LeftRight::Left, TraStrain::TraEmp);
1517
1518 let trace = trie.cc_trace();
1519
1520 assert_eq!(keyword.0.len() + 1, trace.len());
1521
1522 let l_root: *const Node = &trie.left;
1523 assert_eq!(l_root as usize, trace[0].1 as usize);
1524
1525 for k in entries[0..2].iter() {
1526 let s = k.0;
1527 for (ix, c) in s.chars().enumerate() {
1528 let pn = &trace[ix + 1];
1529 assert_eq!(0, pn.0);
1530
1531 let n = pn.n_ref();
1532 assert_eq!(c, n.c);
1533 }
1534
1535 let en = &trace[s.len()].n_ref();
1536 assert_eq!(true, en.lrref());
1537 }
1538
1539 _ = trie.track(&entries[3], LeftRight::Left, TraStrain::TraEmp);
1540 let trace = trie.cc_trace();
1541
1542 let h_node = &trace[4];
1543 assert_eq!('h', h_node.n_ref().c);
1544
1545 assert_eq!(2, h_node.0);
1546 }
1547
1548 #[test]
1549 fn ok() {
1550 let entry = &KeyEntry("información meteorológica");
1551
1552 let mut trie = LrTrie::new();
1553 _ = trie.insert(entry, entry);
1554 let res = trie.track(entry, LeftRight::Left, TraStrain::NonEmp);
1555
1556 match res {
1557 TraRes::Ok => {}
1558 _ => panic!("Not `TraRes::Ok`, but {:?}.", res),
1559 }
1560 }
1561
1562 #[test]
1563 fn ok_ref() {
1564 let entry = &KeyEntry("información meteorológica X");
1565
1566 let mut trie = LrTrie::new();
1567 _ = trie.insert(entry, entry);
1568 let res = trie.track(entry, LeftRight::Left, TraStrain::NonRef);
1569
1570 match res {
1571 TraRes::OkRef(n) => {
1572 assert_eq!(true, n.lrref());
1573 assert_eq!('X', n.c);
1574 }
1575 _ => panic!("Not `TraRes::OkRef(_)`, but {:?}.", res),
1576 }
1577 }
1578
1579 #[test]
1580 #[should_panic(expected = "Unsupported result scenario.")]
1581 fn unsupported_result() {
1582 let entry = &KeyEntry("información meteorológica");
1583
1584 let mut trie = LrTrie::new();
1585 _ = trie.insert(entry, entry);
1586
1587 _ = trie.track(entry, LeftRight::Left, TraStrain::NonMut);
1588 }
1589
1590 #[test]
1591 fn unknown_not_path() {
1592 let entry = &KeyEntry("wordbook");
1593 let key = &KeyEntry("wordbooks");
1594
1595 let mut trie = LrTrie::new();
1596 _ = trie.insert(entry, entry);
1597 let res = trie.track(key, LeftRight::Left, TraStrain::NonEmp);
1598 assert_eq!(TraRes::UnknownForAbsentPathLinks, res);
1599 }
1600
1601 #[test]
1602 fn unknown_not_path2() {
1603 let entry = &KeyEntry("wordbookz");
1604 let key = &KeyEntry("wordbooks");
1605
1606 let mut trie = LrTrie::new();
1607 _ = trie.insert(entry, entry);
1608 let res = trie.track(key, LeftRight::Left, TraStrain::NonEmp);
1609 assert_eq!(TraRes::UnknownForAbsentPathNode, res);
1610 }
1611
1612 #[test]
1613 fn unknown_not_entry() {
1614 let entry = &KeyEntry("wordbooks");
1615 let key = &KeyEntry("wordbook");
1616
1617 let mut trie = LrTrie::new();
1618 _ = trie.insert(entry, entry);
1619
1620 let res = trie.track(key, LeftRight::Left, TraStrain::NonEmp);
1621 assert_eq!(TraRes::UnknownForNotEntry, res);
1622 }
1623 }
1624
1625 mod member {
1626
1627 use crate::{Entry, Key, KeyEntry, LeftRight, LrTrie};
1628
1629 #[test]
1630 fn member() {
1631 let left_ke = KeyEntry("LEFT");
1632 let right_ke = KeyEntry("RIGHT");
1633
1634 let mut trie = LrTrie::new();
1635 trie.insert(&left_ke, &right_ke);
1636 assert_eq!(0, trie.entry.capacity());
1637
1638 verify(&left_ke, LeftRight::Left, &right_ke, &trie);
1639 verify(&right_ke, LeftRight::Right, &left_ke, &trie);
1640
1641 fn verify(key: &Key, lr: LeftRight, e: &Entry, trie: &LrTrie) {
1642 let entry = trie.member(key, lr);
1643 assert!(entry.is_some());
1644 assert_eq!(e.0, &entry.unwrap());
1645 assert_eq!(0, trie.entry.len());
1646 assert_eq!(true, trie.entry.capacity() > 0);
1647 }
1648 }
1649
1650 #[test]
1651 fn not_member() {
1652 let keyword = KeyEntry("Keyword");
1653
1654 let mut trie = LrTrie::new();
1655 trie.insert(&keyword, &keyword);
1656
1657 for lr in [LeftRight::Left, LeftRight::Right] {
1658 for key in ["Key", "Opener"] {
1659 let key = KeyEntry(key);
1660
1661 let member = trie.member(&key, lr.clone());
1662 assert!(member.is_none());
1663 }
1664 }
1665 }
1666 }
1667
1668 #[test]
1669 fn root() {
1670 let trie = LrTrie::new();
1671
1672 let left = &trie.left as *const Node as usize;
1673 let right = &trie.right as *const Node as usize;
1674
1675 let vals = [(left, LeftRight::Left), (right, LeftRight::Right)];
1676 for v in vals {
1677 let test = trie.root(v.1) as *const Node as usize;
1678 assert_eq!(v.0, test);
1679 }
1680 }
1681
1682 use crate::Links;
1683
1684 #[test]
1685 fn links() {
1686 let mut trie = LrTrie::new();
1687 let l_proof: *const Links = trie.left.links.get_or_insert(Links::new());
1688 let r_proof: *const Links = trie.right.links.get_or_insert(Links::new());
1689
1690 let l_test: *const Links = trie.links(LeftRight::Left).unwrap();
1691 let r_test: *const Links = trie.links(LeftRight::Right).unwrap();
1692
1693 assert_eq!(l_proof, l_test);
1694 assert_eq!(r_proof, r_test);
1695 }
1696
1697 mod delete {
1701
1702 use std::ops::Deref;
1703
1704 use crate::{tra::TraStrain, Key, KeyEntry, LeftRight, LrTrie};
1705
1706 #[test]
1707 fn known_unknown() {
1708 let known = &KeyEntry("plainoperator");
1709 let unknown = &KeyEntry("secretagent");
1710
1711 let mut trie = LrTrie::new();
1712 _ = trie.insert(&known, &known);
1713
1714 assert_eq!(Err(()), trie.delete(&unknown, LeftRight::Left));
1715 assert_eq!(0, trie.trace.len());
1716 assert_eq!(1, trie.count);
1717
1718 assert_eq!(Ok(()), trie.delete(&known, LeftRight::Left));
1719 assert_eq!(0, trie.trace.len());
1720 assert_eq!(0, trie.count);
1721 assert_eq!(None, trie.member(&known, LeftRight::Right));
1722 }
1723
1724 #[test]
1725 fn inner_entry() {
1726 let mut trie = LrTrie::new();
1727
1728 let outer = KeyEntry("Keyword");
1729 trie.insert(&outer, &outer);
1730
1731 for lr in [LeftRight::Left, LeftRight::Right] {
1732 let inner = KeyEntry("Key");
1733 trie.insert(&inner, &inner);
1734
1735 assert!(trie.delete(&inner, lr).is_ok());
1736 assert!(trie.member(&inner, LeftRight::Left).is_none());
1737 assert!(trie.member(&inner, LeftRight::Right).is_none());
1738 assert!(trie.member(&outer, LeftRight::Left).is_some());
1739 assert!(trie.member(&outer, LeftRight::Right).is_some());
1740 }
1741 }
1742
1743 #[test]
1744 fn branching_node() {
1745 let keyword = KeyEntry("Keyword");
1746 let keyboard = KeyEntry("Keyboard");
1747 let keypad = KeyEntry("Keypad");
1748 let key: Key = KeyEntry("Key");
1749
1750 for lr in [LeftRight::Left, LeftRight::Right] {
1751 let mut trie = LrTrie::new();
1752 trie.insert(&keyword, &keyword);
1753 trie.insert(&keyboard, &keyboard);
1754 trie.insert(&keypad, &keypad);
1755
1756 assert!(trie.delete(&keyboard, lr).is_ok());
1757
1758 for lr in [LeftRight::Left, LeftRight::Right] {
1759 assert!(trie.member(&keyboard, lr.clone()).is_none());
1760 assert!(trie.member(&keyword, lr.clone()).is_some());
1761 assert!(trie.member(&keypad, lr.clone()).is_some());
1762
1763 _ = trie.track(&key, lr, TraStrain::TraEmp);
1764 let y_node = trie.trace[key.0.len()].n_ref();
1765 let links = y_node.links.as_ref().unwrap();
1766 assert_eq!(2, links.len());
1767 let filtered = links.iter().filter(|x| x.c == 'w' || x.c == 'p').count();
1768 assert_eq!(2, filtered);
1769 }
1770 }
1771 }
1772
1773 #[test]
1774 fn links_removal() {
1775 let keyword = KeyEntry("Keyword");
1776 let mut trie = LrTrie::new();
1777
1778 for lr in [LeftRight::Left, LeftRight::Right] {
1779 trie.insert(&keyword, &keyword);
1780
1781 assert!(trie.delete(&keyword, lr.clone()).is_ok());
1782 assert!(trie.member(&keyword, lr.clone()).is_none());
1783 assert!(trie.member(&keyword, lr.invert()).is_none());
1784
1785 assert!(trie.links(LeftRight::Left).is_none());
1786 assert!(trie.links(LeftRight::Right).is_none());
1787 }
1788 }
1789
1790 #[test]
1791 fn node_composing_path() {
1792 let dissimilar = KeyEntry("Dissimilar");
1793 let keyword = KeyEntry("Keyword");
1794
1795 for lr in [LeftRight::Left, LeftRight::Right] {
1796 let mut trie = LrTrie::new();
1797
1798 trie.insert(&dissimilar, &dissimilar);
1799 trie.insert(&keyword, &keyword);
1800
1801 assert!(trie.delete(&keyword, lr.clone()).is_ok());
1802 assert!(trie.member(&keyword, lr.clone()).is_none());
1803 assert!(trie.member(&dissimilar, lr).is_some());
1804 }
1805 }
1806
1807 #[test]
1808 fn node_being_keyentry() {
1809 let keyword = KeyEntry("Keyword");
1810 let k = KeyEntry("K");
1811
1812 let mut trie = LrTrie::new();
1813 trie.insert(&k, &k);
1814
1815 for lr in [LeftRight::Left, LeftRight::Right] {
1816 trie.insert(&keyword, &keyword);
1817
1818 assert!(trie.delete(&keyword, lr.clone()).is_ok());
1819 assert!(trie.member(&keyword, lr.clone()).is_none());
1820 assert!(trie.member(&k, lr.clone()).is_some());
1821
1822 let links = trie.links(lr);
1823 let k = &links.unwrap()[0];
1824 assert_eq!(false, k.links());
1825 }
1826 }
1827
1828 #[test]
1829 fn one_letter_a() {
1830 let keyword = KeyEntry("Keyword");
1831 let k = KeyEntry("K");
1832
1833 let mut trie = LrTrie::new();
1834 trie.insert(&keyword, &keyword);
1835
1836 for lr in [LeftRight::Left, LeftRight::Right] {
1837 trie.insert(&k, &k);
1838
1839 assert!(trie.delete(&k, lr.clone()).is_ok());
1840 assert!(trie.member(&k, lr.clone()).is_none());
1841 assert!(trie.member(&keyword, lr.clone()).is_some());
1842
1843 let links = trie.links(lr);
1844 let k = links.unwrap()[0].deref();
1845 assert_eq!('K', k.c);
1846 assert_eq!(true, k.links());
1847 }
1848 }
1849
1850 #[test]
1851 fn one_letter_b() {
1852 let c = KeyEntry("C");
1853 let k = KeyEntry("K");
1854
1855 let mut trie = LrTrie::new();
1856 trie.insert(&c, &c);
1857
1858 for lr in [LeftRight::Left, LeftRight::Right] {
1859 trie.insert(&k, &k);
1860
1861 assert!(trie.delete(&k, lr.clone()).is_ok());
1862 assert!(trie.member(&k, lr.clone()).is_none());
1863 assert!(trie.member(&c, lr.clone()).is_some());
1864
1865 let links = trie.links(lr);
1866 let c = links.unwrap()[0].deref();
1867 assert_eq!('C', c.c);
1868 }
1869 }
1870 }
1871
1872 mod put_buf_cap {
1873 use crate::{Buffer, LrTrie};
1874
1875 #[test]
1876 fn trace() {
1877 let mut trie = LrTrie::new();
1878 assert_eq!(0, trie.trace.capacity());
1879
1880 let cap = 100;
1881 let size = trie.put_buf_cap(cap, Buffer::Delete);
1882 assert_eq!(true, size >= cap);
1883 assert_eq!(true, trie.trace.capacity() >= cap);
1884 }
1885
1886 #[test]
1887 fn entry() {
1888 let mut trie = LrTrie::new();
1889 assert_eq!(0, trie.entry.capacity());
1890
1891 let cap = 100;
1892 let size = trie.put_buf_cap(cap, Buffer::Member);
1893 assert_eq!(true, size >= cap);
1894 assert_eq!(true, trie.entry.capacity() >= cap);
1895 }
1896 }
1897
1898 mod aq_buf_cap {
1899 use crate::{Buffer, LrTrie};
1900
1901 #[test]
1902 fn trace() {
1903 let cap = 10;
1904 let trie = LrTrie::new();
1905 let buf = trie.trace.get_mut();
1906
1907 assert!(buf.capacity() < cap);
1908 buf.reserve_exact(cap);
1909 let cap = buf.capacity();
1910
1911 assert_eq!(cap, trie.aq_buf_cap(Buffer::Delete));
1912 }
1913
1914 #[test]
1915 fn entry() {
1916 let cap = 10;
1917 let trie = LrTrie::new();
1918 let buf = trie.entry.get_mut();
1919
1920 assert!(buf.capacity() < cap);
1921 buf.reserve_exact(cap);
1922 let cap = buf.capacity();
1923
1924 assert_eq!(cap, trie.aq_buf_cap(Buffer::Member));
1925 }
1926 }
1927 }
1928
1929 use crate::KeyEntry;
1930 #[test]
1931 fn clear() {
1932 let mut trie = LrTrie::new();
1933 let entry = KeyEntry("Key");
1934 trie.insert(&entry, &entry);
1935
1936 assert_eq!(1, trie.clear());
1937 assert_eq!(0, trie.count);
1938
1939 assert_eq!(trie.left, Node::empty());
1940 assert_eq!(trie.right, Node::empty());
1941 assert_eq!(trie, LrTrie::new());
1942 }
1943
1944 #[test]
1945 fn count() {
1946 let mut trie = LrTrie::new();
1947 assert_eq!(0, trie.count());
1948
1949 trie.count = 99;
1950
1951 assert_eq!(99, trie.count());
1952 }
1953
1954 mod extract {
1955 use crate::{KeyEntry, LeftRight, LrTrie};
1956
1957 #[test]
1958 fn left() {
1959 let proof = [
1960 ("olivenite", "limelight"),
1961 ("olivewood", "limehound"),
1962 ("tapestry", "platform"),
1963 ("lemonade", "podium"),
1964 ("lemongrass", "rostrum"),
1965 ("cheque", "constellation"),
1966 ("array", "formation"),
1967 ];
1968
1969 let mut trie = LrTrie::new();
1970 for es in proof {
1971 trie.insert(&KeyEntry(es.0), &KeyEntry(es.1));
1972 }
1973
1974 let ext = trie.extract(LeftRight::Left);
1975 assert_eq!(true, ext.is_some());
1976 let ext = ext.unwrap();
1977
1978 assert_eq!(proof.len(), ext.len());
1979
1980 for z in proof.iter().zip(ext.iter()) {
1981 let p = z.0;
1982 let l = z.1;
1983
1984 assert_eq!(p.0, l.0);
1985 assert_eq!(p.1, l.1);
1986 }
1987 }
1988
1989 #[test]
1990 fn right() {
1991 let proof = [
1992 ("olivenite", "limelight"),
1993 ("olivewood", "limehound"),
1994 ("lemon", "bandoline"),
1995 ("lemonade", "podium"),
1996 ("lemon balm", "platina"),
1997 ("cheque", "constellation"),
1998 ("season", "crops"),
1999 ];
2000
2001 let mut trie = LrTrie::new();
2002 for es in proof {
2003 trie.insert(&KeyEntry(es.0), &KeyEntry(es.1));
2004 }
2005
2006 let ext = trie.extract(LeftRight::Right);
2007 assert_eq!(true, ext.is_some());
2008 let ext = ext.unwrap();
2009
2010 assert_eq!(proof.len(), ext.len());
2011
2012 for z in proof.iter().zip(ext.iter()) {
2013 let p = z.0;
2014 let r = z.1;
2015
2016 assert_eq!(p.0, r.1);
2017 assert_eq!(p.1, r.0);
2018 }
2019 }
2020
2021 #[test]
2022 fn empty() {
2023 let trie = LrTrie::new();
2024 assert_eq!(None, trie.extract(LeftRight::Right));
2025 assert_eq!(None, trie.extract(LeftRight::Left));
2026 }
2027 }
2028
2029 #[test]
2031 fn load_1() {
2032 const P_LEN: usize = 15;
2033 let proof: [(&str, &str); P_LEN] = [
2034 ("olivenite", "limelight"),
2035 ("olivewood", "limehound"),
2036 ("olivary", "limestone"),
2037 ("oligotrophic", "limescale"),
2038 ("lemon", "bandoline"),
2039 ("lemonade", "podium"),
2040 ("lemongrass", "rostrum"),
2041 ("lemon balm", "platina"),
2042 ("tapestry", "platform"),
2043 ("tapis", "constituent"),
2044 ("temperate", "region"),
2045 ("cheque", "constellation"),
2046 ("array", "formation"),
2047 ("season", "crops"),
2048 ("glassware", "glasswork"),
2049 ];
2050
2051 let mut trie = LrTrie::new();
2052 for es in proof {
2053 trie.insert(&KeyEntry(es.0), &KeyEntry(es.1));
2054 }
2055 for p in proof {
2056 let entry = trie.member(&KeyEntry(p.0), LeftRight::Left);
2057 assert_eq!(p.1, entry.unwrap().as_str());
2058
2059 let entry = trie.member(&KeyEntry(p.1), LeftRight::Right);
2060 assert_eq!(p.0, entry.unwrap().as_str());
2061 }
2062
2063 for i in 0..P_LEN {
2064 if i & 1 == 0 {
2065 assert_eq!(Ok(()), trie.delete(&KeyEntry(proof[i].0), LeftRight::Left));
2066 }
2067 }
2068
2069 for i in 0..P_LEN {
2070 let p = proof[i];
2071
2072 if i & 1 == 1 {
2073 let entry = trie.member(&KeyEntry(p.0), LeftRight::Left);
2074 assert_eq!(p.1, entry.unwrap().as_str());
2075
2076 let entry = trie.member(&KeyEntry(p.1), LeftRight::Right);
2077 assert_eq!(p.0, entry.unwrap().as_str());
2078 } else {
2079 let entry = trie.member(&KeyEntry(p.0), LeftRight::Left);
2080 assert_eq!(true, entry.is_none());
2081
2082 let entry = trie.member(&KeyEntry(p.1), LeftRight::Right);
2083 assert_eq!(true, entry.is_none());
2084 }
2085 }
2086 }
2087
2088 #[test]
2090 fn load_2() {
2091 const P_LEN: usize = 15;
2092 let last_ix = P_LEN - 1;
2093 let proof: [(&str, &str); P_LEN] = [
2094 ("olivenite", "limelight"),
2095 ("olivewood", "limehound"),
2096 ("olivary", "limestone"),
2097 ("oligotrophic", "limescale"),
2098 ("lemon", "bandoline"),
2099 ("lemonade", "podium"),
2100 ("lemongrass", "rostrum"),
2101 ("lemon balm", "platina"),
2102 ("tapestry", "platform"),
2103 ("tapis", "constituent"),
2104 ("temperate", "region"),
2105 ("cheque", "constellation"),
2106 ("array", "formation"),
2107 ("season", "crops"),
2108 ("glassware", "glasswork"),
2109 ];
2110
2111 let mut trie = LrTrie::new();
2112 for es in proof {
2113 trie.insert(&KeyEntry(es.0), &KeyEntry(es.1));
2114 }
2115 for p in proof {
2116 let entry = trie.member(&KeyEntry(p.0), LeftRight::Left);
2117 assert_eq!(p.1, entry.unwrap().as_str());
2118
2119 let entry = trie.member(&KeyEntry(p.1), LeftRight::Right);
2120 assert_eq!(p.0, entry.unwrap().as_str());
2121 }
2122
2123 for i in 1..last_ix {
2124 assert_eq!(Ok(()), trie.delete(&KeyEntry(proof[i].1), LeftRight::Right));
2125 }
2126
2127 for i in 1..last_ix {
2128 let p = proof[i];
2129
2130 assert_eq!(None, trie.member(&KeyEntry(p.0), LeftRight::Left));
2131 assert_eq!(None, trie.member(&KeyEntry(p.1), LeftRight::Right));
2132 }
2133
2134 for i in [0, last_ix] {
2135 let p = proof[i];
2136
2137 let entry = trie.member(&KeyEntry(p.0), LeftRight::Left);
2138 assert_eq!(p.1, entry.unwrap().as_str());
2139
2140 let entry = trie.member(&KeyEntry(p.1), LeftRight::Right);
2141 assert_eq!(p.0, entry.unwrap().as_str());
2142 }
2143 }
2144
2145 mod readme {
2146 use crate::{KeyEntry, LeftRight, LrTrie};
2147
2148 #[test]
2149 fn test() {
2150 const ONE: &str = "emoción";
2151 const ANOTHER: &str = "emotion";
2152 const REPLACEMENT: &str = "equilibrio sicofísico";
2153
2154 let mut trie = LrTrie::new();
2155
2156 let one = &KeyEntry::new(ONE).unwrap();
2157 let another = &KeyEntry::new(ANOTHER).unwrap();
2158 let replacement = &KeyEntry::new(REPLACEMENT).unwrap();
2159
2160 trie.insert(one, another);
2161 assert!(trie.member(one, LeftRight::Left).is_some());
2162 assert!(trie.member(another, LeftRight::Left).is_none());
2163 assert!(trie.member(another, LeftRight::Right).is_some());
2164
2165 trie.insert(one, replacement);
2166 assert_eq!(
2167 Some(String::from(REPLACEMENT)),
2168 trie.member(&one, LeftRight::Left)
2169 );
2170 assert!(trie.member(another, LeftRight::Right).is_none());
2171 assert_eq!(
2172 Some(String::from(ONE)),
2173 trie.member(replacement, LeftRight::Right)
2174 );
2175
2176 assert_eq!(Ok(()), trie.delete(one, LeftRight::Left));
2177
2178 assert!(trie.member(one, LeftRight::Left).is_none());
2179 assert!(trie.member(replacement, LeftRight::Right).is_none());
2180
2181 assert_eq!(Err(()), trie.delete(replacement, LeftRight::Right));
2182 }
2183 }
2184}
2185
2186