pijul nest
guest [sign in]

Tests

[?]
Feb 1, 2021, 9:33 AM
UAQX27N4PI4LHEW6LSHJETIE5MV7JTEMPLTJFYUBMYVPC43H7VOAC

Dependencies

Change contents

  • file addition: tests.rs (-xw-x--x--)
    [2.71008]
    use log::*;
    use std::collections::btree_map::Entry;
    use std::collections::BTreeMap;
    use sanakirja_core::btree;
    use sanakirja_core::btree::*;
    use sanakirja_core::*;
    use crate::environment::*;
    use crate::*;
    type B<T> = btree::page::Page<u64, A<T>>;
    #[derive(Eq, PartialEq, PartialOrd, Ord)]
    struct A<T>([u64; 100], std::marker::PhantomData<T>);
    impl<T> std::fmt::Debug for A<T> {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
    write!(fmt, "A(…)")?;
    Ok(())
    }
    }
    impl<T> Representable<T> for A<T> {
    type PageOffsets = core::iter::Empty<u64>;
    fn page_offsets(&self) -> Self::PageOffsets {
    core::iter::empty()
    }
    const ALIGN: usize = core::mem::align_of::<Self>();
    const SIZE: Option<usize> = Some(core::mem::size_of::<Self>());
    type Ord = [u64; 100];
    fn ord(&self, _: &T) -> &Self::Ord {
    &self.0
    }
    fn size(&self) -> usize {
    core::mem::size_of::<Self>()
    }
    }
    type T<'a> = MutTxn<&'a Env<Exclusive>, ()>;
    #[test]
    pub fn main() {
    env_logger::try_init().unwrap_or(());
    let env = Env::new_anon(409600000).unwrap();
    let mut txn = Env::mut_txn_begin(&env).unwrap();
    let mut db = create_db::<MutTxn<&Env<Exclusive>, ()>, u64, A<T>, B<T>>(&mut txn).unwrap();
    let n = 100_000u64;
    let m = 1000;
    let now = std::time::SystemTime::now();
    let mut values = Vec::with_capacity(n as usize);
    let i0 = 500;
    for i in 0..n {
    // debug!("put {:?} {:?} {:?}", i, (i*i)%m, i*i*i);
    if i != i0 && (i * i) % m == (i0 * i0) % m {
    continue;
    }
    let a = A([i * i * i; 100], std::marker::PhantomData);
    if put(&mut txn, &mut db, &((i * i) % m), &a).unwrap() {
    values.push((i * i) % m);
    } else {
    // debug!("not inserted");
    }
    }
    debug!("{:?}", now.elapsed());
    debug::debug(&txn, &db, "debug_final", true);
    values.sort();
    let mut curs = btree::cursor::Cursor::new(&db);
    let mut nn = 0;
    while let Some((k, _v)) = curs.next(&mut txn).unwrap() {
    // debug!("{:?} {:?} {:?}", k, values[nn], (v.0)[0]);
    assert_eq!(*k, values[nn]);
    nn += 1;
    }
    assert_eq!(nn, values.len());
    let db2 = fork_db(&mut txn, &db).unwrap();
    let a = A([0; 100], std::marker::PhantomData);
    put(&mut txn, &mut db, &(m/2), &a).unwrap();
    let mut curs = btree::cursor::Cursor::new(&db);
    let (k, v) = curs
    .set(&txn, Some((&((i0 * i0) % m), None)))
    .unwrap()
    .unwrap();
    assert_eq!((i0 * i0) % m, *k);
    assert_eq!(i0 * i0 * i0, (v.0)[0]);
    let mut curs = btree::cursor::Cursor::new(&db);
    let a = A([i0 * i0 * i0; 100], std::marker::PhantomData);
    let (k, v) = curs
    .set(&txn, Some((&((i0 * i0) % m), Some(&a))))
    .unwrap()
    .unwrap();
    assert_eq!((i0 * i0) % m, *k);
    assert_eq!(i0 * i0 * i0, (v.0)[0]);
    let mut curs = btree::cursor::Cursor::new(&db);
    let (k, _) = curs.set_last(&txn).unwrap().unwrap();
    assert_eq!(k, values.last().unwrap());
    /*
    println!("moi: {:?}", now.elapsed());
    let d = 10;
    for i in 0..d {
    debug!("deleting {:?}", (i*i)%1_000_000);
    debug::debug(&txn, &db, &format!("debug{}", i), true);
    del(&mut txn, &mut db, &((i * i) % 1_000_000), None).unwrap();
    }
    debug::debug(&txn, &db, "debug_final", true);
    txn.commit().unwrap();
    */
    /*
    let mut btree = std::collections::BTreeMap::new();
    let now = std::time::SystemTime::now();
    for i in 0..n {
    btree.insert(i * i, i * i * i);
    }
    println!("std: {:?}", now.elapsed());
    */
    /*
    std::mem::forget(txn);
    {
    let env = EnvBuilder::new()
    .map_size(1 << 27)
    .open("test-lmdb", 0o777)
    .unwrap();
    let db_handle = env.get_default_db(DbFlags::empty()).unwrap();
    let txn = env.new_transaction().unwrap();
    {
    let db = txn.bind(&db_handle); // get a database bound to this transaction
    let now = std::time::SystemTime::now();
    for i in 0..n {
    db.set(&(i * i), &(i * i * i)).unwrap();
    }
    println!("lmdb: {:?}", now.elapsed());
    }
    }
    */
    }
    #[test]
    pub fn u64_unit() {
    type B = btree::page::Page<u64, ()>;
    env_logger::try_init().unwrap_or(());
    let env = Env::new_anon(409600000).unwrap();
    let mut txn = Env::mut_txn_begin(&env).unwrap();
    let mut db: Db<_, u64, (), B> = create_db(&mut txn).unwrap();
    let n = 100_000 as u64;
    let now = std::time::SystemTime::now();
    for i in 0..n {
    put(&mut txn, &mut db, &((i * i) % 1_000), &()).unwrap();
    }
    println!("moi: {:?}", now.elapsed());
    let d = 10;
    for i in 0..d {
    // debug!("deleting {:?}", (i*i)%1_000_000);
    del(&mut txn, &mut db, &((i * i) % 1_000_000), None).unwrap();
    }
    txn.commit().unwrap();
    }
    #[test]
    pub fn last_cursor() {
    type B = btree::page::Page<u64, ()>;
    env_logger::try_init().unwrap_or(());
    let env = Env::new_anon(409600000).unwrap();
    let mut txn = Env::mut_txn_begin(&env).unwrap();
    let mut db: Db<_, u64, (), B> = create_db(&mut txn).unwrap();
    let n = 100_000 as u64;
    let m = 10_000;
    let now = std::time::SystemTime::now();
    let mut max = 0;
    for i in 0..n {
    put(&mut txn, &mut db, &((i * i) % m), &()).unwrap();
    max = max.max((i * i) % m);
    }
    let _db2 = fork_db(&mut txn, &db);
    debug!("{:?}", now.elapsed());
    let mut curs = btree::cursor::Cursor::new(&db);
    let (&nn, _) = curs.set_last(&txn).unwrap().unwrap();
    assert_eq!(max, nn)
    }
    #[test]
    pub fn fork() {
    type B = btree::page::Page<u64, ()>;
    env_logger::try_init().unwrap_or(());
    let env = Env::new_anon(409600000).unwrap();
    let mut txn = Env::mut_txn_begin(&env).unwrap();
    let mut db: Db<_, u64, (), B> = create_db(&mut txn).unwrap();
    let n = 1000 as u64;
    let now = std::time::SystemTime::now();
    let mut values = Vec::with_capacity(n as usize);
    for i in 0..n - 1 {
    if put(&mut txn, &mut db, &i, &()).unwrap() {
    values.push(i);
    }
    }
    debug!("{:?}", now.elapsed());
    let db2 = fork_db(&mut txn, &db).unwrap();
    debug::debug(&txn, &db2, "debug_just", true);
    let mut values2 = values.clone();
    values2.sort();
    for i in n - 1..n {
    if put(&mut txn, &mut db, &i, &()).unwrap() {
    values.push(i);
    }
    }
    values.sort();
    debug::debug(&txn, &db, "debug", true);
    debug::debug(&txn, &db2, "debug_forked", true);
    let mut curs = btree::cursor::Cursor::new(&db);
    let mut nn = 0;
    while let Some((k, _)) = curs.next(&mut txn).unwrap() {
    // debug!("{:?}", k);
    assert_eq!(*k, values[nn]);
    nn += 1;
    }
    let mut curs = btree::cursor::Cursor::new(&db);
    curs.set(&txn, Some((&500, Some(&())))).unwrap();
    assert_eq!(nn, values.len());
    let mut curs = btree::cursor::Cursor::new(&db2);
    let mut nn = 0;
    while let Some((k, _)) = curs.next(&mut txn).unwrap() {
    assert_eq!(*k, values2[nn]);
    nn += 1;
    }
    assert_eq!(nn, values2.len());
    let mut refs = BTreeMap::new();
    debug!("{:?} {:?}", db, db2);
    add_refs(&txn, &db, &mut refs).unwrap();
    add_refs(&txn, &db2, &mut refs).unwrap();
    txn.commit().unwrap();
    let mut txn = Env::mut_txn_begin(&env).unwrap();
    if txn.free.offset > 0 {
    let db_free = Db {
    db: txn.free,
    marker: std::marker::PhantomData,
    };
    let mut curs: btree::cursor::Cursor<T, _, _, B> = btree::cursor::Cursor::new(&db_free);
    debug!("{:?}", db_free);
    while let Some((k, _)) = curs.next(&mut txn).unwrap() {
    debug!("free: {:?}", k);
    }
    }
    debug!("{:?}", refs);
    }
    fn add_refs<T: LoadPage, K: Representable<T>, V: Representable<T>, P: BTreePage<T, K, V>>(
    txn: &T,
    db: &Db<T, K, V, P>,
    pages: &mut BTreeMap<u64, usize>,
    ) -> Result<(), T::Error> {
    let mut stack = vec![db.db];
    while let Some(p) = stack.pop() {
    match pages.entry(p.offset) {
    Entry::Vacant(e) => {
    e.insert(1);
    let mut c = P::first_cursor(p.as_page());
    let l = P::left_child(p.as_page(), &c);
    if l > 0 {
    stack.push(txn.load_page(l)?);
    while let Some((_, _, r)) = P::next(p.as_page(), &mut c) {
    stack.push(txn.load_page(r)?)
    }
    }
    }
    Entry::Occupied(mut e) => {
    e.insert(e.get() + 1);
    }
    }
    }
    Ok(())
    }