clt_database/skiplist/base.rs
1//! A lock-free skip list. See [`SkipList`].
2
3use core::{
4 alloc::Layout,
5 cmp, fmt,
6 marker::PhantomData,
7 mem,
8 ops::{Bound, Deref, RangeBounds},
9 ptr,
10 ptr::NonNull,
11 sync::atomic::{fence, AtomicUsize, Ordering},
12};
13use std::alloc::handle_alloc_error;
14
15use crossbeam_epoch::{self as epoch, Atomic, Collector, Guard, Shared};
16use crossbeam_utils::CachePadded;
17
18use super::comparator::{BasicComparator, Comparator};
19use crate::alloc::{ConcurrentAllocator, TryReserveError, TursoAllocator};
20
21/// An allocator that can back a [`SkipList`].
22///
23/// Blanket-implemented for every [`ConcurrentAllocator`].
24/// Cloning must be cheap and must not panic: deferred node destruction
25/// captures a clone of the allocator that is dropped once the node is
26/// reclaimed. The `'static` bound is required for the same reason the insert
27/// APIs require `K: Send + 'static`: deferred destruction can run after the
28/// skip list itself is gone, so the allocator must not borrow from anything
29/// (in particular, `&LocalAlloc` would dangle by the time the deferred
30/// closure deallocates the node).
31pub trait SkiplistAllocator: ConcurrentAllocator {}
32
33impl<A: ConcurrentAllocator> SkiplistAllocator for A {}
34
35/// Number of bits needed to store height.
36const HEIGHT_BITS: usize = 5;
37
38/// Maximum height of a skip list tower.
39const MAX_HEIGHT: usize = 1 << HEIGHT_BITS;
40
41/// The bits of `refs_and_height` that keep the height.
42const HEIGHT_MASK: usize = (1 << HEIGHT_BITS) - 1;
43
44/// The tower of atomic pointers.
45///
46/// The actual size of the tower will vary depending on the height that a node
47/// was allocated with.
48#[repr(C)]
49struct Tower<K, V> {
50 pointers: [Atomic<Node<K, V>>; 0],
51}
52
53/// A "reference" to a Tower that preserves provenance for accessing the dynamically sized tower.
54///
55/// A regular `&'a Tower<K, V>` would not have permission to access any bytes under stacked borrows
56/// since Tower is a placeholder ZST.
57///
58/// Note, under tree borrows this isn't necessary.
59struct TowerRef<'a, K, V> {
60 ptr: NonNull<Tower<K, V>>,
61 _marker: PhantomData<&'a Tower<K, V>>,
62}
63
64impl<K, V> Clone for TowerRef<'_, K, V> {
65 fn clone(&self) -> Self {
66 *self
67 }
68}
69impl<K, V> Copy for TowerRef<'_, K, V> {}
70
71impl<'a, K, V> TowerRef<'a, K, V> {
72 /// Creates a TowerRef.
73 ///
74 /// # Safety
75 ///
76 /// Same as NonNull::as_ref, except the pointer must be valid for accessing the actual
77 /// size of the tower.
78 #[inline]
79 unsafe fn new(ptr: NonNull<Tower<K, V>>) -> Self {
80 Self {
81 ptr,
82 _marker: PhantomData,
83 }
84 }
85
86 /// Gets the atomic node pointer at the specified level of the tower.
87 ///
88 /// # Safety
89 ///
90 /// Index must be in bounds.
91 #[inline]
92 unsafe fn get_level(self, index: usize) -> &'a Atomic<Node<K, V>> {
93 // SAFETY: Requirements passed to caller.
94 unsafe { &*(self.ptr.as_ptr() as *const Atomic<Node<K, V>>).add(index) }
95 }
96}
97
98/// Tower at the head of a skip list.
99///
100/// This is located in the `SkipList` struct itself and holds a full height
101/// tower.
102#[repr(C)]
103struct Head<K, V> {
104 pointers: [Atomic<Node<K, V>>; MAX_HEIGHT],
105}
106
107impl<K, V> Head<K, V> {
108 /// Initializes a `Head`.
109 #[inline]
110 fn new() -> Self {
111 // Initializing arrays in rust is a pain...
112 Self {
113 pointers: Default::default(),
114 }
115 }
116
117 /// Gets `TowerRef`
118 #[inline]
119 fn as_tower(&self) -> TowerRef<'_, K, V> {
120 unsafe { TowerRef::new(NonNull::from(self).cast::<Tower<K, V>>()) }
121 }
122
123 /// Gets the atomic node pointer at the specified level.
124 ///
125 /// # Safety
126 ///
127 /// Index must be in bounds.
128 #[inline]
129 unsafe fn get_level(&self, index: usize) -> &Atomic<Node<K, V>> {
130 // SAFETY: Requirements passed to caller.
131 unsafe { self.pointers.get_unchecked(index) }
132 }
133}
134
135/// A skip list node.
136///
137/// This struct is marked with `repr(C)` so that the specific order of fields is enforced.
138/// It is important that the tower is the last field since it is dynamically sized. The key,
139/// reference count, and height are kept close to the tower to improve cache locality during
140/// skip list traversal.
141#[repr(C)]
142struct Node<K, V> {
143 /// The value.
144 value: V,
145
146 /// The key.
147 key: K,
148
149 /// Keeps the reference count and the height of its tower.
150 ///
151 /// The reference count is equal to the number of `Entry`s pointing to this node, plus the
152 /// number of levels in which this node is installed.
153 refs_and_height: AtomicUsize,
154
155 /// The tower of atomic pointers.
156 tower: Tower<K, V>,
157}
158
159/// A "reference" to a Node that preserves provenance for accessing the dynamically sized tower at
160/// the end of the node allocation.
161///
162/// Note, in a few situations below, we also rely on this for preserving write permissions.
163struct NodeRef<'a, K, V> {
164 ptr: NonNull<Node<K, V>>,
165 _marker: PhantomData<&'a Node<K, V>>,
166}
167
168impl<K, V> Clone for NodeRef<'_, K, V> {
169 fn clone(&self) -> Self {
170 *self
171 }
172}
173impl<K, V> Copy for NodeRef<'_, K, V> {}
174
175// Local modification (not upstream): `NodeRef` is semantically `&'a Node<K, V>`,
176// so give it the same auto-trait behavior. Upstream's switch from `&'a Node` to
177// `NonNull` dropped these impls, making `RefEntry`/`RefIter` (and the map/set
178// iterators built on them) `!Send + !Sync`.
179unsafe impl<K: Sync, V: Sync> Send for NodeRef<'_, K, V> {}
180unsafe impl<K: Sync, V: Sync> Sync for NodeRef<'_, K, V> {}
181
182impl<K, V> Node<K, V> {
183 /// Allocates a node, returning the layout that could not be allocated on failure.
184 ///
185 /// The returned node will start with reference count of `ref_count` and the tower will be initialized
186 /// with null pointers. However, the key and the value will be left uninitialized, and that is
187 /// why this function is unsafe.
188 unsafe fn try_alloc<A: SkiplistAllocator>(
189 alloc: &A,
190 height: usize,
191 ref_count: usize,
192 ) -> Result<*mut Self, Layout> {
193 let layout = Self::get_layout(height);
194 unsafe {
195 let ptr = match alloc.allocate(layout) {
196 Ok(ptr) => ptr.as_ptr().cast::<Self>(),
197 Err(_) => return Err(layout),
198 };
199
200 ptr::addr_of_mut!((*ptr).refs_and_height)
201 .write(AtomicUsize::new((height - 1) | (ref_count << HEIGHT_BITS)));
202 ptr::addr_of_mut!((*ptr).tower.pointers)
203 .cast::<Atomic<Self>>()
204 .write_bytes(0, height);
205 Ok(ptr)
206 }
207 }
208
209 /// Deallocates a node.
210 ///
211 /// This function will not run any destructors.
212 unsafe fn dealloc<A: SkiplistAllocator>(alloc: &A, ptr: *mut Self) {
213 unsafe {
214 let height = (*ptr).height();
215 let layout = Self::get_layout(height);
216 alloc.deallocate(NonNull::new_unchecked(ptr.cast::<u8>()), layout);
217 }
218 }
219
220 /// Returns the layout of a node with the given `height`.
221 fn get_layout(height: usize) -> Layout {
222 assert!((1..=MAX_HEIGHT).contains(&height));
223
224 Layout::new::<Self>()
225 .extend(Layout::array::<Atomic<Self>>(height).unwrap())
226 .unwrap()
227 .0
228 .pad_to_align()
229 }
230
231 /// Returns the height of this node's tower.
232 #[inline]
233 fn height(&self) -> usize {
234 (self.refs_and_height.load(Ordering::Relaxed) & HEIGHT_MASK) + 1
235 }
236
237 /// Attempts to increment the reference count of a node and returns `true` on success.
238 ///
239 /// The reference count can be incremented only if it is non-zero.
240 ///
241 /// # Panics
242 ///
243 /// Panics if the reference count overflows.
244 #[inline]
245 unsafe fn try_increment(&self) -> bool {
246 let mut refs_and_height = self.refs_and_height.load(Ordering::Relaxed);
247
248 loop {
249 // If the reference count is zero, then the node has already been
250 // queued for deletion. Incrementing it again could lead to a
251 // double-free.
252 if refs_and_height & !HEIGHT_MASK == 0 {
253 return false;
254 }
255
256 // If all bits in the reference count are ones, we're about to overflow it.
257 let new_refs_and_height = refs_and_height
258 .checked_add(1 << HEIGHT_BITS)
259 .expect("SkipList reference count overflow");
260
261 // Try incrementing the count.
262 match self.refs_and_height.compare_exchange_weak(
263 refs_and_height,
264 new_refs_and_height,
265 Ordering::Relaxed,
266 Ordering::Relaxed,
267 ) {
268 Ok(_) => return true,
269 Err(current) => refs_and_height = current,
270 }
271 }
272 }
273
274 /// Drops the key and value of a node, then deallocates it.
275 #[cold]
276 unsafe fn finalize<A: SkiplistAllocator>(alloc: &A, ptr: *mut Self) {
277 unsafe {
278 // Call destructors: drop the key and the value.
279 ptr::drop_in_place(&mut (*ptr).key);
280 ptr::drop_in_place(&mut (*ptr).value);
281
282 // Finally, deallocate the memory occupied by the node.
283 Self::dealloc(alloc, ptr);
284 }
285 }
286}
287
288impl<'a, K, V> NodeRef<'a, K, V> {
289 /// Creates a NodeRef.
290 ///
291 /// # Safety
292 ///
293 /// Same as NonNull::as_ref, except the pointer must also be valid for accessing the actual
294 /// size of the tower at the end of the node.
295 #[inline]
296 unsafe fn new(ptr: NonNull<Node<K, V>>) -> Self {
297 Self {
298 ptr,
299 _marker: PhantomData,
300 }
301 }
302
303 /// # Safety
304 ///
305 /// See [`Shared::as_ref`].
306 #[inline]
307 #[allow(clippy::manual_map)] // vendored: keep upstream code as-is
308 unsafe fn from_shared(shared: Shared<'a, Node<K, V>>) -> Option<Self> {
309 if let Some(ptr) = NonNull::new(shared.as_raw() as *mut Node<K, V>) {
310 Some(unsafe { Self::new(ptr) })
311 } else {
312 None
313 }
314 }
315
316 /// Decrements the reference count of a node, destroying it if the count becomes zero.
317 ///
318 /// `alloc` must be the allocator the node was allocated with; destruction captures a
319 /// clone of it.
320 #[inline]
321 unsafe fn decrement<A: SkiplistAllocator>(self, alloc: &A, guard: &Guard) {
322 if self
323 .refs_and_height
324 .fetch_sub(1 << HEIGHT_BITS, Ordering::Release)
325 >> HEIGHT_BITS
326 == 1
327 {
328 fence(Ordering::Acquire);
329 let alloc = alloc.clone();
330 unsafe { guard.defer_unchecked(move || Node::finalize(&alloc, self.ptr.as_ptr())) }
331 }
332 }
333
334 /// Decrements the reference count of a node, pinning the thread and destroying the node
335 /// if the count become zero.
336 #[inline]
337 unsafe fn decrement_with_pin<F, C, A: SkiplistAllocator>(
338 self,
339 parent: &SkipList<K, V, C, A>,
340 pin: F,
341 ) where
342 F: FnOnce() -> Guard,
343 {
344 if self
345 .refs_and_height
346 .fetch_sub(1 << HEIGHT_BITS, Ordering::Release)
347 >> HEIGHT_BITS
348 == 1
349 {
350 fence(Ordering::Acquire);
351 let guard = &pin();
352 parent.check_guard(guard);
353 let alloc = parent.alloc.clone();
354 unsafe { guard.defer_unchecked(move || Node::finalize(&alloc, self.ptr.as_ptr())) }
355 }
356 }
357
358 /// Marks all pointers in the tower and returns `true` if the level 0 was not marked.
359 fn mark_tower(self) -> bool {
360 let height = self.height();
361
362 for level in (0..height).rev() {
363 let tag = unsafe {
364 // We're loading the pointer only for the tag, so it's okay to use
365 // `epoch::unprotected()` in this situation.
366 // TODO(Amanieu): can we use release ordering here?
367 self.get_level(level)
368 .fetch_or(1, Ordering::SeqCst, epoch::unprotected())
369 .tag()
370 };
371
372 // If the level 0 pointer was already marked, somebody else removed the node.
373 if level == 0 && tag == 1 {
374 return false;
375 }
376 }
377
378 // We marked the level 0 pointer, therefore we removed the node.
379 true
380 }
381
382 /// Returns `true` if the node is removed.
383 #[inline]
384 fn is_removed(self) -> bool {
385 let tag = unsafe {
386 // We're loading the pointer only for the tag, so it's okay to use
387 // `epoch::unprotected()` in this situation.
388 self.get_level(0)
389 .load(Ordering::Relaxed, epoch::unprotected())
390 .tag()
391 };
392 tag == 1
393 }
394
395 /// Creates a TowerRef to the atomic pointers at the end of this Node allocation.
396 #[inline]
397 fn as_tower(self) -> TowerRef<'a, K, V> {
398 // SAFETY: self.ptr has provenance to access the tower.
399 unsafe {
400 TowerRef::new(NonNull::new_unchecked(
401 ptr::addr_of!((*self.ptr.as_ptr()).tower) as *mut Tower<K, V>,
402 ))
403 }
404 }
405
406 /// Gets a plain reference to the node which can be used for anything that doesn't need to access
407 /// the tower.
408 #[inline]
409 fn as_ref(self) -> &'a Node<K, V> {
410 // SAFETY: Self::new requires the conditions for creating a Node reference.
411 unsafe { self.ptr.as_ref() }
412 }
413
414 /// Gets the atomic node pointer at the specified level of the tower.
415 ///
416 /// # Safety
417 ///
418 /// Index must be in bounds.
419 #[inline]
420 unsafe fn get_level(&self, index: usize) -> &Atomic<Node<K, V>> {
421 // SAFETY: Requirements passed to caller.
422 unsafe { self.as_tower().get_level(index) }
423 }
424}
425
426impl<K, V> Deref for NodeRef<'_, K, V> {
427 type Target = Node<K, V>;
428 #[inline]
429 fn deref(&self) -> &Node<K, V> {
430 self.as_ref()
431 }
432}
433
434impl<K, V> fmt::Debug for Node<K, V>
435where
436 K: fmt::Debug,
437 V: fmt::Debug,
438{
439 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
440 f.debug_tuple("Node")
441 .field(&self.key)
442 .field(&self.value)
443 .finish()
444 }
445}
446
447impl<K, V> fmt::Debug for NodeRef<'_, K, V>
448where
449 K: fmt::Debug,
450 V: fmt::Debug,
451{
452 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
453 <Node<K, V> as fmt::Debug>::fmt(self, f)
454 }
455}
456
457/// A search result.
458///
459/// The result indicates whether the key was found, as well as what were the adjacent nodes to the
460/// key on each level of the skip list.
461struct Position<'a, K, V> {
462 /// Reference to a node with the given key, if found.
463 ///
464 /// If this is `Some` then it will point to the same node as `right[0]`.
465 found: Option<NodeRef<'a, K, V>>,
466
467 /// Adjacent nodes with smaller keys (predecessors).
468 left: [TowerRef<'a, K, V>; MAX_HEIGHT],
469
470 /// Adjacent nodes with equal or greater keys (successors).
471 right: [Shared<'a, Node<K, V>>; MAX_HEIGHT],
472}
473
474/// Frequently modified data associated with a skip list.
475struct HotData {
476 /// The seed for random height generation.
477 seed: AtomicUsize,
478
479 /// The number of entries in the skip list.
480 len: AtomicUsize,
481
482 /// Highest tower currently in use. This value is used as a hint for where
483 /// to start lookups and never decreases.
484 max_height: AtomicUsize,
485}
486
487/// A lock-free skip list.
488// TODO(stjepang): Embed a custom `epoch::Collector` inside `SkipList<K, V>`. Instead of adding
489// garbage to the default global collector, we should add it to a local collector tied to the
490// particular skip list instance.
491//
492// Since global collector might destroy garbage arbitrarily late in the future, some skip list
493// methods have `K: 'static` and `V: 'static` bounds. But a local collector embedded in the skip
494// list would destroy all remaining garbage when the skip list is dropped, so in that case we'd be
495// able to remove those bounds on types `K` and `V`.
496//
497// As a further future optimization, if `!mem::needs_drop::<K>() && !mem::needs_drop::<V>()`
498// (neither key nor the value have destructors), there's no point in creating a new local
499// collector, so we should simply use the global one.
500pub struct SkipList<K, V, C = BasicComparator, A: SkiplistAllocator = TursoAllocator> {
501 /// The head of the skip list (just a dummy node, not a real entry).
502 head: Head<K, V>,
503
504 /// The `Collector` associated with this skip list.
505 collector: Collector,
506
507 /// Hot data associated with the skip list, stored in a dedicated cache line.
508 hot_data: CachePadded<HotData>,
509
510 /// The `Comparator` used to determine key ordering.
511 comparator: C,
512
513 /// The allocator used for the skip list nodes.
514 alloc: A,
515}
516
517unsafe impl<K: Send + Sync, V: Send + Sync, C: Send + Sync, A: SkiplistAllocator> Send
518 for SkipList<K, V, C, A>
519{
520}
521unsafe impl<K: Send + Sync, V: Send + Sync, C: Send + Sync, A: SkiplistAllocator> Sync
522 for SkipList<K, V, C, A>
523{
524}
525
526impl<K, V> SkipList<K, V> {
527 /// Returns a new, empty skip list.
528 pub fn new(collector: Collector) -> Self {
529 Self::with_comparator(collector, Default::default())
530 }
531}
532
533impl<K, V, A: SkiplistAllocator> SkipList<K, V, BasicComparator, A> {
534 /// Returns a new, empty skip list that allocates its nodes in `alloc`.
535 pub fn new_in(collector: Collector, alloc: A) -> Self {
536 Self::with_comparator_in(collector, Default::default(), alloc)
537 }
538}
539
540impl<K, V, C> SkipList<K, V, C> {
541 /// Returns a new, empty skip list using the given comparator.
542 pub fn with_comparator(collector: Collector, comparator: C) -> Self {
543 Self::with_comparator_in(collector, comparator, TursoAllocator)
544 }
545}
546
547impl<K, V, C, A: SkiplistAllocator> SkipList<K, V, C, A> {
548 /// Returns a new, empty skip list using the given comparator, allocating its nodes
549 /// in `alloc`.
550 pub fn with_comparator_in(collector: Collector, comparator: C, alloc: A) -> Self {
551 Self {
552 head: Head::new(),
553 collector,
554 hot_data: CachePadded::new(HotData {
555 seed: AtomicUsize::new(1),
556 len: AtomicUsize::new(0),
557 max_height: AtomicUsize::new(1),
558 }),
559 comparator,
560 alloc,
561 }
562 }
563
564 /// Returns `true` if the skip list is empty.
565 pub fn is_empty(&self) -> bool {
566 self.len() == 0
567 }
568
569 /// Returns the number of entries in the skip list.
570 ///
571 /// If the skip list is being concurrently modified, consider the returned number just an
572 /// approximation without any guarantees.
573 pub fn len(&self) -> usize {
574 let len = self.hot_data.len.load(Ordering::Relaxed);
575
576 // Due to the relaxed memory ordering, the length counter may sometimes
577 // underflow and produce a very large value. We treat such values as 0.
578 if len > isize::MAX as usize {
579 0
580 } else {
581 len
582 }
583 }
584
585 /// Ensures that all `Guard`s used with the skip list come from the same
586 /// `Collector`.
587 fn check_guard(&self, guard: &Guard) {
588 if let Some(c) = guard.collector() {
589 assert!(c == &self.collector);
590 }
591 }
592}
593
594impl<K, V, C, A: SkiplistAllocator> SkipList<K, V, C, A>
595where
596 C: Comparator<K>,
597{
598 /// Returns the entry with the smallest key.
599 pub fn front<'a: 'g, 'g>(&'a self, guard: &'g Guard) -> Option<Entry<'a, 'g, K, V, C, A>> {
600 self.check_guard(guard);
601 let n = self.next_node(self.head.as_tower(), Bound::Unbounded, guard)?;
602 Some(Entry {
603 parent: self,
604 node: n,
605 guard,
606 })
607 }
608
609 /// Returns the entry with the largest key.
610 pub fn back<'a: 'g, 'g>(&'a self, guard: &'g Guard) -> Option<Entry<'a, 'g, K, V, C, A>> {
611 self.check_guard(guard);
612 let n = self.search_bound::<K>(Bound::Unbounded, true, guard)?;
613 Some(Entry {
614 parent: self,
615 node: n,
616 guard,
617 })
618 }
619
620 /// Returns `true` if the map contains a value for the specified key.
621 pub fn contains_key<Q>(&self, key: &Q, guard: &Guard) -> bool
622 where
623 C: Comparator<K, Q>,
624 Q: ?Sized,
625 {
626 self.get(key, guard).is_some()
627 }
628
629 /// Returns an entry with the specified `key`.
630 pub fn get<'a: 'g, 'g, Q>(
631 &'a self,
632 key: &Q,
633 guard: &'g Guard,
634 ) -> Option<Entry<'a, 'g, K, V, C, A>>
635 where
636 C: Comparator<K, Q>,
637 Q: ?Sized,
638 {
639 self.check_guard(guard);
640 let n = self.search_bound(Bound::Included(key), false, guard)?;
641 if !self.comparator.equivalent(&n.key, key) {
642 return None;
643 }
644
645 Some(Entry {
646 parent: self,
647 node: n,
648 guard,
649 })
650 }
651
652 /// Returns an `Entry` pointing to the lowest element whose key is above
653 /// the given bound. If no such element is found then `None` is
654 /// returned.
655 pub fn lower_bound<'a: 'g, 'g, Q>(
656 &'a self,
657 bound: Bound<&Q>,
658 guard: &'g Guard,
659 ) -> Option<Entry<'a, 'g, K, V, C, A>>
660 where
661 C: Comparator<K, Q>,
662 Q: ?Sized,
663 {
664 self.check_guard(guard);
665 let n = self.search_bound(bound, false, guard)?;
666 Some(Entry {
667 parent: self,
668 node: n,
669 guard,
670 })
671 }
672
673 /// Returns an `Entry` pointing to the highest element whose key is below
674 /// the given bound. If no such element is found then `None` is
675 /// returned.
676 pub fn upper_bound<'a: 'g, 'g, Q>(
677 &'a self,
678 bound: Bound<&Q>,
679 guard: &'g Guard,
680 ) -> Option<Entry<'a, 'g, K, V, C, A>>
681 where
682 C: Comparator<K, Q>,
683 Q: ?Sized,
684 {
685 self.check_guard(guard);
686 let n = self.search_bound(bound, true, guard)?;
687 Some(Entry {
688 parent: self,
689 node: n,
690 guard,
691 })
692 }
693
694 /// Finds an entry with the specified key, or inserts a new `key`-`value` pair if none exist.
695 pub fn get_or_insert(&self, key: K, value: V, guard: &Guard) -> RefEntry<'_, K, V, C, A> {
696 match self.insert_internal(key, || value, |_| false, guard) {
697 Ok(entry) => entry,
698 Err(layout) => handle_alloc_error(layout),
699 }
700 }
701
702 /// Fallible version of [`get_or_insert`](Self::get_or_insert): returns an error instead of
703 /// aborting the process when node allocation fails.
704 ///
705 /// On error the skip list is unchanged and both `key` and `value` are dropped.
706 pub fn try_get_or_insert(
707 &self,
708 key: K,
709 value: V,
710 guard: &Guard,
711 ) -> Result<RefEntry<'_, K, V, C, A>, TryReserveError> {
712 self.insert_internal(key, || value, |_| false, guard)
713 .map_err(|_| TryReserveError)
714 }
715
716 /// Finds an entry with the specified key, or inserts a new `key`-`value` pair if none exist,
717 /// where value is calculated with a function.
718 ///
719 /// <b>Note:</b> Another thread may write key value first, leading to the result of this closure
720 /// discarded. If closure is modifying some other state (such as shared counters or shared
721 /// objects), it may lead to <u>undesired behaviour</u> such as counters being changed without
722 /// result of closure inserted
723 pub fn get_or_insert_with<F>(&self, key: K, value: F, guard: &Guard) -> RefEntry<'_, K, V, C, A>
724 where
725 F: FnOnce() -> V,
726 {
727 match self.insert_internal(key, value, |_| false, guard) {
728 Ok(entry) => entry,
729 Err(layout) => handle_alloc_error(layout),
730 }
731 }
732
733 /// Fallible version of [`get_or_insert_with`](Self::get_or_insert_with): returns an error
734 /// instead of aborting the process when node allocation fails.
735 ///
736 /// On error the skip list is unchanged and both `key` and the value built by `value` are
737 /// dropped.
738 pub fn try_get_or_insert_with<F>(
739 &self,
740 key: K,
741 value: F,
742 guard: &Guard,
743 ) -> Result<RefEntry<'_, K, V, C, A>, TryReserveError>
744 where
745 F: FnOnce() -> V,
746 {
747 self.insert_internal(key, value, |_| false, guard)
748 .map_err(|_| TryReserveError)
749 }
750
751 /// Returns an iterator over all entries in the skip list.
752 pub fn iter<'a: 'g, 'g>(&'a self, guard: &'g Guard) -> Iter<'a, 'g, K, V, C, A> {
753 self.check_guard(guard);
754 Iter {
755 parent: self,
756 head: None,
757 tail: None,
758 guard,
759 }
760 }
761
762 /// Returns an iterator over all entries in the skip list.
763 pub fn ref_iter(&self) -> RefIter<'_, K, V, C, A> {
764 RefIter {
765 parent: self,
766 head: None,
767 tail: None,
768 }
769 }
770
771 /// Returns an iterator over a subset of entries in the skip list.
772 pub fn range<'a: 'g, 'g, Q, R>(
773 &'a self,
774 range: R,
775 guard: &'g Guard,
776 ) -> Range<'a, 'g, Q, R, K, V, C, A>
777 where
778 C: Comparator<K, Q>,
779 R: RangeBounds<Q>,
780 Q: ?Sized,
781 {
782 self.check_guard(guard);
783 Range {
784 parent: self,
785 head: None,
786 tail: None,
787 range,
788 guard,
789 _marker: PhantomData,
790 }
791 }
792
793 /// Returns an iterator over a subset of entries in the skip list.
794 #[allow(clippy::needless_lifetimes)]
795 pub fn ref_range<'a, Q, R>(&'a self, range: R) -> RefRange<'a, Q, R, K, V, C, A>
796 where
797 C: Comparator<K, Q>,
798 R: RangeBounds<Q>,
799 Q: ?Sized,
800 {
801 RefRange {
802 parent: self,
803 range,
804 head: None,
805 tail: None,
806 _marker: PhantomData,
807 }
808 }
809
810 /// Generates a random height and returns it.
811 fn random_height(&self) -> usize {
812 // Pseudorandom number generation from "Xorshift RNGs" by George Marsaglia.
813 //
814 // This particular set of operations generates 32-bit integers. See:
815 // https://en.wikipedia.org/wiki/Xorshift#Example_implementation
816 let mut num = self.hot_data.seed.load(Ordering::Relaxed);
817 num ^= num << 13;
818 num ^= num >> 17;
819 num ^= num << 5;
820 self.hot_data.seed.store(num, Ordering::Relaxed);
821
822 let mut height = cmp::min(MAX_HEIGHT, num.trailing_zeros() as usize + 1);
823 unsafe {
824 // Keep decreasing the height while it's much larger than all towers currently in the
825 // skip list.
826 //
827 // Note that we're loading the pointer only to check whether it is null, so it's okay
828 // to use `epoch::unprotected()` in this situation.
829 while height >= 4
830 && self
831 .head
832 .get_level(height - 2)
833 .load(Ordering::Relaxed, epoch::unprotected())
834 .is_null()
835 {
836 height -= 1;
837 }
838 }
839
840 // Track the max height to speed up lookups
841 let mut max_height = self.hot_data.max_height.load(Ordering::Relaxed);
842 while height > max_height {
843 match self.hot_data.max_height.compare_exchange_weak(
844 max_height,
845 height,
846 Ordering::Relaxed,
847 Ordering::Relaxed,
848 ) {
849 Ok(_) => break,
850 Err(h) => max_height = h,
851 }
852 }
853 height
854 }
855
856 /// If we encounter a deleted node while searching, help with the deletion
857 /// by attempting to unlink the node from the list.
858 ///
859 /// If the unlinking is successful then this function returns the next node
860 /// with which the search should continue on the current level.
861 #[cold]
862 unsafe fn help_unlink<'a>(
863 &'a self,
864 pred: &'a Atomic<Node<K, V>>,
865 curr: NodeRef<'a, K, V>,
866 succ: Shared<'a, Node<K, V>>,
867 guard: &'a Guard,
868 ) -> Option<Shared<'a, Node<K, V>>> {
869 // If `succ` is marked, that means `curr` is removed. Let's try
870 // unlinking it from the skip list at this level.
871 match pred.compare_exchange(
872 Shared::from(curr.ptr.as_ptr() as *const Node<K, V>),
873 succ.with_tag(0),
874 Ordering::Release,
875 Ordering::Relaxed,
876 guard,
877 ) {
878 Ok(_) => {
879 unsafe { curr.decrement(&self.alloc, guard) }
880 Some(succ.with_tag(0))
881 }
882 Err(_) => None,
883 }
884 }
885
886 /// Returns the successor of a node.
887 ///
888 /// This will keep searching until a non-deleted node is found. If a deleted
889 /// node is reached then a search is performed using the given key.
890 fn next_node<'a>(
891 &'a self,
892 pred: TowerRef<'a, K, V>,
893 lower_bound: Bound<&K>,
894 guard: &'a Guard,
895 ) -> Option<NodeRef<'a, K, V>> {
896 unsafe {
897 // Load the level 0 successor of the current node.
898 let mut curr = pred.get_level(0).load_consume(guard);
899
900 // If `curr` is marked, that means `pred` is removed and we have to use
901 // a key search.
902 if curr.tag() == 1 {
903 return self.search_bound(lower_bound, false, guard);
904 }
905
906 while let Some(c) = NodeRef::from_shared(curr) {
907 let succ = c.get_level(0).load_consume(guard);
908
909 if succ.tag() == 1 {
910 if let Some(c) = self.help_unlink(pred.get_level(0), c, succ, guard) {
911 // On success, continue searching through the current level.
912 curr = c;
913 continue;
914 } else {
915 // On failure, we cannot do anything reasonable to continue
916 // searching from the current position. Restart the search.
917 return self.search_bound(lower_bound, false, guard);
918 }
919 }
920
921 return Some(c);
922 }
923
924 None
925 }
926 }
927
928 /// Searches for first/last node that is greater/less/equal to a key in the skip list.
929 ///
930 /// If `upper_bound == true`: the last node less than (or equal to) the key.
931 ///
932 /// If `upper_bound == false`: the first node greater than (or equal to) the key.
933 ///
934 /// This is unsafe because the returned nodes are bound to the lifetime of
935 /// the `SkipList`, not the `Guard`.
936 fn search_bound<'a, Q>(
937 &'a self,
938 bound: Bound<&Q>,
939 upper_bound: bool,
940 guard: &'a Guard,
941 ) -> Option<NodeRef<'a, K, V>>
942 where
943 C: Comparator<K, Q>,
944 Q: ?Sized,
945 {
946 unsafe {
947 'search: loop {
948 // The current level we're at.
949 let mut level = self.hot_data.max_height.load(Ordering::Relaxed);
950
951 // Fast loop to skip empty tower levels.
952 while level >= 1
953 && self
954 .head
955 .get_level(level - 1)
956 .load(Ordering::Relaxed, guard)
957 .is_null()
958 {
959 level -= 1;
960 }
961
962 // The current best node
963 let mut result = None;
964
965 // The predecessor node
966 let mut pred = self.head.as_tower();
967
968 while level >= 1 {
969 level -= 1;
970
971 // Two adjacent nodes at the current level.
972 let mut curr = pred.get_level(level).load_consume(guard);
973
974 // If `curr` is marked, that means `pred` is removed and we have to restart the
975 // search.
976 if curr.tag() == 1 {
977 continue 'search;
978 }
979
980 // Iterate through the current level until we reach a node with a key greater
981 // than or equal to `key`.
982 while let Some(c) = NodeRef::from_shared(curr) {
983 let succ = c.get_level(level).load_consume(guard);
984
985 if succ.tag() == 1 {
986 if let Some(c) = self.help_unlink(pred.get_level(level), c, succ, guard)
987 {
988 // On success, continue searching through the current level.
989 curr = c;
990 continue;
991 } else {
992 // On failure, we cannot do anything reasonable to continue
993 // searching from the current position. Restart the search.
994 continue 'search;
995 }
996 }
997
998 // If `curr` contains a key that is greater than (or equal) to `key`, we're
999 // done with this level.
1000 //
1001 // The condition determines whether we should stop the search. For the upper
1002 // bound, we return the last node before the condition became true. For the
1003 // lower bound, we return the first node after the condition became true.
1004 if upper_bound {
1005 if !below_upper_bound(&self.comparator, &bound, &c.key) {
1006 break;
1007 }
1008 result = Some(c);
1009 } else if above_lower_bound(&self.comparator, &bound, &c.key) {
1010 result = Some(c);
1011 break;
1012 }
1013
1014 // Move one step forward.
1015 pred = c.as_tower();
1016 curr = succ;
1017 }
1018 }
1019
1020 return result;
1021 }
1022 }
1023 }
1024
1025 /// Searches for a key in the skip list and returns a list of all adjacent nodes.
1026 fn search_position<'a, Q>(&'a self, key: &Q, guard: &'a Guard) -> Position<'a, K, V>
1027 where
1028 C: Comparator<K, Q>,
1029 Q: ?Sized,
1030 {
1031 unsafe {
1032 'search: loop {
1033 // The result of this search.
1034 let mut result = Position {
1035 found: None,
1036 left: [self.head.as_tower(); MAX_HEIGHT],
1037 right: [Shared::null(); MAX_HEIGHT],
1038 };
1039
1040 // The current level we're at.
1041 let mut level = self.hot_data.max_height.load(Ordering::Relaxed);
1042
1043 // Fast loop to skip empty tower levels.
1044 while level >= 1
1045 && self
1046 .head
1047 .get_level(level - 1)
1048 .load(Ordering::Relaxed, guard)
1049 .is_null()
1050 {
1051 level -= 1;
1052 }
1053
1054 // The predecessor node
1055 let mut pred = self.head.as_tower();
1056
1057 while level >= 1 {
1058 level -= 1;
1059
1060 // Two adjacent nodes at the current level.
1061 let mut curr = pred.get_level(level).load_consume(guard);
1062
1063 // If `curr` is marked, that means `pred` is removed and we have to restart the
1064 // search.
1065 if curr.tag() == 1 {
1066 continue 'search;
1067 }
1068
1069 // Iterate through the current level until we reach a node with a key greater
1070 // than or equal to `key`.
1071 while let Some(c) = NodeRef::from_shared(curr) {
1072 let succ = c.get_level(level).load_consume(guard);
1073
1074 if succ.tag() == 1 {
1075 if let Some(c) = self.help_unlink(pred.get_level(level), c, succ, guard)
1076 {
1077 // On success, continue searching through the current level.
1078 curr = c;
1079 continue;
1080 } else {
1081 // On failure, we cannot do anything reasonable to continue
1082 // searching from the current position. Restart the search.
1083 continue 'search;
1084 }
1085 }
1086
1087 // If `curr` contains a key that is greater than or equal to `key`, we're
1088 // done with this level.
1089 match self.comparator.compare(&c.key, key) {
1090 cmp::Ordering::Greater => break,
1091 cmp::Ordering::Equal => {
1092 result.found = Some(c);
1093 break;
1094 }
1095 cmp::Ordering::Less => {}
1096 }
1097
1098 // Move one step forward.
1099 pred = c.as_tower();
1100 curr = succ;
1101 }
1102
1103 // Store the position at the current level into the result.
1104 result.left[level] = pred;
1105 result.right[level] = curr;
1106 }
1107
1108 return result;
1109 }
1110 }
1111 }
1112
1113 /// Inserts an entry with the specified `key` and `value`.
1114 ///
1115 /// If `replace` is `true`, then any existing entry with this key will first be removed.
1116 ///
1117 /// If allocating the new node fails, returns the layout that could not be allocated.
1118 /// In that case the skip list is unchanged and both `key` and the constructed value
1119 /// are dropped.
1120 fn insert_internal<F, CompareF>(
1121 &self,
1122 key: K,
1123 value: F,
1124 replace: CompareF,
1125 guard: &Guard,
1126 ) -> Result<RefEntry<'_, K, V, C, A>, Layout>
1127 where
1128 C: Comparator<K>,
1129 F: FnOnce() -> V,
1130 CompareF: Fn(&V) -> bool,
1131 {
1132 self.check_guard(guard);
1133
1134 unsafe {
1135 // Rebind the guard to the lifetime of self. This is a bit of a
1136 // hack but it allows us to return references that are not bound to
1137 // the lifetime of the guard.
1138 let guard = &*(guard as *const _);
1139
1140 // First try searching for the key.
1141 // Note that the `Ord` implementation for `K` may panic during the search.
1142 let mut search = self.search_position(&key, guard);
1143 if let Some(r) = search.found {
1144 let replace = replace(&r.value);
1145 if !replace {
1146 // If a node with the key was found and we're not going to replace it, let's
1147 // try returning it as an entry.
1148 if let Some(e) = RefEntry::try_acquire(self, r) {
1149 return Ok(e);
1150 }
1151 }
1152 }
1153
1154 // create value before creating node, so extra allocation doesn't happen if value() function panics
1155 let value = value();
1156 // Create a new node.
1157 let height = self.random_height();
1158 let (node, n) = {
1159 // The reference count is initially two to account for:
1160 // 1. The entry that will be returned.
1161 // 2. The link at the level 0 of the tower.
1162 let n = Node::<K, V>::try_alloc(&self.alloc, height, 2)?;
1163
1164 // Write the key and the value into the node.
1165 ptr::addr_of_mut!((*n).key).write(key);
1166 ptr::addr_of_mut!((*n).value).write(value);
1167
1168 (
1169 Shared::<Node<K, V>>::from(n as *const _),
1170 NodeRef::new(NonNull::new_unchecked(n)),
1171 )
1172 };
1173
1174 // Optimistically increment `len`.
1175 self.hot_data.len.fetch_add(1, Ordering::Relaxed);
1176
1177 loop {
1178 // Set the lowest successor of `n` to `search.right[0]`.
1179 n.get_level(0).store(search.right[0], Ordering::Relaxed);
1180
1181 // Try installing the new node into the skip list (at level 0).
1182 // TODO(Amanieu): can we use release ordering here?
1183 if search.left[0]
1184 .get_level(0)
1185 .compare_exchange(
1186 search.right[0],
1187 node,
1188 Ordering::SeqCst,
1189 Ordering::SeqCst,
1190 guard,
1191 )
1192 .is_ok()
1193 {
1194 // This node has been abandoned
1195 if let Some(r) = search.found {
1196 if r.mark_tower() {
1197 self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
1198 }
1199 }
1200 break;
1201 }
1202
1203 // We failed. Let's search for the key and try again.
1204 {
1205 // Create a guard that destroys the new node in case search panics.
1206 struct ScopeGuard<'a, K, V, A: SkiplistAllocator>(*const Node<K, V>, &'a A);
1207 impl<K, V, A: SkiplistAllocator> Drop for ScopeGuard<'_, K, V, A> {
1208 fn drop(&mut self) {
1209 unsafe { Node::finalize(self.1, self.0 as *mut Node<K, V>) }
1210 }
1211 }
1212 let sg = ScopeGuard(node.as_raw(), &self.alloc);
1213 search = self.search_position(&n.key, guard);
1214 mem::forget(sg);
1215 }
1216
1217 if let Some(r) = search.found {
1218 let replace = replace(&r.value);
1219 if !replace {
1220 // If a node with the key was found and we're not going to replace it,
1221 // let's try returning it as an entry.
1222 if let Some(e) = RefEntry::try_acquire(self, r) {
1223 // Destroy the new node.
1224 Node::finalize(&self.alloc, node.as_raw() as *mut Node<K, V>);
1225 self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
1226
1227 return Ok(e);
1228 }
1229
1230 // If we couldn't increment the reference count, that means someone has
1231 // just now removed the node.
1232 }
1233 }
1234 }
1235
1236 // The new node was successfully installed. Let's create an entry associated with it.
1237 let entry = RefEntry {
1238 parent: self,
1239 node: n,
1240 };
1241
1242 // Build the rest of the tower above level 0.
1243 'build: for level in 1..height {
1244 loop {
1245 // Obtain the predecessor and successor at the current level.
1246 let pred = search.left[level];
1247 let succ = search.right[level];
1248
1249 // Load the current value of the pointer in the tower at this level.
1250 // TODO(Amanieu): can we use relaxed ordering here?
1251 let next = n.get_level(level).load(Ordering::SeqCst, guard);
1252
1253 // If the current pointer is marked, that means another thread is already
1254 // removing the node we've just inserted. In that case, let's just stop
1255 // building the tower.
1256 if next.tag() == 1 {
1257 break 'build;
1258 }
1259
1260 // When searching for `key` and traversing the skip list from the highest level
1261 // to the lowest, it is possible to observe a node with an equal key at higher
1262 // levels and then find it missing at the lower levels if it gets removed
1263 // during traversal. Even worse, it is possible to observe completely different
1264 // nodes with the exact same key at different levels.
1265 //
1266 // Linking the new node to a dead successor with an equal key could create
1267 // subtle corner cases that would require special care. It's much easier to
1268 // simply prohibit linking two nodes with equal keys.
1269 //
1270 // If the successor has the same key as the new node, that means it is marked
1271 // as removed and should be unlinked from the skip list. In that case, let's
1272 // repeat the search to make sure it gets unlinked and try again.
1273 //
1274 // If this comparison or the following search panics, we simply stop building
1275 // the tower without breaking any invariants. Note that building higher levels
1276 // is completely optional. Only the lowest level really matters, and all the
1277 // higher levels are there just to make searching faster.
1278 if succ
1279 .as_ref()
1280 .is_some_and(|s| self.comparator.equivalent(&s.key, &n.key))
1281 {
1282 search = self.search_position(&n.key, guard);
1283 continue;
1284 }
1285
1286 // Change the pointer at the current level from `next` to `succ`. If this CAS
1287 // operation fails, that means another thread has marked the pointer and we
1288 // should stop building the tower.
1289 // TODO(Amanieu): can we use release ordering here?
1290 if n.get_level(level)
1291 .compare_exchange(next, succ, Ordering::SeqCst, Ordering::SeqCst, guard)
1292 .is_err()
1293 {
1294 break 'build;
1295 }
1296
1297 // Increment the reference count. The current value will always be at least 1
1298 // because we are holding `entry`.
1299 n.refs_and_height
1300 .fetch_add(1 << HEIGHT_BITS, Ordering::Relaxed);
1301
1302 // Try installing the new node at the current level.
1303 // TODO(Amanieu): can we use release ordering here?
1304 if pred
1305 .get_level(level)
1306 .compare_exchange(succ, node, Ordering::SeqCst, Ordering::SeqCst, guard)
1307 .is_ok()
1308 {
1309 // Success! Continue on the next level.
1310 break;
1311 }
1312
1313 // Installation failed. Decrement the reference count.
1314 n.refs_and_height
1315 .fetch_sub(1 << HEIGHT_BITS, Ordering::Relaxed);
1316
1317 // We don't have the most up-to-date search results. Repeat the search.
1318 //
1319 // If this search panics, we simply stop building the tower without breaking
1320 // any invariants. Note that building higher levels is completely optional.
1321 // Only the lowest level really matters, and all the higher levels are there
1322 // just to make searching faster.
1323 search = self.search_position(&n.key, guard);
1324 }
1325 }
1326
1327 // If any pointer in the tower is marked, that means our node is in the process of
1328 // removal or already removed. It is possible that another thread (either partially or
1329 // completely) removed the new node while we were building the tower, and just after
1330 // that we installed the new node at one of the higher levels. In order to undo that
1331 // installation, we must repeat the search, which will unlink the new node at that
1332 // level.
1333 // TODO(Amanieu): can we use relaxed ordering here?
1334 if n.get_level(height - 1).load(Ordering::SeqCst, guard).tag() == 1 {
1335 self.search_bound(Bound::Included(&n.key), false, guard);
1336 }
1337
1338 // Finally, return the new entry.
1339 Ok(entry)
1340 }
1341 }
1342}
1343
1344impl<K, V, C, A: SkiplistAllocator> SkipList<K, V, C, A>
1345where
1346 C: Comparator<K>,
1347 K: Send + 'static,
1348 V: Send + 'static,
1349{
1350 /// Inserts a `key`-`value` pair into the skip list and returns the new entry.
1351 ///
1352 /// If there is an existing entry with this key, it will be removed before inserting the new
1353 /// one.
1354 pub fn insert(&self, key: K, value: V, guard: &Guard) -> RefEntry<'_, K, V, C, A> {
1355 match self.insert_internal(key, || value, |_| true, guard) {
1356 Ok(entry) => entry,
1357 Err(layout) => handle_alloc_error(layout),
1358 }
1359 }
1360
1361 /// Fallible version of [`insert`](Self::insert): returns an error instead of aborting the
1362 /// process when node allocation fails.
1363 ///
1364 /// On error the skip list is unchanged and both `key` and `value` are dropped.
1365 pub fn try_insert(
1366 &self,
1367 key: K,
1368 value: V,
1369 guard: &Guard,
1370 ) -> Result<RefEntry<'_, K, V, C, A>, TryReserveError> {
1371 self.insert_internal(key, || value, |_| true, guard)
1372 .map_err(|_| TryReserveError)
1373 }
1374
1375 /// Inserts a `key`-`value` pair into the skip list and returns the new entry.
1376 ///
1377 /// If there is an existing entry with this key and compare(entry.value) returns true,
1378 /// it will be removed before inserting the new one.
1379 /// The closure will not be called if the key is not present.
1380 pub fn compare_insert<F>(
1381 &self,
1382 key: K,
1383 value: V,
1384 compare_fn: F,
1385 guard: &Guard,
1386 ) -> RefEntry<'_, K, V, C, A>
1387 where
1388 F: Fn(&V) -> bool,
1389 {
1390 match self.insert_internal(key, || value, compare_fn, guard) {
1391 Ok(entry) => entry,
1392 Err(layout) => handle_alloc_error(layout),
1393 }
1394 }
1395
1396 /// Fallible version of [`compare_insert`](Self::compare_insert): returns an error instead of
1397 /// aborting the process when node allocation fails.
1398 ///
1399 /// On error the skip list is unchanged and both `key` and `value` are dropped.
1400 pub fn try_compare_insert<F>(
1401 &self,
1402 key: K,
1403 value: V,
1404 compare_fn: F,
1405 guard: &Guard,
1406 ) -> Result<RefEntry<'_, K, V, C, A>, TryReserveError>
1407 where
1408 F: Fn(&V) -> bool,
1409 {
1410 self.insert_internal(key, || value, compare_fn, guard)
1411 .map_err(|_| TryReserveError)
1412 }
1413
1414 /// Removes an entry with the specified `key` from the map and returns it.
1415 pub fn remove<Q>(&self, key: &Q, guard: &Guard) -> Option<RefEntry<'_, K, V, C, A>>
1416 where
1417 C: Comparator<K, Q>,
1418 Q: ?Sized,
1419 {
1420 self.check_guard(guard);
1421
1422 unsafe {
1423 // Rebind the guard to the lifetime of self. This is a bit of a
1424 // hack but it allows us to return references that are not bound to
1425 // the lifetime of the guard.
1426 let guard = &*(guard as *const _);
1427
1428 loop {
1429 // Try searching for the key.
1430 let search = self.search_position(key, guard);
1431
1432 let n = search.found?;
1433
1434 // First try incrementing the reference count because we have to return the node as
1435 // an entry. If this fails, repeat the search.
1436 let entry = match RefEntry::try_acquire(self, n) {
1437 Some(e) => e,
1438 None => continue,
1439 };
1440
1441 // Try removing the node by marking its tower.
1442 if n.mark_tower() {
1443 // Success! Decrement `len`.
1444 self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
1445
1446 // Unlink the node at each level of the skip list. We could do this by simply
1447 // repeating the search, but it's usually faster to unlink it manually using
1448 // the `left` and `right` lists.
1449 for level in (0..n.height()).rev() {
1450 // TODO(Amanieu): can we use relaxed ordering here?
1451 let succ = n.get_level(level).load(Ordering::SeqCst, guard).with_tag(0);
1452
1453 // Try linking the predecessor and successor at this level.
1454 // TODO(Amanieu): can we use release ordering here?
1455 if search.left[level]
1456 .get_level(level)
1457 .compare_exchange(
1458 Shared::from(n.ptr.as_ptr() as *const Node<K, V>),
1459 succ,
1460 Ordering::SeqCst,
1461 Ordering::SeqCst,
1462 guard,
1463 )
1464 .is_ok()
1465 {
1466 // Success! Decrement the reference count.
1467 n.decrement(&self.alloc, guard);
1468 } else {
1469 // Failed! Just repeat the search to completely unlink the node.
1470 self.search_bound(Bound::Included(key), false, guard);
1471 break;
1472 }
1473 }
1474 return Some(entry);
1475 } else {
1476 // The node has already been marked.
1477 n.decrement(&self.alloc, guard);
1478 return None;
1479 }
1480 }
1481 }
1482 }
1483
1484 /// Removes an entry from the front of the skip list.
1485 pub fn pop_front(&self, guard: &Guard) -> Option<RefEntry<'_, K, V, C, A>> {
1486 self.check_guard(guard);
1487 loop {
1488 let e = self.front(guard)?;
1489 if let Some(e) = e.pin() {
1490 if e.remove(guard) {
1491 return Some(e);
1492 } else {
1493 e.release(guard);
1494 }
1495 }
1496 }
1497 }
1498
1499 /// Removes an entry from the back of the skip list.
1500 pub fn pop_back(&self, guard: &Guard) -> Option<RefEntry<'_, K, V, C, A>> {
1501 self.check_guard(guard);
1502 loop {
1503 let e = self.back(guard)?;
1504 if let Some(e) = e.pin() {
1505 if e.remove(guard) {
1506 return Some(e);
1507 } else {
1508 e.release(guard);
1509 }
1510 }
1511 }
1512 }
1513
1514 /// Iterates over the map and removes every entry.
1515 pub fn clear(&self, guard: &mut Guard) {
1516 self.check_guard(guard);
1517
1518 /// Number of steps after which we repin the current thread and unlink removed nodes.
1519 const BATCH_SIZE: usize = 100;
1520
1521 loop {
1522 {
1523 // Search for the first entry in order to unlink all the preceding entries
1524 // we have removed.
1525 //
1526 // By unlinking nodes in batches we make sure that the final search doesn't
1527 // unlink all nodes at once, which could keep the current thread pinned for a
1528 // long time.
1529 let mut entry = self.lower_bound::<K>(Bound::Unbounded, guard);
1530
1531 for _ in 0..BATCH_SIZE {
1532 // Stop if we have reached the end of the list.
1533 let e = match entry {
1534 None => return,
1535 Some(e) => e,
1536 };
1537
1538 // Before removing the current entry, first obtain the following one.
1539 let next = e.next();
1540
1541 // Try removing the current entry.
1542 if e.node.mark_tower() {
1543 // Success! Decrement `len`.
1544 self.hot_data.len.fetch_sub(1, Ordering::Relaxed);
1545 }
1546
1547 entry = next;
1548 }
1549 }
1550
1551 // Repin the current thread because we don't want to keep it pinned in the same
1552 // epoch for a too long time.
1553 guard.repin();
1554 }
1555 }
1556}
1557
1558impl<K, V, C, A: SkiplistAllocator> Drop for SkipList<K, V, C, A> {
1559 fn drop(&mut self) {
1560 unsafe {
1561 let mut node = NodeRef::from_shared(
1562 self.head
1563 .get_level(0)
1564 .load(Ordering::Relaxed, epoch::unprotected()),
1565 );
1566
1567 // Iterate through the whole skip list and destroy every node.
1568 while let Some(n) = node {
1569 // Unprotected loads are okay because this function is the only one currently using
1570 // the skip list.
1571 let next = NodeRef::from_shared(
1572 n.get_level(0).load(Ordering::Relaxed, epoch::unprotected()),
1573 );
1574
1575 // Deallocate every node.
1576 Node::finalize(&self.alloc, n.ptr.as_ptr());
1577
1578 node = next;
1579 }
1580 }
1581 }
1582}
1583
1584impl<K, V, C, A: SkiplistAllocator> fmt::Debug for SkipList<K, V, C, A>
1585where
1586 K: fmt::Debug,
1587 V: fmt::Debug,
1588{
1589 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1590 f.pad("SkipList { .. }")
1591 }
1592}
1593
1594impl<K, V, C, A: SkiplistAllocator> IntoIterator for SkipList<K, V, C, A> {
1595 type Item = (K, V);
1596 type IntoIter = IntoIter<K, V, A>;
1597
1598 fn into_iter(self) -> Self::IntoIter {
1599 unsafe {
1600 // Clone the allocator before nulling the head: if `clone` panicked after the
1601 // nulling, `SkipList::drop` would walk an empty list and leak every node.
1602 let alloc = self.alloc.clone();
1603
1604 // Load the front node.
1605 //
1606 // Unprotected loads are okay because this function is the only one currently using
1607 // the skip list.
1608 let front = self
1609 .head
1610 .get_level(0)
1611 .load(Ordering::Relaxed, epoch::unprotected())
1612 .as_raw();
1613
1614 // Clear the skip list by setting all pointers in head to null.
1615 for level in 0..MAX_HEIGHT {
1616 self.head
1617 .get_level(level)
1618 .store(Shared::null(), Ordering::Relaxed);
1619 }
1620
1621 IntoIter {
1622 node: front as *mut Node<K, V>,
1623 alloc,
1624 }
1625 }
1626 }
1627}
1628
1629/// An entry in a skip list, protected by a `Guard`.
1630///
1631/// The lifetimes of the key and value are the same as that of the `Guard`
1632/// used when creating the `Entry` (`'g`). This lifetime is also constrained to
1633/// not outlive the `SkipList`.
1634pub struct Entry<'a: 'g, 'g, K, V, C = BasicComparator, A: SkiplistAllocator = TursoAllocator> {
1635 parent: &'a SkipList<K, V, C, A>,
1636 node: NodeRef<'g, K, V>,
1637 guard: &'g Guard,
1638}
1639
1640impl<'a: 'g, 'g, K: 'a, V: 'a, C, A: SkiplistAllocator> Entry<'a, 'g, K, V, C, A> {
1641 /// Returns `true` if the entry is removed from the skip list.
1642 pub fn is_removed(&self) -> bool {
1643 self.node.is_removed()
1644 }
1645
1646 /// Returns a reference to the key.
1647 pub fn key(&self) -> &'g K {
1648 &self.node.as_ref().key
1649 }
1650
1651 /// Returns a reference to the value.
1652 pub fn value(&self) -> &'g V {
1653 &self.node.as_ref().value
1654 }
1655
1656 /// Returns a reference to the parent `SkipList`
1657 pub fn skiplist(&self) -> &'a SkipList<K, V, C, A> {
1658 self.parent
1659 }
1660
1661 /// Attempts to pin the entry with a reference count, ensuring that it
1662 /// remains accessible even after the `Guard` is dropped.
1663 ///
1664 /// This method may return `None` if the reference count is already 0 and
1665 /// the node has been queued for deletion.
1666 pub fn pin(&self) -> Option<RefEntry<'a, K, V, C, A>> {
1667 unsafe { RefEntry::try_acquire(self.parent, self.node) }
1668 }
1669}
1670
1671impl<K, V, C, A: SkiplistAllocator> Entry<'_, '_, K, V, C, A>
1672where
1673 C: Comparator<K>,
1674 K: Send + 'static,
1675 V: Send + 'static,
1676{
1677 /// Removes the entry from the skip list.
1678 ///
1679 /// Returns `true` if this call removed the entry and `false` if it was already removed.
1680 pub fn remove(&self) -> bool {
1681 // Try marking the tower.
1682 if self.node.mark_tower() {
1683 // Success - the entry is removed. Now decrement `len`.
1684 self.parent.hot_data.len.fetch_sub(1, Ordering::Relaxed);
1685
1686 // Search for the key to unlink the node from the skip list.
1687 self.parent
1688 .search_bound(Bound::Included(&self.node.key), false, self.guard);
1689
1690 true
1691 } else {
1692 false
1693 }
1694 }
1695}
1696
1697impl<K, V, C, A: SkiplistAllocator> Clone for Entry<'_, '_, K, V, C, A> {
1698 fn clone(&self) -> Self {
1699 Self {
1700 parent: self.parent,
1701 node: self.node,
1702 guard: self.guard,
1703 }
1704 }
1705}
1706
1707impl<K, V, C, A: SkiplistAllocator> fmt::Debug for Entry<'_, '_, K, V, C, A>
1708where
1709 K: fmt::Debug,
1710 V: fmt::Debug,
1711{
1712 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1713 f.debug_tuple("Entry")
1714 .field(self.key())
1715 .field(self.value())
1716 .finish()
1717 }
1718}
1719
1720impl<K, V, C, A: SkiplistAllocator> Entry<'_, '_, K, V, C, A>
1721where
1722 C: Comparator<K>,
1723{
1724 /// Moves to the next entry in the skip list.
1725 pub fn move_next(&mut self) -> bool {
1726 match self.next() {
1727 None => false,
1728 Some(n) => {
1729 *self = n;
1730 true
1731 }
1732 }
1733 }
1734
1735 /// Returns the next entry in the skip list.
1736 pub fn next(&self) -> Option<Self> {
1737 let n = self.parent.next_node(
1738 self.node.as_tower(),
1739 Bound::Excluded(&self.node.key),
1740 self.guard,
1741 )?;
1742 Some(Entry {
1743 parent: self.parent,
1744 node: n,
1745 guard: self.guard,
1746 })
1747 }
1748
1749 /// Moves to the previous entry in the skip list.
1750 pub fn move_prev(&mut self) -> bool {
1751 match self.prev() {
1752 None => false,
1753 Some(n) => {
1754 *self = n;
1755 true
1756 }
1757 }
1758 }
1759
1760 /// Returns the previous entry in the skip list.
1761 pub fn prev(&self) -> Option<Self> {
1762 let n = self
1763 .parent
1764 .search_bound(Bound::Excluded(&self.node.key), true, self.guard)?;
1765 Some(Entry {
1766 parent: self.parent,
1767 node: n,
1768 guard: self.guard,
1769 })
1770 }
1771}
1772
1773/// A reference-counted entry in a skip list.
1774///
1775/// You *must* call `release` to free this type, otherwise the node will be
1776/// leaked. This is because releasing the entry requires a `Guard`.
1777pub struct RefEntry<'a, K, V, C = BasicComparator, A: SkiplistAllocator = TursoAllocator> {
1778 parent: &'a SkipList<K, V, C, A>,
1779 node: NodeRef<'a, K, V>,
1780}
1781
1782impl<'a, K: 'a, V: 'a, C: 'a, A: SkiplistAllocator> RefEntry<'a, K, V, C, A> {
1783 /// Returns `true` if the entry is removed from the skip list.
1784 pub fn is_removed(&self) -> bool {
1785 self.node.is_removed()
1786 }
1787
1788 /// Returns a reference to the key.
1789 pub fn key(&self) -> &'a K {
1790 &self.node.as_ref().key
1791 }
1792
1793 /// Returns a reference to the value.
1794 pub fn value(&self) -> &'a V {
1795 &self.node.as_ref().value
1796 }
1797
1798 /// Returns a reference to the parent `SkipList`
1799 pub fn skiplist(&self) -> &'a SkipList<K, V, C, A> {
1800 self.parent
1801 }
1802
1803 /// Releases the reference on the entry.
1804 pub fn release(self, guard: &Guard) {
1805 self.parent.check_guard(guard);
1806 unsafe { self.node.decrement(&self.parent.alloc, guard) }
1807 }
1808
1809 /// Releases the reference of the entry, pinning the thread only when
1810 /// the reference count of the node becomes 0.
1811 pub fn release_with_pin<F>(self, pin: F)
1812 where
1813 F: FnOnce() -> Guard,
1814 {
1815 unsafe { self.node.decrement_with_pin(self.parent, pin) }
1816 }
1817
1818 /// Tries to create a new `RefEntry` by incrementing the reference count of
1819 /// a node.
1820 unsafe fn try_acquire(
1821 parent: &'a SkipList<K, V, C, A>,
1822 node: NodeRef<'_, K, V>,
1823 ) -> Option<Self> {
1824 if unsafe { node.try_increment() } {
1825 Some(RefEntry {
1826 parent,
1827
1828 // We re-bind the lifetime of the node here to that of the skip
1829 // list since we now hold a reference to it.
1830 node: unsafe { NodeRef::new(node.ptr) },
1831 })
1832 } else {
1833 None
1834 }
1835 }
1836}
1837
1838impl<K, V, C, A: SkiplistAllocator> RefEntry<'_, K, V, C, A>
1839where
1840 C: Comparator<K>,
1841 K: Send + 'static,
1842 V: Send + 'static,
1843{
1844 /// Removes the entry from the skip list.
1845 ///
1846 /// Returns `true` if this call removed the entry and `false` if it was already removed.
1847 pub fn remove(&self, guard: &Guard) -> bool {
1848 self.parent.check_guard(guard);
1849
1850 // Try marking the tower.
1851 if self.node.mark_tower() {
1852 // Success - the entry is removed. Now decrement `len`.
1853 self.parent.hot_data.len.fetch_sub(1, Ordering::Relaxed);
1854
1855 // Search for the key to unlink the node from the skip list.
1856 self.parent
1857 .search_bound(Bound::Included(&self.node.key), false, guard);
1858
1859 true
1860 } else {
1861 false
1862 }
1863 }
1864}
1865
1866impl<K, V, C, A: SkiplistAllocator> Clone for RefEntry<'_, K, V, C, A> {
1867 fn clone(&self) -> Self {
1868 unsafe {
1869 // Incrementing will always succeed since we're already holding a reference to the node.
1870 Node::try_increment(&*self.node);
1871 }
1872 Self {
1873 parent: self.parent,
1874 node: self.node,
1875 }
1876 }
1877}
1878
1879impl<K, V, C, A: SkiplistAllocator> fmt::Debug for RefEntry<'_, K, V, C, A>
1880where
1881 K: fmt::Debug,
1882 V: fmt::Debug,
1883{
1884 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1885 f.debug_tuple("RefEntry")
1886 .field(self.key())
1887 .field(self.value())
1888 .finish()
1889 }
1890}
1891
1892impl<K, V, C, A: SkiplistAllocator> RefEntry<'_, K, V, C, A>
1893where
1894 C: Comparator<K>,
1895{
1896 /// Moves to the next entry in the skip list.
1897 pub fn move_next(&mut self, guard: &Guard) -> bool {
1898 match self.next(guard) {
1899 None => false,
1900 Some(e) => {
1901 mem::replace(self, e).release(guard);
1902 true
1903 }
1904 }
1905 }
1906
1907 /// Returns the next entry in the skip list.
1908 pub fn next(&self, guard: &Guard) -> Option<Self> {
1909 self.parent.check_guard(guard);
1910 unsafe {
1911 let mut n = self.node;
1912 loop {
1913 n = self
1914 .parent
1915 .next_node(n.as_tower(), Bound::Excluded(&n.key), guard)?;
1916 if let Some(e) = RefEntry::try_acquire(self.parent, n) {
1917 return Some(e);
1918 }
1919 }
1920 }
1921 }
1922
1923 /// Moves to the previous entry in the skip list.
1924 pub fn move_prev(&mut self, guard: &Guard) -> bool {
1925 match self.prev(guard) {
1926 None => false,
1927 Some(e) => {
1928 mem::replace(self, e).release(guard);
1929 true
1930 }
1931 }
1932 }
1933
1934 /// Returns the previous entry in the skip list.
1935 pub fn prev(&self, guard: &Guard) -> Option<Self> {
1936 self.parent.check_guard(guard);
1937 unsafe {
1938 let mut n = self.node;
1939 loop {
1940 n = self
1941 .parent
1942 .search_bound(Bound::Excluded(&n.key), true, guard)?;
1943 if let Some(e) = RefEntry::try_acquire(self.parent, n) {
1944 return Some(e);
1945 }
1946 }
1947 }
1948 }
1949}
1950
1951/// An iterator over the entries of a `SkipList`.
1952pub struct Iter<'a: 'g, 'g, K, V, C = BasicComparator, A: SkiplistAllocator = TursoAllocator> {
1953 parent: &'a SkipList<K, V, C, A>,
1954 head: Option<NodeRef<'g, K, V>>,
1955 tail: Option<NodeRef<'g, K, V>>,
1956 guard: &'g Guard,
1957}
1958
1959impl<'a: 'g, 'g, K: 'a, V: 'a, C, A: SkiplistAllocator> Iterator for Iter<'a, 'g, K, V, C, A>
1960where
1961 C: Comparator<K>,
1962{
1963 type Item = Entry<'a, 'g, K, V, C, A>;
1964
1965 fn next(&mut self) -> Option<Self::Item> {
1966 self.head = match self.head {
1967 Some(n) => self
1968 .parent
1969 .next_node(n.as_tower(), Bound::Excluded(&n.key), self.guard),
1970 None => {
1971 self.parent
1972 .next_node(self.parent.head.as_tower(), Bound::Unbounded, self.guard)
1973 }
1974 };
1975 if let (Some(h), Some(t)) = (self.head, self.tail) {
1976 if self.parent.comparator.compare(&h.key, &t.key).is_ge() {
1977 self.head = None;
1978 self.tail = None;
1979 }
1980 }
1981 self.head.map(|n| Entry {
1982 parent: self.parent,
1983 node: n,
1984 guard: self.guard,
1985 })
1986 }
1987}
1988
1989impl<'a: 'g, 'g, K: 'a, V: 'a, C, A: SkiplistAllocator> DoubleEndedIterator
1990 for Iter<'a, 'g, K, V, C, A>
1991where
1992 C: Comparator<K>,
1993{
1994 fn next_back(&mut self) -> Option<Self::Item> {
1995 self.tail = match self.tail {
1996 Some(n) => self
1997 .parent
1998 .search_bound(Bound::Excluded(&n.key), true, self.guard),
1999 None => self
2000 .parent
2001 .search_bound::<K>(Bound::Unbounded, true, self.guard),
2002 };
2003 if let (Some(h), Some(t)) = (self.head, self.tail) {
2004 if self.parent.comparator.compare(&h.key, &t.key).is_ge() {
2005 self.head = None;
2006 self.tail = None;
2007 }
2008 }
2009 self.tail.map(|n| Entry {
2010 parent: self.parent,
2011 node: n,
2012 guard: self.guard,
2013 })
2014 }
2015}
2016
2017impl<K, V, C, A: SkiplistAllocator> fmt::Debug for Iter<'_, '_, K, V, C, A>
2018where
2019 K: fmt::Debug,
2020 V: fmt::Debug,
2021{
2022 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2023 f.debug_struct("Iter")
2024 .field("head", &self.head.as_deref().map(|n| (&n.key, &n.value)))
2025 .field("tail", &self.tail.as_deref().map(|n| (&n.key, &n.value)))
2026 .finish()
2027 }
2028}
2029
2030/// An iterator over reference-counted entries of a `SkipList`.
2031pub struct RefIter<'a, K, V, C = BasicComparator, A: SkiplistAllocator = TursoAllocator> {
2032 parent: &'a SkipList<K, V, C, A>,
2033 head: Option<RefEntry<'a, K, V, C, A>>,
2034 tail: Option<RefEntry<'a, K, V, C, A>>,
2035}
2036
2037impl<K, V, C, A: SkiplistAllocator> fmt::Debug for RefIter<'_, K, V, C, A>
2038where
2039 K: fmt::Debug,
2040 V: fmt::Debug,
2041{
2042 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2043 let mut d = f.debug_struct("RefIter");
2044 match &self.head {
2045 None => d.field("head", &None::<(&K, &V)>),
2046 Some(e) => d.field("head", &(e.key(), e.value())),
2047 };
2048 match &self.tail {
2049 None => d.field("tail", &None::<(&K, &V)>),
2050 Some(e) => d.field("tail", &(e.key(), e.value())),
2051 };
2052 d.finish()
2053 }
2054}
2055
2056impl<'a, K: 'a, V: 'a, C, A: SkiplistAllocator> RefIter<'a, K, V, C, A>
2057where
2058 C: Comparator<K>,
2059{
2060 /// Advances the iterator and returns the next value.
2061 pub fn next(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V, C, A>> {
2062 self.parent.check_guard(guard);
2063 let next_head = match &self.head {
2064 Some(e) => e.next(guard),
2065 None => try_pin_loop(|| self.parent.front(guard)),
2066 };
2067 match (&next_head, &self.tail) {
2068 // The next key is larger than the latest tail key we observed with this iterator.
2069 (Some(ref next), Some(t))
2070 if self.parent.comparator.compare(next.key(), t.key()).is_ge() =>
2071 {
2072 unsafe {
2073 next.node.decrement(&self.parent.alloc, guard);
2074 }
2075 None
2076 }
2077 (Some(_), _) => {
2078 if let Some(e) = mem::replace(&mut self.head, next_head.clone()) {
2079 unsafe {
2080 e.node.decrement(&self.parent.alloc, guard);
2081 }
2082 }
2083 next_head
2084 }
2085 (None, _) => None,
2086 }
2087 }
2088
2089 /// Removes and returns an element from the end of the iterator.
2090 pub fn next_back(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V, C, A>> {
2091 self.parent.check_guard(guard);
2092 let next_tail = match &self.tail {
2093 Some(e) => e.prev(guard),
2094 None => try_pin_loop(|| self.parent.back(guard)),
2095 };
2096 match (&self.head, &next_tail) {
2097 // The prev key is smaller than the latest head key we observed with this iterator.
2098 (Some(h), Some(next))
2099 if self.parent.comparator.compare(h.key(), next.key()).is_ge() =>
2100 {
2101 unsafe {
2102 next.node.decrement(&self.parent.alloc, guard);
2103 }
2104 None
2105 }
2106 (_, Some(_)) => {
2107 if let Some(e) = mem::replace(&mut self.tail, next_tail.clone()) {
2108 unsafe {
2109 e.node.decrement(&self.parent.alloc, guard);
2110 }
2111 }
2112 next_tail
2113 }
2114 (_, None) => None,
2115 }
2116 }
2117}
2118
2119impl<'a, K: 'a, V: 'a, C, A: SkiplistAllocator> RefIter<'a, K, V, C, A> {
2120 /// Decrements the reference count of `RefEntry` owned by the iterator.
2121 pub fn drop_impl(&mut self, guard: &Guard) {
2122 self.parent.check_guard(guard);
2123 if let Some(e) = self.head.take() {
2124 unsafe { e.node.decrement(&self.parent.alloc, guard) };
2125 }
2126 if let Some(e) = self.tail.take() {
2127 unsafe { e.node.decrement(&self.parent.alloc, guard) };
2128 }
2129 }
2130}
2131
2132/// An iterator over a subset of entries of a `SkipList`.
2133pub struct Range<'a: 'g, 'g, Q, R, K, V, C = BasicComparator, A: SkiplistAllocator = TursoAllocator>
2134where
2135 C: Comparator<K> + Comparator<K, Q>,
2136 R: RangeBounds<Q>,
2137 Q: ?Sized,
2138{
2139 parent: &'a SkipList<K, V, C, A>,
2140 head: Option<NodeRef<'g, K, V>>,
2141 tail: Option<NodeRef<'g, K, V>>,
2142 range: R,
2143 guard: &'g Guard,
2144 _marker: PhantomData<fn() -> Q>, // covariant over `Q`
2145}
2146
2147impl<'a: 'g, 'g, Q, R, K: 'a, V: 'a, C, A: SkiplistAllocator> Iterator
2148 for Range<'a, 'g, Q, R, K, V, C, A>
2149where
2150 C: Comparator<K> + Comparator<K, Q>,
2151 R: RangeBounds<Q>,
2152 Q: ?Sized,
2153{
2154 type Item = Entry<'a, 'g, K, V, C, A>;
2155
2156 fn next(&mut self) -> Option<Self::Item> {
2157 self.head = match self.head {
2158 Some(n) => self
2159 .parent
2160 .next_node(n.as_tower(), Bound::Excluded(&n.key), self.guard),
2161 None => self
2162 .parent
2163 .search_bound(self.range.start_bound(), false, self.guard),
2164 };
2165 if let Some(h) = self.head {
2166 match self.tail {
2167 Some(t) => {
2168 let bound = Bound::Excluded(&t.as_ref().key);
2169 if !below_upper_bound(&self.parent.comparator, &bound, &h.key) {
2170 self.head = None;
2171 self.tail = None;
2172 }
2173 }
2174 None => {
2175 let bound = self.range.end_bound();
2176 if !below_upper_bound(&self.parent.comparator, &bound, &h.key) {
2177 self.head = None;
2178 self.tail = None;
2179 }
2180 }
2181 };
2182 }
2183 self.head.map(|n| Entry {
2184 parent: self.parent,
2185 node: n,
2186 guard: self.guard,
2187 })
2188 }
2189}
2190
2191impl<'a: 'g, 'g, Q, R, K: 'a, V: 'a, C, A: SkiplistAllocator> DoubleEndedIterator
2192 for Range<'a, 'g, Q, R, K, V, C, A>
2193where
2194 C: Comparator<K> + Comparator<K, Q>,
2195 R: RangeBounds<Q>,
2196 Q: ?Sized,
2197{
2198 fn next_back(&mut self) -> Option<Self::Item> {
2199 self.tail = match self.tail {
2200 Some(n) => self
2201 .parent
2202 .search_bound::<K>(Bound::Excluded(&n.key), true, self.guard),
2203 None => self
2204 .parent
2205 .search_bound(self.range.end_bound(), true, self.guard),
2206 };
2207 if let Some(t) = self.tail {
2208 match self.head {
2209 Some(h) => {
2210 let bound = Bound::Excluded(&h.as_ref().key);
2211 if !above_lower_bound(&self.parent.comparator, &bound, &t.key) {
2212 self.head = None;
2213 self.tail = None;
2214 }
2215 }
2216 None => {
2217 let bound = self.range.start_bound();
2218 if !above_lower_bound(&self.parent.comparator, &bound, &t.key) {
2219 self.head = None;
2220 self.tail = None;
2221 }
2222 }
2223 };
2224 }
2225 self.tail.map(|n| Entry {
2226 parent: self.parent,
2227 node: n,
2228 guard: self.guard,
2229 })
2230 }
2231}
2232
2233impl<Q, R, K, V, C, A: SkiplistAllocator> fmt::Debug for Range<'_, '_, Q, R, K, V, C, A>
2234where
2235 C: Comparator<K> + Comparator<K, Q>,
2236 K: fmt::Debug,
2237 V: fmt::Debug,
2238 R: RangeBounds<Q> + fmt::Debug,
2239 Q: ?Sized,
2240{
2241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2242 f.debug_struct("Range")
2243 .field("range", &self.range)
2244 .field("head", &self.head)
2245 .field("tail", &self.tail)
2246 .finish()
2247 }
2248}
2249
2250/// An iterator over reference-counted subset of entries of a `SkipList`.
2251pub struct RefRange<'a, Q, R, K, V, C = BasicComparator, A: SkiplistAllocator = TursoAllocator>
2252where
2253 C: Comparator<K> + Comparator<K, Q>,
2254 R: RangeBounds<Q>,
2255 Q: ?Sized,
2256{
2257 parent: &'a SkipList<K, V, C, A>,
2258 pub(crate) head: Option<RefEntry<'a, K, V, C, A>>,
2259 pub(crate) tail: Option<RefEntry<'a, K, V, C, A>>,
2260 pub(crate) range: R,
2261 _marker: PhantomData<fn() -> Q>, // covariant over `Q`
2262}
2263
2264unsafe impl<Q, R, K, V, C, A: SkiplistAllocator> Send for RefRange<'_, Q, R, K, V, C, A>
2265where
2266 C: Comparator<K> + Comparator<K, Q>,
2267 R: RangeBounds<Q>,
2268 Q: ?Sized,
2269{
2270}
2271
2272unsafe impl<Q, R, K, V, C, A: SkiplistAllocator> Sync for RefRange<'_, Q, R, K, V, C, A>
2273where
2274 C: Comparator<K> + Comparator<K, Q>,
2275 R: RangeBounds<Q>,
2276 Q: ?Sized,
2277{
2278}
2279
2280impl<Q, R, K, V, C, A: SkiplistAllocator> fmt::Debug for RefRange<'_, Q, R, K, V, C, A>
2281where
2282 C: Comparator<K> + Comparator<K, Q>,
2283 K: fmt::Debug,
2284 V: fmt::Debug,
2285 R: RangeBounds<Q> + fmt::Debug,
2286 Q: ?Sized,
2287{
2288 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2289 f.debug_struct("RefRange")
2290 .field("range", &self.range)
2291 .field("head", &self.head)
2292 .field("tail", &self.tail)
2293 .finish()
2294 }
2295}
2296
2297impl<'a, Q, R, K: 'a, V: 'a, C, A: SkiplistAllocator> RefRange<'a, Q, R, K, V, C, A>
2298where
2299 C: Comparator<K> + Comparator<K, Q>,
2300 R: RangeBounds<Q>,
2301 Q: ?Sized,
2302{
2303 /// Advances the iterator and returns the next value.
2304 pub fn next(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V, C, A>> {
2305 self.parent.check_guard(guard);
2306 let next_head = match self.head {
2307 Some(ref e) => e.next(guard),
2308 None => try_pin_loop(|| self.parent.lower_bound(self.range.start_bound(), guard)),
2309 };
2310
2311 if let Some(ref h) = next_head {
2312 match self.tail {
2313 Some(ref t) => {
2314 let bound = Bound::Excluded(t.key());
2315 if below_upper_bound(&self.parent.comparator, &bound, h.key()) {
2316 if let Some(e) = mem::replace(&mut self.head, next_head.clone()) {
2317 unsafe {
2318 e.node.decrement(&self.parent.alloc, guard);
2319 }
2320 }
2321 next_head
2322 } else {
2323 unsafe {
2324 h.node.decrement(&self.parent.alloc, guard);
2325 }
2326 None
2327 }
2328 }
2329 None => {
2330 let bound = self.range.end_bound();
2331 if below_upper_bound(&self.parent.comparator, &bound, h.key()) {
2332 if let Some(e) = mem::replace(&mut self.head, next_head.clone()) {
2333 unsafe {
2334 e.node.decrement(&self.parent.alloc, guard);
2335 }
2336 }
2337 next_head
2338 } else {
2339 unsafe {
2340 h.node.decrement(&self.parent.alloc, guard);
2341 }
2342 None
2343 }
2344 }
2345 }
2346 } else {
2347 None
2348 }
2349 }
2350
2351 /// Removes and returns an element from the end of the iterator.
2352 pub fn next_back(&mut self, guard: &Guard) -> Option<RefEntry<'a, K, V, C, A>> {
2353 self.parent.check_guard(guard);
2354 let next_tail = match self.tail {
2355 Some(ref e) => e.prev(guard),
2356 None => try_pin_loop(|| self.parent.upper_bound(self.range.end_bound(), guard)),
2357 };
2358
2359 if let Some(ref t) = next_tail {
2360 match self.head {
2361 Some(ref h) => {
2362 let bound = Bound::Excluded(h.key());
2363 if above_lower_bound(&self.parent.comparator, &bound, t.key()) {
2364 if let Some(e) = mem::replace(&mut self.tail, next_tail.clone()) {
2365 unsafe {
2366 e.node.decrement(&self.parent.alloc, guard);
2367 }
2368 }
2369 next_tail
2370 } else {
2371 unsafe {
2372 t.node.decrement(&self.parent.alloc, guard);
2373 }
2374 None
2375 }
2376 }
2377 None => {
2378 let bound = self.range.start_bound();
2379 if above_lower_bound(&self.parent.comparator, &bound, t.key()) {
2380 if let Some(e) = mem::replace(&mut self.tail, next_tail.clone()) {
2381 unsafe {
2382 e.node.decrement(&self.parent.alloc, guard);
2383 }
2384 }
2385 next_tail
2386 } else {
2387 unsafe {
2388 t.node.decrement(&self.parent.alloc, guard);
2389 }
2390 None
2391 }
2392 }
2393 }
2394 } else {
2395 None
2396 }
2397 }
2398
2399 /// Decrements a reference count owned by this iterator.
2400 pub fn drop_impl(&mut self, guard: &Guard) {
2401 self.parent.check_guard(guard);
2402 if let Some(e) = self.head.take() {
2403 unsafe { e.node.decrement(&self.parent.alloc, guard) };
2404 }
2405 if let Some(e) = self.tail.take() {
2406 unsafe { e.node.decrement(&self.parent.alloc, guard) };
2407 }
2408 }
2409}
2410
2411/// An owning iterator over the entries of a `SkipList`.
2412pub struct IntoIter<K, V, A: SkiplistAllocator = TursoAllocator> {
2413 /// The current node.
2414 ///
2415 /// All preceding nods have already been destroyed.
2416 node: *mut Node<K, V>,
2417
2418 /// The allocator the nodes were allocated with.
2419 alloc: A,
2420}
2421
2422impl<K, V, A: SkiplistAllocator> Drop for IntoIter<K, V, A> {
2423 fn drop(&mut self) {
2424 // Iterate through the whole chain and destroy every node.
2425 while let Some(node) = NonNull::new(self.node) {
2426 unsafe {
2427 let node = NodeRef::new(node);
2428 // Unprotected loads are okay because this function is the only one currently using
2429 // the skip list.
2430 let next = node
2431 .get_level(0)
2432 .load(Ordering::Relaxed, epoch::unprotected());
2433
2434 // We can safely do this without deferring because references to
2435 // keys & values that we give out never outlive the SkipList.
2436 Node::finalize(&self.alloc, node.ptr.as_ptr());
2437
2438 self.node = next.as_raw() as *mut Node<K, V>;
2439 }
2440 }
2441 }
2442}
2443
2444impl<K, V, A: SkiplistAllocator> Iterator for IntoIter<K, V, A> {
2445 type Item = (K, V);
2446
2447 fn next(&mut self) -> Option<Self::Item> {
2448 loop {
2449 // Have we reached the end of the skip list?
2450 if self.node.is_null() {
2451 return None;
2452 }
2453
2454 unsafe {
2455 // Take the key and value out of the node.
2456 let key = ptr::read(&(*self.node).key);
2457 let value = ptr::read(&(*self.node).value);
2458
2459 // Get the next node in the skip list.
2460 //
2461 // Unprotected loads are okay because this function is the only one currently using
2462 // the skip list.
2463 let next = {
2464 let node = NodeRef::new(NonNull::new_unchecked(self.node));
2465 node.get_level(0)
2466 .load(Ordering::Relaxed, epoch::unprotected())
2467 };
2468
2469 // Deallocate the current node and move to the next one.
2470 Node::dealloc(&self.alloc, self.node);
2471 self.node = next.as_raw() as *mut Node<K, V>;
2472
2473 // The current node may be marked. If it is, it's been removed from the skip list
2474 // and we should just skip it.
2475 if next.tag() == 0 {
2476 return Some((key, value));
2477 }
2478 }
2479 }
2480 }
2481}
2482
2483impl<K, V, A: SkiplistAllocator> fmt::Debug for IntoIter<K, V, A> {
2484 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2485 f.pad("IntoIter { .. }")
2486 }
2487}
2488
2489/// Helper function to retry an operation until pinning succeeds or `None` is
2490/// returned.
2491pub(crate) fn try_pin_loop<'a: 'g, 'g, F, K, V, C, A: SkiplistAllocator>(
2492 mut f: F,
2493) -> Option<RefEntry<'a, K, V, C, A>>
2494where
2495 F: FnMut() -> Option<Entry<'a, 'g, K, V, C, A>>,
2496{
2497 loop {
2498 if let Some(e) = f()?.pin() {
2499 return Some(e);
2500 }
2501 }
2502}
2503
2504/// Helper function to check if a value is above a lower bound
2505fn above_lower_bound<V, T, C>(comparator: &C, bound: &Bound<&T>, other: &V) -> bool
2506where
2507 T: ?Sized,
2508 C: Comparator<V, T>,
2509{
2510 match *bound {
2511 Bound::Unbounded => true,
2512 Bound::Included(key) => comparator.compare(other, key).is_ge(),
2513 Bound::Excluded(key) => comparator.compare(other, key).is_gt(),
2514 }
2515}
2516
2517/// Helper function to check if a value is below an upper bound
2518fn below_upper_bound<V, T, C>(comparator: &C, bound: &Bound<&T>, other: &V) -> bool
2519where
2520 T: ?Sized,
2521 C: Comparator<V, T>,
2522{
2523 match *bound {
2524 Bound::Unbounded => true,
2525 Bound::Included(key) => comparator.compare(other, key).is_le(),
2526 Bound::Excluded(key) => comparator.compare(other, key).is_lt(),
2527 }
2528}