use grin_core as core;
use grin_store as store;
use grin_util as util;
use crate::core::global;
use crate::core::ser::{self, Readable, Reader, Writeable, Writer};
use std::fs;
const WRITE_CHUNK_SIZE: usize = 20;
const TEST_ALLOC_SIZE: usize = store::lmdb::ALLOC_CHUNK_SIZE_DEFAULT / 8 / WRITE_CHUNK_SIZE;
#[derive(Clone)]
struct PhatChunkStruct {
phatness: u64,
}
impl PhatChunkStruct {
pub fn new() -> PhatChunkStruct {
PhatChunkStruct { phatness: 0 }
}
}
impl Readable for PhatChunkStruct {
fn read<R: Reader>(reader: &mut R) -> Result<PhatChunkStruct, ser::Error> {
let mut retval = PhatChunkStruct::new();
for _ in 0..TEST_ALLOC_SIZE {
retval.phatness = reader.read_u64()?;
}
Ok(retval)
}
}
impl Writeable for PhatChunkStruct {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
for _ in 0..TEST_ALLOC_SIZE {
writer.write_u64(self.phatness)?;
}
Ok(())
}
}
fn clean_output_dir(test_dir: &str) {
let _ = fs::remove_dir_all(test_dir);
}
fn setup(test_dir: &str) {
global::set_local_chain_type(global::ChainTypes::Mainnet);
util::init_test_logger();
clean_output_dir(test_dir);
}
#[test]
fn test_exists() -> Result<(), store::Error> {
let test_dir = "target/test_exists";
setup(test_dir);
let store = store::Store::new(test_dir, Some("test1"), None, None)?;
let key = [0, 0, 0, 1];
let value = [1, 1, 1, 1];
let batch = store.batch()?;
batch.put(&key, &value)?;
assert!(batch.exists(&key)?);
assert!(!store.exists(&key)?);
batch.commit()?;
assert!(store.exists(&key)?);
clean_output_dir(test_dir);
Ok(())
}
#[test]
fn test_iter() -> Result<(), store::Error> {
let test_dir = "target/test_iter";
setup(test_dir);
let store = store::Store::new(test_dir, Some("test1"), None, None)?;
let key = [0, 0, 0, 1];
let value = [1, 1, 1, 1];
let batch = store.batch()?;
batch.put(&key, &value)?;
let mut iter = store.iter(&[0], |_, v| Ok(v.to_vec()))?;
assert_eq!(iter.next(), None);
batch.commit()?;
let mut iter = store.iter(&[0], |_, v| Ok(v.to_vec()))?;
assert_eq!(iter.next(), Some(value.to_vec()));
assert_eq!(iter.next(), None);
clean_output_dir(test_dir);
Ok(())
}
#[test]
fn lmdb_allocate() -> Result<(), store::Error> {
let test_dir = "target/lmdb_allocate";
setup(test_dir);
{
let store = store::Store::new(test_dir, Some("test1"), None, None)?;
for i in 0..WRITE_CHUNK_SIZE * 2 {
println!("Allocating chunk: {}", i);
let chunk = PhatChunkStruct::new();
let key_val = format!("phat_chunk_set_1_{}", i);
let batch = store.batch()?;
let key = store::to_key(b'P', &key_val);
batch.put_ser(&key, &chunk)?;
batch.commit()?;
}
}
println!("***********************************");
println!("***************NEXT*****************");
println!("***********************************");
{
let store = store::Store::new(test_dir, Some("test1"), None, None)?;
for i in 0..WRITE_CHUNK_SIZE * 2 {
println!("Allocating chunk: {}", i);
let chunk = PhatChunkStruct::new();
let key_val = format!("phat_chunk_set_2_{}", i);
let batch = store.batch()?;
let key = store::to_key(b'P', &key_val);
batch.put_ser(&key, &chunk)?;
batch.commit()?;
}
}
Ok(())
}