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