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 { self.index[block].add(slot).write(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 {
167 let block = index >> self.k;
168 let slot = index & self.k_mask;
169 unsafe { &*self.index[block].add(slot) }
170 }
171
172 pub fn get(&self, index: usize) -> Option<&T> {
178 if index >= self.count {
179 None
180 } else {
181 Some(self.raw_get(index))
182 }
183 }
184
185 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
191 if index >= self.count {
192 None
193 } else {
194 let block = index >> self.k;
195 let slot = index & self.k_mask;
196 unsafe { (self.index[block].add(slot)).as_mut() }
197 }
198 }
199
200 fn compress(&mut self) {
203 let old_index: Vec<*mut T> = std::mem::take(&mut self.index);
204 for old_buffer in old_index.into_iter() {
205 let half = self.l / 2;
206 let layout = Layout::array::<T>(half).expect("unexpected overflow");
207 let a = unsafe {
208 let ptr = alloc(layout).cast::<T>();
209 if ptr.is_null() {
210 handle_alloc_error(layout);
211 }
212 ptr
213 };
214 let b = unsafe {
215 let ptr = alloc(layout).cast::<T>();
216 if ptr.is_null() {
217 handle_alloc_error(layout);
218 }
219 ptr
220 };
221 unsafe {
222 std::ptr::copy(old_buffer, a, half);
223 std::ptr::copy(old_buffer.add(half), b, half);
224 };
225 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
226 unsafe {
227 dealloc(old_buffer as *mut u8, layout);
228 }
229 self.index.push(a);
230 self.index.push(b);
231 }
232 self.k -= 1;
233 self.k_mask = (1 << self.k) - 1;
234 self.l = 1 << self.k;
235 self.upper_limit = self.l * self.l;
236 self.lower_limit = self.upper_limit / 8;
237 }
238
239 pub fn raw_pop(&mut self) -> T {
243 let index = self.count - 1;
244 if index < self.lower_limit && self.k > 2 {
246 self.compress();
247 }
248 let block = index >> self.k;
249 let slot = index & self.k_mask;
250 let ret = unsafe { self.index[block].add(slot).read() };
251 if slot == 0 {
252 let ptr = self.index.pop().unwrap();
254 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
255 unsafe {
256 dealloc(ptr as *mut u8, layout);
257 }
258 }
259 self.count -= 1;
260 ret
261 }
262
263 pub fn pop(&mut self) -> Option<T> {
270 if self.count > 0 {
271 Some(self.raw_pop())
272 } else {
273 None
274 }
275 }
276
277 pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
285 if self.count == 0 {
286 None
287 } else if let Some(last) = self.get_mut(self.count - 1) {
288 if predicate(last) { self.pop() } else { None }
289 } else {
290 None
291 }
292 }
293
294 pub fn swap_remove(&mut self, index: usize) -> T {
308 if index >= self.count {
309 panic!(
310 "swap_remove index (is {index}) should be < len (is {})",
311 self.count
312 );
313 }
314 let block = index >> self.k;
316 let slot = index & self.k_mask;
317 unsafe {
318 let index_ptr = self.index[block].add(slot);
319 let value = index_ptr.read();
320 let block = (self.count - 1) >> self.k;
322 let slot = (self.count - 1) & self.k_mask;
323 let last_ptr = self.index[block].add(slot);
324 std::ptr::copy(last_ptr, index_ptr, 1);
325 if slot == 0 {
326 let ptr = self.index.pop().unwrap();
328 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
329 dealloc(ptr as *mut u8, layout);
330 }
331 self.count -= 1;
332 value
333 }
334 }
335
336 pub fn iter(&self) -> ArrayIter<'_, T> {
340 ArrayIter {
341 array: self,
342 index: 0,
343 count: self.count,
344 }
345 }
346
347 pub fn iter_mut(&mut self) -> ArrayIterMut<'_, T> {
351 ArrayIterMut {
352 dope: self.index.as_mut_ptr(),
353 index: 0,
354 count: self.count,
355 k: self.k,
356 k_mask: self.k_mask,
357 _marker: std::marker::PhantomData,
358 }
359 }
360
361 pub fn len(&self) -> usize {
367 self.count
368 }
369
370 pub fn capacity(&self) -> usize {
377 (1 << self.k) * self.index.len()
378 }
379
380 pub fn is_empty(&self) -> bool {
386 self.count == 0
387 }
388
389 pub fn clear(&mut self) {
395 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
396
397 if self.count > 0 && std::mem::needs_drop::<T>() {
398 let last_index = self.count - 1;
400 let last_block = last_index >> self.k;
401 let last_slot = last_index & self.k_mask;
402 unsafe {
403 drop_in_place(slice_from_raw_parts_mut(
406 self.index[last_block],
407 last_slot + 1,
408 ));
409 }
410
411 for block in 0..last_block {
413 unsafe {
414 drop_in_place(slice_from_raw_parts_mut(self.index[block], self.l));
415 }
416 }
417 }
418
419 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
421 for block in 0..self.index.len() {
422 unsafe {
423 dealloc(self.index[block] as *mut u8, layout);
424 }
425 }
426 self.index.clear();
427
428 self.count = 0;
429 self.k = 2;
430 self.k_mask = 3;
431 self.l = 1 << self.k;
432 self.upper_limit = self.l * self.l;
433 self.lower_limit = 0;
434 }
435
436 pub fn swap(&mut self, a: usize, b: usize) {
442 if a >= self.count {
443 panic!("swap a (is {a}) should be < len (is {})", self.count);
444 }
445 if b >= self.count {
446 panic!("swap b (is {b}) should be < len (is {})", self.count);
447 }
448 let a_block = a >> self.k;
451 let a_slot = a & self.k_mask;
452 let b_block = b >> self.k;
453 let b_slot = b & self.k_mask;
454 unsafe {
455 let a_ptr = self.index[a_block].add(a_slot);
456 let value = a_ptr.read();
457 let b_ptr = self.index[b_block].add(b_slot);
458 std::ptr::copy(b_ptr, a_ptr, 1);
459 b_ptr.write(value);
460 }
461 }
462
463 pub fn sort_unstable_by<F>(&mut self, mut compare: F)
471 where
472 F: FnMut(&T, &T) -> Ordering,
473 {
474 if self.count < 2 {
475 return;
476 }
477 let mut start = self.count / 2;
478 let mut end = self.count;
479 while end > 1 {
480 if start > 0 {
481 start -= 1;
482 } else {
483 end -= 1;
484 self.swap(end, 0);
485 }
486 let mut root = start;
487 let mut child = 2 * root + 1;
488 while child < end {
489 if child + 1 < end && compare(&self[child], &self[child + 1]) == Ordering::Less {
490 child += 1;
491 }
492 if compare(&self[root], &self[child]) == Ordering::Less {
493 self.swap(root, child);
494 root = child;
495 child = 2 * root + 1;
496 } else {
497 break;
498 }
499 }
500 }
501 }
502
503 pub fn dedup_by<F>(&mut self, mut same_bucket: F)
513 where
514 F: FnMut(&T, &T) -> bool,
515 {
516 let len = self.len();
517 if len <= 1 {
518 return;
519 }
520
521 let mut first_duplicate_idx: usize = 1;
524 while first_duplicate_idx != len {
525 let found_duplicate = {
526 let prev = self.raw_get(first_duplicate_idx - 1);
527 let current = self.raw_get(first_duplicate_idx);
528 same_bucket(current, prev)
529 };
530 if found_duplicate {
531 break;
532 }
533 first_duplicate_idx += 1;
534 }
535 if first_duplicate_idx == len {
536 return;
537 }
538
539 let index = std::mem::take(&mut self.index);
543 let old_l = self.l;
544 let mut remaining = self.count - 1;
545 self.count = 0;
546 self.clear();
547 let layout = Layout::array::<T>(old_l).expect("unexpected overflow");
548
549 let mut prev = unsafe { index[0].read() };
552 let mut slot = 1;
553 for buffer in index.into_iter() {
554 while slot < old_l {
555 let current = unsafe { buffer.add(slot).read() };
556 if same_bucket(¤t, &prev) {
557 drop(current);
558 } else {
559 self.push(prev);
560 prev = current;
561 }
562 remaining -= 1;
563 if remaining == 0 {
564 break;
565 }
566 slot += 1;
567 }
568 unsafe {
569 dealloc(buffer as *mut u8, layout);
570 }
571 slot = 0;
572 }
573 self.push(prev);
575 }
576
577 pub fn append(&mut self, other: &mut Self) {
579 let index = std::mem::take(&mut other.index);
580 let mut remaining = other.count;
581 other.count = 0;
583 let layout = Layout::array::<T>(other.l).expect("unexpected overflow");
584 for buffer in index.into_iter() {
585 for slot in 0..other.l {
586 let value = unsafe { buffer.add(slot).read() };
587 self.push(value);
588 remaining -= 1;
589 if remaining == 0 {
590 break;
591 }
592 }
593 unsafe {
594 dealloc(buffer as *mut u8, layout);
595 }
596 }
597 }
598
599 pub fn split_off(&mut self, at: usize) -> Self {
613 if at >= self.count {
614 panic!("index out of bounds: {at}");
615 }
616 let mut other = Self::new();
624 while self.count > at {
625 other.push(self.raw_pop());
626 }
627 let mut low = 0;
628 let mut high = other.count - 1;
629 while low < high {
630 unsafe {
631 let lp = other.index[low >> other.k].add(low & other.k_mask);
632 let value = lp.read();
633 let hp = other.index[high >> other.k].add(high & other.k_mask);
634 std::ptr::copy(hp, lp, 1);
635 hp.write(value);
636 }
637 low += 1;
638 high -= 1;
639 }
640 other
641 }
642
643 pub fn truncate(&mut self, len: usize) {
653 while self.count > len {
654 self.raw_pop();
655 }
657 }
658}
659
660impl<T> Default for HashedArrayTree<T> {
661 fn default() -> Self {
662 Self::new()
663 }
664}
665
666impl<T> fmt::Display for HashedArrayTree<T> {
667 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
668 write!(
669 f,
670 "HashedArrayTree(k: {}, count: {}, dope: {})",
671 self.k,
672 self.count,
673 self.index.len(),
674 )
675 }
676}
677
678impl<T> Index<usize> for HashedArrayTree<T> {
679 type Output = T;
680
681 fn index(&self, index: usize) -> &Self::Output {
682 let Some(item) = self.get(index) else {
683 panic!("index out of bounds: {}", index);
684 };
685 item
686 }
687}
688
689impl<T> IndexMut<usize> for HashedArrayTree<T> {
690 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
691 let Some(item) = self.get_mut(index) else {
692 panic!("index out of bounds: {}", index);
693 };
694 item
695 }
696}
697
698impl<T> Drop for HashedArrayTree<T> {
699 fn drop(&mut self) {
700 self.clear();
701 }
702}
703
704impl<T: Clone> Clone for HashedArrayTree<T> {
705 fn clone(&self) -> Self {
706 let mut result = HashedArrayTree::<T>::new();
707 for value in self.iter() {
708 result.push(value.clone());
709 }
710 result
711 }
712}
713
714unsafe impl<T: Send> Send for HashedArrayTree<T> {}
715
716impl<A> FromIterator<A> for HashedArrayTree<A> {
717 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
718 let mut arr: HashedArrayTree<A> = HashedArrayTree::new();
719 for value in iter {
720 arr.push(value)
721 }
722 arr
723 }
724}
725
726pub struct ArrayIter<'a, T> {
728 array: &'a HashedArrayTree<T>,
729 index: usize,
730 count: usize,
731}
732
733impl<'a, T> Iterator for ArrayIter<'a, T> {
734 type Item = &'a T;
735
736 fn next(&mut self) -> Option<Self::Item> {
737 if self.index < self.count {
738 let value = self.array.get(self.index);
739 self.index += 1;
740 value
741 } else {
742 None
743 }
744 }
745
746 fn size_hint(&self) -> (usize, Option<usize>) {
747 let remaining = self.count - self.index;
748 (remaining, Some(remaining))
749 }
750}
751
752impl<'a, T> ExactSizeIterator for ArrayIter<'a, T> {}
753
754pub struct ArrayIterMut<'a, T> {
756 dope: *mut *mut T, index: usize,
758 count: usize,
759 k: usize,
760 k_mask: usize,
761 _marker: std::marker::PhantomData<&'a mut T>,
762}
763
764impl<'a, T> Iterator for ArrayIterMut<'a, T> {
765 type Item = &'a mut T;
766
767 fn next(&mut self) -> Option<Self::Item> {
768 if self.index < self.count {
769 let block = self.index >> self.k;
770 let slot = self.index & self.k_mask;
771 self.index += 1;
772 unsafe {
776 let block_ptr = *self.dope.add(block);
777 Some(&mut *block_ptr.add(slot))
778 }
779 } else {
780 None
781 }
782 }
783
784 fn size_hint(&self) -> (usize, Option<usize>) {
785 let remaining = self.count - self.index;
786 (remaining, Some(remaining))
787 }
788}
789
790impl<'a, T> ExactSizeIterator for ArrayIterMut<'a, T> {}
791
792pub struct ArrayIntoIter<T> {
794 index: usize,
795 k: usize,
796 k_mask: usize,
797 count: usize,
798 dope: Vec<*mut T>,
799}
800
801impl<T> Iterator for ArrayIntoIter<T> {
802 type Item = T;
803
804 fn next(&mut self) -> Option<Self::Item> {
805 if self.index < self.count {
806 let block = self.index >> self.k;
807 let slot = self.index & self.k_mask;
808 self.index += 1;
809 unsafe { Some((self.dope[block].add(slot)).read()) }
810 } else {
811 None
812 }
813 }
814
815 fn size_hint(&self) -> (usize, Option<usize>) {
816 let remaining = self.count - self.index;
817 (remaining, Some(remaining))
818 }
819}
820
821impl<T> IntoIterator for HashedArrayTree<T> {
822 type Item = T;
823 type IntoIter = ArrayIntoIter<Self::Item>;
824
825 fn into_iter(self) -> Self::IntoIter {
826 let mut me = std::mem::ManuallyDrop::new(self);
827 let dope = std::mem::take(&mut me.index);
828 ArrayIntoIter {
829 index: 0,
830 count: me.count,
831 k: me.k,
832 k_mask: me.k_mask,
833 dope,
834 }
835 }
836}
837
838impl<T> ExactSizeIterator for ArrayIntoIter<T> {}
839
840impl<T> Drop for ArrayIntoIter<T> {
841 fn drop(&mut self) {
842 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
843 let block_len = 1 << self.k;
844
845 if self.count > 0 && std::mem::needs_drop::<T>() {
846 let first_block = self.index >> self.k;
849 let first_slot = self.index & self.k_mask;
850 let last_block = (self.count - 1) >> self.k;
851 let last_slot = (self.count - 1) & self.k_mask;
852 if first_block == last_block {
853 if first_slot <= last_slot {
855 unsafe {
856 drop_in_place(slice_from_raw_parts_mut(
859 self.dope[first_block].add(first_slot),
860 last_slot - first_slot + 1,
861 ));
862 }
863 }
864 } else if first_block < last_block {
865 if block_len < self.count {
867 unsafe {
868 drop_in_place(slice_from_raw_parts_mut(
869 self.dope[first_block].add(first_slot),
870 block_len - first_slot,
871 ));
872 }
873 }
874
875 unsafe {
877 drop_in_place(slice_from_raw_parts_mut(
878 self.dope[last_block],
879 last_slot + 1,
880 ));
881 }
882
883 for block in first_block + 1..last_block {
885 unsafe {
886 drop_in_place(slice_from_raw_parts_mut(self.dope[block], block_len));
887 }
888 }
889 }
890 }
891
892 for block in 0..self.dope.len() {
894 let layout = Layout::array::<T>(block_len).expect("unexpected overflow");
895 unsafe {
896 dealloc(self.dope[block] as *mut u8, layout);
897 }
898 }
899 }
900}
901
902#[macro_export]
907macro_rules! hat {
908 () => {
909 HashedArrayTree::new()
910 };
911 ( $($item:expr),* $(,)? ) => {
913 {
914 let mut result = HashedArrayTree::new();
915 $(
916 result.push($item);
917 )*
918 result
919 }
920 };
921}
922
923#[cfg(test)]
924mod tests {
925 use super::*;
926
927 #[test]
928 fn test_hat_macro() {
929 let sut: HashedArrayTree<usize> = hat![];
930 assert_eq!(sut.len(), 0);
931 assert_eq!(sut.capacity(), 0);
932
933 let sut: HashedArrayTree<usize> = hat![1];
934 assert_eq!(sut.len(), 1);
935 assert_eq!(sut.capacity(), 4);
936
937 let sut = hat![1, 2, 3, 4, 5, 6, 7, 8, 9,];
938 assert_eq!(sut.len(), 9);
939 assert_eq!(sut.capacity(), 12);
940 assert_eq!(sut[0], 1);
941 assert_eq!(sut[1], 2);
942 assert_eq!(sut[2], 3);
943 assert_eq!(sut[3], 4);
944 assert_eq!(sut[4], 5);
945 assert_eq!(sut[5], 6);
946 assert_eq!(sut[6], 7);
947 assert_eq!(sut[7], 8);
948 assert_eq!(sut[8], 9);
949 }
950
951 #[test]
952 fn test_empty() {
953 let sut = HashedArrayTree::<usize>::new();
954 assert!(sut.get(0).is_none());
955 }
956
957 #[test]
958 #[should_panic(expected = "index out of bounds:")]
959 fn test_index_out_of_bounds() {
960 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
961 sut.push(10);
962 sut.push(20);
963 let _ = sut[2];
964 }
965
966 #[test]
967 #[should_panic(expected = "index out of bounds:")]
968 fn test_index_mut_out_of_bounds() {
969 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
970 sut.push(10);
971 sut.push(20);
972 sut[2] = 30;
973 }
974
975 #[test]
976 fn test_push_no_expand() {
977 let mut sut = HashedArrayTree::<usize>::new();
979 for value in 0..13 {
980 sut.push(value);
981 }
982 assert_eq!(sut.len(), 13);
983 assert_eq!(sut.capacity(), 16);
984 for value in 0..13 {
985 assert_eq!(sut[value], value);
986 }
987 sut.pop();
989 assert_eq!(sut.len(), 12);
990 assert_eq!(sut.capacity(), 12);
991 }
992
993 #[test]
994 fn test_push_with_expand() {
995 let mut sut = HashedArrayTree::<usize>::new();
997 for value in 0..64 {
998 sut.push(value);
999 }
1000 assert_eq!(sut.len(), 64);
1001 assert_eq!(sut.capacity(), 64);
1002 for value in 0..64 {
1003 assert_eq!(sut[value], value);
1004 }
1005 }
1006
1007 #[test]
1008 fn test_expand_and_compress() {
1009 let mut sut = HashedArrayTree::<usize>::new();
1011 for value in 0..1024 {
1012 sut.push(value);
1013 }
1014 assert_eq!(sut.len(), 1024);
1015 assert_eq!(sut.capacity(), 1024);
1016 for _ in 0..960 {
1018 sut.pop();
1019 }
1020 assert_eq!(sut.len(), 64);
1022 assert_eq!(sut.capacity(), 64);
1023 for value in 0..64 {
1024 assert_eq!(sut[value], value);
1025 }
1026 }
1027
1028 #[test]
1029 fn test_push_get_get_mut() {
1030 let mut sut = HashedArrayTree::<usize>::new();
1031 for value in 0..12 {
1032 sut.push(value);
1033 }
1034 assert_eq!(sut.get(2), Some(&2));
1035 if let Some(value) = sut.get_mut(1) {
1036 *value = 11;
1037 } else {
1038 panic!("get_mut() returned None")
1039 }
1040 assert_eq!(sut[0], 0);
1041 assert_eq!(sut[1], 11);
1042 assert_eq!(sut[2], 2);
1043 }
1044
1045 #[test]
1046 fn test_push_within_capacity() {
1047 let mut sut = HashedArrayTree::<u32>::new();
1049 assert_eq!(sut.push_within_capacity(101), Err(101));
1050 sut.push(1);
1052 sut.push(2);
1053 assert_eq!(sut.push_within_capacity(3), Ok(()));
1054 assert_eq!(sut.push_within_capacity(4), Ok(()));
1055 assert_eq!(sut.push_within_capacity(5), Err(5));
1056 }
1057
1058 #[test]
1059 fn test_pop_small() {
1060 let mut sut = HashedArrayTree::<usize>::new();
1061 assert!(sut.is_empty());
1062 assert_eq!(sut.len(), 0);
1063 for value in 0..15 {
1064 sut.push(value);
1065 }
1066 assert!(!sut.is_empty());
1067 assert_eq!(sut.len(), 15);
1068 for value in (0..15).rev() {
1069 assert_eq!(sut.pop(), Some(value));
1070 }
1071 assert!(sut.is_empty());
1072 assert_eq!(sut.len(), 0);
1073 assert_eq!(sut.capacity(), 0);
1074 }
1075
1076 #[test]
1077 fn test_pop_if() {
1078 let mut sut = HashedArrayTree::<u32>::new();
1079 assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
1080 for value in 0..10 {
1081 sut.push(value);
1082 }
1083 assert!(sut.pop_if(|_| false).is_none());
1084 let maybe = sut.pop_if(|v| *v == 9);
1085 assert_eq!(maybe.unwrap(), 9);
1086 assert!(sut.pop_if(|v| *v == 9).is_none());
1087 }
1088
1089 #[test]
1090 fn test_clear_and_reuse_ints() {
1091 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
1092 for value in 0..512 {
1093 sut.push(value);
1094 }
1095 assert_eq!(sut.len(), 512);
1096 sut.clear();
1097 assert_eq!(sut.len(), 0);
1098 for value in 0..512 {
1099 sut.push(value);
1100 }
1101 for idx in 0..512 {
1102 let maybe = sut.get(idx);
1103 assert!(maybe.is_some(), "{idx} is none");
1104 let actual = maybe.unwrap();
1105 assert_eq!(idx, *actual as usize);
1106 }
1107 }
1108
1109 #[test]
1110 fn test_clear_and_reuse_strings() {
1111 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1112 for _ in 0..512 {
1113 let value = ulid::Ulid::new().to_string();
1114 sut.push(value);
1115 }
1116 assert_eq!(sut.len(), 512);
1117 sut.clear();
1118 assert_eq!(sut.len(), 0);
1119 for _ in 0..512 {
1120 let value = ulid::Ulid::new().to_string();
1121 sut.push(value);
1122 }
1123 assert_eq!(sut.len(), 512);
1124 }
1126
1127 #[test]
1128 fn test_clone_ints() {
1129 let mut sut = HashedArrayTree::<usize>::new();
1130 for value in 0..512 {
1131 sut.push(value);
1132 }
1133 let cloned = sut.clone();
1134 let ai = sut.iter();
1135 let bi = cloned.iter();
1136 for (a, b) in ai.zip(bi) {
1137 assert_eq!(a, b);
1138 }
1139 }
1140
1141 #[test]
1142 fn test_clone_strings() {
1143 let mut sut = HashedArrayTree::<String>::new();
1144 for _ in 0..64 {
1145 let value = ulid::Ulid::new().to_string();
1146 sut.push(value);
1147 }
1148 let cloned = sut.clone();
1149 let ai = sut.iter();
1150 let bi = cloned.iter();
1151 for (a, b) in ai.zip(bi) {
1152 assert_eq!(a, b);
1153 }
1154 }
1155
1156 #[test]
1157 fn test_swap() {
1158 let mut sut = HashedArrayTree::<usize>::new();
1159 sut.push(1);
1160 sut.push(2);
1161 sut.push(3);
1162 sut.push(4);
1163 sut.swap(1, 3);
1164 assert_eq!(sut[0], 1);
1165 assert_eq!(sut[1], 4);
1166 assert_eq!(sut[2], 3);
1167 assert_eq!(sut[3], 2);
1168 }
1169
1170 #[test]
1171 #[should_panic(expected = "swap a (is 1) should be < len (is 1)")]
1172 fn test_swap_panic_a() {
1173 let mut sut = HashedArrayTree::<usize>::new();
1174 sut.push(1);
1175 sut.swap(1, 2);
1176 }
1177
1178 #[test]
1179 #[should_panic(expected = "swap b (is 1) should be < len (is 1)")]
1180 fn test_swap_panic_b() {
1181 let mut sut = HashedArrayTree::<usize>::new();
1182 sut.push(1);
1183 sut.swap(0, 1);
1184 }
1185
1186 #[test]
1187 fn test_sort_unstable_by_ints() {
1188 let mut sut = HashedArrayTree::<usize>::new();
1189 sut.push(10);
1190 sut.push(1);
1191 sut.push(100);
1192 sut.push(20);
1193 sut.push(2);
1194 sut.push(99);
1195 sut.push(88);
1196 sut.push(77);
1197 sut.push(66);
1198 sut.sort_unstable_by(|a, b| a.cmp(b));
1199 assert_eq!(sut[0], 1);
1200 assert_eq!(sut[1], 2);
1201 assert_eq!(sut[2], 10);
1202 assert_eq!(sut[3], 20);
1203 assert_eq!(sut[4], 66);
1204 assert_eq!(sut[5], 77);
1205 assert_eq!(sut[6], 88);
1206 assert_eq!(sut[7], 99);
1207 assert_eq!(sut[8], 100);
1208 }
1209
1210 #[test]
1211 fn test_sort_unstable_by_strings() {
1212 let mut sut = HashedArrayTree::<String>::new();
1213 sut.push("cat".into());
1214 sut.push("ape".into());
1215 sut.push("zebra".into());
1216 sut.push("dog".into());
1217 sut.push("bird".into());
1218 sut.push("tapir".into());
1219 sut.push("monkey".into());
1220 sut.push("giraffe".into());
1221 sut.push("frog".into());
1222 sut.sort_unstable_by(|a, b| a.cmp(b));
1223 assert_eq!(sut[0], "ape");
1224 assert_eq!(sut[1], "bird");
1225 assert_eq!(sut[2], "cat");
1226 assert_eq!(sut[3], "dog");
1227 assert_eq!(sut[4], "frog");
1228 assert_eq!(sut[5], "giraffe");
1229 assert_eq!(sut[6], "monkey");
1230 assert_eq!(sut[7], "tapir");
1231 assert_eq!(sut[8], "zebra");
1232 }
1233
1234 #[test]
1235 fn test_append() {
1236 let odds = ["one", "three", "five", "seven", "nine"];
1237 let mut sut = HashedArrayTree::<String>::new();
1238 for item in odds {
1239 sut.push(item.to_owned());
1240 }
1241 let evens = ["two", "four", "six", "eight", "ten"];
1242 let mut other = HashedArrayTree::<String>::new();
1243 for item in evens {
1244 other.push(item.to_owned());
1245 }
1246 sut.append(&mut other);
1247 assert_eq!(sut.len(), 10);
1248 assert_eq!(sut.capacity(), 12);
1249 assert_eq!(other.len(), 0);
1250 assert_eq!(other.capacity(), 0);
1251 sut.sort_unstable_by(|a, b| a.cmp(b));
1252 assert_eq!(sut[0], "eight");
1253 assert_eq!(sut[1], "five");
1254 assert_eq!(sut[2], "four");
1255 assert_eq!(sut[3], "nine");
1256 assert_eq!(sut[4], "one");
1257 assert_eq!(sut[5], "seven");
1258 assert_eq!(sut[6], "six");
1259 assert_eq!(sut[7], "ten");
1260 assert_eq!(sut[8], "three");
1261 assert_eq!(sut[9], "two");
1262 }
1263
1264 #[test]
1265 fn test_dedup_by_tiny() {
1266 let mut sut = HashedArrayTree::<String>::new();
1267 sut.push("one".into());
1268 sut.dedup_by(|a, b| a == b);
1269 assert_eq!(sut.len(), 1);
1270 assert_eq!(sut[0], "one");
1271 }
1272
1273 #[test]
1274 fn test_dedup_by_2_dupes() {
1275 let mut sut = HashedArrayTree::<String>::new();
1276 sut.push("one".into());
1277 sut.push("one".into());
1278 sut.dedup_by(|a, b| a == b);
1279 assert_eq!(sut.len(), 1);
1280 assert_eq!(sut[0], "one");
1281 }
1282
1283 #[test]
1284 fn test_dedup_by_2_unique() {
1285 let mut sut = HashedArrayTree::<String>::new();
1286 sut.push("one".into());
1287 sut.push("two".into());
1288 sut.dedup_by(|a, b| a == b);
1289 assert_eq!(sut.len(), 2);
1290 assert_eq!(sut[0], "one");
1291 assert_eq!(sut[1], "two");
1292 }
1293
1294 #[test]
1295 fn test_dedup_by_all_unique() {
1296 let inputs = [
1297 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1298 ];
1299 let mut sut = HashedArrayTree::<String>::new();
1300 for item in inputs {
1301 sut.push(item.to_owned());
1302 }
1303 sut.dedup_by(|a, b| a == b);
1304 assert_eq!(sut.len(), 9);
1305 for (idx, elem) in sut.into_iter().enumerate() {
1306 assert_eq!(inputs[idx], elem);
1307 }
1308 }
1309
1310 #[test]
1311 fn test_dedup_by_all_dupes() {
1312 let inputs = [
1313 "one", "one", "one", "one", "one", "one", "one", "one", "one", "one",
1314 ];
1315 let mut sut = HashedArrayTree::<String>::new();
1316 for item in inputs {
1317 sut.push(item.to_owned());
1318 }
1319 assert_eq!(sut.len(), 10);
1320 sut.dedup_by(|a, b| a == b);
1321 assert_eq!(sut.len(), 1);
1322 assert_eq!(inputs[0], "one");
1323 }
1324
1325 #[test]
1326 fn test_dedup_by_some_dupes_ints() {
1327 let inputs = [1, 2, 2, 3, 2];
1328 let mut sut = HashedArrayTree::<usize>::new();
1329 for item in inputs {
1330 sut.push(item.to_owned());
1331 }
1332 assert_eq!(sut.len(), 5);
1333 sut.dedup_by(|a, b| a == b);
1334 assert_eq!(sut.len(), 4);
1335 assert_eq!(sut[0], 1);
1336 assert_eq!(sut[1], 2);
1337 assert_eq!(sut[2], 3);
1338 assert_eq!(sut[3], 2);
1339 }
1340
1341 #[test]
1342 fn test_dedup_by_some_dupes_strings() {
1343 let inputs = ["foo", "bar", "Bar", "baz", "bar"];
1344 let mut sut = HashedArrayTree::<String>::new();
1345 for item in inputs {
1346 sut.push(item.to_owned());
1347 }
1348 assert_eq!(sut.len(), 5);
1349 sut.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1350 assert_eq!(sut.len(), 4);
1351 assert_eq!(sut[0], "foo");
1352 assert_eq!(sut[1], "bar");
1353 assert_eq!(sut[2], "baz");
1354 assert_eq!(sut[3], "bar");
1355 }
1356
1357 #[test]
1358 #[should_panic(expected = "index out of bounds: 10")]
1359 fn test_split_off_bounds_panic() {
1360 let mut sut = HashedArrayTree::<usize>::new();
1361 sut.split_off(10);
1362 }
1363
1364 #[test]
1365 fn test_split_off_middle() {
1366 let mut sut = HashedArrayTree::<usize>::new();
1367 for value in 0..16 {
1368 sut.push(value);
1369 }
1370 assert_eq!(sut.len(), 16);
1371 assert_eq!(sut.capacity(), 16);
1372 let other = sut.split_off(8);
1373 assert_eq!(sut.len(), 8);
1374 assert_eq!(sut.capacity(), 8);
1375 for value in 0..8 {
1376 assert_eq!(sut[value], value);
1377 }
1378 assert_eq!(other.len(), 8);
1379 assert_eq!(other.capacity(), 8);
1380 for (index, value) in (8..16).enumerate() {
1381 assert_eq!(other[index], value);
1382 }
1383 }
1384
1385 #[test]
1386 fn test_split_off_almost_start() {
1387 let mut sut = HashedArrayTree::<usize>::new();
1388 for value in 0..16 {
1389 sut.push(value);
1390 }
1391 assert_eq!(sut.len(), 16);
1392 assert_eq!(sut.capacity(), 16);
1393 let other = sut.split_off(1);
1394 assert_eq!(sut.len(), 1);
1395 assert_eq!(sut.capacity(), 4);
1396 for value in 0..1 {
1397 assert_eq!(sut[value], value);
1398 }
1399 assert_eq!(other.len(), 15);
1400 assert_eq!(other.capacity(), 16);
1401 for (index, value) in (1..16).enumerate() {
1402 assert_eq!(other[index], value);
1403 }
1404 }
1405
1406 #[test]
1407 fn test_split_off_almost_end() {
1408 let mut sut = HashedArrayTree::<usize>::new();
1409 for value in 0..16 {
1410 sut.push(value);
1411 }
1412 assert_eq!(sut.len(), 16);
1413 assert_eq!(sut.capacity(), 16);
1414 let other = sut.split_off(15);
1415 assert_eq!(sut.len(), 15);
1416 assert_eq!(sut.capacity(), 16);
1417 for value in 0..15 {
1418 assert_eq!(sut[value], value);
1419 }
1420 assert_eq!(other.len(), 1);
1421 assert_eq!(other.capacity(), 4);
1422 assert_eq!(other[0], 15);
1423 }
1424
1425 #[test]
1426 fn test_split_off_odd_other() {
1427 let mut sut = HashedArrayTree::<usize>::new();
1428 for value in 0..16 {
1429 sut.push(value);
1430 }
1431 assert_eq!(sut.len(), 16);
1432 assert_eq!(sut.capacity(), 16);
1433 let other = sut.split_off(11);
1434 assert_eq!(sut.len(), 11);
1435 assert_eq!(sut.capacity(), 12);
1436 for value in 0..11 {
1437 assert_eq!(sut[value], value);
1438 }
1439 assert_eq!(other.len(), 5);
1440 assert_eq!(other.capacity(), 8);
1441 for (index, value) in (11..16).enumerate() {
1442 assert_eq!(other[index], value);
1443 }
1444 }
1445
1446 #[test]
1447 fn test_truncate_typical() {
1448 let mut sut = hat![1, 2, 3, 4, 5, 6, 7, 8];
1449 assert_eq!(sut.len(), 8);
1450 assert_eq!(sut.capacity(), 8);
1451 sut.truncate(5);
1452 assert_eq!(sut.len(), 5);
1453 assert_eq!(sut.capacity(), 8);
1454 for (index, value) in (1..6).enumerate() {
1455 assert_eq!(sut[index], value);
1456 }
1457 }
1458
1459 #[test]
1460 fn test_truncate_out_of_bounds() {
1461 let mut sut = hat![1, 2, 3, 4, 5,];
1462 assert_eq!(sut.len(), 5);
1463 assert_eq!(sut.capacity(), 8);
1464 sut.truncate(8);
1465 assert_eq!(sut.len(), 5);
1466 assert_eq!(sut.capacity(), 8);
1467 for (index, value) in (1..6).enumerate() {
1468 assert_eq!(sut[index], value);
1469 }
1470 }
1471
1472 #[test]
1473 fn test_truncate_to_empty() {
1474 let mut sut = hat![1, 2, 3, 4, 5,];
1475 assert_eq!(sut.len(), 5);
1476 assert_eq!(sut.capacity(), 8);
1477 sut.truncate(0);
1478 assert_eq!(sut.len(), 0);
1479 assert_eq!(sut.capacity(), 0);
1480 }
1481
1482 #[test]
1483 fn test_from_iterator() {
1484 let mut inputs: Vec<i32> = Vec::new();
1485 for value in 0..10_000 {
1486 inputs.push(value);
1487 }
1488 let sut: HashedArrayTree<i32> = inputs.into_iter().collect();
1489 assert_eq!(sut.len(), 10_000);
1490 for idx in 0..10_000i32 {
1491 let maybe = sut.get(idx as usize);
1492 assert!(maybe.is_some(), "{idx} is none");
1493 let actual = maybe.unwrap();
1494 assert_eq!(idx, *actual);
1495 }
1496 }
1497
1498 #[test]
1499 fn test_iterator() {
1500 let mut sut = HashedArrayTree::<usize>::new();
1501 for value in 0..512 {
1502 sut.push(value);
1503 }
1504 assert_eq!(sut.len(), 512);
1505 for (idx, elem) in sut.iter().enumerate() {
1506 assert_eq!(sut[idx], *elem);
1507 }
1508 }
1509
1510 #[test]
1511 fn test_iter_mut() {
1512 let mut sut = HashedArrayTree::<usize>::new();
1513 for value in 0..512 {
1514 sut.push(value);
1515 }
1516 for elem in sut.iter_mut() {
1518 *elem *= 2;
1519 }
1520 for idx in 0..512 {
1521 assert_eq!(sut[idx], idx * 2);
1522 }
1523 }
1524
1525 #[test]
1526 fn test_iter_mut_empty() {
1527 let mut sut = HashedArrayTree::<usize>::new();
1528 assert_eq!(sut.iter_mut().count(), 0);
1529 }
1530
1531 #[test]
1532 fn test_into_iterator_edge_case() {
1533 let inputs = [
1535 "one", "two", "three", "four", "five", "six", "seven", "eight",
1536 ];
1537 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1538 for item in inputs {
1539 sut.push(item.to_owned());
1540 }
1541 for (idx, elem) in sut.into_iter().enumerate() {
1542 assert_eq!(inputs[idx], elem);
1543 }
1544 }
1546
1547 #[test]
1548 fn test_into_iterator_multiple_leaves() {
1549 let inputs = [
1550 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1551 ];
1552 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1553 for item in inputs {
1554 sut.push(item.to_owned());
1555 }
1556 for (idx, elem) in sut.into_iter().enumerate() {
1557 assert_eq!(inputs[idx], elem);
1558 }
1559 }
1561
1562 #[test]
1563 fn test_into_iterator_drop_empty() {
1564 let sut: HashedArrayTree<String> = HashedArrayTree::new();
1565 assert_eq!(sut.into_iter().count(), 0);
1566 }
1567
1568 #[test]
1569 fn test_into_iterator_drop_single_leaf() {
1570 let inputs = ["one", "two", "three", "four"];
1573 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1574 for item in inputs {
1575 sut.push(item.to_owned());
1576 }
1577 for (idx, _) in sut.into_iter().enumerate() {
1578 if idx > 1 {
1579 break;
1580 }
1581 }
1582 }
1584
1585 #[test]
1586 fn test_into_iterator_drop_large() {
1587 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1591 for _ in 0..512 {
1592 let value = ulid::Ulid::new().to_string();
1593 sut.push(value);
1594 }
1595 for (idx, _) in sut.into_iter().enumerate() {
1596 if idx >= 28 {
1597 break;
1598 }
1599 }
1600 }
1602
1603 #[test]
1604 fn test_swap_remove_single_segment() {
1605 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1606 sut.push(1);
1607 sut.push(2);
1608 assert_eq!(sut.len(), 2);
1609 let one = sut.swap_remove(0);
1610 assert_eq!(one, 1);
1611 assert_eq!(sut[0], 2);
1612 }
1613
1614 #[test]
1615 fn test_swap_remove_prune_empty() {
1616 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1617 for value in 0..13 {
1618 sut.push(value);
1619 }
1620 assert_eq!(sut.len(), 13);
1621 assert_eq!(sut.capacity(), 16);
1622 let value = sut.swap_remove(8);
1623 assert_eq!(value, 8);
1624 assert_eq!(sut[8], 12);
1625 assert_eq!(sut.len(), 12);
1626 assert_eq!(sut.capacity(), 12);
1627 }
1628
1629 #[test]
1630 fn test_swap_remove_multiple_segments() {
1631 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1632 for value in 0..512 {
1633 sut.push(value);
1634 }
1635 assert_eq!(sut.len(), 512);
1636 let eighty = sut.swap_remove(80);
1637 assert_eq!(eighty, 80);
1638 assert_eq!(sut.pop(), Some(510));
1639 assert_eq!(sut[80], 511);
1640 }
1641
1642 #[test]
1643 #[should_panic(expected = "swap_remove index (is 0) should be < len (is 0)")]
1644 fn test_swap_remove_panic_empty() {
1645 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1646 sut.swap_remove(0);
1647 }
1648
1649 #[test]
1650 #[should_panic(expected = "swap_remove index (is 1) should be < len (is 1)")]
1651 fn test_swap_remove_panic_range_edge() {
1652 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1653 sut.push(1);
1654 sut.swap_remove(1);
1655 }
1656
1657 #[test]
1658 #[should_panic(expected = "swap_remove index (is 2) should be < len (is 1)")]
1659 fn test_swap_remove_panic_range_exceed() {
1660 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
1661 sut.push(1);
1662 sut.swap_remove(2);
1663 }
1664
1665 #[test]
1666 fn test_push_get_many_instances_ints() {
1667 for _ in 0..1_000 {
1669 let mut sut: HashedArrayTree<usize> = HashedArrayTree::new();
1670 for value in 0..10_000 {
1671 sut.push(value);
1672 }
1673 assert_eq!(sut.len(), 10_000);
1674 }
1675 }
1676
1677 #[test]
1678 fn test_push_get_many_instances_strings() {
1679 for _ in 0..1_000 {
1681 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
1682 for _ in 0..1_000 {
1683 let value = ulid::Ulid::new().to_string();
1684 sut.push(value);
1685 }
1686 assert_eq!(sut.len(), 1_000);
1687 }
1688 }
1689}