1use alloc::alloc::{alloc, dealloc, handle_alloc_error};
61use core::alloc::Layout;
62use core::fmt;
63use core::mem::{MaybeUninit, align_of, needs_drop, size_of};
64use core::ptr::{NonNull, null_mut};
65use embed_collections::CACHE_LINE_SIZE;
66
67pub struct SegList<T> {
86 tail: NonNull<SegHeader<T>>,
88 count: usize,
90}
91
92unsafe impl<T: Send> Send for SegList<T> {}
93unsafe impl<T: Send> Sync for SegList<T> {}
94
95impl<T> SegList<T> {
96 pub fn new() -> Self {
98 let mut seg = unsafe { Segment::<T>::alloc(null_mut(), null_mut(), true) };
99 let header_ptr = seg.header.as_ptr();
100 let header = seg.get_header_mut();
101 header.next = header_ptr;
103 Self { tail: seg.header, count: 0 }
104 }
105
106 #[inline(always)]
108 pub fn is_empty(&self) -> bool {
109 self.count == 0
110 }
111
112 #[inline(always)]
114 pub const fn segment_cap() -> usize {
115 Segment::<T>::base_cap()
116 }
117
118 #[inline(always)]
120 pub fn len(&self) -> usize {
121 self.count
122 }
123
124 #[inline]
126 pub fn push(&mut self, item: T) {
127 unsafe {
128 let mut tail_seg = Segment::from_raw(self.tail);
129 if tail_seg.is_full() {
130 let tail_ptr = tail_seg.header.as_ptr();
131 let cur = tail_seg.get_header_mut();
132 let new_seg = Segment::alloc(tail_ptr, cur.next, false);
134 cur.next = new_seg.header.as_ptr();
135 self.tail = new_seg.header;
136 tail_seg = new_seg;
137 }
138 tail_seg.push(item);
139 }
140 self.count += 1;
141 }
142
143 #[inline]
145 pub fn pop(&mut self) -> Option<T> {
146 if self.count == 0 {
147 return None;
148 }
149 unsafe {
150 let mut tail_seg = Segment::from_raw(self.tail);
151 let (item, is_empty) = tail_seg.pop();
152 if is_empty {
153 let cur = tail_seg.get_header_mut();
154 let first_ptr = cur.next;
155 let cur_prev = cur.prev;
156 if self.tail.as_ptr() != first_ptr && !cur_prev.is_null() {
157 self.tail = NonNull::new_unchecked(cur_prev);
159 (*self.tail.as_ptr()).next = first_ptr;
160 tail_seg.dealloc();
161 }
162 }
164 self.count -= 1;
165 Some(item)
166 }
167 }
168
169 #[inline(always)]
171 fn break_first_node(&mut self) -> Segment<T> {
172 let tail_header = unsafe { self.tail.as_mut() };
173 let first = tail_header.next;
174 tail_header.next = null_mut();
175 unsafe { Segment::from_raw(NonNull::new_unchecked(first)) }
176 }
177
178 #[inline(always)]
179 fn first_ptr(&self) -> NonNull<SegHeader<T>> {
180 unsafe {
183 let tail_header = self.tail.as_ref();
184 let first = tail_header.next;
185 NonNull::new_unchecked(first)
186 }
187 }
188
189 #[inline]
191 pub fn iter(&self) -> SegListIter<'_, T> {
192 let first_seg = unsafe { Segment::from_raw(self.first_ptr()) };
193 SegListIter {
194 base: IterBase { cur: first_seg, cur_idx: 0, remaining: self.count, forward: true },
195 _marker: core::marker::PhantomData,
196 }
197 }
198
199 #[inline]
201 pub fn iter_rev(&self) -> SegListIter<'_, T> {
202 let tail_seg = unsafe { Segment::from_raw(self.tail) };
203 let tail_header = tail_seg.get_header();
204 let start_idx = if tail_header.count > 0 { tail_header.count as usize - 1 } else { 0 };
205 SegListIter {
206 base: IterBase {
207 cur: tail_seg,
208 cur_idx: start_idx,
209 remaining: self.count,
210 forward: false,
211 },
212 _marker: core::marker::PhantomData,
213 }
214 }
215
216 #[inline]
218 pub fn iter_mut(&mut self) -> SegListIterMut<'_, T> {
219 let first_seg = unsafe { Segment::from_raw(self.first_ptr()) };
220 SegListIterMut {
221 base: IterBase { cur: first_seg, cur_idx: 0, remaining: self.count, forward: true },
222 _marker: core::marker::PhantomData,
223 }
224 }
225
226 #[inline]
228 pub fn iter_mut_rev(&mut self) -> SegListIterMut<'_, T> {
229 let tail_seg = unsafe { Segment::from_raw(self.tail) };
230 let tail_header = tail_seg.get_header();
231 let start_idx = if tail_header.count > 0 { tail_header.count as usize - 1 } else { 0 };
232 SegListIterMut {
233 base: IterBase {
234 cur: tail_seg,
235 cur_idx: start_idx,
236 remaining: self.count,
237 forward: false,
238 },
239 _marker: core::marker::PhantomData,
240 }
241 }
242
243 pub fn into_iter_rev(mut self) -> SegListIntoIter<T> {
245 let mut first = self.break_first_node();
247 let remaining = self.count;
248 let (cur, start_idx) = if self.count == 0 {
249 unsafe {
250 first.dealloc();
251 }
252 (None, 0)
253 } else {
254 let tail_seg = unsafe { Segment::from_raw(self.tail) };
255 let tail_header = tail_seg.get_header();
256 let start_idx = if tail_header.count > 0 { tail_header.count as usize - 1 } else { 0 };
257 (Some(tail_seg), start_idx)
258 };
259 core::mem::forget(self);
260 SegListIntoIter { cur, cur_idx: start_idx, forward: false, remaining }
261 }
262
263 #[inline]
265 pub fn first(&self) -> Option<&T> {
266 if self.count == 0 {
267 return None;
268 }
269 unsafe {
272 let first_seg = Segment::from_raw(self.first_ptr());
273 Some((*first_seg.item_ptr(0)).assume_init_ref())
274 }
275 }
276
277 #[inline]
279 pub fn first_mut(&self) -> Option<&T> {
280 if self.count == 0 {
281 return None;
282 }
283 unsafe {
286 let first_seg = Segment::from_raw(self.first_ptr());
287 Some((*first_seg.item_ptr(0)).assume_init_mut())
288 }
289 }
290
291 #[inline]
293 pub fn last(&self) -> Option<&T> {
294 unsafe {
296 let tail_seg = Segment::from_raw(self.tail);
297 let header = tail_seg.get_header();
298 if header.count == 0 {
299 return None;
300 }
301 let idx = (header.count - 1) as usize;
302 Some((*tail_seg.item_ptr(idx)).assume_init_ref())
303 }
304 }
305
306 #[inline]
308 pub fn last_mut(&mut self) -> Option<&mut T> {
309 unsafe {
311 let tail_seg = Segment::from_raw(self.tail);
312 let header = tail_seg.get_header();
313 if header.count == 0 {
314 return None;
315 }
316 let idx = (header.count - 1) as usize;
317 Some((*tail_seg.item_ptr(idx)).assume_init_mut())
318 }
319 }
320
321 #[inline(always)]
323 pub fn clear(&mut self) {
324 if self.count == 0 {
325 return;
326 }
327 unsafe {
328 let tail_header = self.tail.as_mut();
329 let first = tail_header.next;
330 let mut cur = Segment::from_raw(self.tail);
331 loop {
332 let next = cur.get_header().prev;
333 if next.is_null() {
334 if needs_drop::<T>() {
335 cur.drop_items();
336 }
337 self.count = 0;
338 let header = cur.get_header_mut();
339 header.count = 0;
340 header.next = first;
341 self.tail = NonNull::new_unchecked(first);
342 return;
343 } else {
344 cur.dealloc_with_items();
345 cur = Segment::from_raw(NonNull::new_unchecked(next));
346 }
347 }
348 }
349 }
350}
351
352impl<T> Default for SegList<T> {
353 fn default() -> Self {
354 Self::new()
355 }
356}
357
358impl<T> Drop for SegList<T> {
359 fn drop(&mut self) {
360 let mut cur = self.break_first_node();
362 loop {
363 let next = cur.get_header().next;
365 unsafe { cur.dealloc_with_items() };
366 if next.is_null() {
367 break;
368 }
369 cur = unsafe { Segment::from_raw(NonNull::new_unchecked(next)) };
370 }
371 }
372}
373
374impl<T> IntoIterator for SegList<T> {
375 type Item = T;
376 type IntoIter = SegListIntoIter<T>;
377
378 #[inline(always)]
379 fn into_iter(mut self) -> Self::IntoIter {
380 let mut first = self.break_first_node();
382 let remaining = self.count;
383 let cur = if self.count == 0 {
384 unsafe {
385 first.dealloc();
386 }
387 None
388 } else {
389 Some(first)
390 };
391 core::mem::forget(self);
393 SegListIntoIter { cur, cur_idx: 0, forward: true, remaining }
394 }
395}
396
397impl<'a, T> IntoIterator for &'a SegList<T> {
398 type Item = &'a T;
399 type IntoIter = SegListIter<'a, T>;
400
401 #[inline(always)]
402 fn into_iter(self) -> Self::IntoIter {
403 self.iter()
404 }
405}
406
407impl<'a, T> IntoIterator for &'a mut SegList<T> {
408 type Item = &'a mut T;
409 type IntoIter = SegListIterMut<'a, T>;
410
411 #[inline(always)]
412 fn into_iter(self) -> Self::IntoIter {
413 self.iter_mut()
414 }
415}
416
417impl<T: fmt::Debug> fmt::Debug for SegList<T> {
418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
419 f.debug_struct("SegList").field("len", &self.len()).finish()
420 }
421}
422
423#[repr(C)]
425struct SegHeader<T> {
426 count: u32,
428 cap: u32,
430 prev: *mut SegHeader<T>,
431 next: *mut SegHeader<T>,
433 _marker: core::marker::PhantomData<T>,
434}
435
436struct Segment<T> {
438 header: NonNull<SegHeader<T>>,
440}
441
442unsafe impl<T: Send> Send for Segment<T> {}
443
444impl<T> Segment<T> {
445 const DATA_OFFSET: usize = Self::calc_data_offset();
447
448 const BASE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 2);
451
452 const LARGE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 4);
455
456 const fn calc_data_offset() -> usize {
458 let mut data_offset = size_of::<SegHeader<T>>();
459 let t_size = size_of::<T>();
460 let t_align = align_of::<MaybeUninit<T>>();
461
462 if t_size != 0 {
463 data_offset = (data_offset + t_align - 1) & !(t_align - 1);
464 }
465 data_offset
466 }
467
468 const fn calc_layout_const(cache_line: usize) -> (usize, Layout) {
470 let t_size = size_of::<T>();
471 let data_offset = Self::DATA_OFFSET;
472 let capacity;
473 let final_alloc_size;
474 let final_align;
475
476 if t_size == 0 {
477 capacity = 1024;
479 final_alloc_size = cache_line;
480 final_align = cache_line;
481 } else {
482 let min_elements = 2;
483 let min_required_size = data_offset + (t_size * min_elements);
484 let alloc_size = (min_required_size + cache_line - 1) & !(cache_line - 1);
485 final_align = if cache_line > align_of::<MaybeUninit<T>>() {
486 cache_line
487 } else {
488 align_of::<MaybeUninit<T>>()
489 };
490 final_alloc_size = (alloc_size + final_align - 1) & !(final_align - 1);
491 capacity = (final_alloc_size - data_offset) / t_size;
492 assert!(capacity >= min_elements);
494 }
495
496 match Layout::from_size_align(final_alloc_size, final_align) {
497 Ok(l) => (capacity, l),
498 Err(_) => panic!("Invalid layout"),
499 }
500 }
501
502 #[inline(always)]
504 const fn base_cap() -> usize {
505 Self::BASE_LAYOUT.0
506 }
507
508 #[inline(always)]
510 const fn large_cap() -> usize {
511 Self::LARGE_LAYOUT.0
512 }
513
514 #[inline(always)]
516 const fn data_offset() -> usize {
517 Self::DATA_OFFSET
518 }
519
520 #[inline]
523 unsafe fn alloc(prev: *mut SegHeader<T>, next: *mut SegHeader<T>, is_first: bool) -> Self {
524 let (cap, layout) = if is_first {
525 (Self::base_cap() as u32, Self::BASE_LAYOUT.1)
526 } else {
527 (Self::large_cap() as u32, Self::LARGE_LAYOUT.1)
528 };
529 let ptr: *mut u8 = unsafe { alloc(layout) };
530 if ptr.is_null() {
531 handle_alloc_error(layout);
532 }
533 unsafe {
534 let p = NonNull::new_unchecked(ptr as *mut SegHeader<T>);
535 let header = p.as_ptr();
536 (*header).count = 0;
538 (*header).cap = cap;
539 (*header).prev = prev;
540 (*header).next = next;
541 Self::from_raw(p)
542 }
543 }
544
545 #[inline(always)]
546 unsafe fn drop_items(&self) {
547 unsafe {
548 for i in 0..self.len() {
549 (*self.item_ptr(i)).assume_init_drop();
550 }
551 }
552 }
553
554 #[inline(always)]
555 unsafe fn dealloc_with_items(&mut self) {
556 unsafe {
557 if needs_drop::<T>() {
558 self.drop_items();
559 }
560 self.dealloc();
561 }
562 }
563
564 #[inline(always)]
565 unsafe fn dealloc(&mut self) {
566 unsafe {
568 let cap = (*self.header.as_ptr()).cap as usize;
569 let layout =
570 if cap == Self::base_cap() { Self::BASE_LAYOUT.1 } else { Self::LARGE_LAYOUT.1 };
571 dealloc(self.header.as_ptr() as *mut u8, layout);
572 }
573 }
574
575 #[inline(always)]
576 unsafe fn from_raw(header: NonNull<SegHeader<T>>) -> Self {
577 Self { header }
578 }
579
580 #[inline(always)]
582 fn len(&self) -> usize {
583 unsafe { (*self.header.as_ptr()).count as usize }
584 }
585
586 #[inline(always)]
587 fn get_header(&self) -> &SegHeader<T> {
588 unsafe { self.header.as_ref() }
589 }
590
591 #[inline(always)]
592 fn get_header_mut(&mut self) -> &mut SegHeader<T> {
593 unsafe { self.header.as_mut() }
594 }
595
596 #[inline(always)]
598 fn is_empty(&self) -> bool {
599 self.len() == 0
600 }
601
602 #[inline(always)]
604 fn is_full(&self) -> bool {
605 let header = self.get_header();
606 header.count >= header.cap
607 }
608
609 #[inline]
611 fn item_ptr(&self, index: usize) -> *mut MaybeUninit<T> {
612 unsafe {
613 let items =
614 (self.header.as_ptr() as *mut u8).add(Self::data_offset()) as *mut MaybeUninit<T>;
615 items.add(index)
616 }
617 }
618
619 #[inline]
621 fn push(&mut self, item: T) {
622 debug_assert!(!self.is_full());
623 let idx = self.get_header().count as usize;
624 unsafe {
625 (*self.item_ptr(idx)).write(item);
626 }
627 self.get_header_mut().count = (idx + 1) as u32;
628 }
629
630 #[inline]
632 fn pop(&mut self) -> (T, bool) {
633 debug_assert!(!self.is_empty());
634 let idx = self.get_header().count - 1;
635 let item = unsafe { (*self.item_ptr(idx as usize)).assume_init_read() };
636 self.get_header_mut().count = idx;
637 (item, idx == 0)
638 }
639}
640
641struct IterBase<T> {
645 cur: Segment<T>,
646 cur_idx: usize,
647 remaining: usize,
648 forward: bool,
649}
650
651impl<T> IterBase<T> {
652 #[inline]
654 fn next(&mut self) -> Option<*mut MaybeUninit<T>> {
655 if self.remaining == 0 {
656 return None;
657 }
658 self.remaining -= 1;
659
660 if self.forward {
661 let cur_header = self.cur.get_header();
662 let idx = if self.cur_idx >= cur_header.count as usize {
663 let next = cur_header.next;
664 self.cur = unsafe { Segment::from_raw(NonNull::new_unchecked(next)) };
665 self.cur_idx = 1;
666 0
667 } else {
668 let _idx = self.cur_idx;
669 self.cur_idx = _idx + 1;
670 _idx
671 };
672 Some(self.cur.item_ptr(idx))
673 } else {
674 let idx = self.cur_idx;
675 let item_ptr = self.cur.item_ptr(idx);
676 if self.cur_idx == 0 {
677 let cur_header = self.cur.get_header();
678 if !cur_header.prev.is_null() {
679 self.cur =
680 unsafe { Segment::from_raw(NonNull::new_unchecked(cur_header.prev)) };
681 let prev_header = self.cur.get_header();
682 self.cur_idx = prev_header.count as usize - 1;
683 }
684 } else {
685 self.cur_idx -= 1;
686 }
687 Some(item_ptr)
688 }
689 }
690
691 #[inline]
692 fn size_hint(&self) -> (usize, Option<usize>) {
693 (self.remaining, Some(self.remaining))
694 }
695}
696
697pub struct SegListIter<'a, T> {
699 base: IterBase<T>,
700 _marker: core::marker::PhantomData<&'a T>,
701}
702
703impl<'a, T> Iterator for SegListIter<'a, T> {
704 type Item = &'a T;
705
706 #[inline]
707 fn next(&mut self) -> Option<Self::Item> {
708 self.base.next().map(|ptr| unsafe { (*ptr).assume_init_ref() })
709 }
710
711 #[inline]
712 fn size_hint(&self) -> (usize, Option<usize>) {
713 self.base.size_hint()
714 }
715}
716
717impl<'a, T> ExactSizeIterator for SegListIter<'a, T> {}
718
719pub struct SegListIterMut<'a, T> {
721 base: IterBase<T>,
722 _marker: core::marker::PhantomData<&'a mut T>,
723}
724
725impl<'a, T> Iterator for SegListIterMut<'a, T> {
726 type Item = &'a mut T;
727
728 #[inline]
729 fn next(&mut self) -> Option<Self::Item> {
730 self.base.next().map(|ptr| unsafe { (*ptr).assume_init_mut() })
731 }
732
733 #[inline]
734 fn size_hint(&self) -> (usize, Option<usize>) {
735 self.base.size_hint()
736 }
737}
738
739impl<'a, T> ExactSizeIterator for SegListIterMut<'a, T> {}
740
741pub struct SegListIntoIter<T> {
744 cur: Option<Segment<T>>,
745 cur_idx: usize,
746 forward: bool,
747 remaining: usize,
748}
749
750impl<T> Iterator for SegListIntoIter<T> {
751 type Item = T;
752
753 #[inline]
754 fn next(&mut self) -> Option<Self::Item> {
755 let cur_seg = self.cur.as_mut()?;
756 self.remaining -= 1;
757 unsafe {
758 let item = (*cur_seg.item_ptr(self.cur_idx)).assume_init_read();
759 let header = cur_seg.get_header();
760 if self.forward {
761 let next_idx = self.cur_idx + 1;
762 if next_idx >= header.count as usize {
763 let next = header.next;
764 cur_seg.dealloc();
765 if next.is_null() {
766 self.cur = None;
767 } else {
768 self.cur = Some(Segment::from_raw(NonNull::new_unchecked(next)));
769 self.cur_idx = 0;
770 }
771 } else {
772 self.cur_idx = next_idx;
773 }
774 } else if self.cur_idx == 0 {
775 let prev = header.prev;
776 cur_seg.dealloc();
777 if prev.is_null() {
778 self.cur = None;
779 } else {
780 let _cur = Segment::from_raw(NonNull::new_unchecked(prev));
781 self.cur_idx = _cur.get_header().count as usize - 1;
782 self.cur = Some(_cur);
783 }
784 } else {
785 self.cur_idx -= 1;
786 }
787 Some(item)
788 }
789 }
790
791 #[inline]
792 fn size_hint(&self) -> (usize, Option<usize>) {
793 (self.remaining, Some(self.remaining))
794 }
795}
796
797impl<T> ExactSizeIterator for SegListIntoIter<T> {}
798
799impl<T> Drop for SegListIntoIter<T> {
800 fn drop(&mut self) {
801 if let Some(mut cur) = self.cur.take() {
802 unsafe {
803 if self.forward {
804 let header = cur.get_header();
806 let mut next = header.next;
807 if needs_drop::<T>() {
809 for i in self.cur_idx..header.count as usize {
810 (*cur.item_ptr(i)).assume_init_drop();
811 }
812 }
813 cur.dealloc();
814 while !next.is_null() {
815 cur = Segment::from_raw(NonNull::new_unchecked(next));
816 next = cur.get_header().next;
817 cur.dealloc_with_items();
818 }
819 } else {
820 let mut prev = cur.get_header().prev;
822 if needs_drop::<T>() {
824 for i in 0..=self.cur_idx {
825 (*cur.item_ptr(i)).assume_init_drop();
826 }
827 }
828 cur.dealloc();
829 while !prev.is_null() {
830 cur = Segment::from_raw(NonNull::new_unchecked(prev));
831 prev = cur.get_header().prev;
832 cur.dealloc_with_items();
833 }
834 }
835 }
836 }
837 }
838}
839
840#[cfg(test)]
841mod tests {
842 use super::*;
843 use embed_collections_test::{CounterI32, alive_count, reset_alive_count};
844
845 #[test]
846 fn test_multiple_segments() {
847 let mut list: SegList<i32> = SegList::new();
848 if CACHE_LINE_SIZE == 128 {
849 assert_eq!(Segment::<i32>::base_cap(), 26);
850 }
851
852 for i in 0..100 {
853 list.push(i);
854 }
855
856 assert_eq!(list.len(), 100);
857
858 for i in (0..100).rev() {
859 assert_eq!(list.pop(), Some(i));
860 }
861
862 assert_eq!(list.pop(), None);
863 }
864
865 #[test]
866 fn test_iter_single_segment() {
867 let mut list: SegList<i32> = SegList::new();
869
870 for i in 0..10 {
871 list.push(i);
872 }
873 assert_eq!(list.first(), Some(&0));
874 assert_eq!(list.last(), Some(&9));
875
876 let collected: Vec<i32> = list.iter().copied().collect();
878 assert_eq!(collected, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
879
880 for item in list.iter_mut() {
882 *item *= 2;
883 }
884 assert_eq!(list.first(), Some(&0));
885 assert_eq!(list.last(), Some(&18));
886
887 let collected: Vec<i32> = list.iter().copied().collect();
889 assert_eq!(collected, vec![0, 2, 4, 6, 8, 10, 12, 14, 16, 18]);
890
891 for i in (0..10).rev() {
893 assert_eq!(list.pop(), Some(i * 2));
894 }
895 assert_eq!(list.pop(), None);
896 assert!(list.is_empty());
897 }
898
899 #[test]
900 fn test_iter_multi_segment() {
901 let mut list: SegList<i32> = SegList::new();
903
904 for i in 0..200 {
905 list.push(i * 10);
906 }
907 assert_eq!(list.first(), Some(&0));
908 assert_eq!(list.last(), Some(&1990));
909
910 let collected: Vec<i32> = list.iter().copied().collect();
912 let expected: Vec<i32> = (0..200).map(|i| i * 10).collect();
913 assert_eq!(collected, expected);
914
915 for item in list.iter_mut() {
917 *item += 1;
918 }
919 assert_eq!(list.first(), Some(&1));
920 assert_eq!(list.last(), Some(&1991));
921
922 let collected: Vec<i32> = list.iter().copied().collect();
924 let expected: Vec<i32> = (0..200).map(|i| i * 10 + 1).collect();
925 assert_eq!(collected, expected);
926
927 for i in (0..200).rev() {
929 assert_eq!(list.pop(), Some(i * 10 + 1));
930 }
931 assert_eq!(list.pop(), None);
932 assert!(list.is_empty());
933 }
934
935 #[test]
936 fn test_into_iter() {
937 let cap = Segment::<CounterI32>::base_cap();
939
940 {
942 reset_alive_count();
943 {
944 let mut list: SegList<CounterI32> = SegList::new();
945 for i in 0..5 {
947 list.push(CounterI32::new(i));
948 }
949 assert!(list.len() < cap);
950
951 let drained: Vec<i32> = list.into_iter().map(|d| *d).collect();
953 assert_eq!(drained, vec![0, 1, 2, 3, 4]);
954 }
955 assert_eq!(alive_count(), 0);
957 }
958
959 {
961 reset_alive_count();
962 {
963 let mut list: SegList<CounterI32> = SegList::new();
964 let total = cap * 2 + 5;
966 for i in 0..total {
967 list.push(CounterI32::new(i as i32));
968 }
969 assert_eq!(alive_count(), cap * 2 + 5);
970
971 let drain_count = cap / 2;
973 let mut drain_iter = list.into_iter();
974 for i in 0..drain_count {
975 assert_eq!(*drain_iter.next().unwrap(), i as i32);
976 }
977 drop(drain_iter);
979 }
980 assert_eq!(alive_count(), 0);
982 }
983
984 {
986 reset_alive_count();
987 {
988 let mut list: SegList<CounterI32> = SegList::new();
989 let total = cap * 2 + 3;
991 for i in 0..total {
992 list.push(CounterI32::new(i as i32));
993 }
994 assert_eq!(alive_count(), cap * 2 + 3);
995
996 let mut drain_iter = list.into_iter();
998 for i in 0..cap {
999 assert_eq!(*drain_iter.next().unwrap(), i as i32);
1000 }
1001 drop(drain_iter);
1003 }
1004 assert_eq!(alive_count(), 0);
1006 }
1007 }
1008
1009 #[test]
1010 fn test_drop_single_segment() {
1011 reset_alive_count();
1012 {
1013 let mut list: SegList<CounterI32> = SegList::new();
1014 let cap = Segment::<CounterI32>::base_cap();
1015
1016 for i in 0..5 {
1018 list.push(CounterI32::new(i));
1019 }
1020 assert!(list.len() < cap);
1021 assert_eq!(alive_count(), 5);
1022
1023 }
1025
1026 assert_eq!(alive_count(), 0);
1027 }
1028
1029 #[test]
1030 fn test_drop_multi_segment() {
1031 let cap = Segment::<CounterI32>::base_cap();
1032 reset_alive_count();
1033 {
1034 let mut list: SegList<CounterI32> = SegList::new();
1035
1036 let total = cap * 2 + 10;
1038 for i in 0..total {
1039 list.push(CounterI32::new(i as i32));
1040 }
1041 assert_eq!(alive_count(), cap * 2 + 10);
1042 }
1044 assert_eq!(alive_count(), 0);
1045 }
1046
1047 #[test]
1048 fn test_clear_1_segment() {
1049 reset_alive_count();
1050 {
1051 let mut list: SegList<CounterI32> = SegList::new();
1052 let base_cap = Segment::<CounterI32>::base_cap();
1053
1054 for i in 0..base_cap as i32 {
1055 list.push(CounterI32::new(i));
1056 }
1057 assert_eq!(alive_count(), base_cap);
1058 list.clear();
1059 assert!(list.is_empty());
1060 assert_eq!(list.len(), 0);
1061 assert!(list.pop().is_none());
1062 }
1063 assert_eq!(alive_count(), 0);
1064 }
1065
1066 #[test]
1067 fn test_clear_2_segment() {
1068 reset_alive_count();
1069 {
1070 let mut list: SegList<CounterI32> = SegList::new();
1071
1072 let count = Segment::<CounterI32>::base_cap() + Segment::<CounterI32>::large_cap();
1073 for i in 0..count as i32 {
1074 list.push(CounterI32::new(i));
1075 }
1076 assert_eq!(alive_count(), count);
1077 list.clear();
1078 assert!(list.is_empty());
1079 assert_eq!(list.len(), 0);
1080 assert!(list.pop().is_none());
1081 }
1082 assert_eq!(alive_count(), 0);
1083 }
1084
1085 #[test]
1086 fn test_clear_3_segment() {
1087 reset_alive_count();
1088 let mut list: SegList<CounterI32> = SegList::new();
1089
1090 let count = Segment::<CounterI32>::base_cap() + Segment::<CounterI32>::large_cap() * 2;
1091 for i in 0..count as i32 {
1092 list.push(CounterI32::new(i));
1093 }
1094 assert_eq!(alive_count(), count);
1095 list.clear();
1096 assert!(list.is_empty());
1097 assert_eq!(list.len(), 0);
1098 assert!(list.pop().is_none());
1099 assert_eq!(alive_count(), 0);
1100 }
1101
1102 #[derive(Debug, Clone, Copy, PartialEq)]
1104 struct LargeStruct {
1105 data: [u64; 16], }
1107
1108 impl LargeStruct {
1109 fn new(val: u64) -> Self {
1110 Self { data: [val; 16] }
1111 }
1112 }
1113
1114 #[test]
1115 fn test_size() {
1116 println!("SegList<u64>: {}", size_of::<SegList<u64>>());
1117 println!("SegList<(u64, u32)>: {}", size_of::<SegList<(u64, u32)>>());
1118 assert_eq!(size_of::<SegHeader::<LargeStruct>>(), 24);
1119 let data_offset = Segment::<LargeStruct>::data_offset();
1120 let base_cap = Segment::<LargeStruct>::base_cap();
1121 let large_cap = Segment::<LargeStruct>::large_cap();
1122 let base_layout = Segment::<LargeStruct>::BASE_LAYOUT.1;
1123 let large_layout = Segment::<LargeStruct>::LARGE_LAYOUT.1;
1124 println!(
1125 "LargeStruct: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1126 data_offset,
1127 base_cap,
1128 base_layout.size(),
1129 base_layout.align(),
1130 large_cap,
1131 large_layout.size(),
1132 large_layout.align()
1133 );
1134 let data_offset = Segment::<u64>::data_offset();
1135 let base_cap = Segment::<u64>::base_cap();
1136 let large_cap = Segment::<u64>::large_cap();
1137 let base_layout = Segment::<u64>::BASE_LAYOUT.1;
1138 let large_layout = Segment::<u64>::LARGE_LAYOUT.1;
1139 println!(
1140 "u64: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1141 data_offset,
1142 base_cap,
1143 base_layout.size(),
1144 base_layout.align(),
1145 large_cap,
1146 large_layout.size(),
1147 large_layout.align()
1148 );
1149 let data_offset = Segment::<u32>::data_offset();
1150 let base_cap = Segment::<u32>::base_cap();
1151 let large_cap = Segment::<u32>::large_cap();
1152 let base_layout = Segment::<u32>::BASE_LAYOUT.1;
1153 let large_layout = Segment::<u32>::LARGE_LAYOUT.1;
1154 println!(
1155 "u32: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1156 data_offset,
1157 base_cap,
1158 base_layout.size(),
1159 base_layout.align(),
1160 large_cap,
1161 large_layout.size(),
1162 large_layout.align()
1163 );
1164 let data_offset = Segment::<u16>::data_offset();
1165 let base_cap = Segment::<u16>::base_cap();
1166 let large_cap = Segment::<u16>::large_cap();
1167 let base_layout = Segment::<u16>::BASE_LAYOUT.1;
1168 let large_layout = Segment::<u16>::LARGE_LAYOUT.1;
1169 println!(
1170 "u16: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1171 data_offset,
1172 base_cap,
1173 base_layout.size(),
1174 base_layout.align(),
1175 large_cap,
1176 large_layout.size(),
1177 large_layout.align()
1178 );
1179 }
1180
1181 #[test]
1182 fn test_large_type_push_pop() {
1183 let mut list: SegList<LargeStruct> = SegList::new();
1184 for i in 0..50 {
1186 list.push(LargeStruct::new(i));
1187 }
1188 assert_eq!(list.len(), 50);
1189
1190 for i in (0..50).rev() {
1192 let val = list.pop().unwrap();
1193 assert_eq!(val.data[0], i);
1194 assert_eq!(val.data[7], i);
1195 }
1196 assert!(list.is_empty());
1197 assert_eq!(list.pop(), None);
1198 }
1199
1200 #[test]
1201 fn test_large_type_iter() {
1202 let mut list: SegList<LargeStruct> = SegList::new();
1203
1204 for i in 0..30 {
1206 list.push(LargeStruct::new(i * 10));
1207 }
1208
1209 let collected: Vec<u64> = list.iter().map(|s| s.data[0]).collect();
1211 let expected: Vec<u64> = (0..30).map(|i| i * 10).collect();
1212 assert_eq!(collected, expected);
1213 }
1214
1215 #[test]
1216 fn test_large_type_iter_mut() {
1217 let mut list: SegList<LargeStruct> = SegList::new();
1218
1219 for i in 0..20 {
1221 list.push(LargeStruct::new(i));
1222 }
1223
1224 for item in list.iter_mut() {
1226 item.data[0] *= 2;
1227 }
1228
1229 let collected: Vec<u64> = list.iter().map(|s| s.data[0]).collect();
1231 let expected: Vec<u64> = (0..20).map(|i| i * 2).collect();
1232 assert_eq!(collected, expected);
1233 }
1234
1235 #[test]
1236 fn test_large_type_drain() {
1237 let mut list: SegList<LargeStruct> = SegList::new();
1238
1239 for i in 0..40 {
1241 list.push(LargeStruct::new(i));
1242 }
1243
1244 let drained: Vec<u64> = list.into_iter().map(|s| s.data[0]).collect();
1246 let expected: Vec<u64> = (0..40).collect();
1247 assert_eq!(drained, expected);
1248 }
1249
1250 #[test]
1251 fn test_large_type_clear() {
1252 let mut list: SegList<LargeStruct> = SegList::new();
1253
1254 for i in 0..60 {
1256 list.push(LargeStruct::new(i));
1257 }
1258 assert_eq!(list.len(), 60);
1259
1260 list.clear();
1262 assert!(list.is_empty());
1263 assert_eq!(list.len(), 0);
1264 assert_eq!(list.pop(), None);
1265 }
1266
1267 #[test]
1268 fn test_iter_rev_single_segment() {
1269 let mut list: SegList<i32> = SegList::new();
1271
1272 for i in 0..10 {
1273 list.push(i);
1274 }
1275
1276 let collected: Vec<i32> = list.iter_rev().copied().collect();
1278 let expected: Vec<i32> = (0..10).rev().collect();
1279 assert_eq!(collected, expected);
1280
1281 for item in list.iter_mut_rev() {
1283 *item *= 10;
1284 }
1285
1286 assert_eq!(list.first(), Some(&0));
1288 assert_eq!(list.last(), Some(&90));
1289
1290 let collected: Vec<i32> = list.iter().copied().collect();
1291 let expected: Vec<i32> = vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90];
1292 assert_eq!(collected, expected);
1293 }
1294
1295 #[test]
1296 fn test_iter_rev_multi_segment() {
1297 let mut list: SegList<i32> = SegList::new();
1299
1300 for i in 0..200 {
1301 list.push(i);
1302 }
1303
1304 let collected: Vec<i32> = list.iter_rev().copied().collect();
1306 let expected: Vec<i32> = (0..200).rev().collect();
1307 assert_eq!(collected, expected);
1308
1309 for item in list.iter_mut_rev() {
1311 *item += 1000;
1312 }
1313
1314 assert_eq!(list.first(), Some(&1000));
1316 assert_eq!(list.last(), Some(&1199));
1317
1318 let collected: Vec<i32> = list.iter().copied().collect();
1319 let expected: Vec<i32> = (0..200).map(|i| i + 1000).collect();
1320 assert_eq!(collected, expected);
1321 }
1322
1323 #[test]
1324 fn test_iter_rev_empty() {
1325 let list: SegList<i32> = SegList::new();
1326
1327 let collected: Vec<i32> = list.iter_rev().copied().collect();
1328 assert!(collected.is_empty());
1329
1330 let mut list_mut: SegList<i32> = SegList::new();
1331 let count = list_mut.iter_mut_rev().count();
1332 assert_eq!(count, 0);
1333 }
1334
1335 #[test]
1336 fn test_iter_exact_size() {
1337 let mut list: SegList<i32> = SegList::new();
1338
1339 for i in 0..50 {
1340 list.push(i);
1341 }
1342
1343 let iter = list.iter();
1345 assert_eq!(iter.len(), 50);
1346
1347 let mut iter = list.iter();
1348 assert_eq!(iter.len(), 50);
1349 assert_eq!(iter.next(), Some(&0));
1350 assert_eq!(iter.len(), 49);
1351 assert_eq!(iter.next(), Some(&1));
1352 assert_eq!(iter.len(), 48);
1353
1354 let mut iter_mut = list.iter_mut();
1356 assert_eq!(iter_mut.len(), 50);
1357 assert_eq!(iter_mut.next(), Some(&mut 0));
1358 assert_eq!(iter_mut.len(), 49);
1359 }
1360
1361 #[test]
1362 fn test_iter_rev_exact_size() {
1363 let mut list: SegList<i32> = SegList::new();
1364
1365 for i in 0..50 {
1366 list.push(i);
1367 }
1368
1369 let iter = list.iter_rev();
1371 assert_eq!(iter.len(), 50);
1372
1373 let mut iter = list.iter_rev();
1374 assert_eq!(iter.len(), 50);
1375 assert_eq!(iter.next(), Some(&49));
1376 assert_eq!(iter.len(), 49);
1377 assert_eq!(iter.next(), Some(&48));
1378 assert_eq!(iter.len(), 48);
1379
1380 let mut iter_mut = list.iter_mut_rev();
1382 assert_eq!(iter_mut.len(), 50);
1383 assert_eq!(iter_mut.next(), Some(&mut 49));
1384 assert_eq!(iter_mut.len(), 49);
1385 }
1386
1387 #[test]
1388 fn test_into_iter_rev_single_segment() {
1389 let mut list: SegList<i32> = SegList::new();
1391
1392 for i in 0..10 {
1393 list.push(i);
1394 }
1395 let mut iter = list.into_iter_rev();
1396 assert_eq!(iter.len(), 10);
1397 let mut drained: Vec<i32> = Vec::new();
1399 assert_eq!(iter.next(), Some(9));
1400 assert_eq!(iter.len(), 9);
1401 drained.push(9);
1402 let mut left: Vec<i32> = iter.collect();
1403 drained.append(&mut left);
1404 let expected: Vec<i32> = (0..10).rev().collect();
1405 assert_eq!(drained, expected);
1406 }
1407
1408 #[test]
1409 fn test_into_iter_multi_segment() {
1410 let mut list: SegList<i32> = SegList::new();
1412
1413 for i in 0..200i32 {
1414 list.push(i);
1415 }
1416 let mut iter = list.into_iter();
1417 assert_eq!(iter.len(), 200);
1418 for i in 0..200i32 {
1419 assert_eq!(iter.len(), 200 - (i as usize));
1420 assert_eq!(iter.next(), Some(i));
1421 }
1422 assert_eq!(iter.next(), None);
1423 }
1424
1425 #[test]
1426 fn test_into_iter_rev_multi_segment() {
1427 let mut list: SegList<i32> = SegList::new();
1429
1430 for i in 0..200i32 {
1431 list.push(i);
1432 }
1433 let mut iter = list.into_iter_rev();
1434 assert_eq!(iter.len(), 200);
1435 for i in 0..200i32 {
1436 assert_eq!(iter.len(), 200 - (i as usize));
1437 assert_eq!(iter.next(), Some(199 - i));
1438 }
1439 assert_eq!(iter.next(), None);
1440 }
1441
1442 #[test]
1443 fn test_into_iter_rev_empty() {
1444 let list: SegList<i32> = SegList::new();
1445 let iter = list.into_iter_rev();
1446 assert_eq!(iter.len(), 0);
1447 let drained: Vec<i32> = iter.collect();
1448 assert!(drained.is_empty());
1449 }
1450
1451 #[test]
1452 fn test_into_iter_rev_partial() {
1453 let mut list: SegList<i32> = SegList::new();
1455
1456 for i in 0..50 {
1457 list.push(i);
1458 }
1459
1460 let mut drain = list.into_iter_rev();
1462 let mut drained = Vec::new();
1463 for _ in 0..25 {
1464 if let Some(item) = drain.next() {
1465 drained.push(item);
1466 }
1467 }
1468 assert_eq!(drain.len(), 25);
1469 drop(drain);
1471
1472 let expected: Vec<i32> = (25..50).rev().collect();
1474 assert_eq!(drained, expected);
1475 }
1476}