use crossbeam_skiplist::SkipSet; use crossbeam_utils::thread; use std::{iter, ops::Bound, sync::Barrier}; #[test] fn smoke() { let m = SkipSet::new(); m.insert(1); m.insert(5); m.insert(7); } #[test] fn is_empty() { let s = SkipSet::new(); assert!(s.is_empty()); s.insert(1); assert!(!s.is_empty()); s.insert(2); s.insert(3); assert!(!s.is_empty()); s.remove(&2); assert!(!s.is_empty()); s.remove(&1); assert!(!s.is_empty()); s.remove(&3); assert!(s.is_empty()); } #[test] fn insert() { let insert = [0, 4, 2, 12, 8, 7, 11, 5]; let not_present = [1, 3, 6, 9, 10]; let s = SkipSet::new(); for &x in &insert { s.insert(x); assert_eq!(*s.get(&x).unwrap(), x); } for &x in ¬_present { assert!(s.get(&x).is_none()); } } #[test] fn remove() { let insert = [0, 4, 2, 12, 8, 7, 11, 5]; let not_present = [1, 3, 6, 9, 10]; let remove = [2, 12, 8]; let remaining = [0, 4, 5, 7, 11]; let s = SkipSet::new(); for &x in &insert { s.insert(x); } for x in ¬_present { assert!(s.remove(x).is_none()); } for x in &remove { assert!(s.remove(x).is_some()); } let mut v = vec![]; let mut e = s.front().unwrap(); loop { v.push(*e); if !e.move_next() { break; } } assert_eq!(v, remaining); for x in &insert { s.remove(x); } assert!(s.is_empty()); } // https://github.com/crossbeam-rs/crossbeam/issues/672 #[test] fn concurrent_insert() { for _ in 0..100 { let set: SkipSet = iter::once(1).collect(); let barrier = Barrier::new(2); thread::scope(|s| { s.spawn(|_| { barrier.wait(); set.insert(1); }); s.spawn(|_| { barrier.wait(); set.insert(1); }); }) .unwrap(); } } // https://github.com/crossbeam-rs/crossbeam/issues/672 #[test] fn concurrent_remove() { for _ in 0..100 { let set: SkipSet = iter::once(1).collect(); let barrier = Barrier::new(2); thread::scope(|s| { s.spawn(|_| { barrier.wait(); set.remove(&1); }); s.spawn(|_| { barrier.wait(); set.remove(&1); }); }) .unwrap(); } } #[test] fn entry() { let s = SkipSet::new(); assert!(s.front().is_none()); assert!(s.back().is_none()); for &x in &[4, 2, 12, 8, 7, 11, 5] { s.insert(x); } let mut e = s.front().unwrap(); assert_eq!(*e, 2); assert!(!e.move_prev()); assert!(e.move_next()); assert_eq!(*e, 4); e = s.back().unwrap(); assert_eq!(*e, 12); assert!(!e.move_next()); assert!(e.move_prev()); assert_eq!(*e, 11); } #[test] fn entry_remove() { let s = SkipSet::new(); for &x in &[4, 2, 12, 8, 7, 11, 5] { s.insert(x); } let mut e = s.get(&7).unwrap(); assert!(!e.is_removed()); assert!(e.remove()); assert!(e.is_removed()); e.move_prev(); e.move_next(); assert_ne!(*e, 7); for e in s.iter() { assert!(!s.is_empty()); assert_ne!(s.len(), 0); e.remove(); } assert!(s.is_empty()); assert_eq!(s.len(), 0); } #[test] fn entry_reposition() { let s = SkipSet::new(); for &x in &[4, 2, 12, 8, 7, 11, 5] { s.insert(x); } let mut e = s.get(&7).unwrap(); assert!(!e.is_removed()); assert!(e.remove()); assert!(e.is_removed()); s.insert(7); e.move_prev(); e.move_next(); assert_eq!(*e, 7); } #[test] fn len() { let s = SkipSet::new(); assert_eq!(s.len(), 0); for (i, &x) in [4, 2, 12, 8, 7, 11, 5].iter().enumerate() { s.insert(x); assert_eq!(s.len(), i + 1); } s.insert(5); assert_eq!(s.len(), 7); s.insert(5); assert_eq!(s.len(), 7); s.remove(&6); assert_eq!(s.len(), 7); s.remove(&5); assert_eq!(s.len(), 6); s.remove(&12); assert_eq!(s.len(), 5); } #[test] fn insert_and_remove() { let s = SkipSet::new(); let keys = || s.iter().map(|e| *e).collect::>(); s.insert(3); s.insert(5); s.insert(1); s.insert(4); s.insert(2); assert_eq!(keys(), [1, 2, 3, 4, 5]); assert!(s.remove(&4).is_some()); assert_eq!(keys(), [1, 2, 3, 5]); assert!(s.remove(&3).is_some()); assert_eq!(keys(), [1, 2, 5]); assert!(s.remove(&1).is_some()); assert_eq!(keys(), [2, 5]); assert!(s.remove(&1).is_none()); assert_eq!(keys(), [2, 5]); assert!(s.remove(&3).is_none()); assert_eq!(keys(), [2, 5]); assert!(s.remove(&2).is_some()); assert_eq!(keys(), [5]); assert!(s.remove(&5).is_some()); assert_eq!(keys(), []); s.insert(3); assert_eq!(keys(), [3]); s.insert(1); assert_eq!(keys(), [1, 3]); s.insert(3); assert_eq!(keys(), [1, 3]); s.insert(5); assert_eq!(keys(), [1, 3, 5]); assert!(s.remove(&3).is_some()); assert_eq!(keys(), [1, 5]); assert!(s.remove(&1).is_some()); assert_eq!(keys(), [5]); assert!(s.remove(&3).is_none()); assert_eq!(keys(), [5]); assert!(s.remove(&5).is_some()); assert_eq!(keys(), []); } #[test] fn get() { let s = SkipSet::new(); s.insert(30); s.insert(50); s.insert(10); s.insert(40); s.insert(20); assert_eq!(*s.get(&10).unwrap(), 10); assert_eq!(*s.get(&20).unwrap(), 20); assert_eq!(*s.get(&30).unwrap(), 30); assert_eq!(*s.get(&40).unwrap(), 40); assert_eq!(*s.get(&50).unwrap(), 50); assert!(s.get(&7).is_none()); assert!(s.get(&27).is_none()); assert!(s.get(&31).is_none()); assert!(s.get(&97).is_none()); } #[test] fn lower_bound() { let s = SkipSet::new(); s.insert(30); s.insert(50); s.insert(10); s.insert(40); s.insert(20); assert_eq!(*s.lower_bound(Bound::Unbounded).unwrap(), 10); assert_eq!(*s.lower_bound(Bound::Included(&10)).unwrap(), 10); assert_eq!(*s.lower_bound(Bound::Included(&20)).unwrap(), 20); assert_eq!(*s.lower_bound(Bound::Included(&30)).unwrap(), 30); assert_eq!(*s.lower_bound(Bound::Included(&40)).unwrap(), 40); assert_eq!(*s.lower_bound(Bound::Included(&50)).unwrap(), 50); assert_eq!(*s.lower_bound(Bound::Included(&7)).unwrap(), 10); assert_eq!(*s.lower_bound(Bound::Included(&27)).unwrap(), 30); assert_eq!(*s.lower_bound(Bound::Included(&31)).unwrap(), 40); assert!(s.lower_bound(Bound::Included(&97)).is_none()); assert_eq!(*s.lower_bound(Bound::Excluded(&10)).unwrap(), 20); assert_eq!(*s.lower_bound(Bound::Excluded(&20)).unwrap(), 30); assert_eq!(*s.lower_bound(Bound::Excluded(&30)).unwrap(), 40); assert_eq!(*s.lower_bound(Bound::Excluded(&40)).unwrap(), 50); assert!(s.lower_bound(Bound::Excluded(&50)).is_none()); assert_eq!(*s.lower_bound(Bound::Excluded(&7)).unwrap(), 10); assert_eq!(*s.lower_bound(Bound::Excluded(&27)).unwrap(), 30); assert_eq!(*s.lower_bound(Bound::Excluded(&31)).unwrap(), 40); assert!(s.lower_bound(Bound::Excluded(&97)).is_none()); } #[test] fn upper_bound() { let s = SkipSet::new(); s.insert(30); s.insert(50); s.insert(10); s.insert(40); s.insert(20); assert_eq!(*s.upper_bound(Bound::Unbounded).unwrap(), 50); assert_eq!(*s.upper_bound(Bound::Included(&10)).unwrap(), 10); assert_eq!(*s.upper_bound(Bound::Included(&20)).unwrap(), 20); assert_eq!(*s.upper_bound(Bound::Included(&30)).unwrap(), 30); assert_eq!(*s.upper_bound(Bound::Included(&40)).unwrap(), 40); assert_eq!(*s.upper_bound(Bound::Included(&50)).unwrap(), 50); assert!(s.upper_bound(Bound::Included(&7)).is_none()); assert_eq!(*s.upper_bound(Bound::Included(&27)).unwrap(), 20); assert_eq!(*s.upper_bound(Bound::Included(&31)).unwrap(), 30); assert_eq!(*s.upper_bound(Bound::Included(&97)).unwrap(), 50); assert!(s.upper_bound(Bound::Excluded(&10)).is_none()); assert_eq!(*s.upper_bound(Bound::Excluded(&20)).unwrap(), 10); assert_eq!(*s.upper_bound(Bound::Excluded(&30)).unwrap(), 20); assert_eq!(*s.upper_bound(Bound::Excluded(&40)).unwrap(), 30); assert_eq!(*s.upper_bound(Bound::Excluded(&50)).unwrap(), 40); assert!(s.upper_bound(Bound::Excluded(&7)).is_none()); assert_eq!(*s.upper_bound(Bound::Excluded(&27)).unwrap(), 20); assert_eq!(*s.upper_bound(Bound::Excluded(&31)).unwrap(), 30); assert_eq!(*s.upper_bound(Bound::Excluded(&97)).unwrap(), 50); } #[test] fn get_or_insert() { let s = SkipSet::new(); s.insert(3); s.insert(5); s.insert(1); s.insert(4); s.insert(2); assert_eq!(*s.get(&4).unwrap(), 4); assert_eq!(*s.insert(4), 4); assert_eq!(*s.get(&4).unwrap(), 4); assert_eq!(*s.get_or_insert(4), 4); assert_eq!(*s.get(&4).unwrap(), 4); assert_eq!(*s.get_or_insert(6), 6); } #[test] fn get_next_prev() { let s = SkipSet::new(); s.insert(3); s.insert(5); s.insert(1); s.insert(4); s.insert(2); let mut e = s.get(&3).unwrap(); assert_eq!(*e.next().unwrap(), 4); assert_eq!(*e.prev().unwrap(), 2); assert_eq!(*e, 3); e.move_prev(); assert_eq!(*e.next().unwrap(), 3); assert_eq!(*e.prev().unwrap(), 1); assert_eq!(*e, 2); e.move_prev(); assert_eq!(*e.next().unwrap(), 2); assert!(e.prev().is_none()); assert_eq!(*e, 1); e.move_next(); e.move_next(); e.move_next(); e.move_next(); assert!(e.next().is_none()); assert_eq!(*e.prev().unwrap(), 4); assert_eq!(*e, 5); } #[test] fn front_and_back() { let s = SkipSet::new(); assert!(s.front().is_none()); assert!(s.back().is_none()); for &x in &[4, 2, 12, 8, 7, 11, 5] { s.insert(x); } assert_eq!(*s.front().unwrap(), 2); assert_eq!(*s.back().unwrap(), 12); } #[test] fn iter() { let s = SkipSet::new(); for &x in &[4, 2, 12, 8, 7, 11, 5] { s.insert(x); } assert_eq!( s.iter().map(|e| *e).collect::>(), &[2, 4, 5, 7, 8, 11, 12] ); let mut it = s.iter(); s.remove(&2); assert_eq!(*it.next().unwrap(), 4); s.remove(&7); assert_eq!(*it.next().unwrap(), 5); s.remove(&5); assert_eq!(*it.next().unwrap(), 8); s.remove(&12); assert_eq!(*it.next().unwrap(), 11); assert!(it.next().is_none()); } #[test] fn iter_range() { use std::ops::Bound::*; let s = SkipSet::new(); let v = (0..10).map(|x| x * 10).collect::>(); for &x in v.iter() { s.insert(x); } assert_eq!( s.iter().map(|x| *x).collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( s.iter().rev().map(|x| *x).collect::>(), vec![90, 80, 70, 60, 50, 40, 30, 20, 10, 0] ); assert_eq!( s.range(..).map(|x| *x).collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( s.range((Included(&0), Unbounded)) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( s.range((Excluded(&0), Unbounded)) .map(|x| *x) .collect::>(), vec![10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( s.range((Included(&25), Unbounded)) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80, 90] ); assert_eq!( s.range((Excluded(&25), Unbounded)) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80, 90] ); assert_eq!( s.range((Included(&70), Unbounded)) .map(|x| *x) .collect::>(), vec![70, 80, 90] ); assert_eq!( s.range((Excluded(&70), Unbounded)) .map(|x| *x) .collect::>(), vec![80, 90] ); assert_eq!( s.range((Included(&100), Unbounded)) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Excluded(&100), Unbounded)) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Unbounded, Included(&90))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( s.range((Unbounded, Excluded(&90))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80] ); assert_eq!( s.range((Unbounded, Included(&25))) .map(|x| *x) .collect::>(), vec![0, 10, 20] ); assert_eq!( s.range((Unbounded, Excluded(&25))) .map(|x| *x) .collect::>(), vec![0, 10, 20] ); assert_eq!( s.range((Unbounded, Included(&70))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70] ); assert_eq!( s.range((Unbounded, Excluded(&70))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60] ); assert_eq!( s.range((Unbounded, Included(&-1))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Unbounded, Excluded(&-1))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Included(&25), Included(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80] ); assert_eq!( s.range((Included(&25), Excluded(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70] ); assert_eq!( s.range((Excluded(&25), Included(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80] ); assert_eq!( s.range((Excluded(&25), Excluded(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70] ); assert_eq!( s.range((Included(&25), Included(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Included(&25), Excluded(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Excluded(&25), Included(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Excluded(&25), Excluded(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Included(&50), Included(&50))) .map(|x| *x) .collect::>(), vec![50] ); assert_eq!( s.range((Included(&50), Excluded(&50))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Excluded(&50), Included(&50))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Excluded(&50), Excluded(&50))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Included(&100), Included(&-2))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Included(&100), Excluded(&-2))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Excluded(&100), Included(&-2))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( s.range((Excluded(&100), Excluded(&-2))) .map(|x| *x) .collect::>(), vec![] ); } // https://github.com/crossbeam-rs/crossbeam/issues/671 #[test] fn iter_range2() { let set: SkipSet<_> = [1, 3, 5].iter().cloned().collect(); assert_eq!(set.range(2..4).count(), 1); set.insert(3); } #[test] fn into_iter() { let s = SkipSet::new(); for &x in &[4, 2, 12, 8, 7, 11, 5] { s.insert(x); } assert_eq!(s.into_iter().collect::>(), &[2, 4, 5, 7, 8, 11, 12]); } #[test] fn clear() { let s = SkipSet::new(); for &x in &[4, 2, 12, 8, 7, 11, 5] { s.insert(x); } assert!(!s.is_empty()); assert_ne!(s.len(), 0); s.clear(); assert!(s.is_empty()); assert_eq!(s.len(), 0); }