Struct orx_linked_list::LinkedList
source · pub struct LinkedList<'a, T, P = SplitVec<LinkedListNode<'a, T>>>where
T: 'a,
P: PinnedVec<LinkedListNode<'a, T>> + 'a,{
pub memory_utilization: MemoryUtilization,
/* private fields */
}
Expand description
The LinkedList allows pushing and popping elements at either end in constant time.
Also see LinkedListX
for the structurally immutable version of the linked list.
Cost of conversion between these two types is considerably cheap
(equivalent to adding/removing a RefCell
indirection).
Another major difference is between the implementation of Send
and Sync
traits:
type / trait | Send | Sync |
---|---|---|
LinkedList | + | - |
LinkedListX | + | + |
Fields§
§memory_utilization: MemoryUtilization
Memory utilization strategy of the linked list allowing control over the tradeoff between
memory efficiency and amortized time complexity of pop_back
, pop_front
or remove
operations.
See MemoryUtilization for details.
Implementations§
source§impl<'a, T, P> LinkedList<'a, T, P>where
T: Clone,
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
impl<'a, T, P> LinkedList<'a, T, P>where T: Clone, P: PinnedVec<LinkedListNode<'a, T>> + 'a,
sourcepub fn collect_vec(&self) -> Vec<T>
pub fn collect_vec(&self) -> Vec<T>
Clones and collects values in the linked list into a standard vector.
self.collect_vec()
is simply a shorthand for self.iter().cloned().collect()
.
source§impl<'a, T> LinkedList<'a, T, FixedVec<LinkedListNode<'a, T>>>
impl<'a, T> LinkedList<'a, T, FixedVec<LinkedListNode<'a, T>>>
sourcepub fn room(&self) -> usize
pub fn room(&self) -> usize
Returns the available room for new items.
Examples
pub use orx_linked_list::prelude::*;
let mut list =
LinkedList::with_fixed_capacity(5).with_memory_utilization(MemoryUtilization::Lazy);
assert_eq!(4, list.room());
list.push_back(1);
list.push_back(1);
list.push_back(1);
list.push_back(1);
assert_eq!(0, list.room());
_ = list.pop_back();
_ = list.pop_back();
_ = list.pop_back();
assert_eq!(0, list.room());
list.memory_reclaim();
assert_eq!(3, list.room());
Safety
Note that since FixedVec
has a strict capacity; pushing to the list
while there is no room leads to a panic.
source§impl<'a, T, P> LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
sourcepub fn contains(&self, x: &T) -> bool
pub fn contains(&self, x: &T) -> bool
Returns true
if the LinkedList
contains an element equal to the
given value.
Note that, as usual, this method compares value equality.
This operation should compute linearly in O(n) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_doubling_growth(8);
list.push_back(0);
list.push_back(1);
list.push_back(2);
assert_eq!(list.contains(&0), true);
assert_eq!(list.contains(&10), false);
source§impl<'a, T, P> LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: 'a,
impl<'a, T, P> LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: 'a,
sourcepub fn iter<'b>(&self) -> IterFromFront<'b, T>where
'a: 'b,
pub fn iter<'b>(&self) -> IterFromFront<'b, T>where 'a: 'b,
Provides a forward iterator; which starts from the front-most element to the back.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(4);
list.push_back(1);
list.push_back(2);
list.push_front(0);
list.push_back(3);
let mut iter = list.iter();
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
sourcepub fn iter_from_back<'b>(&self) -> IterFromBack<'b, T>where
'a: 'b,
pub fn iter_from_back<'b>(&self) -> IterFromBack<'b, T>where 'a: 'b,
Provides a backward iterator; which starts from the back-most element to the front.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(4);
list.push_back(1);
list.push_back(2);
list.push_front(0);
list.push_back(3);
let mut iter = list.iter_from_back();
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), None);
source§impl<'a, T, P> LinkedList<'a, T, P>where
T: 'a,
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
impl<'a, T, P> LinkedList<'a, T, P>where T: 'a, P: PinnedVec<LinkedListNode<'a, T>> + 'a,
sourcepub fn built(self) -> LinkedListX<'a, T, P>
pub fn built(self) -> LinkedListX<'a, T, P>
Converts the LinkedList
to a LinkedList
stopping all structural mutations.
Mutations of element data depends on whether the created LinkedListX
is assigned
to an immutable variable or mut
variable.
See the documentation of LinkedListX
for details.
sourcepub fn with_memory_utilization(
self,
memory_utilization: MemoryUtilization
) -> Self
pub fn with_memory_utilization( self, memory_utilization: MemoryUtilization ) -> Self
Covnerts the linked list into one with the given memory_utilization
.
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the length of the linked list.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::new();
assert_eq!(0, list.len());
list.push_back('a');
list.push_front('b');
assert_eq!(2, list.len());
_ = list.pop_back();
assert_eq!(1, list.len());
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the LinkedList is empty.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::new();
assert!(list.is_empty());
list.push_front('a');
list.push_front('b');
assert!(!list.is_empty());
_ = list.pop_back();
assert!(!list.is_empty());
list.clear();
assert!(list.is_empty());
sourcepub fn back(&self) -> Option<&T>
pub fn back(&self) -> Option<&T>
Provides a reference to the back element, or None if the list is empty.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_doubling_growth(4);
assert_eq!(list.back(), None);
list.push_back(42);
assert_eq!(list.back(), Some(&42));
list.push_front(1);
assert_eq!(list.back(), Some(&42));
list.push_back(7);
assert_eq!(list.back(), Some(&7));
sourcepub fn back_mut(&mut self) -> Option<&mut T>
pub fn back_mut(&mut self) -> Option<&mut T>
Provides a mutable reference to the back element, or None if the list is empty.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(16);
assert_eq!(list.back(), None);
list.push_back(42);
assert_eq!(list.back(), Some(&42));
match list.back_mut() {
None => {},
Some(x) => *x = 7,
}
assert_eq!(list.back(), Some(&7));
sourcepub fn front(&self) -> Option<&T>
pub fn front(&self) -> Option<&T>
Provides a reference to the front element, or None if the list is empty.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_doubling_growth(4);
assert_eq!(list.front(), None);
list.push_front(42);
assert_eq!(list.front(), Some(&42));
list.push_back(1);
assert_eq!(list.front(), Some(&42));
list.push_front(7);
assert_eq!(list.front(), Some(&7));
sourcepub fn front_mut(&mut self) -> Option<&mut T>
pub fn front_mut(&mut self) -> Option<&mut T>
Provides a mutable reference to the front element, or None if the list is empty.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(16);
assert_eq!(list.front(), None);
list.push_front(42);
assert_eq!(list.front(), Some(&42));
match list.front_mut() {
None => {},
Some(x) => *x = 7,
}
assert_eq!(list.front(), Some(&7));
sourcepub fn push_back(&mut self, value: T)
pub fn push_back(&mut self, value: T)
Appends an element to the back of a list.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_exponential_growth(2, 1.5);
list.push_back('a');
assert_eq!('a', *list.back().unwrap());
list.push_back('b');
assert_eq!('b', *list.back().unwrap());
list.push_front('x');
assert_eq!('b', *list.back().unwrap());
sourcepub fn push_front(&mut self, value: T)
pub fn push_front(&mut self, value: T)
Appends an element to the back of a list.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_exponential_growth(2, 1.5);
list.push_front('a');
assert_eq!('a', *list.front().unwrap());
list.push_front('b');
assert_eq!('b', *list.front().unwrap());
list.push_back('x');
assert_eq!('b', *list.front().unwrap());
sourcepub fn pop_back(&mut self) -> Option<T>
pub fn pop_back(&mut self) -> Option<T>
Removes the last element from a list and returns it, or None if it is empty.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_exponential_growth(2, 1.5);
// build linked list: x <-> a <-> b <-> c
list.push_back('a');
list.push_back('b');
list.push_front('x');
list.push_back('c');
assert_eq!(Some('c'), list.pop_back());
assert_eq!(Some('b'), list.pop_back());
assert_eq!(Some('a'), list.pop_back());
assert_eq!(Some('x'), list.pop_back());
assert_eq!(None, list.pop_back());
assert_eq!(None, list.pop_front());
sourcepub fn pop_front(&mut self) -> Option<T>
pub fn pop_front(&mut self) -> Option<T>
Removes the last element from a list and returns it, or None if it is empty.
This operation should compute in O(1) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_exponential_growth(2, 1.5);
// build linked list: c <-> b <-> a <-> x
list.push_front('a');
list.push_front('b');
list.push_back('x');
list.push_front('c');
assert_eq!(Some('c'), list.pop_front());
assert_eq!(Some('b'), list.pop_front());
assert_eq!(Some('a'), list.pop_front());
assert_eq!(Some('x'), list.pop_front());
assert_eq!(None, list.pop_front());
assert_eq!(None, list.pop_back());
sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Removes all elements from the LinkedList.
This operation should compute in O(n) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_exponential_growth(2, 1.5);
// build linked list: x <-> a <-> b <-> c
list.push_front('a');
list.push_front('b');
list.push_back('x');
list.push_front('c');
assert_eq!(4, list.len());
assert_eq!(Some(&'c'), list.front());
assert_eq!(Some(&'x'), list.back());
list.clear();
assert!(list.is_empty());
assert_eq!(None, list.front());
assert_eq!(None, list.back());
sourcepub fn remove_at(&mut self, at: usize) -> T
pub fn remove_at(&mut self, at: usize) -> T
Removes the element at the given index and returns it.
This operation requires O(n) time to access the at
-th element and constant time to remove.
Panics
Panics if at >= len
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(8);
// build linked list: x <-> a <-> b <-> c
list.push_back('a');
list.push_back('b');
list.push_front('x');
list.push_back('c');
assert_eq!(list.remove_at(1), 'a');
assert_eq!(list.remove_at(0), 'x');
assert_eq!(list.remove_at(1), 'c');
assert_eq!(list.remove_at(0), 'b');
sourcepub fn insert_at(&mut self, at: usize, value: T)
pub fn insert_at(&mut self, at: usize, value: T)
Inserts the element at the given position.
This operation requires O(n) time to access the at
-th element and constant time to insert.
Panics
Panics if at > len
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(8);
// build linked list: a <-> b <-> c
list.push_back('a');
list.push_back('b');
list.push_back('c');
list.insert_at(1, 'w');
assert_eq!(vec!['a', 'w', 'b', 'c'], list.collect_vec());
sourcepub fn get_at(&self, at: usize) -> Option<&T>
pub fn get_at(&self, at: usize) -> Option<&T>
Returns a reference to element at the at
position starting from the front
;
None when at
is out of bounds.
This operation requires O(n) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(8);
// build linked list: a <-> b <-> c
list.push_back('b');
list.push_front('a');
list.push_back('c');
assert_eq!(Some(&'a'), list.get_at(0));
assert_eq!(Some(&'b'), list.get_at(1));
assert_eq!(Some(&'c'), list.get_at(2));
assert_eq!(None, list.get_at(3));
sourcepub fn get_mut_at(&mut self, at: usize) -> Option<&mut T>
pub fn get_mut_at(&mut self, at: usize) -> Option<&mut T>
Returns a mutable reference to element at the at
position starting from the front
;
None when at
is out of bounds.
This operation requires O(n) time.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_linear_growth(8);
// build linked list: a <-> b <-> c
list.push_back('b');
list.push_front('a');
list.push_back('c');
*list.get_mut_at(0).unwrap() = 'x';
*list.get_mut_at(1).unwrap() = 'y';
*list.get_mut_at(2).unwrap() = 'z';
assert_eq!(None, list.get_mut_at(3));
assert_eq!(Some(&'x'), list.get_at(0));
assert_eq!(Some(&'y'), list.get_at(1));
assert_eq!(Some(&'z'), list.get_at(2));
source§impl<'a, T, P> LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: 'a,
impl<'a, T, P> LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: 'a,
sourcepub fn memory_status(&self) -> MemoryStatus
pub fn memory_status(&self) -> MemoryStatus
Returns the utilization of the underlying vector of the linked list.
LinkedList
holds all elements close to each other in a PinnedVec
aiming for better cache locality while using thin references rather
than wide pointers and to reduce heap allocations.
In order to achieve O(1) time complexity while avoiding smart pointers,
remove and pop operations are able to be Lazy
.
In this case; i.e., when the strategy is set to MemoryReclaimStrategy::Lazy
:
every pop_back
, pop_front
or remove
method call leaves a gap in the
underlying vector. Status of utilization of the underlying vector can be
queried using the memory_status
method and the gaps can completely be
reclaimed by manually calling the memory_reclaim
method which has a time
complexity of O(n) where n is the length of the underlying vector.
This method reveals the memory utilization of the underlying pinned vector at any given time as the fraction of active linked list nodes to total spaces used by the pinned vector.
Some extreme examples are as follows:
- in an push-only situation, memory utilization is equal to 1.0:
num_active_nodes == num_used_nodes
- in a situation where each push is followed by a pop,
memory utilization is 0.0:
num_active_nodes == 0
num_used_nodes == n
, wheren
is the number of items pushed.
Complexity
LinkedList
gives the control over laziness to user:
- the list can remain lazy throughout the lifetime until it is dropped, or
- at certain points in its lifetime, memory which is not utilized can be
reclaimed by the
memory_reclaim
method.
memory_reclaim
shrinks the used memory by placing all linked list elements
next to each other in the underlying pinned vector without leaving any gaps.
This is achieved by a single pass; hence, the method has O(n) time complexity.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_exponential_growth(2, 1.5)
.with_memory_utilization(MemoryUtilization::Lazy);
// fill list with 4 elements
list.push_back('a');
list.push_back('b');
list.push_back('c');
list.push_back('d');
let util = list.memory_status();
assert_eq!(4, util.num_active_nodes);
assert_eq!(4, util.num_used_nodes);
assert_eq!(1.00, util.utilization());
// remove 1 of 4
_ = list.remove_at(2);
let util = list.memory_status();
assert_eq!(3, util.num_active_nodes);
assert_eq!(4, util.num_used_nodes);
assert_eq!(0.75, util.utilization());
// pop 2 more
_ = list.pop_back();
_ = list.pop_front();
let util = list.memory_status();
assert_eq!(1, util.num_active_nodes);
assert_eq!(4, util.num_used_nodes);
assert_eq!(0.25, util.utilization());
// remove the last element
_ = list.remove_at(0);
let util = list.memory_status();
assert_eq!(0, util.num_active_nodes);
assert_eq!(4, util.num_used_nodes);
assert_eq!(0.00, util.utilization());
sourcepub fn memory_reclaim(&mut self) -> usize
pub fn memory_reclaim(&mut self) -> usize
This method reclaims the gaps which are opened due to lazy pops and removals,
and brings back memory_status
to 100% in O(n) time complexity.
use orx_linked_list::prelude::*;
let mut list = LinkedList::default();
list.memory_utilization = MemoryUtilization::Lazy;
// ...
// regardless of the sequence of pushes, pops, removals
// memory utilization will be 100% after memory_reclaim call.
let _reclaimed = list.memory_reclaim();
assert_eq!(1.00, list.memory_status().utilization());
LinkedList
holds all elements close to each other in a PinnedVec
aiming for better cache locality while using thin references rather
than wide pointers and to reduce heap allocations.
In order to achieve O(1) time complexity while avoiding smart pointers,
remove and pop operations are able to be Lazy
.
In this case; i.e., when the strategy is set to MemoryReclaimStrategy::Lazy
:
every pop_back
, pop_front
or remove
method call leaves a gap in the
underlying vector. Status of utilization of the underlying vector can be
queried using the memory_status
method and the gaps can completely be
reclaimed by manually calling the memory_reclaim
method which has a time
complexity of O(n) where n is the length of the underlying vector.
In addition to the automatic memory utilization strategy,
memory can be manually reclaimed by using this method.
The memory_status
method helps here by revealing the memory utilization
at any given time as the fraction of active linked list nodes to total
spaces used by the pinned vector.
Some extreme examples are as follows:
- in an push-only situation, memory utilization is equal to 1.0:
num_active_nodes == num_used_nodes
- in a situation where each push is followed by a pop,
memory utilization is 0.0:
num_active_nodes == 0
num_used_nodes == n
, wheren
is the number of items pushed.
Complexity
LinkedList
gives the control over laziness to user:
- the list can remain lazy throughout the lifetime until it is dropped, or
- at certain points in its lifetime, memory which is not utilized can be
reclaimed by the
memory_reclaim
method having O(n) time complexity.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_exponential_growth(2, 1.5)
.with_memory_utilization(MemoryUtilization::Lazy);
// build list: c <-> b <-> a <-> d
list.push_back('a');
list.push_front('b');
list.push_front('c');
list.push_back('d');
assert_eq!(
list.iter().cloned().collect::<Vec<_>>(),
['c', 'b', 'a', 'd'],
);
assert_eq!(1.00, list.memory_status().utilization());
// nothing to reclaim
let reclaimed = list.memory_reclaim();
assert_eq!(0, reclaimed);
let popped = list.pop_back();
assert_eq!(Some('d'), popped);
assert_eq!(list.iter().cloned().collect::<Vec<_>>(), ['c', 'b', 'a']);
assert_eq!(0.75, list.memory_status().utilization());
// one position to reclaim
let reclaimed = list.memory_reclaim();
assert_eq!(1, reclaimed);
assert_eq!(list.iter().cloned().collect::<Vec<_>>(), ['c', 'b', 'a']);
assert_eq!(1.00, list.memory_status().utilization());
let removed = list.remove_at(1);
assert_eq!('b', removed);
let popped = list.pop_front();
assert_eq!(Some('c'), popped);
assert_eq!(list.iter().cloned().collect::<Vec<_>>(), ['a']);
assert_eq!(1.0 / 3.0, list.memory_status().utilization());
// two positions to reclaim
let reclaimed = list.memory_reclaim();
assert_eq!(2, reclaimed);
assert_eq!(list.iter().cloned().collect::<Vec<_>>(), ['a']);
assert_eq!(1.00, list.memory_status().utilization());
// pushing more using reclaimed capacity under the hood
list.push_back('x');
list.push_back('y');
list.push_back('z');
assert_eq!(1.00, list.memory_status().utilization());
// as one could expect, `clear` does not leave gaps
list.clear();
assert!(list.is_empty());
assert_eq!(1.00, list.memory_status().utilization());
source§impl<'a, T> LinkedList<'a, T>
impl<'a, T> LinkedList<'a, T>
sourcepub fn new() -> Self
pub fn new() -> Self
Creates an empty LinkedList with default pinned vector.
Default underlying pinned vector is the SplitVec
with default growth strategy.
See [SplitVec(https://crates.io/crates/orx-split-vec) for details.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::new();
list.push_back('a');
sourcepub fn with_initial_capacity(initial_capacity: usize) -> Self
pub fn with_initial_capacity(initial_capacity: usize) -> Self
Creates an empty LinkedList with default pinned vector
having the given initial_capacity
.
Default underlying pinned vector is the SplitVec
with default growth strategy.
See [SplitVec(https://crates.io/crates/orx-split-vec) for details.
Examples
use orx_linked_list::prelude::*;
let mut list = LinkedList::with_initial_capacity(8);
list.push_back('a');
source§impl<'a, T> LinkedList<'a, T, FixedVec<LinkedListNode<'a, T>>>
impl<'a, T> LinkedList<'a, T, FixedVec<LinkedListNode<'a, T>>>
sourcepub fn with_fixed_capacity(fixed_capacity: usize) -> Self
pub fn with_fixed_capacity(fixed_capacity: usize) -> Self
Creates an empty LinkedList with fixed capacity.
FixedVec
is the most efficient PinnedVec
implementation which can be
used as the underlying data structure; however, it panics if the memory
usage exceeds the given fixed_capacity
.
It implements the room
method to reveal the available space in number
of elements.
The ImpVec
of the linked list allowing to build internal links
uses a FixedVec: PinnedVec
, see FixedVec
for details.
Examples
use orx_linked_list::prelude::*;
let list: LinkedList<char, FixedVec<LinkedListNode<char>>>
= LinkedList::with_fixed_capacity(128);
// equivalent brief type alias
let list: LinkedListFixed<char>
= LinkedList::with_fixed_capacity(128);
source§impl<'a, T> LinkedList<'a, T, SplitVec<LinkedListNode<'a, T>, Doubling>>
impl<'a, T> LinkedList<'a, T, SplitVec<LinkedListNode<'a, T>, Doubling>>
sourcepub fn with_doubling_growth(first_fragment_capacity: usize) -> Self
pub fn with_doubling_growth(first_fragment_capacity: usize) -> Self
Creates an empty LinkedList where new allocations are doubled every time the vector reaches its capacity.
first_fragment_capacity
determines the capacity of the first fragment of the underlying split vector.
The ImpVec
of the linked list allowing to build internal links
uses a SplitVec: PinnedVec
with Doubling
growth strategy.
See SplitVec
for details.
Examples
use orx_linked_list::prelude::*;
let list: LinkedList<char, SplitVec<LinkedListNode<char>, Doubling>>
= LinkedList::with_doubling_growth(4);
// equivalent brief type alias
let list: LinkedListDoubling<char>
= LinkedList::with_doubling_growth(128);
source§impl<'a, T> LinkedList<'a, T, SplitVec<LinkedListNode<'a, T>, Linear>>
impl<'a, T> LinkedList<'a, T, SplitVec<LinkedListNode<'a, T>, Linear>>
sourcepub fn with_linear_growth(constant_fragment_capacity: usize) -> Self
pub fn with_linear_growth(constant_fragment_capacity: usize) -> Self
Creates an empty LinkedList where new allocations are always the same and equal to the initial capacity of the vector.
constant_fragment_capacity
determines the capacity of the first fragment and every succeeding fragment of the underlying split vector.
The ImpVec
of the linked list allowing to build internal links
uses a SplitVec: PinnedVec
with Linear
growth strategy.
See SplitVec
for details.
Examples
use orx_linked_list::prelude::*;
let list: LinkedList<char, SplitVec<LinkedListNode<char>, Linear>>
= LinkedList::with_linear_growth(32);
// equivalent brief type alias
let list: LinkedListLinear<char>
= LinkedList::with_linear_growth(128);
source§impl<'a, T> LinkedList<'a, T, SplitVec<LinkedListNode<'a, T>, Exponential>>
impl<'a, T> LinkedList<'a, T, SplitVec<LinkedListNode<'a, T>, Exponential>>
sourcepub fn with_exponential_growth(
first_fragment_capacity: usize,
growth_coefficient: f32
) -> Self
pub fn with_exponential_growth( first_fragment_capacity: usize, growth_coefficient: f32 ) -> Self
Creates an empty LinkedList where new allocations are exponentially increased every time the vector reaches its capacity.
first_fragment_capacity
determines the capacity of the first fragment of the underlying split vector.growth_coefficient
determines the exponential growth rate of the succeeding fragments of the split vector.
The ImpVec
of the linked list allowing to build internal links
uses a SplitVec: PinnedVec
with Exponential
growth strategy.
See SplitVec
for details.
Examples
use orx_linked_list::prelude::*;
let list: LinkedList<char, SplitVec<LinkedListNode<char>, Exponential>>
= LinkedList::with_exponential_growth(4, 1.5);
// equivalent brief type alias
let list: LinkedListExponential<char>
= LinkedList::with_exponential_growth(4, 1.5);
Trait Implementations§
source§impl<'a, T, P> Clone for LinkedList<'a, T, P>where
T: 'a + Clone + Debug,
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
impl<'a, T, P> Clone for LinkedList<'a, T, P>where T: 'a + Clone + Debug, P: PinnedVec<LinkedListNode<'a, T>> + 'a,
source§impl<'a, T, P> Debug for LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: Debug,
impl<'a, T, P> Debug for LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: Debug,
source§impl<'a, T> Default for LinkedList<'a, T>
impl<'a, T> Default for LinkedList<'a, T>
source§impl<'a, T, P> PartialEq<[T]> for LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<[T]> for LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§impl<'a, T, P, const N: usize> PartialEq<[T; N]> for LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P, const N: usize> PartialEq<[T; N]> for LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§impl<'a, T, P> PartialEq<FixedVec<T>> for LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<FixedVec<T>> for LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for [T]where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for [T]where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<'a, T, P, const N: usize> PartialEq<LinkedList<'a, T, P>> for [T; N]where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P, const N: usize> PartialEq<LinkedList<'a, T, P>> for [T; N]where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for FixedVec<T>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for FixedVec<T>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for LinkedListX<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for LinkedListX<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<'a, T, P, G> PartialEq<LinkedList<'a, T, P>> for SplitVec<T, G>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
G: Growth,
impl<'a, T, P, G> PartialEq<LinkedList<'a, T, P>> for SplitVec<T, G>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq, G: Growth,
source§fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for Vec<T>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<LinkedList<'a, T, P>> for Vec<T>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
fn eq(&self, other: &LinkedList<'a, T, P>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<'a, T, P> PartialEq<LinkedListX<'a, T, P>> for LinkedList<'a, T, P>where
P: PinnedVec<LinkedListNode<'a, T>> + 'a,
T: PartialEq,
impl<'a, T, P> PartialEq<LinkedListX<'a, T, P>> for LinkedList<'a, T, P>where P: PinnedVec<LinkedListNode<'a, T>> + 'a, T: PartialEq,
source§fn eq(&self, other: &LinkedListX<'a, T, P>) -> bool
fn eq(&self, other: &LinkedListX<'a, T, P>) -> bool
self
and other
values to be equal, and is used
by ==
.