1use std::alloc::{Layout, alloc, dealloc, handle_alloc_error};
43use std::fmt;
44use std::iter::{FromIterator, Iterator};
45use std::ops::{Index, IndexMut};
46
47const MAX_SEGMENT_COUNT: usize = 26;
58
59const SMALL_SEGMENTS_TO_SKIP: usize = 6;
63const SMALL_SEGMENTS_CAPACITY: usize = 1 << SMALL_SEGMENTS_TO_SKIP;
64
65#[inline]
67fn slots_in_segment(segment: usize) -> usize {
68 SMALL_SEGMENTS_CAPACITY << segment
69}
70
71#[inline]
73fn capacity_for_segment_count(segment: usize) -> usize {
74 (SMALL_SEGMENTS_CAPACITY << segment) - SMALL_SEGMENTS_CAPACITY
75}
76
77pub struct SegmentArray<T> {
83 count: usize,
85 used_segments: usize,
87 segments: [*mut T; MAX_SEGMENT_COUNT],
89}
90
91impl<T> SegmentArray<T> {
92 pub fn new() -> Self {
98 Self {
99 count: 0,
100 used_segments: 0,
101 segments: [std::ptr::null_mut::<T>(); MAX_SEGMENT_COUNT],
102 }
103 }
104
105 pub fn push(&mut self, value: T) {
115 if self.count >= capacity_for_segment_count(self.used_segments) {
116 assert!(
117 self.used_segments < MAX_SEGMENT_COUNT,
118 "maximum number of segments exceeded"
119 );
120 let segment_len = slots_in_segment(self.used_segments);
121 let layout = Layout::array::<T>(segment_len).expect("unexpected overflow");
124 unsafe {
125 let ptr = alloc(layout).cast::<T>();
126 if ptr.is_null() {
127 handle_alloc_error(layout);
128 }
129 self.segments[self.used_segments] = ptr;
130 }
131 self.used_segments += 1;
132 }
133
134 let segment = ((self.count >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
135 let slot = self.count - capacity_for_segment_count(segment);
136 unsafe {
137 std::ptr::write(self.segments[segment].add(slot), value);
138 }
139 self.count += 1;
140 }
141
142 fn shrink(&mut self) {
144 if self.used_segments > 0
145 && self.count <= capacity_for_segment_count(self.used_segments - 1)
146 {
147 let segment = self.used_segments - 1;
148 let segment_len = slots_in_segment(segment);
149 let layout = Layout::array::<T>(segment_len).expect("unexpected overflow");
150 unsafe {
151 dealloc(self.segments[segment] as *mut u8, layout);
152 }
153 self.segments[segment] = std::ptr::null_mut();
154 self.used_segments -= 1;
155 }
156 }
157
158 pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
165 if self.count >= capacity_for_segment_count(self.used_segments) {
166 Err(value)
167 } else {
168 self.push(value);
169 Ok(())
170 }
171 }
172
173 pub fn pop(&mut self) -> Option<T> {
180 if self.count > 0 {
181 self.count -= 1;
182 let segment = ((self.count >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
183 let slot = self.count - capacity_for_segment_count(segment);
184 let value = unsafe { Some((self.segments[segment].add(slot)).read()) };
185 self.shrink();
186 value
187 } else {
188 None
189 }
190 }
191
192 pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
200 if self.count == 0 {
201 None
202 } else if let Some(last) = self.get_mut(self.count - 1) {
203 if predicate(last) { self.pop() } else { None }
204 } else {
205 None
206 }
207 }
208
209 pub fn len(&self) -> usize {
215 self.count
216 }
217
218 pub fn capacity(&self) -> usize {
225 capacity_for_segment_count(self.used_segments)
226 }
227
228 pub fn is_empty(&self) -> bool {
234 self.count == 0
235 }
236
237 pub fn get(&self, index: usize) -> Option<&T> {
243 if index >= self.count {
244 None
245 } else {
246 let segment = ((index >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
247 let slot = index - capacity_for_segment_count(segment);
248 unsafe { (self.segments[segment].add(slot)).as_ref() }
249 }
250 }
251
252 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
258 if index >= self.count {
259 None
260 } else {
261 let segment = ((index >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
262 let slot = index - capacity_for_segment_count(segment);
263 unsafe { (self.segments[segment].add(slot)).as_mut() }
264 }
265 }
266
267 pub fn swap_remove(&mut self, index: usize) -> T {
277 if index >= self.count {
278 panic!(
279 "swap_remove index (is {index}) should be < len (is {})",
280 self.count
281 );
282 }
283 let segment = ((index >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
285 let slot = index - capacity_for_segment_count(segment);
286 unsafe {
287 let index_ptr = self.segments[segment].add(slot);
288 let value = index_ptr.read();
289 self.count -= 1;
291 let segment = ((self.count >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
292 let slot = self.count - capacity_for_segment_count(segment);
293 let last_ptr = self.segments[segment].add(slot);
294 std::ptr::copy(last_ptr, index_ptr, 1);
295 self.shrink();
296 value
297 }
298 }
299
300 pub fn iter(&self) -> SegArrayIter<'_, T> {
304 SegArrayIter {
305 array: self,
306 index: 0,
307 }
308 }
309
310 pub fn clear(&mut self) {
315 if self.count > 0 && std::mem::needs_drop::<T>() {
316 let last_segment = ((self.count >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
318 let last_slot = self.count - capacity_for_segment_count(last_segment);
319 unsafe {
320 std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(
321 self.segments[last_segment],
322 last_slot,
323 ));
324 }
325 for segment in 0..last_segment {
327 let segment_len = slots_in_segment(segment);
328 unsafe {
329 std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(
330 self.segments[segment],
331 segment_len,
332 ));
333 }
334 }
335 }
336 self.count = 0;
337
338 for segment in 0..self.used_segments {
340 if !self.segments[segment].is_null() {
341 let segment_len = slots_in_segment(segment);
342 let layout = Layout::array::<T>(segment_len).expect("unexpected overflow");
343 unsafe {
344 dealloc(self.segments[segment] as *mut u8, layout);
345 }
346 self.segments[segment] = std::ptr::null_mut();
347 }
348 }
349 self.used_segments = 0;
350 }
351}
352
353impl<T> Default for SegmentArray<T> {
354 fn default() -> Self {
355 Self::new()
356 }
357}
358
359impl<T> fmt::Display for SegmentArray<T> {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 let longest_segment = if self.used_segments > 0 {
362 slots_in_segment(self.used_segments - 1)
363 } else {
364 0
365 };
366 write!(
367 f,
368 "SegmentArray(count: {}, used_segments: {}, longest segment: {})",
369 self.count, self.used_segments, longest_segment
370 )
371 }
372}
373
374impl<T> Drop for SegmentArray<T> {
375 fn drop(&mut self) {
376 self.clear();
377 }
378}
379
380impl<T> Index<usize> for SegmentArray<T> {
381 type Output = T;
382
383 fn index(&self, index: usize) -> &Self::Output {
384 let Some(item) = self.get(index) else {
385 panic!("index out of bounds: {}", index);
386 };
387 item
388 }
389}
390
391impl<T> IndexMut<usize> for SegmentArray<T> {
392 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
393 let Some(item) = self.get_mut(index) else {
394 panic!("index out of bounds: {}", index);
395 };
396 item
397 }
398}
399
400impl<A> FromIterator<A> for SegmentArray<A> {
401 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
402 let mut arr: SegmentArray<A> = SegmentArray::new();
403 for value in iter {
404 arr.push(value)
405 }
406 arr
407 }
408}
409
410pub struct SegArrayIter<'a, T> {
412 array: &'a SegmentArray<T>,
413 index: usize,
414}
415
416impl<'a, T> Iterator for SegArrayIter<'a, T> {
417 type Item = &'a T;
418
419 fn next(&mut self) -> Option<Self::Item> {
420 let value = self.array.get(self.index);
421 self.index += 1;
422 value
423 }
424}
425
426pub struct SegArrayIntoIter<T> {
428 index: usize,
429 count: usize,
430 used_segments: usize,
431 segments: [*mut T; MAX_SEGMENT_COUNT],
432}
433
434impl<T> Iterator for SegArrayIntoIter<T> {
435 type Item = T;
436
437 fn next(&mut self) -> Option<Self::Item> {
438 if self.index < self.count {
439 let segment = ((self.index >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
440 let slot = self.index - capacity_for_segment_count(segment);
441 self.index += 1;
442 unsafe { Some((self.segments[segment].add(slot)).read()) }
443 } else {
444 None
445 }
446 }
447}
448
449impl<T> Drop for SegArrayIntoIter<T> {
450 fn drop(&mut self) {
451 if std::mem::needs_drop::<T>() {
452 let first_segment = ((self.index >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
453 let last_segment = (((self.count - 1) >> SMALL_SEGMENTS_TO_SKIP) + 1).ilog2() as usize;
454 if first_segment == last_segment {
455 let first = self.index - capacity_for_segment_count(first_segment);
457 let last = self.count - capacity_for_segment_count(first_segment);
458 if first < last {
459 let len = last - first;
460 unsafe {
461 let first: *mut T = self.segments[first_segment].add(first);
462 std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(first, len));
463 }
464 }
465 } else {
466 let first = self.index - capacity_for_segment_count(first_segment);
469 let segment_len = slots_in_segment(first_segment);
470 if segment_len < self.count {
471 unsafe {
472 let ptr: *mut T = self.segments[first_segment].add(first);
473 let len = segment_len - first;
474 std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(ptr, len));
475 }
476 }
477
478 let last_slot = self.count - capacity_for_segment_count(last_segment);
480 unsafe {
481 std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(
482 self.segments[last_segment],
483 last_slot,
484 ));
485 }
486
487 for segment in first_segment + 1..last_segment {
489 let segment_len = slots_in_segment(segment);
490 unsafe {
491 std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(
492 self.segments[segment],
493 segment_len,
494 ));
495 }
496 }
497 }
498 }
499
500 for segment in 0..self.used_segments {
502 if !self.segments[segment].is_null() {
503 let segment_len = slots_in_segment(segment);
504 let layout = Layout::array::<T>(segment_len).expect("unexpected overflow");
505 unsafe {
506 dealloc(self.segments[segment] as *mut u8, layout);
507 }
508 self.segments[segment] = std::ptr::null_mut();
509 }
510 }
511 self.index = 0;
512 self.count = 0;
513 self.used_segments = 0;
514 }
515}
516
517impl<T> IntoIterator for SegmentArray<T> {
518 type Item = T;
519 type IntoIter = SegArrayIntoIter<Self::Item>;
520
521 fn into_iter(self) -> Self::IntoIter {
522 let me = std::mem::ManuallyDrop::new(self);
523 SegArrayIntoIter {
524 index: 0,
525 count: me.count,
526 used_segments: me.used_segments,
527 segments: me.segments,
528 }
529 }
530}
531
532#[cfg(test)]
533mod tests {
534 use super::*;
535
536 #[test]
537 fn test_slots_in_segment() {
538 let expected_values = [
541 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288,
542 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456,
543 536870912, 1073741824, 2147483648,
544 ];
545 assert_eq!(expected_values.len(), MAX_SEGMENT_COUNT);
546 for (segment, item) in expected_values.iter().enumerate() {
547 assert_eq!(*item, slots_in_segment(segment));
548 }
549 }
550
551 #[test]
552 fn test_capacity_for_segment_count() {
553 let expected_values = [
560 0, 64, 192, 448, 960, 1984, 4032, 8128, 16320, 32704, 65472, 131008, 262080, 524224,
561 1048512, 2097088, 4194240, 8388544, 16777152, 33554368, 67108800, 134217664, 268435392,
562 536870848, 1073741760, 2147483584, 4294967232,
563 ];
564 assert_eq!(expected_values.len(), MAX_SEGMENT_COUNT + 1);
565 for (count, item) in expected_values.iter().enumerate() {
566 assert_eq!(*item, capacity_for_segment_count(count));
567 }
568 }
569
570 #[test]
571 fn test_push_within_capacity() {
572 let mut sut: SegmentArray<u32> = SegmentArray::new();
574 assert_eq!(sut.push_within_capacity(101), Err(101));
575 sut.push(10);
576 assert_eq!(sut.push_within_capacity(101), Ok(()));
577
578 let mut sut: SegmentArray<u32> = SegmentArray::new();
580 for value in 1..64 {
581 sut.push(value);
582 }
583 assert_eq!(sut.push_within_capacity(64), Ok(()));
584 assert_eq!(sut.push_within_capacity(65), Err(65));
585 }
586
587 #[test]
588 fn test_push_get_one_item() {
589 let item = String::from("hello world");
590 let mut sut: SegmentArray<String> = SegmentArray::new();
591 assert_eq!(sut.len(), 0);
592 assert!(sut.is_empty());
593 sut.push(item);
594 assert_eq!(sut.len(), 1);
595 assert!(!sut.is_empty());
596 let maybe = sut.get(0);
597 assert!(maybe.is_some());
598 let actual = maybe.unwrap();
599 assert_eq!("hello world", actual);
600 let missing = sut.get(10);
601 assert!(missing.is_none());
602 }
603
604 #[test]
605 fn test_push_get_several_strings() {
606 let inputs = [
607 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
608 ];
609 let mut sut: SegmentArray<String> = SegmentArray::new();
610 for item in inputs {
611 sut.push(item.to_owned());
612 }
613 assert_eq!(sut.len(), 9);
614 for (idx, item) in inputs.iter().enumerate() {
615 let maybe = sut.get(idx);
616 assert!(maybe.is_some(), "{idx} is none");
617 let actual = maybe.unwrap();
618 assert_eq!(item, actual);
619 }
620 let maybe = sut.get(10);
621 assert!(maybe.is_none());
622 assert_eq!(sut[3], "four");
623 }
624
625 #[test]
626 fn test_get_mut_index_mut() {
627 let mut sut: SegmentArray<String> = SegmentArray::new();
628 sut.push(String::from("first"));
629 sut.push(String::from("second"));
630 sut.push(String::from("third"));
631 if let Some(value) = sut.get_mut(1) {
632 value.push_str(" place");
633 } else {
634 panic!("get_mut() returned None")
635 }
636 assert_eq!(sut[1], "second place");
637 sut[2] = "third planet".into();
638 assert_eq!(sut[2], "third planet");
639 }
640
641 #[test]
642 #[should_panic(expected = "index out of bounds:")]
643 fn test_index_out_of_bounds() {
644 let mut sut: SegmentArray<i32> = SegmentArray::new();
645 sut.push(10);
646 sut.push(20);
647 let _ = sut[2];
648 }
649
650 #[test]
651 #[should_panic(expected = "index out of bounds:")]
652 fn test_index_mut_out_of_bounds() {
653 let mut sut: SegmentArray<i32> = SegmentArray::new();
654 sut.push(10);
655 sut.push(20);
656 sut[2] = 30;
657 }
658
659 #[test]
660 fn test_push_and_pop() {
661 let inputs = [
662 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
663 ];
664 let mut sut: SegmentArray<String> = SegmentArray::new();
665 assert_eq!(sut.capacity(), 0);
666 assert!(sut.pop().is_none());
667 for item in inputs {
668 sut.push(item.to_owned());
669 }
670 assert_eq!(sut.len(), 9);
671 for (idx, elem) in sut.iter().enumerate() {
672 assert_eq!(inputs[idx], elem);
673 }
674 let maybe = sut.pop();
675 assert!(maybe.is_some());
676 let value = maybe.unwrap();
677 assert_eq!(value, "nine");
678 assert_eq!(sut.len(), 8);
679 sut.push(String::from("nine"));
680 assert_eq!(sut.len(), 9);
681 for (idx, elem) in sut.iter().enumerate() {
682 assert_eq!(inputs[idx], elem);
683 }
684
685 while !sut.is_empty() {
687 sut.pop();
688 }
689 assert_eq!(sut.len(), 0);
690 assert_eq!(sut.capacity(), 0);
691 for item in inputs {
692 sut.push(item.to_owned());
693 }
694 assert_eq!(sut.len(), 9);
695 for (idx, elem) in sut.iter().enumerate() {
696 assert_eq!(inputs[idx], elem);
697 }
698 }
699
700 #[test]
701 fn test_push_many_pop_all_verify() {
702 let mut sut: SegmentArray<usize> = SegmentArray::new();
704 for value in 0..16384 {
705 sut.push(value);
706 }
707 for value in (0..16384).rev() {
708 assert_eq!(sut.pop(), Some(value));
709 }
710 assert_eq!(sut.len(), 0);
711 assert_eq!(sut.capacity(), 0);
712 }
713
714 #[test]
715 fn test_pop_if() {
716 let mut sut: SegmentArray<u32> = SegmentArray::new();
717 assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
718 for value in 0..10 {
719 sut.push(value);
720 }
721 assert!(sut.pop_if(|_| false).is_none());
722 let maybe = sut.pop_if(|v| *v == 9);
723 assert_eq!(maybe.unwrap(), 9);
724 assert!(sut.pop_if(|v| *v == 9).is_none());
725 }
726
727 #[test]
728 fn test_swap_remove_single_segment() {
729 let mut sut: SegmentArray<u32> = SegmentArray::new();
730 for value in 0..10 {
731 sut.push(value);
732 }
733 assert_eq!(sut.len(), 10);
734 let five = sut.swap_remove(5);
735 assert_eq!(five, 5);
736 assert_eq!(sut.pop(), Some(8));
737 assert_eq!(sut[5], 9);
738 }
739
740 #[test]
741 fn test_swap_remove_multiple_segments() {
742 let mut sut: SegmentArray<u32> = SegmentArray::new();
743 for value in 0..512 {
744 sut.push(value);
745 }
746 assert_eq!(sut.len(), 512);
747 let eighty = sut.swap_remove(80);
748 assert_eq!(eighty, 80);
749 assert_eq!(sut.pop(), Some(510));
750 assert_eq!(sut[80], 511);
751 }
752
753 #[test]
754 #[should_panic(expected = "swap_remove index (is 0) should be < len (is 0)")]
755 fn test_swap_remove_panic_empty() {
756 let mut sut: SegmentArray<u32> = SegmentArray::new();
757 sut.swap_remove(0);
758 }
759
760 #[test]
761 #[should_panic(expected = "swap_remove index (is 1) should be < len (is 1)")]
762 fn test_swap_remove_panic_range_edge() {
763 let mut sut: SegmentArray<u32> = SegmentArray::new();
764 sut.push(1);
765 sut.swap_remove(1);
766 }
767
768 #[test]
769 #[should_panic(expected = "swap_remove index (is 2) should be < len (is 1)")]
770 fn test_swap_remove_panic_range_exceed() {
771 let mut sut: SegmentArray<u32> = SegmentArray::new();
772 sut.push(1);
773 sut.swap_remove(2);
774 }
775
776 #[test]
777 fn test_push_get_thousands_structs() {
778 struct MyData {
779 a: u64,
780 b: i32,
781 }
782 let mut sut: SegmentArray<MyData> = SegmentArray::new();
783 for value in 0..88_888i32 {
784 sut.push(MyData {
785 a: value as u64,
786 b: value,
787 });
788 }
789 assert_eq!(sut.len(), 88_888);
790 for idx in 0..88_888i32 {
791 let maybe = sut.get(idx as usize);
792 assert!(maybe.is_some(), "{idx} is none");
793 let actual = maybe.unwrap();
794 assert_eq!(idx as u64, actual.a);
795 assert_eq!(idx, actual.b);
796 }
797 }
798
799 #[test]
800 fn test_push_get_hundred_ints() {
801 let mut sut: SegmentArray<i32> = SegmentArray::new();
802 for value in 0..100 {
803 sut.push(value);
804 }
805 assert_eq!(sut.len(), 100);
806 for idx in 0..100 {
807 let maybe = sut.get(idx);
808 assert!(maybe.is_some(), "{idx} is none");
809 let actual = maybe.unwrap();
810 assert_eq!(idx, *actual as usize);
811 }
812 assert_eq!(sut[99], 99);
813 }
814
815 #[test]
816 fn test_len_and_capacity() {
817 let mut sut: SegmentArray<i32> = SegmentArray::new();
818 assert_eq!(sut.len(), 0);
819 assert_eq!(sut.capacity(), 0);
820 for value in 0..100 {
821 sut.push(value);
822 }
823 assert_eq!(sut.len(), 100);
824 assert_eq!(sut.capacity(), 192);
825 }
826
827 #[test]
828 fn test_clear_and_reuse_tiny() {
829 let inputs = [
831 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
832 ];
833 let mut sut: SegmentArray<String> = SegmentArray::new();
834 for item in inputs {
835 sut.push(item.to_owned());
836 }
837 assert_eq!(sut.len(), 9);
838 sut.clear();
839 assert_eq!(sut.len(), 0);
840 for item in inputs {
841 sut.push(item.to_owned());
842 }
843 assert_eq!(sut.len(), 9);
844 }
846
847 #[test]
848 fn test_clear_and_reuse_ints() {
849 let mut sut: SegmentArray<i32> = SegmentArray::new();
850 for value in 0..512 {
851 sut.push(value);
852 }
853 assert_eq!(sut.len(), 512);
854 sut.clear();
855 assert_eq!(sut.len(), 0);
856 for value in 0..512 {
857 sut.push(value);
858 }
859 for idx in 0..512 {
860 let maybe = sut.get(idx);
861 assert!(maybe.is_some(), "{idx} is none");
862 let actual = maybe.unwrap();
863 assert_eq!(idx, *actual as usize);
864 }
865 }
866
867 #[test]
868 fn test_clear_and_reuse_strings() {
869 let mut sut: SegmentArray<String> = SegmentArray::new();
870 for _ in 0..512 {
871 let value = ulid::Ulid::new().to_string();
872 sut.push(value);
873 }
874 assert_eq!(sut.len(), 512);
875 sut.clear();
876 assert_eq!(sut.len(), 0);
877 for _ in 0..512 {
878 let value = ulid::Ulid::new().to_string();
879 sut.push(value);
880 }
881 assert_eq!(sut.len(), 512);
882 }
884
885 #[test]
886 fn test_push_get_many_ints() {
887 let mut sut: SegmentArray<i32> = SegmentArray::new();
888 for value in 0..1_000_000 {
889 sut.push(value);
890 }
891 assert_eq!(sut.len(), 1_000_000);
892 for idx in 0..1_000_000 {
893 let maybe = sut.get(idx);
894 assert!(maybe.is_some(), "{idx} is none");
895 let actual = maybe.unwrap();
896 assert_eq!(idx, *actual as usize);
897 }
898 assert_eq!(sut[99_999], 99_999);
899 }
900
901 #[test]
902 fn test_array_iterator() {
903 let inputs = [
904 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
905 ];
906 let mut sut: SegmentArray<String> = SegmentArray::new();
907 for item in inputs {
908 sut.push(item.to_owned());
909 }
910 for (idx, elem) in sut.iter().enumerate() {
911 assert_eq!(inputs[idx], elem);
912 }
913 }
914
915 #[test]
916 fn test_array_intoiterator() {
917 let inputs = [
919 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
920 ];
921 let mut sut: SegmentArray<String> = SegmentArray::new();
922 for item in inputs {
923 sut.push(item.to_owned());
924 }
925 for (idx, elem) in sut.into_iter().enumerate() {
926 assert_eq!(inputs[idx], elem);
927 }
928 }
930
931 #[test]
932 fn test_array_intoiterator_drop_tiny() {
933 let inputs = [
936 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
937 ];
938 let mut sut: SegmentArray<String> = SegmentArray::new();
939 for item in inputs {
940 sut.push(item.to_owned());
941 }
942 for (idx, _) in sut.into_iter().enumerate() {
943 if idx > 2 {
944 break;
945 }
946 }
947 }
949
950 #[test]
951 fn test_array_intoiterator_drop_large() {
952 let mut sut: SegmentArray<String> = SegmentArray::new();
956 for _ in 0..512 {
957 let value = ulid::Ulid::new().to_string();
958 sut.push(value);
959 }
960 for (idx, _) in sut.into_iter().enumerate() {
961 if idx >= 30 {
962 break;
963 }
964 }
965 }
967
968 #[test]
969 fn test_array_fromiterator() {
970 let mut inputs: Vec<i32> = Vec::new();
971 for value in 0..10_000 {
972 inputs.push(value);
973 }
974 let sut: SegmentArray<i32> = inputs.into_iter().collect();
975 assert_eq!(sut.len(), 10_000);
976 for idx in 0..10_000i32 {
977 let maybe = sut.get(idx as usize);
978 assert!(maybe.is_some(), "{idx} is none");
979 let actual = maybe.unwrap();
980 assert_eq!(idx, *actual);
981 }
982 }
983
984 #[test]
985 fn test_push_get_many_instances_ints() {
986 for _ in 0..1_000 {
988 let mut sut: SegmentArray<usize> = SegmentArray::new();
989 for value in 0..10_000 {
990 sut.push(value);
991 }
992 assert_eq!(sut.len(), 10_000);
993 }
994 }
995
996 #[test]
997 fn test_push_get_many_instances_strings() {
998 for _ in 0..1_000 {
1000 let mut sut: SegmentArray<String> = SegmentArray::new();
1001 for _ in 0..1_000 {
1002 let value = ulid::Ulid::new().to_string();
1003 sut.push(value);
1004 }
1005 assert_eq!(sut.len(), 1_000);
1006 }
1007 }
1008}