extern crate cask;
extern crate env_logger;
extern crate log;
extern crate rand;
extern crate time;
use std::env;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use env_logger::LogBuilder;
use rand::{Rng, SeedableRng, XorShiftRng};
use log::LogRecord;
use cask::CaskOptions;
fn init_logger() {
let format = |record: &LogRecord| {
let ts = time::strftime("%Y-%m-%d %H:%M:%S,%f", &time::now()).unwrap();
format!(
"{} {} {} {}",
&ts[..ts.len() - 6],
record.level(),
record.location().module_path(),
record.args()
)
};
let mut builder = LogBuilder::new();
builder.format(format);
if let Ok(s) = env::var("RUST_LOG") {
builder.parse(&s);
}
builder.init().unwrap();
}
fn main() {
init_logger();
let cask = CaskOptions::default()
.compaction_check_frequency(1)
.max_file_size(50 * 1024 * 1024)
.open("test.db")
.unwrap();
let seed = [1, 2, 3, 4];
const N_THREADS: usize = 8;
const WRITE_PROBABILITY: f64 = 0.1;
const DURATION_SECS: u64 = 10;
let base_value = rand::thread_rng().gen::<usize>();
let mut threads = Vec::new();
let mut txs = Vec::new();
for id in 1..N_THREADS + 1 {
let (tx, rx) = mpsc::channel();
let cask = cask.clone();
let vec = vec![1u8; 4096];
let mut rng: XorShiftRng = SeedableRng::from_seed(seed);
let t = thread::spawn(move || {
let mut i = 0;
loop {
if let Ok(_) = rx.try_recv() {
break;
}
let r = rng.next_f64();
if r < WRITE_PROBABILITY {
let key = (id * i).to_string();
cask.put(key, &vec).unwrap();
} else {
let key = ((base_value + (id * i)) * r as usize).to_string();
cask.get(key).unwrap();
}
i += 1
}
});
threads.push(t);
txs.push(tx);
}
thread::sleep(Duration::from_secs(DURATION_SECS));
for tx in txs {
tx.send(()).unwrap();
}
for thread in threads {
thread.join().unwrap();
}
}