use std::sync::Arc;
use node_replication::Dispatch;
use node_replication::Log;
use node_replication::Replica;
#[derive(Clone, Debug, PartialEq)]
enum Modify {
Push(u32),
Pop,
}
#[derive(Clone, Debug, PartialEq)]
enum Access {
Peek,
}
struct Stack {
storage: Vec<u32>,
}
impl Default for Stack {
fn default() -> Stack {
const DEFAULT_STACK_SIZE: u32 = 1_000u32;
let mut s = Stack {
storage: Default::default(),
};
for e in 0..DEFAULT_STACK_SIZE {
s.storage.push(e);
}
s
}
}
impl Dispatch for Stack {
type ReadOperation = Access;
type WriteOperation = Modify;
type Response = Option<u32>;
fn dispatch(&self, op: Self::ReadOperation) -> Self::Response {
match op {
Access::Peek => self.storage.last().cloned(),
}
}
fn dispatch_mut(&mut self, op: Self::WriteOperation) -> Self::Response {
match op {
Modify::Push(v) => {
self.storage.push(v);
return None;
}
Modify::Pop => return self.storage.pop(),
}
}
}
fn main() {
let log = Arc::new(Log::<<Stack as Dispatch>::WriteOperation>::new(
2 * 1024 * 1024,
));
let replica1 = Replica::<Stack>::new(&log);
let replica2 = Replica::<Stack>::new(&log);
let thread_loop = |replica: &Arc<Replica<Stack>>, ridx| {
for i in 0..2048 {
let _r = match i % 3 {
0 => replica.execute_mut(Modify::Push(i as u32), ridx),
1 => replica.execute_mut(Modify::Pop, ridx),
2 => replica.execute(Access::Peek, ridx),
_ => unreachable!(),
};
}
};
let replica11 = replica1.clone();
let mut threads = Vec::with_capacity(3);
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();
}
}