extern crate woot; extern crate rand; use woot::{WString, Operation}; use rand::distributions::{IndependentSample, Range}; use std::collections::BinaryHeap; type W = WString; struct E (u64, usize, Operation); 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 { 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 = Vec::with_capacity(sites_count); for id in 0 .. sites_count { sites.push(WString::with_id(id)); } let mut heap: BinaryHeap = BinaryHeap::new(); // initial trigger 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); //println!("{:5} {:?}", site, s); 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 { // insert // where do we want to insert 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 { // where do we want to delete let n = Range::new(0, len-1).ind_sample(&mut rng); s.del(n) }; //println!("op: {:?}", op); // broadcast (with some latency issues) 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!(); } } } // 10^3 #[test] fn brute_1_2() { test(10, 100); } // 10^4 #[test] fn brute_1_3() { test(10, 1_000); } #[test] fn brute_2_2() { test(100, 100); } // 10^5 #[test] fn brute_1_4() { test(10, 10_000); } #[test] fn brute_2_3() { test(100, 1_000); } // 10^6 #[test] fn brute_3_3() { test(1_000, 1_000); } #[test] fn brute_2_4() { test(100, 10_000); }