use std::ops::Bound;
use std::time::{SystemTime, UNIX_EPOCH};
use rand::prelude::random;
use rand::{rngs::SmallRng, SeedableRng};
use crate::error::Error;
use crate::llrb::Llrb;
#[test]
fn test_id() {
let llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
assert_eq!(llrb.id(), "test-llrb".to_string());
}
#[test]
fn test_len() {
let llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
assert_eq!(llrb.len(), 0);
}
#[test]
fn test_stats() {
let llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let stats = llrb.stats();
assert_eq!(stats.node_size(), 40);
let llrb: Llrb<Vec<u8>, Vec<u8>> = Llrb::new("test-llrb");
let stats = llrb.stats();
assert_eq!(stats.node_size(), 72);
}
#[test]
fn test_create() {
let mut llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let mut refns = RefNodes::new(10);
assert!(llrb.create(2, 10).is_ok());
refns.create(2, 10);
assert!(llrb.create(1, 10).is_ok());
refns.create(1, 10);
assert!(llrb.create(3, 10).is_ok());
refns.create(3, 10);
assert!(llrb.create(6, 10).is_ok());
refns.create(6, 10);
assert!(llrb.create(5, 10).is_ok());
refns.create(5, 10);
assert!(llrb.create(4, 10).is_ok());
refns.create(4, 10);
assert!(llrb.create(8, 10).is_ok());
refns.create(8, 10);
assert!(llrb.create(0, 10).is_ok());
refns.create(0, 10);
assert!(llrb.create(9, 10).is_ok());
refns.create(9, 10);
assert!(llrb.create(7, 10).is_ok());
refns.create(7, 10);
assert_eq!(llrb.len(), 10);
assert!(llrb.validate().is_ok());
assert_eq!(llrb.create(7, 20), Err(Error::OverwriteKey));
for i in 0..10 {
let val = llrb.get(&i);
let refval = refns.get(i);
assert_eq!(val, refval);
}
let (mut iter, mut iter_ref) = (llrb.iter(), refns.iter());
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(_, _) => panic!("invalid"),
}
}
}
#[test]
fn test_set() {
let mut llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let mut refns = RefNodes::new(10);
assert!(llrb.set(2, 10).is_none());
refns.set(2, 10);
assert!(llrb.set(1, 10).is_none());
refns.set(1, 10);
assert!(llrb.set(3, 10).is_none());
refns.set(3, 10);
assert!(llrb.set(6, 10).is_none());
refns.set(6, 10);
assert!(llrb.set(5, 10).is_none());
refns.set(5, 10);
assert!(llrb.set(4, 10).is_none());
refns.set(4, 10);
assert!(llrb.set(8, 10).is_none());
refns.set(8, 10);
assert!(llrb.set(0, 10).is_none());
refns.set(0, 10);
assert!(llrb.set(9, 10).is_none());
refns.set(9, 10);
assert!(llrb.set(7, 10).is_none());
refns.set(7, 10);
assert_eq!(llrb.len(), 10);
assert!(llrb.validate().is_ok());
for i in 0..10 {
let val = llrb.get(&i);
let refval = refns.get(i);
assert_eq!(val, refval);
}
let (mut iter, mut iter_ref) = (llrb.iter(), refns.iter());
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(_, _) => panic!("invalid"),
}
}
}
#[test]
fn test_delete() {
let mut llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let mut refns = RefNodes::new(11);
assert!(llrb.set(2, 100).is_none());
refns.set(2, 100);
assert!(llrb.set(1, 100).is_none());
refns.set(1, 100);
assert!(llrb.set(3, 100).is_none());
refns.set(3, 100);
assert!(llrb.set(6, 100).is_none());
refns.set(6, 100);
assert!(llrb.set(5, 100).is_none());
refns.set(5, 100);
assert!(llrb.set(4, 100).is_none());
refns.set(4, 100);
assert!(llrb.set(8, 100).is_none());
refns.set(8, 100);
assert!(llrb.set(0, 100).is_none());
refns.set(0, 100);
assert!(llrb.set(9, 100).is_none());
refns.set(9, 100);
assert!(llrb.set(7, 100).is_none());
refns.set(7, 100);
assert!(llrb.delete(&10).is_none());
assert!(refns.delete(10).is_none());
assert_eq!(llrb.len(), 10);
assert!(llrb.validate().is_ok());
{
let (mut iter, mut iter_ref) = (llrb.iter(), refns.iter());
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(_, _) => panic!("invalid"),
}
}
}
for i in 0..10 {
let val = llrb.delete(&i);
let refval = refns.delete(i);
assert_eq!(val, refval);
}
assert_eq!(llrb.len(), 0);
assert!(llrb.validate().is_ok());
assert!(llrb.iter().next().is_none());
}
#[test]
fn test_random() {
let mut llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let mut rng = SmallRng::from_seed(make_seed().to_le_bytes());
assert_eq!(llrb.random(&mut rng), None);
assert!(llrb.create(0, 0).is_ok());
assert_eq!(llrb.random(&mut rng), Some((0, 0)));
assert_eq!(llrb.random(&mut rng), Some((0, 0)));
for key in 1..1_000_000 {
assert!(llrb.set(key, key * 10).is_none());
}
for _i in 0..2_000_000 {
let (key, value) = llrb.random(&mut rng).unwrap();
assert!(key >= 0 && key < 1_000_000);
assert_eq!(value, key * 10);
}
}
#[test]
fn test_iter() {
let mut llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let mut refns = RefNodes::new(10);
assert!(llrb.create(2, 10).is_ok());
refns.create(2, 10);
assert!(llrb.create(1, 10).is_ok());
refns.create(1, 10);
assert!(llrb.create(3, 10).is_ok());
refns.create(3, 10);
assert!(llrb.create(6, 10).is_ok());
refns.create(6, 10);
assert!(llrb.create(5, 10).is_ok());
refns.create(5, 10);
assert!(llrb.create(4, 10).is_ok());
refns.create(4, 10);
assert!(llrb.create(8, 10).is_ok());
refns.create(8, 10);
assert!(llrb.create(0, 10).is_ok());
refns.create(0, 10);
assert!(llrb.create(9, 10).is_ok());
refns.create(9, 10);
assert!(llrb.create(7, 10).is_ok());
refns.create(7, 10);
assert_eq!(llrb.len(), 10);
assert!(llrb.validate().is_ok());
let (mut iter, mut iter_ref) = (llrb.iter(), refns.iter());
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(_, _) => panic!("invalid"),
}
}
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
}
#[test]
fn test_range() {
let mut llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let mut refns = RefNodes::new(10);
assert!(llrb.create(2, 10).is_ok());
refns.create(2, 10);
assert!(llrb.create(1, 10).is_ok());
refns.create(1, 10);
assert!(llrb.create(3, 10).is_ok());
refns.create(3, 10);
assert!(llrb.create(6, 10).is_ok());
refns.create(6, 10);
assert!(llrb.create(5, 10).is_ok());
refns.create(5, 10);
assert!(llrb.create(4, 10).is_ok());
refns.create(4, 10);
assert!(llrb.create(8, 10).is_ok());
refns.create(8, 10);
assert!(llrb.create(0, 10).is_ok());
refns.create(0, 10);
assert!(llrb.create(9, 10).is_ok());
refns.create(9, 10);
assert!(llrb.create(7, 10).is_ok());
refns.create(7, 10);
assert_eq!(llrb.len(), 10);
assert!(llrb.validate().is_ok());
for _ in 0..1_000 {
let (low, high) = random_low_high(llrb.len());
let mut iter = llrb.range((low, high));
let mut iter_ref = refns.range(low, high);
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(Some(item), None) => panic!("invalid item: {:?}", item),
(None, Some(ref_item)) => panic!("invalid none: {:?}", ref_item),
}
}
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
let mut iter = llrb.reverse((low, high));
let mut iter_ref = refns.reverse(low, high);
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(_, _) => panic!("invalid"),
}
}
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
}
}
#[test]
fn test_crud() {
let size = 1000;
let mut llrb: Llrb<i64, i64> = Llrb::new("test-llrb");
let mut refns = RefNodes::new(size);
for _ in 0..100_000 {
let key: i64 = (random::<i64>() % (size as i64)).abs();
let value: i64 = random();
let op: i64 = (random::<i64>() % 4).abs();
match op {
0 => {
let ok1 = llrb.get(&key).is_none();
let ok2 = llrb.create(key, value).is_ok();
refns.create(key, value);
assert_eq!(ok1, ok2);
false
}
1 => {
let val = llrb.set(key, value);
let refval = refns.set(key, value);
assert_eq!(val, refval);
false
}
2 => {
let val = llrb.delete(&key);
let refval = refns.delete(key);
assert_eq!(val, refval);
true
}
3 => {
let val = llrb.get(&key);
let refval = refns.get(key);
assert_eq!(val, refval);
true
}
op => panic!("unreachable {}", op),
};
assert!(llrb.validate().is_ok());
}
println!("index-length {}", llrb.len());
let (mut iter, mut iter_ref) = (llrb.iter(), refns.iter());
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(_, _) => panic!("invalid"),
}
}
for _ in 0..10_000 {
let (low, high) = random_low_high(size);
let mut iter = llrb.range((low, high));
let mut iter_ref = refns.range(low, high);
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(Some(item), None) => panic!("invalid item: {:?}", item),
(None, Some(ref_item)) => panic!("invalid none: {:?}", ref_item),
}
}
let mut iter = llrb.reverse((low, high));
let mut iter_ref = refns.reverse(low, high);
loop {
match (iter.next(), iter_ref.next()) {
(Some(item), Some(ref_item)) => {
assert_eq!(item.0, ref_item.0);
assert_eq!(item.1, ref_item.1);
}
(None, None) => break,
(_, _) => panic!("invalid"),
}
}
}
}
fn make_seed() -> u128 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos()
}
include!("./ref_test.rs");