use skiplist::map::{SkipMap, SkipMapIntoIter, SkipMapIter};
use std::ops::{Add, Sub};
use std::borrow::Borrow;
pub struct SkipSet<T> {
map: SkipMap<T, ()>,
}
impl<T> SkipSet<T> {
pub fn new() -> Self {
SkipSet {
map: SkipMap::new(),
}
}
pub fn insert(&mut self, key: T) -> Option<T>
where
T: Ord,
{
self.map.insert(key, ()).map(|pair| pair.0)
}
pub fn remove<V>(&mut self, key: &V) -> Option<T>
where
T: Borrow<V>,
V: Ord + ?Sized,
{
self.map.remove(key).map(|pair| pair.0)
}
pub fn contains<V>(&self, key: &V) -> bool
where
T: Borrow<V>,
V: Ord + ?Sized,
{
self.map.contains_key(key)
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn clear(&mut self) {
self.map.clear();
}
pub fn floor<V>(&self, key: &V) -> Option<&T>
where
T: Borrow<V>,
V: Ord + ?Sized,
{
self.map.floor(key)
}
pub fn ceil<V>(&self, key: &V) -> Option<&T>
where
T: Borrow<V>,
V: Ord + ?Sized,
{
self.map.ceil(key)
}
pub fn min(&self) -> Option<&T>
where
T: Ord,
{
self.map.min()
}
pub fn max(&self) -> Option<&T>
where
T: Ord,
{
self.map.max()
}
pub fn union(left: Self, right: Self) -> Self
where
T: Ord,
{
SkipSet {
map: SkipMap::union(left.map, right.map),
}
}
pub fn intersection(left: Self, right: Self) -> Self
where
T: Ord,
{
SkipSet {
map: SkipMap::intersection(left.map, right.map),
}
}
pub fn difference(left: Self, right: Self) -> Self
where
T: Ord,
{
SkipSet {
map: SkipMap::difference(left.map, right.map),
}
}
pub fn symmetric_difference(left: Self, right: Self) -> Self
where
T: Ord,
{
SkipSet {
map: SkipMap::symmetric_difference(left.map, right.map),
}
}
pub fn iter(&self) -> SkipSetIter<T> {
SkipSetIter {
map_iter: self.map.iter(),
}
}
}
impl<T> IntoIterator for SkipSet<T> {
type Item = T;
type IntoIter = SkipSetIntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter {
map_iter: self.map.into_iter(),
}
}
}
impl<'a, T> IntoIterator for &'a SkipSet<T>
where
T: 'a,
{
type Item = &'a T;
type IntoIter = SkipSetIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct SkipSetIntoIter<T> {
map_iter: SkipMapIntoIter<T, ()>,
}
impl<T> Iterator for SkipSetIntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.map_iter.next().map(|pair| pair.0)
}
}
pub struct SkipSetIter<'a, T>
where
T: 'a,
{
map_iter: SkipMapIter<'a, T, ()>,
}
impl<'a, T> Iterator for SkipSetIter<'a, T>
where
T: 'a,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.map_iter.next().map(|pair| pair.0)
}
}
impl<T> Default for SkipSet<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Add for SkipSet<T>
where
T: Ord,
{
type Output = SkipSet<T>;
fn add(self, other: SkipSet<T>) -> SkipSet<T> {
Self::union(self, other)
}
}
impl<T> Sub for SkipSet<T>
where
T: Ord,
{
type Output = SkipSet<T>;
fn sub(self, other: SkipSet<T>) -> SkipSet<T> {
Self::difference(self, other)
}
}
#[cfg(test)]
mod tests {
use super::SkipSet;
#[test]
fn test_len_empty() {
let set: SkipSet<u32> = SkipSet::new();
assert_eq!(set.len(), 0);
}
#[test]
fn test_is_empty() {
let set: SkipSet<u32> = SkipSet::new();
assert!(set.is_empty());
}
#[test]
fn test_min_max_empty() {
let set: SkipSet<u32> = SkipSet::new();
assert_eq!(set.min(), None);
assert_eq!(set.max(), None);
}
#[test]
fn test_insert() {
let mut set = SkipSet::new();
assert_eq!(set.insert(1), None);
assert!(set.contains(&1));
}
#[test]
fn test_insert_replace() {
let mut set = SkipSet::new();
assert_eq!(set.insert(1), None);
assert_eq!(set.insert(1), Some(1));
}
#[test]
fn test_remove() {
let mut set = SkipSet::new();
set.insert(1);
assert_eq!(set.remove(&1), Some(1));
assert!(!set.contains(&1));
}
#[test]
fn test_min_max() {
let mut set = SkipSet::new();
set.insert(1);
set.insert(3);
set.insert(5);
assert_eq!(set.min(), Some(&1));
assert_eq!(set.max(), Some(&5));
}
#[test]
fn test_floor_ceil() {
let mut set = SkipSet::new();
set.insert(1);
set.insert(3);
set.insert(5);
assert_eq!(set.floor(&0), None);
assert_eq!(set.floor(&2), Some(&1));
assert_eq!(set.floor(&4), Some(&3));
assert_eq!(set.floor(&6), Some(&5));
assert_eq!(set.ceil(&0), Some(&1));
assert_eq!(set.ceil(&2), Some(&3));
assert_eq!(set.ceil(&4), Some(&5));
assert_eq!(set.ceil(&6), None);
}
#[test]
fn test_union() {
let mut n = SkipSet::new();
n.insert(1);
n.insert(2);
n.insert(3);
let mut m = SkipSet::new();
m.insert(3);
m.insert(4);
m.insert(5);
let union = n + m;
assert_eq!(
union.iter().collect::<Vec<&u32>>(),
vec![&1, &2, &3, &4, &5],
);
assert_eq!(union.len(), 5);
}
#[test]
fn test_intersection() {
let mut n = SkipSet::new();
n.insert(1);
n.insert(2);
n.insert(3);
let mut m = SkipSet::new();
m.insert(3);
m.insert(4);
m.insert(5);
let intersection = SkipSet::intersection(n, m);
assert_eq!(
intersection.iter().collect::<Vec<&u32>>(),
vec![&3],
);
assert_eq!(intersection.len(), 1);
}
#[test]
fn test_difference() {
let mut n = SkipSet::new();
n.insert(1);
n.insert(2);
n.insert(3);
let mut m = SkipSet::new();
m.insert(3);
m.insert(4);
m.insert(5);
let difference = n - m;
assert_eq!(
difference.iter().collect::<Vec<&u32>>(),
vec![&1, &2],
);
assert_eq!(difference.len(), 2);
}
#[test]
fn test_symmetric_difference() {
let mut n = SkipSet::new();
n.insert(1);
n.insert(2);
n.insert(3);
let mut m = SkipSet::new();
m.insert(3);
m.insert(4);
m.insert(5);
let symmetric_difference = SkipSet::symmetric_difference(n, m);
assert_eq!(
symmetric_difference.iter().collect::<Vec<&u32>>(),
vec![&1, &2, &4, &5],
);
assert_eq!(symmetric_difference.len(), 4);
}
#[test]
fn test_into_iter() {
let mut set = SkipSet::new();
set.insert(1);
set.insert(5);
set.insert(3);
assert_eq!(
set.into_iter().collect::<Vec<u32>>(),
vec![1, 3, 5],
);
}
#[test]
fn test_iter() {
let mut set = SkipSet::new();
set.insert(1);
set.insert(5);
set.insert(3);
assert_eq!(
set.iter().collect::<Vec<&u32>>(),
vec![&1, &3, &5],
);
}
}