use core::ptr::NonNull;
use crate::{
comparator::{Comparator, OrdComparator},
level_generator::{LevelGenerator, geometric::Geometric},
node::Node,
};
mod access;
mod filter;
mod insert_remove;
mod iter;
pub use iter::{Drain, ExtractIf, IntoIter, Iter};
mod structural;
mod traits;
pub struct OrderedSkipList<
T,
const N: usize = 16,
C: Comparator<T> = OrdComparator,
G: LevelGenerator = Geometric,
> {
head: NonNull<Node<T, N>>,
tail: Option<NonNull<Node<T, N>>>,
len: usize,
comparator: C,
generator: G,
}
unsafe impl<T: Send, C: Comparator<T> + Send, G: LevelGenerator + Send, const N: usize> Send
for OrderedSkipList<T, N, C, G>
{
}
unsafe impl<T: Sync, C: Comparator<T> + Sync, G: LevelGenerator + Sync, const N: usize> Sync
for OrderedSkipList<T, N, C, G>
{
}
impl<T: Ord, const N: usize> OrderedSkipList<T, N, OrdComparator, Geometric> {
#[inline]
#[must_use]
pub fn new() -> Self {
Self::with_comparator_and_level_generator(OrdComparator, Geometric::default())
}
}
impl<T: Ord, G: LevelGenerator, const N: usize> OrderedSkipList<T, N, OrdComparator, G> {
#[inline]
#[must_use]
pub fn with_level_generator(generator: G) -> Self {
Self::with_comparator_and_level_generator(OrdComparator, generator)
}
}
impl<T, C: Comparator<T>, const N: usize> OrderedSkipList<T, N, C, Geometric> {
#[inline]
#[must_use]
pub fn with_comparator(comparator: C) -> Self {
Self::with_comparator_and_level_generator(comparator, Geometric::default())
}
}
impl<T, C: Comparator<T>, G: LevelGenerator, const N: usize> OrderedSkipList<T, N, C, G> {
#[inline]
#[must_use]
pub fn with_comparator_and_level_generator(comparator: C, generator: G) -> Self {
let max_levels = generator.total();
debug_assert!(
max_levels <= N,
"generator.total() ({max_levels}) exceeds node capacity ({N})"
);
let head = unsafe {
NonNull::new_unchecked(Box::into_raw(Box::new(Node::new(max_levels.min(N)))))
};
Self {
head,
tail: None,
len: 0,
comparator,
generator,
}
}
#[inline]
fn head_ref(&self) -> &Node<T, N> {
unsafe { self.head.as_ref() }
}
#[inline]
fn head_mut(&mut self) -> &mut Node<T, N> {
unsafe { self.head.as_mut() }
}
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.len
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub(crate) fn head_ptr(&self) -> NonNull<Node<T, N>> {
self.head
}
#[inline]
pub(crate) fn decrement_len(&mut self) {
self.len = self.len.saturating_sub(1);
}
#[inline]
pub(crate) unsafe fn update_tail_before_pop(&mut self, about_to_pop: NonNull<Node<T, N>>) {
if self.tail == Some(about_to_pop) {
self.tail = unsafe { about_to_pop.as_ref() }
.prev()
.filter(|&p| unsafe { p.as_ref() }.value().is_some());
}
}
#[inline]
pub(crate) unsafe fn rebuild_skip_links(&mut self) {
let (_, new_tail) = unsafe { Node::filter_rebuild(self.head, |_| true, |_| {}) };
self.tail = new_tail;
}
}
impl<T: Ord, const N: usize> Default for OrderedSkipList<T, N, OrdComparator, Geometric> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<T, C: Comparator<T>, G: LevelGenerator, const N: usize> Drop for OrderedSkipList<T, N, C, G> {
#[inline]
fn drop(&mut self) {
unsafe { drop(Box::from_raw(self.head.as_ptr())) };
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use super::OrderedSkipList;
use crate::{comparator::FnComparator, level_generator::geometric::Geometric};
#[test]
fn new_is_empty() {
let list = OrderedSkipList::<i32>::new();
assert!(list.is_empty());
}
#[test]
fn new_len_zero() {
let list = OrderedSkipList::<i32>::new();
assert_eq!(list.len(), 0);
}
#[test]
fn with_level_generator_is_empty() {
let g = Geometric::new(8, 0.5).expect("valid parameters");
let list = OrderedSkipList::<i32>::with_level_generator(g);
assert!(list.is_empty());
assert_eq!(list.len(), 0);
}
#[test]
fn with_level_generator_custom_params() {
let g = Geometric::new(4, 0.25).expect("valid parameters");
let list = OrderedSkipList::<String>::with_level_generator(g);
assert!(list.is_empty());
}
#[test]
fn with_comparator_is_empty() {
let list: OrderedSkipList<i32, 16, _> =
OrderedSkipList::with_comparator(FnComparator(|a: &i32, b: &i32| b.cmp(a)));
assert!(list.is_empty());
assert_eq!(list.len(), 0);
}
#[test]
fn with_comparator_and_level_generator_is_empty() {
let g = Geometric::new(8, 0.25).expect("valid parameters");
let list: OrderedSkipList<i32, 8, _> = OrderedSkipList::with_comparator_and_level_generator(
FnComparator(|a: &i32, b: &i32| b.cmp(a)),
g,
);
assert!(list.is_empty());
assert_eq!(list.len(), 0);
}
#[test]
fn default_is_empty() {
let list = OrderedSkipList::<i32>::default();
assert_eq!(list.len(), 0);
assert!(list.is_empty());
}
}