fast_list/
linked_list.rs

1use core::fmt;
2use slotmap::{new_key_type, SecondaryMap, SlotMap, SparseSecondaryMap};
3
4#[cfg(feature = "unstable")]
5use crate::{LinkedListWalker, Walker};
6
7new_key_type! {
8    /// A newtype for the index of an item in the list.
9    pub struct LinkedListIndex;
10}
11
12#[derive(Debug)]
13pub struct LinkedListItem<T> {
14    /// The index of the item in the list.
15    pub index: LinkedListIndex,
16    /// The value of the item.
17    pub value: T,
18    /// The index of the next item in the list.
19    pub next_index: Option<LinkedListIndex>,
20    /// The index of the previous item in the list.
21    pub prev_index: Option<LinkedListIndex>,
22}
23
24/// A doubly linked list using SlotMap for better cache performance than a linked list using pointers, and which also solves the ABA problem.
25pub struct LinkedList<T = ()> {
26    /// The index of the first item in the list.
27    pub head: Option<LinkedListIndex>,
28    /// The index of the last item in the list.
29    pub tail: Option<LinkedListIndex>,
30    /// The items in the list.
31    items: SlotMap<LinkedListIndex, LinkedListItem<T>>,
32}
33
34impl<T: fmt::Debug> fmt::Debug for LinkedList<T> {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        f.debug_list().entries(self.items.values()).finish()
37    }
38}
39
40impl<T> LinkedList<T> {
41    /// Create a new empty list.
42    pub fn new() -> Self {
43        Self {
44            head: None,
45            tail: None,
46            items: SlotMap::with_key(),
47        }
48    }
49
50    /// Checks if the list contains the given index.
51    pub fn contains_key(&self, index: LinkedListIndex) -> bool {
52        self.items.contains_key(index)
53    }
54
55    /// Get the first item in the list.
56    /// Can be None if the list is empty.
57    #[inline]
58    pub fn head(&self) -> Option<&LinkedListItem<T>> {
59        if let Some(head) = self.head {
60            self.get(head)
61        } else {
62            None
63        }
64    }
65
66    /// Get a mutable reference to the first item in the list.
67    /// Can be None if the list is empty.
68    #[inline]
69    pub fn head_mut(&mut self) -> Option<&mut LinkedListItem<T>> {
70        if let Some(head) = self.head {
71            self.get_mut(head)
72        } else {
73            None
74        }
75    }
76
77    /// Get the last item in the list.
78    /// Can be None if the list is empty.
79    #[inline]
80    pub fn tail(&self) -> Option<&LinkedListItem<T>> {
81        if let Some(tail) = self.tail {
82            self.get(tail)
83        } else {
84            None
85        }
86    }
87
88    /// Get a mutable reference to the last item in the list.
89    /// Can be None if the list is empty.
90    #[inline]
91    pub fn tail_mut(&mut self) -> Option<&mut LinkedListItem<T>> {
92        if let Some(tail) = self.tail {
93            self.get_mut(tail)
94        } else {
95            None
96        }
97    }
98
99    /// Convenience method to return a slotmap::SecondaryMap of type V
100    pub fn new_data<V>(&self) -> SecondaryMap<LinkedListIndex, V> {
101        SecondaryMap::new()
102    }
103
104    /// Convenience method to return a slotmap::SparseSecondaryMap of type V
105    pub fn new_data_sparse<V>(&self) -> SparseSecondaryMap<LinkedListIndex, V> {
106        SparseSecondaryMap::new()
107    }
108
109    /// Get an item in the list.
110    #[inline]
111    pub fn get(&self, index: LinkedListIndex) -> Option<&LinkedListItem<T>> {
112        self.items.get(index).map(|item| item)
113    }
114
115    /// Get a mutable reference to an item in the list.
116    #[inline]
117    pub fn get_mut(&mut self, index: LinkedListIndex) -> Option<&mut LinkedListItem<T>> {
118        let item = self.items.get_mut(index);
119        item
120    }
121
122    /// Get the item after the item with the given index if it exists.
123    #[inline]
124    pub fn next_of(&self, index: LinkedListIndex) -> Option<&LinkedListItem<T>> {
125        self.items
126            .get(index)
127            .and_then(|item| item.next_index.and_then(|next| self.items.get(next)))
128    }
129
130    /// Get the item before the item with the given index if it exists.
131    #[inline]
132    pub fn prev_of(&self, index: LinkedListIndex) -> Option<&LinkedListItem<T>> {
133        self.items
134            .get(index)
135            .and_then(|item| item.prev_index.and_then(|prev| self.items.get(prev)))
136    }
137
138    /// Get a mutable reference to the item after the item with the given index if it exists.
139    pub fn next_of_mut(&mut self, index: LinkedListIndex) -> Option<&mut LinkedListItem<T>> {
140        let item = self.items.get_mut(index);
141        let next = item.and_then(|item| item.prev_index);
142        if let Some(next) = next {
143            self.items.get_mut(next)
144        } else {
145            None
146        }
147    }
148
149    /// Get a mutable reference to the item before the item with the given index if it exists.
150    pub fn prev_of_mut(&mut self, index: LinkedListIndex) -> Option<&mut LinkedListItem<T>> {
151        let item = self.items.get_mut(index);
152        let prev = item.and_then(|item| item.prev_index);
153        if let Some(prev) = prev {
154            self.items.get_mut(prev)
155        } else {
156            None
157        }
158    }
159
160    /// Insert an item after the given index and return the index of the new item.
161    pub fn insert_after(&mut self, index: LinkedListIndex, value: T) -> LinkedListIndex {
162        let next_index = self.items.get(index).unwrap().next_index;
163
164        let new_index = self.items.insert_with_key(|i| LinkedListItem {
165            index: i,
166            value,
167            next_index: next_index,
168            prev_index: Some(index),
169        });
170
171        let items = &mut self.items;
172
173        if let Some(next) = next_index {
174            // If the element we insert after has a next element, we need to update the next element's `prev` to point to the new element.
175            items.get_mut(next).unwrap().prev_index = Some(new_index);
176        } else {
177            // If the element we insert after does not have a next element, we need to update the tail to point to the new element.
178            self.tail = Some(new_index);
179        }
180
181        if let Some(item) = items.get_mut(index) {
182            // Update the element we insert after to point its `prev` to the new element.
183            item.next_index = Some(new_index);
184        }
185
186        // Return the new element
187        new_index
188    }
189
190    /// Insert an item before the given index.
191    pub fn insert_before(&mut self, index: LinkedListIndex, value: T) -> LinkedListIndex {
192        let prev_index = self.items.get(index).unwrap().prev_index;
193
194        let new_index = self.items.insert_with_key(|i| LinkedListItem {
195            index: i,
196            value,
197            next_index: Some(index),
198            prev_index: prev_index,
199        });
200
201        let items = &mut self.items;
202
203        if let Some(prev) = prev_index {
204            // If the element we insert before has a previous element, we need to update the previous element's `next` to point to the new element.
205            items.get_mut(prev).unwrap().next_index = Some(new_index);
206        } else {
207            // If the element we insert before does not have a previous element, we need to update the head to point to the new element.
208            self.head = Some(new_index);
209        }
210
211        let item = items.get_mut(index).unwrap();
212        // Update the element we insert before to point its `prev` to the new element.
213        item.prev_index = Some(new_index);
214
215        new_index
216    }
217
218    /// Add an item to the back of the list and return its index.
219    pub fn push_back(&mut self, value: T) -> LinkedListIndex {
220        let index = self.items.insert_with_key(|i| LinkedListItem {
221            index: i,
222            value,
223            next_index: None,
224            prev_index: self.tail,
225        });
226
227        match self.tail {
228            Some(tail) => {
229                if let Some(tail) = self.items.get_mut(tail) {
230                    tail.next_index = Some(index);
231                }
232            }
233            None => {
234                self.head = Some(index);
235            }
236        }
237
238        self.tail = Some(index);
239
240        index
241    }
242
243    /// Push an item to the front of the list.
244    pub fn push_front(&mut self, value: T) -> LinkedListIndex {
245        let index = self.items.insert_with_key(|i| LinkedListItem {
246            index: i,
247            value,
248            next_index: self.head,
249            prev_index: None,
250        });
251
252        match self.head {
253            Some(head) => {
254                let head = self.items.get_mut(head);
255                head.unwrap().prev_index = Some(index);
256            }
257            None => {
258                self.tail = Some(index);
259            }
260        }
261
262        self.head = Some(index);
263
264        index
265    }
266
267    /// Remove the last item in the list and return it (if it exists)
268    pub fn pop_back(&mut self) -> Option<T> {
269        self.tail.and_then(|old_tail| {
270            let old_tail = self.items.remove(old_tail);
271
272            if let Some(old_tail) = old_tail {
273                self.tail = old_tail.prev_index;
274
275                match old_tail.prev_index {
276                    Some(prev) => {
277                        let prev_mut = self.items.get_mut(prev);
278                        prev_mut.unwrap().next_index = None
279                    }
280                    None => {
281                        self.head = None;
282                    }
283                }
284
285                Some(old_tail.value)
286            } else {
287                None
288            }
289        })
290    }
291
292    /// Remove the first item in the list and return it (if it exists)
293    pub fn pop_front(&mut self) -> Option<T> {
294        self.head.and_then(|old_head| {
295            let old_head = self.items.remove(old_head);
296            if let Some(old_head) = old_head {
297                self.head = old_head.next_index;
298                match old_head.next_index {
299                    Some(next) => {
300                        self.items.get_mut(next).unwrap().prev_index = None;
301                    }
302                    None => {
303                        self.tail = None;
304                    }
305                }
306                Some(old_head.value)
307            } else {
308                None
309            }
310        })
311    }
312
313    /// Convenience method for `list.iter_next(list.head.unwrap())`
314    /// # Example
315    /// ```
316    /// use fast_list::LinkedList;
317    /// let mut list = LinkedList::new();
318    /// list.extend(0..100);
319    ///
320    /// assert_eq!(list.iter_next(list.head.unwrap()).count(), 100);
321    /// assert_eq!(list.iter().count(), 100);
322    /// assert_eq!(
323    ///     list.iter().next().unwrap().value,
324    ///     list.iter_next(list.head.unwrap()).next().unwrap().value
325    /// );
326    /// ```
327    #[inline]
328    pub fn iter(&self) -> impl Iterator<Item = &LinkedListItem<T>> {
329        self.iter_next(self.head.unwrap())
330    }
331
332    /// Returns an iterator that iterates over the items of the list in no particular order.
333    #[inline]
334    pub fn iter_unordered(&self) -> impl Iterator<Item = &LinkedListItem<T>> {
335        self.items.values()
336    }
337
338    /// Returns an iterator that iterates over the items of the list.
339    #[inline]
340    pub fn iter_next(&self, start: LinkedListIndex) -> impl Iterator<Item = &LinkedListItem<T>> {
341        self.cursor_iter_next(start)
342            .map(move |index| self.items.get(index).unwrap())
343    }
344
345    /// Returns an iterator that iterates over the items of the list in reverse order.
346    #[inline]
347    pub fn iter_prev(&self, start: LinkedListIndex) -> impl Iterator<Item = &LinkedListItem<T>> {
348        self.cursor_iter_prev(start)
349            .map(move |index| self.items.get(index).unwrap())
350    }
351
352    /// Returns the next index of the item with the given index.
353    pub fn cursor_next(&self, item: LinkedListIndex) -> Option<LinkedListIndex> {
354        self.items.get(item).and_then(|item| item.next_index)
355    }
356
357    /// Returns the previous index of the item with the given index.
358    pub fn cursor_prev(&self, item: LinkedListIndex) -> Option<LinkedListIndex> {
359        self.items.get(item).and_then(|item| item.next_index)
360    }
361
362    /// Returns an iterator that iterates over the indexes of the list.
363    pub fn cursor_iter_next(
364        &self,
365        start: LinkedListIndex,
366    ) -> impl Iterator<Item = LinkedListIndex> + '_ {
367        let items = &self.items;
368        std::iter::successors(Some(start), move |index| {
369            items.get(*index).and_then(move |item| item.next_index)
370        })
371    }
372
373    /// Returns an iterator that iterates over the indexes of the list in reverse order.
374    pub fn cursor_iter_prev(
375        &self,
376        start: LinkedListIndex,
377    ) -> impl Iterator<Item = LinkedListIndex> + '_ {
378        let items = &self.items;
379        std::iter::successors(Some(start), move |index| {
380            items.get(*index).and_then(move |item| item.prev_index)
381        })
382    }
383
384    /// Splits the list into two at the given index. Returns a new list containing everything after the given index, including the index.
385    /// This operation should compute in O(n) time.
386    ///
387    /// T needs to implement Clone only to be able to insert the index, but not for the following items.
388    ///
389    /// The old indexes will become invalid after this operation and new indexes can be
390    /// retrieved by iterating from the head & tail of the new list.
391    pub fn split_off(&mut self, index: LinkedListIndex) -> Self {
392        let mut new_list = Self::new();
393        // let mut walker = LinkedListWalker::new(&self, index, false);
394
395        // let first = self.remove(index);
396        // if let Some(first) = first {
397        //     new_list.push_back(first.value);
398        // }
399        // while let Some(next) = walker.walk_next(&new_list) {
400        //     self.remove(next).map(|item| new_list.push_back(item.value));
401        // }
402        let mut current = index;
403
404        let first = self.remove(index);
405        if let Some(first) = first {
406            new_list.push_back(first.value);
407        }
408        while let Some(next) = self.cursor_next(current) {
409            let removed = self.remove(next);
410            if let Some(removed) = removed {
411                new_list.push_back(removed.value);
412            }
413        }
414        return new_list;
415    }
416
417    /// Returns the nth index by iterating from the head or tail, whichever is closer.
418    #[inline]
419    pub fn nth(&self, n: usize) -> Option<LinkedListIndex> {
420        let len = self.len();
421
422        if n >= len {
423            return None;
424        }
425        if len == 0 {
426            return None;
427        }
428        if n < len / 2 {
429            self.cursor_iter_next(self.head.unwrap()).nth(n)
430        } else {
431            self.cursor_iter_prev(self.tail.unwrap()).nth(len - n - 1)
432        }
433    }
434
435    /// Push many items to the back of the list.
436    ///
437    /// Returns the indexes of the new items
438    pub fn extend<I>(&mut self, values: I) -> Vec<LinkedListIndex>
439    where
440        I: IntoIterator<Item = T>,
441    {
442        let mut indexes = Vec::new();
443        for value in values {
444            indexes.push(self.push_back(value));
445        }
446        indexes
447    }
448
449    /// Push many items to the front of the list.
450    ///
451    /// Returns the indexes of the new items
452    pub fn extend_front<I>(&mut self, values: I) -> Vec<LinkedListIndex>
453    where
454        I: IntoIterator<Item = T>,
455    {
456        let mut indexes = Vec::new();
457        for value in values {
458            indexes.push(self.push_front(value));
459        }
460        indexes
461    }
462
463    /// Get the number of items in the list.
464    #[inline]
465    pub fn len(&self) -> usize {
466        self.items.len()
467    }
468
469    /// Remove an item from the list, returning the value at the key if the key was not previously removed.
470    pub fn remove(&mut self, index: LinkedListIndex) -> Option<LinkedListItem<T>> {
471        let item = self.items.remove(index)?;
472
473        if let Some(prev) = item.prev_index {
474            if let Some(prev_mut) = self.items.get_mut(prev) {
475                prev_mut.next_index = item.next_index;
476            }
477        } else {
478            self.head = item.next_index;
479        }
480
481        if let Some(next) = item.next_index {
482            if let Some(next_mut) = self.items.get_mut(next) {
483                next_mut.prev_index = item.prev_index;
484            }
485        } else {
486            self.tail = item.prev_index;
487        }
488
489        Some(item)
490    }
491
492    /// Retain only the elements specified by the predicate.
493    /// This operation should compute in O(n) time.
494    /// Modifies the list in place.
495    pub fn retain_mut<F>(&mut self, mut f: F)
496    where
497        F: FnMut(&T) -> bool,
498    {
499        let mut current = self.head;
500        while let Some(index) = current {
501            let item = self.items.get(index).unwrap();
502            let next = item.next_index;
503            if !f(&item.value) {
504                self.remove(index);
505            }
506            current = next;
507        }
508    }
509
510    /// Returns a cloned list retaining only the elements specified by the predicate.
511    pub fn retain<F>(&self, mut f: F) -> Self
512    where
513        F: FnMut(&T) -> bool,
514        T: Clone,
515        LinkedListItem<T>: Clone,
516    {
517        let mut new_list = Self::new();
518        new_list.items = self.items.clone();
519        new_list.head = self.head;
520        new_list.tail = self.tail;
521        new_list.retain_mut(f);
522        new_list
523    }
524}