use std::sync::{Arc, Mutex};
const MAX_LEVEL: usize = 32;
struct SkipNode<K, V> {
key: Option<K>,
value: Option<V>,
forward: Vec<Option<Arc<Mutex<SkipNode<K, V>>>>>,
}
impl<K, V> SkipNode<K, V> {
fn new_head(height: usize) -> Self {
SkipNode {
key: None,
value: None,
forward: vec![None; height],
}
}
fn new(key: K, value: V, height: usize) -> Self {
SkipNode {
key: Some(key),
value: Some(value),
forward: vec![None; height],
}
}
}
struct LevelGen {
state: u64,
}
impl LevelGen {
fn new() -> Self {
let seed = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos() as u64)
.unwrap_or(12345678);
LevelGen {
state: seed ^ 0xdeadbeef_cafebabe,
}
}
fn next_u64(&mut self) -> u64 {
let mut x = self.state;
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
self.state = x;
x
}
fn random_level(&mut self, max: usize) -> usize {
let mut level = 1usize;
while level < max && (self.next_u64() & 1) == 0 {
level += 1;
}
level
}
}
pub struct SkipList<K, V> {
head: Arc<Mutex<SkipNode<K, V>>>,
level: usize,
len: usize,
rng: LevelGen,
}
impl<K: Ord + Clone, V: Clone> SkipList<K, V> {
pub fn new() -> Self {
SkipList {
head: Arc::new(Mutex::new(SkipNode::new_head(MAX_LEVEL))),
level: 1,
len: 0,
rng: LevelGen::new(),
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[allow(clippy::while_let_loop)]
pub fn get(&self, key: &K) -> Option<V> {
let head_guard = self.head.lock().ok()?;
let mut forwards: Vec<Option<Arc<Mutex<SkipNode<K, V>>>>> = head_guard.forward.clone();
drop(head_guard);
for lvl in (0..self.level).rev() {
loop {
let next = match forwards.get(lvl).and_then(|f| f.as_ref()) {
Some(n) => Arc::clone(n),
None => break,
};
let guard = match next.lock() {
Ok(g) => g,
Err(_) => break,
};
match guard.key.as_ref() {
Some(k) if k < key => {
let node_fwd = guard.forward.clone();
drop(guard);
let node_height = node_fwd.len();
let copy_len = node_height.min(forwards.len());
forwards[..copy_len].clone_from_slice(&node_fwd[..copy_len]);
}
Some(k) if k == key => {
return guard.value.clone();
}
_ => break,
}
}
}
None
}
#[allow(clippy::while_let_loop)]
pub fn insert(&mut self, key: K, value: V) {
let new_level = self.rng.random_level(MAX_LEVEL);
if new_level > self.level {
self.level = new_level;
}
let mut update: Vec<Option<Arc<Mutex<SkipNode<K, V>>>>> = vec![None; self.level];
let head_guard = match self.head.lock() {
Ok(g) => g,
Err(_) => return,
};
let mut forwards: Vec<Option<Arc<Mutex<SkipNode<K, V>>>>> = head_guard.forward.clone();
drop(head_guard);
let mut current_node_arc: Option<Arc<Mutex<SkipNode<K, V>>>> = None;
for lvl in (0..self.level).rev() {
loop {
let next = match forwards.get(lvl).and_then(|f| f.as_ref()) {
Some(n) => Arc::clone(n),
None => break,
};
let guard = match next.lock() {
Ok(g) => g,
Err(_) => break,
};
match guard.key.as_ref() {
Some(k) if k < &key => {
let node_fwd = guard.forward.clone();
drop(guard);
let node_height = node_fwd.len();
let copy_len = node_height.min(forwards.len());
forwards[..copy_len].clone_from_slice(&node_fwd[..copy_len]);
update[lvl] = Some(Arc::clone(&next));
current_node_arc = Some(next);
}
_ => break,
}
}
if update[lvl].is_none() {
update[lvl] = current_node_arc.clone(); }
}
if let Some(next_arc) = forwards.first().and_then(|f| f.as_ref()) {
let mut guard = match next_arc.lock() {
Ok(g) => g,
Err(_) => return,
};
if guard.key.as_ref() == Some(&key) {
guard.value = Some(value);
return;
}
}
let new_node = Arc::new(Mutex::new(SkipNode::new(key, value, new_level)));
for lvl in 0..new_level {
let pred = update.get(lvl).and_then(|u| u.as_ref());
if let Some(pred_arc) = pred {
let mut pred_guard = match pred_arc.lock() {
Ok(g) => g,
Err(_) => return,
};
let old_next = pred_guard.forward.get(lvl).and_then(|f| f.clone());
if let Ok(mut new_guard) = new_node.lock() {
new_guard.forward[lvl] = old_next;
}
pred_guard.forward[lvl] = Some(Arc::clone(&new_node));
} else {
let mut head_guard = match self.head.lock() {
Ok(g) => g,
Err(_) => return,
};
let old_next = head_guard.forward.get(lvl).and_then(|f| f.clone());
if let Ok(mut new_guard) = new_node.lock() {
new_guard.forward[lvl] = old_next;
}
head_guard.forward[lvl] = Some(Arc::clone(&new_node));
}
}
self.len += 1;
}
#[allow(clippy::while_let_loop)]
pub fn remove(&mut self, key: &K) -> bool {
let mut update: Vec<Option<Arc<Mutex<SkipNode<K, V>>>>> = vec![None; self.level];
let head_guard = match self.head.lock() {
Ok(g) => g,
Err(_) => return false,
};
let mut forwards: Vec<Option<Arc<Mutex<SkipNode<K, V>>>>> = head_guard.forward.clone();
drop(head_guard);
let mut current_node_arc: Option<Arc<Mutex<SkipNode<K, V>>>> = None;
for lvl in (0..self.level).rev() {
loop {
let next = match forwards.get(lvl).and_then(|f| f.as_ref()) {
Some(n) => Arc::clone(n),
None => break,
};
let guard = match next.lock() {
Ok(g) => g,
Err(_) => break,
};
match guard.key.as_ref() {
Some(k) if k < key => {
let node_fwd = guard.forward.clone();
drop(guard);
let node_height = node_fwd.len();
let copy_len = node_height.min(forwards.len());
forwards[..copy_len].clone_from_slice(&node_fwd[..copy_len]);
update[lvl] = Some(Arc::clone(&next));
current_node_arc = Some(next);
}
_ => break,
}
}
if update[lvl].is_none() {
update[lvl] = current_node_arc.clone();
}
}
let target_arc = match forwards.first().and_then(|f| f.as_ref()) {
Some(a) => Arc::clone(a),
None => return false,
};
let target_guard = match target_arc.lock() {
Ok(g) => g,
Err(_) => return false,
};
if target_guard.key.as_ref() != Some(key) {
return false;
}
let target_forward = target_guard.forward.clone();
drop(target_guard);
for lvl in 0..self.level {
let target_next = target_forward.get(lvl).and_then(|f| f.clone());
let pred = update.get(lvl).and_then(|u| u.as_ref());
if let Some(pred_arc) = pred {
let mut pred_guard = match pred_arc.lock() {
Ok(g) => g,
Err(_) => continue,
};
let is_target = pred_guard
.forward
.get(lvl)
.and_then(|f| f.as_ref())
.map(|a| Arc::ptr_eq(a, &target_arc))
.unwrap_or(false);
if is_target {
pred_guard.forward[lvl] = target_next;
}
} else {
let mut head_guard = match self.head.lock() {
Ok(g) => g,
Err(_) => continue,
};
let is_target = head_guard
.forward
.get(lvl)
.and_then(|f| f.as_ref())
.map(|a| Arc::ptr_eq(a, &target_arc))
.unwrap_or(false);
if is_target {
head_guard.forward[lvl] = target_next;
}
}
}
self.len -= 1;
true
}
#[allow(clippy::while_let_loop)]
pub fn range(&self, lo: &K, hi: &K) -> Vec<(K, V)> {
let mut result = Vec::new();
let head_guard = match self.head.lock() {
Ok(g) => g,
Err(_) => return result,
};
let mut forwards: Vec<Option<Arc<Mutex<SkipNode<K, V>>>>> = head_guard.forward.clone();
drop(head_guard);
'outer: for lvl in (1..self.level).rev() {
loop {
let next = match forwards.get(lvl).and_then(|f| f.as_ref()) {
Some(n) => Arc::clone(n),
None => break,
};
let guard = match next.lock() {
Ok(g) => g,
Err(_) => break 'outer,
};
match guard.key.as_ref() {
Some(k) if k < lo => {
let node_fwd = guard.forward.clone();
drop(guard);
let node_height = node_fwd.len();
let copy_len = node_height.min(forwards.len());
forwards[..copy_len].clone_from_slice(&node_fwd[..copy_len]);
}
_ => break,
}
}
}
loop {
let next = match forwards.first().and_then(|f| f.as_ref()) {
Some(n) => Arc::clone(n),
None => break,
};
let guard = match next.lock() {
Ok(g) => g,
Err(_) => break,
};
match guard.key.as_ref() {
Some(k) if k >= lo && k < hi => {
if let (Some(k2), Some(v2)) = (guard.key.clone(), guard.value.clone()) {
result.push((k2, v2));
}
let fwd0 = guard.forward.first().cloned().flatten();
drop(guard);
forwards[0] = fwd0;
}
Some(k) if k >= hi => break,
None => break,
_ => {
let fwd0 = guard.forward.first().cloned().flatten();
drop(guard);
forwards[0] = fwd0;
}
}
}
result
}
pub fn contains(&self, key: &K) -> bool {
self.get(key).is_some()
}
pub fn iter(&self) -> Vec<(K, V)> {
let mut result = Vec::with_capacity(self.len);
let head_guard = match self.head.lock() {
Ok(g) => g,
Err(_) => return result,
};
let mut current = head_guard.forward.first().cloned().flatten();
drop(head_guard);
while let Some(node_arc) = current {
let guard = match node_arc.lock() {
Ok(g) => g,
Err(_) => break,
};
if let (Some(k), Some(v)) = (guard.key.clone(), guard.value.clone()) {
result.push((k, v));
}
current = guard.forward.first().cloned().flatten();
}
result
}
pub fn remove_entry(&mut self, key: &K) -> Option<V> {
let value = self.get(key);
if value.is_some() && self.remove(key) {
value
} else {
None
}
}
}
impl<K: Ord + Clone, V: Clone> Default for SkipList<K, V> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_insert_get() {
let mut sl: SkipList<u32, &str> = SkipList::new();
sl.insert(5, "five");
sl.insert(2, "two");
sl.insert(8, "eight");
assert_eq!(sl.get(&2), Some("two"));
assert_eq!(sl.get(&5), Some("five"));
assert_eq!(sl.get(&8), Some("eight"));
assert_eq!(sl.get(&1), None);
assert_eq!(sl.len(), 3);
}
#[test]
fn test_remove() {
let mut sl: SkipList<u32, u32> = SkipList::new();
for i in 0..10u32 {
sl.insert(i, i * 10);
}
assert_eq!(sl.len(), 10);
assert!(sl.remove(&5));
assert_eq!(sl.get(&5), None);
assert_eq!(sl.len(), 9);
assert!(!sl.remove(&99));
}
#[test]
fn test_range() {
let mut sl: SkipList<u32, u32> = SkipList::new();
for i in 0..20u32 {
sl.insert(i, i);
}
let r = sl.range(&5, &10);
assert_eq!(r.len(), 5);
let keys: Vec<u32> = r.iter().map(|(k, _)| *k).collect();
assert_eq!(keys, vec![5, 6, 7, 8, 9]);
}
#[test]
fn test_overwrite_existing_key() {
let mut sl: SkipList<u32, u32> = SkipList::new();
sl.insert(1, 100);
sl.insert(1, 200);
assert_eq!(sl.get(&1), Some(200));
assert_eq!(sl.len(), 1);
}
#[test]
fn test_is_empty_and_len() {
let mut sl: SkipList<i32, i32> = SkipList::new();
assert!(sl.is_empty());
sl.insert(42, 0);
assert!(!sl.is_empty());
assert_eq!(sl.len(), 1);
sl.remove(&42);
assert!(sl.is_empty());
}
#[test]
fn test_large_insert_ordered() {
let mut sl: SkipList<u32, u32> = SkipList::new();
for i in (0..100u32).rev() {
sl.insert(i, i);
}
let r = sl.range(&0, &100);
assert_eq!(r.len(), 100);
for (i, (k, v)) in r.iter().enumerate() {
assert_eq!(*k, i as u32);
assert_eq!(*v, i as u32);
}
}
#[test]
fn test_contains() {
let mut sl: SkipList<u32, u32> = SkipList::new();
sl.insert(10, 100);
sl.insert(20, 200);
assert!(sl.contains(&10));
assert!(sl.contains(&20));
assert!(!sl.contains(&30));
}
#[test]
fn test_iter_sorted_order() {
let mut sl: SkipList<u32, u32> = SkipList::new();
sl.insert(5, 50);
sl.insert(1, 10);
sl.insert(9, 90);
sl.insert(3, 30);
sl.insert(7, 70);
let items = sl.iter();
assert_eq!(items.len(), 5);
let keys: Vec<u32> = items.iter().map(|(k, _)| *k).collect();
assert_eq!(keys, vec![1, 3, 5, 7, 9]);
}
#[test]
fn test_remove_entry() {
let mut sl: SkipList<u32, String> = SkipList::new();
sl.insert(1, "one".to_string());
sl.insert(2, "two".to_string());
let removed = sl.remove_entry(&1);
assert_eq!(removed, Some("one".to_string()));
assert_eq!(sl.len(), 1);
let not_found = sl.remove_entry(&99);
assert!(not_found.is_none());
}
#[test]
fn test_iter_empty() {
let sl: SkipList<u32, u32> = SkipList::new();
assert!(sl.iter().is_empty());
}
#[test]
fn test_range_empty_result() {
let mut sl: SkipList<u32, u32> = SkipList::new();
for i in 0..10u32 {
sl.insert(i, i);
}
let r = sl.range(&10, &5);
assert!(r.is_empty());
let r2 = sl.range(&100, &200);
assert!(r2.is_empty());
}
#[test]
fn test_concurrent_read_access() {
use std::sync::Arc;
use std::thread;
let mut sl = SkipList::new();
for i in 0..100u32 {
sl.insert(i, i * 10);
}
let shared = Arc::new(sl);
let mut handles = Vec::new();
for t in 0..4 {
let sl_ref = Arc::clone(&shared);
handles.push(thread::spawn(move || {
for i in 0..100u32 {
let val = sl_ref.get(&i);
assert_eq!(val, Some(i * 10), "thread {t} failed for key {i}");
}
}));
}
for h in handles {
if let Err(e) = h.join() {
panic!("Thread panicked: {e:?}");
}
}
}
}