1use std::alloc::{Layout, alloc, dealloc, handle_alloc_error};
40use std::cmp::Ordering;
41use std::fmt;
42use std::ops::{Index, IndexMut};
43
44pub struct HashedArrayTree<T> {
46 index: Vec<*mut T>,
48 count: usize,
50 k: usize,
52 k_mask: usize,
54 l: usize,
56 upper_limit: usize,
58 lower_limit: usize,
60}
61
62impl<T> HashedArrayTree<T> {
63 pub fn new() -> Self {
65 let index: Vec<*mut T> = vec![];
66 Self {
67 index,
68 count: 0,
69 k: 2,
70 k_mask: 3,
71 l: 4,
72 upper_limit: 16,
73 lower_limit: 0,
74 }
75 }
76
77 fn expand(&mut self) {
80 let l_prime = 1 << (self.k + 1);
81 let old_index: Vec<*mut T> = std::mem::take(&mut self.index);
82 let mut iter = old_index.into_iter();
83 while let Some(a) = iter.next() {
84 let layout = Layout::array::<T>(l_prime).expect("unexpected overflow");
85 let buffer = unsafe {
86 let ptr = alloc(layout).cast::<T>();
87 if ptr.is_null() {
88 handle_alloc_error(layout);
89 }
90 ptr
91 };
92 if let Some(b) = iter.next() {
93 let b_dst = unsafe { buffer.add(self.l) };
94 let old_layout = Layout::array::<T>(self.l).expect("unexpected overflow");
95 unsafe {
96 std::ptr::copy(a, buffer, self.l);
97 std::ptr::copy(b, b_dst, self.l);
98 dealloc(a as *mut u8, old_layout);
99 dealloc(b as *mut u8, old_layout);
100 }
101 } else {
102 let old_layout = Layout::array::<T>(self.l).expect("unexpected overflow");
103 unsafe {
104 std::ptr::copy(a, buffer, self.l);
105 dealloc(a as *mut u8, old_layout);
106 }
107 }
108 self.index.push(buffer);
109 }
110 self.k += 1;
111 self.k_mask = (1 << self.k) - 1;
112 self.l = 1 << self.k;
113 self.upper_limit = self.l * self.l;
114 self.lower_limit = self.upper_limit / 8;
115 }
116
117 pub fn push(&mut self, value: T) {
127 let len = self.count;
128 if len >= self.upper_limit {
129 self.expand();
130 }
131 if len >= self.capacity() {
132 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
133 let buffer = unsafe {
134 let ptr = alloc(layout).cast::<T>();
135 if ptr.is_null() {
136 handle_alloc_error(layout);
137 }
138 ptr
139 };
140 self.index.push(buffer);
141 }
142 let block = len >> self.k;
143 let slot = len & self.k_mask;
144 unsafe { std::ptr::write(self.index[block].add(slot), value) }
145 self.count += 1;
146 }
147
148 pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
155 if self.capacity() <= self.count {
156 Err(value)
157 } else {
158 self.push(value);
159 Ok(())
160 }
161 }
162
163 fn raw_get(&self, index: usize) -> &T {
165 let block = index >> self.k;
166 let slot = index & self.k_mask;
167 unsafe { &*self.index[block].add(slot) }
168 }
169
170 pub fn get(&self, index: usize) -> Option<&T> {
176 if index >= self.count {
177 None
178 } else {
179 Some(self.raw_get(index))
180 }
181 }
182
183 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
189 if index >= self.count {
190 None
191 } else {
192 let block = index >> self.k;
193 let slot = index & self.k_mask;
194 unsafe { (self.index[block].add(slot)).as_mut() }
195 }
196 }
197
198 fn compress(&mut self) {
201 let old_index: Vec<*mut T> = std::mem::take(&mut self.index);
202 for old_buffer in old_index.into_iter() {
203 let half = self.l / 2;
204 let layout = Layout::array::<T>(half).expect("unexpected overflow");
205 let a = unsafe {
206 let ptr = alloc(layout).cast::<T>();
207 if ptr.is_null() {
208 handle_alloc_error(layout);
209 }
210 ptr
211 };
212 let b = unsafe {
213 let ptr = alloc(layout).cast::<T>();
214 if ptr.is_null() {
215 handle_alloc_error(layout);
216 }
217 ptr
218 };
219 unsafe {
220 std::ptr::copy(old_buffer, a, half);
221 std::ptr::copy(old_buffer.add(half), b, half);
222 };
223 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
224 unsafe {
225 dealloc(old_buffer as *mut u8, layout);
226 }
227 self.index.push(a);
228 self.index.push(b);
229 }
230 self.k -= 1;
231 self.k_mask = (1 << self.k) - 1;
232 self.l = 1 << self.k;
233 self.upper_limit = self.l * self.l;
234 self.lower_limit = self.upper_limit / 8;
235 }
236
237 pub fn pop(&mut self) -> Option<T> {
244 if self.count > 0 {
245 let index = self.count - 1;
246 if index < self.lower_limit && self.k > 2 {
248 self.compress();
249 }
250 let block = index >> self.k;
251 let slot = index & self.k_mask;
252 let ret = unsafe { Some(std::ptr::read(self.index[block].add(slot))) };
253 if slot == 0 {
254 let ptr = self.index.pop().unwrap();
256 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
257 unsafe {
258 dealloc(ptr as *mut u8, layout);
259 }
260 }
261 self.count -= 1;
262 ret
263 } else {
264 None
265 }
266 }
267
268 pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
276 if self.count == 0 {
277 None
278 } else if let Some(last) = self.get_mut(self.count - 1) {
279 if predicate(last) { self.pop() } else { None }
280 } else {
281 None
282 }
283 }
284
285 pub fn swap_remove(&mut self, index: usize) -> T {
299 if index >= self.count {
300 panic!(
301 "swap_remove index (is {index}) should be < len (is {})",
302 self.count
303 );
304 }
305 let block = index >> self.k;
307 let slot = index & self.k_mask;
308 unsafe {
309 let index_ptr = self.index[block].add(slot);
310 let value = index_ptr.read();
311 let block = (self.count - 1) >> self.k;
313 let slot = (self.count - 1) & self.k_mask;
314 let last_ptr = self.index[block].add(slot);
315 std::ptr::copy(last_ptr, index_ptr, 1);
316 if slot == 0 {
317 let ptr = self.index.pop().unwrap();
319 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
320 dealloc(ptr as *mut u8, layout);
321 }
322 self.count -= 1;
323 value
324 }
325 }
326
327 pub fn iter(&self) -> ArrayIter<'_, T> {
331 ArrayIter {
332 array: self,
333 index: 0,
334 }
335 }
336
337 pub fn len(&self) -> usize {
343 self.count
344 }
345
346 pub fn capacity(&self) -> usize {
353 (1 << self.k) * self.index.len()
354 }
355
356 pub fn is_empty(&self) -> bool {
362 self.count == 0
363 }
364
365 pub fn clear(&mut self) {
371 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
372
373 if self.count > 0 && std::mem::needs_drop::<T>() {
374 let last_index = self.count - 1;
376 let last_block = last_index >> self.k;
377 let last_slot = last_index & self.k_mask;
378 unsafe {
379 drop_in_place(slice_from_raw_parts_mut(
382 self.index[last_block],
383 last_slot + 1,
384 ));
385 }
386
387 for block in 0..last_block {
389 unsafe {
390 drop_in_place(slice_from_raw_parts_mut(self.index[block], self.l));
391 }
392 }
393 }
394
395 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
397 for block in 0..self.index.len() {
398 unsafe {
399 dealloc(self.index[block] as *mut u8, layout);
400 }
401 }
402 self.index.clear();
403
404 self.count = 0;
405 self.k = 2;
406 self.k_mask = 3;
407 self.l = 1 << self.k;
408 self.upper_limit = self.l * self.l;
409 self.lower_limit = 0;
410 }
411
412 pub fn swap(&mut self, a: usize, b: usize) {
419 if a >= self.count {
420 panic!("swap a (is {a}) should be < len (is {})", self.count);
421 }
422 if b >= self.count {
423 panic!("swap b (is {b}) should be < len (is {})", self.count);
424 }
425 let a_block = a >> self.k;
428 let a_slot = a & self.k_mask;
429 let b_block = b >> self.k;
430 let b_slot = b & self.k_mask;
431 unsafe {
432 let a_ptr = self.index[a_block].add(a_slot);
433 let value = a_ptr.read();
434 let b_ptr = self.index[b_block].add(b_slot);
435 std::ptr::copy(b_ptr, a_ptr, 1);
436 std::ptr::write(b_ptr, value);
437 }
438 }
439
440 pub fn sort_unstable_by<F>(&mut self, mut compare: F)
448 where
449 F: FnMut(&T, &T) -> Ordering,
450 {
451 if self.count < 2 {
452 return;
453 }
454 let mut start = self.count / 2;
455 let mut end = self.count;
456 while end > 1 {
457 if start > 0 {
458 start -= 1;
459 } else {
460 end -= 1;
461 self.swap(end, 0);
462 }
463 let mut root = start;
464 let mut child = 2 * root + 1;
465 while child < end {
466 if child + 1 < end && compare(&self[child], &self[child + 1]) == Ordering::Less {
467 child += 1;
468 }
469 if compare(&self[root], &self[child]) == Ordering::Less {
470 self.swap(root, child);
471 root = child;
472 child = 2 * root + 1;
473 } else {
474 break;
475 }
476 }
477 }
478 }
479
480 pub fn dedup_by<F>(&mut self, mut same_bucket: F)
490 where
491 F: FnMut(&T, &T) -> bool,
492 {
493 let len = self.len();
494 if len <= 1 {
495 return;
496 }
497
498 let mut first_duplicate_idx: usize = 1;
501 while first_duplicate_idx != len {
502 let found_duplicate = {
503 let prev = self.raw_get(first_duplicate_idx - 1);
504 let current = self.raw_get(first_duplicate_idx);
505 same_bucket(current, prev)
506 };
507 if found_duplicate {
508 break;
509 }
510 first_duplicate_idx += 1;
511 }
512 if first_duplicate_idx == len {
513 return;
514 }
515
516 let index = std::mem::take(&mut self.index);
520 let old_l = self.l;
521 let mut remaining = self.count - 1;
522 self.count = 0;
523 self.clear();
524 let layout = Layout::array::<T>(old_l).expect("unexpected overflow");
525
526 let mut prev = unsafe { index[0].read() };
529 let mut slot = 1;
530 for buffer in index.into_iter() {
531 while slot < old_l {
532 let current = unsafe { buffer.add(slot).read() };
533 if same_bucket(¤t, &prev) {
534 drop(current);
535 } else {
536 self.push(prev);
537 prev = current;
538 }
539 remaining -= 1;
540 if remaining == 0 {
541 break;
542 }
543 slot += 1;
544 }
545 unsafe {
546 dealloc(buffer as *mut u8, layout);
547 }
548 slot = 0;
549 }
550 self.push(prev);
552 }
553
554 pub fn append(&mut self, other: &mut Self) {
556 let index = std::mem::take(&mut other.index);
557 let mut remaining = other.count;
558 other.count = 0;
560 let layout = Layout::array::<T>(other.l).expect("unexpected overflow");
561 for buffer in index.into_iter() {
562 for slot in 0..other.l {
563 let value = unsafe { buffer.add(slot).read() };
564 self.push(value);
565 remaining -= 1;
566 if remaining == 0 {
567 break;
568 }
569 }
570 unsafe {
571 dealloc(buffer as *mut u8, layout);
572 }
573 }
574 }
575}
576
577impl<T> Default for HashedArrayTree<T> {
578 fn default() -> Self {
579 Self::new()
580 }
581}
582
583impl<T> fmt::Display for HashedArrayTree<T> {
584 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
585 write!(
586 f,
587 "HashedArrayTree(k: {}, count: {}, dope: {})",
588 self.k,
589 self.count,
590 self.index.len(),
591 )
592 }
593}
594
595impl<T> Index<usize> for HashedArrayTree<T> {
596 type Output = T;
597
598 fn index(&self, index: usize) -> &Self::Output {
599 let Some(item) = self.get(index) else {
600 panic!("index out of bounds: {}", index);
601 };
602 item
603 }
604}
605
606impl<T> IndexMut<usize> for HashedArrayTree<T> {
607 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
608 let Some(item) = self.get_mut(index) else {
609 panic!("index out of bounds: {}", index);
610 };
611 item
612 }
613}
614
615impl<T> Drop for HashedArrayTree<T> {
616 fn drop(&mut self) {
617 self.clear();
618 }
619}
620
621impl<T: Clone> Clone for HashedArrayTree<T> {
622 fn clone(&self) -> Self {
623 let mut result = HashedArrayTree::<T>::new();
624 for value in self.iter() {
625 result.push(value.clone());
626 }
627 result
628 }
629}
630
631unsafe impl<T: Send> Send for HashedArrayTree<T> {}
632
633impl<A> FromIterator<A> for HashedArrayTree<A> {
634 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
635 let mut arr: HashedArrayTree<A> = HashedArrayTree::new();
636 for value in iter {
637 arr.push(value)
638 }
639 arr
640 }
641}
642
643pub struct ArrayIter<'a, T> {
645 array: &'a HashedArrayTree<T>,
646 index: usize,
647}
648
649impl<'a, T> Iterator for ArrayIter<'a, T> {
650 type Item = &'a T;
651
652 fn next(&mut self) -> Option<Self::Item> {
653 let value = self.array.get(self.index);
654 self.index += 1;
655 value
656 }
657}
658
659pub struct ArrayIntoIter<T> {
661 index: usize,
662 k: usize,
663 k_mask: usize,
664 count: usize,
665 dope: Vec<*mut T>,
666}
667
668impl<T> Iterator for ArrayIntoIter<T> {
669 type Item = T;
670
671 fn next(&mut self) -> Option<Self::Item> {
672 if self.index < self.count {
673 let block = self.index >> self.k;
674 let slot = self.index & self.k_mask;
675 self.index += 1;
676 unsafe { Some((self.dope[block].add(slot)).read()) }
677 } else {
678 None
679 }
680 }
681}
682
683impl<T> IntoIterator for HashedArrayTree<T> {
684 type Item = T;
685 type IntoIter = ArrayIntoIter<Self::Item>;
686
687 fn into_iter(self) -> Self::IntoIter {
688 let mut me = std::mem::ManuallyDrop::new(self);
689 let dope = std::mem::take(&mut me.index);
690 ArrayIntoIter {
691 index: 0,
692 count: me.count,
693 k: me.k,
694 k_mask: me.k_mask,
695 dope,
696 }
697 }
698}
699
700impl<T> Drop for ArrayIntoIter<T> {
701 fn drop(&mut self) {
702 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
703 let block_len = 1 << self.k;
704
705 if std::mem::needs_drop::<T>() {
706 let first_block = self.index >> self.k;
707 let first_slot = self.index & self.k_mask;
708 let last_block = (self.count - 1) >> self.k;
709 let last_slot = (self.count - 1) & self.k_mask;
710 if first_block == last_block {
711 if first_slot <= last_slot {
713 unsafe {
714 drop_in_place(slice_from_raw_parts_mut(
717 self.dope[first_block].add(first_slot),
718 last_slot - first_slot + 1,
719 ));
720 }
721 }
722 } else {
723 if block_len < self.count {
725 unsafe {
726 drop_in_place(slice_from_raw_parts_mut(
727 self.dope[first_block].add(first_slot),
728 block_len - first_slot,
729 ));
730 }
731 }
732
733 unsafe {
735 drop_in_place(slice_from_raw_parts_mut(
736 self.dope[last_block],
737 last_slot + 1,
738 ));
739 }
740
741 for block in first_block + 1..last_block {
743 unsafe {
744 drop_in_place(slice_from_raw_parts_mut(self.dope[block], block_len));
745 }
746 }
747 }
748 }
749
750 for block in 0..self.dope.len() {
752 let layout = Layout::array::<T>(block_len).expect("unexpected overflow");
753 unsafe {
754 dealloc(self.dope[block] as *mut u8, layout);
755 }
756 }
757 }
758}
759
760#[cfg(test)]
761mod tests {
762 use super::*;
763
764 #[test]
765 fn test_empty() {
766 let sut = HashedArrayTree::<usize>::new();
767 assert!(sut.get(0).is_none());
768 }
769
770 #[test]
771 #[should_panic(expected = "index out of bounds:")]
772 fn test_index_out_of_bounds() {
773 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
774 sut.push(10);
775 sut.push(20);
776 let _ = sut[2];
777 }
778
779 #[test]
780 #[should_panic(expected = "index out of bounds:")]
781 fn test_index_mut_out_of_bounds() {
782 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
783 sut.push(10);
784 sut.push(20);
785 sut[2] = 30;
786 }
787
788 #[test]
789 fn test_push_no_expand() {
790 let mut sut = HashedArrayTree::<usize>::new();
792 for value in 0..13 {
793 sut.push(value);
794 }
795 assert_eq!(sut.len(), 13);
796 assert_eq!(sut.capacity(), 16);
797 for value in 0..13 {
798 assert_eq!(sut[value], value);
799 }
800 sut.pop();
802 assert_eq!(sut.len(), 12);
803 assert_eq!(sut.capacity(), 12);
804 }
805
806 #[test]
807 fn test_push_with_expand() {
808 let mut sut = HashedArrayTree::<usize>::new();
810 for value in 0..64 {
811 sut.push(value);
812 }
813 assert_eq!(sut.len(), 64);
814 assert_eq!(sut.capacity(), 64);
815 for value in 0..64 {
816 assert_eq!(sut[value], value);
817 }
818 }
819
820 #[test]
821 fn test_expand_and_compress() {
822 let mut sut = HashedArrayTree::<usize>::new();
824 for value in 0..1024 {
825 sut.push(value);
826 }
827 assert_eq!(sut.len(), 1024);
828 assert_eq!(sut.capacity(), 1024);
829 for _ in 0..960 {
831 sut.pop();
832 }
833 assert_eq!(sut.len(), 64);
835 assert_eq!(sut.capacity(), 64);
836 for value in 0..64 {
837 assert_eq!(sut[value], value);
838 }
839 }
840
841 #[test]
842 fn test_push_get_get_mut() {
843 let mut sut = HashedArrayTree::<usize>::new();
844 for value in 0..12 {
845 sut.push(value);
846 }
847 assert_eq!(sut.get(2), Some(&2));
848 if let Some(value) = sut.get_mut(1) {
849 *value = 11;
850 } else {
851 panic!("get_mut() returned None")
852 }
853 assert_eq!(sut[0], 0);
854 assert_eq!(sut[1], 11);
855 assert_eq!(sut[2], 2);
856 }
857
858 #[test]
859 fn test_push_within_capacity() {
860 let mut sut = HashedArrayTree::<u32>::new();
862 assert_eq!(sut.push_within_capacity(101), Err(101));
863 sut.push(1);
865 sut.push(2);
866 assert_eq!(sut.push_within_capacity(3), Ok(()));
867 assert_eq!(sut.push_within_capacity(4), Ok(()));
868 assert_eq!(sut.push_within_capacity(5), Err(5));
869 }
870
871 #[test]
872 fn test_pop_small() {
873 let mut sut = HashedArrayTree::<usize>::new();
874 assert!(sut.is_empty());
875 assert_eq!(sut.len(), 0);
876 for value in 0..15 {
877 sut.push(value);
878 }
879 assert!(!sut.is_empty());
880 assert_eq!(sut.len(), 15);
881 for value in (0..15).rev() {
882 assert_eq!(sut.pop(), Some(value));
883 }
884 assert!(sut.is_empty());
885 assert_eq!(sut.len(), 0);
886 assert_eq!(sut.capacity(), 0);
887 }
888
889 #[test]
890 fn test_pop_if() {
891 let mut sut = HashedArrayTree::<u32>::new();
892 assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
893 for value in 0..10 {
894 sut.push(value);
895 }
896 assert!(sut.pop_if(|_| false).is_none());
897 let maybe = sut.pop_if(|v| *v == 9);
898 assert_eq!(maybe.unwrap(), 9);
899 assert!(sut.pop_if(|v| *v == 9).is_none());
900 }
901
902 #[test]
903 fn test_clear_and_reuse_ints() {
904 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
905 for value in 0..512 {
906 sut.push(value);
907 }
908 assert_eq!(sut.len(), 512);
909 sut.clear();
910 assert_eq!(sut.len(), 0);
911 for value in 0..512 {
912 sut.push(value);
913 }
914 for idx in 0..512 {
915 let maybe = sut.get(idx);
916 assert!(maybe.is_some(), "{idx} is none");
917 let actual = maybe.unwrap();
918 assert_eq!(idx, *actual as usize);
919 }
920 }
921
922 #[test]
923 fn test_clear_and_reuse_strings() {
924 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
925 for _ in 0..512 {
926 let value = ulid::Ulid::new().to_string();
927 sut.push(value);
928 }
929 assert_eq!(sut.len(), 512);
930 sut.clear();
931 assert_eq!(sut.len(), 0);
932 for _ in 0..512 {
933 let value = ulid::Ulid::new().to_string();
934 sut.push(value);
935 }
936 assert_eq!(sut.len(), 512);
937 }
939
940 #[test]
941 fn test_clone_ints() {
942 let mut sut = HashedArrayTree::<usize>::new();
943 for value in 0..512 {
944 sut.push(value);
945 }
946 let cloned = sut.clone();
947 let ai = sut.iter();
948 let bi = cloned.iter();
949 for (a, b) in ai.zip(bi) {
950 assert_eq!(a, b);
951 }
952 }
953
954 #[test]
955 fn test_clone_strings() {
956 let mut sut = HashedArrayTree::<String>::new();
957 for _ in 0..64 {
958 let value = ulid::Ulid::new().to_string();
959 sut.push(value);
960 }
961 let cloned = sut.clone();
962 let ai = sut.iter();
963 let bi = cloned.iter();
964 for (a, b) in ai.zip(bi) {
965 assert_eq!(a, b);
966 }
967 }
968
969 #[test]
970 fn test_swap() {
971 let mut sut = HashedArrayTree::<usize>::new();
972 sut.push(1);
973 sut.push(2);
974 sut.push(3);
975 sut.push(4);
976 sut.swap(1, 3);
977 assert_eq!(sut[0], 1);
978 assert_eq!(sut[1], 4);
979 assert_eq!(sut[2], 3);
980 assert_eq!(sut[3], 2);
981 }
982
983 #[test]
984 #[should_panic(expected = "swap a (is 1) should be < len (is 1)")]
985 fn test_swap_panic_a() {
986 let mut sut = HashedArrayTree::<usize>::new();
987 sut.push(1);
988 sut.swap(1, 2);
989 }
990
991 #[test]
992 #[should_panic(expected = "swap b (is 1) should be < len (is 1)")]
993 fn test_swap_panic_b() {
994 let mut sut = HashedArrayTree::<usize>::new();
995 sut.push(1);
996 sut.swap(0, 1);
997 }
998
999 #[test]
1000 fn test_sort_unstable_by_ints() {
1001 let mut sut = HashedArrayTree::<usize>::new();
1002 sut.push(10);
1003 sut.push(1);
1004 sut.push(100);
1005 sut.push(20);
1006 sut.push(2);
1007 sut.push(99);
1008 sut.push(88);
1009 sut.push(77);
1010 sut.push(66);
1011 sut.sort_unstable_by(|a, b| a.cmp(b));
1012 assert_eq!(sut[0], 1);
1013 assert_eq!(sut[1], 2);
1014 assert_eq!(sut[2], 10);
1015 assert_eq!(sut[3], 20);
1016 assert_eq!(sut[4], 66);
1017 assert_eq!(sut[5], 77);
1018 assert_eq!(sut[6], 88);
1019 assert_eq!(sut[7], 99);
1020 assert_eq!(sut[8], 100);
1021 }
1022
1023 #[test]
1024 fn test_sort_unstable_by_strings() {
1025 let mut sut = HashedArrayTree::<String>::new();
1026 sut.push("cat".into());
1027 sut.push("ape".into());
1028 sut.push("zebra".into());
1029 sut.push("dog".into());
1030 sut.push("bird".into());
1031 sut.push("tapir".into());
1032 sut.push("monkey".into());
1033 sut.push("giraffe".into());
1034 sut.push("frog".into());
1035 sut.sort_unstable_by(|a, b| a.cmp(b));
1036 assert_eq!(sut[0], "ape");
1037 assert_eq!(sut[1], "bird");
1038 assert_eq!(sut[2], "cat");
1039 assert_eq!(sut[3], "dog");
1040 assert_eq!(sut[4], "frog");
1041 assert_eq!(sut[5], "giraffe");
1042 assert_eq!(sut[6], "monkey");
1043 assert_eq!(sut[7], "tapir");
1044 assert_eq!(sut[8], "zebra");
1045 }
1046
1047 #[test]
1048 fn test_append() {
1049 let odds = ["one", "three", "five", "seven", "nine"];
1050 let mut sut = HashedArrayTree::<String>::new();
1051 for item in odds {
1052 sut.push(item.to_owned());
1053 }
1054 let evens = ["two", "four", "six", "eight", "ten"];
1055 let mut other = HashedArrayTree::<String>::new();
1056 for item in evens {
1057 other.push(item.to_owned());
1058 }
1059 sut.append(&mut other);
1060 assert_eq!(sut.len(), 10);
1061 assert_eq!(sut.capacity(), 12);
1062 assert_eq!(other.len(), 0);
1063 assert_eq!(other.capacity(), 0);
1064 sut.sort_unstable_by(|a, b| a.cmp(b));
1065 assert_eq!(sut[0], "eight");
1066 assert_eq!(sut[1], "five");
1067 assert_eq!(sut[2], "four");
1068 assert_eq!(sut[3], "nine");
1069 assert_eq!(sut[4], "one");
1070 assert_eq!(sut[5], "seven");
1071 assert_eq!(sut[6], "six");
1072 assert_eq!(sut[7], "ten");
1073 assert_eq!(sut[8], "three");
1074 assert_eq!(sut[9], "two");
1075 }
1076
1077 #[test]
1078 fn test_dedup_by_tiny() {
1079 let mut sut = HashedArrayTree::<String>::new();
1080 sut.push("one".into());
1081 sut.dedup_by(|a, b| a == b);
1082 assert_eq!(sut.len(), 1);
1083 assert_eq!(sut[0], "one");
1084 }
1085
1086 #[test]
1087 fn test_dedup_by_2_dupes() {
1088 let mut sut = HashedArrayTree::<String>::new();
1089 sut.push("one".into());
1090 sut.push("one".into());
1091 sut.dedup_by(|a, b| a == b);
1092 assert_eq!(sut.len(), 1);
1093 assert_eq!(sut[0], "one");
1094 }
1095
1096 #[test]
1097 fn test_dedup_by_2_unique() {
1098 let mut sut = HashedArrayTree::<String>::new();
1099 sut.push("one".into());
1100 sut.push("two".into());
1101 sut.dedup_by(|a, b| a == b);
1102 assert_eq!(sut.len(), 2);
1103 assert_eq!(sut[0], "one");
1104 assert_eq!(sut[1], "two");
1105 }
1106
1107 #[test]
1108 fn test_dedup_by_all_unique() {
1109 let inputs = [
1110 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1111 ];
1112 let mut sut = HashedArrayTree::<String>::new();
1113 for item in inputs {
1114 sut.push(item.to_owned());
1115 }
1116 sut.dedup_by(|a, b| a == b);
1117 assert_eq!(sut.len(), 9);
1118 for (idx, elem) in sut.into_iter().enumerate() {
1119 assert_eq!(inputs[idx], elem);
1120 }
1121 }
1122
1123 #[test]
1124 fn test_dedup_by_all_dupes() {
1125 let inputs = [
1126 "one", "one", "one", "one", "one", "one", "one", "one", "one", "one",
1127 ];
1128 let mut sut = HashedArrayTree::<String>::new();
1129 for item in inputs {
1130 sut.push(item.to_owned());
1131 }
1132 assert_eq!(sut.len(), 10);
1133 sut.dedup_by(|a, b| a == b);
1134 assert_eq!(sut.len(), 1);
1135 assert_eq!(inputs[0], "one");
1136 }
1137
1138 #[test]
1139 fn test_dedup_by_some_dupes_ints() {
1140 let inputs = [1, 2, 2, 3, 2];
1141 let mut sut = HashedArrayTree::<usize>::new();
1142 for item in inputs {
1143 sut.push(item.to_owned());
1144 }
1145 assert_eq!(sut.len(), 5);
1146 sut.dedup_by(|a, b| a == b);
1147 assert_eq!(sut.len(), 4);
1148 assert_eq!(sut[0], 1);
1149 assert_eq!(sut[1], 2);
1150 assert_eq!(sut[2], 3);
1151 assert_eq!(sut[3], 2);
1152 }
1153
1154 #[test]
1155 fn test_dedup_by_some_dupes_strings() {
1156 let inputs = ["foo", "bar", "Bar", "baz", "bar"];
1157 let mut sut = HashedArrayTree::<String>::new();
1158 for item in inputs {
1159 sut.push(item.to_owned());
1160 }
1161 assert_eq!(sut.len(), 5);
1162 sut.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1163 assert_eq!(sut.len(), 4);
1164 assert_eq!(sut[0], "foo");
1165 assert_eq!(sut[1], "bar");
1166 assert_eq!(sut[2], "baz");
1167 assert_eq!(sut[3], "bar");
1168 }
1169
1170 #[test]
1171 fn test_from_iterator() {
1172 let mut inputs: Vec<i32> = Vec::new();
1173 for value in 0..10_000 {
1174 inputs.push(value);
1175 }
1176 let sut: HashedArrayTree<i32> = inputs.into_iter().collect();
1177 assert_eq!(sut.len(), 10_000);
1178 for idx in 0..10_000i32 {
1179 let maybe = sut.get(idx as usize);
1180 assert!(maybe.is_some(), "{idx} is none");
1181 let actual = maybe.unwrap();
1182 assert_eq!(idx, *actual);
1183 }
1184 }
1185
1186 #[test]
1187 fn test_iterator() {
1188 let mut sut = HashedArrayTree::<usize>::new();
1189 for value in 0..512 {
1190 sut.push(value);
1191 }
1192 assert_eq!(sut.len(), 512);
1193 for (idx, elem) in sut.iter().enumerate() {
1194 assert_eq!(sut[idx], *elem);
1195 }
1196 }
1197
1198 #[test]
1199 fn test_into_iterator() {
1200 let inputs = [
1202 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1203 ];
1204 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1205 for item in inputs {
1206 sut.push(item.to_owned());
1207 }
1208 for (idx, elem) in sut.into_iter().enumerate() {
1209 assert_eq!(inputs[idx], elem);
1210 }
1211 }
1213
1214 #[test]
1215 fn test_into_iterator_drop_tiny() {
1216 let inputs = [
1219 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1220 ];
1221 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1222 for item in inputs {
1223 sut.push(item.to_owned());
1224 }
1225 for (idx, _) in sut.into_iter().enumerate() {
1226 if idx > 2 {
1227 break;
1228 }
1229 }
1230 }
1232
1233 #[test]
1234 fn test_into_iterator_drop_large() {
1235 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1239 for _ in 0..512 {
1240 let value = ulid::Ulid::new().to_string();
1241 sut.push(value);
1242 }
1243 for (idx, _) in sut.into_iter().enumerate() {
1244 if idx >= 30 {
1245 break;
1246 }
1247 }
1248 }
1250
1251 #[test]
1252 fn test_swap_remove_single_segment() {
1253 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1254 sut.push(1);
1255 sut.push(2);
1256 assert_eq!(sut.len(), 2);
1257 let one = sut.swap_remove(0);
1258 assert_eq!(one, 1);
1259 assert_eq!(sut[0], 2);
1260 }
1261
1262 #[test]
1263 fn test_swap_remove_prune_empty() {
1264 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1265 for value in 0..13 {
1266 sut.push(value);
1267 }
1268 assert_eq!(sut.len(), 13);
1269 assert_eq!(sut.capacity(), 16);
1270 let value = sut.swap_remove(8);
1271 assert_eq!(value, 8);
1272 assert_eq!(sut[8], 12);
1273 assert_eq!(sut.len(), 12);
1274 assert_eq!(sut.capacity(), 12);
1275 }
1276
1277 #[test]
1278 fn test_swap_remove_multiple_segments() {
1279 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1280 for value in 0..512 {
1281 sut.push(value);
1282 }
1283 assert_eq!(sut.len(), 512);
1284 let eighty = sut.swap_remove(80);
1285 assert_eq!(eighty, 80);
1286 assert_eq!(sut.pop(), Some(510));
1287 assert_eq!(sut[80], 511);
1288 }
1289
1290 #[test]
1291 #[should_panic(expected = "swap_remove index (is 0) should be < len (is 0)")]
1292 fn test_swap_remove_panic_empty() {
1293 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1294 sut.swap_remove(0);
1295 }
1296
1297 #[test]
1298 #[should_panic(expected = "swap_remove index (is 1) should be < len (is 1)")]
1299 fn test_swap_remove_panic_range_edge() {
1300 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1301 sut.push(1);
1302 sut.swap_remove(1);
1303 }
1304
1305 #[test]
1306 #[should_panic(expected = "swap_remove index (is 2) should be < len (is 1)")]
1307 fn test_swap_remove_panic_range_exceed() {
1308 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1309 sut.push(1);
1310 sut.swap_remove(2);
1311 }
1312
1313 #[test]
1314 fn test_push_get_many_instances_ints() {
1315 for _ in 0..1_000 {
1317 let mut sut: HashedArrayTree<usize> = HashedArrayTree::new();
1318 for value in 0..10_000 {
1319 sut.push(value);
1320 }
1321 assert_eq!(sut.len(), 10_000);
1322 }
1323 }
1324
1325 #[test]
1326 fn test_push_get_many_instances_strings() {
1327 for _ in 0..1_000 {
1329 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1330 for _ in 0..1_000 {
1331 let value = ulid::Ulid::new().to_string();
1332 sut.push(value);
1333 }
1334 assert_eq!(sut.len(), 1_000);
1335 }
1336 }
1337}