use crate::MAX_CAPACITY;
use nanorand::{Rng, WyRand};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
use std::iter::{Extend, FromIterator, IntoIterator};
use std::slice::Iter;
#[derive(Clone, Serialize, Deserialize)]
pub struct Set {
indicator: Vec<bool>,
elements: Vec<usize>,
pages: Vec<Option<Vec<usize>>>,
max: usize,
current_max: Option<usize>,
current_min: Option<usize>,
}
impl Set {
const PAGE_SIZE: usize = 16;
const PAGE_SHIFT: usize = Self::PAGE_SIZE.trailing_zeros() as usize;
const PAGE_MASK: usize = Self::PAGE_SIZE - 1;
pub fn with_max(max_element: usize) -> Self {
if max_element > MAX_CAPACITY {
panic!("max_element is larger than MAX_ELEMENTS");
}
Self {
indicator: vec![false; max_element.saturating_add(1)], elements: Vec::with_capacity(max_element.saturating_add(1)),
pages: Vec::new(),
max: max_element,
current_max: None,
current_min: None,
}
}
#[deprecated(since = "0.5.0", note = "Use with_max instead")]
pub fn new(max_element: usize) -> Self {
Self::with_max(max_element)
}
#[inline(always)]
pub fn with_capacity(capacity: usize) -> Self {
Set {
indicator: vec![false; capacity.saturating_add(1)], elements: Vec::with_capacity(capacity),
pages: Vec::new(),
max: capacity, current_max: None,
current_min: None,
}
}
pub fn capacity(&self) -> usize {
self.max }
pub fn max_value(&self) -> usize {
self.max
}
#[inline(always)]
pub fn reserve(&mut self, new_max_element: usize) {
if new_max_element > self.max {
let new_size = new_max_element + 1;
self.indicator.resize(new_size, false);
self.max = new_max_element;
}
}
#[inline(always)]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.elements.shrink_to(min_capacity);
let new_max = if self.is_empty() {
min_capacity } else {
std::cmp::max(self.current_max.unwrap_or(0), min_capacity)
};
self.max = new_max;
self.indicator.resize(new_max + 1, false);
}
#[inline(always)]
pub fn shrink_to_fit(&mut self) {
self.elements.shrink_to_fit();
if self.is_empty() {
self.max = 0;
self.indicator.resize(1, false);
self.pages.clear();
} else {
self.max = self.current_max.unwrap_or(0);
self.indicator.resize(self.max + 1, false);
if !self.pages.is_empty() {
let max_page_idx = Self::page_indices(self.max).0;
if max_page_idx + 1 < self.pages.len() {
self.pages.truncate(max_page_idx + 1);
}
}
}
self.pages.shrink_to_fit();
}
#[inline(always)]
pub fn len(&self) -> usize {
self.elements.len()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
#[inline(always)]
pub fn iter(&self) -> Iter<'_, usize> {
self.elements.iter()
}
#[inline(always)]
pub fn clear(&mut self) {
self.indicator.fill(false);
self.elements.clear();
self.pages.clear();
self.current_max = None;
self.current_min = None;
}
#[inline(always)]
pub fn insert(&mut self, value: usize) -> bool {
if value == self.max + 1 {
self.indicator.push(false);
self.max = value;
return self.insert_unchecked(value);
}
match value > self.max {
true => match value < MAX_CAPACITY {
true => {
self.reserve(value);
self.insert_unchecked(value)
}
false => false,
},
false => {
self.insert_unchecked(value)
}
}
}
#[inline(always)]
pub fn remove(&mut self, value: &usize) -> bool {
match *value >= self.indicator.len() {
true => false,
false => unsafe { self.remove_unchecked(value) },
}
}
#[inline(always)]
pub fn contains(&self, value: &usize) -> bool {
match *value < self.indicator.len() {
true => unsafe { *self.indicator.as_ptr().add(*value) },
false => false, }
}
#[inline(always)]
pub fn get(&self, value: &usize) -> Option<usize> {
match self.contains(value) {
true => Some(*value),
false => None,
}
}
#[inline(always)]
pub fn take(&mut self, value: &usize) -> Option<usize> {
match self.contains(value) {
true => {
unsafe { self.remove_unchecked(value) };
Some(*value)
}
false => None,
}
}
#[inline(always)]
pub fn max(&self) -> Option<usize> {
self.current_max
}
#[inline(always)]
pub fn min(&self) -> Option<usize> {
self.current_min
}
#[inline(always)]
pub fn peek_largest(&self) -> Option<usize> {
self.current_max
}
#[inline(always)]
pub fn peek_smallest(&self) -> Option<usize> {
self.current_min
}
#[inline(always)]
fn page_indices(value: usize) -> (usize, usize) {
let page_index = value >> Self::PAGE_SHIFT; let in_page_index = value & Self::PAGE_MASK; (page_index, in_page_index)
}
#[inline(always)]
pub fn range_cardinality<R>(&self, range: R) -> usize
where
R: std::ops::RangeBounds<usize>,
{
let start = match range.start_bound() {
std::ops::Bound::Included(&s) => s,
std::ops::Bound::Excluded(&s) => s + 1,
std::ops::Bound::Unbounded => 0,
};
let end = match range.end_bound() {
std::ops::Bound::Included(&e) => e + 1,
std::ops::Bound::Excluded(&e) => e,
std::ops::Bound::Unbounded => self.max + 1,
};
(start..end).filter(|&value| self.contains(&value)).count()
}
#[inline(always)]
pub fn rank(&self, value: usize) -> usize {
self.elements
.iter()
.filter(|&&element| element < value)
.count()
}
#[inline(always)]
pub fn remove_largest(&mut self) -> Option<usize> {
match self.current_max {
Some(max_val) => {
unsafe { self.remove_unchecked(&max_val) };
Some(max_val)
}
None => None,
}
}
#[inline(always)]
pub fn remove_smallest(&mut self) -> Option<usize> {
match self.current_min {
Some(min_val) => {
unsafe { self.remove_unchecked(&min_val) };
Some(min_val)
}
None => None,
}
}
#[inline(always)]
pub fn random(&self, rng: &mut WyRand) -> Option<usize> {
match self.elements.is_empty() {
false => unsafe {
Some(
*self
.elements
.as_ptr()
.add(rng.generate_range(0..self.elements.len())),
)
},
true => None,
}
}
#[inline(always)]
pub fn insert_unchecked(&mut self, value: usize) -> bool {
if self.indicator[value] {
return false;
}
self.indicator[value] = true;
let (page_idx, in_page_idx) = Self::page_indices(value);
if page_idx >= self.pages.len() {
self.pages.resize_with(page_idx + 1, Default::default);
}
if self.pages[page_idx].is_none() {
self.pages[page_idx] = Some(vec![0; Self::PAGE_SIZE]);
}
let elem_index = self.elements.len();
self.elements.push(value);
self.pages[page_idx].as_mut().unwrap()[in_page_idx] = elem_index;
match self.current_max {
Some(max) if value > max => self.current_max = Some(value),
None => self.current_max = Some(value),
_ => {}
}
match self.current_min {
Some(min) if value < min => self.current_min = Some(value),
None => self.current_min = Some(value),
_ => {}
}
true
}
#[inline(always)]
pub unsafe fn remove_unchecked(&mut self, value: &usize) -> bool {
if !self.indicator[*value] {
return false;
}
self.indicator[*value] = false;
let (page_idx, in_page_idx) = Self::page_indices(*value);
let elem_index = self.pages[page_idx].as_ref().unwrap()[in_page_idx];
if elem_index < self.elements.len() - 1 {
let last_index = self.elements.len() - 1;
self.elements.swap(elem_index, last_index);
let swapped_value = self.elements[elem_index];
let (swapped_page_idx, swapped_in_page_idx) = Self::page_indices(swapped_value);
self.pages[swapped_page_idx].as_mut().unwrap()[swapped_in_page_idx] = elem_index;
}
self.elements.pop();
self.pages[page_idx].as_mut().unwrap()[in_page_idx] = 0;
if Some(*value) == self.current_max || Some(*value) == self.current_min {
if self.is_empty() {
self.current_max = None;
self.current_min = None;
} else {
if Some(*value) == self.current_max {
self.current_max = self.elements.iter().max().copied();
}
if Some(*value) == self.current_min {
self.current_min = self.elements.iter().min().copied();
}
}
}
true
}
}
pub trait SetOps {
fn contains(&self, value: &usize) -> bool;
fn iter(&self) -> Box<dyn Iterator<Item = &usize> + '_>;
fn max(&self) -> Option<usize>;
}
impl SetOps for Set {
fn contains(&self, value: &usize) -> bool {
self.contains(value)
}
fn iter(&self) -> Box<dyn Iterator<Item = &usize> + '_> {
Box::new(self.elements.iter())
}
fn max(&self) -> Option<usize> {
self.current_max
}
}
impl SetOps for HashSet<usize> {
fn contains(&self, value: &usize) -> bool {
HashSet::contains(self, value)
}
fn iter(&self) -> Box<dyn Iterator<Item = &usize> + '_> {
Box::new(self.iter())
}
fn max(&self) -> Option<usize> {
self.iter().max().copied()
}
}
impl Set {
#[inline(always)]
pub fn is_subset<T: SetOps>(&self, other: &T) -> bool {
self.elements.iter().all(|&value| other.contains(&value))
}
#[inline(always)]
pub fn is_superset<T: SetOps>(&self, other: &T) -> bool {
other.iter().all(|value| self.contains(value))
}
#[inline(always)]
pub fn is_disjoint<T: SetOps>(&self, other: &T) -> bool {
!self.iter().any(|&value| other.contains(&value))
}
#[inline(always)]
pub fn union<T: SetOps>(&self, other: &T) -> Self {
let max_other = other.max().unwrap_or(0);
let mut result = Set::with_max(std::cmp::max(self.max, max_other));
self.iter().chain(other.iter()).for_each(|&value| {
result.insert(value);
});
result
}
#[inline(always)]
pub fn intersection<T: SetOps>(&self, other: &T) -> Self {
let max_other = other.max().unwrap_or(0);
let mut result = Set::with_max(std::cmp::max(self.max, max_other));
self.elements
.iter()
.filter(|&&value| other.contains(&value))
.for_each(|&value| {
result.insert(value);
});
result
}
#[inline(always)]
pub fn difference<T: SetOps>(&self, other: &T) -> Self {
let max_other = other.max().unwrap_or(0);
let mut result = Set::with_max(std::cmp::max(self.max, max_other));
self.iter()
.filter(|&&value| !other.contains(&value))
.for_each(|&value| {
result.insert(value);
});
result
}
#[inline(always)]
pub fn symmetric_difference<T: SetOps>(&self, other: &T) -> Self {
let max_other = other.max().unwrap_or(0);
let mut result = Set::with_max(std::cmp::max(self.max, max_other));
self.iter()
.filter(|&&value| !other.contains(&value))
.chain(other.iter().filter(|&value| !self.contains(value)))
.for_each(|&value| {
result.insert(value);
});
result
}
}
impl<'a> std::ops::BitOr<&'a Set> for &'a Set {
type Output = Set;
fn bitor(self, rhs: &'a Set) -> Set {
self.union(rhs)
}
}
impl<'a> std::ops::BitOr<&'a HashSet<usize>> for &'a Set {
type Output = Set;
fn bitor(self, rhs: &'a HashSet<usize>) -> Set {
self.union(rhs)
}
}
impl std::ops::BitOr<&Set> for Set {
type Output = Set;
fn bitor(self, rhs: &Set) -> Set {
self.union(rhs)
}
}
impl std::ops::BitOr<&HashSet<usize>> for Set {
type Output = Set;
fn bitor(self, rhs: &HashSet<usize>) -> Set {
self.union(rhs)
}
}
impl<'a> std::ops::BitOr<Set> for &'a Set {
type Output = Set;
fn bitor(self, rhs: Set) -> Set {
self.union(&rhs)
}
}
impl<'a> std::ops::BitOr<HashSet<usize>> for &'a Set {
type Output = Set;
fn bitor(self, rhs: HashSet<usize>) -> Set {
self.union(&rhs)
}
}
impl std::ops::BitOr for Set {
type Output = Set;
fn bitor(self, rhs: Set) -> Set {
self.union(&rhs)
}
}
impl std::ops::BitOr<HashSet<usize>> for Set {
type Output = Set;
fn bitor(self, rhs: HashSet<usize>) -> Set {
self.union(&rhs)
}
}
impl<'a> std::ops::BitOrAssign<&'a Set> for Set {
fn bitor_assign(&mut self, rhs: &'a Set) {
*self = self.union(rhs);
}
}
impl<'a> std::ops::BitOrAssign<&'a HashSet<usize>> for Set {
fn bitor_assign(&mut self, rhs: &'a HashSet<usize>) {
*self = self.union(rhs);
}
}
impl<'a> std::ops::BitAnd<&'a Set> for &'a Set {
type Output = Set;
fn bitand(self, rhs: &'a Set) -> Set {
self.intersection(rhs)
}
}
impl<'a> std::ops::BitAnd<&'a HashSet<usize>> for &'a Set {
type Output = Set;
fn bitand(self, rhs: &'a HashSet<usize>) -> Set {
self.intersection(rhs)
}
}
impl std::ops::BitAnd<&Set> for Set {
type Output = Set;
fn bitand(self, rhs: &Set) -> Set {
self.intersection(rhs)
}
}
impl std::ops::BitAnd<&HashSet<usize>> for Set {
type Output = Set;
fn bitand(self, rhs: &HashSet<usize>) -> Set {
self.intersection(rhs)
}
}
impl<'a> std::ops::BitAnd<Set> for &'a Set {
type Output = Set;
fn bitand(self, rhs: Set) -> Set {
self.intersection(&rhs)
}
}
impl<'a> std::ops::BitAnd<HashSet<usize>> for &'a Set {
type Output = Set;
fn bitand(self, rhs: HashSet<usize>) -> Set {
self.intersection(&rhs)
}
}
impl std::ops::BitAnd for Set {
type Output = Set;
fn bitand(self, rhs: Set) -> Set {
self.intersection(&rhs)
}
}
impl std::ops::BitAnd<HashSet<usize>> for Set {
type Output = Set;
fn bitand(self, rhs: HashSet<usize>) -> Set {
self.intersection(&rhs)
}
}
impl<'a> std::ops::BitAndAssign<&'a Set> for Set {
fn bitand_assign(&mut self, rhs: &'a Set) {
*self = self.intersection(rhs);
}
}
impl<'a> std::ops::BitAndAssign<&'a HashSet<usize>> for Set {
fn bitand_assign(&mut self, rhs: &'a HashSet<usize>) {
*self = self.intersection(rhs);
}
}
impl<'a> std::ops::Sub<&'a Set> for &'a Set {
type Output = Set;
fn sub(self, rhs: &'a Set) -> Set {
self.difference(rhs)
}
}
impl<'a> std::ops::Sub<&'a HashSet<usize>> for &'a Set {
type Output = Set;
fn sub(self, rhs: &'a HashSet<usize>) -> Set {
self.difference(rhs)
}
}
impl std::ops::Sub<&Set> for Set {
type Output = Set;
fn sub(self, rhs: &Set) -> Set {
self.difference(rhs)
}
}
impl std::ops::Sub<&HashSet<usize>> for Set {
type Output = Set;
fn sub(self, rhs: &HashSet<usize>) -> Set {
self.difference(rhs)
}
}
impl<'a> std::ops::Sub<Set> for &'a Set {
type Output = Set;
fn sub(self, rhs: Set) -> Set {
self.difference(&rhs)
}
}
impl<'a> std::ops::Sub<HashSet<usize>> for &'a Set {
type Output = Set;
fn sub(self, rhs: HashSet<usize>) -> Set {
self.difference(&rhs)
}
}
impl std::ops::Sub for Set {
type Output = Set;
fn sub(self, rhs: Set) -> Set {
self.difference(&rhs)
}
}
impl std::ops::Sub<HashSet<usize>> for Set {
type Output = Set;
fn sub(self, rhs: HashSet<usize>) -> Set {
self.difference(&rhs)
}
}
impl<'a> std::ops::SubAssign<&'a Set> for Set {
fn sub_assign(&mut self, rhs: &'a Set) {
*self = self.difference(rhs);
}
}
impl<'a> std::ops::SubAssign<&'a HashSet<usize>> for Set {
fn sub_assign(&mut self, rhs: &'a HashSet<usize>) {
*self = self.difference(rhs);
}
}
impl std::ops::SubAssign<Set> for Set {
fn sub_assign(&mut self, rhs: Set) {
*self = self.difference(&rhs);
}
}
impl std::ops::SubAssign<HashSet<usize>> for Set {
fn sub_assign(&mut self, rhs: HashSet<usize>) {
*self = self.difference(&rhs);
}
}
impl<'a> std::ops::BitXor<&'a Set> for &'a Set {
type Output = Set;
fn bitxor(self, rhs: &'a Set) -> Set {
self.symmetric_difference(rhs)
}
}
impl<'a> std::ops::BitXor<&'a HashSet<usize>> for &'a Set {
type Output = Set;
fn bitxor(self, rhs: &'a HashSet<usize>) -> Set {
self.symmetric_difference(rhs)
}
}
impl std::ops::BitXor<&Set> for Set {
type Output = Set;
fn bitxor(self, rhs: &Set) -> Set {
self.symmetric_difference(rhs)
}
}
impl std::ops::BitXor<&HashSet<usize>> for Set {
type Output = Set;
fn bitxor(self, rhs: &HashSet<usize>) -> Set {
self.symmetric_difference(rhs)
}
}
impl<'a> std::ops::BitXor<Set> for &'a Set {
type Output = Set;
fn bitxor(self, rhs: Set) -> Set {
self.symmetric_difference(&rhs)
}
}
impl<'a> std::ops::BitXor<HashSet<usize>> for &'a Set {
type Output = Set;
fn bitxor(self, rhs: HashSet<usize>) -> Set {
self.symmetric_difference(&rhs)
}
}
impl std::ops::BitXor for Set {
type Output = Set;
fn bitxor(self, rhs: Set) -> Set {
self.symmetric_difference(&rhs)
}
}
impl std::ops::BitXor<HashSet<usize>> for Set {
type Output = Set;
fn bitxor(self, rhs: HashSet<usize>) -> Set {
self.symmetric_difference(&rhs)
}
}
impl<'a> std::ops::BitXorAssign<&'a Set> for Set {
fn bitxor_assign(&mut self, rhs: &'a Set) {
*self = self.symmetric_difference(rhs);
}
}
impl<'a> std::ops::BitXorAssign<&'a HashSet<usize>> for Set {
fn bitxor_assign(&mut self, rhs: &'a HashSet<usize>) {
*self = self.symmetric_difference(rhs);
}
}
impl std::fmt::Debug for Set {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let element_details: Vec<String> = self
.elements
.iter()
.map(|&e| {
let indicator = self.indicator[e]; let (page_idx, in_page_idx) = Self::page_indices(e);
let page = &self.pages[page_idx];
let mapped_index = page
.as_ref()
.map_or("None".to_string(), |p| p[in_page_idx].to_string());
format!(
"Element: {}, Indicator: {}, Mapped Index: {}",
e, indicator, mapped_index
)
})
.collect();
f.debug_struct("Set")
.field("elements", &self.elements) .field("element_details", &element_details) .field("max", &self.max) .field("current_max", &self.current_max)
.field("current_min", &self.current_min)
.finish()
}
}
impl std::fmt::Display for Set {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{{{}}}",
self.elements
.iter()
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join(", ")
)
}
}
impl Default for Set {
fn default() -> Self {
Self::with_max(64)
}
}
impl PartialEq for Set {
fn eq(&self, other: &Self) -> bool {
match self.elements.len() == other.elements.len() {
true => self.elements.iter().all(|&item| other.contains(&item)),
false => false,
}
}
}
impl Eq for Set {}
impl PartialEq<HashSet<usize>> for Set {
fn eq(&self, other: &HashSet<usize>) -> bool {
match self.len() == other.len() {
true => self.iter().all(|&item| other.contains(&item)),
false => false,
}
}
}
impl Hash for Set {
fn hash<H: Hasher>(&self, state: &mut H) {
for (idx, &bit) in self.indicator.iter().enumerate() {
if bit {
idx.hash(state);
}
}
}
}
impl From<Vec<usize>> for Set {
fn from(vec: Vec<usize>) -> Self {
let mut set = Set::with_max(vec.iter().max().cloned().unwrap_or(0));
vec.iter().for_each(|&item| {
set.insert(item);
});
set
}
}
impl<'a> From<&'a [usize]> for Set {
fn from(slice: &'a [usize]) -> Self {
let max_element = slice.iter().max().cloned().unwrap_or_default();
let mut set = Set::with_max(max_element);
slice.iter().for_each(|&item| {
set.insert(item);
});
set
}
}
impl<const N: usize> From<&[usize; N]> for Set {
fn from(array: &[usize; N]) -> Self {
let max_element = *array.iter().max().unwrap_or(&0);
let mut set = Set::with_max(max_element);
array.iter().for_each(|&item| {
set.insert(item);
});
set
}
}
impl From<HashSet<usize>> for Set {
fn from(hashset: HashSet<usize>) -> Self {
let mut set = Set::with_max(*hashset.iter().max().unwrap_or(&0));
hashset.iter().for_each(|&item| {
set.insert(item);
});
set
}
}
impl<'a> From<&'a HashSet<usize>> for Set {
fn from(hashset: &'a HashSet<usize>) -> Self {
let mut set = Set::with_max(*hashset.iter().max().unwrap_or(&0) + 1);
hashset.iter().for_each(|&item| {
set.insert(item);
});
set
}
}
impl Extend<usize> for Set {
fn extend<I: IntoIterator<Item = usize>>(&mut self, iter: I) {
iter.into_iter().for_each(|elem| {
self.insert(elem);
});
}
}
impl<'a> Extend<&'a usize> for Set {
fn extend<I: IntoIterator<Item = &'a usize>>(&mut self, iter: I) {
iter.into_iter().for_each(|&elem| {
self.insert(elem);
});
}
}
impl FromIterator<usize> for Set {
fn from_iter<I: IntoIterator<Item = usize>>(iter: I) -> Self {
let collected: Vec<usize> = iter.into_iter().collect();
let max_element = collected.iter().max().cloned().unwrap_or(0);
let mut set = Set::with_max(max_element);
collected.into_iter().for_each(|i| {
set.insert(i);
});
set
}
}
impl<'a> FromIterator<&'a usize> for Set {
fn from_iter<I: IntoIterator<Item = &'a usize>>(iter: I) -> Self {
let collected: Vec<usize> = iter.into_iter().cloned().collect();
let max_element = collected.iter().max().cloned().unwrap_or(0);
let mut set = Set::with_max(max_element);
collected.into_iter().for_each(|i| {
set.insert(i);
});
set
}
}
impl IntoIterator for Set {
type Item = usize;
type IntoIter = std::vec::IntoIter<usize>;
fn into_iter(self) -> Self::IntoIter {
self.elements.into_iter()
}
}
impl<'a> IntoIterator for &'a Set {
type Item = &'a usize;
type IntoIter = std::slice::Iter<'a, usize>;
fn into_iter(self) -> Self::IntoIter {
self.elements.iter()
}
}
impl<'a> IntoIterator for &'a mut Set {
type Item = &'a mut usize;
type IntoIter = std::slice::IterMut<'a, usize>;
fn into_iter(self) -> Self::IntoIter {
self.elements.iter_mut()
}
}
#[cfg(test)]
mod tests {
use super::*;
use statrs::distribution::{ChiSquared, ContinuousCDF};
use std::collections::hash_map::DefaultHasher;
#[test]
fn new_with_zero_max_element() {
let set = Set::with_max(0);
assert!(set.is_empty());
assert!(set.elements.is_empty());
assert!(!set.indicator.is_empty());
assert_eq!(set.max, 0);
}
#[test]
fn new_with_nonzero_max_element() {
let max_element = 10;
let set = Set::with_max(max_element);
assert_eq!(set.elements.len(), 0);
assert_eq!(set.len(), 0);
assert_eq!(set.max, max_element);
}
#[test]
fn new_with_large_max_element() {
let max_element = 1000000;
let set = Set::with_max(max_element);
assert_eq!(set.elements.len(), 0);
assert_eq!(set.max, max_element);
}
#[test]
fn new_with_multiple_calls() {
let set1 = Set::with_max(5);
let set2 = Set::with_max(10);
assert_eq!(set1.max, 5);
assert_eq!(set2.max, 10);
}
#[test]
fn with_capacity_zero() {
let set = Set::with_capacity(0);
assert_eq!(set.indicator.len(), 1);
assert!(set.elements.is_empty());
assert!(set.pages.is_empty());
assert_eq!(set.max, 0);
}
#[test]
fn with_capacity_nonzero() {
let capacity = 10;
let set = Set::with_capacity(capacity);
assert_eq!(set.elements.len(), 0);
assert_eq!(set.indicator.len(), capacity + 1);
assert_eq!(set.max, capacity);
}
#[test]
fn with_capacity_large() {
let capacity = 1000000;
let set = Set::with_capacity(capacity);
assert_eq!(set.elements.len(), 0);
assert_eq!(set.indicator.len(), capacity + 1);
assert_eq!(set.max, capacity);
}
#[test]
fn with_capacity_multiple_calls() {
let set1 = Set::with_capacity(5);
let set2 = Set::with_capacity(10);
assert_eq!(set1.max, 5);
assert_eq!(set2.max, 10);
}
#[test]
fn reserve_increase_capacity() {
let mut set = Set::with_max(5);
set.reserve(10);
assert_eq!(set.max, 10);
assert_eq!(set.indicator.len(), 11);
}
#[test]
fn reserve_no_increase_capacity() {
let mut set = Set::with_max(5);
set.reserve(3);
assert_eq!(set.max, 5);
assert_eq!(set.indicator.len(), 6);
}
#[test]
fn reserve_same_capacity() {
let mut set = Set::with_max(5);
set.reserve(5);
assert_eq!(set.max, 5);
assert_eq!(set.indicator.len(), 6);
}
#[test]
fn reserve_large_capacity() {
let mut set = Set::with_max(5);
set.reserve(100);
assert_eq!(set.max, 100);
assert_eq!(set.indicator.len(), 101);
}
#[test]
fn len_empty_set() {
let set = Set::with_max(5);
assert_eq!(set.len(), 0);
}
#[test]
fn len_non_empty_set() {
let mut set = Set::with_max(5);
set.insert(1);
set.insert(2);
set.insert(3);
assert_eq!(set.len(), 3);
}
#[test]
fn is_empty_empty_set() {
let set = Set::with_max(5);
assert!(set.is_empty());
}
#[test]
fn is_empty_non_empty_set() {
let mut set = Set::with_max(5);
set.insert(1);
assert!(!set.is_empty());
}
#[test]
fn iter_empty_set() {
let set = Set::with_max(5);
let mut iter = set.iter();
assert_eq!(iter.next(), None);
}
#[test]
fn iter_non_empty_set() {
let mut set = Set::with_max(5);
set.insert(1);
set.insert(2);
let mut iter = set.iter();
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
}
#[test]
fn clear() {
let mut set = Set::with_max(3);
set.insert(1);
set.insert(2);
set.insert(3);
set.clear();
assert!(set.is_empty());
for i in 1..=3 {
assert!(!set.contains(&i));
}
}
#[test]
fn clear_empty_set() {
let mut set = Set::with_max(5);
set.clear();
assert!(set.is_empty());
}
#[test]
fn clear_non_empty_set() {
let mut set = Set::with_max(5);
set.insert(1);
set.insert(2);
set.clear();
assert!(set.is_empty());
}
#[test]
fn insert() {
let mut set = Set::with_max(MAX_CAPACITY);
set.insert(1);
assert!(set.contains(&1), "Set should contain 1");
set.insert(1);
assert_eq!(
set.len(),
1,
"Inserting a duplicate should not increase set size"
);
set.insert(2);
set.insert(1000);
assert!(set.contains(&2), "Set should contain 2");
assert!(set.contains(&1000), "Set should contain 1000");
assert_eq!(set.len(), 3, "Set should contain 3 unique elements");
}
#[test]
fn insert_within_capacity() {
let mut set = Set::with_max(5);
assert!(set.insert(1));
assert!(set.contains(&1));
assert_eq!(set.len(), 1);
}
#[test]
fn insert_beyond_capacity_and_within_max() {
let mut set = Set::with_max(5);
assert!(set.insert(6));
assert!(set.contains(&6));
assert_eq!(set.len(), 1);
}
#[test]
#[should_panic]
fn insert_beyond_max_capacity() {
let mut set = Set::with_max(usize::MAX);
assert!(!set.insert(usize::MAX));
assert!(!set.contains(&usize::MAX));
assert_eq!(set.len(), 0);
}
#[test]
fn remove() {
let mut set = Set::with_max(MAX_CAPACITY / 3000);
set.insert(1);
set.insert(2);
set.insert(3);
set.insert(4);
set.remove(&3);
assert!(!set.contains(&3), "Set should not contain 3 after removal");
set.remove(&5);
assert!(
!set.contains(&5),
"Set should not contain 5 as it was never added"
);
assert!(set.contains(&1), "Set should still contain 1");
assert!(set.contains(&2), "Set should still contain 2");
assert!(set.contains(&4), "Set should still contain 4");
assert_eq!(set.len(), 3, "Set should contain 3 elements after removals");
set.remove(&1);
set.remove(&2);
set.remove(&4);
assert!(
set.is_empty(),
"Set should be empty after removing all elements"
);
}
#[test]
fn remove_existing_element() {
let mut set = Set::with_max(5);
set.insert(3);
assert!(set.remove(&3));
assert!(!set.contains(&3));
assert_eq!(set.len(), 0);
}
#[test]
fn remove_non_existing_element() {
let mut set = Set::with_max(5);
set.insert(3);
assert!(!set.remove(&5));
assert_eq!(set.len(), 1);
}
#[test]
fn remove_element_beyond_capacity() {
let mut set = Set::with_max(5);
set.insert(3);
assert!(!set.remove(&(usize::MAX)));
assert_eq!(set.len(), 1);
}
#[test]
fn contains() {
let mut set = Set::with_max(MAX_CAPACITY);
set.insert(1);
set.insert(2);
set.insert(3);
assert!(set.contains(&1), "Set should contain 1");
assert!(set.contains(&2), "Set should contain 2");
assert!(set.contains(&3), "Set should contain 3");
assert!(!set.contains(&4), "Set should not contain 4");
assert!(!set.contains(&0), "Set should not contain 0");
assert!(!set.contains(&100), "Set should not contain 100");
}
#[test]
fn contains_existing_element() {
let set = Set::from(vec![1, 2, 3]);
assert!(set.contains(&2));
}
#[test]
fn contains_non_existing_element() {
let set = Set::from(vec![1, 2, 3]);
assert!(!set.contains(&5));
}
#[test]
fn contains_element_beyond_capacity() {
let set = Set::with_max(5);
assert!(!set.contains(&(usize::MAX)));
}
#[test]
fn get_existing_element() {
let set = Set::from(vec![1, 2, 3]);
assert_eq!(set.get(&2), Some(2));
}
#[test]
fn get_non_existing_element() {
let set = Set::from(vec![1, 2, 3]);
assert_eq!(set.get(&5), None);
}
#[test]
fn get_element_beyond_capacity() {
let set = Set::with_max(5);
assert_eq!(set.get(&(usize::MAX)), None);
}
#[test]
fn take_existing_element() {
let mut set = Set::from(vec![1, 2, 3]);
assert_eq!(set.take(&2), Some(2));
assert!(!set.contains(&2));
}
#[test]
fn take_non_existing_element() {
let mut set = Set::from(vec![1, 2, 3]);
assert_eq!(set.take(&5), None);
assert_eq!(set.len(), 3);
}
#[test]
fn take_element_beyond_capacity() {
let mut set = Set::with_max(5);
assert_eq!(set.take(&(usize::MAX)), None);
}
#[test]
fn max_empty_set() {
let set = Set::with_max(5);
assert_eq!(set.max(), None);
}
#[test]
fn max_non_empty_set() {
let set = Set::from(vec![1, 2, 3]);
assert_eq!(set.max(), Some(3));
}
#[test]
fn max_set_with_single_element() {
let set = Set::from(vec![5]);
assert_eq!(set.max(), Some(5));
}
#[test]
fn min_empty_set() {
let set = Set::with_max(5);
assert_eq!(set.min(), None);
}
#[test]
fn min_non_empty_set() {
let set = Set::from(vec![3, 1, 5]);
assert_eq!(set.min(), Some(1));
}
#[test]
fn min_set_with_single_element() {
let set = Set::from(vec![5]);
assert_eq!(set.min(), Some(5));
}
#[test]
fn range_cardinality_empty_set() {
let set = Set::with_max(10);
assert_eq!(set.range_cardinality(..), 0);
assert_eq!(set.range_cardinality(0..5), 0);
}
#[test]
fn range_cardinality_full_set() {
let set = Set::from(vec![1, 2, 3, 4, 5]);
assert_eq!(set.range_cardinality(..), 5);
assert_eq!(set.range_cardinality(1..4), 3);
}
#[test]
fn range_cardinality_out_of_bounds() {
let set = Set::from(vec![1, 2, 3, 4, 5]);
assert_eq!(set.range_cardinality(6..10), 0);
}
#[test]
fn rank_empty_set() {
let set = Set::with_max(10);
assert_eq!(set.rank(5), 0);
}
#[test]
fn rank_non_empty_set() {
let set = Set::from(vec![1, 3, 5, 7, 9]);
assert_eq!(set.rank(5), 2);
}
#[test]
fn rank_non_existing_element() {
let set = Set::from(vec![1, 3, 5, 7, 9]);
assert_eq!(set.rank(6), 3);
}
#[test]
fn remove_largest_from_empty_set() {
let mut set = Set::with_max(10);
assert_eq!(set.remove_largest(), None);
}
#[test]
fn remove_largest_from_non_empty_set() {
let mut set = Set::from(vec![1, 3, 5, 7, 9]);
assert_eq!(set.remove_largest(), Some(9));
assert!(!set.contains(&9));
}
#[test]
fn remove_largest_from_unsorted_set() {
let mut set = Set::with_max(100);
set.insert(10);
set.insert(1);
set.insert(7);
assert_eq!(set.remove_largest(), Some(10));
assert!(!set.contains(&10));
}
#[test]
fn remove_smallest_from_empty_set() {
let mut set = Set::with_max(10);
assert_eq!(set.remove_smallest(), None);
}
#[test]
fn remove_smallest_from_non_empty_set() {
let mut set = Set::from(vec![1, 3, 5, 7, 9]);
assert_eq!(set.remove_smallest(), Some(1));
assert!(!set.contains(&1));
}
#[test]
fn remove_smallest_from_unsorted_set() {
let mut set = Set::with_max(100);
set.insert(10);
set.insert(1);
set.insert(7);
assert_eq!(set.remove_smallest(), Some(1));
assert!(!set.contains(&1));
}
#[test]
fn random() {
let mut set = Set::with_max(MAX_CAPACITY / 3000);
set.insert(1);
set.insert(2);
set.insert(3);
set.insert(4);
set.insert(5);
let mut observed_values = HashSet::new();
let mut rng = WyRand::new();
for _ in 0..100 {
if let Some(value) = set.random(&mut rng) {
assert!(
set.contains(&value),
"Randomly selected value should be in the set"
);
observed_values.insert(value);
}
}
assert!(
observed_values.len() > 1,
"Random should return different values over multiple calls"
);
set.clear();
assert!(
set.random(&mut rng).is_none(),
"Random should return None for an empty set"
);
}
#[test]
fn random_returns_none_for_empty_set() {
let set = Set::with_max(10);
let mut rng = WyRand::new();
assert_eq!(set.random(&mut rng), None);
}
#[test]
fn insert_unchecked_adds_element_correctly() {
let mut set = Set::with_max(5);
let result = set.insert_unchecked(3);
assert!(result);
assert_eq!(set.len(), 1);
assert!(set.contains(&3));
assert_eq!(set.current_max, Some(3));
assert_eq!(set.current_min, Some(3));
}
#[test]
fn remove_unchecked_removes_element_correctly() {
let mut set = Set::with_max(5);
set.insert(3);
let result = unsafe { set.remove_unchecked(&3) };
assert!(result);
assert_eq!(set.len(), 0);
assert!(!set.contains(&3));
assert_eq!(set.current_max, None);
assert_eq!(set.current_min, None);
}
#[test]
#[should_panic]
fn remove_unchecked_panics_for_out_of_bounds() {
let mut set = Set::with_max(5);
set.insert(3);
unsafe { assert!(!set.remove_unchecked(&6)) };
}
#[test]
fn contains_returns_true_for_existing_element() {
let mut set = Set::with_max(100);
set.insert(42);
assert!(set.contains(&42));
}
#[test]
fn contains_returns_false_for_nonexistent_element() {
let set = HashSet::<usize>::new();
assert!(!set.contains(&100));
}
#[test]
fn iter_returns_correct_values() {
let mut set = Set::with_max(2);
set.insert(42);
set.insert(100);
let mut iter = set.iter();
assert_eq!(iter.next(), Some(&42));
assert_eq!(iter.next(), Some(&100));
assert_eq!(iter.next(), None);
}
#[test]
fn max_returns_correct_value() {
let mut set = HashSet::new();
set.insert(42);
set.insert(100);
assert_eq!(set.max(), Some(100));
}
#[test]
fn max_returns_none_for_empty_set() {
let set = HashSet::new();
assert_eq!(set.max(), None);
}
#[test]
fn is_subset_returns_true_for_subset() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(1..=10);
assert!(set1.is_subset(&set2));
}
#[test]
fn is_subset_returns_false_for_non_subset() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(6..=10);
assert!(!set1.is_subset(&set2));
}
#[test]
fn is_superset_returns_true_for_superset() {
let set1 = Set::from_iter(1..=10);
let set2 = Set::from_iter(1..=5);
assert!(set1.is_superset(&set2));
}
#[test]
fn is_superset_returns_false_for_non_superset() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(6..=10);
assert!(!set1.is_superset(&set2));
}
#[test]
fn is_disjoint_returns_true_for_disjoint_sets() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(6..=10);
assert!(set1.is_disjoint(&set2));
}
#[test]
fn is_disjoint_returns_false_for_non_disjoint_sets() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=10);
assert!(!set1.is_disjoint(&set2));
}
#[test]
fn test_intersection() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let intersection = set1.intersection(&set2);
assert_eq!(intersection.len(), 2);
for i in 4..=5 {
assert!(intersection.contains(&i));
}
}
#[test]
fn test_difference() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let difference = set1.difference(&set2);
assert_eq!(difference.len(), 3);
for i in 1..=3 {
assert!(difference.contains(&i));
}
}
#[test]
fn test_symmetric_difference() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let symmetric_difference = set1.symmetric_difference(&set2);
assert_eq!(symmetric_difference.len(), 6);
for i in 1..=3 {
assert!(symmetric_difference.contains(&i));
}
for i in 6..=8 {
assert!(symmetric_difference.contains(&i));
}
}
#[test]
fn test_empty_set_operations() {
let set1 = Set::with_max(100);
let set2 = Set::with_max(100);
assert!(set1.union(&set2).is_empty());
assert!(set1.intersection(&set2).is_empty());
assert!(set1.difference(&set2).is_empty());
assert!(set1.symmetric_difference(&set2).is_empty());
}
#[test]
fn test_sets_with_same_elements() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(1..=5);
assert_eq!(set1.union(&set2), set1.intersection(&set2));
assert!(set1.difference(&set2).is_empty());
assert!(set1.symmetric_difference(&set2).is_empty());
}
#[test]
fn test_boundary_cases() {
let set1 = Set::with_max(10);
let set2 = Set::from_iter(1..=5);
assert!(set1.is_subset(&set2));
assert!(!set2.is_subset(&set1));
assert!(!set1.is_superset(&set2));
assert!(set2.is_superset(&set1));
assert!(set1.is_disjoint(&set2));
let set3 = Set::from_iter(1..=5);
let set4 = Set::from_iter(1..=10);
assert!(set3.is_subset(&set4));
assert!(!set4.is_subset(&set3));
assert!(!set3.is_superset(&set4));
assert!(set4.is_superset(&set3));
assert!(!set3.is_disjoint(&set4));
let set5 = Set::from_iter(1..=5);
let set6 = Set::from_iter(4..=8);
assert!(!set5.is_subset(&set6));
assert!(!set6.is_subset(&set5));
assert!(!set5.is_superset(&set6));
assert!(!set6.is_superset(&set5));
assert!(!set5.is_disjoint(&set6));
}
#[test]
fn test_bit_xor_sets() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let result = &set1 ^ &set2;
assert_eq!(result.len(), 6);
assert!(result.contains(&6));
assert!(result.contains(&7));
assert!(result.contains(&8));
}
#[test]
fn test_bit_xor_assignment_sets() {
let mut set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
set1 ^= &set2;
assert_eq!(set1.len(), 6);
assert!(set1.contains(&1));
assert!(set1.contains(&2));
assert!(set1.contains(&3));
assert!(!set1.contains(&4));
assert!(!set1.contains(&5));
assert!(set1.contains(&6));
assert!(set1.contains(&7));
assert!(set1.contains(&8));
}
#[test]
fn test_bit_xor_assignment_set_and_hashset() {
let mut set = Set::from_iter(1..=5);
let hash_set = (4..=8).collect::<HashSet<_>>();
set ^= &hash_set;
assert_eq!(set.len(), 6);
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(set.contains(&3));
assert!(set.contains(&6));
assert!(set.contains(&7));
assert!(set.contains(&8));
}
#[test]
fn test_sub_sets() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let result = &set1 - &set2;
assert_eq!(result.len(), 3);
assert!(result.contains(&1));
assert!(result.contains(&2));
assert!(result.contains(&3));
}
#[test]
fn test_sub_set_and_hashset() {
let set = Set::from_iter(1..=5);
let hash_set = (4..=8).collect::<HashSet<_>>();
let result = &set - &hash_set;
assert_eq!(result.len(), 3);
assert!(result.contains(&1));
assert!(result.contains(&2));
assert!(result.contains(&3));
assert!(!result.contains(&4));
}
#[test]
fn test_sub_assignment_sets() {
let mut set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
set1 -= &set2;
assert_eq!(set1.len(), 3);
assert!(set1.contains(&1));
assert!(set1.contains(&2));
assert!(set1.contains(&3));
}
#[test]
fn test_sub_assignment_set_and_hashset() {
let mut set = Set::from_iter(1..=5);
let hash_set = (4..=8).collect::<HashSet<_>>();
set -= &hash_set;
assert_eq!(set.len(), 3);
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(set.contains(&3));
}
#[test]
fn test_bitand_sets() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let result = &set1 & &set2;
assert_eq!(result.len(), 2);
assert!(result.contains(&4));
assert!(result.contains(&5));
}
#[test]
fn test_bitand_set_and_hashset() {
let set = Set::from_iter(1..=5);
let hash_set = (4..=8).collect::<HashSet<_>>();
let result = &set & &hash_set;
assert_eq!(result.len(), 2);
assert!(result.contains(&4));
assert!(result.contains(&5));
assert!(!result.contains(&3));
assert!(!result.contains(&7));
}
#[test]
fn test_bitand_assignment_sets() {
let mut set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
set1 &= &set2;
assert_eq!(set1.len(), 2);
assert!(set1.contains(&4));
assert!(set1.contains(&5));
}
#[test]
fn test_bitand_assignment_set_and_hashset() {
let mut set = Set::from_iter(1..=5);
let hash_set = (4..=8).collect::<HashSet<_>>();
set &= &hash_set;
assert_eq!(set.len(), 2);
assert!(set.contains(&4));
assert!(set.contains(&5));
let mut set2 = Set::from_iter(1..5);
let hash_set2 = (4..=8).collect::<HashSet<_>>();
set2 &= &hash_set2;
assert_eq!(set2.len(), 1);
assert!(set2.contains(&4));
assert!(!set2.contains(&5));
let mut set3 = Set::from_iter(1..5);
let hash_set3 = (6..=8).collect::<HashSet<_>>();
set3 &= &hash_set3;
assert_eq!(set3.len(), 0);
assert!(!set3.contains(&1));
}
#[test]
fn debug_format() {
let mut set = Set::with_max(5);
for i in 1..=5 {
set.insert(i); }
let debug_output = format!("{:?}", set);
assert!(debug_output.contains("Set {"));
assert!(debug_output.contains("elements: [1, 2, 3, 4, 5]"));
assert!(debug_output.contains("max: 5"));
assert!(debug_output.contains("current_max: Some(5)"));
assert!(debug_output.contains("current_min: Some(1)"));
assert!(debug_output.contains("Element: 1, Indicator: true, Mapped Index: 0"));
assert!(debug_output.contains("Element: 5, Indicator: true, Mapped Index: 4"));
}
#[test]
fn display_format() {
let set = Set::from_iter(1..=3);
let display_output = format!("{}", set);
assert!(display_output == "{1, 2, 3}" || display_output == "{3, 2, 1}");
}
#[test]
fn test_default() {
let set: Set = Default::default();
assert!(set.is_empty());
}
#[test]
fn test_partial_eq_sets_equal() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(1..=5);
assert_eq!(set1, set2);
}
#[test]
fn test_partial_eq_sets_not_equal() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(6..=10);
assert_ne!(set1, set2);
}
#[test]
fn test_eq_sets_equal() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter((1..=5).rev());
assert_eq!(set1, set2);
}
#[test]
fn test_eq_sets_not_equal() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(1..=4);
assert_ne!(set1, set2);
}
#[test]
fn test_partial_eq_with_hashset() {
let set = Set::from_iter(1..=5);
let hash_set: HashSet<usize> = (1..=5).collect();
assert_eq!(set, hash_set);
}
#[test]
fn test_hash() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(1..=5);
let mut hasher1 = DefaultHasher::new();
let mut hasher2 = DefaultHasher::new();
set1.hash(&mut hasher1);
set2.hash(&mut hasher2);
assert_eq!(hasher1.finish(), hasher2.finish());
}
#[test]
fn test_from_vec() {
let vec = vec![1, 2, 3, 4, 5];
let set = Set::from(vec.clone());
for item in vec {
assert!(set.contains(&item));
}
}
#[test]
fn test_from_slice() {
let items = &[1, 2, 3, 4, 5];
let set = Set::from(items);
for &item in items {
assert!(set.contains(&item));
}
}
#[test]
fn test_from_array() {
let items = &[1, 2, 3, 4, 5];
let set = Set::from(items);
for &item in items {
assert!(set.contains(&item));
}
}
#[test]
fn test_from_hashset_owned() {
let mut hash_set = HashSet::new();
hash_set.insert(1);
hash_set.insert(2);
hash_set.insert(3);
let set = Set::from(hash_set.clone());
for item in hash_set {
assert!(set.contains(&item));
}
}
#[test]
fn test_from_hashset_ref() {
let mut hash_set = HashSet::new();
hash_set.insert(1);
hash_set.insert(2);
hash_set.insert(3);
let set = Set::from(&hash_set);
for &item in &hash_set {
assert!(set.contains(&item));
}
}
#[test]
fn test_extend_usize() {
let mut set = Set::with_max(0);
set.extend(vec![1, 2, 3]);
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(set.contains(&3));
}
#[test]
fn test_extend_ref_usize() {
let mut set = Set::with_max(0);
let values = [1, 2, 3];
set.extend(values.iter());
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(set.contains(&3));
}
#[test]
fn test_from_iterator_usize() {
let set: Set = (1..=5).collect();
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(set.contains(&3));
assert!(set.contains(&4));
assert!(set.contains(&5));
}
#[test]
fn test_from_iterator_ref_usize() {
let values = [1, 2, 3];
let set: Set = values.iter().collect();
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(set.contains(&3));
}
#[test]
fn test_into_iter_owned() {
let set = Set::from(vec![1, 2, 3]);
let mut iter = set.into_iter();
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), None);
}
#[test]
fn test_into_iter_ref() {
let set = Set::from(vec![1, 2, 3]);
let mut values = Vec::new();
for &value in &set {
values.push(value);
}
assert_eq!(values, vec![1, 2, 3]);
}
#[test]
fn test_into_iter_mut_ref() {
let mut set = Set::from(vec![1, 2, 3]);
for value in &mut set {
*value += 1;
}
assert_eq!(set.elements, vec![2, 3, 4]);
}
#[test]
fn comparison() {
let mut set = Set::with_capacity(1_000_000);
let mut std_set = HashSet::new();
let mut rng = WyRand::new();
for iteration in 0..10000 {
let value = rng.generate_range(..100_000usize);
if rng.generate::<bool>() {
set.insert(value);
std_set.insert(value);
if rng.generate::<bool>() {
let more_values: Vec<usize> =
(0..10).map(|_| rng.generate_range(..1000usize)).collect();
for &val in more_values.iter() {
std_set.insert(val);
}
for &val in more_values.iter() {
set.insert(val);
}
}
} else {
set.remove(&value);
std_set.remove(&value);
if rng.generate::<bool>() {
let more_values: Vec<usize> =
(0..10).map(|_| rng.generate_range(..1000usize)).collect();
for &val in more_values.iter() {
std_set.remove(&val);
}
for &val in more_values.iter() {
set.remove(&val);
}
}
}
if iteration % 100 == 0 {
let diff = set.difference(&std_set);
if !diff.is_empty() {
println!("Differences at iteration {}: {:?}", iteration, diff);
}
assert!(
diff.is_empty(),
"Iteration {}: HashSet and StdHashSet differ: {:?}",
iteration,
diff
);
}
}
}
#[test]
fn test_max_element_reached() {
let max_element = MAX_CAPACITY / 3000 - 1; let set1 = Set::from_iter(0..max_element);
let set2 = Set::from_iter((max_element - 4)..=max_element);
let union = set1.union(&set2);
let intersection = set1.intersection(&set2);
let difference = set1.difference(&set2);
let symmetric_difference = set1.symmetric_difference(&set2);
assert_eq!(union.len(), MAX_CAPACITY / 3000); assert_eq!(intersection.len(), 4); assert_eq!(difference.len(), max_element - 4);
assert_eq!(symmetric_difference.len(), (max_element - 4) + 1);
}
#[test]
fn test_randomized_operations() {
let mut rng = WyRand::new();
let set1: Set = (0..100).map(|_| rng.generate_range(0..100)).collect();
let set2: Set = (0..150).map(|_| rng.generate_range(0..150)).collect();
let union = set1.union(&set2);
let intersection = set1.intersection(&set2);
let difference = set1.difference(&set2);
let symmetric_difference = set1.symmetric_difference(&set2);
for element in &union {
assert!(set1.contains(element) || set2.contains(element));
}
for element in &intersection {
assert!(set1.contains(element) && set2.contains(element));
}
for element in &difference {
assert!(set1.contains(element) && !set2.contains(element));
}
for element in &symmetric_difference {
assert!(set1.contains(element) != set2.contains(element));
}
}
#[test]
fn test_bit_or_sets() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let result = &set1 | &set2;
assert_eq!(result.len(), 8);
assert!(result.contains(&1));
assert!(result.contains(&2));
assert!(result.contains(&3));
assert!(result.contains(&4));
assert!(result.contains(&5));
assert!(result.contains(&6));
assert!(result.contains(&7));
assert!(result.contains(&8));
}
#[test]
fn test_bit_or_set_and_hashset() {
let set = Set::from_iter(1..=5);
let hash_set = (4..=8).collect::<HashSet<_>>();
let result = &set | &hash_set;
assert_eq!(result.len(), 8);
assert!(result.contains(&1));
assert!(result.contains(&2));
assert!(result.contains(&3));
assert!(result.contains(&4));
assert!(result.contains(&5));
assert!(result.contains(&6));
assert!(result.contains(&7));
assert!(result.contains(&8));
}
#[test]
fn test_bit_or_assignment_sets() {
let mut set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
set1 |= &set2;
assert_eq!(set1.len(), 8);
assert!(set1.contains(&1));
assert!(set1.contains(&2));
assert!(set1.contains(&3));
assert!(set1.contains(&4));
assert!(set1.contains(&5));
assert!(set1.contains(&6));
assert!(set1.contains(&7));
assert!(set1.contains(&8));
}
#[test]
fn test_bit_or_assignment_set_and_hashset() {
let mut set = Set::from_iter(1..=5);
let hash_set = (4..=8).collect::<HashSet<_>>();
set |= &hash_set;
assert_eq!(set.len(), 8);
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(set.contains(&3));
assert!(set.contains(&4));
assert!(set.contains(&5));
assert!(set.contains(&6));
assert!(set.contains(&7));
assert!(set.contains(&8));
}
#[test]
fn test_overlapping_ranges() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let union = set1.union(&set2);
let intersection = set1.intersection(&set2);
let difference = set1.difference(&set2);
let symmetric_difference = set1.symmetric_difference(&set2);
assert_eq!(union.len(), 8);
assert_eq!(intersection.len(), 2); assert_eq!(difference.len(), 3); assert_eq!(symmetric_difference.len(), 6); }
#[test]
fn test_nested_set_operations() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let set3 = Set::from_iter(6..=10);
let union = set1.union(&set2);
let nested_intersection = union.intersection(&set3);
assert_eq!(nested_intersection.len(), 3); }
#[test]
fn test_union() {
let set1 = Set::from_iter(1..=5);
let set2 = Set::from_iter(4..=8);
let union = set1.union(&set2);
assert_eq!(union.len(), 8);
for i in 1..=8 {
assert!(union.contains(&i));
}
}
#[test]
fn test_current_max_min_tracking() {
let mut set = Set::with_max(100);
assert_eq!(set.current_max, None);
assert_eq!(set.current_min, None);
set.insert(10);
assert_eq!(set.current_max, Some(10));
assert_eq!(set.current_min, Some(10));
set.insert(5);
assert_eq!(set.current_max, Some(10));
assert_eq!(set.current_min, Some(5));
set.insert(20);
assert_eq!(set.current_max, Some(20));
assert_eq!(set.current_min, Some(5));
set.remove(&20);
assert_eq!(set.current_max, Some(10));
assert_eq!(set.current_min, Some(5));
set.remove(&5);
assert_eq!(set.current_max, Some(10));
assert_eq!(set.current_min, Some(10));
set.remove(&10);
assert_eq!(set.current_max, None);
assert_eq!(set.current_min, None);
}
#[test]
fn test_remove_largest_smallest() {
let mut set = Set::with_max(100);
set.insert(30);
set.insert(10);
set.insert(50);
set.insert(20);
set.insert(40);
assert_eq!(set.current_max, Some(50));
assert_eq!(set.current_min, Some(10));
assert_eq!(set.remove_largest(), Some(50));
assert_eq!(set.current_max, Some(40));
assert_eq!(set.remove_smallest(), Some(10));
assert_eq!(set.current_min, Some(20));
}
#[test]
fn sampling_is_uniformly_at_random() {
const SAMPLES: usize = 1_000_000;
const EDGE_OF_THE_UNIVERSE: usize = 10000;
let elements = (1..=EDGE_OF_THE_UNIVERSE).collect::<Vec<_>>();
let set = Set::from(elements.clone());
let mut rng = WyRand::new_seed(42u64);
let mut counts = vec![0f64; elements.len()];
for _ in 0..SAMPLES {
if let Some(value) = set.random(&mut rng) {
counts[value - 1] += 1.0;
}
}
let e = SAMPLES as f64 / elements.len() as f64;
let statistic: f64 = counts.iter().map(|&o| (o - e) * (o - e) / e).sum();
let dof = elements.len() - 1;
let chi = ChiSquared::new(dof as f64).unwrap();
let acceptable = chi.inverse_cdf(0.99);
assert!(
statistic < acceptable,
"Chi-square statistic {} is greater than what's acceptable ({})",
statistic,
acceptable,
);
}
}