use cpp_map::linkedlist::LinkedList;
use cpp_map::prelude::*;
use rand::{Rng, SeedableRng, rngs::StdRng};
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::fmt;
use std::fmt::Debug;
#[cfg(test)]
#[allow(dead_code)]
pub fn skp_create_test_data(
insert_count: usize,
remove_count: usize,
seed_add: u64,
) -> (SkipList<i32, String>, BTreeMap<i32, String>) {
let mut rng = StdRng::seed_from_u64(4 + seed_add); let mut skiplist = SkipList::<i32, String>::default();
let mut btreemap = BTreeMap::new();
let mut inserted_keys = Vec::new();
let mut remove_count = remove_count;
for _ in 0..insert_count {
let key = rng.random_range(0..1000);
let value = format!("value_{key}");
let _ = skiplist.insert(key, value.clone());
btreemap.entry(key).or_insert(value);
if rng.random_bool(0.01) {
remove_count -= 1;
skiplist.remove(&key);
btreemap.remove(&key);
}
inserted_keys.push(key);
}
for _ in 0..remove_count.min(inserted_keys.len()) {
let idx = rng.random_range(0..inserted_keys.len());
let key = inserted_keys.remove(idx);
skiplist.remove(&key);
btreemap.remove(&key);
}
let mut iter1 = skiplist.iter();
let mut iter2 = btreemap.iter();
loop {
match (iter1.next(), iter2.next()) {
(Some(x), Some(y)) => assert_eq!(x.0, y.0),
(None, None) => break,
_ => panic!(),
}
}
(skiplist, btreemap)
}
#[cfg(test)]
#[allow(dead_code)]
pub fn llt_create_test_data(
insert_count: usize,
remove_count: usize,
seed_add: u64,
) -> (LinkedList<i32, String>, BTreeMap<i32, String>) {
let mut rng = StdRng::seed_from_u64(4 + seed_add); let mut linkedlist = LinkedList::<i32, String>::default();
let mut btreemap = BTreeMap::new();
let mut inserted_keys = Vec::new();
let mut remove_count = remove_count;
for _ in 0..insert_count {
let key = rng.random_range(0..1000);
let value = format!("value_{key}");
let _ = linkedlist.insert(key, value.clone());
btreemap.entry(key).or_insert(value);
if rng.random_bool(0.01) {
remove_count -= 1;
linkedlist.remove(&key);
btreemap.remove(&key);
}
inserted_keys.push(key);
}
for _ in 0..remove_count.min(inserted_keys.len()) {
let idx = rng.random_range(0..inserted_keys.len());
let key = inserted_keys.remove(idx);
linkedlist.remove(&key);
btreemap.remove(&key);
}
let mut iter1 = linkedlist.iter();
let mut iter2 = btreemap.iter();
loop {
match (iter1.next(), iter2.next()) {
(Some(x), Some(y)) => assert_eq!(x.0, y.0),
(None, None) => break,
_ => panic!(),
}
}
(linkedlist, btreemap)
}
#[cfg(test)]
#[allow(dead_code)]
pub fn skp_test_head_and_tail_is_some<K, V>(list: &SkipList<K, V>)
where
K: Debug + Ord + Clone + IsLessThan,
V: Debug + Clone,
{
assert!(list.first().is_some());
assert!(list.last().is_some());
}
#[cfg(test)]
#[allow(dead_code)]
pub fn skp_test_head_and_tail_is_none<K, V>(list: &SkipList<K, V>)
where
K: Debug + Ord + Clone + IsLessThan,
V: Debug + Clone,
{
assert!(list.first().is_none());
assert!(list.last().is_none());
}
#[cfg(test)]
#[allow(dead_code)]
pub fn llt_test_head_and_tail_is_some<K, V>(list: &LinkedList<K, V>)
where
K: Debug + Ord + Clone + IsLessThan,
V: Debug + Clone,
{
assert!(list.first().is_some());
assert!(list.last().is_some());
}
#[cfg(test)]
#[allow(dead_code)]
pub fn llt_test_head_and_tail_is_none<K, V>(list: &LinkedList<K, V>)
where
K: Debug + Ord + Clone + IsLessThan,
V: Debug + Clone,
{
assert!(list.first().is_none());
assert!(list.last().is_none());
}
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq)]
pub struct RoundedTen(pub i32);
impl Ord for RoundedTen {
fn cmp(&self, other: &Self) -> Ordering {
(self.0 / 10).cmp(&(other.0 / 10))
}
}
impl PartialOrd for RoundedTen {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl fmt::Display for RoundedTen {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl PartialEq for RoundedTen {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl IsLessThan for RoundedTen {
fn is_less_than(&self, other: &Self) -> bool {
self < other
}
}