1use std::alloc::{Layout, alloc, dealloc, handle_alloc_error};
47use std::cmp::Ordering;
48use std::fmt;
49use std::ops::{Index, IndexMut};
50
51pub struct HashedArrayTree<T> {
53 index: Vec<*mut T>,
55 count: usize,
57 k: usize,
59 k_mask: usize,
61 l: usize,
63 upper_limit: usize,
65 lower_limit: usize,
67}
68
69impl<T> HashedArrayTree<T> {
70 pub fn new() -> Self {
72 let index: Vec<*mut T> = vec![];
73 Self {
74 index,
75 count: 0,
76 k: 2,
77 k_mask: 3,
78 l: 4,
79 upper_limit: 16,
80 lower_limit: 0,
81 }
82 }
83
84 fn expand(&mut self) {
87 let l_prime = 1 << (self.k + 1);
88 let old_index: Vec<*mut T> = std::mem::take(&mut self.index);
89 let mut iter = old_index.into_iter();
90 while let Some(a) = iter.next() {
91 let layout = Layout::array::<T>(l_prime).expect("unexpected overflow");
92 let buffer = unsafe {
93 let ptr = alloc(layout).cast::<T>();
94 if ptr.is_null() {
95 handle_alloc_error(layout);
96 }
97 ptr
98 };
99 if let Some(b) = iter.next() {
100 let b_dst = unsafe { buffer.add(self.l) };
101 let old_layout = Layout::array::<T>(self.l).expect("unexpected overflow");
102 unsafe {
103 std::ptr::copy(a, buffer, self.l);
104 std::ptr::copy(b, b_dst, self.l);
105 dealloc(a as *mut u8, old_layout);
106 dealloc(b as *mut u8, old_layout);
107 }
108 } else {
109 let old_layout = Layout::array::<T>(self.l).expect("unexpected overflow");
110 unsafe {
111 std::ptr::copy(a, buffer, self.l);
112 dealloc(a as *mut u8, old_layout);
113 }
114 }
115 self.index.push(buffer);
116 }
117 self.k += 1;
118 self.k_mask = (1 << self.k) - 1;
119 self.l = 1 << self.k;
120 self.upper_limit = self.l * self.l;
121 self.lower_limit = self.upper_limit / 8;
122 }
123
124 pub fn push(&mut self, value: T) {
134 let len = self.count;
135 if len >= self.upper_limit {
136 self.expand();
137 }
138 if len >= self.capacity() {
139 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
140 let buffer = unsafe {
141 let ptr = alloc(layout).cast::<T>();
142 if ptr.is_null() {
143 handle_alloc_error(layout);
144 }
145 ptr
146 };
147 self.index.push(buffer);
148 }
149 let block = len >> self.k;
150 let slot = len & self.k_mask;
151 unsafe { self.index[block].add(slot).write(value) }
152 self.count += 1;
153 }
154
155 pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
162 if self.capacity() <= self.count {
163 Err(value)
164 } else {
165 self.push(value);
166 Ok(())
167 }
168 }
169
170 fn raw_get(&self, index: usize) -> &T {
174 let block = index >> self.k;
175 let slot = index & self.k_mask;
176 unsafe { &*self.index[block].add(slot) }
177 }
178
179 pub fn get(&self, index: usize) -> Option<&T> {
185 if index >= self.count {
186 None
187 } else {
188 Some(self.raw_get(index))
189 }
190 }
191
192 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
198 if index >= self.count {
199 None
200 } else {
201 let block = index >> self.k;
202 let slot = index & self.k_mask;
203 unsafe { (self.index[block].add(slot)).as_mut() }
204 }
205 }
206
207 fn compress(&mut self) {
210 let old_index: Vec<*mut T> = std::mem::take(&mut self.index);
211 for old_buffer in old_index.into_iter() {
212 let half = self.l / 2;
213 let layout = Layout::array::<T>(half).expect("unexpected overflow");
214 let a = unsafe {
215 let ptr = alloc(layout).cast::<T>();
216 if ptr.is_null() {
217 handle_alloc_error(layout);
218 }
219 ptr
220 };
221 let b = unsafe {
222 let ptr = alloc(layout).cast::<T>();
223 if ptr.is_null() {
224 handle_alloc_error(layout);
225 }
226 ptr
227 };
228 unsafe {
232 std::ptr::copy(old_buffer, a, half);
233 std::ptr::copy(old_buffer.add(half), b, half);
234 };
235 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
236 unsafe {
237 dealloc(old_buffer as *mut u8, layout);
238 }
239 self.index.push(a);
240 self.index.push(b);
241 }
242 self.k -= 1;
243 self.k_mask = (1 << self.k) - 1;
244 self.l = 1 << self.k;
245 self.upper_limit = self.l * self.l;
246 self.lower_limit = self.upper_limit / 8;
247 }
248
249 pub fn raw_pop(&mut self) -> T {
253 let index = self.count - 1;
254 if index < self.lower_limit && self.k > 2 {
264 self.compress();
265 }
266 let block = index >> self.k;
267 let slot = index & self.k_mask;
268 let ret = unsafe { self.index[block].add(slot).read() };
269 if slot == 0 {
270 let ptr = self.index.pop().unwrap();
272 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
273 unsafe {
274 dealloc(ptr as *mut u8, layout);
275 }
276 }
277 self.count -= 1;
278 ret
279 }
280
281 pub fn pop(&mut self) -> Option<T> {
288 if self.count > 0 {
289 Some(self.raw_pop())
290 } else {
291 None
292 }
293 }
294
295 pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
303 if self.count == 0 {
304 None
305 } else if let Some(last) = self.get_mut(self.count - 1) {
306 if predicate(last) { self.pop() } else { None }
307 } else {
308 None
309 }
310 }
311
312 pub fn swap_remove(&mut self, index: usize) -> T {
326 if index >= self.count {
327 panic!(
328 "swap_remove index (is {index}) should be < len (is {})",
329 self.count
330 );
331 }
332 let block = index >> self.k;
334 let slot = index & self.k_mask;
335 unsafe {
336 let index_ptr = self.index[block].add(slot);
337 let value = index_ptr.read();
338 let block = (self.count - 1) >> self.k;
340 let slot = (self.count - 1) & self.k_mask;
341 let last_ptr = self.index[block].add(slot);
342 std::ptr::copy(last_ptr, index_ptr, 1);
343 if slot == 0 {
344 let ptr = self.index.pop().unwrap();
346 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
347 dealloc(ptr as *mut u8, layout);
348 }
349 self.count -= 1;
350 value
351 }
352 }
353
354 pub fn iter(&self) -> ArrayIter<'_, T> {
358 ArrayIter {
359 array: self,
360 index: 0,
361 count: self.count,
362 }
363 }
364
365 pub fn iter_mut(&mut self) -> ArrayIterMut<'_, T> {
369 ArrayIterMut {
370 dope: self.index.as_mut_ptr(),
371 index: 0,
372 count: self.count,
373 k: self.k,
374 k_mask: self.k_mask,
375 _marker: std::marker::PhantomData,
376 }
377 }
378
379 pub fn len(&self) -> usize {
385 self.count
386 }
387
388 pub fn capacity(&self) -> usize {
395 self.l * self.index.len()
396 }
397
398 pub fn is_empty(&self) -> bool {
404 self.count == 0
405 }
406
407 pub fn clear(&mut self) {
413 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
414
415 if self.count > 0 && std::mem::needs_drop::<T>() {
416 let last_index = self.count - 1;
418 let last_block = last_index >> self.k;
419 let last_slot = last_index & self.k_mask;
420 unsafe {
421 drop_in_place(slice_from_raw_parts_mut(
424 self.index[last_block],
425 last_slot + 1,
426 ));
427 }
428
429 for block in 0..last_block {
431 unsafe {
432 drop_in_place(slice_from_raw_parts_mut(self.index[block], self.l));
433 }
434 }
435 }
436
437 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
439 for block in 0..self.index.len() {
440 unsafe {
441 dealloc(self.index[block] as *mut u8, layout);
442 }
443 }
444 self.index.clear();
445
446 self.count = 0;
447 self.k = 2;
448 self.k_mask = 3;
449 self.l = 1 << self.k;
450 self.upper_limit = self.l * self.l;
451 self.lower_limit = 0;
452 }
453
454 pub fn swap(&mut self, a: usize, b: usize) {
460 if a >= self.count {
461 panic!("swap a (is {a}) should be < len (is {})", self.count);
462 }
463 if b >= self.count {
464 panic!("swap b (is {b}) should be < len (is {})", self.count);
465 }
466 let a_block = a >> self.k;
469 let a_slot = a & self.k_mask;
470 let b_block = b >> self.k;
471 let b_slot = b & self.k_mask;
472 unsafe {
473 let a_ptr = self.index[a_block].add(a_slot);
474 let value = a_ptr.read();
475 let b_ptr = self.index[b_block].add(b_slot);
476 std::ptr::copy(b_ptr, a_ptr, 1);
477 b_ptr.write(value);
478 }
479 }
480
481 pub fn sort_unstable_by<F>(&mut self, mut compare: F)
489 where
490 F: FnMut(&T, &T) -> Ordering,
491 {
492 if self.count < 2 {
493 return;
494 }
495 let mut start = self.count / 2;
496 let mut end = self.count;
497 while end > 1 {
498 if start > 0 {
499 start -= 1;
500 } else {
501 end -= 1;
502 self.swap(end, 0);
503 }
504 let mut root = start;
505 let mut child = 2 * root + 1;
506 while child < end {
507 if child + 1 < end && compare(&self[child], &self[child + 1]) == Ordering::Less {
508 child += 1;
509 }
510 if compare(&self[root], &self[child]) == Ordering::Less {
511 self.swap(root, child);
512 root = child;
513 child = 2 * root + 1;
514 } else {
515 break;
516 }
517 }
518 }
519 }
520
521 pub fn dedup_by<F>(&mut self, mut same_bucket: F)
531 where
532 F: FnMut(&T, &T) -> bool,
533 {
534 let len = self.len();
535 if len <= 1 {
536 return;
537 }
538
539 let mut first_duplicate_idx: usize = 1;
542 while first_duplicate_idx != len {
543 let found_duplicate = {
544 let prev = self.raw_get(first_duplicate_idx - 1);
545 let current = self.raw_get(first_duplicate_idx);
546 same_bucket(current, prev)
547 };
548 if found_duplicate {
549 break;
550 }
551 first_duplicate_idx += 1;
552 }
553 if first_duplicate_idx == len {
554 return;
555 }
556
557 let index = std::mem::take(&mut self.index);
561 let old_l = self.l;
562 let mut remaining = self.count - 1;
563 self.count = 0;
564 self.clear();
565 let layout = Layout::array::<T>(old_l).expect("unexpected overflow");
566
567 let mut prev = unsafe { index[0].read() };
570 let mut slot = 1;
571 for buffer in index.into_iter() {
572 while slot < old_l && remaining > 0 {
576 let current = unsafe { buffer.add(slot).read() };
577 if same_bucket(¤t, &prev) {
578 drop(current);
579 } else {
580 self.push(prev);
581 prev = current;
582 }
583 remaining -= 1;
584 slot += 1;
585 }
586 unsafe {
587 dealloc(buffer as *mut u8, layout);
588 }
589 slot = 0;
590 }
591 self.push(prev);
593 }
594
595 pub fn append(&mut self, other: &mut Self) {
597 let index = std::mem::take(&mut other.index);
598 let mut remaining = other.count;
599 other.count = 0;
601 let layout = Layout::array::<T>(other.l).expect("unexpected overflow");
602 for buffer in index.into_iter() {
603 let mut slot = 0;
607 while slot < other.l && remaining > 0 {
608 let value = unsafe { buffer.add(slot).read() };
609 self.push(value);
610 remaining -= 1;
611 slot += 1;
612 }
613 unsafe {
614 dealloc(buffer as *mut u8, layout);
615 }
616 }
617 }
618
619 pub fn split_off(&mut self, at: usize) -> Self {
633 if at > self.count {
634 panic!(
635 "`at` split index (is {at}) should be <= len (is {})",
636 self.count
637 );
638 }
639 let mut other = Self::new();
647 while self.count > at {
648 other.push(self.raw_pop());
649 }
650 if other.count > 1 {
653 let mut low = 0;
654 let mut high = other.count - 1;
655 while low < high {
656 unsafe {
657 let lp = other.index[low >> other.k].add(low & other.k_mask);
658 let value = lp.read();
659 let hp = other.index[high >> other.k].add(high & other.k_mask);
660 std::ptr::copy(hp, lp, 1);
661 hp.write(value);
662 }
663 low += 1;
664 high -= 1;
665 }
666 }
667 other
668 }
669
670 pub fn truncate(&mut self, len: usize) {
680 while self.count > len {
681 self.raw_pop();
682 }
684 }
685}
686
687impl<T> Default for HashedArrayTree<T> {
688 fn default() -> Self {
689 Self::new()
690 }
691}
692
693impl<T> fmt::Display for HashedArrayTree<T> {
694 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
695 write!(
696 f,
697 "HashedArrayTree(k: {}, count: {}, dope: {})",
698 self.k,
699 self.count,
700 self.index.len(),
701 )
702 }
703}
704
705impl<T> Index<usize> for HashedArrayTree<T> {
706 type Output = T;
707
708 fn index(&self, index: usize) -> &Self::Output {
709 let Some(item) = self.get(index) else {
710 panic!("index out of bounds: {}", index);
711 };
712 item
713 }
714}
715
716impl<T> IndexMut<usize> for HashedArrayTree<T> {
717 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
718 let Some(item) = self.get_mut(index) else {
719 panic!("index out of bounds: {}", index);
720 };
721 item
722 }
723}
724
725impl<T> Drop for HashedArrayTree<T> {
726 fn drop(&mut self) {
727 self.clear();
728 }
729}
730
731impl<T: Clone> Clone for HashedArrayTree<T> {
732 fn clone(&self) -> Self {
733 let mut result = HashedArrayTree::<T>::new();
734 for value in self.iter() {
735 result.push(value.clone());
736 }
737 result
738 }
739}
740
741unsafe impl<T: Send> Send for HashedArrayTree<T> {}
742
743unsafe impl<T: Sync> Sync for HashedArrayTree<T> {}
744
745impl<A> FromIterator<A> for HashedArrayTree<A> {
746 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
747 let mut arr: HashedArrayTree<A> = HashedArrayTree::new();
748 for value in iter {
749 arr.push(value)
750 }
751 arr
752 }
753}
754
755pub struct ArrayIter<'a, T> {
757 array: &'a HashedArrayTree<T>,
758 index: usize,
759 count: usize,
760}
761
762impl<'a, T> Iterator for ArrayIter<'a, T> {
763 type Item = &'a T;
764
765 fn next(&mut self) -> Option<Self::Item> {
766 if self.index < self.count {
767 let value = self.array.get(self.index);
768 self.index += 1;
769 value
770 } else {
771 None
772 }
773 }
774
775 fn size_hint(&self) -> (usize, Option<usize>) {
776 let remaining = self.count - self.index;
777 (remaining, Some(remaining))
778 }
779}
780
781impl<'a, T> ExactSizeIterator for ArrayIter<'a, T> {}
782
783pub struct ArrayIterMut<'a, T> {
785 dope: *mut *mut T, index: usize,
787 count: usize,
788 k: usize,
789 k_mask: usize,
790 _marker: std::marker::PhantomData<&'a mut T>,
791}
792
793impl<'a, T> Iterator for ArrayIterMut<'a, T> {
794 type Item = &'a mut T;
795
796 fn next(&mut self) -> Option<Self::Item> {
797 if self.index < self.count {
798 let block = self.index >> self.k;
799 let slot = self.index & self.k_mask;
800 self.index += 1;
801 unsafe {
805 let block_ptr = *self.dope.add(block);
806 Some(&mut *block_ptr.add(slot))
807 }
808 } else {
809 None
810 }
811 }
812
813 fn size_hint(&self) -> (usize, Option<usize>) {
814 let remaining = self.count - self.index;
815 (remaining, Some(remaining))
816 }
817}
818
819impl<'a, T> ExactSizeIterator for ArrayIterMut<'a, T> {}
820
821pub struct ArrayIntoIter<T> {
823 index: usize,
824 k: usize,
825 k_mask: usize,
826 count: usize,
827 dope: Vec<*mut T>,
828}
829
830impl<T> Iterator for ArrayIntoIter<T> {
831 type Item = T;
832
833 fn next(&mut self) -> Option<Self::Item> {
834 if self.index < self.count {
835 let block = self.index >> self.k;
836 let slot = self.index & self.k_mask;
837 self.index += 1;
838 unsafe { Some((self.dope[block].add(slot)).read()) }
839 } else {
840 None
841 }
842 }
843
844 fn size_hint(&self) -> (usize, Option<usize>) {
845 let remaining = self.count - self.index;
846 (remaining, Some(remaining))
847 }
848}
849
850impl<T> IntoIterator for HashedArrayTree<T> {
851 type Item = T;
852 type IntoIter = ArrayIntoIter<Self::Item>;
853
854 fn into_iter(self) -> Self::IntoIter {
855 let mut me = std::mem::ManuallyDrop::new(self);
856 let dope = std::mem::take(&mut me.index);
857 ArrayIntoIter {
858 index: 0,
859 count: me.count,
860 k: me.k,
861 k_mask: me.k_mask,
862 dope,
863 }
864 }
865}
866
867impl<T> ExactSizeIterator for ArrayIntoIter<T> {}
868
869impl<T> Drop for ArrayIntoIter<T> {
870 fn drop(&mut self) {
871 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
872 let block_len = 1 << self.k;
873
874 if self.count > 0 && std::mem::needs_drop::<T>() {
875 let first_block = self.index >> self.k;
878 let first_slot = self.index & self.k_mask;
879 let last_block = (self.count - 1) >> self.k;
880 let last_slot = (self.count - 1) & self.k_mask;
881 if first_block == last_block {
882 if first_slot <= last_slot {
884 unsafe {
885 drop_in_place(slice_from_raw_parts_mut(
888 self.dope[first_block].add(first_slot),
889 last_slot - first_slot + 1,
890 ));
891 }
892 }
893 } else if first_block < last_block {
894 if block_len < self.count {
896 unsafe {
897 drop_in_place(slice_from_raw_parts_mut(
898 self.dope[first_block].add(first_slot),
899 block_len - first_slot,
900 ));
901 }
902 }
903
904 unsafe {
906 drop_in_place(slice_from_raw_parts_mut(
907 self.dope[last_block],
908 last_slot + 1,
909 ));
910 }
911
912 for block in first_block + 1..last_block {
914 unsafe {
915 drop_in_place(slice_from_raw_parts_mut(self.dope[block], block_len));
916 }
917 }
918 }
919 }
920
921 for block in 0..self.dope.len() {
923 let layout = Layout::array::<T>(block_len).expect("unexpected overflow");
924 unsafe {
925 dealloc(self.dope[block] as *mut u8, layout);
926 }
927 }
928 }
929}
930
931#[macro_export]
936macro_rules! hat {
937 () => {
938 HashedArrayTree::new()
939 };
940 ( $($item:expr),* $(,)? ) => {
942 {
943 let mut result = HashedArrayTree::new();
944 $(
945 result.push($item);
946 )*
947 result
948 }
949 };
950}
951
952#[cfg(test)]
953mod tests {
954 use super::*;
955
956 #[test]
957 fn test_hat_macro() {
958 let sut: HashedArrayTree<usize> = hat![];
959 assert_eq!(sut.len(), 0);
960 assert_eq!(sut.capacity(), 0);
961
962 let sut: HashedArrayTree<usize> = hat![1];
963 assert_eq!(sut.len(), 1);
964 assert_eq!(sut.capacity(), 4);
965
966 let sut = hat![1, 2, 3, 4, 5, 6, 7, 8, 9,];
967 assert_eq!(sut.len(), 9);
968 assert_eq!(sut.capacity(), 12);
969 assert_eq!(sut[0], 1);
970 assert_eq!(sut[1], 2);
971 assert_eq!(sut[2], 3);
972 assert_eq!(sut[3], 4);
973 assert_eq!(sut[4], 5);
974 assert_eq!(sut[5], 6);
975 assert_eq!(sut[6], 7);
976 assert_eq!(sut[7], 8);
977 assert_eq!(sut[8], 9);
978 }
979
980 #[test]
981 fn test_empty() {
982 let sut = HashedArrayTree::<usize>::new();
983 assert!(sut.get(0).is_none());
984 }
985
986 #[test]
987 #[should_panic(expected = "index out of bounds:")]
988 fn test_index_out_of_bounds() {
989 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
990 sut.push(10);
991 sut.push(20);
992 let _ = sut[2];
993 }
994
995 #[test]
996 #[should_panic(expected = "index out of bounds:")]
997 fn test_index_mut_out_of_bounds() {
998 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
999 sut.push(10);
1000 sut.push(20);
1001 sut[2] = 30;
1002 }
1003
1004 #[test]
1005 fn test_push_no_expand() {
1006 let mut sut = HashedArrayTree::<usize>::new();
1008 for value in 0..13 {
1009 sut.push(value);
1010 }
1011 assert_eq!(sut.len(), 13);
1012 assert_eq!(sut.capacity(), 16);
1013 for value in 0..13 {
1014 assert_eq!(sut[value], value);
1015 }
1016 sut.pop();
1018 assert_eq!(sut.len(), 12);
1019 assert_eq!(sut.capacity(), 12);
1020 }
1021
1022 #[test]
1023 fn test_push_with_expand() {
1024 let mut sut = HashedArrayTree::<usize>::new();
1026 for value in 0..64 {
1027 sut.push(value);
1028 }
1029 assert_eq!(sut.len(), 64);
1030 assert_eq!(sut.capacity(), 64);
1031 for value in 0..64 {
1032 assert_eq!(sut[value], value);
1033 }
1034 }
1035
1036 #[test]
1037 fn test_expand_and_compress() {
1038 let mut sut = HashedArrayTree::<usize>::new();
1040 for value in 0..1024 {
1041 sut.push(value);
1042 }
1043 assert_eq!(sut.len(), 1024);
1044 assert_eq!(sut.capacity(), 1024);
1045 for _ in 0..960 {
1047 sut.pop();
1048 }
1049 assert_eq!(sut.len(), 64);
1051 assert_eq!(sut.capacity(), 64);
1052 for value in 0..64 {
1053 assert_eq!(sut[value], value);
1054 }
1055 }
1056
1057 #[test]
1058 fn test_push_get_get_mut() {
1059 let mut sut = HashedArrayTree::<usize>::new();
1060 for value in 0..12 {
1061 sut.push(value);
1062 }
1063 assert_eq!(sut.get(2), Some(&2));
1064 if let Some(value) = sut.get_mut(1) {
1065 *value = 11;
1066 } else {
1067 panic!("get_mut() returned None")
1068 }
1069 assert_eq!(sut[0], 0);
1070 assert_eq!(sut[1], 11);
1071 assert_eq!(sut[2], 2);
1072 }
1073
1074 #[test]
1075 fn test_push_within_capacity() {
1076 let mut sut = HashedArrayTree::<u32>::new();
1078 assert_eq!(sut.push_within_capacity(101), Err(101));
1079 sut.push(1);
1081 sut.push(2);
1082 assert_eq!(sut.push_within_capacity(3), Ok(()));
1083 assert_eq!(sut.push_within_capacity(4), Ok(()));
1084 assert_eq!(sut.push_within_capacity(5), Err(5));
1085 }
1086
1087 #[test]
1088 fn test_pop_small() {
1089 let mut sut = HashedArrayTree::<usize>::new();
1090 assert!(sut.is_empty());
1091 assert_eq!(sut.len(), 0);
1092 for value in 0..15 {
1093 sut.push(value);
1094 }
1095 assert!(!sut.is_empty());
1096 assert_eq!(sut.len(), 15);
1097 for value in (0..15).rev() {
1098 assert_eq!(sut.pop(), Some(value));
1099 }
1100 assert!(sut.is_empty());
1101 assert_eq!(sut.len(), 0);
1102 assert_eq!(sut.capacity(), 0);
1103 }
1104
1105 #[test]
1106 fn test_pop_if() {
1107 let mut sut = HashedArrayTree::<u32>::new();
1108 assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
1109 for value in 0..10 {
1110 sut.push(value);
1111 }
1112 assert!(sut.pop_if(|_| false).is_none());
1113 let maybe = sut.pop_if(|v| *v == 9);
1114 assert_eq!(maybe.unwrap(), 9);
1115 assert!(sut.pop_if(|v| *v == 9).is_none());
1116 }
1117
1118 #[test]
1119 fn test_clear_and_reuse_ints() {
1120 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
1121 for value in 0..512 {
1122 sut.push(value);
1123 }
1124 assert_eq!(sut.len(), 512);
1125 sut.clear();
1126 assert_eq!(sut.len(), 0);
1127 for value in 0..512 {
1128 sut.push(value);
1129 }
1130 for idx in 0..512 {
1131 let maybe = sut.get(idx);
1132 assert!(maybe.is_some(), "{idx} is none");
1133 let actual = maybe.unwrap();
1134 assert_eq!(idx, *actual as usize);
1135 }
1136 }
1137
1138 #[test]
1139 fn test_clear_and_reuse_strings() {
1140 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1141 for _ in 0..512 {
1142 let value = ulid::Ulid::new().to_string();
1143 sut.push(value);
1144 }
1145 assert_eq!(sut.len(), 512);
1146 sut.clear();
1147 assert_eq!(sut.len(), 0);
1148 for _ in 0..512 {
1149 let value = ulid::Ulid::new().to_string();
1150 sut.push(value);
1151 }
1152 assert_eq!(sut.len(), 512);
1153 }
1155
1156 #[test]
1157 fn test_clone_ints() {
1158 let mut sut = HashedArrayTree::<usize>::new();
1159 for value in 0..512 {
1160 sut.push(value);
1161 }
1162 let cloned = sut.clone();
1163 let ai = sut.iter();
1164 let bi = cloned.iter();
1165 for (a, b) in ai.zip(bi) {
1166 assert_eq!(a, b);
1167 }
1168 }
1169
1170 #[test]
1171 fn test_clone_strings() {
1172 let mut sut = HashedArrayTree::<String>::new();
1173 for _ in 0..64 {
1174 let value = ulid::Ulid::new().to_string();
1175 sut.push(value);
1176 }
1177 let cloned = sut.clone();
1178 let ai = sut.iter();
1179 let bi = cloned.iter();
1180 for (a, b) in ai.zip(bi) {
1181 assert_eq!(a, b);
1182 }
1183 }
1184
1185 #[test]
1186 fn test_swap() {
1187 let mut sut = HashedArrayTree::<usize>::new();
1188 sut.push(1);
1189 sut.push(2);
1190 sut.push(3);
1191 sut.push(4);
1192 sut.swap(1, 3);
1193 assert_eq!(sut[0], 1);
1194 assert_eq!(sut[1], 4);
1195 assert_eq!(sut[2], 3);
1196 assert_eq!(sut[3], 2);
1197 }
1198
1199 #[test]
1200 #[should_panic(expected = "swap a (is 1) should be < len (is 1)")]
1201 fn test_swap_panic_a() {
1202 let mut sut = HashedArrayTree::<usize>::new();
1203 sut.push(1);
1204 sut.swap(1, 2);
1205 }
1206
1207 #[test]
1208 #[should_panic(expected = "swap b (is 1) should be < len (is 1)")]
1209 fn test_swap_panic_b() {
1210 let mut sut = HashedArrayTree::<usize>::new();
1211 sut.push(1);
1212 sut.swap(0, 1);
1213 }
1214
1215 #[test]
1216 fn test_sort_unstable_by_ints() {
1217 let mut sut = HashedArrayTree::<usize>::new();
1218 sut.push(10);
1219 sut.push(1);
1220 sut.push(100);
1221 sut.push(20);
1222 sut.push(2);
1223 sut.push(99);
1224 sut.push(88);
1225 sut.push(77);
1226 sut.push(66);
1227 sut.sort_unstable_by(|a, b| a.cmp(b));
1228 assert_eq!(sut[0], 1);
1229 assert_eq!(sut[1], 2);
1230 assert_eq!(sut[2], 10);
1231 assert_eq!(sut[3], 20);
1232 assert_eq!(sut[4], 66);
1233 assert_eq!(sut[5], 77);
1234 assert_eq!(sut[6], 88);
1235 assert_eq!(sut[7], 99);
1236 assert_eq!(sut[8], 100);
1237 }
1238
1239 #[test]
1240 fn test_sort_unstable_by_strings() {
1241 let mut sut = HashedArrayTree::<String>::new();
1242 sut.push("cat".into());
1243 sut.push("ape".into());
1244 sut.push("zebra".into());
1245 sut.push("dog".into());
1246 sut.push("bird".into());
1247 sut.push("tapir".into());
1248 sut.push("monkey".into());
1249 sut.push("giraffe".into());
1250 sut.push("frog".into());
1251 sut.sort_unstable_by(|a, b| a.cmp(b));
1252 assert_eq!(sut[0], "ape");
1253 assert_eq!(sut[1], "bird");
1254 assert_eq!(sut[2], "cat");
1255 assert_eq!(sut[3], "dog");
1256 assert_eq!(sut[4], "frog");
1257 assert_eq!(sut[5], "giraffe");
1258 assert_eq!(sut[6], "monkey");
1259 assert_eq!(sut[7], "tapir");
1260 assert_eq!(sut[8], "zebra");
1261 }
1262
1263 #[test]
1264 fn test_append() {
1265 let odds = ["one", "three", "five", "seven", "nine"];
1266 let mut sut = HashedArrayTree::<String>::new();
1267 for item in odds {
1268 sut.push(item.to_owned());
1269 }
1270 let evens = ["two", "four", "six", "eight", "ten"];
1271 let mut other = HashedArrayTree::<String>::new();
1272 for item in evens {
1273 other.push(item.to_owned());
1274 }
1275 sut.append(&mut other);
1276 assert_eq!(sut.len(), 10);
1277 assert_eq!(sut.capacity(), 12);
1278 assert_eq!(other.len(), 0);
1279 assert_eq!(other.capacity(), 0);
1280 sut.sort_unstable_by(|a, b| a.cmp(b));
1281 assert_eq!(sut[0], "eight");
1282 assert_eq!(sut[1], "five");
1283 assert_eq!(sut[2], "four");
1284 assert_eq!(sut[3], "nine");
1285 assert_eq!(sut[4], "one");
1286 assert_eq!(sut[5], "seven");
1287 assert_eq!(sut[6], "six");
1288 assert_eq!(sut[7], "ten");
1289 assert_eq!(sut[8], "three");
1290 assert_eq!(sut[9], "two");
1291 }
1292
1293 #[test]
1294 fn test_dedup_by_tiny() {
1295 let mut sut = HashedArrayTree::<String>::new();
1296 sut.push("one".into());
1297 sut.dedup_by(|a, b| a == b);
1298 assert_eq!(sut.len(), 1);
1299 assert_eq!(sut[0], "one");
1300 }
1301
1302 #[test]
1303 fn test_dedup_by_2_dupes() {
1304 let mut sut = HashedArrayTree::<String>::new();
1305 sut.push("one".into());
1306 sut.push("one".into());
1307 sut.dedup_by(|a, b| a == b);
1308 assert_eq!(sut.len(), 1);
1309 assert_eq!(sut[0], "one");
1310 }
1311
1312 #[test]
1313 fn test_dedup_by_2_unique() {
1314 let mut sut = HashedArrayTree::<String>::new();
1315 sut.push("one".into());
1316 sut.push("two".into());
1317 sut.dedup_by(|a, b| a == b);
1318 assert_eq!(sut.len(), 2);
1319 assert_eq!(sut[0], "one");
1320 assert_eq!(sut[1], "two");
1321 }
1322
1323 #[test]
1324 fn test_dedup_by_all_unique() {
1325 let inputs = [
1326 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1327 ];
1328 let mut sut = HashedArrayTree::<String>::new();
1329 for item in inputs {
1330 sut.push(item.to_owned());
1331 }
1332 sut.dedup_by(|a, b| a == b);
1333 assert_eq!(sut.len(), 9);
1334 for (idx, elem) in sut.into_iter().enumerate() {
1335 assert_eq!(inputs[idx], elem);
1336 }
1337 }
1338
1339 #[test]
1340 fn test_dedup_by_all_dupes() {
1341 let inputs = [
1342 "one", "one", "one", "one", "one", "one", "one", "one", "one", "one",
1343 ];
1344 let mut sut = HashedArrayTree::<String>::new();
1345 for item in inputs {
1346 sut.push(item.to_owned());
1347 }
1348 assert_eq!(sut.len(), 10);
1349 sut.dedup_by(|a, b| a == b);
1350 assert_eq!(sut.len(), 1);
1351 assert_eq!(inputs[0], "one");
1352 }
1353
1354 #[test]
1355 fn test_dedup_by_some_dupes_ints() {
1356 let inputs = [1, 2, 2, 3, 2];
1357 let mut sut = HashedArrayTree::<usize>::new();
1358 for item in inputs {
1359 sut.push(item.to_owned());
1360 }
1361 assert_eq!(sut.len(), 5);
1362 sut.dedup_by(|a, b| a == b);
1363 assert_eq!(sut.len(), 4);
1364 assert_eq!(sut[0], 1);
1365 assert_eq!(sut[1], 2);
1366 assert_eq!(sut[2], 3);
1367 assert_eq!(sut[3], 2);
1368 }
1369
1370 #[test]
1371 fn test_dedup_by_some_dupes_strings() {
1372 let inputs = ["foo", "bar", "Bar", "baz", "bar"];
1373 let mut sut = HashedArrayTree::<String>::new();
1374 for item in inputs {
1375 sut.push(item.to_owned());
1376 }
1377 assert_eq!(sut.len(), 5);
1378 sut.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1379 assert_eq!(sut.len(), 4);
1380 assert_eq!(sut[0], "foo");
1381 assert_eq!(sut[1], "bar");
1382 assert_eq!(sut[2], "baz");
1383 assert_eq!(sut[3], "bar");
1384 }
1385
1386 #[test]
1387 #[should_panic(expected = "`at` split index (is 10) should be <= len (is 0)")]
1388 fn test_split_off_bounds_panic() {
1389 let mut sut = HashedArrayTree::<usize>::new();
1390 sut.split_off(10);
1391 }
1392
1393 #[test]
1394 fn test_split_off_at_len() {
1395 let mut sut = HashedArrayTree::<usize>::new();
1396 for value in 0..13 {
1397 sut.push(value);
1398 }
1399 let other = sut.split_off(sut.len());
1401 assert_eq!(sut.len(), 13);
1402 assert!(other.is_empty());
1403 for value in 0..13 {
1404 assert_eq!(sut[value], value);
1405 }
1406 }
1407
1408 #[test]
1409 fn test_split_off_empty_at_zero() {
1410 let mut sut = HashedArrayTree::<usize>::new();
1411 let other = sut.split_off(0);
1412 assert!(sut.is_empty());
1413 assert!(other.is_empty());
1414 }
1415
1416 #[test]
1417 fn test_split_off_middle() {
1418 let mut sut = HashedArrayTree::<usize>::new();
1419 for value in 0..16 {
1420 sut.push(value);
1421 }
1422 assert_eq!(sut.len(), 16);
1423 assert_eq!(sut.capacity(), 16);
1424 let other = sut.split_off(8);
1425 assert_eq!(sut.len(), 8);
1426 assert_eq!(sut.capacity(), 8);
1427 for value in 0..8 {
1428 assert_eq!(sut[value], value);
1429 }
1430 assert_eq!(other.len(), 8);
1431 assert_eq!(other.capacity(), 8);
1432 for (index, value) in (8..16).enumerate() {
1433 assert_eq!(other[index], value);
1434 }
1435 }
1436
1437 #[test]
1438 fn test_split_off_almost_start() {
1439 let mut sut = HashedArrayTree::<usize>::new();
1440 for value in 0..16 {
1441 sut.push(value);
1442 }
1443 assert_eq!(sut.len(), 16);
1444 assert_eq!(sut.capacity(), 16);
1445 let other = sut.split_off(1);
1446 assert_eq!(sut.len(), 1);
1447 assert_eq!(sut.capacity(), 4);
1448 for value in 0..1 {
1449 assert_eq!(sut[value], value);
1450 }
1451 assert_eq!(other.len(), 15);
1452 assert_eq!(other.capacity(), 16);
1453 for (index, value) in (1..16).enumerate() {
1454 assert_eq!(other[index], value);
1455 }
1456 }
1457
1458 #[test]
1459 fn test_split_off_almost_end() {
1460 let mut sut = HashedArrayTree::<usize>::new();
1461 for value in 0..16 {
1462 sut.push(value);
1463 }
1464 assert_eq!(sut.len(), 16);
1465 assert_eq!(sut.capacity(), 16);
1466 let other = sut.split_off(15);
1467 assert_eq!(sut.len(), 15);
1468 assert_eq!(sut.capacity(), 16);
1469 for value in 0..15 {
1470 assert_eq!(sut[value], value);
1471 }
1472 assert_eq!(other.len(), 1);
1473 assert_eq!(other.capacity(), 4);
1474 assert_eq!(other[0], 15);
1475 }
1476
1477 #[test]
1478 fn test_split_off_odd_other() {
1479 let mut sut = HashedArrayTree::<usize>::new();
1480 for value in 0..16 {
1481 sut.push(value);
1482 }
1483 assert_eq!(sut.len(), 16);
1484 assert_eq!(sut.capacity(), 16);
1485 let other = sut.split_off(11);
1486 assert_eq!(sut.len(), 11);
1487 assert_eq!(sut.capacity(), 12);
1488 for value in 0..11 {
1489 assert_eq!(sut[value], value);
1490 }
1491 assert_eq!(other.len(), 5);
1492 assert_eq!(other.capacity(), 8);
1493 for (index, value) in (11..16).enumerate() {
1494 assert_eq!(other[index], value);
1495 }
1496 }
1497
1498 #[test]
1499 fn test_truncate_typical() {
1500 let mut sut = hat![1, 2, 3, 4, 5, 6, 7, 8];
1501 assert_eq!(sut.len(), 8);
1502 assert_eq!(sut.capacity(), 8);
1503 sut.truncate(5);
1504 assert_eq!(sut.len(), 5);
1505 assert_eq!(sut.capacity(), 8);
1506 for (index, value) in (1..6).enumerate() {
1507 assert_eq!(sut[index], value);
1508 }
1509 }
1510
1511 #[test]
1512 fn test_truncate_out_of_bounds() {
1513 let mut sut = hat![1, 2, 3, 4, 5,];
1514 assert_eq!(sut.len(), 5);
1515 assert_eq!(sut.capacity(), 8);
1516 sut.truncate(8);
1517 assert_eq!(sut.len(), 5);
1518 assert_eq!(sut.capacity(), 8);
1519 for (index, value) in (1..6).enumerate() {
1520 assert_eq!(sut[index], value);
1521 }
1522 }
1523
1524 #[test]
1525 fn test_truncate_to_empty() {
1526 let mut sut = hat![1, 2, 3, 4, 5,];
1527 assert_eq!(sut.len(), 5);
1528 assert_eq!(sut.capacity(), 8);
1529 sut.truncate(0);
1530 assert_eq!(sut.len(), 0);
1531 assert_eq!(sut.capacity(), 0);
1532 }
1533
1534 #[test]
1535 fn test_from_iterator() {
1536 let mut inputs: Vec<i32> = Vec::new();
1537 for value in 0..10_000 {
1538 inputs.push(value);
1539 }
1540 let sut: HashedArrayTree<i32> = inputs.into_iter().collect();
1541 assert_eq!(sut.len(), 10_000);
1542 for idx in 0..10_000i32 {
1543 let maybe = sut.get(idx as usize);
1544 assert!(maybe.is_some(), "{idx} is none");
1545 let actual = maybe.unwrap();
1546 assert_eq!(idx, *actual);
1547 }
1548 }
1549
1550 #[test]
1551 fn test_iterator() {
1552 let mut sut = HashedArrayTree::<usize>::new();
1553 for value in 0..512 {
1554 sut.push(value);
1555 }
1556 assert_eq!(sut.len(), 512);
1557 for (idx, elem) in sut.iter().enumerate() {
1558 assert_eq!(sut[idx], *elem);
1559 }
1560 }
1561
1562 #[test]
1563 fn test_iter_mut() {
1564 let mut sut = HashedArrayTree::<usize>::new();
1565 for value in 0..512 {
1566 sut.push(value);
1567 }
1568 for elem in sut.iter_mut() {
1570 *elem *= 2;
1571 }
1572 for idx in 0..512 {
1573 assert_eq!(sut[idx], idx * 2);
1574 }
1575 }
1576
1577 #[test]
1578 fn test_iter_mut_empty() {
1579 let mut sut = HashedArrayTree::<usize>::new();
1580 assert_eq!(sut.iter_mut().count(), 0);
1581 }
1582
1583 #[test]
1584 fn test_into_iterator_edge_case() {
1585 let inputs = [
1587 "one", "two", "three", "four", "five", "six", "seven", "eight",
1588 ];
1589 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1590 for item in inputs {
1591 sut.push(item.to_owned());
1592 }
1593 for (idx, elem) in sut.into_iter().enumerate() {
1594 assert_eq!(inputs[idx], elem);
1595 }
1596 }
1598
1599 #[test]
1600 fn test_into_iterator_multiple_leaves() {
1601 let inputs = [
1602 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1603 ];
1604 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1605 for item in inputs {
1606 sut.push(item.to_owned());
1607 }
1608 for (idx, elem) in sut.into_iter().enumerate() {
1609 assert_eq!(inputs[idx], elem);
1610 }
1611 }
1613
1614 #[test]
1615 fn test_into_iterator_drop_empty() {
1616 let sut: HashedArrayTree<String> = HashedArrayTree::new();
1617 assert_eq!(sut.into_iter().count(), 0);
1618 }
1619
1620 #[test]
1621 fn test_into_iterator_drop_single_leaf() {
1622 let inputs = ["one", "two", "three", "four"];
1625 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1626 for item in inputs {
1627 sut.push(item.to_owned());
1628 }
1629 for (idx, _) in sut.into_iter().enumerate() {
1630 if idx > 1 {
1631 break;
1632 }
1633 }
1634 }
1636
1637 #[test]
1638 fn test_into_iterator_drop_large() {
1639 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1643 for _ in 0..512 {
1644 let value = ulid::Ulid::new().to_string();
1645 sut.push(value);
1646 }
1647 for (idx, _) in sut.into_iter().enumerate() {
1648 if idx >= 28 {
1649 break;
1650 }
1651 }
1652 }
1654
1655 #[test]
1656 fn test_swap_remove_single_segment() {
1657 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1658 sut.push(1);
1659 sut.push(2);
1660 assert_eq!(sut.len(), 2);
1661 let one = sut.swap_remove(0);
1662 assert_eq!(one, 1);
1663 assert_eq!(sut[0], 2);
1664 }
1665
1666 #[test]
1667 fn test_swap_remove_prune_empty() {
1668 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1669 for value in 0..13 {
1670 sut.push(value);
1671 }
1672 assert_eq!(sut.len(), 13);
1673 assert_eq!(sut.capacity(), 16);
1674 let value = sut.swap_remove(8);
1675 assert_eq!(value, 8);
1676 assert_eq!(sut[8], 12);
1677 assert_eq!(sut.len(), 12);
1678 assert_eq!(sut.capacity(), 12);
1679 }
1680
1681 #[test]
1682 fn test_swap_remove_multiple_segments() {
1683 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1684 for value in 0..512 {
1685 sut.push(value);
1686 }
1687 assert_eq!(sut.len(), 512);
1688 let eighty = sut.swap_remove(80);
1689 assert_eq!(eighty, 80);
1690 assert_eq!(sut.pop(), Some(510));
1691 assert_eq!(sut[80], 511);
1692 }
1693
1694 #[test]
1695 #[should_panic(expected = "swap_remove index (is 0) should be < len (is 0)")]
1696 fn test_swap_remove_panic_empty() {
1697 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1698 sut.swap_remove(0);
1699 }
1700
1701 #[test]
1702 #[should_panic(expected = "swap_remove index (is 1) should be < len (is 1)")]
1703 fn test_swap_remove_panic_range_edge() {
1704 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1705 sut.push(1);
1706 sut.swap_remove(1);
1707 }
1708
1709 #[test]
1710 #[should_panic(expected = "swap_remove index (is 2) should be < len (is 1)")]
1711 fn test_swap_remove_panic_range_exceed() {
1712 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1713 sut.push(1);
1714 sut.swap_remove(2);
1715 }
1716
1717 #[test]
1718 fn test_push_get_many_instances_ints() {
1719 for _ in 0..1_000 {
1721 let mut sut: HashedArrayTree<usize> = HashedArrayTree::new();
1722 for value in 0..10_000 {
1723 sut.push(value);
1724 }
1725 assert_eq!(sut.len(), 10_000);
1726 }
1727 }
1728
1729 #[test]
1730 fn test_push_get_many_instances_strings() {
1731 for _ in 0..1_000 {
1733 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1734 for _ in 0..1_000 {
1735 let value = ulid::Ulid::new().to_string();
1736 sut.push(value);
1737 }
1738 assert_eq!(sut.len(), 1_000);
1739 }
1740 }
1741}