1use crate::CACHE_LINE_SIZE;
61use alloc::alloc::{alloc, dealloc, handle_alloc_error};
62use core::alloc::Layout;
63use core::mem::{MaybeUninit, align_of, needs_drop, size_of};
64use core::ptr::{NonNull, null_mut};
65
66pub struct SegList<T> {
85 tail: NonNull<SegHeader<T>>,
87 count: usize,
89}
90
91unsafe impl<T: Send> Send for SegList<T> {}
92unsafe impl<T: Send> Sync for SegList<T> {}
93
94impl<T> SegList<T> {
95 pub fn new() -> Self {
97 let mut seg = unsafe { Segment::<T>::alloc(null_mut(), null_mut(), true) };
98 let header_ptr = seg.header.as_ptr();
99 let header = seg.get_header_mut();
100 header.next = header_ptr;
102 Self { tail: seg.header, count: 0 }
103 }
104
105 #[inline(always)]
107 pub fn is_empty(&self) -> bool {
108 self.count == 0
109 }
110
111 #[inline(always)]
113 pub const fn segment_cap() -> usize {
114 Segment::<T>::base_cap()
115 }
116
117 #[inline(always)]
119 pub fn len(&self) -> usize {
120 self.count
121 }
122
123 #[inline]
125 pub fn push(&mut self, item: T) {
126 unsafe {
127 let mut tail_seg = Segment::from_raw(self.tail);
128 if tail_seg.is_full() {
129 let tail_ptr = tail_seg.header.as_ptr();
130 let cur = tail_seg.get_header_mut();
131 let new_seg = Segment::alloc(tail_ptr, cur.next, false);
133 cur.next = new_seg.header.as_ptr();
134 self.tail = new_seg.header;
135 tail_seg = new_seg;
136 }
137 tail_seg.push(item);
138 }
139 self.count += 1;
140 }
141
142 #[inline]
144 pub fn pop(&mut self) -> Option<T> {
145 if self.count == 0 {
146 return None;
147 }
148 unsafe {
149 let mut tail_seg = Segment::from_raw(self.tail);
150 let (item, is_empty) = tail_seg.pop();
151 if is_empty {
152 let cur = tail_seg.get_header_mut();
153 let first_ptr = cur.next;
154 let cur_prev = cur.prev;
155 if self.tail.as_ptr() != first_ptr && !cur_prev.is_null() {
156 self.tail = NonNull::new_unchecked(cur_prev);
158 (*self.tail.as_ptr()).next = first_ptr;
159 tail_seg.dealloc();
160 }
161 }
163 self.count -= 1;
164 Some(item)
165 }
166 }
167
168 #[inline(always)]
170 fn break_first_node(&mut self) -> Segment<T> {
171 let tail_header = unsafe { self.tail.as_mut() };
172 let first = tail_header.next;
173 tail_header.next = null_mut();
174 unsafe { Segment::from_raw(NonNull::new_unchecked(first)) }
175 }
176
177 #[inline(always)]
178 fn first_ptr(&self) -> NonNull<SegHeader<T>> {
179 unsafe {
182 let tail_header = self.tail.as_ref();
183 let first = tail_header.next;
184 NonNull::new_unchecked(first)
185 }
186 }
187
188 #[inline]
190 pub fn iter(&self) -> SegListIter<'_, T> {
191 let first_seg = unsafe { Segment::from_raw(self.first_ptr()) };
192 SegListIter {
193 base: IterBase { cur: first_seg, cur_idx: 0, remaining: self.count, forward: true },
194 _marker: core::marker::PhantomData,
195 }
196 }
197
198 #[inline]
200 pub fn iter_rev(&self) -> SegListIter<'_, T> {
201 let tail_seg = unsafe { Segment::from_raw(self.tail) };
202 let tail_header = tail_seg.get_header();
203 let start_idx = if tail_header.count > 0 { tail_header.count as usize - 1 } else { 0 };
204 SegListIter {
205 base: IterBase {
206 cur: tail_seg,
207 cur_idx: start_idx,
208 remaining: self.count,
209 forward: false,
210 },
211 _marker: core::marker::PhantomData,
212 }
213 }
214
215 #[inline]
217 pub fn iter_mut(&mut self) -> SegListIterMut<'_, T> {
218 let first_seg = unsafe { Segment::from_raw(self.first_ptr()) };
219 SegListIterMut {
220 base: IterBase { cur: first_seg, cur_idx: 0, remaining: self.count, forward: true },
221 _marker: core::marker::PhantomData,
222 }
223 }
224
225 #[inline]
227 pub fn iter_mut_rev(&mut self) -> SegListIterMut<'_, T> {
228 let tail_seg = unsafe { Segment::from_raw(self.tail) };
229 let tail_header = tail_seg.get_header();
230 let start_idx = if tail_header.count > 0 { tail_header.count as usize - 1 } else { 0 };
231 SegListIterMut {
232 base: IterBase {
233 cur: tail_seg,
234 cur_idx: start_idx,
235 remaining: self.count,
236 forward: false,
237 },
238 _marker: core::marker::PhantomData,
239 }
240 }
241
242 pub fn drain(mut self) -> SegListDrain<T> {
244 let mut first = self.break_first_node();
246 let cur = if self.count == 0 {
247 unsafe {
248 first.dealloc();
249 }
250 None
251 } else {
252 Some(first)
253 };
254 core::mem::forget(self);
256 SegListDrain { cur, cur_idx: 0, forward: true }
257 }
258
259 pub fn into_rev(mut self) -> SegListDrain<T> {
261 let mut first = self.break_first_node();
263 let (cur, start_idx) = if self.count == 0 {
264 unsafe {
265 first.dealloc();
266 }
267 (None, 0)
268 } else {
269 let tail_seg = unsafe { Segment::from_raw(self.tail) };
270 let tail_header = tail_seg.get_header();
271 let start_idx = if tail_header.count > 0 { tail_header.count as usize - 1 } else { 0 };
272 (Some(tail_seg), start_idx)
273 };
274 core::mem::forget(self);
275 SegListDrain { cur, cur_idx: start_idx, forward: false }
276 }
277
278 #[inline]
280 pub fn first(&self) -> Option<&T> {
281 if self.count == 0 {
282 return None;
283 }
284 unsafe {
287 let first_seg = Segment::from_raw(self.first_ptr());
288 Some((*first_seg.item_ptr(0)).assume_init_ref())
289 }
290 }
291
292 #[inline]
294 pub fn first_mut(&self) -> Option<&T> {
295 if self.count == 0 {
296 return None;
297 }
298 unsafe {
301 let first_seg = Segment::from_raw(self.first_ptr());
302 Some((*first_seg.item_ptr(0)).assume_init_mut())
303 }
304 }
305
306 #[inline]
308 pub fn last(&self) -> Option<&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_ref())
318 }
319 }
320
321 #[inline]
323 pub fn last_mut(&mut self) -> Option<&mut T> {
324 unsafe {
326 let tail_seg = Segment::from_raw(self.tail);
327 let header = tail_seg.get_header();
328 if header.count == 0 {
329 return None;
330 }
331 let idx = (header.count - 1) as usize;
332 Some((*tail_seg.item_ptr(idx)).assume_init_mut())
333 }
334 }
335
336 #[inline(always)]
338 pub fn clear(&mut self) {
339 if self.count == 0 {
340 return;
341 }
342 unsafe {
343 let tail_header = self.tail.as_mut();
344 let first = tail_header.next;
345 let mut cur = Segment::from_raw(self.tail);
346 loop {
347 let next = cur.get_header().prev;
348 if next.is_null() {
349 if needs_drop::<T>() {
350 cur.drop_items();
351 }
352 self.count = 0;
353 let header = cur.get_header_mut();
354 header.count = 0;
355 header.next = first;
356 self.tail = NonNull::new_unchecked(first);
357 return;
358 } else {
359 cur.dealloc_with_items();
360 cur = Segment::from_raw(NonNull::new_unchecked(next));
361 }
362 }
363 }
364 }
365}
366
367impl<T> Default for SegList<T> {
368 fn default() -> Self {
369 Self::new()
370 }
371}
372
373impl<T> Drop for SegList<T> {
374 fn drop(&mut self) {
375 let mut cur = self.break_first_node();
377 loop {
378 let next = cur.get_header().next;
380 unsafe { cur.dealloc_with_items() };
381 if next.is_null() {
382 break;
383 }
384 cur = unsafe { Segment::from_raw(NonNull::new_unchecked(next)) };
385 }
386 }
387}
388
389impl<T> IntoIterator for SegList<T> {
390 type Item = T;
391 type IntoIter = SegListDrain<T>;
392
393 #[inline(always)]
394 fn into_iter(self) -> Self::IntoIter {
395 self.drain()
396 }
397}
398
399impl<T: core::fmt::Debug> core::fmt::Debug for SegList<T> {
400 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
401 f.debug_struct("SegList").field("len", &self.len()).finish()
402 }
403}
404
405#[repr(C)]
407struct SegHeader<T> {
408 count: u32,
410 cap: u32,
412 prev: *mut SegHeader<T>,
413 next: *mut SegHeader<T>,
415 _marker: core::marker::PhantomData<T>,
416}
417
418struct Segment<T> {
420 header: NonNull<SegHeader<T>>,
422}
423
424impl<T> Segment<T> {
425 const DATA_OFFSET: usize = Self::calc_data_offset();
427
428 const BASE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 2);
431
432 const LARGE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 4);
435
436 const fn calc_data_offset() -> usize {
438 let mut data_offset = size_of::<SegHeader<T>>();
439 let t_size = size_of::<T>();
440 let t_align = align_of::<MaybeUninit<T>>();
441
442 if t_size != 0 {
443 data_offset = (data_offset + t_align - 1) & !(t_align - 1);
444 }
445 data_offset
446 }
447
448 const fn calc_layout_const(cache_line: usize) -> (usize, Layout) {
450 let t_size = size_of::<T>();
451 let data_offset = Self::DATA_OFFSET;
452 let capacity;
453 let final_alloc_size;
454 let final_align;
455
456 if t_size == 0 {
457 capacity = 1024;
459 final_alloc_size = cache_line;
460 final_align = cache_line;
461 } else {
462 let min_elements = 2;
463 let min_required_size = data_offset + (t_size * min_elements);
464 let alloc_size = (min_required_size + cache_line - 1) & !(cache_line - 1);
465 final_align = if cache_line > align_of::<MaybeUninit<T>>() {
466 cache_line
467 } else {
468 align_of::<MaybeUninit<T>>()
469 };
470 final_alloc_size = (alloc_size + final_align - 1) & !(final_align - 1);
471 capacity = (final_alloc_size - data_offset) / t_size;
472 assert!(capacity >= min_elements);
474 }
475
476 match Layout::from_size_align(final_alloc_size, final_align) {
477 Ok(l) => (capacity, l),
478 Err(_) => panic!("Invalid layout"),
479 }
480 }
481
482 #[inline(always)]
484 const fn base_cap() -> usize {
485 Self::BASE_LAYOUT.0
486 }
487
488 #[inline(always)]
490 const fn large_cap() -> usize {
491 Self::LARGE_LAYOUT.0
492 }
493
494 #[inline(always)]
496 const fn data_offset() -> usize {
497 Self::DATA_OFFSET
498 }
499
500 #[inline]
503 unsafe fn alloc(prev: *mut SegHeader<T>, next: *mut SegHeader<T>, is_first: bool) -> Self {
504 let (cap, layout) = if is_first {
505 (Self::base_cap() as u32, Self::BASE_LAYOUT.1)
506 } else {
507 (Self::large_cap() as u32, Self::LARGE_LAYOUT.1)
508 };
509 let ptr: *mut u8 = unsafe { alloc(layout) };
510 if ptr.is_null() {
511 handle_alloc_error(layout);
512 }
513 unsafe {
514 let p = NonNull::new_unchecked(ptr as *mut SegHeader<T>);
515 let header = p.as_ptr();
516 (*header).count = 0;
518 (*header).cap = cap;
519 (*header).prev = prev;
520 (*header).next = next;
521 Self::from_raw(p)
522 }
523 }
524
525 #[inline(always)]
526 unsafe fn drop_items(&self) {
527 unsafe {
528 for i in 0..self.len() {
529 (*self.item_ptr(i)).assume_init_drop();
530 }
531 }
532 }
533
534 #[inline(always)]
535 unsafe fn dealloc_with_items(&mut self) {
536 unsafe {
537 if needs_drop::<T>() {
538 self.drop_items();
539 }
540 self.dealloc();
541 }
542 }
543
544 #[inline(always)]
545 unsafe fn dealloc(&mut self) {
546 unsafe {
548 let cap = (*self.header.as_ptr()).cap as usize;
549 let layout =
550 if cap == Self::base_cap() { Self::BASE_LAYOUT.1 } else { Self::LARGE_LAYOUT.1 };
551 dealloc(self.header.as_ptr() as *mut u8, layout);
552 }
553 }
554
555 #[inline(always)]
556 unsafe fn from_raw(header: NonNull<SegHeader<T>>) -> Self {
557 Self { header }
558 }
559
560 #[inline(always)]
562 fn len(&self) -> usize {
563 unsafe { (*self.header.as_ptr()).count as usize }
564 }
565
566 #[inline(always)]
567 fn get_header(&self) -> &SegHeader<T> {
568 unsafe { self.header.as_ref() }
569 }
570
571 #[inline(always)]
572 fn get_header_mut(&mut self) -> &mut SegHeader<T> {
573 unsafe { self.header.as_mut() }
574 }
575
576 #[inline(always)]
578 fn is_empty(&self) -> bool {
579 self.len() == 0
580 }
581
582 #[inline(always)]
584 fn is_full(&self) -> bool {
585 let header = self.get_header();
586 header.count >= header.cap
587 }
588
589 #[inline]
591 fn item_ptr(&self, index: usize) -> *mut MaybeUninit<T> {
592 unsafe {
593 let items =
594 (self.header.as_ptr() as *mut u8).add(Self::data_offset()) as *mut MaybeUninit<T>;
595 items.add(index)
596 }
597 }
598
599 #[inline]
601 fn push(&mut self, item: T) {
602 debug_assert!(!self.is_full());
603 let idx = self.get_header().count as usize;
604 unsafe {
605 (*self.item_ptr(idx)).write(item);
606 }
607 self.get_header_mut().count = (idx + 1) as u32;
608 }
609
610 #[inline]
612 fn pop(&mut self) -> (T, bool) {
613 debug_assert!(!self.is_empty());
614 let idx = self.get_header().count - 1;
615 let item = unsafe { (*self.item_ptr(idx as usize)).assume_init_read() };
616 self.get_header_mut().count = idx;
617 (item, idx == 0)
618 }
619}
620
621struct IterBase<T> {
625 cur: Segment<T>,
626 cur_idx: usize,
627 remaining: usize,
628 forward: bool,
629}
630
631impl<T> IterBase<T> {
632 #[inline]
634 fn next(&mut self) -> Option<*mut MaybeUninit<T>> {
635 if self.remaining == 0 {
636 return None;
637 }
638 self.remaining -= 1;
639
640 if self.forward {
641 let cur_header = self.cur.get_header();
642 let idx = if self.cur_idx >= cur_header.count as usize {
643 let next = cur_header.next;
644 self.cur = unsafe { Segment::from_raw(NonNull::new_unchecked(next)) };
645 self.cur_idx = 1;
646 0
647 } else {
648 let _idx = self.cur_idx;
649 self.cur_idx = _idx + 1;
650 _idx
651 };
652 Some(self.cur.item_ptr(idx))
653 } else {
654 let idx = self.cur_idx;
655 let item_ptr = self.cur.item_ptr(idx);
656 if self.cur_idx == 0 {
657 let cur_header = self.cur.get_header();
658 if !cur_header.prev.is_null() {
659 self.cur =
660 unsafe { Segment::from_raw(NonNull::new_unchecked(cur_header.prev)) };
661 let prev_header = self.cur.get_header();
662 self.cur_idx = prev_header.count as usize - 1;
663 }
664 } else {
665 self.cur_idx -= 1;
666 }
667 Some(item_ptr)
668 }
669 }
670
671 #[inline]
672 fn size_hint(&self) -> (usize, Option<usize>) {
673 (self.remaining, Some(self.remaining))
674 }
675}
676
677pub struct SegListIter<'a, T> {
679 base: IterBase<T>,
680 _marker: core::marker::PhantomData<&'a T>,
681}
682
683impl<'a, T> Iterator for SegListIter<'a, T> {
684 type Item = &'a T;
685
686 #[inline]
687 fn next(&mut self) -> Option<Self::Item> {
688 self.base.next().map(|ptr| unsafe { (*ptr).assume_init_ref() })
689 }
690
691 #[inline]
692 fn size_hint(&self) -> (usize, Option<usize>) {
693 self.base.size_hint()
694 }
695}
696
697impl<'a, T> ExactSizeIterator for SegListIter<'a, T> {}
698
699pub struct SegListIterMut<'a, T> {
701 base: IterBase<T>,
702 _marker: core::marker::PhantomData<&'a mut T>,
703}
704
705impl<'a, T> Iterator for SegListIterMut<'a, T> {
706 type Item = &'a mut T;
707
708 #[inline]
709 fn next(&mut self) -> Option<Self::Item> {
710 self.base.next().map(|ptr| unsafe { (*ptr).assume_init_mut() })
711 }
712
713 #[inline]
714 fn size_hint(&self) -> (usize, Option<usize>) {
715 self.base.size_hint()
716 }
717}
718
719impl<'a, T> ExactSizeIterator for SegListIterMut<'a, T> {}
720
721pub struct SegListDrain<T> {
724 cur: Option<Segment<T>>,
725 cur_idx: usize,
726 forward: bool,
727}
728
729impl<T> Iterator for SegListDrain<T> {
730 type Item = T;
731
732 #[inline]
733 fn next(&mut self) -> Option<Self::Item> {
734 let cur_seg = self.cur.as_mut()?;
735 unsafe {
736 let item = (*cur_seg.item_ptr(self.cur_idx)).assume_init_read();
737 let header = cur_seg.get_header();
738 if self.forward {
739 let next_idx = self.cur_idx + 1;
740 if next_idx >= header.count as usize {
741 let next = header.next;
742 cur_seg.dealloc();
743 if next.is_null() {
744 self.cur = None;
745 } else {
746 self.cur = Some(Segment::from_raw(NonNull::new_unchecked(next)));
747 self.cur_idx = 0;
748 }
749 } else {
750 self.cur_idx = next_idx;
751 }
752 } else if self.cur_idx == 0 {
753 let prev = header.prev;
754 cur_seg.dealloc();
755 if prev.is_null() {
756 self.cur = None;
757 } else {
758 let _cur = Segment::from_raw(NonNull::new_unchecked(prev));
759 self.cur_idx = _cur.get_header().count as usize - 1;
760 self.cur = Some(_cur);
761 }
762 } else {
763 self.cur_idx -= 1;
764 }
765 Some(item)
766 }
767 }
768
769 #[inline]
770 fn size_hint(&self) -> (usize, Option<usize>) {
771 let remaining = if let Some(_cur) = &self.cur {
772 1 } else {
776 0
777 };
778 (remaining, None)
779 }
780}
781
782impl<T> Drop for SegListDrain<T> {
783 fn drop(&mut self) {
784 if let Some(mut cur) = self.cur.take() {
785 unsafe {
786 if self.forward {
787 let header = cur.get_header();
789 let mut next = header.next;
790 if needs_drop::<T>() {
792 for i in self.cur_idx..header.count as usize {
793 (*cur.item_ptr(i)).assume_init_drop();
794 }
795 }
796 cur.dealloc();
797 while !next.is_null() {
798 cur = Segment::from_raw(NonNull::new_unchecked(next));
799 next = cur.get_header().next;
800 cur.dealloc_with_items();
801 }
802 } else {
803 let mut prev = cur.get_header().prev;
805 if needs_drop::<T>() {
807 for i in 0..=self.cur_idx {
808 (*cur.item_ptr(i)).assume_init_drop();
809 }
810 }
811 cur.dealloc();
812 while !prev.is_null() {
813 cur = Segment::from_raw(NonNull::new_unchecked(prev));
814 prev = cur.get_header().prev;
815 cur.dealloc_with_items();
816 }
817 }
818 }
819 }
820 }
821}
822
823#[cfg(test)]
824mod tests {
825 use super::*;
826 use crate::test::{CounterI32, alive_count, reset_alive_count};
827
828 #[test]
829 fn test_multiple_segments() {
830 let mut list: SegList<i32> = SegList::new();
831 if CACHE_LINE_SIZE == 128 {
832 assert_eq!(Segment::<i32>::base_cap(), 26);
833 }
834
835 for i in 0..100 {
836 list.push(i);
837 }
838
839 assert_eq!(list.len(), 100);
840
841 for i in (0..100).rev() {
842 assert_eq!(list.pop(), Some(i));
843 }
844
845 assert_eq!(list.pop(), None);
846 }
847
848 #[test]
849 fn test_iter_single_segment() {
850 let mut list: SegList<i32> = SegList::new();
852
853 for i in 0..10 {
854 list.push(i);
855 }
856 assert_eq!(list.first(), Some(&0));
857 assert_eq!(list.last(), Some(&9));
858
859 let collected: Vec<i32> = list.iter().copied().collect();
861 assert_eq!(collected, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
862
863 for item in list.iter_mut() {
865 *item *= 2;
866 }
867 assert_eq!(list.first(), Some(&0));
868 assert_eq!(list.last(), Some(&18));
869
870 let collected: Vec<i32> = list.iter().copied().collect();
872 assert_eq!(collected, vec![0, 2, 4, 6, 8, 10, 12, 14, 16, 18]);
873
874 for i in (0..10).rev() {
876 assert_eq!(list.pop(), Some(i * 2));
877 }
878 assert_eq!(list.pop(), None);
879 assert!(list.is_empty());
880 }
881
882 #[test]
883 fn test_iter_multi_segment() {
884 let mut list: SegList<i32> = SegList::new();
886
887 for i in 0..200 {
888 list.push(i * 10);
889 }
890 assert_eq!(list.first(), Some(&0));
891 assert_eq!(list.last(), Some(&1990));
892
893 let collected: Vec<i32> = list.iter().copied().collect();
895 let expected: Vec<i32> = (0..200).map(|i| i * 10).collect();
896 assert_eq!(collected, expected);
897
898 for item in list.iter_mut() {
900 *item += 1;
901 }
902 assert_eq!(list.first(), Some(&1));
903 assert_eq!(list.last(), Some(&1991));
904
905 let collected: Vec<i32> = list.iter().copied().collect();
907 let expected: Vec<i32> = (0..200).map(|i| i * 10 + 1).collect();
908 assert_eq!(collected, expected);
909
910 for i in (0..200).rev() {
912 assert_eq!(list.pop(), Some(i * 10 + 1));
913 }
914 assert_eq!(list.pop(), None);
915 assert!(list.is_empty());
916 }
917
918 #[test]
919 fn test_drain() {
920 let cap = Segment::<CounterI32>::base_cap();
922
923 {
925 reset_alive_count();
926 {
927 let mut list: SegList<CounterI32> = SegList::new();
928 for i in 0..5 {
930 list.push(CounterI32::new(i));
931 }
932 assert!(list.len() < cap);
933
934 let drained: Vec<i32> = list.drain().map(|d| *d).collect();
936 assert_eq!(drained, vec![0, 1, 2, 3, 4]);
937 }
938 assert_eq!(alive_count(), 0);
940 }
941
942 {
944 reset_alive_count();
945 {
946 let mut list: SegList<CounterI32> = SegList::new();
947 let total = cap * 2 + 5;
949 for i in 0..total {
950 list.push(CounterI32::new(i as i32));
951 }
952 assert_eq!(alive_count(), cap * 2 + 5);
953
954 let drain_count = cap / 2;
956 let mut drain_iter = list.drain();
957 for i in 0..drain_count {
958 assert_eq!(*drain_iter.next().unwrap(), i as i32);
959 }
960 drop(drain_iter);
962 }
963 assert_eq!(alive_count(), 0);
965 }
966
967 {
969 reset_alive_count();
970 {
971 let mut list: SegList<CounterI32> = SegList::new();
972 let total = cap * 2 + 3;
974 for i in 0..total {
975 list.push(CounterI32::new(i as i32));
976 }
977 assert_eq!(alive_count(), cap * 2 + 3);
978
979 let mut drain_iter = list.drain();
981 for i in 0..cap {
982 assert_eq!(*drain_iter.next().unwrap(), i as i32);
983 }
984 drop(drain_iter);
986 }
987 assert_eq!(alive_count(), 0);
989 }
990 }
991
992 #[test]
993 fn test_drop_single_segment() {
994 reset_alive_count();
995 {
996 let mut list: SegList<CounterI32> = SegList::new();
997 let cap = Segment::<CounterI32>::base_cap();
998
999 for i in 0..5 {
1001 list.push(CounterI32::new(i));
1002 }
1003 assert!(list.len() < cap);
1004 assert_eq!(alive_count(), 5);
1005
1006 }
1008
1009 assert_eq!(alive_count(), 0);
1010 }
1011
1012 #[test]
1013 fn test_drop_multi_segment() {
1014 let cap = Segment::<CounterI32>::base_cap();
1015 reset_alive_count();
1016 {
1017 let mut list: SegList<CounterI32> = SegList::new();
1018
1019 let total = cap * 2 + 10;
1021 for i in 0..total {
1022 list.push(CounterI32::new(i as i32));
1023 }
1024 assert_eq!(alive_count(), cap * 2 + 10);
1025 }
1027 assert_eq!(alive_count(), 0);
1028 }
1029
1030 #[test]
1031 fn test_clear_1_segment() {
1032 reset_alive_count();
1033 {
1034 let mut list: SegList<CounterI32> = SegList::new();
1035 let base_cap = Segment::<CounterI32>::base_cap();
1036
1037 for i in 0..base_cap as i32 {
1038 list.push(CounterI32::new(i));
1039 }
1040 assert_eq!(alive_count(), base_cap);
1041 list.clear();
1042 assert!(list.is_empty());
1043 assert_eq!(list.len(), 0);
1044 assert!(list.pop().is_none());
1045 }
1046 assert_eq!(alive_count(), 0);
1047 }
1048
1049 #[test]
1050 fn test_clear_2_segment() {
1051 reset_alive_count();
1052 {
1053 let mut list: SegList<CounterI32> = SegList::new();
1054
1055 let count = Segment::<CounterI32>::base_cap() + Segment::<CounterI32>::large_cap();
1056 for i in 0..count as i32 {
1057 list.push(CounterI32::new(i));
1058 }
1059 assert_eq!(alive_count(), count);
1060 list.clear();
1061 assert!(list.is_empty());
1062 assert_eq!(list.len(), 0);
1063 assert!(list.pop().is_none());
1064 }
1065 assert_eq!(alive_count(), 0);
1066 }
1067
1068 #[test]
1069 fn test_clear_3_segment() {
1070 reset_alive_count();
1071 let mut list: SegList<CounterI32> = SegList::new();
1072
1073 let count = Segment::<CounterI32>::base_cap() + Segment::<CounterI32>::large_cap() * 2;
1074 for i in 0..count as i32 {
1075 list.push(CounterI32::new(i));
1076 }
1077 assert_eq!(alive_count(), count);
1078 list.clear();
1079 assert!(list.is_empty());
1080 assert_eq!(list.len(), 0);
1081 assert!(list.pop().is_none());
1082 assert_eq!(alive_count(), 0);
1083 }
1084
1085 #[derive(Debug, Clone, Copy, PartialEq)]
1087 struct LargeStruct {
1088 data: [u64; 16], }
1090
1091 impl LargeStruct {
1092 fn new(val: u64) -> Self {
1093 Self { data: [val; 16] }
1094 }
1095 }
1096
1097 #[test]
1098 fn test_size() {
1099 println!("SegList<u64>: {}", size_of::<SegList<u64>>());
1100 println!("SegList<(u64, u32)>: {}", size_of::<SegList<(u64, u32)>>());
1101 assert_eq!(size_of::<SegHeader::<LargeStruct>>(), 24);
1102 let data_offset = Segment::<LargeStruct>::data_offset();
1103 let base_cap = Segment::<LargeStruct>::base_cap();
1104 let large_cap = Segment::<LargeStruct>::large_cap();
1105 let base_layout = Segment::<LargeStruct>::BASE_LAYOUT.1;
1106 let large_layout = Segment::<LargeStruct>::LARGE_LAYOUT.1;
1107 println!(
1108 "LargeStruct: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1109 data_offset,
1110 base_cap,
1111 base_layout.size(),
1112 base_layout.align(),
1113 large_cap,
1114 large_layout.size(),
1115 large_layout.align()
1116 );
1117 let data_offset = Segment::<u64>::data_offset();
1118 let base_cap = Segment::<u64>::base_cap();
1119 let large_cap = Segment::<u64>::large_cap();
1120 let base_layout = Segment::<u64>::BASE_LAYOUT.1;
1121 let large_layout = Segment::<u64>::LARGE_LAYOUT.1;
1122 println!(
1123 "u64: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1124 data_offset,
1125 base_cap,
1126 base_layout.size(),
1127 base_layout.align(),
1128 large_cap,
1129 large_layout.size(),
1130 large_layout.align()
1131 );
1132 let data_offset = Segment::<u32>::data_offset();
1133 let base_cap = Segment::<u32>::base_cap();
1134 let large_cap = Segment::<u32>::large_cap();
1135 let base_layout = Segment::<u32>::BASE_LAYOUT.1;
1136 let large_layout = Segment::<u32>::LARGE_LAYOUT.1;
1137 println!(
1138 "u32: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1139 data_offset,
1140 base_cap,
1141 base_layout.size(),
1142 base_layout.align(),
1143 large_cap,
1144 large_layout.size(),
1145 large_layout.align()
1146 );
1147 let data_offset = Segment::<u16>::data_offset();
1148 let base_cap = Segment::<u16>::base_cap();
1149 let large_cap = Segment::<u16>::large_cap();
1150 let base_layout = Segment::<u16>::BASE_LAYOUT.1;
1151 let large_layout = Segment::<u16>::LARGE_LAYOUT.1;
1152 println!(
1153 "u16: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1154 data_offset,
1155 base_cap,
1156 base_layout.size(),
1157 base_layout.align(),
1158 large_cap,
1159 large_layout.size(),
1160 large_layout.align()
1161 );
1162 }
1163
1164 #[test]
1165 fn test_large_type_push_pop() {
1166 let mut list: SegList<LargeStruct> = SegList::new();
1167 for i in 0..50 {
1169 list.push(LargeStruct::new(i));
1170 }
1171 assert_eq!(list.len(), 50);
1172
1173 for i in (0..50).rev() {
1175 let val = list.pop().unwrap();
1176 assert_eq!(val.data[0], i);
1177 assert_eq!(val.data[7], i);
1178 }
1179 assert!(list.is_empty());
1180 assert_eq!(list.pop(), None);
1181 }
1182
1183 #[test]
1184 fn test_large_type_iter() {
1185 let mut list: SegList<LargeStruct> = SegList::new();
1186
1187 for i in 0..30 {
1189 list.push(LargeStruct::new(i * 10));
1190 }
1191
1192 let collected: Vec<u64> = list.iter().map(|s| s.data[0]).collect();
1194 let expected: Vec<u64> = (0..30).map(|i| i * 10).collect();
1195 assert_eq!(collected, expected);
1196 }
1197
1198 #[test]
1199 fn test_large_type_iter_mut() {
1200 let mut list: SegList<LargeStruct> = SegList::new();
1201
1202 for i in 0..20 {
1204 list.push(LargeStruct::new(i));
1205 }
1206
1207 for item in list.iter_mut() {
1209 item.data[0] *= 2;
1210 }
1211
1212 let collected: Vec<u64> = list.iter().map(|s| s.data[0]).collect();
1214 let expected: Vec<u64> = (0..20).map(|i| i * 2).collect();
1215 assert_eq!(collected, expected);
1216 }
1217
1218 #[test]
1219 fn test_large_type_drain() {
1220 let mut list: SegList<LargeStruct> = SegList::new();
1221
1222 for i in 0..40 {
1224 list.push(LargeStruct::new(i));
1225 }
1226
1227 let drained: Vec<u64> = list.drain().map(|s| s.data[0]).collect();
1229 let expected: Vec<u64> = (0..40).collect();
1230 assert_eq!(drained, expected);
1231 }
1232
1233 #[test]
1234 fn test_large_type_clear() {
1235 let mut list: SegList<LargeStruct> = SegList::new();
1236
1237 for i in 0..60 {
1239 list.push(LargeStruct::new(i));
1240 }
1241 assert_eq!(list.len(), 60);
1242
1243 list.clear();
1245 assert!(list.is_empty());
1246 assert_eq!(list.len(), 0);
1247 assert_eq!(list.pop(), None);
1248 }
1249
1250 #[test]
1251 fn test_iter_rev_single_segment() {
1252 let mut list: SegList<i32> = SegList::new();
1254
1255 for i in 0..10 {
1256 list.push(i);
1257 }
1258
1259 let collected: Vec<i32> = list.iter_rev().copied().collect();
1261 let expected: Vec<i32> = (0..10).rev().collect();
1262 assert_eq!(collected, expected);
1263
1264 for item in list.iter_mut_rev() {
1266 *item *= 10;
1267 }
1268
1269 assert_eq!(list.first(), Some(&0));
1271 assert_eq!(list.last(), Some(&90));
1272
1273 let collected: Vec<i32> = list.iter().copied().collect();
1274 let expected: Vec<i32> = vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90];
1275 assert_eq!(collected, expected);
1276 }
1277
1278 #[test]
1279 fn test_iter_rev_multi_segment() {
1280 let mut list: SegList<i32> = SegList::new();
1282
1283 for i in 0..200 {
1284 list.push(i);
1285 }
1286
1287 let collected: Vec<i32> = list.iter_rev().copied().collect();
1289 let expected: Vec<i32> = (0..200).rev().collect();
1290 assert_eq!(collected, expected);
1291
1292 for item in list.iter_mut_rev() {
1294 *item += 1000;
1295 }
1296
1297 assert_eq!(list.first(), Some(&1000));
1299 assert_eq!(list.last(), Some(&1199));
1300
1301 let collected: Vec<i32> = list.iter().copied().collect();
1302 let expected: Vec<i32> = (0..200).map(|i| i + 1000).collect();
1303 assert_eq!(collected, expected);
1304 }
1305
1306 #[test]
1307 fn test_iter_rev_empty() {
1308 let list: SegList<i32> = SegList::new();
1309
1310 let collected: Vec<i32> = list.iter_rev().copied().collect();
1311 assert!(collected.is_empty());
1312
1313 let mut list_mut: SegList<i32> = SegList::new();
1314 let count = list_mut.iter_mut_rev().count();
1315 assert_eq!(count, 0);
1316 }
1317
1318 #[test]
1319 fn test_iter_rev_exact_size() {
1320 let mut list: SegList<i32> = SegList::new();
1321
1322 for i in 0..50 {
1323 list.push(i);
1324 }
1325
1326 let iter = list.iter_rev();
1328 assert_eq!(iter.len(), 50);
1329
1330 let mut iter = list.iter_rev();
1331 assert_eq!(iter.len(), 50);
1332 iter.next();
1333 assert_eq!(iter.len(), 49);
1334 iter.next();
1335 assert_eq!(iter.len(), 48);
1336
1337 let mut iter_mut = list.iter_mut_rev();
1339 assert_eq!(iter_mut.len(), 50);
1340 iter_mut.next();
1341 assert_eq!(iter_mut.len(), 49);
1342 }
1343
1344 #[test]
1345 fn test_into_rev_single_segment() {
1346 let mut list: SegList<i32> = SegList::new();
1348
1349 for i in 0..10 {
1350 list.push(i);
1351 }
1352
1353 let drained: Vec<i32> = list.into_rev().collect();
1355 let expected: Vec<i32> = (0..10).rev().collect();
1356 assert_eq!(drained, expected);
1357 }
1358
1359 #[test]
1360 fn test_into_rev_multi_segment() {
1361 let mut list: SegList<i32> = SegList::new();
1363
1364 for i in 0..200 {
1365 list.push(i);
1366 }
1367
1368 let drained: Vec<i32> = list.into_rev().collect();
1370 let expected: Vec<i32> = (0..200).rev().collect();
1371 assert_eq!(drained, expected);
1372 }
1373
1374 #[test]
1375 fn test_into_rev_empty() {
1376 let list: SegList<i32> = SegList::new();
1377
1378 let drained: Vec<i32> = list.into_rev().collect();
1379 assert!(drained.is_empty());
1380 }
1381
1382 #[test]
1383 fn test_into_rev_partial() {
1384 let mut list: SegList<i32> = SegList::new();
1386
1387 for i in 0..50 {
1388 list.push(i);
1389 }
1390
1391 let mut drain = list.into_rev();
1393 let mut drained = Vec::new();
1394 for _ in 0..25 {
1395 if let Some(item) = drain.next() {
1396 drained.push(item);
1397 }
1398 }
1399 drop(drain);
1401
1402 let expected: Vec<i32> = (25..50).rev().collect();
1404 assert_eq!(drained, expected);
1405 }
1406}