Skip to main content

embed_collections/
seg_list.rs

1//! Segmented List - A segmented list with cache-friendly node sizes.
2//!
3//! Support push() / pop() from the tail, and one-time consume all elements.
4//! It does not support random access.
5//!
6//! Each segment's capacity is calculated at runtime based on T's size
7//! to fit within a cache line. (The first segment is 2* CACHE_LINE_SIZE, the subsequent allocation
8//! use CACHE_LINE_SIZE * 4)
9//!
10//! It's faster than Vec when the number of items is small (1~64), because it does not re-allocate
11//! during `push()`. It's slower than Vec when the number is very large (due to pointer dereference cost).
12//!
13//! # NOTE
14//!
15//! T is allow to larger than `2 * CACHE_LINE_SIZE`, in this case `SegList` will ensure at least 2
16//! items in one segment. But it's not efficient when T larger than 64B, you should consider put T into Box.
17//!
18//! # Example
19//!
20//! ```rust
21//! use embed_collections::seg_list::SegList;
22//!
23//! // Create a new SegList
24//! let mut list: SegList<i32> = SegList::new();
25//!
26//! // Push elements to the back
27//! list.push(10);
28//! list.push(20);
29//! list.push(30);
30//!
31//! assert_eq!(list.len(), 3);
32//! assert_eq!(list.first(), Some(&10));
33//! assert_eq!(list.last(), Some(&30));
34//!
35//! // Pop elements from the back (LIFO order)
36//! assert_eq!(list.pop(), Some(30));
37//! assert_eq!(list.pop(), Some(20));
38//! assert_eq!(list.pop(), Some(10));
39//! assert_eq!(list.pop(), None);
40//! assert!(list.is_empty());
41//!
42//! // Iterate over elements
43//! list.push(1);
44//! list.push(2);
45//! list.push(3);
46//! let sum: i32 = list.iter().sum();
47//! assert_eq!(sum, 6);
48//!
49//! // Mutable iteration
50//! for item in list.iter_mut() {
51//!     *item *= 10;
52//! }
53//! assert_eq!(list.last(), Some(&30));
54//!
55//! // Drain all elements (consumes the list)
56//! let drained: Vec<i32> = list.drain().collect();
57//! assert_eq!(drained, vec![10, 20, 30]);
58//! ```
59
60use 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
66/// Segmented list with cache-friendly segment sizes.
67///
68/// Support push() / pop() from the tail, and one-time consume all elements.
69/// It does not support random access.
70///
71/// Each segment's capacity is calculated at runtime based on T's size
72/// to fit within a cache line. (The first segment is 2 * CACHE_LINE_SIZE, the subsequent allocation
73/// use CACHE_LINE_SIZE * 4)
74///
75/// It's faster than Vec when the number of items is small (1~64), because it does not re-allocate
76/// during `push()`. It's slower than Vec when the number is very large (due to pointer dereference cost).
77///
78/// # NOTE
79///
80/// T is allow to larger than `2 * CACHE_LINE_SIZE`, in this case SegList will ensure at least 2
81/// items in one segment. But it's not efficient when T larger than 128B, you should consider put T into Box.
82///
83/// Refer to [module level](crate::seg_list) doc for examples.
84pub struct SegList<T> {
85    /// Pointer to the last segment (tail.get_header().next points to first element), to reduce the main struct size
86    tail: NonNull<SegHeader<T>>,
87    /// Total number of elements in the list
88    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    /// Create a new empty SegList with one allocated segment
96    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        // Make it circular: tail.next points to head (itself for now)
101        header.next = header_ptr;
102        Self { tail: seg.header, count: 0 }
103    }
104
105    /// Returns true if the list is empty
106    #[inline(always)]
107    pub fn is_empty(&self) -> bool {
108        self.count == 0
109    }
110
111    /// Get the base capacity of the first segment
112    #[inline(always)]
113    pub const fn segment_cap() -> usize {
114        Segment::<T>::base_cap()
115    }
116
117    /// Returns the total number of elements in the list
118    #[inline(always)]
119    pub fn len(&self) -> usize {
120        self.count
121    }
122
123    /// Push an element to the back of the list
124    #[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                // Subsequent segments use LARGE_LAYOUT (cacheline * 2)
132                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    /// Pop an element from the back of the list
143    #[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                    // More than one segment: remove tail segment
157                    self.tail = NonNull::new_unchecked(cur_prev);
158                    (*self.tail.as_ptr()).next = first_ptr;
159                    tail_seg.dealloc();
160                }
161                // If only one segment, keep it for future use
162            }
163            self.count -= 1;
164            Some(item)
165        }
166    }
167
168    // Break the cycle and free all segments
169    #[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        // SAFETY: tail always points to a valid segment with at least one element.
180        // get first segment through next ptr from the tail
181        unsafe {
182            let tail_header = self.tail.as_ref();
183            let first = tail_header.next;
184            NonNull::new_unchecked(first)
185        }
186    }
187
188    /// Returns an iterator over the list
189    #[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    /// Returns a reverse iterator over the list
199    #[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    /// Returns a mutable iterator over the list
216    #[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    /// Returns a mutable reverse iterator over the list
226    #[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    /// Returns a draining iterator that consumes the list and yields elements from head to tail
243    pub fn drain(mut self) -> SegListDrain<T> {
244        // Break the cycle and get the first segment
245        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        // To prevent drop from being called
255        core::mem::forget(self);
256        SegListDrain { cur, cur_idx: 0, forward: true }
257    }
258
259    /// Returns a draining iterator that consumes the list and yields elements from tail to head
260    pub fn into_rev(mut self) -> SegListDrain<T> {
261        // break the cycle
262        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    /// Returns a reference to the first element in the list
279    #[inline]
280    pub fn first(&self) -> Option<&T> {
281        if self.count == 0 {
282            return None;
283        }
284        // SAFETY: tail always points to a valid segment with at least one element.
285        // get first segment through next ptr from the tail
286        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    /// Returns a mut reference to the first element in the list
293    #[inline]
294    pub fn first_mut(&self) -> Option<&T> {
295        if self.count == 0 {
296            return None;
297        }
298        // SAFETY: tail always points to a valid segment with at least one element.
299        // get first segment through next ptr from the tail
300        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    /// Returns a reference to the last element in the list
307    #[inline]
308    pub fn last(&self) -> Option<&T> {
309        // SAFETY: tail always points to a valid segment with at least one element
310        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    /// Returns a mutable reference to the last element in the list
322    #[inline]
323    pub fn last_mut(&mut self) -> Option<&mut T> {
324        // SAFETY: tail always points to a valid segment with at least one element
325        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    /// Clear all elements from the list
337    #[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        // Break the cycle and get the first segment
376        let mut cur = self.break_first_node();
377        loop {
378            // Save next pointer before dealloc
379            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/// Segment header containing metadata
406#[repr(C)]
407struct SegHeader<T> {
408    /// Count of valid elements in this segment
409    count: u32,
410    /// Capacity of this segment (may vary for different segments)
411    cap: u32,
412    prev: *mut SegHeader<T>,
413    /// Next segment in the list
414    next: *mut SegHeader<T>,
415    _marker: core::marker::PhantomData<T>,
416}
417
418/// A segment containing header and element storage
419struct Segment<T> {
420    /// Pointer to the header
421    header: NonNull<SegHeader<T>>,
422}
423
424impl<T> Segment<T> {
425    // data_offset is the same for both base and large layouts
426    const DATA_OFFSET: usize = Self::calc_data_offset();
427
428    // Pre-calculate layout for cacheline-sized segment (first segment)
429    // (cap, layout)
430    const BASE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 2);
431
432    // Pre-calculate layout for cacheline*2-sized segment (subsequent segments)
433    // (cap, layout)
434    const LARGE_LAYOUT: (usize, Layout) = Self::calc_layout_const(CACHE_LINE_SIZE * 4);
435
436    /// Const fn to calculate data offset (same for all segments)
437    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 to calculate layout for a given cache line size
449    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            // 0-size does not actually take place
458            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            // rust 1.57 support assert in const fn
473            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    /// Get the base capacity (first segment's capacity)
483    #[inline(always)]
484    const fn base_cap() -> usize {
485        Self::BASE_LAYOUT.0
486    }
487
488    /// Get the large capacity (subsequent segments' capacity)
489    #[inline(always)]
490    const fn large_cap() -> usize {
491        Self::LARGE_LAYOUT.0
492    }
493
494    /// Get the data offset (offset of first element from header start)
495    #[inline(always)]
496    const fn data_offset() -> usize {
497        Self::DATA_OFFSET
498    }
499
500    /// Create a new empty segment
501    /// is_first: true for first segment (uses BASE_LAYOUT), false for subsequent (uses LARGE_LAYOUT)
502    #[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            // Initialize header
517            (*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        // Deallocate the entire segment (header + items)
547        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    /// Get the count of valid elements in this segment
561    #[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    /// Check if segment has no valid elements
577    #[inline(always)]
578    fn is_empty(&self) -> bool {
579        self.len() == 0
580    }
581
582    /// Check if segment is full
583    #[inline(always)]
584    fn is_full(&self) -> bool {
585        let header = self.get_header();
586        header.count >= header.cap
587    }
588
589    /// Get pointer to item at index
590    #[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    /// Push an element to this segment (if not full)
600    #[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    /// return (item, is_empty_now)
611    #[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
621/// Base iterator implementation shared by immutable and mutable iterators.
622/// Manages iteration state and returns raw pointers to elements.
623/// `forward` is true for forward iteration, false for backward iteration.
624struct IterBase<T> {
625    cur: Segment<T>,
626    cur_idx: usize,
627    remaining: usize,
628    forward: bool,
629}
630
631impl<T> IterBase<T> {
632    /// Advances the iterator and returns a pointer to the next element's MaybeUninit.
633    #[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
677/// Immutable iterator over SegList
678pub 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
699/// Mutable iterator over SegList
700pub 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
721/// Draining iterator over SegList
722/// Consumes elements from head to tail (FIFO order) or tail to head (LIFO order)
723pub 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            // Estimate remaining elements - this is approximate for backward iteration
773            // across multiple segments, but sufficient for size_hint
774            1 // At least one element if cur is Some
775        } 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                    // Save next pointer before dealloc
788                    let header = cur.get_header();
789                    let mut next = header.next;
790                    // Drop remaining elements in this segment (from current index to end)
791                    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                    // Save prev pointer before dealloc
804                    let mut prev = cur.get_header().prev;
805                    // Drop remaining elements in this segment (from start to current index)
806                    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        // Test with small number of elements (single segment)
851        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        // Test immutable iterator
860        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        // Test mutable iterator - modify elements
864        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        // Verify modification
871        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        // Test pop() - should return elements in LIFO order
875        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        // Test with many elements (multiple segments)
885        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        // Test immutable iterator across multiple segments
894        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        // Test mutable iterator - modify elements
899        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        // Verify modification
906        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        // Test pop() - should return elements in LIFO order across multiple segments
911        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        // Get capacity per segment for CounterI32 (i32)
921        let cap = Segment::<CounterI32>::base_cap();
922
923        // Scenario 1: Single segment, drain completely
924        {
925            reset_alive_count();
926            {
927                let mut list: SegList<CounterI32> = SegList::new();
928                // Push fewer elements than one segment capacity
929                for i in 0..5 {
930                    list.push(CounterI32::new(i));
931                }
932                assert!(list.len() < cap);
933
934                // Drain all elements
935                let drained: Vec<i32> = list.drain().map(|d| *d).collect();
936                assert_eq!(drained, vec![0, 1, 2, 3, 4]);
937            }
938            // All 5 elements should be dropped by drain
939            assert_eq!(alive_count(), 0);
940        }
941
942        // Scenario 2: Three segments, drain first segment partially, then drop remaining
943        {
944            reset_alive_count();
945            {
946                let mut list: SegList<CounterI32> = SegList::new();
947                // Push elements to create 3 segments (cap * 2 + 5 = more than 2 segments)
948                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                // Drain only half of first segment
955                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 the drain iterator early (remaining elements should be dropped)
961                drop(drain_iter);
962            }
963            // All elements should be dropped (drained + remaining in list)
964            assert_eq!(alive_count(), 0);
965        }
966
967        // Scenario 3: Three segments, drain exactly first segment, then drop remaining
968        {
969            reset_alive_count();
970            {
971                let mut list: SegList<CounterI32> = SegList::new();
972                // Push elements to create 3 segments
973                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                // Drain exactly first segment
980                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 the drain iterator early
985                drop(drain_iter);
986            }
987            // All elements should be dropped
988            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            // Push fewer elements than one segment capacity
1000            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            // list drops here, should drop all elements
1007        }
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            // Push elements to create multiple segments (3 segments)
1020            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            // list drops here, should drop all elements across all segments
1026        }
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    /// Large struct that larger than cache line
1086    #[derive(Debug, Clone, Copy, PartialEq)]
1087    struct LargeStruct {
1088        data: [u64; 16], // 128 bytes
1089    }
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        // Push elements - each segment can only hold a few due to large element size
1168        for i in 0..50 {
1169            list.push(LargeStruct::new(i));
1170        }
1171        assert_eq!(list.len(), 50);
1172
1173        // Pop all elements - should work correctly across multiple segments
1174        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        // Push elements
1188        for i in 0..30 {
1189            list.push(LargeStruct::new(i * 10));
1190        }
1191
1192        // Test iterator
1193        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        // Push elements
1203        for i in 0..20 {
1204            list.push(LargeStruct::new(i));
1205        }
1206
1207        // Modify through iterator
1208        for item in list.iter_mut() {
1209            item.data[0] *= 2;
1210        }
1211
1212        // Verify modification
1213        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        // Push elements
1223        for i in 0..40 {
1224            list.push(LargeStruct::new(i));
1225        }
1226
1227        // Drain and verify FIFO order
1228        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        // Push elements
1238        for i in 0..60 {
1239            list.push(LargeStruct::new(i));
1240        }
1241        assert_eq!(list.len(), 60);
1242
1243        // Clear
1244        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        // Test with small number of elements (single segment)
1253        let mut list: SegList<i32> = SegList::new();
1254
1255        for i in 0..10 {
1256            list.push(i);
1257        }
1258
1259        // Test reverse iterator
1260        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        // Test mutable reverse iterator
1265        for item in list.iter_mut_rev() {
1266            *item *= 10;
1267        }
1268
1269        // Verify modification
1270        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        // Test with many elements (multiple segments)
1281        let mut list: SegList<i32> = SegList::new();
1282
1283        for i in 0..200 {
1284            list.push(i);
1285        }
1286
1287        // Test reverse iterator across multiple segments
1288        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        // Test mutable reverse iterator across multiple segments
1293        for item in list.iter_mut_rev() {
1294            *item += 1000;
1295        }
1296
1297        // Verify modification
1298        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        // Test ExactSizeIterator on reverse iterator
1327        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        // Test ExactSizeIterator on mutable reverse iterator
1338        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        // Test with small number of elements (single segment)
1347        let mut list: SegList<i32> = SegList::new();
1348
1349        for i in 0..10 {
1350            list.push(i);
1351        }
1352
1353        // Test into_rev - should yield elements in LIFO order
1354        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        // Test with many elements (multiple segments)
1362        let mut list: SegList<i32> = SegList::new();
1363
1364        for i in 0..200 {
1365            list.push(i);
1366        }
1367
1368        // Test into_rev - should yield elements in LIFO order across segments
1369        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        // Test partial consumption of into_rev
1385        let mut list: SegList<i32> = SegList::new();
1386
1387        for i in 0..50 {
1388            list.push(i);
1389        }
1390
1391        // Only drain half
1392        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 - remaining elements should be dropped properly
1400        drop(drain);
1401
1402        // Verify we got the last 25 elements in reverse order
1403        let expected: Vec<i32> = (25..50).rev().collect();
1404        assert_eq!(drained, expected);
1405    }
1406}