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
424unsafe impl<T: Send> Send for Segment<T> {}
425
426impl<T> Segment<T> {
427 const DATA_OFFSET: usize = Self::calc_data_offset();
429
430 const BASE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 2);
433
434 const LARGE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 4);
437
438 const fn calc_data_offset() -> usize {
440 let mut data_offset = size_of::<SegHeader<T>>();
441 let t_size = size_of::<T>();
442 let t_align = align_of::<MaybeUninit<T>>();
443
444 if t_size != 0 {
445 data_offset = (data_offset + t_align - 1) & !(t_align - 1);
446 }
447 data_offset
448 }
449
450 const fn calc_layout_const(cache_line: usize) -> (usize, Layout) {
452 let t_size = size_of::<T>();
453 let data_offset = Self::DATA_OFFSET;
454 let capacity;
455 let final_alloc_size;
456 let final_align;
457
458 if t_size == 0 {
459 capacity = 1024;
461 final_alloc_size = cache_line;
462 final_align = cache_line;
463 } else {
464 let min_elements = 2;
465 let min_required_size = data_offset + (t_size * min_elements);
466 let alloc_size = (min_required_size + cache_line - 1) & !(cache_line - 1);
467 final_align = if cache_line > align_of::<MaybeUninit<T>>() {
468 cache_line
469 } else {
470 align_of::<MaybeUninit<T>>()
471 };
472 final_alloc_size = (alloc_size + final_align - 1) & !(final_align - 1);
473 capacity = (final_alloc_size - data_offset) / t_size;
474 assert!(capacity >= min_elements);
476 }
477
478 match Layout::from_size_align(final_alloc_size, final_align) {
479 Ok(l) => (capacity, l),
480 Err(_) => panic!("Invalid layout"),
481 }
482 }
483
484 #[inline(always)]
486 const fn base_cap() -> usize {
487 Self::BASE_LAYOUT.0
488 }
489
490 #[inline(always)]
492 const fn large_cap() -> usize {
493 Self::LARGE_LAYOUT.0
494 }
495
496 #[inline(always)]
498 const fn data_offset() -> usize {
499 Self::DATA_OFFSET
500 }
501
502 #[inline]
505 unsafe fn alloc(prev: *mut SegHeader<T>, next: *mut SegHeader<T>, is_first: bool) -> Self {
506 let (cap, layout) = if is_first {
507 (Self::base_cap() as u32, Self::BASE_LAYOUT.1)
508 } else {
509 (Self::large_cap() as u32, Self::LARGE_LAYOUT.1)
510 };
511 let ptr: *mut u8 = unsafe { alloc(layout) };
512 if ptr.is_null() {
513 handle_alloc_error(layout);
514 }
515 unsafe {
516 let p = NonNull::new_unchecked(ptr as *mut SegHeader<T>);
517 let header = p.as_ptr();
518 (*header).count = 0;
520 (*header).cap = cap;
521 (*header).prev = prev;
522 (*header).next = next;
523 Self::from_raw(p)
524 }
525 }
526
527 #[inline(always)]
528 unsafe fn drop_items(&self) {
529 unsafe {
530 for i in 0..self.len() {
531 (*self.item_ptr(i)).assume_init_drop();
532 }
533 }
534 }
535
536 #[inline(always)]
537 unsafe fn dealloc_with_items(&mut self) {
538 unsafe {
539 if needs_drop::<T>() {
540 self.drop_items();
541 }
542 self.dealloc();
543 }
544 }
545
546 #[inline(always)]
547 unsafe fn dealloc(&mut self) {
548 unsafe {
550 let cap = (*self.header.as_ptr()).cap as usize;
551 let layout =
552 if cap == Self::base_cap() { Self::BASE_LAYOUT.1 } else { Self::LARGE_LAYOUT.1 };
553 dealloc(self.header.as_ptr() as *mut u8, layout);
554 }
555 }
556
557 #[inline(always)]
558 unsafe fn from_raw(header: NonNull<SegHeader<T>>) -> Self {
559 Self { header }
560 }
561
562 #[inline(always)]
564 fn len(&self) -> usize {
565 unsafe { (*self.header.as_ptr()).count as usize }
566 }
567
568 #[inline(always)]
569 fn get_header(&self) -> &SegHeader<T> {
570 unsafe { self.header.as_ref() }
571 }
572
573 #[inline(always)]
574 fn get_header_mut(&mut self) -> &mut SegHeader<T> {
575 unsafe { self.header.as_mut() }
576 }
577
578 #[inline(always)]
580 fn is_empty(&self) -> bool {
581 self.len() == 0
582 }
583
584 #[inline(always)]
586 fn is_full(&self) -> bool {
587 let header = self.get_header();
588 header.count >= header.cap
589 }
590
591 #[inline]
593 fn item_ptr(&self, index: usize) -> *mut MaybeUninit<T> {
594 unsafe {
595 let items =
596 (self.header.as_ptr() as *mut u8).add(Self::data_offset()) as *mut MaybeUninit<T>;
597 items.add(index)
598 }
599 }
600
601 #[inline]
603 fn push(&mut self, item: T) {
604 debug_assert!(!self.is_full());
605 let idx = self.get_header().count as usize;
606 unsafe {
607 (*self.item_ptr(idx)).write(item);
608 }
609 self.get_header_mut().count = (idx + 1) as u32;
610 }
611
612 #[inline]
614 fn pop(&mut self) -> (T, bool) {
615 debug_assert!(!self.is_empty());
616 let idx = self.get_header().count - 1;
617 let item = unsafe { (*self.item_ptr(idx as usize)).assume_init_read() };
618 self.get_header_mut().count = idx;
619 (item, idx == 0)
620 }
621}
622
623struct IterBase<T> {
627 cur: Segment<T>,
628 cur_idx: usize,
629 remaining: usize,
630 forward: bool,
631}
632
633impl<T> IterBase<T> {
634 #[inline]
636 fn next(&mut self) -> Option<*mut MaybeUninit<T>> {
637 if self.remaining == 0 {
638 return None;
639 }
640 self.remaining -= 1;
641
642 if self.forward {
643 let cur_header = self.cur.get_header();
644 let idx = if self.cur_idx >= cur_header.count as usize {
645 let next = cur_header.next;
646 self.cur = unsafe { Segment::from_raw(NonNull::new_unchecked(next)) };
647 self.cur_idx = 1;
648 0
649 } else {
650 let _idx = self.cur_idx;
651 self.cur_idx = _idx + 1;
652 _idx
653 };
654 Some(self.cur.item_ptr(idx))
655 } else {
656 let idx = self.cur_idx;
657 let item_ptr = self.cur.item_ptr(idx);
658 if self.cur_idx == 0 {
659 let cur_header = self.cur.get_header();
660 if !cur_header.prev.is_null() {
661 self.cur =
662 unsafe { Segment::from_raw(NonNull::new_unchecked(cur_header.prev)) };
663 let prev_header = self.cur.get_header();
664 self.cur_idx = prev_header.count as usize - 1;
665 }
666 } else {
667 self.cur_idx -= 1;
668 }
669 Some(item_ptr)
670 }
671 }
672
673 #[inline]
674 fn size_hint(&self) -> (usize, Option<usize>) {
675 (self.remaining, Some(self.remaining))
676 }
677}
678
679pub struct SegListIter<'a, T> {
681 base: IterBase<T>,
682 _marker: core::marker::PhantomData<&'a T>,
683}
684
685impl<'a, T> Iterator for SegListIter<'a, T> {
686 type Item = &'a T;
687
688 #[inline]
689 fn next(&mut self) -> Option<Self::Item> {
690 self.base.next().map(|ptr| unsafe { (*ptr).assume_init_ref() })
691 }
692
693 #[inline]
694 fn size_hint(&self) -> (usize, Option<usize>) {
695 self.base.size_hint()
696 }
697}
698
699impl<'a, T> ExactSizeIterator for SegListIter<'a, T> {}
700
701pub struct SegListIterMut<'a, T> {
703 base: IterBase<T>,
704 _marker: core::marker::PhantomData<&'a mut T>,
705}
706
707impl<'a, T> Iterator for SegListIterMut<'a, T> {
708 type Item = &'a mut T;
709
710 #[inline]
711 fn next(&mut self) -> Option<Self::Item> {
712 self.base.next().map(|ptr| unsafe { (*ptr).assume_init_mut() })
713 }
714
715 #[inline]
716 fn size_hint(&self) -> (usize, Option<usize>) {
717 self.base.size_hint()
718 }
719}
720
721impl<'a, T> ExactSizeIterator for SegListIterMut<'a, T> {}
722
723pub struct SegListDrain<T> {
726 cur: Option<Segment<T>>,
727 cur_idx: usize,
728 forward: bool,
729}
730
731impl<T> Iterator for SegListDrain<T> {
732 type Item = T;
733
734 #[inline]
735 fn next(&mut self) -> Option<Self::Item> {
736 let cur_seg = self.cur.as_mut()?;
737 unsafe {
738 let item = (*cur_seg.item_ptr(self.cur_idx)).assume_init_read();
739 let header = cur_seg.get_header();
740 if self.forward {
741 let next_idx = self.cur_idx + 1;
742 if next_idx >= header.count as usize {
743 let next = header.next;
744 cur_seg.dealloc();
745 if next.is_null() {
746 self.cur = None;
747 } else {
748 self.cur = Some(Segment::from_raw(NonNull::new_unchecked(next)));
749 self.cur_idx = 0;
750 }
751 } else {
752 self.cur_idx = next_idx;
753 }
754 } else if self.cur_idx == 0 {
755 let prev = header.prev;
756 cur_seg.dealloc();
757 if prev.is_null() {
758 self.cur = None;
759 } else {
760 let _cur = Segment::from_raw(NonNull::new_unchecked(prev));
761 self.cur_idx = _cur.get_header().count as usize - 1;
762 self.cur = Some(_cur);
763 }
764 } else {
765 self.cur_idx -= 1;
766 }
767 Some(item)
768 }
769 }
770
771 #[inline]
772 fn size_hint(&self) -> (usize, Option<usize>) {
773 let remaining = if let Some(_cur) = &self.cur {
774 1 } else {
778 0
779 };
780 (remaining, None)
781 }
782}
783
784impl<T> Drop for SegListDrain<T> {
785 fn drop(&mut self) {
786 if let Some(mut cur) = self.cur.take() {
787 unsafe {
788 if self.forward {
789 let header = cur.get_header();
791 let mut next = header.next;
792 if needs_drop::<T>() {
794 for i in self.cur_idx..header.count as usize {
795 (*cur.item_ptr(i)).assume_init_drop();
796 }
797 }
798 cur.dealloc();
799 while !next.is_null() {
800 cur = Segment::from_raw(NonNull::new_unchecked(next));
801 next = cur.get_header().next;
802 cur.dealloc_with_items();
803 }
804 } else {
805 let mut prev = cur.get_header().prev;
807 if needs_drop::<T>() {
809 for i in 0..=self.cur_idx {
810 (*cur.item_ptr(i)).assume_init_drop();
811 }
812 }
813 cur.dealloc();
814 while !prev.is_null() {
815 cur = Segment::from_raw(NonNull::new_unchecked(prev));
816 prev = cur.get_header().prev;
817 cur.dealloc_with_items();
818 }
819 }
820 }
821 }
822 }
823}
824
825#[cfg(test)]
826mod tests {
827 use super::*;
828 use crate::test::{CounterI32, alive_count, reset_alive_count};
829
830 #[test]
831 fn test_multiple_segments() {
832 let mut list: SegList<i32> = SegList::new();
833 if CACHE_LINE_SIZE == 128 {
834 assert_eq!(Segment::<i32>::base_cap(), 26);
835 }
836
837 for i in 0..100 {
838 list.push(i);
839 }
840
841 assert_eq!(list.len(), 100);
842
843 for i in (0..100).rev() {
844 assert_eq!(list.pop(), Some(i));
845 }
846
847 assert_eq!(list.pop(), None);
848 }
849
850 #[test]
851 fn test_iter_single_segment() {
852 let mut list: SegList<i32> = SegList::new();
854
855 for i in 0..10 {
856 list.push(i);
857 }
858 assert_eq!(list.first(), Some(&0));
859 assert_eq!(list.last(), Some(&9));
860
861 let collected: Vec<i32> = list.iter().copied().collect();
863 assert_eq!(collected, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
864
865 for item in list.iter_mut() {
867 *item *= 2;
868 }
869 assert_eq!(list.first(), Some(&0));
870 assert_eq!(list.last(), Some(&18));
871
872 let collected: Vec<i32> = list.iter().copied().collect();
874 assert_eq!(collected, vec![0, 2, 4, 6, 8, 10, 12, 14, 16, 18]);
875
876 for i in (0..10).rev() {
878 assert_eq!(list.pop(), Some(i * 2));
879 }
880 assert_eq!(list.pop(), None);
881 assert!(list.is_empty());
882 }
883
884 #[test]
885 fn test_iter_multi_segment() {
886 let mut list: SegList<i32> = SegList::new();
888
889 for i in 0..200 {
890 list.push(i * 10);
891 }
892 assert_eq!(list.first(), Some(&0));
893 assert_eq!(list.last(), Some(&1990));
894
895 let collected: Vec<i32> = list.iter().copied().collect();
897 let expected: Vec<i32> = (0..200).map(|i| i * 10).collect();
898 assert_eq!(collected, expected);
899
900 for item in list.iter_mut() {
902 *item += 1;
903 }
904 assert_eq!(list.first(), Some(&1));
905 assert_eq!(list.last(), Some(&1991));
906
907 let collected: Vec<i32> = list.iter().copied().collect();
909 let expected: Vec<i32> = (0..200).map(|i| i * 10 + 1).collect();
910 assert_eq!(collected, expected);
911
912 for i in (0..200).rev() {
914 assert_eq!(list.pop(), Some(i * 10 + 1));
915 }
916 assert_eq!(list.pop(), None);
917 assert!(list.is_empty());
918 }
919
920 #[test]
921 fn test_drain() {
922 let cap = Segment::<CounterI32>::base_cap();
924
925 {
927 reset_alive_count();
928 {
929 let mut list: SegList<CounterI32> = SegList::new();
930 for i in 0..5 {
932 list.push(CounterI32::new(i));
933 }
934 assert!(list.len() < cap);
935
936 let drained: Vec<i32> = list.drain().map(|d| *d).collect();
938 assert_eq!(drained, vec![0, 1, 2, 3, 4]);
939 }
940 assert_eq!(alive_count(), 0);
942 }
943
944 {
946 reset_alive_count();
947 {
948 let mut list: SegList<CounterI32> = SegList::new();
949 let total = cap * 2 + 5;
951 for i in 0..total {
952 list.push(CounterI32::new(i as i32));
953 }
954 assert_eq!(alive_count(), cap * 2 + 5);
955
956 let drain_count = cap / 2;
958 let mut drain_iter = list.drain();
959 for i in 0..drain_count {
960 assert_eq!(*drain_iter.next().unwrap(), i as i32);
961 }
962 drop(drain_iter);
964 }
965 assert_eq!(alive_count(), 0);
967 }
968
969 {
971 reset_alive_count();
972 {
973 let mut list: SegList<CounterI32> = SegList::new();
974 let total = cap * 2 + 3;
976 for i in 0..total {
977 list.push(CounterI32::new(i as i32));
978 }
979 assert_eq!(alive_count(), cap * 2 + 3);
980
981 let mut drain_iter = list.drain();
983 for i in 0..cap {
984 assert_eq!(*drain_iter.next().unwrap(), i as i32);
985 }
986 drop(drain_iter);
988 }
989 assert_eq!(alive_count(), 0);
991 }
992 }
993
994 #[test]
995 fn test_drop_single_segment() {
996 reset_alive_count();
997 {
998 let mut list: SegList<CounterI32> = SegList::new();
999 let cap = Segment::<CounterI32>::base_cap();
1000
1001 for i in 0..5 {
1003 list.push(CounterI32::new(i));
1004 }
1005 assert!(list.len() < cap);
1006 assert_eq!(alive_count(), 5);
1007
1008 }
1010
1011 assert_eq!(alive_count(), 0);
1012 }
1013
1014 #[test]
1015 fn test_drop_multi_segment() {
1016 let cap = Segment::<CounterI32>::base_cap();
1017 reset_alive_count();
1018 {
1019 let mut list: SegList<CounterI32> = SegList::new();
1020
1021 let total = cap * 2 + 10;
1023 for i in 0..total {
1024 list.push(CounterI32::new(i as i32));
1025 }
1026 assert_eq!(alive_count(), cap * 2 + 10);
1027 }
1029 assert_eq!(alive_count(), 0);
1030 }
1031
1032 #[test]
1033 fn test_clear_1_segment() {
1034 reset_alive_count();
1035 {
1036 let mut list: SegList<CounterI32> = SegList::new();
1037 let base_cap = Segment::<CounterI32>::base_cap();
1038
1039 for i in 0..base_cap as i32 {
1040 list.push(CounterI32::new(i));
1041 }
1042 assert_eq!(alive_count(), base_cap);
1043 list.clear();
1044 assert!(list.is_empty());
1045 assert_eq!(list.len(), 0);
1046 assert!(list.pop().is_none());
1047 }
1048 assert_eq!(alive_count(), 0);
1049 }
1050
1051 #[test]
1052 fn test_clear_2_segment() {
1053 reset_alive_count();
1054 {
1055 let mut list: SegList<CounterI32> = SegList::new();
1056
1057 let count = Segment::<CounterI32>::base_cap() + Segment::<CounterI32>::large_cap();
1058 for i in 0..count as i32 {
1059 list.push(CounterI32::new(i));
1060 }
1061 assert_eq!(alive_count(), count);
1062 list.clear();
1063 assert!(list.is_empty());
1064 assert_eq!(list.len(), 0);
1065 assert!(list.pop().is_none());
1066 }
1067 assert_eq!(alive_count(), 0);
1068 }
1069
1070 #[test]
1071 fn test_clear_3_segment() {
1072 reset_alive_count();
1073 let mut list: SegList<CounterI32> = SegList::new();
1074
1075 let count = Segment::<CounterI32>::base_cap() + Segment::<CounterI32>::large_cap() * 2;
1076 for i in 0..count as i32 {
1077 list.push(CounterI32::new(i));
1078 }
1079 assert_eq!(alive_count(), count);
1080 list.clear();
1081 assert!(list.is_empty());
1082 assert_eq!(list.len(), 0);
1083 assert!(list.pop().is_none());
1084 assert_eq!(alive_count(), 0);
1085 }
1086
1087 #[derive(Debug, Clone, Copy, PartialEq)]
1089 struct LargeStruct {
1090 data: [u64; 16], }
1092
1093 impl LargeStruct {
1094 fn new(val: u64) -> Self {
1095 Self { data: [val; 16] }
1096 }
1097 }
1098
1099 #[test]
1100 fn test_size() {
1101 println!("SegList<u64>: {}", size_of::<SegList<u64>>());
1102 println!("SegList<(u64, u32)>: {}", size_of::<SegList<(u64, u32)>>());
1103 assert_eq!(size_of::<SegHeader::<LargeStruct>>(), 24);
1104 let data_offset = Segment::<LargeStruct>::data_offset();
1105 let base_cap = Segment::<LargeStruct>::base_cap();
1106 let large_cap = Segment::<LargeStruct>::large_cap();
1107 let base_layout = Segment::<LargeStruct>::BASE_LAYOUT.1;
1108 let large_layout = Segment::<LargeStruct>::LARGE_LAYOUT.1;
1109 println!(
1110 "LargeStruct: offset={}, base(cap={} size={} align={}), large(cap={} size={} align={})",
1111 data_offset,
1112 base_cap,
1113 base_layout.size(),
1114 base_layout.align(),
1115 large_cap,
1116 large_layout.size(),
1117 large_layout.align()
1118 );
1119 let data_offset = Segment::<u64>::data_offset();
1120 let base_cap = Segment::<u64>::base_cap();
1121 let large_cap = Segment::<u64>::large_cap();
1122 let base_layout = Segment::<u64>::BASE_LAYOUT.1;
1123 let large_layout = Segment::<u64>::LARGE_LAYOUT.1;
1124 println!(
1125 "u64: 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::<u32>::data_offset();
1135 let base_cap = Segment::<u32>::base_cap();
1136 let large_cap = Segment::<u32>::large_cap();
1137 let base_layout = Segment::<u32>::BASE_LAYOUT.1;
1138 let large_layout = Segment::<u32>::LARGE_LAYOUT.1;
1139 println!(
1140 "u32: 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::<u16>::data_offset();
1150 let base_cap = Segment::<u16>::base_cap();
1151 let large_cap = Segment::<u16>::large_cap();
1152 let base_layout = Segment::<u16>::BASE_LAYOUT.1;
1153 let large_layout = Segment::<u16>::LARGE_LAYOUT.1;
1154 println!(
1155 "u16: 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 }
1165
1166 #[test]
1167 fn test_large_type_push_pop() {
1168 let mut list: SegList<LargeStruct> = SegList::new();
1169 for i in 0..50 {
1171 list.push(LargeStruct::new(i));
1172 }
1173 assert_eq!(list.len(), 50);
1174
1175 for i in (0..50).rev() {
1177 let val = list.pop().unwrap();
1178 assert_eq!(val.data[0], i);
1179 assert_eq!(val.data[7], i);
1180 }
1181 assert!(list.is_empty());
1182 assert_eq!(list.pop(), None);
1183 }
1184
1185 #[test]
1186 fn test_large_type_iter() {
1187 let mut list: SegList<LargeStruct> = SegList::new();
1188
1189 for i in 0..30 {
1191 list.push(LargeStruct::new(i * 10));
1192 }
1193
1194 let collected: Vec<u64> = list.iter().map(|s| s.data[0]).collect();
1196 let expected: Vec<u64> = (0..30).map(|i| i * 10).collect();
1197 assert_eq!(collected, expected);
1198 }
1199
1200 #[test]
1201 fn test_large_type_iter_mut() {
1202 let mut list: SegList<LargeStruct> = SegList::new();
1203
1204 for i in 0..20 {
1206 list.push(LargeStruct::new(i));
1207 }
1208
1209 for item in list.iter_mut() {
1211 item.data[0] *= 2;
1212 }
1213
1214 let collected: Vec<u64> = list.iter().map(|s| s.data[0]).collect();
1216 let expected: Vec<u64> = (0..20).map(|i| i * 2).collect();
1217 assert_eq!(collected, expected);
1218 }
1219
1220 #[test]
1221 fn test_large_type_drain() {
1222 let mut list: SegList<LargeStruct> = SegList::new();
1223
1224 for i in 0..40 {
1226 list.push(LargeStruct::new(i));
1227 }
1228
1229 let drained: Vec<u64> = list.drain().map(|s| s.data[0]).collect();
1231 let expected: Vec<u64> = (0..40).collect();
1232 assert_eq!(drained, expected);
1233 }
1234
1235 #[test]
1236 fn test_large_type_clear() {
1237 let mut list: SegList<LargeStruct> = SegList::new();
1238
1239 for i in 0..60 {
1241 list.push(LargeStruct::new(i));
1242 }
1243 assert_eq!(list.len(), 60);
1244
1245 list.clear();
1247 assert!(list.is_empty());
1248 assert_eq!(list.len(), 0);
1249 assert_eq!(list.pop(), None);
1250 }
1251
1252 #[test]
1253 fn test_iter_rev_single_segment() {
1254 let mut list: SegList<i32> = SegList::new();
1256
1257 for i in 0..10 {
1258 list.push(i);
1259 }
1260
1261 let collected: Vec<i32> = list.iter_rev().copied().collect();
1263 let expected: Vec<i32> = (0..10).rev().collect();
1264 assert_eq!(collected, expected);
1265
1266 for item in list.iter_mut_rev() {
1268 *item *= 10;
1269 }
1270
1271 assert_eq!(list.first(), Some(&0));
1273 assert_eq!(list.last(), Some(&90));
1274
1275 let collected: Vec<i32> = list.iter().copied().collect();
1276 let expected: Vec<i32> = vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90];
1277 assert_eq!(collected, expected);
1278 }
1279
1280 #[test]
1281 fn test_iter_rev_multi_segment() {
1282 let mut list: SegList<i32> = SegList::new();
1284
1285 for i in 0..200 {
1286 list.push(i);
1287 }
1288
1289 let collected: Vec<i32> = list.iter_rev().copied().collect();
1291 let expected: Vec<i32> = (0..200).rev().collect();
1292 assert_eq!(collected, expected);
1293
1294 for item in list.iter_mut_rev() {
1296 *item += 1000;
1297 }
1298
1299 assert_eq!(list.first(), Some(&1000));
1301 assert_eq!(list.last(), Some(&1199));
1302
1303 let collected: Vec<i32> = list.iter().copied().collect();
1304 let expected: Vec<i32> = (0..200).map(|i| i + 1000).collect();
1305 assert_eq!(collected, expected);
1306 }
1307
1308 #[test]
1309 fn test_iter_rev_empty() {
1310 let list: SegList<i32> = SegList::new();
1311
1312 let collected: Vec<i32> = list.iter_rev().copied().collect();
1313 assert!(collected.is_empty());
1314
1315 let mut list_mut: SegList<i32> = SegList::new();
1316 let count = list_mut.iter_mut_rev().count();
1317 assert_eq!(count, 0);
1318 }
1319
1320 #[test]
1321 fn test_iter_rev_exact_size() {
1322 let mut list: SegList<i32> = SegList::new();
1323
1324 for i in 0..50 {
1325 list.push(i);
1326 }
1327
1328 let iter = list.iter_rev();
1330 assert_eq!(iter.len(), 50);
1331
1332 let mut iter = list.iter_rev();
1333 assert_eq!(iter.len(), 50);
1334 iter.next();
1335 assert_eq!(iter.len(), 49);
1336 iter.next();
1337 assert_eq!(iter.len(), 48);
1338
1339 let mut iter_mut = list.iter_mut_rev();
1341 assert_eq!(iter_mut.len(), 50);
1342 iter_mut.next();
1343 assert_eq!(iter_mut.len(), 49);
1344 }
1345
1346 #[test]
1347 fn test_into_rev_single_segment() {
1348 let mut list: SegList<i32> = SegList::new();
1350
1351 for i in 0..10 {
1352 list.push(i);
1353 }
1354
1355 let drained: Vec<i32> = list.into_rev().collect();
1357 let expected: Vec<i32> = (0..10).rev().collect();
1358 assert_eq!(drained, expected);
1359 }
1360
1361 #[test]
1362 fn test_into_rev_multi_segment() {
1363 let mut list: SegList<i32> = SegList::new();
1365
1366 for i in 0..200 {
1367 list.push(i);
1368 }
1369
1370 let drained: Vec<i32> = list.into_rev().collect();
1372 let expected: Vec<i32> = (0..200).rev().collect();
1373 assert_eq!(drained, expected);
1374 }
1375
1376 #[test]
1377 fn test_into_rev_empty() {
1378 let list: SegList<i32> = SegList::new();
1379
1380 let drained: Vec<i32> = list.into_rev().collect();
1381 assert!(drained.is_empty());
1382 }
1383
1384 #[test]
1385 fn test_into_rev_partial() {
1386 let mut list: SegList<i32> = SegList::new();
1388
1389 for i in 0..50 {
1390 list.push(i);
1391 }
1392
1393 let mut drain = list.into_rev();
1395 let mut drained = Vec::new();
1396 for _ in 0..25 {
1397 if let Some(item) = drain.next() {
1398 drained.push(item);
1399 }
1400 }
1401 drop(drain);
1403
1404 let expected: Vec<i32> = (25..50).rev().collect();
1406 assert_eq!(drained, expected);
1407 }
1408}