diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..a70d4ff71 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +language: rust +matrix: + allow_failures: + - rust: nightly + include: + - rust: beta + - rust: nightly + env: + - FEATURES='unstable' +cache: cargo +before_script: +- export PATH="$PATH:$HOME/.cargo/bin" +- rustup component add rustfmt-preview +script: +- cargo fmt -- --write-mode=diff +- cargo build --verbose --features "$FEATURES" +- cargo test --verbose --features "$FEATURES" diff --git a/Cargo.toml b/Cargo.toml index 9d68ba060..3727561d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,9 @@ name = "loomination" version = "0.1.0" authors = ["Greg Fitzgerald "] +[features] +unstable = [] + [dependencies] +rayon = "0.9" +itertools = "0.7.6" diff --git a/src/lib.rs b/src/lib.rs index e127cb341..d08f10f3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,4 @@ +#![cfg_attr(feature = "unstable", feature(test))] pub mod tick; +extern crate itertools; +extern crate rayon; diff --git a/src/tick.rs b/src/tick.rs index f7ea7a77e..33127f628 100644 --- a/src/tick.rs +++ b/src/tick.rs @@ -49,7 +49,42 @@ impl Tick { /// assert!(!verify_slice(&vec![Tick::new(0, 0), Tick::new(1, 0)], 0)); // lazy inductive case, bad /// ``` pub fn verify_slice(ticks: &[Tick], seed: u64) -> bool { + use rayon::prelude::*; let genesis = [Tick { hash: seed, n: 0 }]; - let mut tick_pairs = genesis.iter().chain(ticks).zip(ticks); + let tick_pairs = genesis.par_iter().chain(ticks).zip(ticks); tick_pairs.all(|(x, x1)| x1.verify(x.hash)) } + +/// Verifies the hashes and ticks serially. Exists only for reference. +pub fn verify_slice_seq(ticks: &[Tick], seed: u64) -> bool { + let genesis = [Tick { hash: seed, n: 0 }]; + let tick_pairs = genesis.iter().chain(ticks).zip(ticks); + tick_pairs.into_iter().all(|(x, x1)| x1.verify(x.hash)) +} + +/// Create a vector of Ticks of length 'len' from 'seed' hash and 'hashes_per_tick'. +pub fn create_ticks(seed: u64, hashes_per_tick: u64, len: usize) -> Vec { + use itertools::unfold; + let mut ticks_iter = unfold(seed, |state| { + let tick = Tick::new(*state, hashes_per_tick); + *state = tick.hash; + return Some(tick); + }); + ticks_iter.by_ref().take(len).collect() +} + +#[cfg(all(feature = "unstable", test))] +mod bench { + extern crate test; + use self::test::Bencher; + use tick; + + #[bench] + fn tick_bench(bencher: &mut Bencher) { + let seed = 0; + let ticks = tick::create_ticks(seed, 100_000, 4); + bencher.iter(|| { + assert!(tick::verify_slice(&ticks, seed)); + }); + } +}