#![cfg(any(feature = "alloc", feature = "allocator-api", feature = "nightly"))]
#![cfg_attr(feature = "nightly", feature(allocator_api))]
mod helpers;
use std::iter::repeat_with;
use augmented_rbtree::{AugmentedRBTree, AugmentedRBTreeFactory, SubtreeSize, SumAugmentation};
use itertools::Itertools;
use rand::{RngExt, seq::SliceRandom};
use crate::helpers::common::test_rng;
#[test]
fn check_iter() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut rng = test_rng();
let keys: Vec<i32> = repeat_with(|| rng.random_range(1..100))
.unique()
.take(10)
.collect();
for &key in &keys {
tree.insert(key, key);
}
for (key, value, _stats) in &tree {
assert!(keys.contains(key));
assert_eq!(tree.get(key), Some(value));
}
for (key, value, _stats) in tree.iter().rev() {
assert!(keys.contains(key));
assert_eq!(tree.get(key), Some(value));
}
assert_eq!(tree.iter().len(), keys.len());
let arr = tree.iter().collect::<Vec<_>>();
assert_eq!(arr.len(), keys.len());
}
#[test]
fn check_iter_mut() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut rng = test_rng();
let keys: Vec<i32> = repeat_with(|| rng.random_range(1..100))
.unique()
.take(10)
.collect();
for &key in &keys {
tree.insert(key, key);
}
for mut guard in &mut tree {
assert!(keys.contains(guard.key()));
*guard.value_mut() += 1000; }
for mut value in tree.values_mut().rev() {
assert!(*value > 1000);
*value -= 1000;
}
assert_eq!(tree.values_mut().len(), keys.len());
for &key in &keys {
assert_eq!(tree.get(&key), Some(&key));
}
}
#[test]
fn check_iter_mut_no_change() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
tree.insert(10, 10);
tree.insert(20, 20);
let keys_copied: Vec<i32> = tree
.iter_mut()
.map(|guard| *guard.key() + *guard.value())
.collect();
assert_eq!(keys_copied, vec![20, 40]);
}
#[test]
fn check_iter_mut_change_value() {
let mut tree = AugmentedRBTreeFactory::<SubtreeSize>::new_tree();
tree.insert(10, "A".to_string());
tree.insert(20, "B".to_string());
let _keys: Vec<i32> = tree
.iter_mut()
.map(|mut guard| {
let key = *guard.key();
let value = guard.as_mut();
let new_value = format!("{}-{}", *value, key);
*value = new_value;
key
})
.collect();
let values = tree.iter().map(|(_, value, _stats)| value).collect_vec();
assert_eq!(values, vec!["A-10", "B-20"]);
}
#[test]
fn check_iter_mut_collect() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut rng = test_rng();
let keys: Vec<i32> = repeat_with(|| rng.random_range(1..100))
.unique()
.take(10)
.collect();
for &key in &keys {
tree.insert(key, key);
}
let arr = tree.iter_mut().collect::<Vec<_>>();
assert_eq!(arr.len(), keys.len());
}
#[test]
fn check_valmut_explicit_reborrow() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let keys = vec![10, 20, 30];
for &key in &keys {
tree.insert(key, key);
}
for mut guard in &mut tree {
*guard.value_mut() += 2;
}
for &key in &keys {
assert_eq!(tree.get(&key).copied(), Some(key + 2));
}
}
#[test]
fn check_back_field_isolated() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
tree.insert(10, 100);
tree.insert(20, 200);
let mut iter = tree.iter_mut();
assert_eq!(iter.len(), 2);
let node_guard = iter.next_back().unwrap();
assert_eq!(*node_guard.key(), 20);
assert_eq!(iter.len(), 1);
let node_guard = iter.next().unwrap();
assert_eq!(*node_guard.key(), 10);
assert_eq!(iter.len(), 0);
assert!(iter.next_back().is_none());
assert!(iter.next().is_none());
}
#[test]
fn check_into_iter() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut rng = test_rng();
let keys: Vec<i32> = repeat_with(|| rng.random_range(1..1000))
.unique()
.take(200)
.collect();
for &key in &keys {
tree.insert(key, key);
}
let cloned_tree_for_lookup = tree.clone();
for (key, value) in tree {
assert!(keys.contains(&key));
assert_eq!(cloned_tree_for_lookup.get(&key), Some(&value));
}
}
#[test]
fn check_into_iter_partial_drop() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut rng = test_rng();
let keys: Vec<i32> = repeat_with(|| rng.random_range(1..100))
.unique()
.take(10)
.collect();
for &key in &keys {
tree.insert(key, key);
}
let cloned_tree_for_lookup = tree.clone();
let mut count = 0;
for (key, value) in tree {
assert!(keys.contains(&key));
assert_eq!(cloned_tree_for_lookup.get(&key), Some(&value));
count += 1;
if count == 3 {
break;
}
}
}
mod range_tests {
use core::ops::Bound;
use augmented_rbtree::{AugmentedRBTree, SubtreeSize};
fn setup_test_tree() -> AugmentedRBTree<i32, String, SubtreeSize> {
let mut tree = AugmentedRBTree::new();
tree.insert(20, "twenty".to_string());
tree.insert(10, "ten".to_string());
tree.insert(30, "thirty".to_string());
tree.insert(15, "fifteen".to_string());
tree.insert(25, "twenty-five".to_string());
tree
}
#[test]
fn test_bounds_unbounded_to_unbounded() {
let tree = setup_test_tree();
let range = tree.range(..);
let items: Vec<&i32> = range.map(|(k, _, _)| k).collect();
assert_eq!(items, vec![&10, &15, &20, &25, &30]);
}
#[test]
fn test_bounds_included_to_included() {
let tree = setup_test_tree();
let range = tree.range(10..=25);
let items: Vec<&i32> = range.map(|(k, _, _)| k).collect();
assert_eq!(items, vec![&10, &15, &20, &25]);
}
#[test]
fn test_bounds_excluded_to_excluded() {
let tree = setup_test_tree();
let range = tree.range((Bound::Excluded(10), Bound::Excluded(25)));
let items: Vec<&i32> = range.map(|(k, _, _)| k).collect();
assert_eq!(items, vec![&15, &20]);
}
#[test]
fn test_bounds_excluded_missing_keys() {
let tree = setup_test_tree();
let range = tree.range((Bound::Excluded(12), Bound::Excluded(27)));
let items: Vec<&i32> = range.map(|(k, _, _)| k).collect();
assert_eq!(items, vec![&15, &20, &25]);
}
#[test]
#[allow(clippy::reversed_empty_ranges)]
fn test_bounds_exhausted_inverted_range() {
let tree = setup_test_tree();
let mut range = tree.range(30..=10);
assert!(range.next().is_none());
assert!(range.next_back().is_none());
}
#[test]
fn test_bounds_exhausted_out_of_tree_range() {
let tree = setup_test_tree();
let mut range = tree.range(50..100);
assert!(range.next().is_none());
}
#[test]
fn test_range_bidirectional_meeting_in_middle() {
let tree = setup_test_tree();
let mut range = tree.range(10..=30);
let f1 = range.next().unwrap();
assert_eq!(f1.0, &10);
let b1 = range.next_back().unwrap();
assert_eq!(b1.0, &30);
let f2 = range.next().unwrap();
assert_eq!(f2.0, &15);
let b2 = range.next_back().unwrap();
assert_eq!(b2.0, &25);
let f3 = range.next().unwrap();
assert_eq!(f3.0, &20);
assert!(range.next().is_none());
assert!(range.next_back().is_none());
}
#[test]
fn test_range_back_exhaustion_first() {
let tree = setup_test_tree();
let mut range = tree.range(15..=20);
assert_eq!(range.next_back().unwrap().0, &20); assert_eq!(range.next_back().unwrap().0, &15); assert!(range.next_back().is_none());
assert!(range.next().is_none());
}
#[test]
fn test_range_mut_forward_and_backward() {
let mut tree = setup_test_tree();
{
let mut range_mut = tree.range_mut(15..=25);
if let Some(mut node_guard) = range_mut.next() {
assert_eq!(node_guard.key(), &15);
node_guard.value_mut().push_str("_mut1");
}
if let Some(mut node_guard) = range_mut.next_back() {
assert_eq!(node_guard.key(), &25);
node_guard.value_mut().push_str("_mut2");
}
if let Some(mut node_guard) = range_mut.next() {
assert_eq!(node_guard.key(), &20);
node_guard.value_mut().push_str("_mut3");
}
assert!(range_mut.next().is_none());
assert!(range_mut.next_back().is_none());
}
assert_eq!(tree.get(&15).unwrap(), "fifteen_mut1");
assert_eq!(tree.get(&20).unwrap(), "twenty_mut3");
assert_eq!(tree.get(&25).unwrap(), "twenty-five_mut2");
}
}
mod into_iter_tests {
use augmented_rbtree::{AugmentedRBTree, SubtreeSize};
fn setup_tree() -> AugmentedRBTree<i32, String, SubtreeSize> {
let mut tree = AugmentedRBTree::new();
tree.insert(30, "thirty".to_string());
tree.insert(10, "ten".to_string());
tree.insert(20, "twenty".to_string());
tree.insert(40, "forty".to_string());
tree
}
#[test]
fn test_into_iter_double_ended() {
let tree = setup_tree();
let mut into_iter = tree.into_iter();
let front1 = into_iter.next().unwrap();
assert_eq!(front1.0, 10);
assert_eq!(front1.1, "ten");
let back1 = into_iter.next_back().unwrap();
assert_eq!(back1.0, 40);
assert_eq!(back1.1, "forty");
let back2 = into_iter.next_back().unwrap();
assert_eq!(back2.0, 30);
assert_eq!(back2.1, "thirty");
let front2 = into_iter.next().unwrap();
assert_eq!(front2.0, 20);
assert_eq!(front2.1, "twenty");
assert!(into_iter.next().is_none());
assert!(into_iter.next_back().is_none());
}
#[test]
fn test_into_iter_partial_iteration_drop() {
let tree = setup_tree();
let mut into_iter = tree.into_iter();
assert_eq!(into_iter.next().unwrap().0, 10);
assert_eq!(into_iter.next_back().unwrap().0, 40);
core::mem::drop(into_iter);
}
#[test]
fn test_into_iter_pointers_meet() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
tree.insert(10, 10);
tree.insert(20, 20);
tree.insert(30, 30);
let mut into_iter = tree.into_iter();
let first = into_iter.next();
assert_eq!(first.map(|(k, _)| k), Some(10));
let last = into_iter.next_back();
assert_eq!(last.map(|(k, _)| k), Some(30));
let middle = into_iter.next_back();
assert_eq!(middle.map(|(k, _)| k), Some(20));
assert_eq!(into_iter.len(), 0);
assert!(into_iter.next().is_none());
assert!(into_iter.next_back().is_none());
}
}
#[test]
fn check_into_iter_collect() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut rng = test_rng();
let keys: Vec<i32> = repeat_with(|| rng.random_range(1..100))
.unique()
.take(10)
.collect();
for &key in &keys {
tree.insert(key, key);
}
let arr = tree.into_iter().collect::<Vec<_>>();
assert_eq!(arr.len(), keys.len());
}
#[test]
fn check_values_iterator() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut rng = test_rng();
let keys: Vec<i32> = repeat_with(|| rng.random_range(1..100))
.unique()
.take(10)
.collect();
for &key in &keys {
tree.insert(key, key);
}
for value in tree.values() {
assert!(keys.contains(value));
}
}
#[test]
fn test_keys_double_ended_and_exact_size() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
tree.insert(10, 100);
tree.insert(20, 200);
tree.insert(30, 300);
let mut keys_iter = tree.keys();
assert_eq!(keys_iter.len(), 3);
assert_eq!(keys_iter.next_back(), Some(&30));
assert_eq!(keys_iter.len(), 2);
assert_eq!(keys_iter.next(), Some(&10));
assert_eq!(keys_iter.len(), 1);
assert_eq!(keys_iter.next_back(), Some(&20));
assert_eq!(keys_iter.len(), 0);
assert_eq!(keys_iter.next_back(), None);
assert_eq!(keys_iter.len(), 0);
}
#[test]
fn test_value_double_ended_and_exact_size() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
tree.insert(10, 100);
tree.insert(20, 200);
tree.insert(30, 300);
let mut values_iter = tree.values();
assert_eq!(values_iter.len(), 3);
assert_eq!(values_iter.next_back(), Some(&300));
assert_eq!(values_iter.len(), 2);
assert_eq!(values_iter.next(), Some(&100));
assert_eq!(values_iter.len(), 1);
assert_eq!(values_iter.next_back(), Some(&200));
assert_eq!(values_iter.len(), 0);
assert_eq!(values_iter.next_back(), None);
assert_eq!(values_iter.len(), 0);
}
#[test]
fn test_values_mut_all_traits() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
tree.insert(10, 100);
tree.insert(20, 200);
tree.insert(30, 300);
let mut values_mut_iter = tree.values_mut();
assert_eq!(values_mut_iter.len(), 3);
assert_eq!(values_mut_iter.size_hint(), (3, Some(3)));
if let Some(mut val_mut) = values_mut_iter.next_back() {
*val_mut = 350;
} else {
panic!("Expected a value from next_back");
}
assert_eq!(values_mut_iter.len(), 2);
assert_eq!(values_mut_iter.size_hint(), (2, Some(2)));
if let Some(mut val_mut) = values_mut_iter.next() {
*val_mut = 150;
} else {
panic!("Expected a value from next");
}
assert!(values_mut_iter.next().is_some());
assert_eq!(values_mut_iter.len(), 0);
assert!(values_mut_iter.next().is_none());
assert!(values_mut_iter.next_back().is_none());
assert!(values_mut_iter.next().is_none());
let final_values: Vec<_> = tree.values().collect();
assert_eq!(final_values, vec![&150, &200, &350]);
}
#[test]
fn test_stats_iterator_all_traits() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
tree.insert(10, 100);
tree.insert(20, 200);
tree.insert(30, 300);
let mut stats_iter = tree.stats();
assert_eq!(stats_iter.len(), 3);
assert_eq!(stats_iter.size_hint(), (3, Some(3)));
let last_stats = stats_iter.next_back();
assert!(last_stats.is_some());
assert_eq!(stats_iter.len(), 2);
assert_eq!(stats_iter.size_hint(), (2, Some(2)));
let first_stats = stats_iter.next();
assert!(first_stats.is_some());
assert!(stats_iter.next().is_some());
assert_eq!(stats_iter.len(), 0);
assert!(stats_iter.next().is_none());
assert!(stats_iter.next_back().is_none());
assert!(stats_iter.next().is_none());
}
#[test]
fn check_node_guard_deref_mut() {
let mut tree = AugmentedRBTree::<i32, i32, SumAugmentation>::new();
let mut keys = (1..=100).collect::<Vec<i32>>();
let mut rng = test_rng();
keys.shuffle(&mut rng);
for &key in &keys {
tree.insert(key, key);
}
assert_eq!(tree.root_stats(), Some(&5050));
for mut guard in &mut tree {
*guard *= 2;
}
assert_eq!(tree.root_stats(), Some(&(5050 * 2)));
assert!(tree.iter().all(|(key, value, _)| *value == *key * 2));
}
#[test]
fn check_node_guard_deref() {
let mut tree = AugmentedRBTree::<i32, i32, SumAugmentation>::new();
let mut keys = (1..=100).collect::<Vec<i32>>();
let mut rng = test_rng();
keys.shuffle(&mut rng);
for &key in &keys {
tree.insert(key, key);
}
assert!(tree.iter_mut().all(|node_guard| {
let key = *node_guard.key();
let value = *node_guard;
value == key
}));
}
#[test]
fn check_node_guard_stats() {
let mut tree = AugmentedRBTree::<i32, i32, SubtreeSize>::new();
let mut keys = (1..=100).collect::<Vec<i32>>();
let mut rng = test_rng();
keys.shuffle(&mut rng);
for &key in &keys {
tree.insert(key, key);
}
let max_count = tree.iter_mut().map(|node_guard| *node_guard.stats()).max();
assert_eq!(max_count, Some(100));
}