convenient_skiplist/lib.rs
1use crate::iter::{
2 IterAll, IterRangeWith, LeftBiasIter, LeftBiasIterWidth, NodeRightIter, NodeWidth,
3 SkipListIndexRange, SkipListRange, VerticalIter,
4};
5use core::ops::RangeBounds;
6use rand::prelude::*;
7use std::cmp::{Ordering, PartialOrd};
8use std::fmt;
9use std::iter::FromIterator;
10use std::ops::Index;
11use std::ptr::NonNull;
12pub mod iter;
13
14#[cfg(feature = "serde_support")]
15mod serde;
16
17#[derive(PartialEq, Debug)]
18enum NodeValue<T> {
19 NegInf,
20 Value(T),
21 PosInf,
22}
23
24impl<T> NodeValue<T> {
25 #[inline]
26 fn get_value(&self) -> &T {
27 match &self {
28 NodeValue::Value(v) => v,
29 _ => unreachable!("Failed to get value! This shouldn't happen."),
30 }
31 }
32 #[inline]
33 fn is_pos_inf(&self) -> bool {
34 match &self {
35 NodeValue::PosInf => true,
36 _ => false,
37 }
38 }
39}
40
41impl<T: PartialEq> PartialEq<T> for NodeValue<T> {
42 #[inline]
43 fn eq(&self, other: &T) -> bool {
44 match self {
45 NodeValue::Value(v) => v == other,
46 _ => false,
47 }
48 }
49}
50
51impl<T: PartialOrd> PartialOrd<NodeValue<T>> for NodeValue<T> {
52 #[inline]
53 fn partial_cmp(&self, other: &NodeValue<T>) -> Option<Ordering> {
54 match (self, other) {
55 (NodeValue::NegInf, _) => Some(Ordering::Less),
56 (_, NodeValue::PosInf) => Some(Ordering::Less),
57 (NodeValue::Value(l), NodeValue::Value(r)) => l.partial_cmp(r),
58 _ => unreachable!(),
59 }
60 }
61}
62
63impl<T: PartialOrd> PartialOrd<T> for NodeValue<T> {
64 #[inline]
65 fn partial_cmp(&self, other: &T) -> Option<Ordering> {
66 match self {
67 NodeValue::NegInf => Some(Ordering::Less),
68 NodeValue::PosInf => Some(Ordering::Greater),
69 NodeValue::Value(v) => v.partial_cmp(other),
70 }
71 }
72}
73
74struct Node<T> {
75 right: Option<NonNull<Node<T>>>,
76 down: Option<NonNull<Node<T>>>,
77 value: NodeValue<T>,
78 width: usize,
79}
80
81impl<T> Node<T> {
82 #[inline]
83 fn nodes_skipped_over(&self) -> usize {
84 self.width - 1
85 }
86
87 #[inline]
88 fn clear_right(&mut self) {
89 self.width = 1;
90 unsafe {
91 while let Some(right) = self.right {
92 if right.as_ref().value.is_pos_inf() {
93 break;
94 }
95 let garbage = std::mem::replace(&mut self.right, (*right.as_ptr()).right);
96 drop(Box::from_raw(garbage.unwrap().as_ptr()));
97 }
98 }
99 }
100}
101
102impl<T: fmt::Debug> fmt::Debug for Node<T> {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 writeln!(f, "Node(")?;
105 writeln!(
106 f,
107 " right: {:?},",
108 self.right
109 .map(|some| format!("{:?}", unsafe { &some.as_ref().value }))
110 )?;
111 writeln!(
112 f,
113 " down: {:?},",
114 self.down
115 .map(|some| format!("{:?}", unsafe { &some.as_ref().value }))
116 )?;
117 writeln!(f, " value: {:?}", self.value)?;
118 writeln!(f, " width: {:?}", self.width)?;
119 write!(f, ")")
120 }
121}
122
123/// Hint that the current value `item` is:
124///
125/// - SmallerThanRange: `item` is strictly smaller than the range.
126/// - InRange: `item` is in the range.
127/// - LargerThanRange: `item` is strictly larger than the range.
128///
129/// Used with IterRangeWith, or `range_with`
130#[derive(Debug)]
131pub enum RangeHint {
132 SmallerThanRange,
133 InRange,
134 LargerThanRange,
135}
136
137/// `SkipLists` are fast probabilistic data-structures that feature logarithmic time complexity for inserting elements,
138/// testing element association, removing elements, and finding ranges of elements.
139///
140/// ```rust
141/// use convenient_skiplist::SkipList;
142///
143/// // Make a new skiplist
144/// let mut sk = SkipList::new();
145/// for i in 0..5usize {
146/// // Inserts are O(log(n)) on average
147/// sk.insert(i);
148/// }
149/// // You can print the skiplist!
150/// dbg!(&sk);
151/// // You can check if the skiplist contains an element, O(log(n))
152/// assert!(sk.contains(&0));
153/// assert!(!sk.contains(&10));
154/// assert!(sk.remove(&0)); // remove is also O(log(n))
155/// assert!(sk == sk); // equality checking is O(n)
156/// let from_vec = SkipList::from(vec![1usize, 2, 3].into_iter()); // From<Vec<T>> is O(nlogn)
157/// assert_eq!(vec![1, 2, 3], from_vec.iter_all().cloned().collect::<Vec<usize>>());
158/// ```
159pub struct SkipList<T> {
160 top_left: NonNull<Node<T>>,
161 height: usize,
162 len: usize,
163 _prevent_sync_send: std::marker::PhantomData<*const ()>,
164}
165
166impl<T> Drop for SkipList<T> {
167 fn drop(&mut self) {
168 // Main idea: Start in top left and iterate row by row.
169 let mut curr_left_node = self.top_left.as_ptr();
170 let mut next_down;
171 let mut curr_node = self.top_left.as_ptr();
172 unsafe {
173 loop {
174 if let Some(down) = (*curr_left_node).down {
175 next_down = Some(down.as_ptr());
176 } else {
177 next_down = None;
178 }
179 while let Some(right) = (*curr_node).right {
180 let garbage = std::mem::replace(&mut curr_node, right.as_ptr());
181 drop(Box::from_raw(garbage));
182 }
183 drop(Box::from_raw(curr_node));
184 if let Some(next_down) = next_down {
185 curr_left_node = next_down;
186 curr_node = curr_left_node;
187 } else {
188 break;
189 }
190 }
191 }
192 }
193}
194
195impl<T: Clone + PartialOrd> From<SkipList<T>> for Vec<T> {
196 fn from(sk: SkipList<T>) -> Vec<T> {
197 sk.iter_all().cloned().collect()
198 }
199}
200
201impl<T: Clone + PartialOrd> Clone for SkipList<T> {
202 fn clone(&self) -> Self {
203 SkipList::from(self.iter_all().cloned())
204 }
205}
206
207impl<T: PartialOrd + Clone> FromIterator<T> for SkipList<T> {
208 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> SkipList<T> {
209 let mut sk = SkipList::new();
210 for item in iter {
211 sk.insert(item);
212 }
213 sk
214 }
215}
216
217impl<T: PartialOrd + Clone, I: Iterator<Item = T>> From<I> for SkipList<T> {
218 fn from(iter: I) -> Self {
219 iter.collect()
220 }
221}
222
223impl<T: PartialOrd + Clone> PartialEq for SkipList<T> {
224 fn eq(&self, other: &Self) -> bool {
225 self.len() == other.len() && self.iter_all().zip(other.iter_all()).all(|(l, r)| l == r)
226 }
227}
228
229macro_rules! fmt_node {
230 ($f:expr, $node:expr) => {
231 write!(
232 $f,
233 "{:?}(skipped: {})",
234 $node.as_ref().value,
235 $node.as_ref().nodes_skipped_over()
236 )
237 };
238}
239
240impl<T: fmt::Debug> fmt::Debug for SkipList<T> {
241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
242 writeln!(f, "SkipList(wall_height: {}), and table:", self.height)?;
243 unsafe {
244 fmt_node!(f, self.top_left)?;
245 write!(f, " -> ")?;
246 fmt_node!(f, self.top_left.as_ref().right.unwrap())?;
247 writeln!(f)?;
248 let mut curr_down = self.top_left.as_ref().down;
249 while let Some(down) = curr_down {
250 fmt_node!(f, down)?;
251 let mut curr_right = down.as_ref().right;
252 while let Some(right) = curr_right {
253 write!(f, " -> ")?;
254 fmt_node!(f, right)?;
255 curr_right = right.as_ref().right;
256 }
257 curr_down = down.as_ref().down;
258 writeln!(f)?;
259 }
260 }
261 Ok(())
262 }
263}
264
265impl<T: PartialOrd + Clone> Default for SkipList<T> {
266 #[inline]
267 fn default() -> Self {
268 Self::new()
269 }
270}
271
272impl<T: PartialOrd + Clone> Index<usize> for SkipList<T> {
273 type Output = T;
274 fn index(&self, index: usize) -> &Self::Output {
275 self.at_index(index).expect("index out of bounds!")
276 }
277}
278
279/// Get the level of an item in the skiplist
280#[inline]
281fn get_level() -> usize {
282 let mut height = 1;
283 let mut rng = rand::thread_rng();
284 while rng.gen::<f32>() >= 0.5 {
285 height += 1;
286 }
287 height
288}
289
290impl<T: PartialOrd + Clone> SkipList<T> {
291 /// Make a new, empty SkipList. By default there is three levels.
292 ///
293 /// # Example
294 ///
295 /// ```rust
296 /// use convenient_skiplist::SkipList;
297 /// let mut sk = SkipList::new();
298 /// sk.insert(0usize);
299 ///
300 /// assert!(sk.contains(&0));
301 /// ```
302 #[inline]
303 pub fn new() -> SkipList<T> {
304 let mut sk = SkipList {
305 top_left: SkipList::pos_neg_pair(1),
306 height: 1,
307 len: 0,
308 _prevent_sync_send: std::marker::PhantomData,
309 };
310 sk.add_levels(2);
311 sk
312 }
313
314 /// add `additional_levels` to the _top_ of the SkipList
315 #[inline]
316 fn add_levels(&mut self, additional_levels: usize) {
317 let mut curr_level = self.top_left;
318 for _ in 0..additional_levels {
319 let mut new_level = SkipList::pos_neg_pair(self.len() + 1);
320 // We're going to insert this `new_level` between curr_level and the row below it.
321 // So it will look like:
322 // | top_left -> top_right
323 // | *new row here*
324 // | *existing row*
325 unsafe {
326 new_level.as_mut().down = curr_level.as_ref().down;
327 curr_level.as_mut().down = Some(new_level);
328 curr_level = new_level;
329 }
330 }
331 self.height += additional_levels as usize;
332 }
333 /// Insert `item` into the `SkipList`.
334 ///
335 /// Returns `true` if the item was actually inserted (i.e. wasn't already in the skiplist)
336 /// and `false` otherwise.
337 ///
338 /// Runs in `O(logn)` time.
339 ///
340 /// # Arguments
341 ///
342 /// * `item` - the item to insert.
343 ///
344 /// # Example
345 ///
346 /// ```rust
347 /// use convenient_skiplist::SkipList;
348 /// let mut sk = SkipList::new();
349 /// sk.insert(0usize);
350 ///
351 /// assert!(sk.contains(&0));
352 /// ```
353 #[inline]
354 pub fn insert(&mut self, item: T) -> bool {
355 #[cfg(debug_assertions)]
356 {
357 self.ensure_invariants()
358 }
359
360 if self.contains(&item) {
361 return false;
362 }
363 let height = get_level();
364 let additional_height_req: i32 = (height as i32 - self.height as i32) + 1;
365 if additional_height_req > 0 {
366 self.add_levels(additional_height_req as usize);
367 debug_assert!(self.height > height);
368 }
369 #[cfg(debug_assertions)]
370 {
371 self.ensure_invariants()
372 }
373
374 // Now the skiplist has enough height to actually insert this element.
375 // We'll need to reverse iterate to stitch the required items between.
376 // As self.path_to returns all nodes immediately *left* of where we've inserted,
377 // we just need to insert the nodes after.
378 let mut node_below_me = None;
379 let mut added = 0;
380 let mut total_width = None;
381 for node in self.insert_path(&item).into_iter().rev() {
382 unsafe {
383 (*node.curr_node).width += 1;
384 }
385 // Set total_width from the bottom node.
386 if total_width.is_none() {
387 total_width = Some(node.curr_width);
388 }
389 let total_width = total_width.unwrap();
390 if added < height {
391 unsafe {
392 // IDEA: We are iterating every node immediately *left* of where we're inserting
393 // an element. This means we can use `total_width`, or the maximum distance
394 // traveled to the right to reach the node to determine node widths relatively.
395 //
396 // eg. We insert 4 into the skiplist below:
397 // -inf -> ...
398 // -inf -> 1 -> ...
399 // -inf -> 1 -> 2 -> ...
400 // -inf -> 1 -> 2 -> 3 -> ...
401 //
402 // Imagine a placeholder where 4 goes.
403 //
404 // eg. We insert 4 into the skiplist below:
405 // -inf -> _ -> ...
406 // -inf -> 1 -> _ -> ...
407 // -inf -> 1 -> 2 -> _ -> ...
408 // -inf -> 1 -> 2 -> 3 -> _ -> ...
409 //
410 // This placeholder has then increased the width of all nodes by 1.
411 // Once we determine height, for every element on the left,
412 // we need to distribute the widths. We can do this
413 // relative to `total_width`:
414 //
415 // 1. -inf -> _ -> ...
416 // 2. -inf -> 1 -> _ -> ...
417 // 3. -inf -> 1 -> 2 -> _ -> ...
418 // 4. -inf -> 1 -> 2 -> 3 -> _ -> ...
419 // ~ ~ ~ ~
420 // We know how far _right_ we've been, and know that
421 // all areas a '4' goes is going to truncate widths
422 // of the elements to the left. For example,
423 // row element '2' in row 3 is going to report a `node.curr_width`
424 // of 3, so it's new width is (4 - 3) + 1 (i.e. the number of links between it and 4)
425 //
426 // Lastly, we distribute the remaining width after the
427 // truncation above to the new element.
428
429 let left_node_width = total_width - node.curr_width + 1;
430 let new_node_width = (*node.curr_node).width - left_node_width;
431
432 (*node.curr_node).width = left_node_width;
433
434 debug_assert!(total_width + 1 == node.curr_width + left_node_width);
435
436 let mut new_node = SkipList::make_node(item.clone(), new_node_width);
437
438 let node: *mut Node<T> = node.curr_node;
439 new_node.as_mut().down = node_below_me;
440 new_node.as_mut().right = (*node).right;
441 (*node).right = Some(new_node);
442 node_below_me = Some(new_node);
443 }
444 added += 1;
445 }
446 }
447 self.len += 1;
448 #[cfg(debug_assertions)]
449 {
450 self.ensure_invariants()
451 }
452 true
453 }
454 /// Test if `item` is in the skiplist. Returns `true` if it's in the skiplist,
455 /// `false` otherwise.
456 ///
457 /// Runs in `O(logn)` time
458 ///
459 /// # Arguments
460 ///
461 /// * `item` - the item we're testing.
462 ///
463 /// # Example
464 ///
465 /// ```rust
466 /// use convenient_skiplist::SkipList;
467 /// let mut sk = SkipList::new();
468 /// sk.insert(0usize);
469 ///
470 /// assert!(sk.contains(&0));
471 /// ```
472 #[inline]
473 pub fn contains(&self, item: &T) -> bool {
474 self.iter_left(item).any(|node| unsafe {
475 if let Some(right) = &(*node).right {
476 &right.as_ref().value == item
477 } else {
478 false
479 }
480 })
481 }
482
483 /// Remove `item` from the SkipList.
484 ///
485 /// Returns `true` if the item was in the collection to be removed,
486 /// and `false` otherwise.
487 ///
488 /// Runs in `O(logn)` time.
489 ///
490 /// # Arguments
491 ///
492 /// * `item` - the item to remove.
493 ///
494 /// # Example
495 ///
496 /// ```rust
497 /// use convenient_skiplist::SkipList;
498 /// let mut sk = SkipList::new();
499 /// sk.insert(0usize);
500 ///
501 /// let removed = sk.remove(&0);
502 /// assert!(removed);
503 /// ```
504 pub fn remove(&mut self, item: &T) -> bool {
505 if !self.contains(item) {
506 return false;
507 }
508 for node in self.iter_left(item) {
509 unsafe {
510 (*node).width -= 1;
511 // Invariant: `node` can never be PosInf
512 let right = (*node).right.unwrap();
513 if &right.as_ref().value != item {
514 continue;
515 }
516 // So the node right of us needs to be removed.
517 (*node).width += right.as_ref().width;
518 let garbage = std::mem::replace(&mut (*node).right, right.as_ref().right);
519 drop(Box::from_raw(garbage.unwrap().as_ptr()));
520 }
521 }
522 self.len -= 1;
523 true
524 }
525
526 /// Remove and return the item at `index`.
527 ///
528 /// Runs in O(log n) time.
529 ///
530 /// # Example
531 ///
532 /// ```rust
533 /// use convenient_skiplist::SkipList;
534 /// let mut sk = SkipList::from(0..5);
535 ///
536 /// assert_eq!(sk.len(), 5);
537 /// assert_eq!(sk.remove_at(1), Some(1));
538 /// assert_eq!(sk.len(), 4);
539 /// ```
540 pub fn remove_at(&mut self, index: usize) -> Option<T> {
541 let item = self.at_index(index).cloned();
542 if let Some(item) = &item {
543 self.remove(item);
544 }
545 item
546 }
547
548 /// Return the number of elements in the skiplist.
549 ///
550 /// # Example
551 /// ```rust
552 /// use convenient_skiplist::SkipList;
553 /// let mut sk = SkipList::new();
554 ///
555 /// sk.insert(0);
556 /// assert_eq!(sk.len(), 1);
557 ///
558 /// sk.insert(1);
559 /// assert_eq!(sk.len(), 2);
560 /// ```
561
562 #[inline]
563 pub fn len(&self) -> usize {
564 self.len
565 }
566
567 /// Returns true if the skiplist is empty
568 #[inline]
569 pub fn is_empty(&self) -> bool {
570 self.len == 0
571 }
572
573 // TODO
574 // fn remove_range<'a>(&'a mut self, _start: &'a T, _end: &'a T) -> usize {
575 // // Idea: Use iter_left twice to determine the chunk in the middle to remove.
576 // // Hardest part will be cleaning up garbage. :thinking:
577 // todo!()
578 // }
579
580 /// Find the index of `item` in the `SkipList`.
581 ///
582 /// Runs in `O(logn)` time.
583 ///
584 /// # Arguments
585 ///
586 /// * `item`: the item to find the position of.
587 ///
588 /// # Example
589 /// ```rust
590 /// use convenient_skiplist::SkipList;
591 /// let mut sk = SkipList::new();
592 /// sk.insert(1);
593 /// sk.insert(2);
594 /// sk.insert(3);
595 ///
596 /// assert_eq!(sk.index_of(&1), Some(0));
597 /// assert_eq!(sk.index_of(&2), Some(1));
598 /// assert_eq!(sk.index_of(&3), Some(2));
599 /// assert_eq!(sk.index_of(&999), None);
600 /// ```
601 #[inline]
602 pub fn index_of(&self, item: &T) -> Option<usize> {
603 // INVARIANT: path_to is a LeftBiasIterWidth, so there's always a
604 // node right of us.
605 self.path_to(item).last().and_then(|node| {
606 if unsafe { &(*node.curr_node).right.unwrap().as_ref().value } == item {
607 Some(node.curr_width)
608 } else {
609 None
610 }
611 })
612 }
613
614 /// Get the item at the index `index `in the `SkipList`.
615 ///
616 /// Runs in `O(logn)` time.
617 ///
618 /// # Arguments
619 ///
620 /// * `index`: the index to get the item at
621 ///
622 /// # Example
623 /// ```rust
624 /// use convenient_skiplist::SkipList;
625 /// let sk = SkipList::from(0..10);
626 /// for i in 0..10 {
627 /// assert_eq!(Some(&i), sk.at_index(i));
628 /// }
629 /// assert_eq!(None, sk.at_index(11));
630 ///
631 /// let mut sk = SkipList::new();
632 /// sk.insert('a');
633 /// sk.insert('b');
634 /// sk.insert('c');
635 /// assert_eq!(Some(&'a'), sk.at_index(0));
636 /// assert_eq!(Some(&'b'), sk.at_index(1));
637 /// assert_eq!(Some(&'c'), sk.at_index(2));
638 /// assert_eq!(None, sk.at_index(3));
639 /// ```
640 #[inline]
641 pub fn at_index(&self, index: usize) -> Option<&T> {
642 if index >= self.len() {
643 return None;
644 }
645 unsafe {
646 let mut curr_node = self.top_left.as_ref();
647 let mut distance_left = index + 1;
648 loop {
649 if distance_left == 0 {
650 return Some(curr_node.value.get_value());
651 }
652 if curr_node.width <= distance_left {
653 distance_left -= curr_node.width;
654 // INVARIANT: We've checked if `index` < self.len(),
655 // so there's always a `right`
656 curr_node = curr_node.right.unwrap().as_ptr().as_ref().unwrap();
657 continue;
658 } else if let Some(down) = curr_node.down {
659 curr_node = down.as_ptr().as_ref().unwrap();
660 } else {
661 unreachable!()
662 }
663 }
664 }
665 }
666
667 /// Peek at the first item in the skiplist.
668 ///
669 /// Runs in constant time.
670 ///
671 /// # Example
672 ///
673 /// ```rust
674 /// use convenient_skiplist::SkipList;
675 /// let mut sk = SkipList::from(0..10);
676 ///
677 /// assert_eq!(Some(&0), sk.peek_first());
678 /// ```
679 #[inline]
680 pub fn peek_first(&self) -> Option<&T> {
681 self.at_index(0)
682 }
683
684 /// Peek at the last item in the skiplist.
685 ///
686 /// Runs in O(log n) time.
687 ///
688 /// # Example
689 ///
690 /// ```rust
691 /// use convenient_skiplist::SkipList;
692 /// let mut sk = SkipList::from(0..10);
693 ///
694 /// assert_eq!(Some(&9), sk.peek_last());
695 /// ```
696 #[inline]
697 pub fn peek_last(&self) -> Option<&T> {
698 if self.is_empty() {
699 None
700 } else {
701 self.at_index(self.len() - 1)
702 }
703 }
704
705 /// Pop `count` elements off of the end of the Skiplist.
706 ///
707 /// Runs in O(logn * count) time, O(logn + count) space.
708 ///
709 /// Memory pressure: This is implemented such that the entire
710 /// region of the skiplist is cleaved off at once. So you'll
711 /// see in the worse case (i.e. all towers have maximum height ~ logn)
712 /// count * logn memory deallocations.
713 ///
714 /// Returns an empty `vec` if count == 0.
715 ///
716 /// Will dealloc the whole skiplist if count >= len and start fresh.
717 ///
718 /// # Example
719 ///
720 /// ```rust
721 /// use convenient_skiplist::SkipList;
722 /// let mut sk = SkipList::from(0..10);
723 ///
724 /// assert_eq!(Some(&7), sk.at_index(7));
725 /// assert_eq!(vec![7, 8, 9], sk.pop_max(3));
726 /// assert_eq!(vec![6], sk.pop_max(1));
727 /// assert_eq!(vec![4, 5], sk.pop_max(2));
728 /// assert_eq!(vec![0, 1, 2, 3], sk.pop_max(5));
729 ///
730 /// let v: Vec<u32> = Vec::new();
731 /// assert_eq!(v, sk.pop_max(1000)); // empty
732 /// ```
733 #[inline]
734 pub fn pop_max(&mut self, count: usize) -> Vec<T> {
735 if self.is_empty() || count == 0 {
736 return vec![];
737 }
738 if count >= self.len() {
739 // let new = SkipList::new();
740 // let garbage = std::mem::replace(&mut self, &mut new);
741 // drop(garbage);
742 let ret = self.iter_all().cloned().collect();
743 *self = SkipList::new(); // TODO: Does this drop me?
744 return ret;
745 }
746 let ele_at = self.at_index(self.len() - count).unwrap().clone();
747 self.len -= count;
748 // IDEA: Calculate widths by adding _backwards_ through the
749 // insert path.
750 let mut frontier = self.insert_path(&ele_at);
751 let last_value = frontier.last_mut().cloned().unwrap();
752 let mut last_width = last_value.curr_width;
753 let mut ret: Vec<_> = Vec::with_capacity(count);
754 let mut jumped_left = 1;
755 unsafe {
756 ret.extend(NodeRightIter::new(
757 (*last_value.curr_node).right.unwrap().as_ptr(),
758 ));
759 (*last_value.curr_node).clear_right();
760 }
761 for mut nw in frontier.into_iter().rev().skip(1) {
762 unsafe {
763 // We've jumped right, and now need to update our width field.
764 // Do we need this if-gate?
765 if (*nw.curr_node).value != (*last_value.curr_node).value {
766 jumped_left += last_width - nw.curr_width;
767 last_width = nw.curr_width;
768 }
769 (*nw.curr_node).clear_right();
770 (*nw.curr_node).width = jumped_left;
771 }
772 }
773 ret
774 }
775
776 /// Pop the last element off of the skiplist.
777 ///
778 /// Runs in O(logn) time, O(1) space.
779 ///
780 /// # Example
781 ///
782 /// ```rust
783 /// use convenient_skiplist::SkipList;
784 /// let mut sk = SkipList::from(0..10);
785 ///
786 /// assert_eq!(Some(9), sk.pop_back());
787 /// ```
788 #[inline]
789 pub fn pop_back(&mut self) -> Option<T> {
790 if self.is_empty() {
791 None
792 } else {
793 self.pop_max(1).pop()
794 }
795 }
796
797 /// Pop the first element off of the skiplist.
798 ///
799 /// Runs in O(logn) time, O(1) space.
800 ///
801 /// # Example
802 ///
803 /// ```rust
804 /// use convenient_skiplist::SkipList;
805 /// let mut sk = SkipList::from(0..10);
806 ///
807 /// assert_eq!(Some(0), sk.pop_front());
808 /// ```
809 #[inline]
810 pub fn pop_front(&mut self) -> Option<T> {
811 if self.is_empty() {
812 None
813 } else {
814 self.pop_min(1).pop()
815 }
816 }
817
818 fn iter_vertical(&self) -> impl Iterator<Item = *mut Node<T>> {
819 VerticalIter::new(self.top_left.as_ptr())
820 }
821
822 /// Pop `count` elements off of the start of the Skiplist.
823 ///
824 /// Runs in O(logn * count) time, O(count) space.
825 ///
826 /// Memory pressure: This is implemented such that the entire
827 /// region of the skiplist is cleaved off at once. So you'll
828 /// see in the worse case (i.e. all towers have maximum height ~ logn)
829 /// count * logn memory deallocations.
830 ///
831 /// Returns an empty `vec` if count == 0.
832 ///
833 /// Will dealloc the whole skiplist if count >= len and start fresh.
834 ///
835 /// # Example
836 ///
837 /// ```rust
838 /// use convenient_skiplist::SkipList;
839 /// let mut sk = SkipList::from(0..10);
840 ///
841 /// assert_eq!(vec![0, 1, 2], sk.pop_min(3));
842 /// assert_eq!(vec![3], sk.pop_min(1));
843 /// assert_eq!(vec![4, 5], sk.pop_min(2));
844 /// assert_eq!(vec![6, 7, 8, 9], sk.pop_max(5));
845 ///
846 /// let v: Vec<u32> = Vec::new();
847 /// assert_eq!(v, sk.pop_min(1000)); // empty
848 /// ```
849 #[inline]
850 pub fn pop_min(&mut self, count: usize) -> Vec<T> {
851 if count == 0 || self.is_empty() {
852 return Vec::with_capacity(0);
853 }
854 if count >= self.len() {
855 let ret = self.iter_all().cloned().collect();
856 // Tested in valgrind -- this drops old me.
857 *self = SkipList::new();
858 return ret;
859 }
860 let ele_at = self.at_index(count).unwrap();
861 // dbg!(ele_at);
862 let mut ret = Vec::with_capacity(count);
863 for (left, row_end) in self.iter_vertical().zip(self.path_to(ele_at)) {
864 // Our path can have the same elements left and right of the
865 // frontier.
866 if std::ptr::eq(left, row_end.curr_node) {
867 unsafe { (*left).width -= count };
868 continue;
869 }
870 debug_assert!(count >= row_end.curr_width);
871 // Next, we need to unlink the first node after `left`,
872 // and calculate width.
873 // Idea: count is how many elements popped over, curr_width
874 // is how far we've traveled so far.
875 // _
876 // -inf -> ...
877 // -inf -> 1 -> ...
878 // -inf -> 1 -> 2 -> 3 -> ...
879 // ~ ~ ~
880 // width_over_removed = count(_) - count(~) = 2
881 // new_width = Node<1>.width - width_over_removed
882 let width_over_removed = count - row_end.curr_width;
883 let new_width = unsafe { (*row_end.curr_node).width - width_over_removed };
884 // Now, surgically remove this stretch of nodes.
885 unsafe {
886 let mut start_garbage = (*left).right.unwrap();
887 (*left).right = (*row_end.curr_node).right;
888 (*left).width = new_width;
889 (*row_end.curr_node).right = None;
890 // We're at the bottom, so lets grab our return values.
891 if start_garbage.as_ref().down.is_none() {
892 let mut curr_node = start_garbage.as_ptr();
893 loop {
894 ret.push((*curr_node).value.get_value().clone());
895 curr_node = match (*curr_node).right {
896 Some(right) => right.as_ptr(),
897 None => break,
898 };
899 }
900 }
901 start_garbage.as_mut().clear_right();
902 drop(Box::from_raw(start_garbage.as_ptr()));
903 }
904 }
905 self.len -= count;
906 ret
907 }
908
909 /// Left-Biased iterator towards `item`.
910 ///
911 /// Returns all possible positions *left* where `item`
912 /// is or should be in the skiplist.
913 #[inline]
914 fn iter_left<'a>(&'a self, item: &'a T) -> impl Iterator<Item = *mut Node<T>> + 'a {
915 LeftBiasIter::new(self.top_left.as_ptr(), item)
916 }
917
918 /// Iterator over all elements in the Skiplist.
919 ///
920 /// This runs in `O(n)` time.
921 ///
922 /// # Example
923 ///
924 /// ```rust
925 /// use convenient_skiplist::SkipList;
926 /// let mut sk = SkipList::new();
927 /// sk.insert(0usize);
928 /// sk.insert(1usize);
929 /// sk.insert(2usize);
930 /// for item in sk.iter_all() {
931 /// println!("{:?}", item);
932 /// }
933 /// ```
934 #[inline]
935 pub fn iter_all(&self) -> IterAll<T> {
936 unsafe { IterAll::new(self.top_left.as_ref(), self.len) }
937 }
938
939 /// Iterator over an inclusive range of elements in the SkipList.
940 ///
941 /// This runs in `O(logn + k)`, where k is the width of range.
942 ///
943 /// # Example
944 ///
945 /// ```rust
946 /// use convenient_skiplist::SkipList;
947 /// let mut sk = SkipList::new();
948 /// for item in 0..100 {
949 /// sk.insert(item);
950 /// }
951 ///
952 /// for item in sk.range(&20, &40) {
953 /// println!("{}", item); // First prints 20, then 21, ... and finally 40.
954 /// }
955 /// ```
956 #[inline]
957 pub fn range<'a>(&'a self, start: &'a T, end: &'a T) -> SkipListRange<'a, T> {
958 SkipListRange::new(unsafe { self.top_left.as_ref() }, start, end)
959 }
960
961 /// Iterate over a range of indices.
962 ///
963 /// This runs in `O(logn + k)`, where k is the width of range.
964 ///
965 /// This is different than `SkipList::range` as this operates on indices and not values.
966 ///
967 /// # Example
968 ///
969 /// ```rust
970 /// use convenient_skiplist::SkipList;
971 /// let mut sk = SkipList::new();
972 /// for c in 'a'..'z' {
973 /// sk.insert(c);
974 /// }
975 ///
976 /// for item in sk.index_range(0..5) {
977 /// println!("{}", item); // Prints a, b, c, d, e
978 /// }
979 /// ```
980 pub fn index_range<R: RangeBounds<usize>>(&self, range: R) -> SkipListIndexRange<'_, R, T> {
981 SkipListIndexRange::new(unsafe { self.top_left.as_ref() }, range)
982 }
983
984 /// Iterator over an inclusive range of elements in the SkipList,
985 /// as defined by the `inclusive_fn`.
986 ///
987 /// This runs in `O(logn + k)`, where k is the width of range.
988 ///
989 /// As the skiplist is ordered in an ascending way, `inclusive_fn` should be
990 /// structured with the idea in mind that you're going to see the smallest elements
991 /// first. `inclusive_fn` should be designed to extract a *single contiguous
992 /// stretch of elements*.
993 ///
994 /// This iterator will find the smallest element in the range,
995 /// and then return elements until it finds the first element
996 /// larger than the range.
997 ///
998 /// If multiple ranges are desired, you can use `range_with` multiple times,
999 /// and simply use the last element of the previous run as the start of
1000 /// the next run.
1001 ///
1002 /// # Example
1003 ///
1004 /// ```rust
1005 /// use convenient_skiplist::{RangeHint, SkipList};
1006 /// let mut sk = SkipList::new();
1007 /// for item in 0..100 {
1008 /// sk.insert(item);
1009 /// }
1010 ///
1011 /// let desired_range = sk.range_with(|&ele| {
1012 /// if ele <= 5 {
1013 /// RangeHint::SmallerThanRange
1014 /// } else if ele <= 30 {
1015 /// RangeHint::InRange
1016 /// } else {
1017 /// RangeHint::LargerThanRange
1018 /// }
1019 /// });
1020 /// for item in desired_range {
1021 /// println!("{}", item); // First prints 6, then 7, ... and finally 30.
1022 /// }
1023 /// ```
1024 #[inline]
1025 pub fn range_with<F>(&self, inclusive_fn: F) -> IterRangeWith<T, F>
1026 where
1027 F: Fn(&T) -> RangeHint,
1028 {
1029 IterRangeWith::new(unsafe { self.top_left.as_ref() }, inclusive_fn)
1030 }
1031
1032 /// Clear (deallocate all entries in) the skiplist.
1033 ///
1034 /// Returns the number of elements removed (length of bottom row).
1035 ///
1036 /// # Example
1037 ///
1038 /// ```rust
1039 /// use convenient_skiplist::{RangeHint, SkipList};
1040 /// let mut sk = SkipList::from(0..10);
1041 /// assert_eq!(sk.clear(), 10);
1042 /// assert_eq!(sk, SkipList::new());
1043 ///
1044 /// ```
1045 pub fn clear(&mut self) -> usize {
1046 let removed = self.len();
1047 *self = SkipList::new();
1048 removed
1049 }
1050
1051 #[inline]
1052 fn path_to<'a>(&self, item: &'a T) -> LeftBiasIterWidth<'a, T> {
1053 LeftBiasIterWidth::new(self.top_left.as_ptr(), item)
1054 }
1055
1056 #[inline]
1057 fn insert_path(&mut self, item: &T) -> Vec<NodeWidth<T>> {
1058 self.path_to(item).collect()
1059 }
1060
1061 fn pos_neg_pair(width: usize) -> NonNull<Node<T>> {
1062 let right = Box::new(Node {
1063 right: None,
1064 down: None,
1065 value: NodeValue::PosInf,
1066 width: 1,
1067 });
1068 unsafe {
1069 let left = Box::new(Node {
1070 right: Some(NonNull::new_unchecked(Box::into_raw(right))),
1071 down: None,
1072 value: NodeValue::NegInf,
1073 width,
1074 });
1075 NonNull::new_unchecked(Box::into_raw(left))
1076 }
1077 }
1078
1079 fn make_node(value: T, width: usize) -> NonNull<Node<T>> {
1080 unsafe {
1081 let node = Box::new(Node {
1082 right: None,
1083 down: None,
1084 value: NodeValue::Value(value),
1085 width,
1086 });
1087 NonNull::new_unchecked(Box::into_raw(node))
1088 }
1089 }
1090
1091 #[cfg(debug_assertions)]
1092 fn ensure_columns_same_value(&self) {
1093 let mut left_row = self.top_left;
1094 let mut curr_node = self.top_left;
1095 unsafe {
1096 loop {
1097 while let Some(right) = curr_node.as_ref().right {
1098 let curr_value = &curr_node.as_ref().value;
1099 let mut curr_down = curr_node;
1100 while let Some(down) = curr_down.as_ref().down {
1101 assert!(&down.as_ref().value == curr_value);
1102 curr_down = down;
1103 }
1104 curr_node = right;
1105 }
1106 // Now, move a an entire row down.
1107 if let Some(down) = left_row.as_ref().down {
1108 left_row = down;
1109 curr_node = left_row;
1110 } else {
1111 break;
1112 }
1113 }
1114 }
1115 }
1116
1117 #[cfg(debug_assertions)]
1118 fn ensure_rows_ordered(&self) {
1119 let mut left_row = self.top_left;
1120 let mut curr_node = self.top_left;
1121 unsafe {
1122 loop {
1123 while let Some(right) = curr_node.as_ref().right {
1124 assert!(curr_node.as_ref().value < right.as_ref().value);
1125 curr_node = right;
1126 }
1127 if let Some(down) = left_row.as_ref().down {
1128 left_row = down;
1129 curr_node = left_row;
1130 } else {
1131 break;
1132 }
1133 }
1134 }
1135 }
1136
1137 #[cfg(debug_assertions)]
1138 fn ensure_rows_sum_len(&self) {
1139 let mut left_row = self.top_left;
1140 let mut curr_node = self.top_left;
1141 unsafe {
1142 loop {
1143 let mut curr_sum = 0;
1144 while let Some(right) = curr_node.as_ref().right {
1145 curr_sum += curr_node.as_ref().width;
1146 curr_node = right;
1147 }
1148 if let Some(down) = left_row.as_ref().down {
1149 assert_eq!(self.len(), curr_sum - 1);
1150 left_row = down;
1151 curr_node = left_row;
1152 } else {
1153 break;
1154 }
1155 }
1156 }
1157 }
1158
1159 #[cfg(debug_assertions)]
1160 fn ensure_invariants(&self) {
1161 unsafe {
1162 assert!(self.top_left.as_ref().right.unwrap().as_ref().value == NodeValue::PosInf)
1163 }
1164 self.ensure_rows_ordered();
1165 self.ensure_columns_same_value();
1166 self.ensure_rows_sum_len();
1167 }
1168}
1169
1170#[cfg(test)]
1171mod tests {
1172 use crate::SkipList;
1173 use std::collections::HashSet;
1174
1175 #[test]
1176 fn insert_no_panic() {
1177 let mut sl = SkipList::new();
1178 for i in &[10, 30, 50, 5, 0, 3] {
1179 sl.insert(*i);
1180 assert!(sl.contains(&i));
1181 }
1182 #[cfg(debug_assertions)]
1183 sl.ensure_invariants();
1184 }
1185
1186 #[test]
1187 fn test_remove() {
1188 let mut sl = SkipList::new();
1189 sl.insert(0usize);
1190 assert!(sl.remove(&0));
1191 assert!(!sl.remove(&0));
1192 assert!(!sl.contains(&0));
1193 sl.insert(0);
1194 sl.insert(1);
1195 sl.insert(2);
1196 assert!(sl.remove(&1));
1197 assert!(!sl.contains(&1));
1198 sl.remove(&2);
1199 assert!(!sl.contains(&2));
1200 }
1201
1202 #[test]
1203 fn test_inclusive_range() {
1204 let mut sl = SkipList::new();
1205 let values: &[i32] = &[10, 30, 50, 5, 0, 3];
1206 for i in &[10, 30, 50, 5, 0, 3] {
1207 sl.insert(*i);
1208 assert!(sl.contains(&i));
1209 }
1210 let lower = 3;
1211 let upper = 30;
1212 let v: HashSet<i32> = sl.range(&lower, &upper).cloned().collect();
1213 for expected_value in values.iter().filter(|&&i| lower <= i && i <= upper) {
1214 assert!(v.contains(expected_value));
1215 }
1216 let right_empty: HashSet<i32> = sl.range(&100, &1000).cloned().collect();
1217 assert!(right_empty.is_empty());
1218
1219 let left_empty: HashSet<i32> = sl.range(&-2, &-1).cloned().collect();
1220 assert!(left_empty.is_empty());
1221
1222 // Excessive range
1223 let lower = -10;
1224 let upper = 1000;
1225 let v: HashSet<i32> = sl.range(&lower, &upper).cloned().collect();
1226 for expected_value in values.iter().filter(|&&i| lower <= i && i <= upper) {
1227 assert!(v.contains(expected_value));
1228 }
1229 }
1230
1231 #[test]
1232 fn test_len() {
1233 let mut sl = SkipList::new();
1234 assert_eq!(sl.len(), 0);
1235 assert!(sl.is_empty());
1236 sl.insert(0);
1237 assert_eq!(sl.len(), 1);
1238 assert!(!sl.is_empty());
1239 sl.insert(0);
1240 assert_eq!(sl.len(), 1);
1241 sl.insert(1);
1242 assert_eq!(sl.len(), 2);
1243 sl.remove(&1);
1244 assert_eq!(sl.len(), 1);
1245 sl.remove(&1);
1246 assert_eq!(sl.len(), 1);
1247 sl.remove(&0);
1248 assert_eq!(sl.len(), 0);
1249 sl.remove(&0);
1250 assert_eq!(sl.len(), 0);
1251 }
1252
1253 #[test]
1254 fn test_eq() {
1255 let mut s0 = SkipList::new();
1256 let mut s1 = SkipList::new();
1257 assert!(s0 == s1);
1258 s0.insert(0);
1259 assert!(s0 != s1);
1260 s1.insert(1);
1261 assert!(s0 != s1);
1262 s0.insert(1);
1263 s1.insert(0);
1264 assert!(s0 == s1);
1265 s0.insert(2);
1266 s0.insert(3);
1267 assert!(s0 != s1);
1268 }
1269
1270 #[test]
1271 fn test_from() {
1272 let values = vec![1usize, 2, 3];
1273 let sk = SkipList::from(values.clone().into_iter());
1274 assert_eq!(sk.iter_all().cloned().collect::<Vec<_>>(), values);
1275 let values: Vec<usize> = (0..10).collect();
1276 let sk = SkipList::from(0..10);
1277 assert_eq!(sk.iter_all().cloned().collect::<Vec<_>>(), values);
1278 }
1279
1280 #[test]
1281 fn test_index_of() {
1282 let mut sk = SkipList::new();
1283 sk.insert(1);
1284 sk.insert(2);
1285 sk.insert(3);
1286
1287 assert_eq!(sk.index_of(&1), Some(0));
1288 assert_eq!(sk.index_of(&2), Some(1));
1289 assert_eq!(sk.index_of(&3), Some(2));
1290 assert_eq!(sk.index_of(&999), None);
1291 let sk = SkipList::new();
1292 assert_eq!(sk.index_of(&0), None);
1293 assert_eq!(sk.index_of(&999), None);
1294 }
1295
1296 #[test]
1297 fn test_at_index() {
1298 let sk = SkipList::from(0..10);
1299 for i in 0..10 {
1300 assert_eq!(Some(&i), sk.at_index(i));
1301 }
1302 assert_eq!(None, sk.at_index(11));
1303
1304 let mut sk = SkipList::new();
1305 sk.insert('a');
1306 sk.insert('b');
1307 sk.insert('c');
1308 assert_eq!(Some(&'a'), sk.at_index(0));
1309 assert_eq!(Some(&'b'), sk.at_index(1));
1310 assert_eq!(Some(&'c'), sk.at_index(2));
1311 assert_eq!(None, sk.at_index(3));
1312
1313 assert_eq!('a', sk[0]);
1314 assert_eq!('b', sk[1]);
1315 assert_eq!('c', sk[2]);
1316 }
1317
1318 #[test]
1319 #[should_panic]
1320 fn test_bad_index() {
1321 let sk = SkipList::from(0..10);
1322 sk[sk.len()];
1323 }
1324
1325 #[test]
1326 fn test_pop_max() {
1327 let mut sk = SkipList::from(0..10);
1328 assert_eq!(Some(&7), sk.at_index(7));
1329 assert_eq!(vec![7, 8, 9], sk.pop_max(3));
1330 assert_eq!(vec![6], sk.pop_max(1));
1331 assert_eq!(vec![4, 5], sk.pop_max(2));
1332 assert_eq!(vec![0, 1, 2, 3], sk.pop_max(5));
1333 let mut sk = SkipList::from(0..3);
1334 assert_eq!(vec![2], sk.pop_max(1));
1335 let mut sk: SkipList<u32> = SkipList::new();
1336 let v: Vec<u32> = Vec::new();
1337 assert_eq!(v, sk.pop_max(1));
1338 }
1339
1340 #[test]
1341 fn test_pop_min() {
1342 let mut sk = SkipList::from(0..10);
1343 assert_eq!(vec![0, 1, 2], sk.pop_min(3));
1344 assert_eq!(vec![3], sk.pop_min(1));
1345 assert_eq!(vec![4, 5], sk.pop_min(2));
1346 assert_eq!(vec![6, 7, 8, 9], sk.pop_min(5));
1347 let v: Vec<u32> = Vec::new();
1348 assert_eq!(v, sk.pop_min(1));
1349 }
1350
1351 #[test]
1352 fn test_clone() {
1353 let sk = SkipList::from(0..30);
1354 let clone = sk.clone();
1355 assert_eq!(sk, clone);
1356 assert!(!std::ptr::eq(&sk, &clone));
1357 // Empty case
1358 let sk = SkipList::from(0..0);
1359 let clone = sk.clone();
1360 assert_eq!(
1361 sk, clone,
1362 "Empty skiplists should clone nicely, {:?} != {:?}",
1363 sk, clone
1364 );
1365 }
1366
1367 #[test]
1368 fn test_peek() {
1369 let sk = SkipList::from(0..10);
1370 assert_eq!(Some(&0), sk.peek_first());
1371 assert_eq!(Some(&9), sk.peek_last());
1372 }
1373
1374 #[test]
1375 fn test_vec_from() {
1376 let sk: SkipList<u32> = SkipList::from(0..4);
1377 assert_eq!(vec![0, 1, 2, 3], Vec::from(sk));
1378 }
1379
1380 #[test]
1381 fn test_more_complex_type() {
1382 // A bit of history behind this test:
1383 // I tried to avoid cloning by using std::ptr::read
1384 // but you double free as you're copying the string struct
1385 // and dropping the original. So you end up with double frees.
1386 let mut string_sk = SkipList::new();
1387 for c in b'a'..b'z' {
1388 string_sk.insert((c as char).to_string());
1389 }
1390 string_sk.pop_back();
1391 }
1392}