use std::collections::HashMap;
use std::sync::Arc;
use node_replication::Dispatch;
use node_replication::Log;
use node_replication::Replica;
#[derive(Default)]
struct NrHashMap {
storage: HashMap<u64, u64>,
}
#[derive(Clone, Debug, PartialEq)]
enum Modify {
Put(u64, u64),
}
#[derive(Clone, Debug, PartialEq)]
enum Access {
Get(u64),
}
impl Dispatch for NrHashMap {
type ReadOperation = Access;
type WriteOperation = Modify;
type Response = Option<u64>;
fn dispatch(&self, op: Self::ReadOperation) -> Self::Response {
match op {
Access::Get(key) => self.storage.get(&key).map(|v| *v),
}
}
fn dispatch_mut(&mut self, op: Self::WriteOperation) -> Self::Response {
match op {
Modify::Put(key, value) => self.storage.insert(key, value),
}
}
}
fn main() {
let log = Arc::new(Log::<<NrHashMap as Dispatch>::WriteOperation>::new(
2 * 1024 * 1024,
));
let replica1 = Replica::<NrHashMap>::new(&log);
let replica2 = Replica::<NrHashMap>::new(&log);
let thread_loop = |replica: &Arc<Replica<NrHashMap>>, ridx| {
for i in 0..2048 {
let _r = match i % 2 {
0 => replica.execute_mut(Modify::Put(i, i + 1), ridx),
1 => {
let response = replica.execute(Access::Get(i - 1), ridx);
assert_eq!(response, Some(i));
response
}
_ => unreachable!(),
};
}
};
let mut threads = Vec::with_capacity(3);
let replica11 = replica1.clone();
threads.push(std::thread::spawn(move || {
let ridx = replica11.register().expect("Unable to register with log");
thread_loop(&replica11, ridx);
}));
let replica12 = replica1.clone();
threads.push(std::thread::spawn(move || {
let ridx = replica12.register().expect("Unable to register with log");
thread_loop(&replica12, ridx);
}));
threads.push(std::thread::spawn(move || {
let ridx = replica2.register().expect("Unable to register with log");
thread_loop(&replica2, ridx);
}));
for thread in threads {
thread.join().unwrap();
}
}