use crate::{btreemap::Iter as IterMap, BTreeMap, Memory, Storable};
use core::ops::RangeBounds;
#[cfg(test)]
mod proptests;
pub struct Iter<'a, K, M>
where
K: Storable + Ord + Clone,
M: Memory,
{
iter_internal: IterMap<'a, K, (), M>,
}
impl<'a, K, M> Iter<'a, K, M>
where
K: Storable + Ord + Clone,
M: Memory,
{
fn new(iter: IterMap<'a, K, (), M>) -> Self {
Iter {
iter_internal: iter,
}
}
}
impl<K, M> Iterator for Iter<'_, K, M>
where
K: Storable + Ord + Clone,
M: Memory,
{
type Item = K;
fn next(&mut self) -> Option<Self::Item> {
self.iter_internal.next().map(|entry| entry.key().clone())
}
}
pub struct BTreeSet<K, M>
where
K: Storable + Ord + Clone,
M: Memory,
{
map: BTreeMap<K, (), M>,
}
impl<K, M> BTreeSet<K, M>
where
K: Storable + Ord + Clone,
M: Memory,
{
pub fn init(memory: M) -> Self {
BTreeSet {
map: BTreeMap::<K, (), M>::init(memory),
}
}
pub fn new(memory: M) -> Self {
BTreeSet {
map: BTreeMap::<K, (), M>::new(memory),
}
}
pub fn load(memory: M) -> Self {
BTreeSet {
map: BTreeMap::<K, (), M>::load(memory),
}
}
pub fn insert(&mut self, key: K) -> bool {
self.map.insert(key, ()).is_none()
}
pub fn contains(&self, key: &K) -> bool {
self.map.get(key).is_some()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn len(&self) -> u64 {
self.map.len()
}
pub fn into_memory(self) -> M {
self.map.into_memory()
}
pub fn clear(&mut self) {
self.map.clear_new();
}
pub fn first(&self) -> Option<K> {
self.map.first_key_value().map(|(a, _)| a)
}
pub fn last(&self) -> Option<K> {
self.map.last_key_value().map(|(a, _)| a)
}
pub fn remove(&mut self, key: &K) -> bool {
self.map.remove(key).is_some()
}
pub fn pop_last(&mut self) -> Option<K> {
self.map.pop_last().map(|(a, _)| a)
}
pub fn pop_first(&mut self) -> Option<K> {
self.map.pop_first().map(|(a, _)| a)
}
pub fn iter(&self) -> Iter<'_, K, M> {
Iter::new(self.map.iter())
}
pub fn range(&self, key_range: impl RangeBounds<K>) -> Iter<'_, K, M> {
Iter::new(self.map.range(key_range))
}
pub fn union<'a>(&'a self, other: &'a BTreeSet<K, M>) -> impl Iterator<Item = K> + 'a {
let mut iter_self = self.iter();
let mut iter_other = other.iter();
let mut next_self = iter_self.next();
let mut next_other = iter_other.next();
std::iter::from_fn(move || {
match (next_self.clone(), next_other.clone()) {
(Some(ref a), Some(ref b)) => match a.cmp(b) {
std::cmp::Ordering::Less => {
next_self = iter_self.next();
Some(a.clone())
}
std::cmp::Ordering::Greater => {
next_other = iter_other.next();
Some(b.clone())
}
std::cmp::Ordering::Equal => {
next_self = iter_self.next();
next_other = iter_other.next();
Some(a.clone())
}
},
(Some(ref a), None) => {
next_self = iter_self.next();
Some(a.clone())
}
(None, Some(ref b)) => {
next_other = iter_other.next();
Some(b.clone())
}
(None, None) => None,
}
})
}
pub fn intersection<'a>(&'a self, other: &'a BTreeSet<K, M>) -> impl Iterator<Item = K> + 'a {
let mut iter_self = self.iter();
let mut iter_other = other.iter();
let mut next_self = iter_self.next();
let mut next_other = iter_other.next();
std::iter::from_fn(move || {
while let (Some(ref a), Some(ref b)) = (next_self.clone(), next_other.clone()) {
match a.cmp(b) {
std::cmp::Ordering::Less => {
next_self = iter_self.next();
}
std::cmp::Ordering::Greater => {
next_other = iter_other.next();
}
std::cmp::Ordering::Equal => {
next_self = iter_self.next();
next_other = iter_other.next();
return Some(a.clone());
}
}
}
None
})
}
pub fn is_disjoint(&self, other: &BTreeSet<K, M>) -> bool {
let mut iter_self = self.iter();
let mut iter_other = other.iter();
let mut next_self = iter_self.next();
let mut next_other = iter_other.next();
while let (Some(a), Some(b)) = (next_self.as_ref(), next_other.as_ref()) {
match a.cmp(b) {
std::cmp::Ordering::Less => next_self = iter_self.next(),
std::cmp::Ordering::Greater => next_other = iter_other.next(),
std::cmp::Ordering::Equal => return false, }
}
true }
pub fn is_subset(&self, other: &BTreeSet<K, M>) -> bool {
let mut self_iter = self.iter();
let mut other_iter = other.iter();
let mut self_next = self_iter.next();
let mut other_next = other_iter.next();
while let Some(ref self_key) = self_next {
match other_next {
Some(ref other_key) => match self_key.cmp(other_key) {
std::cmp::Ordering::Equal => {
self_next = self_iter.next();
other_next = other_iter.next();
}
std::cmp::Ordering::Greater => {
other_next = other_iter.next();
}
std::cmp::Ordering::Less => {
return false;
}
},
None => {
return false;
}
}
}
true
}
pub fn is_superset(&self, other: &BTreeSet<K, M>) -> bool {
other.is_subset(self)
}
pub fn symmetric_difference<'a>(
&'a self,
other: &'a BTreeSet<K, M>,
) -> impl Iterator<Item = K> + 'a {
let mut iter_self = self.iter();
let mut iter_other = other.iter();
let mut next_self = iter_self.next();
let mut next_other = iter_other.next();
std::iter::from_fn(move || {
loop {
return match (next_self.clone(), next_other.clone()) {
(Some(ref a), Some(ref b)) => {
match a.cmp(b) {
std::cmp::Ordering::Less => {
next_self = iter_self.next();
Some(a.clone())
}
std::cmp::Ordering::Greater => {
next_other = iter_other.next();
Some(b.clone())
}
std::cmp::Ordering::Equal => {
next_self = iter_self.next();
next_other = iter_other.next();
continue;
}
}
}
(Some(ref a), None) => {
next_self = iter_self.next();
Some(a.clone())
}
(None, Some(ref b)) => {
next_other = iter_other.next();
Some(b.clone())
}
(None, None) => None,
};
}
})
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::storable::Blob;
use crate::VectorMemory;
use std::cell::RefCell;
use std::rc::Rc;
pub(crate) fn make_memory() -> Rc<RefCell<Vec<u8>>> {
Rc::new(RefCell::new(Vec::new()))
}
pub(crate) fn b(x: &[u8]) -> Blob<10> {
Blob::<10>::try_from(x).unwrap()
}
pub fn run_btree_test<K, R, F>(f: F)
where
K: Storable + Ord + Clone,
F: Fn(BTreeSet<K, VectorMemory>) -> R,
{
let mem = make_memory();
let btree = BTreeSet::new(mem);
f(btree);
}
#[test]
fn test_union_with_duplicates() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set1.insert(3);
set2.insert(2);
set2.insert(3);
set2.insert(4);
let union: Vec<_> = set1.union(&set2).collect();
assert_eq!(union, vec![1, 2, 3, 4]);
}
#[test]
fn test_intersection_with_duplicates() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set1.insert(3);
set2.insert(2);
set2.insert(3);
set2.insert(4);
let intersection: Vec<_> = set1.intersection(&set2).collect();
assert_eq!(intersection, vec![2, 3]);
}
#[test]
fn test_union_and_intersection_with_identical_sets() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..100 {
set1.insert(i);
set2.insert(i);
}
let union: Vec<_> = set1.union(&set2).collect();
assert_eq!(union.len(), 100);
assert_eq!(union, (0..100).collect::<Vec<_>>());
let intersection: Vec<_> = set1.intersection(&set2).collect();
assert_eq!(intersection.len(), 100);
assert_eq!(intersection, (0..100).collect::<Vec<_>>());
}
#[test]
fn test_union_and_intersection_with_disjoin_sets() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..50 {
set1.insert(i);
}
for i in 50..100 {
set2.insert(i);
}
let union: Vec<_> = set1.union(&set2).collect();
assert_eq!(union.len(), 100);
assert_eq!(union, (0..100).collect::<Vec<_>>());
let intersection: Vec<_> = set1.intersection(&set2).collect();
assert!(intersection.is_empty());
}
#[test]
fn test_union_with_large_sets() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
set1.insert(i);
}
for i in 500..1500 {
set2.insert(i);
}
let union: Vec<_> = set1.union(&set2).collect();
assert_eq!(union.len(), 1500);
assert_eq!(union[0], 0);
assert_eq!(union[1499], 1499);
}
#[test]
fn test_union_odd_even() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
if i % 2 != 0 {
set1.insert(i);
} else {
set2.insert(i);
}
}
let intersection: Vec<_> = set1.union(&set2).collect();
assert_eq!(intersection.len(), 1000);
assert_eq!(intersection, (0..1000).collect::<Vec<_>>());
}
#[test]
fn test_intersection_even() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
set1.insert(i);
if i % 2 == 0 {
set2.insert(i);
}
}
let intersection: Vec<_> = set1.intersection(&set2).collect();
assert_eq!(intersection.len(), 500);
assert_eq!(intersection, set2.iter().collect::<Vec<_>>());
}
#[test]
fn test_intersection_with_large_sets() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
set1.insert(i);
}
for i in 500..1500 {
set2.insert(i);
}
let intersection: Vec<_> = set1.intersection(&set2).collect();
assert_eq!(intersection.len(), 500);
assert_eq!(intersection[0], 500);
assert_eq!(intersection[499], 999);
}
#[test]
fn init_preserves_data_set() {
run_btree_test(|mut btree| {
assert!(btree.insert(b(&[1, 2, 3])));
assert!(btree.contains(&b(&[1, 2, 3])));
let btree = BTreeSet::init(btree.into_memory());
assert!(btree.contains(&b(&[1, 2, 3])));
});
}
#[test]
fn test_insert_and_contains() {
let mem = make_memory();
let mut btreeset = BTreeSet::new(mem);
assert!(!btreeset.contains(&1u32));
btreeset.insert(1u32);
assert!(btreeset.contains(&1u32));
}
#[test]
fn test_remove() {
let mem = make_memory();
let mut btreeset = BTreeSet::new(mem);
btreeset.insert(1u32);
assert!(btreeset.contains(&1u32));
btreeset.remove(&1u32);
assert!(!btreeset.contains(&1u32));
}
#[test]
fn test_iter() {
let mem = make_memory();
let mut btreeset = BTreeSet::new(mem);
btreeset.insert(1u32);
btreeset.insert(2u32);
btreeset.insert(3u32);
let elements: Vec<_> = btreeset.iter().collect();
assert_eq!(elements, vec![1u32, 2u32, 3u32]);
}
#[test]
fn test_range() {
let mem = make_memory();
let mut btreeset = BTreeSet::new(mem);
for i in 1u32..=10 {
btreeset.insert(i);
}
let range: Vec<_> = btreeset.range(4u32..8u32).collect();
assert_eq!(range, vec![4u32, 5u32, 6u32, 7u32]);
}
#[test]
fn test_first_and_last() {
let mem = make_memory();
let mut btreeset = BTreeSet::new(mem);
btreeset.insert(3u32);
btreeset.insert(1u32);
btreeset.insert(2u32);
assert_eq!(btreeset.first(), Some(1u32));
assert_eq!(btreeset.last(), Some(3u32));
}
#[test]
fn test_len_and_is_empty() {
let mem = make_memory();
let mut btreeset = BTreeSet::new(mem);
assert!(btreeset.is_empty());
assert_eq!(btreeset.len(), 0);
btreeset.insert(1u32);
assert!(!btreeset.is_empty());
assert_eq!(btreeset.len(), 1);
}
#[test]
fn test_pop_first_and_last() {
let mem = make_memory();
let mut btreeset = BTreeSet::new(mem);
btreeset.insert(3u32);
btreeset.insert(1u32);
btreeset.insert(2u32);
assert_eq!(btreeset.pop_first(), Some(1u32));
assert_eq!(btreeset.pop_last(), Some(3u32));
assert_eq!(btreeset.len(), 1);
assert_eq!(btreeset.first(), Some(2u32));
assert_eq!(btreeset.last(), Some(2u32));
}
#[test]
fn test_clear() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
btreeset.insert(1);
btreeset.insert(2);
btreeset.insert(3);
assert_eq!(btreeset.len(), 3);
btreeset.clear();
assert!(btreeset.is_empty());
assert_eq!(btreeset.len(), 0);
assert_eq!(btreeset.iter().next(), None);
}
#[test]
fn test_iterate_large_set() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
for i in 0..1000 {
btreeset.insert(i);
}
let elements: Vec<_> = btreeset.iter().collect();
assert_eq!(elements.len(), 1000);
assert_eq!(elements[0], 0);
assert_eq!(elements[999], 999);
}
#[test]
fn test_range_large_set() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
for i in 0u32..1000 {
btreeset.insert(i);
}
let range: Vec<_> = btreeset.range(100..200).collect();
assert_eq!(range.len(), 100);
assert_eq!(range[0], 100);
assert_eq!(range[99], 199);
}
#[test]
fn test_empty_set() {
let mem = make_memory();
let btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
assert!(btreeset.is_empty());
assert_eq!(btreeset.len(), 0);
assert_eq!(btreeset.first(), None);
assert_eq!(btreeset.last(), None);
assert_eq!(btreeset.iter().next(), None);
}
#[test]
fn test_insert_duplicate() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
assert!(btreeset.insert(42));
assert!(!btreeset.insert(42)); assert_eq!(btreeset.len(), 1);
assert!(btreeset.contains(&42));
}
#[test]
fn test_remove_nonexistent() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
assert!(!btreeset.remove(&42)); assert!(btreeset.is_empty());
}
#[test]
fn test_pop_first_and_last_empty() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
assert_eq!(btreeset.pop_first(), None);
assert_eq!(btreeset.pop_last(), None);
}
#[test]
fn test_range_empty() {
let mem = make_memory();
let btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
let range: Vec<_> = btreeset.range(10..20).collect();
assert!(range.is_empty());
}
#[test]
fn test_insert_and_remove_large_set() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
for i in 0..1_000 {
assert!(btreeset.insert(i));
}
assert_eq!(btreeset.len(), 1_000);
for i in 0..1_000 {
assert!(btreeset.remove(&i));
}
assert!(btreeset.is_empty());
}
#[test]
fn test_remove_nonexistent_large_set() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
for i in 0..1_000 {
assert!(btreeset.insert(i));
}
for i in 1_000..2_000 {
assert!(!btreeset.remove(&i)); }
assert_eq!(btreeset.len(), 1_000);
}
#[test]
fn test_iterate_empty_set() {
let mem = make_memory();
let btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
let elements: Vec<_> = btreeset.iter().collect();
assert!(elements.is_empty());
}
#[test]
fn test_range_with_no_matches() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
for i in 0..10 {
btreeset.insert(i);
}
let range: Vec<_> = btreeset.range(20..30).collect();
assert!(range.is_empty());
}
#[test]
fn test_clear_and_reuse() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
for i in 0..100 {
btreeset.insert(i);
}
assert_eq!(btreeset.len(), 100);
btreeset.clear();
assert!(btreeset.is_empty());
for i in 100..200 {
btreeset.insert(i);
}
assert_eq!(btreeset.len(), 100);
assert!(btreeset.contains(&150));
}
#[test]
fn test_pop_first_and_last_large_set() {
let mem = make_memory();
let mut btreeset: BTreeSet<u32, _> = BTreeSet::new(mem);
for i in 0..1_000 {
btreeset.insert(i);
}
for i in 0..500 {
assert_eq!(btreeset.pop_first(), Some(i));
}
for i in (500..1_000).rev() {
assert_eq!(btreeset.pop_last(), Some(i));
}
assert!(btreeset.is_empty());
}
#[test]
fn test_is_disjoint_with_disjoint_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set2.insert(3);
set2.insert(4);
assert!(set1.is_disjoint(&set2));
}
#[test]
fn test_is_disjoint_with_overlapping_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set2.insert(2);
set2.insert(3);
assert!(!set1.is_disjoint(&set2));
}
#[test]
fn test_is_disjoint_with_large_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
set1.insert(i);
}
for i in 1000..2000 {
set2.insert(i);
}
assert!(set1.is_disjoint(&set2));
set2.insert(500);
assert!(!set1.is_disjoint(&set2));
}
#[test]
fn test_is_subset_with_subset() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set2.insert(1);
set2.insert(2);
set2.insert(3);
assert!(set1.is_subset(&set2));
}
#[test]
fn test_is_subset_with_non_subset() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(4);
set2.insert(1);
set2.insert(2);
set2.insert(3);
assert!(!set1.is_subset(&set2));
}
#[test]
fn test_is_subset_with_large_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..500 {
set1.insert(i);
}
for i in 0..1500 {
set2.insert(i);
}
assert!(set1.is_subset(&set2));
set1.insert(1500);
assert!(!set1.is_subset(&set2));
}
#[test]
fn test_is_superset_with_superset() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set1.insert(3);
set2.insert(1);
set2.insert(2);
assert!(set1.is_superset(&set2));
}
#[test]
fn test_is_superset_with_non_superset() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set2.insert(1);
set2.insert(3);
assert!(!set1.is_superset(&set2));
}
#[test]
fn test_is_superset_with_large_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
set1.insert(i);
}
for i in 500..1000 {
set2.insert(i);
}
assert!(set1.is_superset(&set2));
set2.insert(1500);
assert!(!set1.is_superset(&set2));
}
#[test]
fn test_symmetric_difference_with_disjoint_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set2.insert(3);
set2.insert(4);
let symmetric_diff: Vec<_> = set1.symmetric_difference(&set2).collect();
assert_eq!(symmetric_diff, vec![1, 2, 3, 4]);
}
#[test]
fn test_symmetric_difference_with_overlapping_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set1.insert(3);
set2.insert(2);
set2.insert(3);
set2.insert(4);
let symmetric_diff: Vec<_> = set1.symmetric_difference(&set2).collect();
assert_eq!(symmetric_diff, vec![1, 4]);
}
#[test]
fn test_symmetric_difference_with_identical_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
set1.insert(1);
set1.insert(2);
set1.insert(3);
set2.insert(1);
set2.insert(2);
set2.insert(3);
let symmetric_diff: Vec<_> = set1.symmetric_difference(&set2).collect();
assert!(symmetric_diff.is_empty());
}
#[test]
fn test_symmetric_difference_with_large_sets() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
set1.insert(i);
}
for i in 500..1500 {
set2.insert(i);
}
let symmetric_diff: Vec<_> = set1.symmetric_difference(&set2).collect();
assert_eq!(symmetric_diff.len(), 1000);
assert_eq!(symmetric_diff[..500], (0..500).collect::<Vec<_>>());
assert_eq!(symmetric_diff[500..], (1000..1500).collect::<Vec<_>>());
}
#[test]
fn test_symmetric_difference_odd_even() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in 0..1000 {
if i % 2 != 0 {
set1.insert(i);
} else {
set2.insert(i);
}
}
let intersection: Vec<_> = set1.symmetric_difference(&set2).collect();
assert_eq!(intersection.len(), 1000);
assert_eq!(intersection, (0..1000).collect::<Vec<_>>());
}
#[test]
fn test_symmetric_difference_even() {
let mem1 = Rc::new(RefCell::new(Vec::new()));
let mem2 = Rc::new(RefCell::new(Vec::new()));
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
let mut expected_res = vec![];
for i in 0..1000 {
set1.insert(i);
if i % 2 == 0 {
set2.insert(i);
} else {
expected_res.push(i);
}
}
let intersection: Vec<_> = set1.symmetric_difference(&set2).collect();
assert_eq!(intersection.len(), 500);
assert_eq!(intersection, expected_res);
}
#[test]
fn test_is_subset_with_sparse_elements() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in (0..1000).step_by(10) {
set1.insert(i);
}
for i in (0..2000).step_by(5) {
set2.insert(i);
}
assert!(set1.is_subset(&set2));
set1.insert(2001);
assert!(!set1.is_subset(&set2));
}
#[test]
fn test_is_disjoint_with_sparse_elements() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in (0..1000).step_by(10) {
set1.insert(i);
}
for i in (1..1000).step_by(10) {
set2.insert(i);
}
assert!(set1.is_disjoint(&set2));
set2.insert(20);
assert!(!set1.is_disjoint(&set2));
}
#[test]
fn test_is_superset_with_sparse_elements() {
let mem1 = make_memory();
let mem2 = make_memory();
let mut set1: BTreeSet<u32, _> = BTreeSet::new(mem1);
let mut set2: BTreeSet<u32, _> = BTreeSet::new(mem2);
for i in (0..2000).step_by(5) {
set1.insert(i);
}
for i in (0..1000).step_by(10) {
set2.insert(i);
}
assert!(set1.is_superset(&set2));
set2.insert(2001);
assert!(!set1.is_superset(&set2));
}
}