#![forbid(unsafe_code)]
use std::vec::Vec;
use crate::inline_key::Auto;
use crate::tree::node::page::TestPages;
use crate::tree::test_support::TestRng;
use crate::unsync::map::{BBTreeMap, Entry};
type Key = [u64; 8];
fn key(number: u64) -> Key {
[number; 8]
}
type MapIn<'p> = BBTreeMap<Key, u64, Auto, &'p TestPages<Key, u64>>;
fn map_in<'p>(pages: &'p TestPages<Key, u64>, numbers: &[u64]) -> MapIn<'p> {
let mut map = BBTreeMap::new_in(pages);
for &number in numbers {
assert_eq!(map.insert(key(number), number), None);
}
map
}
#[test]
fn every_page_comes_from_and_goes_back_to_the_map_allocator() {
let count = if cfg!(miri) { 200 } else { 2000 };
let mut numbers: Vec<u64> = (0..count).collect();
TestRng::new(21).shuffle(&mut numbers);
let pages = TestPages::<Key, u64>::new();
{
let mut map = map_in(&pages, &numbers);
assert!(map.leaf_depth() >= 2);
for number in &numbers[..numbers.len() / 3] {
assert_eq!(map.remove(&key(*number)), Some(*number));
}
map.pop_first();
map.pop_last();
let Entry::Vacant(vacant) = map.entry(key(count)) else {
panic!("a key past the others is vacant");
};
vacant.insert(count);
map.last_entry().expect("the map has entries").remove();
let mut upper = map.split_off(&key(count / 2));
let copy = upper.clone();
map.append(&mut upper);
let extracted: Vec<(Key, u64)> = map.extract_if(.., |key, _| key[0] % 2 == 1).collect();
assert!(!extracted.is_empty());
map.retain(|key, _| key[0] % 3 != 0);
map.check_invariants();
let mut rest = copy.into_iter();
rest.next();
rest.next_back();
drop(rest);
assert!(pages.in_use_count() > 0);
map.clear();
map.insert(key(1), 1);
}
pages.assert_all_released();
}
#[test]
fn append_keeps_each_page_with_its_own_allocator() {
let count = if cfg!(miri) { 100 } else { 1000 };
let (evens, odds): (Vec<u64>, Vec<u64>) = (0..count).partition(|number| number % 2 == 0);
let (ours, theirs) = (TestPages::<Key, u64>::new(), TestPages::<Key, u64>::new());
{
let mut target = map_in(&ours, &evens);
let mut other = map_in(&theirs, &odds);
target.append(&mut other);
assert_eq!(target.len(), usize::try_from(count).unwrap());
target.check_invariants();
other.insert(key(count), count);
let mut empty = BBTreeMap::new_in(&theirs);
empty.append(&mut target);
assert!(target.is_empty());
target.insert(key(count), count);
}
ours.assert_all_released();
theirs.assert_all_released();
}