use alloc::alloc::{alloc, dealloc, handle_alloc_error, Layout};
use core::borrow::Borrow;
use core::cmp;
use core::fmt;
use core::marker::PhantomData;
use core::mem;
use core::ops::{Bound, Deref, Index, RangeBounds};
use core::ptr;
use core::sync::atomic::{fence, AtomicUsize, Ordering};
use crate::epoch::{self, Atomic, Collector, Guard, Shared};
use crate::utils::CachePadded;
const HEIGHT_BITS: usize = 5;
const MAX_HEIGHT: usize = 1 << HEIGHT_BITS;
const HEIGHT_MASK: usize = (1 << HEIGHT_BITS) - 1;
#[repr(C)]
struct Tower<K, V> {
pointers: [Atomic<Node<K, V>>; 0],
}
impl<K, V> Index<usize> for Tower<K, V> {
type Output = Atomic<Node<K, V>>;
fn index(&self, index: usize) -> &Atomic<Node<K, V>> {
unsafe { self.pointers.get_unchecked(index) }
}
}
#[repr(C)]
struct Head<K, V> {
pointers: [Atomic<Node<K, V>>; MAX_HEIGHT],
}
impl<K, V> Head<K, V> {
#[inline]
fn new() -> Head<K, V> {
Head {
pointers: Default::default(),
}
}
}
impl<K, V> Deref for Head<K, V> {
type Target = Tower<K, V>;
fn deref(&self) -> &Tower<K, V> {
unsafe { &*(self as *const _ as *const Tower<K, V>) }
}
}
#[repr(C)]
struct Node<K, V> {
value: V,
key: K,
refs_and_height: AtomicUsize,
tower: Tower<K, V>,
}
impl<K, V> Node<K, V> {
unsafe fn alloc(height: usize, ref_count: usize) -> *mut Self {
let layout = Self::get_layout(height);
let ptr = alloc(layout).cast::<Self>();
if ptr.is_null() {
handle_alloc_error(layout);
}
ptr::write(
&mut (*ptr).refs_and_height,
AtomicUsize::new((height - 1) | ref_count << HEIGHT_BITS),
);
ptr::write_bytes((*ptr).tower.pointers.as_mut_ptr(), 0, height);
ptr
}
unsafe fn dealloc(ptr: *mut Self) {
let height = (*ptr).height();
let layout = Self::get_layout(height);
dealloc(ptr.cast::<u8>(), layout);
}
unsafe fn get_layout(height: usize) -> Layout {
assert!((1..=MAX_HEIGHT).contains(&height));
let size_self = mem::size_of::<Self>();
let align_self = mem::align_of::<Self>();
let size_pointer = mem::size_of::<Atomic<Self>>();
Layout::from_size_align_unchecked(size_self + size_pointer * height, align_self)
}
#[inline]
fn height(&self) -> usize {
(self.refs_and_height.load(Ordering::Relaxed) & HEIGHT_MASK) + 1
}
fn mark_tower(&self) -> bool {
let height = self.height();
for level in (0..height).rev() {
let tag = unsafe {
self.tower[level]
.fetch_or(1, Ordering::SeqCst, epoch::unprotected())
.tag()
};
if level == 0 && tag == 1 {
return false;
}
}
true
}
#[inline]
fn is_removed(&self) -> bool {
let tag = unsafe {
self.tower[0]
.load(Ordering::Relaxed, epoch::unprotected())
.tag()
};
tag == 1
}
#[inline]
unsafe fn try_increment(&self) -> bool {
let mut refs_and_height = self.refs_and_height.load(Ordering::Relaxed);
loop {
if refs_and_height & !HEIGHT_MASK == 0 {
return false;
}
let new_refs_and_height = refs_and_height
.checked_add(1 << HEIGHT_BITS)
.expect("SkipList reference count overflow");
match self.refs_and_height.compare_exchange_weak(
refs_and_height,
new_refs_and_height,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => return true,
Err(current) => refs_and_height = current,
}
}
}
#[inline]
unsafe fn decrement(&self, guard: &Guard) {
if self
.refs_and_height
.fetch_sub(1 << HEIGHT_BITS, Ordering::Release)
>> HEIGHT_BITS
== 1
{
fence(Ordering::Acquire);
guard.defer_unchecked(move || Self::finalize(self));
}
}
#[inline]
unsafe fn decrement_with_pin<F>(&self, parent: &SkipList<K, V>, pin: F)
where
F: FnOnce() -> Guard,
{
if self
.refs_and_height
.fetch_sub(1 << HEIGHT_BITS, Ordering::Release)
>> HEIGHT_BITS
== 1
{
fence(Ordering::Acquire);
let guard = &pin();
parent.check_guard(guard);
guard.defer_unchecked(move || Self::finalize(self));
}
}
#[cold]
unsafe fn finalize(ptr: *const Self) {
let ptr = ptr as *mut Self;
ptr::drop_in_place(&mut (*ptr).key);
ptr::drop_in_place(&mut (*ptr).value);
Node::dealloc(ptr);
}
}
impl<K, V> fmt::Debug for Node<K, V>
where
K: fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Node")
.field(&self.key)
.field(&self.value)
.finish()
}
}
struct Position<'a, K, V> {
found: Option<&'a Node<K, V>>,
left: [&'a Tower<K, V>; MAX_HEIGHT],
right: [Shared<'a, Node<K, V>>; MAX_HEIGHT],
}
struct HotData {
seed: AtomicUsize,
len: AtomicUsize,
max_height: AtomicUsize,
}
pub struct SkipList<K, V> {
head: Head<K, V>,
collector: Collector,
hot_data: CachePadded<HotData>,
}
unsafe impl<K: Send + Sync, V: Send + Sync> Send for SkipList<K, V> {}
unsafe impl<K: Send + Sync, V: Send + Sync> Sync for SkipList<K, V> {}
impl<K, V> SkipList<K, V> {
pub fn new(collector: Collector) -> SkipList<K, V> {
SkipList {
head: Head::new(),
collector,
hot_data: CachePadded::new(HotData {
seed: AtomicUsize::new(1),
len: AtomicUsize::new(0),
max_height: AtomicUsize::new(1),
}),
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn len(&self) -> usize {
let len = self.hot_data.len.load(Ordering::Relaxed);
if len > isize::max_value() as usize {
0
} else {
len
}
}
fn check_guard(&self, guard: &Guard) {
if let Some(c) = guard.collector() {
assert!(c == &self.collector);
}
}
}
impl<K, V> SkipList<K, V>
where
K: Ord,
{
pub fn front<'a: 'g, 'g>(&'a self, guard: &'g Guard) -> Option<Entry<'a, 'g, K, V>> {
self.check_guard(guard);
let n = self.next_node(&self.head, Bound::Unbounded, guard)?;
Some(Entry {
parent: self,
node: n,
guard,
})
}
pub fn back<'a: 'g, 'g>(&'a self, guard: &'g Guard) -> Option<Entry<'a, 'g, K, V>> {
self.check_guard(guard);
let n = self.search_bound(Bound::Unbounded, true, guard)?;
Some(Entry {
parent: self,
node: n,
guard,
})
}
pub fn contains_key<Q>(&self, key: &Q, guard: &Guard) -> bool
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.get(key, guard).is_some()
}
pub fn get<'a: 'g, 'g, Q>(&'a self, key: &Q, guard: &'g Guard) -> Option<Entry<'a, 'g, K, V>>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.check_guard(guard);
let n = self.search_bound(Bound::Included(key), false, guard)?;
if n.key.borrow() != key {
return None;
}
Some(Entry {
parent: self,
node: n,
guard,
})
}
pub fn lower_bound<'a: 'g, 'g, Q>(
&'a self,
bound: Bound<&Q>,
guard: &'g Guard,
) -> Option<Entry<'a, 'g, K, V>>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.check_guard(guard);
let n = self.search_bound(bound, false, guard)?;
Some(Entry {
parent: self,
node: n,
guard,
})
}
pub fn upper_bound<'a: 'g, 'g, Q>(
&'a self,
bound: Bound<&Q>,
guard: &'g Guard,
) -> Option<Entry<'a, 'g, K, V>>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.check_guard(guard);
let n = self.search_bound(bound, true, guard)?;
Some(Entry {
parent: self,
node: n,
guard,
})
}
pub fn get_or_insert(&self, key: K, value: V, guard: &Guard) -> RefEntry<'_, K, V> {
self.insert_internal(key, || value, false, guard)
}
pub fn get_or_insert_with<F>(&self, key: K, value: F, guard: &Guard) -> RefEntry<'_, K, V>
where
F: FnOnce() -> V,
{
self.insert_internal(key, value, false, guard)
}
pub fn iter<'a: 'g, 'g>(&'a self, guard: &'g Guard) -> Iter<'a, 'g, K, V> {
self.check_guard(guard);
Iter {
parent: self,
head: None,
tail: None,
guard,
}
}
pub fn ref_iter(&self) -> RefIter<'_, K, V> {
RefIter {
parent: self,
head: None,
tail: None,
}
}
pub fn range<'a: 'g, 'g, Q, R>(
&'a self,
range: R,
guard: &'g Guard,
) -> Range<'a, 'g, Q, R, K, V>
where
K: Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
self.check_guard(guard);
Range {
parent: self,
head: None,
tail: None,
range,
guard,
_marker: PhantomData,
}
}
#[allow(clippy::needless_lifetimes)]
pub fn ref_range<'a, Q, R>(&'a self, range: R) -> RefRange<'a, Q, R, K, V>
where
K: Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
RefRange {
parent: self,
range,
head: None,
tail: None,
_marker: PhantomData,
}
}
fn random_height(&self) -> usize {
let mut num = self.hot_data.seed.load(Ordering::Relaxed);
num ^= num << 13;
num ^= num >> 17;
num ^= num << 5;
self.hot_data.seed.store(num, Ordering::Relaxed);
let mut height = cmp::min(MAX_HEIGHT, num.trailing_zeros() as usize + 1);
unsafe {
while height >= 4
&& self.head[height - 2]
.load(Ordering::Relaxed, epoch::unprotected())
.is_null()
{
height -= 1;
}
}
let mut max_height = self.hot_data.max_height.load(Ordering::Relaxed);
while height > max_height {
match self.hot_data.max_height.compare_exchange_weak(
max_height,
height,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => break,
Err(h) => max_height = h,
}
}
height
}
#[cold]
unsafe fn help_unlink<'a>(
&'a self,
pred: &'a Atomic<Node<K, V>>,
curr: &'a Node<K, V>,
succ: Shared<'a, Node<K, V>>,
guard: &'a Guard,
) -> Option<Shared<'a, Node<K, V>>> {
match pred.compare_exchange(
Shared::from(curr as *const _),
succ.with_tag(0),
Ordering::Release,
Ordering::Relaxed,
guard,
) {
Ok(_) => {
curr.decrement(guard);
Some(succ.with_tag(0))
}
Err(_) => None,
}
}
fn next_node<'a>(
&'a self,
pred: &'a Tower<K, V>,
lower_bound: Bound<&K>,
guard: &'a Guard,
) -> Option<&'a Node<K, V>> {
unsafe {
let mut curr = pred[0].load_consume(guard);
if curr.tag() == 1 {
return self.search_bound(lower_bound, false, guard);
}
while let Some(c) = curr.as_ref() {
let succ = c.tower[0].load_consume(guard);
if succ.tag() == 1 {
if let Some(c) = self.help_unlink(&pred[0], c, succ, guard) {
curr = c;
continue;
} else {
return self.search_bound(lower_bound, false, guard);
}
}
return Some(c);
}
None
}
}
fn search_bound<'a, Q>(
&'a self,
bound: Bound<&Q>,
upper_bound: bool,
guard: &'a Guard,
) -> Option<&'a Node<K, V>>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
unsafe {
'search: loop {
let mut level = self.hot_data.max_height.load(Ordering::Relaxed);
while level >= 1
&& self.head[level - 1]
.load(Ordering::Relaxed, guard)
.is_null()
{
level -= 1;
}
let mut result = None;
let mut pred = &*self.head;
while level >= 1 {
level -= 1;
let mut curr = pred[level].load_consume(guard);
if curr.tag() == 1 {
continue 'search;
}
while let Some(c) = curr.as_ref() {
let succ = c.tower[level].load_consume(guard);
if succ.tag() == 1 {
if let Some(c) = self.help_unlink(&pred[level], c, succ, guard) {
curr = c;
continue;
} else {
continue 'search;
}
}
if upper_bound {
if !below_upper_bound(&bound, c.key.borrow()) {
break;
}
result = Some(c);
} else if above_lower_bound(&bound, c.key.borrow()) {
result = Some(c);
break;
}
pred = &c.tower;
curr = succ;
}
}
return result;
}
}
}
fn search_position<'a, Q>(&'a self, key: &Q, guard: &'a Guard) -> Position<'a, K, V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
unsafe {
'search: loop {
let mut result = Position {
found: None,
left: [&*self.head; MAX_HEIGHT],
right: [Shared::null(); MAX_HEIGHT],
};
let mut level = self.hot_data.max_height.load(Ordering::Relaxed);
while level >= 1
&& self.head[level - 1]
.load(Ordering::Relaxed, guard)
.is_null()
{
level -= 1;
}
let mut pred = &*self.head;
while level >= 1 {
level -= 1;
let mut curr = pred[level].load_consume(guard);
if curr.tag() == 1 {
continue 'search;
}
while let Some(c) = curr.as_ref() {
let succ = c.tower[level].load_consume(guard);
if succ.tag() == 1 {
if let Some(c) = self.help_unlink(&pred[level], c, succ, guard) {
curr = c;
continue;
} else {
continue 'search;
}
}
match c.key.borrow().cmp(key) {
cmp::Ordering::Greater => break,
cmp::Ordering::Equal => {
result.found = Some(c);
break;
}
cmp::Ordering::Less => {}
}
pred = &c.tower;
curr = succ;
}
result.left[level] = pred;
result.right[level] = curr;
}
return result;
}
}
}
fn insert_internal<F>(
&self,
key: K,
value: F,
replace: bool,
guard: &Guard,
) -> RefEntry<'_, K, V>
where
F: FnOnce() -> V,
{
self.check_guard(guard);
unsafe {
let guard = &*(guard as *const _);
let mut search;
loop {
search = self.search_position(&key, guard);
let r = match search.found {
Some(r) => r,
None => break,
};
if replace {
if r.mark_tower() {
self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
}
} else {
if let Some(e) = RefEntry::try_acquire(self, r) {
return e;
}
break;
}
}
let value = value();
let height = self.random_height();
let (node, n) = {
let n = Node::<K, V>::alloc(height, 2);
ptr::write(&mut (*n).key, key);
ptr::write(&mut (*n).value, value);
(Shared::<Node<K, V>>::from(n as *const _), &*n)
};
self.hot_data.len.fetch_add(1, Ordering::Relaxed);
loop {
n.tower[0].store(search.right[0], Ordering::Relaxed);
if search.left[0][0]
.compare_exchange(
search.right[0],
node,
Ordering::SeqCst,
Ordering::SeqCst,
guard,
)
.is_ok()
{
break;
}
{
let sg = scopeguard::guard((), |_| {
Node::finalize(node.as_raw());
});
search = self.search_position(&n.key, guard);
mem::forget(sg);
}
if let Some(r) = search.found {
if replace {
if r.mark_tower() {
self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
}
} else {
if let Some(e) = RefEntry::try_acquire(self, r) {
Node::finalize(node.as_raw());
self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
return e;
}
}
}
}
let entry = RefEntry {
parent: self,
node: n,
};
'build: for level in 1..height {
loop {
let pred = search.left[level];
let succ = search.right[level];
let next = n.tower[level].load(Ordering::SeqCst, guard);
if next.tag() == 1 {
break 'build;
}
if succ.as_ref().map(|s| &s.key) == Some(&n.key) {
search = self.search_position(&n.key, guard);
continue;
}
if n.tower[level]
.compare_exchange(next, succ, Ordering::SeqCst, Ordering::SeqCst, guard)
.is_err()
{
break 'build;
}
n.refs_and_height
.fetch_add(1 << HEIGHT_BITS, Ordering::Relaxed);
if pred[level]
.compare_exchange(succ, node, Ordering::SeqCst, Ordering::SeqCst, guard)
.is_ok()
{
break;
}
n.refs_and_height
.fetch_sub(1 << HEIGHT_BITS, Ordering::Relaxed);
search = self.search_position(&n.key, guard);
}
}
if n.tower[height - 1].load(Ordering::SeqCst, guard).tag() == 1 {
self.search_bound(Bound::Included(&n.key), false, guard);
}
entry
}
}
}
impl<K, V> SkipList<K, V>
where
K: Ord + Send + 'static,
V: Send + 'static,
{
pub fn insert(&self, key: K, value: V, guard: &Guard) -> RefEntry<'_, K, V> {
self.insert_internal(key, || value, true, guard)
}
pub fn remove<Q>(&self, key: &Q, guard: &Guard) -> Option<RefEntry<'_, K, V>>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.check_guard(guard);
unsafe {
let guard = &*(guard as *const _);
loop {
let search = self.search_position(key, guard);
let n = search.found?;
let entry = match RefEntry::try_acquire(self, n) {
Some(e) => e,
None => continue,
};
if n.mark_tower() {
self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
for level in (0..n.height()).rev() {
let succ = n.tower[level].load(Ordering::SeqCst, guard).with_tag(0);
if search.left[level][level]
.compare_exchange(
Shared::from(n as *const _),
succ,
Ordering::SeqCst,
Ordering::SeqCst,
guard,
)
.is_ok()
{
n.decrement(guard);
} else {
self.search_bound(Bound::Included(key), false, guard);
break;
}
}
}
return Some(entry);
}
}
}
pub fn pop_front(&self, guard: &Guard) -> Option<RefEntry<'_, K, V>> {
self.check_guard(guard);
loop {
let e = self.front(guard)?;
if let Some(e) = e.pin() {
if e.remove(guard) {
return Some(e);
} else {
e.release(guard);
}
}
}
}
pub fn pop_back(&self, guard: &Guard) -> Option<RefEntry<'_, K, V>> {
self.check_guard(guard);
loop {
let e = self.back(guard)?;
if let Some(e) = e.pin() {
if e.remove(guard) {
return Some(e);
} else {
e.release(guard);
}
}
}
}
pub fn clear(&self, guard: &mut Guard) {
self.check_guard(guard);
const BATCH_SIZE: usize = 100;
loop {
{
let mut entry = self.lower_bound(Bound::Unbounded, guard);
for _ in 0..BATCH_SIZE {
let e = match entry {
None => return,
Some(e) => e,
};
let next = e.next();
if e.node.mark_tower() {
self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
}
entry = next;
}
}
guard.repin();
}
}
}
impl<K, V> Drop for SkipList<K, V> {
fn drop(&mut self) {
unsafe {
let mut node = self.head[0]
.load(Ordering::Relaxed, epoch::unprotected())
.as_ref();
while let Some(n) = node {
let next = n.tower[0]
.load(Ordering::Relaxed, epoch::unprotected())
.as_ref();
Node::finalize(n);
node = next;
}
}
}
}
impl<K, V> fmt::Debug for SkipList<K, V>
where
K: Ord + fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("SkipList { .. }")
}
}
impl<K, V> IntoIterator for SkipList<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> IntoIter<K, V> {
unsafe {
let front = self.head[0]
.load(Ordering::Relaxed, epoch::unprotected())
.as_raw();
for level in 0..MAX_HEIGHT {
self.head[level].store(Shared::null(), Ordering::Relaxed);
}
IntoIter {
node: front as *mut Node<K, V>,
}
}
}
}
pub struct Entry<'a: 'g, 'g, K, V> {
parent: &'a SkipList<K, V>,
node: &'g Node<K, V>,
guard: &'g Guard,
}
impl<'a: 'g, 'g, K: 'a, V: 'a> Entry<'a, 'g, K, V> {
pub fn is_removed(&self) -> bool {
self.node.is_removed()
}
pub fn key(&self) -> &'g K {
&self.node.key
}
pub fn value(&self) -> &'g V {
&self.node.value
}
pub fn skiplist(&self) -> &'a SkipList<K, V> {
self.parent
}
pub fn pin(&self) -> Option<RefEntry<'a, K, V>> {
unsafe { RefEntry::try_acquire(self.parent, self.node) }
}
}
impl<'a: 'g, 'g, K, V> Entry<'a, 'g, K, V>
where
K: Ord + Send + 'static,
V: Send + 'static,
{
pub fn remove(&self) -> bool {
if self.node.mark_tower() {
self.parent.hot_data.len.fetch_sub(1, Ordering::Relaxed);
self.parent
.search_bound(Bound::Included(&self.node.key), false, self.guard);
true
} else {
false
}
}
}
impl<'a: 'g, 'g, K, V> Clone for Entry<'a, 'g, K, V> {
fn clone(&self) -> Entry<'a, 'g, K, V> {
Entry {
parent: self.parent,
node: self.node,
guard: self.guard,
}
}
}
impl<K, V> fmt::Debug for Entry<'_, '_, K, V>
where
K: fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Entry")
.field(self.key())
.field(self.value())
.finish()
}
}
impl<'a: 'g, 'g, K, V> Entry<'a, 'g, K, V>
where
K: Ord,
{
pub fn move_next(&mut self) -> bool {
match self.next() {
None => false,
Some(n) => {
*self = n;
true
}
}
}
pub fn next(&self) -> Option<Entry<'a, 'g, K, V>> {
let n = self.parent.next_node(
&self.node.tower,
Bound::Excluded(&self.node.key),
self.guard,
)?;
Some(Entry {
parent: self.parent,
node: n,
guard: self.guard,
})
}
pub fn move_prev(&mut self) -> bool {
match self.prev() {
None => false,
Some(n) => {
*self = n;
true
}
}
}
pub fn prev(&self) -> Option<Entry<'a, 'g, K, V>> {
let n = self
.parent
.search_bound(Bound::Excluded(&self.node.key), true, self.guard)?;
Some(Entry {
parent: self.parent,
node: n,
guard: self.guard,
})
}
}
pub struct RefEntry<'a, K, V> {
parent: &'a SkipList<K, V>,
node: &'a Node<K, V>,
}
impl<'a, K: 'a, V: 'a> RefEntry<'a, K, V> {
pub fn is_removed(&self) -> bool {
self.node.is_removed()
}
pub fn key(&self) -> &K {
&self.node.key
}
pub fn value(&self) -> &V {
&self.node.value
}
pub fn skiplist(&self) -> &'a SkipList<K, V> {
self.parent
}
pub fn release(self, guard: &Guard) {
self.parent.check_guard(guard);
unsafe { self.node.decrement(guard) }
}
pub fn release_with_pin<F>(self, pin: F)
where
F: FnOnce() -> Guard,
{
unsafe { self.node.decrement_with_pin(self.parent, pin) }
}
unsafe fn try_acquire(
parent: &'a SkipList<K, V>,
node: &Node<K, V>,
) -> Option<RefEntry<'a, K, V>> {
if node.try_increment() {
Some(RefEntry {
parent,
node: &*(node as *const _),
})
} else {
None
}
}
}
impl<K, V> RefEntry<'_, K, V>
where
K: Ord + Send + 'static,
V: Send + 'static,
{
pub fn remove(&self, guard: &Guard) -> bool {
self.parent.check_guard(guard);
if self.node.mark_tower() {
self.parent.hot_data.len.fetch_sub(1, Ordering::Relaxed);
self.parent
.search_bound(Bound::Included(&self.node.key), false, guard);
true
} else {
false
}
}
}
impl<'a, K, V> Clone for RefEntry<'a, K, V> {
fn clone(&self) -> RefEntry<'a, K, V> {
unsafe {
Node::try_increment(self.node);
}
RefEntry {
parent: self.parent,
node: self.node,
}
}
}
impl<K, V> fmt::Debug for RefEntry<'_, K, V>
where
K: fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("RefEntry")
.field(self.key())
.field(self.value())
.finish()
}
}
impl<'a, K, V> RefEntry<'a, K, V>
where
K: Ord,
{
pub fn move_next(&mut self, guard: &Guard) -> bool {
match self.next(guard) {
None => false,
Some(e) => {
mem::replace(self, e).release(guard);
true
}
}
}
pub fn next(&self, guard: &Guard) -> Option<RefEntry<'a, K, V>> {
self.parent.check_guard(guard);
unsafe {
let mut n = self.node;
loop {
n = self
.parent
.next_node(&n.tower, Bound::Excluded(&n.key), guard)?;
if let Some(e) = RefEntry::try_acquire(self.parent, n) {
return Some(e);
}
}
}
}
pub fn move_prev(&mut self, guard: &Guard) -> bool {
match self.prev(guard) {
None => false,
Some(e) => {
mem::replace(self, e).release(guard);
true
}
}
}
pub fn prev(&self, guard: &Guard) -> Option<RefEntry<'a, K, V>> {
self.parent.check_guard(guard);
unsafe {
let mut n = self.node;
loop {
n = self
.parent
.search_bound(Bound::Excluded(&n.key), true, guard)?;
if let Some(e) = RefEntry::try_acquire(self.parent, n) {
return Some(e);
}
}
}
}
}
pub struct Iter<'a: 'g, 'g, K, V> {
parent: &'a SkipList<K, V>,
head: Option<&'g Node<K, V>>,
tail: Option<&'g Node<K, V>>,
guard: &'g Guard,
}
impl<'a: 'g, 'g, K: 'a, V: 'a> Iterator for Iter<'a, 'g, K, V>
where
K: Ord,
{
type Item = Entry<'a, 'g, K, V>;
fn next(&mut self) -> Option<Entry<'a, 'g, K, V>> {
self.head = match self.head {
Some(n) => self
.parent
.next_node(&n.tower, Bound::Excluded(&n.key), self.guard),
None => self
.parent
.next_node(&self.parent.head, Bound::Unbounded, self.guard),
};
if let (Some(h), Some(t)) = (self.head, self.tail) {
if h.key >= t.key {
self.head = None;
self.tail = None;
}
}
self.head.map(|n| Entry {
parent: self.parent,
node: n,
guard: self.guard,
})
}
}
impl<'a: 'g, 'g, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, 'g, K, V>
where
K: Ord,
{
fn next_back(&mut self) -> Option<Entry<'a, 'g, K, V>> {
self.tail = match self.tail {
Some(n) => self
.parent
.search_bound(Bound::Excluded(&n.key), true, self.guard),
None => self.parent.search_bound(Bound::Unbounded, true, self.guard),
};
if let (Some(h), Some(t)) = (self.head, self.tail) {
if h.key >= t.key {
self.head = None;
self.tail = None;
}
}
self.tail.map(|n| Entry {
parent: self.parent,
node: n,
guard: self.guard,
})
}
}
impl<K, V> fmt::Debug for Iter<'_, '_, K, V>
where
K: fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Iter")
.field("head", &self.head.map(|n| (&n.key, &n.value)))
.field("tail", &self.tail.map(|n| (&n.key, &n.value)))
.finish()
}
}
pub struct RefIter<'a, K, V> {
parent: &'a SkipList<K, V>,
head: Option<RefEntry<'a, K, V>>,
tail: Option<RefEntry<'a, K, V>>,
}
impl<K, V> fmt::Debug for RefIter<'_, K, V>
where
K: fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_struct("RefIter");
match &self.head {
None => d.field("head", &None::<(&K, &V)>),
Some(e) => d.field("head", &(e.key(), e.value())),
};
match &self.tail {
None => d.field("tail", &None::<(&K, &V)>),
Some(e) => d.field("tail", &(e.key(), e.value())),
};
d.finish()
}
}
impl<'a, K: 'a, V: 'a> RefIter<'a, K, V>
where
K: Ord,
{
pub fn next(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V>> {
self.parent.check_guard(guard);
let next_head = match &self.head {
Some(e) => e.next(guard),
None => try_pin_loop(|| self.parent.front(guard)),
};
match (&next_head, &self.tail) {
(Some(ref next), &Some(ref t)) if next.key() >= t.key() => {
unsafe {
next.node.decrement(guard);
}
None
}
(Some(_), _) => {
if let Some(e) = mem::replace(&mut self.head, next_head.clone()) {
unsafe {
e.node.decrement(guard);
}
}
next_head
}
(None, _) => None,
}
}
pub fn next_back(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V>> {
self.parent.check_guard(guard);
let next_tail = match &self.tail {
Some(e) => e.prev(guard),
None => try_pin_loop(|| self.parent.back(guard)),
};
match (&self.head, &next_tail) {
(&Some(ref h), Some(next)) if h.key() >= next.key() => {
unsafe {
next.node.decrement(guard);
}
None
}
(_, Some(_)) => {
if let Some(e) = mem::replace(&mut self.tail, next_tail.clone()) {
unsafe {
e.node.decrement(guard);
}
}
next_tail
}
(_, None) => None,
}
}
}
impl<'a, K: 'a, V: 'a> RefIter<'a, K, V> {
pub fn drop_impl(&mut self, guard: &Guard) {
self.parent.check_guard(guard);
if let Some(e) = mem::replace(&mut self.head, None) {
unsafe { e.node.decrement(guard) };
}
if let Some(e) = mem::replace(&mut self.tail, None) {
unsafe { e.node.decrement(guard) };
}
}
}
pub struct Range<'a: 'g, 'g, Q, R, K, V>
where
K: Ord + Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
parent: &'a SkipList<K, V>,
head: Option<&'g Node<K, V>>,
tail: Option<&'g Node<K, V>>,
range: R,
guard: &'g Guard,
_marker: PhantomData<fn() -> Q>, }
impl<'a: 'g, 'g, Q, R, K: 'a, V: 'a> Iterator for Range<'a, 'g, Q, R, K, V>
where
K: Ord + Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
type Item = Entry<'a, 'g, K, V>;
fn next(&mut self) -> Option<Entry<'a, 'g, K, V>> {
self.head = match self.head {
Some(n) => self
.parent
.next_node(&n.tower, Bound::Excluded(&n.key), self.guard),
None => self
.parent
.search_bound(self.range.start_bound(), false, self.guard),
};
if let Some(h) = self.head {
let bound = match self.tail {
Some(t) => Bound::Excluded(t.key.borrow()),
None => self.range.end_bound(),
};
if !below_upper_bound(&bound, h.key.borrow()) {
self.head = None;
self.tail = None;
}
}
self.head.map(|n| Entry {
parent: self.parent,
node: n,
guard: self.guard,
})
}
}
impl<'a: 'g, 'g, Q, R, K: 'a, V: 'a> DoubleEndedIterator for Range<'a, 'g, Q, R, K, V>
where
K: Ord + Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
fn next_back(&mut self) -> Option<Entry<'a, 'g, K, V>> {
self.tail = match self.tail {
Some(n) => self
.parent
.search_bound(Bound::Excluded(n.key.borrow()), true, self.guard),
None => self
.parent
.search_bound(self.range.end_bound(), true, self.guard),
};
if let Some(t) = self.tail {
let bound = match self.head {
Some(h) => Bound::Excluded(h.key.borrow()),
None => self.range.start_bound(),
};
if !above_lower_bound(&bound, t.key.borrow()) {
self.head = None;
self.tail = None;
}
}
self.tail.map(|n| Entry {
parent: self.parent,
node: n,
guard: self.guard,
})
}
}
impl<Q, R, K, V> fmt::Debug for Range<'_, '_, Q, R, K, V>
where
K: Ord + Borrow<Q> + fmt::Debug,
V: fmt::Debug,
R: RangeBounds<Q> + fmt::Debug,
Q: Ord + ?Sized,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Range")
.field("range", &self.range)
.field("head", &self.head)
.field("tail", &self.tail)
.finish()
}
}
pub struct RefRange<'a, Q, R, K, V>
where
K: Ord + Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
parent: &'a SkipList<K, V>,
pub(crate) head: Option<RefEntry<'a, K, V>>,
pub(crate) tail: Option<RefEntry<'a, K, V>>,
pub(crate) range: R,
_marker: PhantomData<fn() -> Q>, }
unsafe impl<Q, R, K, V> Send for RefRange<'_, Q, R, K, V>
where
K: Ord + Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
}
unsafe impl<Q, R, K, V> Sync for RefRange<'_, Q, R, K, V>
where
K: Ord + Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
}
impl<Q, R, K, V> fmt::Debug for RefRange<'_, Q, R, K, V>
where
K: Ord + Borrow<Q> + fmt::Debug,
V: fmt::Debug,
R: RangeBounds<Q> + fmt::Debug,
Q: Ord + ?Sized,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RefRange")
.field("range", &self.range)
.field("head", &self.head)
.field("tail", &self.tail)
.finish()
}
}
impl<'a, Q, R, K: 'a, V: 'a> RefRange<'a, Q, R, K, V>
where
K: Ord + Borrow<Q>,
R: RangeBounds<Q>,
Q: Ord + ?Sized,
{
pub fn next(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V>> {
self.parent.check_guard(guard);
let next_head = match self.head {
Some(ref e) => e.next(guard),
None => try_pin_loop(|| self.parent.lower_bound(self.range.start_bound(), guard)),
};
if let Some(ref h) = next_head {
let bound = match self.tail {
Some(ref t) => Bound::Excluded(t.key().borrow()),
None => self.range.end_bound(),
};
if below_upper_bound(&bound, h.key().borrow()) {
self.head = next_head.clone();
next_head
} else {
unsafe {
h.node.decrement(guard);
}
None
}
} else {
None
}
}
pub fn next_back(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V>> {
self.parent.check_guard(guard);
let next_tail = match self.tail {
Some(ref e) => e.prev(guard),
None => try_pin_loop(|| self.parent.upper_bound(self.range.end_bound(), guard)),
};
if let Some(ref t) = next_tail {
let bound = match self.head {
Some(ref h) => Bound::Excluded(h.key().borrow()),
None => self.range.start_bound(),
};
if above_lower_bound(&bound, t.key().borrow()) {
self.tail = next_tail.clone();
next_tail
} else {
unsafe {
t.node.decrement(guard);
}
None
}
} else {
None
}
}
pub fn drop_impl(&mut self, guard: &Guard) {
self.parent.check_guard(guard);
if let Some(e) = mem::replace(&mut self.head, None) {
unsafe { e.node.decrement(guard) };
}
if let Some(e) = mem::replace(&mut self.tail, None) {
unsafe { e.node.decrement(guard) };
}
}
}
pub struct IntoIter<K, V> {
node: *mut Node<K, V>,
}
impl<K, V> Drop for IntoIter<K, V> {
fn drop(&mut self) {
while !self.node.is_null() {
unsafe {
let next = (*self.node).tower[0].load(Ordering::Relaxed, epoch::unprotected());
Node::finalize(self.node);
self.node = next.as_raw() as *mut Node<K, V>;
}
}
}
}
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
loop {
if self.node.is_null() {
return None;
}
unsafe {
let key = ptr::read(&(*self.node).key);
let value = ptr::read(&(*self.node).value);
let next = (*self.node).tower[0].load(Ordering::Relaxed, epoch::unprotected());
Node::dealloc(self.node);
self.node = next.as_raw() as *mut Node<K, V>;
if next.tag() == 0 {
return Some((key, value));
}
}
}
}
}
impl<K, V> fmt::Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("IntoIter { .. }")
}
}
pub(crate) fn try_pin_loop<'a: 'g, 'g, F, K, V>(mut f: F) -> Option<RefEntry<'a, K, V>>
where
F: FnMut() -> Option<Entry<'a, 'g, K, V>>,
{
loop {
if let Some(e) = f()?.pin() {
return Some(e);
}
}
}
fn above_lower_bound<T: Ord + ?Sized>(bound: &Bound<&T>, other: &T) -> bool {
match *bound {
Bound::Unbounded => true,
Bound::Included(key) => other >= key,
Bound::Excluded(key) => other > key,
}
}
fn below_upper_bound<T: Ord + ?Sized>(bound: &Bound<&T>, other: &T) -> bool {
match *bound {
Bound::Unbounded => true,
Bound::Included(key) => other <= key,
Bound::Excluded(key) => other < key,
}
}