1use std::alloc::{Layout, alloc, dealloc, handle_alloc_error};
35use std::fmt;
36use std::ops::{Index, IndexMut};
37
38const WORD_SIZE: u32 = (8 * std::mem::size_of::<usize>()) as u32;
40
41const BEE_BASE: u32 = WORD_SIZE + 1;
44
45#[inline]
49fn last_segment_for_l(l: usize) -> usize {
50 3 * (1 << (l - 1)) - 2
54}
55
56#[inline]
60fn datablock_capacity(l: usize) -> usize {
61 1 << l
62}
63
64#[inline]
66fn superblock_capacity(l: usize) -> usize {
67 if l == 1 { 2 } else { 3 * (1 << (l - 2)) }
68}
69
70#[inline]
76fn capacity_for_l(l: usize) -> usize {
77 1 << (l << 1)
78}
79
80fn l_for_segment(segment: usize) -> usize {
82 let j = (segment + 1).div_ceil(3);
87 let k = (WORD_SIZE - j.leading_zeros() - 1) as usize;
88 let thabit = 3 * (1 << k) - 1;
89 if segment >= thabit { k + 2 } else { k + 1 }
90}
91
92fn slots_in_segment(segment: usize) -> usize {
94 datablock_capacity(l_for_segment(segment))
95}
96
97fn mapping(v: usize) -> (usize, usize) {
102 let b = if v == 0 {
107 1
108 } else {
109 (BEE_BASE - v.leading_zeros()) >> 1
110 };
111 let segment = (v >> b) + (1 << (b - 1)) - 1;
112 let slot = v & ((1 << b) - 1);
113 (segment, slot)
114}
115
116fn array_capacity(dope_len: usize) -> usize {
122 if dope_len == 0 {
123 0
124 } else {
125 let last_segment = dope_len - 1;
126 let level = l_for_segment(last_segment);
127 let level_capacity = capacity_for_l(level);
128 let block_capacity = datablock_capacity(level);
129 let most_segment = last_segment_for_l(level);
130 let unalloc_capacity = block_capacity * (most_segment - last_segment);
131 level_capacity - unalloc_capacity
132 }
133}
134
135pub struct ExtensibleArray<T> {
139 dope: Vec<*mut T>,
141 count: usize,
143 level: usize,
145 d: usize,
147 empty: usize,
149 last_db_length: usize,
151 last_db_capacity: usize,
153 last_sb_length: usize,
155 last_sb_capacity: usize,
157}
158
159impl<T> ExtensibleArray<T> {
160 pub fn new() -> Self {
166 Self {
167 dope: vec![],
168 count: 0,
169 level: 1,
170 d: 0,
171 empty: 0,
172 last_db_length: 0,
173 last_db_capacity: 0,
174 last_sb_length: 0,
175 last_sb_capacity: 0,
176 }
177 }
178
179 pub fn push(&mut self, value: T) {
189 if self.last_db_capacity == self.last_db_length {
191 if self.last_sb_capacity == self.last_sb_length {
193 self.last_sb_capacity = superblock_capacity(self.level);
194 self.last_db_capacity = datablock_capacity(self.level);
195 self.last_sb_length = 0;
196 self.level += 1;
197 }
198 if self.empty == 0 {
200 let layout =
202 Layout::array::<T>(self.last_db_capacity).expect("unexpected overflow");
203 unsafe {
204 let ptr = alloc(layout).cast::<T>();
205 if ptr.is_null() {
206 handle_alloc_error(layout);
207 }
208 self.dope.push(ptr);
209 }
210 } else {
211 self.empty = 0;
213 }
214 self.d += 1;
215 self.last_sb_length += 1;
216 self.last_db_length = 0;
217 }
218 let (segment, slot) = mapping(self.count);
219 unsafe {
220 std::ptr::write(self.dope[segment].add(slot), value);
221 }
222 self.count += 1;
223 self.last_db_length += 1;
224 }
225
226 pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
233 let (segment, _slot) = mapping(self.count);
234 if self.dope.len() <= segment {
235 Err(value)
236 } else {
237 self.push(value);
238 Ok(())
239 }
240 }
241
242 fn shrink(&mut self) {
244 self.count -= 1;
245 self.last_db_length -= 1;
246 if self.last_db_length == 0 {
248 if self.empty == 1 {
250 let ptr = self.dope.pop().expect("programmer error");
251 let block = self.dope.len();
252 let block_len = slots_in_segment(block);
253 let layout = Layout::array::<T>(block_len).expect("unexpected overflow");
254 unsafe {
255 dealloc(ptr as *mut u8, layout);
256 }
257 }
258 self.empty = 1;
261 if self.dope.len() * 4 <= self.dope.capacity() {
263 self.dope.shrink_to(self.dope.capacity() / 2);
264 }
265 self.d -= 1;
267 self.last_sb_length -= 1;
268 if self.last_sb_length == 0 {
270 self.level -= 1;
271 if self.level == 1 {
272 self.last_sb_capacity = 0;
273 self.last_db_capacity = 0;
274 } else {
275 self.last_sb_capacity = superblock_capacity(self.level - 1);
276 self.last_db_capacity = datablock_capacity(self.level - 1);
277 }
278 self.last_sb_length = self.last_sb_capacity;
280 }
281 self.last_db_length = self.last_db_capacity;
283 }
284 }
285
286 pub fn pop(&mut self) -> Option<T> {
293 if self.count > 0 {
294 let (segment, slot) = mapping(self.count - 1);
295 let value = unsafe { Some((self.dope[segment].add(slot)).read()) };
296 self.shrink();
297 value
298 } else {
299 None
300 }
301 }
302
303 pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
311 if self.count == 0 {
312 None
313 } else if let Some(last) = self.get_mut(self.count - 1) {
314 if predicate(last) { self.pop() } else { None }
315 } else {
316 None
317 }
318 }
319
320 pub fn len(&self) -> usize {
326 self.count
327 }
328
329 pub fn capacity(&self) -> usize {
336 array_capacity(self.dope.len())
337 }
338
339 pub fn is_empty(&self) -> bool {
345 self.count == 0
346 }
347
348 pub fn get(&self, index: usize) -> Option<&T> {
354 if index >= self.count {
355 None
356 } else {
357 let (segment, slot) = mapping(index);
358 unsafe { (self.dope[segment].add(slot)).as_ref() }
359 }
360 }
361
362 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
368 if index >= self.count {
369 None
370 } else {
371 let (segment, slot) = mapping(index);
372 unsafe { (self.dope[segment].add(slot)).as_mut() }
373 }
374 }
375
376 pub fn swap_remove(&mut self, index: usize) -> T {
386 if index >= self.count {
387 panic!(
388 "swap_remove index (is {index}) should be < len (is {})",
389 self.count
390 );
391 }
392 let (segment, slot) = mapping(index);
394 unsafe {
395 let index_ptr = self.dope[segment].add(slot);
396 let value = index_ptr.read();
397 let (segment, slot) = mapping(self.count - 1);
399 let last_ptr = self.dope[segment].add(slot);
400 std::ptr::copy(last_ptr, index_ptr, 1);
401 self.shrink();
402 value
403 }
404 }
405
406 pub fn iter(&self) -> ExtArrayIter<'_, T> {
410 ExtArrayIter {
411 array: self,
412 index: 0,
413 }
414 }
415
416 pub fn clear(&mut self) {
423 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
424
425 if self.count > 0 {
426 if std::mem::needs_drop::<T>() {
427 let (last_segment, last_slot) = mapping(self.count - 1);
429 unsafe {
430 drop_in_place(slice_from_raw_parts_mut(
433 self.dope[last_segment],
434 last_slot + 1,
435 ));
436 }
437
438 let mut segment = 0;
440 for level in 1..=self.level {
441 let level_limit = last_segment_for_l(level);
442 let segment_len = datablock_capacity(level);
443 while segment <= level_limit && segment < last_segment {
444 unsafe {
445 drop_in_place(slice_from_raw_parts_mut(
446 self.dope[segment],
447 segment_len,
448 ));
449 }
450 segment += 1;
451 }
452 }
453 }
454
455 self.level = 1;
456 self.count = 0;
457 self.d = 0;
458 self.empty = 0;
459 self.last_db_length = 0;
460 self.last_db_capacity = 0;
461 self.last_sb_length = 0;
462 self.last_sb_capacity = 0;
463 }
464
465 for segment in 0..self.dope.len() {
467 let segment_len = slots_in_segment(segment);
468 let layout = Layout::array::<T>(segment_len).expect("unexpected overflow");
469 unsafe {
470 dealloc(self.dope[segment] as *mut u8, layout);
471 }
472 }
473 self.dope.clear();
474 }
475}
476
477impl<T> Default for ExtensibleArray<T> {
478 fn default() -> Self {
479 Self::new()
480 }
481}
482
483impl<T> fmt::Display for ExtensibleArray<T> {
484 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
485 write!(
486 f,
487 "ExtensibleArray(n: {}, s: {}, d: {}, e: {}, dl: {}, dc: {}, sl: {}, sc: {})",
488 self.count,
489 self.level,
490 self.d,
491 self.empty,
492 self.last_db_length,
493 self.last_db_capacity,
494 self.last_sb_length,
495 self.last_sb_capacity
496 )
497 }
498}
499
500impl<T> Drop for ExtensibleArray<T> {
501 fn drop(&mut self) {
502 self.clear();
503 }
504}
505
506impl<T> Index<usize> for ExtensibleArray<T> {
507 type Output = T;
508
509 fn index(&self, index: usize) -> &Self::Output {
510 let Some(item) = self.get(index) else {
511 panic!("index out of bounds: {}", index);
512 };
513 item
514 }
515}
516
517impl<T> IndexMut<usize> for ExtensibleArray<T> {
518 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
519 let Some(item) = self.get_mut(index) else {
520 panic!("index out of bounds: {}", index);
521 };
522 item
523 }
524}
525
526impl<A> FromIterator<A> for ExtensibleArray<A> {
527 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
528 let mut arr: ExtensibleArray<A> = ExtensibleArray::new();
529 for value in iter {
530 arr.push(value)
531 }
532 arr
533 }
534}
535
536pub struct ExtArrayIter<'a, T> {
538 array: &'a ExtensibleArray<T>,
539 index: usize,
540}
541
542impl<'a, T> Iterator for ExtArrayIter<'a, T> {
543 type Item = &'a T;
544
545 fn next(&mut self) -> Option<Self::Item> {
546 let value = self.array.get(self.index);
547 self.index += 1;
548 value
549 }
550}
551
552pub struct ExtArrayIntoIter<T> {
554 index: usize,
555 count: usize,
556 level: usize,
557 dope: Vec<*mut T>,
558}
559
560impl<T> Iterator for ExtArrayIntoIter<T> {
561 type Item = T;
562
563 fn next(&mut self) -> Option<Self::Item> {
564 if self.index < self.count {
565 let (segment, slot) = mapping(self.index);
566 self.index += 1;
567 unsafe { Some((self.dope[segment].add(slot)).read()) }
568 } else {
569 None
570 }
571 }
572}
573
574impl<T> Drop for ExtArrayIntoIter<T> {
575 fn drop(&mut self) {
576 use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
577
578 if self.count > 0 && std::mem::needs_drop::<T>() {
579 let (first_segment, first_slot) = mapping(self.index);
580 let (last_segment, last_slot) = mapping(self.count - 1);
581 if first_segment == last_segment {
582 if first_slot <= last_slot {
584 unsafe {
585 drop_in_place(slice_from_raw_parts_mut(
588 self.dope[first_segment].add(first_slot),
589 last_slot - first_slot + 1,
590 ));
591 }
592 }
593 } else if first_segment < last_segment {
594 let segment_len = slots_in_segment(first_segment);
596 if segment_len < self.count {
597 unsafe {
598 drop_in_place(slice_from_raw_parts_mut(
599 self.dope[first_segment].add(first_slot),
600 segment_len - first_slot,
601 ));
602 }
603 }
604
605 unsafe {
607 drop_in_place(slice_from_raw_parts_mut(
608 self.dope[last_segment],
609 last_slot + 1,
610 ));
611 }
612
613 for segment in first_segment + 1..last_segment {
615 let segment_len = slots_in_segment(segment);
616 unsafe {
617 drop_in_place(slice_from_raw_parts_mut(self.dope[segment], segment_len));
618 }
619 }
620 }
621 }
622
623 for segment in 0..self.dope.len() {
625 let segment_len = slots_in_segment(segment);
626 let layout = Layout::array::<T>(segment_len).expect("unexpected overflow");
627 unsafe {
628 dealloc(self.dope[segment] as *mut u8, layout);
629 }
630 }
631
632 self.dope.clear();
633 self.index = 0;
634 self.level = 1;
635 self.count = 0;
636 }
637}
638
639impl<T> IntoIterator for ExtensibleArray<T> {
640 type Item = T;
641 type IntoIter = ExtArrayIntoIter<Self::Item>;
642
643 fn into_iter(self) -> Self::IntoIter {
644 let mut me = std::mem::ManuallyDrop::new(self);
645 let dope = std::mem::take(&mut me.dope);
646 ExtArrayIntoIter {
647 index: 0,
648 count: me.count,
649 level: me.level,
650 dope,
651 }
652 }
653}
654
655#[cfg(test)]
656mod tests {
657 use super::*;
658
659 #[test]
660 fn test_push_get_one_item() {
661 let item = String::from("hello world");
662 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
663 assert_eq!(sut.len(), 0);
664 assert!(sut.is_empty());
665 sut.push(item);
666 assert_eq!(sut.len(), 1);
667 assert!(!sut.is_empty());
668 let maybe = sut.get(0);
669 assert!(maybe.is_some());
670 let actual = maybe.unwrap();
671 assert_eq!("hello world", actual);
672 let missing = sut.get(10);
673 assert!(missing.is_none());
674 }
675
676 #[test]
677 fn test_push_get_several_strings() {
678 let inputs = [
679 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
680 ];
681 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
682 for item in inputs {
683 sut.push(item.to_owned());
684 }
685 assert_eq!(sut.len(), 9);
686 for (idx, item) in inputs.iter().enumerate() {
687 let maybe = sut.get(idx);
688 assert!(maybe.is_some(), "{idx} is none");
689 let actual = maybe.unwrap();
690 assert_eq!(item, actual);
691 }
692 let maybe = sut.get(10);
693 assert!(maybe.is_none());
694 assert_eq!(sut[3], "four");
695 }
696
697 #[test]
698 fn test_push_get_hundred_ints() {
699 let mut sut: ExtensibleArray<i32> = ExtensibleArray::new();
700 for value in 0..100 {
701 sut.push(value);
702 }
703 assert_eq!(sut.len(), 100);
704 for idx in 0..100 {
705 let maybe = sut.get(idx);
706 assert!(maybe.is_some(), "{idx} is none");
707 let actual = maybe.unwrap();
708 assert_eq!(idx, *actual as usize);
709 }
710 assert_eq!(sut[99], 99);
711 }
712
713 #[test]
714 fn test_len_and_capacity() {
715 let mut sut: ExtensibleArray<i32> = ExtensibleArray::new();
716 assert_eq!(sut.len(), 0);
717 assert_eq!(sut.capacity(), 0);
718 for value in 0..100 {
719 sut.push(value);
720 }
721 assert_eq!(sut.len(), 100);
722 assert_eq!(sut.capacity(), 112);
724 }
725
726 #[test]
727 fn test_pop_and_shrink() {
728 let mut sut: ExtensibleArray<usize> = ExtensibleArray::new();
729 for value in 0..8 {
730 sut.push(value);
731 }
732 assert_eq!(sut.len(), 8);
733 assert_eq!(sut.capacity(), 8);
734 while !sut.is_empty() {
735 sut.pop();
736 }
737 assert_eq!(sut.len(), 0);
738 assert_eq!(sut.capacity(), 2);
740 }
741
742 #[test]
743 fn test_push_within_capacity() {
744 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
746 assert_eq!(sut.push_within_capacity(101), Err(101));
747 sut.push(10);
748 assert_eq!(sut.push_within_capacity(101), Ok(()));
749
750 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
752 sut.push(1);
753 assert_eq!(sut.push_within_capacity(2), Ok(()));
754 assert_eq!(sut.push_within_capacity(3), Err(3));
755 }
756
757 #[test]
758 fn test_get_mut_index_mut() {
759 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
760 sut.push(String::from("first"));
761 sut.push(String::from("second"));
762 sut.push(String::from("third"));
763 if let Some(value) = sut.get_mut(1) {
764 value.push_str(" place");
765 } else {
766 panic!("get_mut() returned None")
767 }
768 assert_eq!(sut[1], "second place");
769 sut[2] = "third planet".into();
770 assert_eq!(sut[2], "third planet");
771 }
772
773 #[test]
774 #[should_panic(expected = "index out of bounds:")]
775 fn test_index_out_of_bounds() {
776 let mut sut: ExtensibleArray<i32> = ExtensibleArray::new();
777 sut.push(10);
778 sut.push(20);
779 let _ = sut[2];
780 }
781
782 #[test]
783 #[should_panic(expected = "index out of bounds:")]
784 fn test_index_mut_out_of_bounds() {
785 let mut sut: ExtensibleArray<i32> = ExtensibleArray::new();
786 sut.push(10);
787 sut.push(20);
788 sut[2] = 30;
789 }
790
791 #[test]
792 fn test_push_many_pop_all_verify() {
793 let mut sut: ExtensibleArray<usize> = ExtensibleArray::new();
795 assert_eq!(sut.len(), 0);
796 assert_eq!(sut.capacity(), 0);
797 for value in 0..16384 {
798 sut.push(value);
799 }
800 assert_eq!(sut.len(), 16384);
801 assert_eq!(sut.capacity(), 16384);
802 for value in (0..16384).rev() {
803 assert_eq!(sut.pop(), Some(value));
804 }
805 assert_eq!(sut.len(), 0);
806 assert_eq!(sut.capacity(), 2);
808 }
809
810 #[test]
811 fn test_push_pop_grow_shrink_empty_block() {
812 let mut sut: ExtensibleArray<usize> = ExtensibleArray::new();
818 assert_eq!(sut.len(), 0);
819 assert_eq!(sut.capacity(), 0);
820 for value in 0..20 {
821 sut.push(value);
822 }
823 assert_eq!(sut.len(), 20);
824 assert_eq!(sut.capacity(), 24);
825 for _ in 0..5 {
826 sut.pop();
827 }
828 assert_eq!(sut.len(), 15);
829 assert_eq!(sut.capacity(), 24);
830 for _ in 0..5 {
831 sut.pop();
832 }
833 assert_eq!(sut.len(), 10);
834 assert_eq!(sut.capacity(), 16);
835 for value in 10..22 {
836 sut.push(value);
837 }
838 assert_eq!(sut.len(), 22);
839 assert_eq!(sut.capacity(), 24);
840 for (idx, elem) in sut.iter().enumerate() {
841 assert_eq!(idx, *elem);
842 }
843
844 sut.clear();
846 }
847
848 #[test]
849 fn test_push_pop_iter() {
850 let inputs = [
851 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
852 ];
853 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
854 assert!(sut.pop().is_none());
855 for item in inputs {
856 sut.push(item.to_owned());
857 }
858 assert_eq!(sut.len(), 9);
859 for (idx, elem) in sut.iter().enumerate() {
860 assert_eq!(inputs[idx], elem);
861 }
862 let maybe = sut.pop();
863 assert!(maybe.is_some());
864 let value = maybe.unwrap();
865 assert_eq!(value, "nine");
866 assert_eq!(sut.len(), 8);
867 sut.push(String::from("nine"));
868 assert_eq!(sut.len(), 9);
869 for (idx, elem) in sut.iter().enumerate() {
870 assert_eq!(inputs[idx], elem);
871 }
872
873 while !sut.is_empty() {
875 sut.pop();
876 }
877 assert_eq!(sut.len(), 0);
878 for item in inputs {
879 sut.push(item.to_owned());
880 }
881 assert_eq!(sut.len(), 9);
882 for (idx, elem) in sut.iter().enumerate() {
883 assert_eq!(inputs[idx], elem);
884 }
885 }
886
887 #[test]
888 fn test_pop_if() {
889 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
890 assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
891 for value in 0..10 {
892 sut.push(value);
893 }
894 assert!(sut.pop_if(|_| false).is_none());
895 let maybe = sut.pop_if(|v| *v == 9);
896 assert_eq!(maybe.unwrap(), 9);
897 assert!(sut.pop_if(|v| *v == 9).is_none());
898 }
899
900 #[test]
901 fn test_swap_remove_single_segment() {
902 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
903 sut.push(1);
904 sut.push(2);
905 assert_eq!(sut.len(), 2);
906 let one = sut.swap_remove(0);
907 assert_eq!(one, 1);
908 assert_eq!(sut[0], 2);
909 }
910
911 #[test]
912 fn test_swap_remove_multiple_segments() {
913 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
914 for value in 0..512 {
915 sut.push(value);
916 }
917 assert_eq!(sut.len(), 512);
918 let eighty = sut.swap_remove(80);
919 assert_eq!(eighty, 80);
920 assert_eq!(sut.pop(), Some(510));
921 assert_eq!(sut[80], 511);
922 }
923
924 #[test]
925 #[should_panic(expected = "swap_remove index (is 0) should be < len (is 0)")]
926 fn test_swap_remove_panic_empty() {
927 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
928 sut.swap_remove(0);
929 }
930
931 #[test]
932 #[should_panic(expected = "swap_remove index (is 1) should be < len (is 1)")]
933 fn test_swap_remove_panic_range_edge() {
934 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
935 sut.push(1);
936 sut.swap_remove(1);
937 }
938
939 #[test]
940 #[should_panic(expected = "swap_remove index (is 2) should be < len (is 1)")]
941 fn test_swap_remove_panic_range_exceed() {
942 let mut sut: ExtensibleArray<u32> = ExtensibleArray::new();
943 sut.push(1);
944 sut.swap_remove(2);
945 }
946
947 #[test]
948 fn test_clear_and_reuse_tiny() {
949 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
951 sut.push(String::from("one"));
952 sut.push(String::from("two"));
953 assert_eq!(sut.len(), 2);
954 sut.clear();
955 assert_eq!(sut.len(), 0);
956 sut.push(String::from("one"));
957 sut.push(String::from("two"));
958 assert_eq!(sut.len(), 2);
959 }
961
962 #[test]
963 fn test_clear_and_reuse_ints() {
964 let mut sut: ExtensibleArray<i32> = ExtensibleArray::new();
965 for value in 0..512 {
966 sut.push(value);
967 }
968 assert_eq!(sut.len(), 512);
969 sut.clear();
970 assert_eq!(sut.len(), 0);
971 for value in 0..512 {
972 sut.push(value);
973 }
974 for idx in 0..512 {
975 let maybe = sut.get(idx);
976 assert!(maybe.is_some(), "{idx} is none");
977 let actual = maybe.unwrap();
978 assert_eq!(idx, *actual as usize);
979 }
980 }
981
982 #[test]
983 fn test_clear_and_reuse_strings() {
984 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
985 for _ in 0..512 {
986 let value = ulid::Ulid::new().to_string();
987 sut.push(value);
988 }
989 assert_eq!(sut.len(), 512);
990 sut.clear();
991 assert_eq!(sut.len(), 0);
992 for _ in 0..512 {
993 let value = ulid::Ulid::new().to_string();
994 sut.push(value);
995 }
996 assert_eq!(sut.len(), 512);
997 }
999
1000 #[test]
1001 fn test_push_get_thousands_structs() {
1002 struct MyData {
1003 a: u64,
1004 b: i32,
1005 }
1006 let mut sut: ExtensibleArray<MyData> = ExtensibleArray::new();
1007 for value in 0..88_888i32 {
1008 sut.push(MyData {
1009 a: value as u64,
1010 b: value,
1011 });
1012 }
1013 assert_eq!(sut.len(), 88_888);
1014 for idx in 0..88_888i32 {
1015 let maybe = sut.get(idx as usize);
1016 assert!(maybe.is_some(), "{idx} is none");
1017 let actual = maybe.unwrap();
1018 assert_eq!(idx as u64, actual.a);
1019 assert_eq!(idx, actual.b);
1020 }
1021 }
1022
1023 #[test]
1024 fn test_from_iterator() {
1025 let mut inputs: Vec<i32> = Vec::new();
1026 for value in 0..10_000 {
1027 inputs.push(value);
1028 }
1029 let sut: ExtensibleArray<i32> = inputs.into_iter().collect();
1030 assert_eq!(sut.len(), 10_000);
1031 for idx in 0..10_000i32 {
1032 let maybe = sut.get(idx as usize);
1033 assert!(maybe.is_some(), "{idx} is none");
1034 let actual = maybe.unwrap();
1035 assert_eq!(idx, *actual);
1036 }
1037 }
1038
1039 #[test]
1040 fn test_push_get_many_ints() {
1041 let mut sut: ExtensibleArray<i32> = ExtensibleArray::new();
1042 for value in 0..1_000_000 {
1043 sut.push(value);
1044 }
1045 assert_eq!(sut.len(), 1_000_000);
1046 for idx in 0..1_000_000 {
1047 let maybe = sut.get(idx);
1048 assert!(maybe.is_some(), "{idx} is none");
1049 let actual = maybe.unwrap();
1050 assert_eq!(idx, *actual as usize);
1051 }
1052 assert_eq!(sut[99_999], 99_999);
1053 }
1054
1055 #[test]
1056 fn test_iterator() {
1057 let inputs = [
1058 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1059 ];
1060 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
1061 for item in inputs {
1062 sut.push(item.to_owned());
1063 }
1064 for (idx, elem) in sut.iter().enumerate() {
1065 assert_eq!(inputs[idx], elem);
1066 }
1067 }
1068
1069 #[test]
1070 fn test_into_iterator() {
1071 let inputs = [
1073 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1074 ];
1075 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
1076 for item in inputs {
1077 sut.push(item.to_owned());
1078 }
1079 for (idx, elem) in sut.into_iter().enumerate() {
1080 assert_eq!(inputs[idx], elem);
1081 }
1082 }
1084
1085 #[test]
1086 fn test_into_iterator_edge_case() {
1087 let inputs = [
1089 "one", "two", "three", "four", "five", "six", "seven", "eight",
1090 ];
1091 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
1092 for item in inputs {
1093 sut.push(item.to_owned());
1094 }
1095 for (idx, elem) in sut.into_iter().enumerate() {
1096 assert_eq!(inputs[idx], elem);
1097 }
1098 }
1100
1101 #[test]
1102 fn test_into_iterator_drop_empty() {
1103 let sut: ExtensibleArray<String> = ExtensibleArray::new();
1104 assert_eq!(sut.into_iter().count(), 0);
1105 }
1106
1107 #[test]
1108 fn test_into_iterator_drop_tiny() {
1109 let inputs = [
1112 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
1113 ];
1114 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
1115 for item in inputs {
1116 sut.push(item.to_owned());
1117 }
1118 for (idx, _) in sut.into_iter().enumerate() {
1119 if idx > 2 {
1120 break;
1121 }
1122 }
1123 }
1125
1126 #[test]
1127 fn test_into_iterator_drop_large() {
1128 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
1132 for _ in 0..512 {
1133 let value = ulid::Ulid::new().to_string();
1134 sut.push(value);
1135 }
1136 for (idx, _) in sut.into_iter().enumerate() {
1137 if idx >= 30 {
1138 break;
1139 }
1140 }
1141 }
1143
1144 #[test]
1145 fn test_push_get_many_instances_ints() {
1146 for _ in 0..1_000 {
1148 let mut sut: ExtensibleArray<usize> = ExtensibleArray::new();
1149 for value in 0..10_000 {
1150 sut.push(value);
1151 }
1152 assert_eq!(sut.len(), 10_000);
1153 }
1154 }
1155
1156 #[test]
1157 fn test_push_get_many_instances_strings() {
1158 for _ in 0..1_000 {
1160 let mut sut: ExtensibleArray<String> = ExtensibleArray::new();
1161 for _ in 0..1_000 {
1162 let value = ulid::Ulid::new().to_string();
1163 sut.push(value);
1164 }
1165 assert_eq!(sut.len(), 1_000);
1166 }
1167 }
1168
1169 #[test]
1170 fn test_last_segment() {
1171 assert_eq!(last_segment_for_l(1), 1);
1173 assert_eq!(last_segment_for_l(2), 4);
1174 assert_eq!(last_segment_for_l(3), 10);
1175 assert_eq!(last_segment_for_l(4), 22);
1176 assert_eq!(last_segment_for_l(5), 46);
1177 assert_eq!(last_segment_for_l(6), 94);
1178 assert_eq!(last_segment_for_l(7), 190);
1179 assert_eq!(last_segment_for_l(8), 382);
1180 assert_eq!(last_segment_for_l(9), 766);
1181 assert_eq!(last_segment_for_l(10), 1534);
1182 assert_eq!(last_segment_for_l(11), 3070);
1183 assert_eq!(last_segment_for_l(12), 6142);
1184 assert_eq!(last_segment_for_l(13), 12286);
1185 assert_eq!(last_segment_for_l(14), 24574);
1186 assert_eq!(last_segment_for_l(15), 49150);
1187 assert_eq!(last_segment_for_l(16), 98302);
1188 }
1189
1190 #[test]
1191 fn test_segment_len() {
1192 assert_eq!(datablock_capacity(1), 2);
1194 assert_eq!(datablock_capacity(2), 4);
1195 assert_eq!(datablock_capacity(3), 8);
1196 assert_eq!(datablock_capacity(4), 16);
1197 assert_eq!(datablock_capacity(5), 32);
1198 assert_eq!(datablock_capacity(6), 64);
1199 assert_eq!(datablock_capacity(7), 128);
1200 assert_eq!(datablock_capacity(8), 256);
1201 assert_eq!(datablock_capacity(9), 512);
1202 assert_eq!(datablock_capacity(10), 1024);
1203 assert_eq!(datablock_capacity(11), 2048);
1204 assert_eq!(datablock_capacity(12), 4096);
1205 assert_eq!(datablock_capacity(13), 8192);
1206 assert_eq!(datablock_capacity(14), 16384);
1207 assert_eq!(datablock_capacity(15), 32768);
1208 assert_eq!(datablock_capacity(16), 65536);
1209 }
1210
1211 #[test]
1212 fn test_mapping() {
1213 assert_eq!(mapping(0), (0, 0));
1214 assert_eq!(mapping(1), (0, 1));
1215 assert_eq!(mapping(2), (1, 0));
1216 assert_eq!(mapping(3), (1, 1));
1217 assert_eq!(mapping(4), (2, 0));
1218 assert_eq!(mapping(5), (2, 1));
1219 assert_eq!(mapping(6), (2, 2));
1220 assert_eq!(mapping(7), (2, 3));
1221 assert_eq!(mapping(8), (3, 0));
1222 assert_eq!(mapping(9), (3, 1));
1223 assert_eq!(mapping(10), (3, 2));
1224 assert_eq!(mapping(11), (3, 3));
1225 assert_eq!(mapping(12), (4, 0));
1226 assert_eq!(mapping(72), (11, 8));
1227 assert_eq!(mapping(248), (22, 8));
1228 assert_eq!(mapping(4567), (98, 87)); assert_eq!(mapping(1_048_576), (1535, 0));
1230 assert_eq!(mapping(2_000_000), (1999, 1152));
1231 assert_eq!(mapping(4_194_304), (3071, 0));
1232 assert_eq!(mapping(16_777_216), (6143, 0));
1233 assert_eq!(mapping(67_108_864), (12287, 0));
1234 assert_eq!(mapping(268_435_456), (24575, 0));
1235 assert_eq!(mapping(1_073_741_824), (49151, 0));
1236 assert_eq!(mapping(2_000_000_000), (63284, 37888));
1237 assert_eq!(mapping(2_147_483_647), (65534, 65535));
1238 assert_eq!(mapping(2_147_483_648), (65535, 0));
1239 assert_eq!(mapping(4_294_967_295), (98302, 65535));
1240 }
1241
1242 #[test]
1243 fn test_capacity() {
1244 assert_eq!(array_capacity(0), 0);
1245 assert_eq!(array_capacity(1), 2);
1246 assert_eq!(array_capacity(2), 4);
1247 assert_eq!(array_capacity(3), 8);
1248 assert_eq!(array_capacity(4), 12);
1249 assert_eq!(array_capacity(5), 16);
1250 assert_eq!(array_capacity(8), 40);
1251 assert_eq!(array_capacity(12), 80);
1252 }
1253
1254 #[test]
1255 fn test_l_for_segment() {
1256 assert_eq!(l_for_segment(0), 1);
1257 assert_eq!(l_for_segment(1), 1);
1258 assert_eq!(l_for_segment(2), 2);
1259 assert_eq!(l_for_segment(3), 2);
1260 assert_eq!(l_for_segment(4), 2);
1261 assert_eq!(l_for_segment(5), 3);
1262 assert_eq!(l_for_segment(6), 3);
1263 assert_eq!(l_for_segment(7), 3);
1264 assert_eq!(l_for_segment(8), 3);
1265 assert_eq!(l_for_segment(9), 3);
1266 assert_eq!(l_for_segment(10), 3);
1267 assert_eq!(l_for_segment(11), 4);
1268 assert_eq!(l_for_segment(12), 4);
1269 assert_eq!(l_for_segment(13), 4);
1270 assert_eq!(l_for_segment(14), 4);
1271 assert_eq!(l_for_segment(15), 4);
1272 assert_eq!(l_for_segment(16), 4);
1273 assert_eq!(l_for_segment(17), 4);
1274 assert_eq!(l_for_segment(18), 4);
1275 assert_eq!(l_for_segment(19), 4);
1276 assert_eq!(l_for_segment(20), 4);
1277 assert_eq!(l_for_segment(21), 4);
1278 assert_eq!(l_for_segment(22), 4);
1279 assert_eq!(l_for_segment(23), 5);
1280 assert_eq!(l_for_segment(47), 6);
1281 assert_eq!(l_for_segment(94), 6);
1282 assert_eq!(l_for_segment(95), 7);
1283 assert_eq!(l_for_segment(190), 7);
1284 assert_eq!(l_for_segment(191), 8);
1285 assert_eq!(l_for_segment(382), 8);
1286 assert_eq!(l_for_segment(383), 9);
1287 assert_eq!(l_for_segment(767), 10);
1288 assert_eq!(l_for_segment(1534), 10);
1289 assert_eq!(l_for_segment(1535), 11);
1290 assert_eq!(l_for_segment(3070), 11);
1291 assert_eq!(l_for_segment(3071), 12);
1292 assert_eq!(l_for_segment(6142), 12);
1293 assert_eq!(l_for_segment(6143), 13);
1294 assert_eq!(l_for_segment(12286), 13);
1295 assert_eq!(l_for_segment(12287), 14);
1296 assert_eq!(l_for_segment(24574), 14);
1297 assert_eq!(l_for_segment(24575), 15);
1298 assert_eq!(l_for_segment(49150), 15);
1299 assert_eq!(l_for_segment(49151), 16);
1300 assert_eq!(l_for_segment(98303), 17);
1301 assert_eq!(l_for_segment(196607), 18);
1302 assert_eq!(l_for_segment(393215), 19);
1303 assert_eq!(l_for_segment(786431), 20);
1304 assert_eq!(l_for_segment(1572863), 21);
1305 }
1306
1307 #[test]
1308 fn test_slots_in_segment() {
1309 assert_eq!(slots_in_segment(0), 2);
1310 assert_eq!(slots_in_segment(1), 2);
1311 assert_eq!(slots_in_segment(2), 4);
1312 assert_eq!(slots_in_segment(3), 4);
1313 assert_eq!(slots_in_segment(4), 4);
1314 assert_eq!(slots_in_segment(5), 8);
1315 assert_eq!(slots_in_segment(6), 8);
1316 assert_eq!(slots_in_segment(7), 8);
1317 assert_eq!(slots_in_segment(8), 8);
1318 assert_eq!(slots_in_segment(9), 8);
1319 assert_eq!(slots_in_segment(10), 8);
1320 assert_eq!(slots_in_segment(11), 16);
1321 assert_eq!(slots_in_segment(30), 32);
1322 assert_eq!(slots_in_segment(80), 64);
1323 assert_eq!(slots_in_segment(170), 128);
1324 assert_eq!(slots_in_segment(350), 256);
1325 assert_eq!(slots_in_segment(707), 512);
1326 assert_eq!(slots_in_segment(1400), 1024);
1327 assert_eq!(slots_in_segment(3000), 2048);
1328 assert_eq!(slots_in_segment(6000), 4096);
1329 assert_eq!(slots_in_segment(12000), 8192);
1330 assert_eq!(slots_in_segment(24000), 16384);
1331 assert_eq!(slots_in_segment(49000), 32768);
1332 assert_eq!(slots_in_segment(98000), 65536);
1333 }
1334
1335 #[test]
1336 #[should_panic(expected = "attempt to add with overflow")]
1337 fn test_slots_in_segment_bounds() {
1338 slots_in_segment(usize::MAX);
1340 }
1341
1342 #[test]
1343 fn test_capacity_for_l() {
1344 assert_eq!(capacity_for_l(1), 4);
1345 assert_eq!(capacity_for_l(2), 16);
1346 assert_eq!(capacity_for_l(3), 64);
1347 assert_eq!(capacity_for_l(4), 256);
1348 assert_eq!(capacity_for_l(5), 1024);
1349 assert_eq!(capacity_for_l(6), 4096);
1350 assert_eq!(capacity_for_l(7), 16384);
1351 assert_eq!(capacity_for_l(8), 65536);
1352 assert_eq!(capacity_for_l(9), 262_144);
1353 assert_eq!(capacity_for_l(10), 1_048_576);
1354 assert_eq!(capacity_for_l(11), 4_194_304);
1355 assert_eq!(capacity_for_l(12), 16_777_216);
1356 assert_eq!(capacity_for_l(13), 67_108_864);
1357 assert_eq!(capacity_for_l(14), 268_435_456);
1358 assert_eq!(capacity_for_l(15), 1_073_741_824);
1359 assert_eq!(capacity_for_l(16), 4_294_967_296);
1360 }
1361
1362 #[test]
1363 fn test_superblock_capacity() {
1364 assert_eq!(superblock_capacity(1), 2);
1366 assert_eq!(superblock_capacity(2), 3);
1367 assert_eq!(superblock_capacity(3), 6);
1368 assert_eq!(superblock_capacity(4), 12);
1369 assert_eq!(superblock_capacity(5), 24);
1370 assert_eq!(superblock_capacity(6), 48);
1371 assert_eq!(superblock_capacity(7), 96);
1372 assert_eq!(superblock_capacity(8), 192);
1373 assert_eq!(superblock_capacity(9), 384);
1374 assert_eq!(superblock_capacity(10), 768);
1375 assert_eq!(superblock_capacity(11), 1536);
1376 assert_eq!(superblock_capacity(12), 3072);
1377 assert_eq!(superblock_capacity(13), 6144);
1378 assert_eq!(superblock_capacity(14), 12288);
1379 assert_eq!(superblock_capacity(15), 24576);
1380 assert_eq!(superblock_capacity(16), 49152);
1381 }
1382}