1use std::alloc::{Layout, alloc, dealloc, handle_alloc_error};
40use std::fmt;
41use std::ops::{Index, IndexMut};
42
43pub struct HashedArrayTree<T> {
45 index: Vec<*mut T>,
47 count: usize,
49 k: usize,
51 k_mask: usize,
53 l: usize,
55 upper_limit: usize,
57 lower_limit: usize,
59}
60
61impl<T> HashedArrayTree<T> {
62 pub fn new() -> Self {
64 let index: Vec<*mut T> = vec![];
65 Self {
66 index,
67 count: 0,
68 k: 2,
69 k_mask: 3,
70 l: 4,
71 upper_limit: 16,
72 lower_limit: 0,
73 }
74 }
75
76 fn expand(&mut self) {
79 let l_prime = 1 << (self.k + 1);
80 let old_index: Vec<*mut T> = std::mem::take(&mut self.index);
81 let mut iter = old_index.into_iter();
82 while let Some(a) = iter.next() {
83 let layout = Layout::array::<T>(l_prime).expect("unexpected overflow");
84 let buffer = unsafe {
85 let ptr = alloc(layout).cast::<T>();
86 if ptr.is_null() {
87 handle_alloc_error(layout);
88 }
89 ptr
90 };
91 if let Some(b) = iter.next() {
92 let b_dst = unsafe { buffer.add(self.l) };
93 let old_layout = Layout::array::<T>(self.l).expect("unexpected overflow");
94 unsafe {
95 std::ptr::copy(a, buffer, self.l);
96 std::ptr::copy(b, b_dst, self.l);
97 dealloc(a as *mut u8, old_layout);
98 dealloc(b as *mut u8, old_layout);
99 }
100 } else {
101 let old_layout = Layout::array::<T>(self.l).expect("unexpected overflow");
102 unsafe {
103 std::ptr::copy(a, buffer, self.l);
104 dealloc(a as *mut u8, old_layout);
105 }
106 }
107 self.index.push(buffer);
108 }
109 self.k += 1;
110 self.k_mask = (1 << self.k) - 1;
111 self.l = 1 << self.k;
112 self.upper_limit = self.l * self.l;
113 self.lower_limit = self.upper_limit / 8;
114 }
115
116 pub fn push(&mut self, value: T) {
126 let len = self.count;
127 if len >= self.upper_limit {
128 self.expand();
129 }
130 if len >= self.capacity() {
131 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
132 let buffer = unsafe {
133 let ptr = alloc(layout).cast::<T>();
134 if ptr.is_null() {
135 handle_alloc_error(layout);
136 }
137 ptr
138 };
139 self.index.push(buffer);
140 }
141 let block = len >> self.k;
142 let slot = len & self.k_mask;
143 unsafe { std::ptr::write(self.index[block].add(slot), value) }
144 self.count += 1;
145 }
146
147 pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
154 if self.capacity() <= self.count {
155 Err(value)
156 } else {
157 self.push(value);
158 Ok(())
159 }
160 }
161
162 pub fn get(&self, index: usize) -> Option<&T> {
168 if index >= self.count {
169 None
170 } else {
171 let block = index >> self.k;
172 let slot = index & self.k_mask;
173 unsafe { Some(&*self.index[block].add(slot)) }
174 }
175 }
176
177 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
183 if index >= self.count {
184 None
185 } else {
186 let block = index >> self.k;
187 let slot = index & self.k_mask;
188 unsafe { (self.index[block].add(slot)).as_mut() }
189 }
190 }
191
192 fn compress(&mut self) {
195 let old_index: Vec<*mut T> = std::mem::take(&mut self.index);
196 for old_buffer in old_index.into_iter() {
197 let half = self.l / 2;
198 let layout = Layout::array::<T>(half).expect("unexpected overflow");
199 let a = unsafe {
200 let ptr = alloc(layout).cast::<T>();
201 if ptr.is_null() {
202 handle_alloc_error(layout);
203 }
204 ptr
205 };
206 let b = unsafe {
207 let ptr = alloc(layout).cast::<T>();
208 if ptr.is_null() {
209 handle_alloc_error(layout);
210 }
211 ptr
212 };
213 unsafe {
214 std::ptr::copy(old_buffer, a, half);
215 std::ptr::copy(old_buffer.add(half), b, half);
216 };
217 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
218 unsafe {
219 dealloc(old_buffer as *mut u8, layout);
220 }
221 self.index.push(a);
222 self.index.push(b);
223 }
224 self.k -= 1;
225 self.k_mask = (1 << self.k) - 1;
226 self.l = 1 << self.k;
227 self.upper_limit = self.l * self.l;
228 self.lower_limit = self.upper_limit / 8;
229 }
230
231 pub fn pop(&mut self) -> Option<T> {
238 if self.count > 0 {
239 let index = self.count - 1;
240 if index < self.lower_limit && self.k > 2 {
242 self.compress();
243 }
244 let block = index >> self.k;
245 let slot = index & self.k_mask;
246 let ret = unsafe { Some(std::ptr::read(self.index[block].add(slot))) };
247 if slot == 0 {
248 let ptr = self.index.pop().unwrap();
250 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
251 unsafe {
252 dealloc(ptr as *mut u8, layout);
253 }
254 }
255 self.count -= 1;
256 ret
257 } else {
258 None
259 }
260 }
261
262 pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
270 if self.count == 0 {
271 None
272 } else if let Some(last) = self.get_mut(self.count - 1) {
273 if predicate(last) { self.pop() } else { None }
274 } else {
275 None
276 }
277 }
278
279 pub fn swap_remove(&mut self, index: usize) -> T {
289 if index >= self.count {
290 panic!(
291 "swap_remove index (is {index}) should be < len (is {})",
292 self.count
293 );
294 }
295 let block = index >> self.k;
297 let slot = index & self.k_mask;
298 unsafe {
299 let index_ptr = self.index[block].add(slot);
300 let value = index_ptr.read();
301 let block = (self.count - 1) >> self.k;
303 let slot = (self.count - 1) & self.k_mask;
304 let last_ptr = self.index[block].add(slot);
305 std::ptr::copy(last_ptr, index_ptr, 1);
306 if slot == 0 {
307 let ptr = self.index.pop().unwrap();
309 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
310 dealloc(ptr as *mut u8, layout);
311 }
312 self.count -= 1;
313 value
314 }
315 }
316
317 pub fn iter(&self) -> ArrayIter<'_, T> {
321 ArrayIter {
322 array: self,
323 index: 0,
324 }
325 }
326
327 pub fn len(&self) -> usize {
333 self.count
334 }
335
336 pub fn capacity(&self) -> usize {
343 (1 << self.k) * self.index.len()
344 }
345
346 pub fn is_empty(&self) -> bool {
352 self.count == 0
353 }
354
355 pub fn clear(&mut self) {
361 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
362
363 if self.count > 0 && std::mem::needs_drop::<T>() {
364 let last_index = self.count - 1;
366 let last_block = last_index >> self.k;
367 let last_slot = last_index & self.k_mask;
368 unsafe {
369 drop_in_place(slice_from_raw_parts_mut(
372 self.index[last_block],
373 last_slot + 1,
374 ));
375 }
376
377 for block in 0..last_block {
379 unsafe {
380 drop_in_place(slice_from_raw_parts_mut(self.index[block], self.l));
381 }
382 }
383 }
384
385 let layout = Layout::array::<T>(self.l).expect("unexpected overflow");
387 for block in 0..self.index.len() {
388 unsafe {
389 dealloc(self.index[block] as *mut u8, layout);
390 }
391 }
392 self.index.clear();
393
394 self.count = 0;
395 self.k = 2;
396 self.k_mask = 3;
397 self.l = 1 << self.k;
398 self.upper_limit = self.l * self.l;
399 self.lower_limit = 0;
400 }
401}
402
403impl<T> Default for HashedArrayTree<T> {
404 fn default() -> Self {
405 Self::new()
406 }
407}
408
409impl<T> fmt::Display for HashedArrayTree<T> {
410 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
411 write!(
412 f,
413 "HashedArrayTree(k: {}, count: {}, dope: {})",
414 self.k,
415 self.count,
416 self.index.len(),
417 )
418 }
419}
420
421impl<T> Index<usize> for HashedArrayTree<T> {
422 type Output = T;
423
424 fn index(&self, index: usize) -> &Self::Output {
425 let Some(item) = self.get(index) else {
426 panic!("index out of bounds: {}", index);
427 };
428 item
429 }
430}
431
432impl<T> IndexMut<usize> for HashedArrayTree<T> {
433 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
434 let Some(item) = self.get_mut(index) else {
435 panic!("index out of bounds: {}", index);
436 };
437 item
438 }
439}
440
441impl<T> Drop for HashedArrayTree<T> {
442 fn drop(&mut self) {
443 self.clear();
444 }
445}
446
447impl<A> FromIterator<A> for HashedArrayTree<A> {
448 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
449 let mut arr: HashedArrayTree<A> = HashedArrayTree::new();
450 for value in iter {
451 arr.push(value)
452 }
453 arr
454 }
455}
456
457pub struct ArrayIter<'a, T> {
459 array: &'a HashedArrayTree<T>,
460 index: usize,
461}
462
463impl<'a, T> Iterator for ArrayIter<'a, T> {
464 type Item = &'a T;
465
466 fn next(&mut self) -> Option<Self::Item> {
467 let value = self.array.get(self.index);
468 self.index += 1;
469 value
470 }
471}
472
473pub struct ArrayIntoIter<T> {
475 index: usize,
476 k: usize,
477 k_mask: usize,
478 count: usize,
479 dope: Vec<*mut T>,
480}
481
482impl<T> Iterator for ArrayIntoIter<T> {
483 type Item = T;
484
485 fn next(&mut self) -> Option<Self::Item> {
486 if self.index < self.count {
487 let block = self.index >> self.k;
488 let slot = self.index & self.k_mask;
489 self.index += 1;
490 unsafe { Some((self.dope[block].add(slot)).read()) }
491 } else {
492 None
493 }
494 }
495}
496
497impl<T> IntoIterator for HashedArrayTree<T> {
498 type Item = T;
499 type IntoIter = ArrayIntoIter<Self::Item>;
500
501 fn into_iter(self) -> Self::IntoIter {
502 let mut me = std::mem::ManuallyDrop::new(self);
503 let dope = std::mem::take(&mut me.index);
504 ArrayIntoIter {
505 index: 0,
506 count: me.count,
507 k: me.k,
508 k_mask: me.k_mask,
509 dope,
510 }
511 }
512}
513
514impl<T> Drop for ArrayIntoIter<T> {
515 fn drop(&mut self) {
516 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
517 let block_len = 1 << self.k;
518
519 if std::mem::needs_drop::<T>() {
520 let first_block = self.index >> self.k;
521 let first_slot = self.index & self.k_mask;
522 let last_block = (self.count - 1) >> self.k;
523 let last_slot = (self.count - 1) & self.k_mask;
524 if first_block == last_block {
525 if first_slot <= last_slot {
527 unsafe {
528 drop_in_place(slice_from_raw_parts_mut(
531 self.dope[first_block].add(first_slot),
532 last_slot - first_slot + 1,
533 ));
534 }
535 }
536 } else {
537 if block_len < self.count {
539 unsafe {
540 drop_in_place(slice_from_raw_parts_mut(
541 self.dope[first_block].add(first_slot),
542 block_len - first_slot,
543 ));
544 }
545 }
546
547 unsafe {
549 drop_in_place(slice_from_raw_parts_mut(
550 self.dope[last_block],
551 last_slot + 1,
552 ));
553 }
554
555 for block in first_block + 1..last_block {
557 unsafe {
558 drop_in_place(slice_from_raw_parts_mut(self.dope[block], block_len));
559 }
560 }
561 }
562 }
563
564 for block in 0..self.dope.len() {
566 let layout = Layout::array::<T>(block_len).expect("unexpected overflow");
567 unsafe {
568 dealloc(self.dope[block] as *mut u8, layout);
569 }
570 }
571 }
572}
573
574#[cfg(test)]
575mod tests {
576 use super::*;
577
578 #[test]
579 fn test_empty() {
580 let sut = HashedArrayTree::<usize>::new();
581 assert!(sut.get(0).is_none());
582 }
583
584 #[test]
585 #[should_panic(expected = "index out of bounds:")]
586 fn test_index_out_of_bounds() {
587 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
588 sut.push(10);
589 sut.push(20);
590 let _ = sut[2];
591 }
592
593 #[test]
594 #[should_panic(expected = "index out of bounds:")]
595 fn test_index_mut_out_of_bounds() {
596 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
597 sut.push(10);
598 sut.push(20);
599 sut[2] = 30;
600 }
601
602 #[test]
603 fn test_push_no_expand() {
604 let mut sut = HashedArrayTree::<usize>::new();
606 for value in 0..13 {
607 sut.push(value);
608 }
609 assert_eq!(sut.len(), 13);
610 assert_eq!(sut.capacity(), 16);
611 for value in 0..13 {
612 assert_eq!(sut[value], value);
613 }
614 sut.pop();
616 assert_eq!(sut.len(), 12);
617 assert_eq!(sut.capacity(), 12);
618 }
619
620 #[test]
621 fn test_push_with_expand() {
622 let mut sut = HashedArrayTree::<usize>::new();
624 for value in 0..64 {
625 sut.push(value);
626 }
627 assert_eq!(sut.len(), 64);
628 assert_eq!(sut.capacity(), 64);
629 for value in 0..64 {
630 assert_eq!(sut[value], value);
631 }
632 }
633
634 #[test]
635 fn test_expand_and_compress() {
636 let mut sut = HashedArrayTree::<usize>::new();
638 for value in 0..1024 {
639 sut.push(value);
640 }
641 assert_eq!(sut.len(), 1024);
642 assert_eq!(sut.capacity(), 1024);
643 for _ in 0..960 {
645 sut.pop();
646 }
647 assert_eq!(sut.len(), 64);
649 assert_eq!(sut.capacity(), 64);
650 for value in 0..64 {
651 assert_eq!(sut[value], value);
652 }
653 }
654
655 #[test]
656 fn test_push_get_get_mut() {
657 let mut sut = HashedArrayTree::<usize>::new();
658 for value in 0..12 {
659 sut.push(value);
660 }
661 assert_eq!(sut.get(2), Some(&2));
662 if let Some(value) = sut.get_mut(1) {
663 *value = 11;
664 } else {
665 panic!("get_mut() returned None")
666 }
667 assert_eq!(sut[0], 0);
668 assert_eq!(sut[1], 11);
669 assert_eq!(sut[2], 2);
670 }
671
672 #[test]
673 fn test_push_within_capacity() {
674 let mut sut = HashedArrayTree::<u32>::new();
676 assert_eq!(sut.push_within_capacity(101), Err(101));
677 sut.push(1);
679 sut.push(2);
680 assert_eq!(sut.push_within_capacity(3), Ok(()));
681 assert_eq!(sut.push_within_capacity(4), Ok(()));
682 assert_eq!(sut.push_within_capacity(5), Err(5));
683 }
684
685 #[test]
686 fn test_pop_small() {
687 let mut sut = HashedArrayTree::<usize>::new();
688 assert!(sut.is_empty());
689 assert_eq!(sut.len(), 0);
690 for value in 0..15 {
691 sut.push(value);
692 }
693 assert!(!sut.is_empty());
694 assert_eq!(sut.len(), 15);
695 for value in (0..15).rev() {
696 assert_eq!(sut.pop(), Some(value));
697 }
698 assert!(sut.is_empty());
699 assert_eq!(sut.len(), 0);
700 assert_eq!(sut.capacity(), 0);
701 }
702
703 #[test]
704 fn test_pop_if() {
705 let mut sut = HashedArrayTree::<u32>::new();
706 assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
707 for value in 0..10 {
708 sut.push(value);
709 }
710 assert!(sut.pop_if(|_| false).is_none());
711 let maybe = sut.pop_if(|v| *v == 9);
712 assert_eq!(maybe.unwrap(), 9);
713 assert!(sut.pop_if(|v| *v == 9).is_none());
714 }
715
716 #[test]
717 fn test_clear_and_reuse_ints() {
718 let mut sut: HashedArrayTree<i32> = HashedArrayTree::new();
719 for value in 0..512 {
720 sut.push(value);
721 }
722 assert_eq!(sut.len(), 512);
723 sut.clear();
724 assert_eq!(sut.len(), 0);
725 for value in 0..512 {
726 sut.push(value);
727 }
728 for idx in 0..512 {
729 let maybe = sut.get(idx);
730 assert!(maybe.is_some(), "{idx} is none");
731 let actual = maybe.unwrap();
732 assert_eq!(idx, *actual as usize);
733 }
734 }
735
736 #[test]
737 fn test_clear_and_reuse_strings() {
738 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
739 for _ in 0..512 {
740 let value = ulid::Ulid::new().to_string();
741 sut.push(value);
742 }
743 assert_eq!(sut.len(), 512);
744 sut.clear();
745 assert_eq!(sut.len(), 0);
746 for _ in 0..512 {
747 let value = ulid::Ulid::new().to_string();
748 sut.push(value);
749 }
750 assert_eq!(sut.len(), 512);
751 }
753
754 #[test]
755 fn test_from_iterator() {
756 let mut inputs: Vec<i32> = Vec::new();
757 for value in 0..10_000 {
758 inputs.push(value);
759 }
760 let sut: HashedArrayTree<i32> = inputs.into_iter().collect();
761 assert_eq!(sut.len(), 10_000);
762 for idx in 0..10_000i32 {
763 let maybe = sut.get(idx as usize);
764 assert!(maybe.is_some(), "{idx} is none");
765 let actual = maybe.unwrap();
766 assert_eq!(idx, *actual);
767 }
768 }
769
770 #[test]
771 fn test_iterator() {
772 let mut sut = HashedArrayTree::<usize>::new();
773 for value in 0..512 {
774 sut.push(value);
775 }
776 assert_eq!(sut.len(), 512);
777 for (idx, elem) in sut.iter().enumerate() {
778 assert_eq!(sut[idx], *elem);
779 }
780 }
781
782 #[test]
783 fn test_into_iterator() {
784 let inputs = [
786 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
787 ];
788 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
789 for item in inputs {
790 sut.push(item.to_owned());
791 }
792 for (idx, elem) in sut.into_iter().enumerate() {
793 assert_eq!(inputs[idx], elem);
794 }
795 }
797
798 #[test]
799 fn test_into_iterator_drop_tiny() {
800 let inputs = [
803 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
804 ];
805 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
806 for item in inputs {
807 sut.push(item.to_owned());
808 }
809 for (idx, _) in sut.into_iter().enumerate() {
810 if idx > 2 {
811 break;
812 }
813 }
814 }
816
817 #[test]
818 fn test_into_iterator_drop_large() {
819 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
823 for _ in 0..512 {
824 let value = ulid::Ulid::new().to_string();
825 sut.push(value);
826 }
827 for (idx, _) in sut.into_iter().enumerate() {
828 if idx >= 30 {
829 break;
830 }
831 }
832 }
834
835 #[test]
836 fn test_swap_remove_single_segment() {
837 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
838 sut.push(1);
839 sut.push(2);
840 assert_eq!(sut.len(), 2);
841 let one = sut.swap_remove(0);
842 assert_eq!(one, 1);
843 assert_eq!(sut[0], 2);
844 }
845
846 #[test]
847 fn test_swap_remove_prune_empty() {
848 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
849 for value in 0..13 {
850 sut.push(value);
851 }
852 assert_eq!(sut.len(), 13);
853 assert_eq!(sut.capacity(), 16);
854 let value = sut.swap_remove(8);
855 assert_eq!(value, 8);
856 assert_eq!(sut[8], 12);
857 assert_eq!(sut.len(), 12);
858 assert_eq!(sut.capacity(), 12);
859 }
860
861 #[test]
862 fn test_swap_remove_multiple_segments() {
863 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
864 for value in 0..512 {
865 sut.push(value);
866 }
867 assert_eq!(sut.len(), 512);
868 let eighty = sut.swap_remove(80);
869 assert_eq!(eighty, 80);
870 assert_eq!(sut.pop(), Some(510));
871 assert_eq!(sut[80], 511);
872 }
873
874 #[test]
875 #[should_panic(expected = "swap_remove index (is 0) should be < len (is 0)")]
876 fn test_swap_remove_panic_empty() {
877 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
878 sut.swap_remove(0);
879 }
880
881 #[test]
882 #[should_panic(expected = "swap_remove index (is 1) should be < len (is 1)")]
883 fn test_swap_remove_panic_range_edge() {
884 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
885 sut.push(1);
886 sut.swap_remove(1);
887 }
888
889 #[test]
890 #[should_panic(expected = "swap_remove index (is 2) should be < len (is 1)")]
891 fn test_swap_remove_panic_range_exceed() {
892 let mut sut: HashedArrayTree<u32> = HashedArrayTree::new();
893 sut.push(1);
894 sut.swap_remove(2);
895 }
896
897 #[test]
898 fn test_push_get_many_instances_ints() {
899 for _ in 0..1_000 {
901 let mut sut: HashedArrayTree<usize> = HashedArrayTree::new();
902 for value in 0..10_000 {
903 sut.push(value);
904 }
905 assert_eq!(sut.len(), 10_000);
906 }
907 }
908
909 #[test]
910 fn test_push_get_many_instances_strings() {
911 for _ in 0..1_000 {
913 let mut sut: HashedArrayTree<String> = HashedArrayTree::new();
914 for _ in 0..1_000 {
915 let value = ulid::Ulid::new().to_string();
916 sut.push(value);
917 }
918 assert_eq!(sut.len(), 1_000);
919 }
920 }
921}