extern crate woot;
extern crate rand;
use woot::{WString, Operation};
use rand::distributions::{IndependentSample, Range};
use std::collections::BinaryHeap;
type W = WString<u8>;
struct E (u64, usize, Operation<u8>);
impl std::cmp::Ord for E {
fn cmp(&self, rhs: &E) -> std::cmp::Ordering {
rhs.0.cmp(&self.0)
}
}
impl std::cmp::PartialOrd for E {
fn partial_cmp(&self, rhs: &E) -> Option<std::cmp::Ordering> {
Some(self.cmp(rhs))
}
}
impl std::cmp::PartialEq for E {
fn eq(&self, rhs: &E) -> bool {
self.0.eq(&rhs.0)
}
}
impl std::cmp::Eq for E {}
fn test(sites_count: usize, timeout: u64) {
let mut rng = rand::thread_rng();
let sites_range = Range::new(0, sites_count);
let latency_range = Range::new(0, 100u64);
let mut sites: Vec<W> = Vec::with_capacity(sites_count);
for id in 0 .. sites_count {
sites.push(WString::with_id(id));
}
let mut heap: BinaryHeap<E> = BinaryHeap::new();
let op = sites[0].ins(0, 42);
for m in 1 .. sites_count {
let latency = latency_range.ind_sample(&mut rng);
heap.push(E(latency, m, op.clone()));
}
while let Some(E(time, site, op)) = heap.pop() {
let s: &mut W = &mut sites[site];
let len = s.len();
println!("\nSite {} at time {:10}", site, time);
s.apply(op);
if sites_range.ind_sample(&mut rng) < heap.len() {
continue;
}
if time > timeout {
continue;
}
let op = if Range::new(0, len+1).ind_sample(&mut rng) < 100 {
let n = if len > 1 { Range::new(0, len).ind_sample(&mut rng) } else { 0 };
let c = Range::new(0, 255u8).ind_sample(&mut rng);
s.ins(n, c)
} else {
let n = Range::new(0, len-1).ind_sample(&mut rng);
s.del(n)
};
for m in 0 .. sites_count {
if m != site {
let latency = latency_range.ind_sample(&mut rng);
heap.push(E(time + latency, m, op.clone()));
}
}
}
let result = sites[0].contents();
for i in 1 .. sites_count {
println!("{:03}: {:?}", i, sites[i]);
if result != sites[i].contents() {
for i in 0 .. sites_count {
println!("{:03}: {:?}", i, sites[i]);
}
panic!();
}
}
}
#[test]
fn brute_1_2() {
test(10, 100);
}
#[test]
fn brute_1_3() {
test(10, 1_000);
}
#[test]
fn brute_2_2() {
test(100, 100);
}
#[test]
fn brute_1_4() {
test(10, 10_000);
}
#[test]
fn brute_2_3() {
test(100, 1_000);
}
#[test]
fn brute_3_3() {
test(1_000, 1_000);
}
#[test]
fn brute_2_4() {
test(100, 10_000);
}