<commit_before>#![feature(test)]

#![allow(raw_pointer_derive)]
extern crate test;
extern crate itertools;

use test::{black_box};
use itertools::Stride;
use itertools::Itertools;

#[cfg(not(feature = "unstable"))]
use itertools::Zip;

#[cfg(feature = "unstable")]
use itertools::{Zip, ZipTrusted};

use std::iter::repeat;
use std::marker::PhantomData;
use std::cmp;
use std::mem;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[derive(Copy, Clone)]
struct ZipSlices<'a, T: 'a, U :'a>
{
    t_ptr: *const T,
    t_end: *const T,
    u_ptr: *const U,
    mark: PhantomData<&'a (T, U)>,
}

impl<'a, T, U> ZipSlices<'a, T, U>
{
    pub fn new(t: &'a [T], u: &'a [U]) -> Self
    {
        assert!(mem::size_of::<T>() != 0);
        assert!(mem::size_of::<U>() != 0);
        let minl = cmp::min(t.len(), u.len());
        let tptr = t.as_ptr();
        let uptr = u.as_ptr();
        let end_ptr = unsafe {
            tptr.offset(minl as isize)
        };
        ZipSlices {
            t_ptr: tptr,
            t_end: end_ptr,
            u_ptr: uptr,
            mark: PhantomData,
        }
    }
}

impl<'a, T, U> Iterator for ZipSlices<'a, T, U>
{
    type Item = (&'a T, &'a U);

    #[inline]
    fn next(&mut self) -> Option<(&'a T, &'a U)>
    {
        if self.t_ptr == self.t_end {
            return None
        }
        let t_elt: &T;
        let u_elt: &U;
        unsafe {
            t_elt = &*self.t_ptr;
            self.t_ptr = self.t_ptr.offset(1);
            u_elt = &*self.u_ptr;
            self.u_ptr = self.u_ptr.offset(1);
        }
        Some((t_elt, u_elt))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>)
    {
        let len = self.t_end as usize - self.t_ptr as usize;
        (len, Some(len))
    }
}

#[bench]
fn zip_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in xs.iter().zip(ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        let zs = black_box(&zs);
        for ((&x, &y), &z) in xs.iter().zip(ys).zip(zs) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

/*
#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in Zip::new((xs, ys)) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}
*/

#[bench]
fn zip_slices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in ZipSlices::new(xs, ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        let zs = black_box(&zs);
        for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        let len = cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        let zs = black_box(&zs);
        let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}

#[bench]
fn group_by_lazy_1(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 10;
    }

    b.iter(|| {
        let iter = test::black_box(data.iter());
        for (_key, group) in &iter.group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn group_by_lazy_2(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 2;
    }

    b.iter(|| {
        let iter = test::black_box(data.iter());
        for (_key, group) in &iter.group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn equal(b: &mut test::Bencher) {
    let data = vec![7; 1024];
    let l = data.len();
    b.iter(|| {
        let a = test::black_box(&data[1..]);
        let b = test::black_box(&data[..l - 1]);
        itertools::equal(a, b)
    })
}
<commit_msg>bench: Update to black box outside of b.iter()<commit_after>#![feature(test)]

#![allow(raw_pointer_derive)]
extern crate test;
extern crate itertools;

use test::{black_box};
use itertools::Stride;
use itertools::Itertools;

#[cfg(not(feature = "unstable"))]
use itertools::Zip;

#[cfg(feature = "unstable")]
use itertools::{Zip, ZipTrusted};

use std::iter::repeat;
use std::marker::PhantomData;
use std::cmp;
use std::mem;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[derive(Copy, Clone)]
struct ZipSlices<'a, T: 'a, U :'a>
{
    t_ptr: *const T,
    t_end: *const T,
    u_ptr: *const U,
    mark: PhantomData<&'a (T, U)>,
}

impl<'a, T, U> ZipSlices<'a, T, U>
{
    pub fn new(t: &'a [T], u: &'a [U]) -> Self
    {
        assert!(mem::size_of::<T>() != 0);
        assert!(mem::size_of::<U>() != 0);
        let minl = cmp::min(t.len(), u.len());
        let tptr = t.as_ptr();
        let uptr = u.as_ptr();
        let end_ptr = unsafe {
            tptr.offset(minl as isize)
        };
        ZipSlices {
            t_ptr: tptr,
            t_end: end_ptr,
            u_ptr: uptr,
            mark: PhantomData,
        }
    }
}

impl<'a, T, U> Iterator for ZipSlices<'a, T, U>
{
    type Item = (&'a T, &'a U);

    #[inline]
    fn next(&mut self) -> Option<(&'a T, &'a U)>
    {
        if self.t_ptr == self.t_end {
            return None
        }
        let t_elt: &T;
        let u_elt: &U;
        unsafe {
            t_elt = &*self.t_ptr;
            self.t_ptr = self.t_ptr.offset(1);
            u_elt = &*self.u_ptr;
            self.u_ptr = self.u_ptr.offset(1);
        }
        Some((t_elt, u_elt))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>)
    {
        let len = self.t_end as usize - self.t_ptr as usize;
        (len, Some(len))
    }
}

#[bench]
fn zip_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in xs.iter().zip(&ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

/*
#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in Zip::new((xs, ys)) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}
*/

#[bench]
fn zip_slices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipSlices::new(&xs, &ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let len = cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}

#[bench]
fn group_by_lazy_1(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 10;
    }

    b.iter(|| {
        let iter = test::black_box(data.iter());
        for (_key, group) in &iter.group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn group_by_lazy_2(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 2;
    }

    b.iter(|| {
        let iter = test::black_box(data.iter());
        for (_key, group) in &iter.group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn equal(b: &mut test::Bencher) {
    let data = vec![7; 1024];
    let l = data.len();
    b.iter(|| {
        let a = test::black_box(&data[1..]);
        let b = test::black_box(&data[..l - 1]);
        itertools::equal(a, b)
    })
}
<|endoftext|>


<commit_before>#![feature(test)]

#![allow(non_snake_case)]

extern crate pfor;
extern crate test;

use pfor::utility::Encodable;
use pfor::binary::Binary;
use test::Bencher;

macro_rules! encode_bench {
  ($(($t: ty, $value: expr, $length: expr, $name: ident)),*) => ($(
    #[bench]
    fn $name(b: &mut Bencher) {
      let mut bin = Binary::new();
      let input: Vec<$t> = vec![$value; $length];
      b.iter(|| {
        bin.encode(&input);
      });
      let output = bin.decode().unwrap();
      assert_eq!(input, output);
    }
  )*)
}

macro_rules! decode_bench {
  ($(($t: ty, $value: expr, $length: expr, $name: ident)),*) => ($(
    #[bench]
    fn $name(b: &mut Bencher) {
      let mut bin = Binary::new();
      let input: Vec<$t> = vec![$value; $length];
      bin.encode(&input);
      let mut output = Vec::new();
      b.iter(|| {
        output = bin.decode().unwrap();
      });
      assert_eq!(input, output);
    }
  )*)
}

macro_rules! vector_bench {
  ($(($t: ty, $value: expr, $length: expr, $name: ident)),*) => ($(
    #[bench]
    fn $name(b: &mut Bencher) {
      let mut input: Vec<$t> = Vec::new();
      b.iter(|| {
        input = vec![$value; $length];
      });
      let output = vec![$value; $length];
      assert_eq!(input, output);
    }
  )*)
}

encode_bench!{
  (u32, 1, 31, en_u32_1_31),
  (u32, 1, 32, en_u32_1_32),
  (u32, 3, 65535, en_u32_3_65535),
  (u32, 3, 65536, en_u32_3_65536),
  (u32, std::u32::MAX, 65536, en_u32_MAX_65536)
}

decode_bench!{
  (u32, 2, 31, de_u32_2_31),
  (u32, 2, 32, de_u32_2_32),
  (u32, 4, 65535, de_u32_4_65535),
  (u32, 4, 65536, de_u32_4_65536),
  (u32, std::u32::MAX, 65536, de_u32_MAX_65536)
}

vector_bench!{
  (u32, 1, 32, vt_u32_1_32),
  (u32, 3, 65536, vt_u32_3_65536),
  (u32, std::u32::MAX, 65536, vt_u32_MAX_65536)
}
<commit_msg>Added benches for other widths.<commit_after>#![feature(test)]

#![allow(non_snake_case)]

extern crate pfor;
extern crate test;

use pfor::utility::Encodable;
use pfor::binary::Binary;
use test::Bencher;

macro_rules! encode_bench {
  ($(($t: ty, $value: expr, $length: expr, $name: ident)),*) => ($(
    #[bench]
    fn $name(b: &mut Bencher) {
      let mut bin = Binary::new();
      let input: Vec<$t> = vec![$value; $length];
      b.iter(|| {
        bin.encode(&input);
      });
      let output = bin.decode().unwrap();
      assert_eq!(input, output);
    }
  )*)
}

macro_rules! decode_bench {
  ($(($t: ty, $value: expr, $length: expr, $name: ident)),*) => ($(
    #[bench]
    fn $name(b: &mut Bencher) {
      let mut bin = Binary::new();
      let input: Vec<$t> = vec![$value; $length];
      bin.encode(&input);
      let mut output = Vec::new();
      b.iter(|| {
        output = bin.decode().unwrap();
      });
      assert_eq!(input, output);
    }
  )*)
}

macro_rules! vector_bench {
  ($(($t: ty, $value: expr, $length: expr, $name: ident)),*) => ($(
    #[bench]
    fn $name(b: &mut Bencher) {
      let mut input: Vec<$t> = Vec::new();
      b.iter(|| {
        input = vec![$value; $length];
      });
      let output = vec![$value; $length];
      assert_eq!(input, output);
    }
  )*)
}

encode_bench!{
  (u32, 1, 31, en_u32_1_31),
  (u32, 1, 32, en_u32_1_32),
  (u32, 3, 65535, en_u32_3_65535),
  (u32, 3, 65536, en_u32_3_65536),
  (u8, std::u8::MAX, 65536, en_u8_MAX_65536),
  (u16, std::u16::MAX, 65536, en_u16_MAX_65536),
  (u32, std::u32::MAX, 65536, en_u32_MAX_65536),
  (u64, std::u64::MAX, 65536, en_u64_MAX_65536)
}

decode_bench!{
  (u32, 2, 31, de_u32_2_31),
  (u32, 2, 32, de_u32_2_32),
  (u32, 4, 65535, de_u32_4_65535),
  (u32, 4, 65536, de_u32_4_65536),
  (u8, std::u8::MAX, 65536, de_u8_MAX_65536),
  (u16, std::u16::MAX, 65536, de_u16_MAX_65536),
  (u32, std::u32::MAX, 65536, de_u32_MAX_65536),
  (u64, std::u64::MAX, 65536, de_u64_MAX_65536)
}

vector_bench!{
  (u32, 1, 32, vt_u32_1_32),
  (u32, 3, 65536, vt_u32_3_65536),
  (u32, std::u32::MAX, 65536, vt_u32_MAX_65536)
}
<|endoftext|>


<commit_before>#![feature(hashmap_hasher)]
#![feature(test)]

extern crate fnv;
extern crate fst;
#[macro_use] extern crate lazy_static;
extern crate test;

const STR_WORDS: &'static str = include_str!("./../data/words-100000");
const STR_WIKI_URLS: &'static str = include_str!("./../data/wiki-urls-100000");

fn get_keys(s: &'static str) -> Vec<String> {
    s.lines().map(str::to_owned).collect()
}

lazy_static! {
    static ref WORDS: Vec<String> = get_keys(STR_WORDS);
    static ref WIKI_URLS: Vec<String> = get_keys(STR_WIKI_URLS);
}

macro_rules! search {
    ($name:ident, $keys:expr) => {
        mod $name {
            use std::collections::{BTreeSet, HashSet};
            use std::collections::hash_state::DefaultState;

            use fnv::FnvHasher;
            use fst::raw::{Builder, Fst};
            use test::Bencher;

            #[bench]
            fn fst_contains(b: &mut Bencher) {
                lazy_static! {
                    static ref FST: Fst = {
                        let mut bfst = Builder::memory();
                        for word in $keys.iter() {
                            bfst.add(word).unwrap();
                        }
                        let bytes = bfst.into_inner().unwrap();
                        Fst::from_bytes(bytes).unwrap()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(FST.contains_key(&$keys[i]));
                })
            }

            #[bench]
            fn hash_fnv_contains(b: &mut Bencher) {
                lazy_static! {
                    static ref SET: HashSet<String, DefaultState<FnvHasher>> = {
                        $keys.clone().into_iter().collect()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(SET.contains(&$keys[i]));
                })
            }

            #[bench]
            fn hash_sip_contains(b: &mut Bencher) {
                lazy_static! {
                    static ref SET: HashSet<String> = {
                        $keys.clone().into_iter().collect()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(SET.contains(&$keys[i]));
                })
            }

            #[bench]
            fn btree_contains(b: &mut Bencher) {
                lazy_static! {
                    static ref SET: BTreeSet<String> = {
                        $keys.clone().into_iter().collect()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(SET.contains(&$keys[i]));
                })
            }
        }
    }
}

search!(words, ::WORDS);
search!(wiki_urls, ::WIKI_URLS);
<commit_msg>rustup<commit_after>#![feature(test)]

extern crate fnv;
extern crate fst;
#[macro_use] extern crate lazy_static;
extern crate test;

const STR_WORDS: &'static str = include_str!("./../data/words-100000");
const STR_WIKI_URLS: &'static str = include_str!("./../data/wiki-urls-100000");

fn get_keys(s: &'static str) -> Vec<String> {
    s.lines().map(str::to_owned).collect()
}

lazy_static! {
    static ref WORDS: Vec<String> = get_keys(STR_WORDS);
    static ref WIKI_URLS: Vec<String> = get_keys(STR_WIKI_URLS);
}

macro_rules! search {
    ($name:ident, $keys:expr) => {
        mod $name {
            use std::collections::{BTreeSet, HashSet};
            use std::hash::BuildHasherDefault;

            use fnv::FnvHasher;
            use fst::raw::{Builder, Fst};
            use test::Bencher;

            #[bench]
            fn fst_contains(b: &mut Bencher) {
                lazy_static! {
                    static ref FST: Fst = {
                        let mut bfst = Builder::memory();
                        for word in $keys.iter() {
                            bfst.add(word).unwrap();
                        }
                        let bytes = bfst.into_inner().unwrap();
                        Fst::from_bytes(bytes).unwrap()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(FST.contains_key(&$keys[i]));
                })
            }

            #[bench]
            fn hash_fnv_contains(b: &mut Bencher) {
                type Fnv = BuildHasherDefault<FnvHasher>;
                lazy_static! {
                    static ref SET: HashSet<String, Fnv> = {
                        $keys.clone().into_iter().collect()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(SET.contains(&$keys[i]));
                })
            }

            #[bench]
            fn hash_sip_contains(b: &mut Bencher) {
                lazy_static! {
                    static ref SET: HashSet<String> = {
                        $keys.clone().into_iter().collect()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(SET.contains(&$keys[i]));
                })
            }

            #[bench]
            fn btree_contains(b: &mut Bencher) {
                lazy_static! {
                    static ref SET: BTreeSet<String> = {
                        $keys.clone().into_iter().collect()
                    };
                }
                let mut i = 0;
                b.iter(|| {
                    i = (i + 1) % $keys.len();
                    assert!(SET.contains(&$keys[i]));
                })
            }
        }
    }
}

search!(words, ::WORDS);
search!(wiki_urls, ::WIKI_URLS);
<|endoftext|>


<commit_before>#![feature(macro_rules)]

extern crate test;
extern crate utp;

use test::Bencher;
use std::io::test::next_test_ip4;
use utp::UtpStream;

macro_rules! iotry(
    ($e:expr) => (match $e { Ok(e) => e, Err(e) => panic!("{}", e) })
)

#[bench]
fn bench_connection_setup_and_teardown(b: &mut Bencher) {
    let server_addr = next_test_ip4();
    b.iter(|| {
        let mut server = iotry!(UtpStream::bind(server_addr));

        spawn(proc() {
            let mut client = iotry!(UtpStream::connect(server_addr));
            iotry!(client.close());
        });

        iotry!(server.read_to_end());
        iotry!(server.close());
    });
}

#[bench]
fn bench_transfer_one_megabyte(b: &mut Bencher) {
    let len = 1024 * 1024;
    let server_addr = next_test_ip4();
    b.iter(|| {
        let data = Vec::from_fn(len, |idx| idx as u8);
        let mut server = iotry!(UtpStream::bind(server_addr));

        spawn(proc() {
            let mut client = iotry!(UtpStream::connect(server_addr));
            iotry!(client.write(data.as_slice()));
            iotry!(client.close());
        });

        iotry!(server.read_to_end());
        iotry!(server.close());
    });
    b.bytes = len as u64;
}
<commit_msg>Move data vector creation out of benchmark loop.<commit_after>#![feature(macro_rules)]

extern crate test;
extern crate utp;

use test::Bencher;
use std::io::test::next_test_ip4;
use utp::UtpStream;
use std::sync::Arc;

macro_rules! iotry(
    ($e:expr) => (match $e { Ok(e) => e, Err(e) => panic!("{}", e) })
)

#[bench]
fn bench_connection_setup_and_teardown(b: &mut Bencher) {
    let server_addr = next_test_ip4();
    b.iter(|| {
        let mut server = iotry!(UtpStream::bind(server_addr));

        spawn(proc() {
            let mut client = iotry!(UtpStream::connect(server_addr));
            iotry!(client.close());
        });

        iotry!(server.read_to_end());
        iotry!(server.close());
    });
}

#[bench]
fn bench_transfer_one_megabyte(b: &mut Bencher) {
    let len = 1024 * 1024;
    let server_addr = next_test_ip4();
    let data = Vec::from_fn(len, |idx| idx as u8);
    let data_arc = Arc::new(data);

    b.iter(|| {
        let data = data_arc.clone();
        let mut server = iotry!(UtpStream::bind(server_addr));

        spawn(proc() {
            let mut client = iotry!(UtpStream::connect(server_addr));
            iotry!(client.write(data.as_slice()));
            iotry!(client.close());
        });

        iotry!(server.read_to_end());
        iotry!(server.close());
    });
    b.bytes = len as u64;
}
<|endoftext|>


<commit_before>//
//   Copyright 2016 Andrew Hunter
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

//!
//! # The bus publisher
//!
//! This publisher works by queueing up changes and then sending them as batches. It is
//! useful for cases where there may be feedback loops or where a single change can have
//! a large list of consequences.
//!
//! Bus publishers can also support multiple input sources: changes are published in the
//! order that they arrive. This can be used to aggregate the output of several components
//! into a single tree.
//!

use std::rc::*;
use std::cell::*;
use std::mem;

use super::super::tree::*;
use super::component::*;
use super::subscriptionmanager::*;

///
/// A tree change bus queues up published changes until they are ready to send
///
pub struct TreeChangeBus {
    /// Changes that are waiting to be published
    /// (Rc so we can share between publishers, RefCell so we can update, Box so we can swap)
    waiting: Rc<RefCell<Box<WaitingChanges>>>,

    /// Consumers of this publisher
    subscriptions: Rc<SubscriptionManager<ConsumerRegistration>>
}

///
/// Changes waiting to be sent
///
struct WaitingChanges {
    waiting: Vec<Box<TreeChange>>
}

///
/// Stores a registration of a consumer
///
#[derive(Clone)]
struct ConsumerRegistration {
    address: TreeAddress,
    extent: TreeExtent
}

///
/// A consumer that receives changes from a TreeChangeBus
///
struct BusConsumer {
    subscriptions: Rc<SubscriptionManager<ConsumerRegistration>>
}

///
/// A publisher that sends changes to a TreeChangeBus
///
struct BusPublisher {
    /// Changes that are waiting to be published
    waiting: Rc<RefCell<Box<WaitingChanges>>>
}

impl TreeChangeBus {
    ///
    /// Creates a new bus publisher
    ///
    pub fn new() -> TreeChangeBus {
        TreeChangeBus {
            waiting:        Rc::new(RefCell::new(Box::new(WaitingChanges { waiting: vec![] }))),
            subscriptions:  Rc::new(SubscriptionManager::new())
        }
    }

    ///
    /// Creates a publisher that will send notifications to this object
    ///
    pub fn create_publisher(&self) -> PublisherRef {
        Box::new(BusPublisher { waiting: self.waiting.to_owned() })
    }

    ///
    /// Creates a consumer that will receive notifications from this publisher
    ///
    pub fn create_consumer(&self) -> ConsumerRef {
        Box::new(BusConsumer { subscriptions: self.subscriptions.clone() })
    }

    ///
    /// Pumps any published messages to the consumer
    ///
    pub fn pump(&mut self) {
        // Create a new list of waiting items and swap it for the active list
        let to_send = {
            let mut borrowed_waiting    = self.waiting.borrow_mut();
            let mut current_value       = Box::new(WaitingChanges { waiting: vec![] });

            mem::swap(&mut *borrowed_waiting, &mut current_value);

            current_value
        };

        // Publish the items in to_send
        for change in to_send.waiting {
            self.subscriptions.call_subscriptions(&|registration| {
                change.applies_to(&registration.address, &registration.extent).unwrap_or(false)
            }, &change);
        }
    }

    ///
    /// Pumps published messages to the consumer repeatedly until there are none left to process
    ///
    pub fn flush(&mut self) {
        // Pump published messages until no more are generated
        loop {
            if self.waiting.borrow().waiting.len() <= 0 {
                return;
            }

            self.pump();
        }
    }
}

impl Publisher for BusPublisher {
    ///
    /// Publishes a change to the consumers of this component
    ///
    #[inline]
    fn publish(&mut self, change: TreeChange) {
        self.waiting.borrow_mut().waiting.push(Box::new(change))
    }
}

impl Consumer for BusConsumer {
    ///
    /// Calls a function whenever a particular section of the tree has changed
    ///
    fn subscribe(&mut self, address: TreeAddress, extent: TreeExtent, callback: ConsumerCallback) {
        // Need to persuade rust that it can call the FnMut (assign parameter to a mutable variable)
        let mut also_callback = callback;

        self.subscriptions.add_subscription(ConsumerRegistration { address: address.clone(), extent: extent }, Box::new(move |change| {
            // The change we get from the subscription will have an address relative to the root of the tree
            // Make the subscription change relative to the address that was subscribed to
            let maybe_relative_change = change.relative_to(&address);
            if let Some(relative_change) = maybe_relative_change {
                also_callback(&relative_change);
            }
        }));
    }
}

#[cfg(test)]
mod bus_publisher_tests {
    use super::super::super::component::*;
    use super::super::output_tree_publisher::*;
    use super::*;

    #[test]
    pub fn can_pump_bus() {
        let mut input_bus           = TreeChangeBus::new();
        let mut input_publisher     = input_bus.create_publisher();
        let output_publisher        = OutputTreePublisher::new();
        let input_consumer          = input_bus.create_consumer();
        let output_reader           = output_publisher.get_tree_reader();
        let add_one                 = component_fn(|x: &i32| { x+1 });

        let _add_component          = add_one.into_component(input_consumer, output_publisher);

        input_publisher.publish(TreeChange::new(&(), TreeChangeType::Child, Some(&1.to_tree_node())));
        input_bus.pump();
        let output = output_reader();
        assert!(output.get_value().to_int(0) == 2);
    }

    #[test]
    pub fn can_have_feedback() {
        let mut input_bus           = TreeChangeBus::new();
        let mut input_publisher     = input_bus.create_publisher();
        let mut feedback_publisher  = input_bus.create_publisher();
        let output_publisher        = OutputTreePublisher::new();
        let input_consumer          = input_bus.create_consumer();
        let output_reader           = output_publisher.get_tree_reader();

        // Feedback component that sends a message back to itself to reduce the value if it's greater than 0
        let tend_to_zero            = component_fn_mut(move |x: &i32| {
            if *x > 0 {
                feedback_publisher.publish(TreeChange::new(&(), TreeChangeType::Child, Some(&(x-1).to_tree_node())));
            }
            *x
        });

        let _becomes_zero_component = tend_to_zero.into_component(input_consumer, output_publisher);

        input_publisher.publish(TreeChange::new(&(), TreeChangeType::Child, Some(&10.to_tree_node())));
        input_bus.pump();
        assert!(output_reader().get_value().to_int(0) == 10);

        input_bus.pump();
        assert!(output_reader().get_value().to_int(0) == 9);

        input_bus.pump();
        assert!(output_reader().get_value().to_int(0) == 8);

        input_bus.flush();
        assert!(output_reader().get_value().to_int(0) == 0);
    }
}
<commit_msg>Fix the bus publisher tests<commit_after>//
//   Copyright 2016 Andrew Hunter
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

//!
//! # The bus publisher
//!
//! This publisher works by queueing up changes and then sending them as batches. It is
//! useful for cases where there may be feedback loops or where a single change can have
//! a large list of consequences.
//!
//! Bus publishers can also support multiple input sources: changes are published in the
//! order that they arrive. This can be used to aggregate the output of several components
//! into a single tree.
//!

use std::rc::*;
use std::cell::*;
use std::mem;

use super::super::tree::*;
use super::component::*;
use super::subscriptionmanager::*;

///
/// A tree change bus queues up published changes until they are ready to send
///
pub struct TreeChangeBus {
    /// Changes that are waiting to be published
    /// (Rc so we can share between publishers, RefCell so we can update, Box so we can swap)
    waiting: Rc<RefCell<Box<WaitingChanges>>>,

    /// Consumers of this publisher
    subscriptions: Rc<SubscriptionManager<ConsumerRegistration>>
}

///
/// Changes waiting to be sent
///
struct WaitingChanges {
    waiting: Vec<Box<TreeChange>>
}

///
/// Stores a registration of a consumer
///
#[derive(Clone)]
struct ConsumerRegistration {
    address: TreeAddress,
    extent: TreeExtent
}

///
/// A consumer that receives changes from a TreeChangeBus
///
struct BusConsumer {
    subscriptions: Rc<SubscriptionManager<ConsumerRegistration>>
}

///
/// A publisher that sends changes to a TreeChangeBus
///
struct BusPublisher {
    /// Changes that are waiting to be published
    waiting: Rc<RefCell<Box<WaitingChanges>>>
}

impl TreeChangeBus {
    ///
    /// Creates a new bus publisher
    ///
    pub fn new() -> TreeChangeBus {
        TreeChangeBus {
            waiting:        Rc::new(RefCell::new(Box::new(WaitingChanges { waiting: vec![] }))),
            subscriptions:  Rc::new(SubscriptionManager::new())
        }
    }

    ///
    /// Creates a publisher that will send notifications to this object
    ///
    pub fn create_publisher(&self) -> PublisherRef {
        Box::new(BusPublisher { waiting: self.waiting.to_owned() })
    }

    ///
    /// Creates a consumer that will receive notifications from this publisher
    ///
    pub fn create_consumer(&self) -> ConsumerRef {
        Box::new(BusConsumer { subscriptions: self.subscriptions.clone() })
    }

    ///
    /// Pumps any published messages to the consumer
    ///
    pub fn pump(&mut self) {
        // Create a new list of waiting items and swap it for the active list
        let to_send = {
            let mut borrowed_waiting    = self.waiting.borrow_mut();
            let mut current_value       = Box::new(WaitingChanges { waiting: vec![] });

            mem::swap(&mut *borrowed_waiting, &mut current_value);

            current_value
        };

        // Publish the items in to_send
        for change in to_send.waiting {
            self.subscriptions.call_subscriptions(&|registration| {
                change.applies_to(&registration.address, &registration.extent).unwrap_or(false)
            }, &change);
        }
    }

    ///
    /// Pumps published messages to the consumer repeatedly until there are none left to process
    ///
    pub fn flush(&mut self) {
        // Pump published messages until no more are generated
        loop {
            if self.waiting.borrow().waiting.len() <= 0 {
                return;
            }

            self.pump();
        }
    }
}

impl Publisher for BusPublisher {
    ///
    /// Publishes a change to the consumers of this component
    ///
    #[inline]
    fn publish(&mut self, change: TreeChange) {
        self.waiting.borrow_mut().waiting.push(Box::new(change))
    }
}

impl Consumer for BusConsumer {
    ///
    /// Calls a function whenever a particular section of the tree has changed
    ///
    fn subscribe(&mut self, address: TreeAddress, extent: TreeExtent, callback: ConsumerCallback) {
        // Need to persuade rust that it can call the FnMut (assign parameter to a mutable variable)
        let mut also_callback = callback;

        self.subscriptions.add_subscription(ConsumerRegistration { address: address.clone(), extent: extent }, Box::new(move |change| {
            // The change we get from the subscription will have an address relative to the root of the tree
            // Make the subscription change relative to the address that was subscribed to
            let maybe_relative_change = change.relative_to(&address);
            if let Some(relative_change) = maybe_relative_change {
                also_callback(&relative_change);
            }
        }));
    }
}

#[cfg(test)]
mod bus_publisher_tests {
    use super::super::super::component::*;
    use super::super::output_tree_publisher::*;
    use super::*;

    #[test]
    pub fn can_pump_bus() {
        let mut input_bus           = TreeChangeBus::new();
        let mut input_publisher     = input_bus.create_publisher();
        let output_publisher        = OutputTreePublisher::new();
        let input_consumer          = input_bus.create_consumer();
        let output_reader           = output_publisher.get_tree_reader();
        let add_one                 = component_fn(|x: &i32| { x+1 });

        let _add_component          = add_one.into_component(input_consumer, output_publisher);

        input_publisher.publish(TreeChange::new(&(), &1));
        input_bus.pump();
        let output = output_reader();
        assert!(output.get_value().to_int(0) == 2);
    }

    #[test]
    pub fn can_have_feedback() {
        let mut input_bus           = TreeChangeBus::new();
        let mut input_publisher     = input_bus.create_publisher();
        let mut feedback_publisher  = input_bus.create_publisher();
        let output_publisher        = OutputTreePublisher::new();
        let input_consumer          = input_bus.create_consumer();
        let output_reader           = output_publisher.get_tree_reader();

        // Feedback component that sends a message back to itself to reduce the value if it's greater than 0
        let tend_to_zero            = component_fn_mut(move |x: &i32| {
            if *x > 0 {
                feedback_publisher.publish(TreeChange::new(&(), &(x-1)));
            }
            *x
        });

        let _becomes_zero_component = tend_to_zero.into_component(input_consumer, output_publisher);

        input_publisher.publish(TreeChange::new(&(), &10));
        input_bus.pump();
        assert!(output_reader().get_value().to_int(0) == 10);

        input_bus.pump();
        assert!(output_reader().get_value().to_int(0) == 9);

        input_bus.pump();
        assert!(output_reader().get_value().to_int(0) == 8);

        input_bus.flush();
        assert!(output_reader().get_value().to_int(0) == 0);
    }
}
<|endoftext|>


<commit_before>use super::*;
use response::FreshHyperResponse;
use request::HyperRequest;
use catcher;

use std::io::Read;
use std::collections::HashMap;
use term_painter::Color::*;
use term_painter::ToStyle;

use hyper::uri::RequestUri as HyperRequestUri;
use hyper::method::Method as HyperMethod;
use hyper::server::Server as HyperServer;
use hyper::server::Handler as HyperHandler;

pub struct Rocket {
    address: &'static str,
    port: isize,
    router: Router,
    catchers: HashMap<u16, Catcher>,
}

fn uri_is_absolute(uri: &HyperRequestUri) -> bool {
    match uri {
        &HyperRequestUri::AbsolutePath(_) => true,
        _ => false
    }
}

fn unwrap_absolute_path<'a>(uri: &'a HyperRequestUri) -> &'a str {
    match uri {
        &HyperRequestUri::AbsolutePath(ref s) => s.as_str(),
        _ => panic!("Can only accept absolute paths!")
    }
}

fn method_is_valid(method: &HyperMethod) -> bool {
    Method::from_hyp(method).is_some()
}

impl HyperHandler for Rocket {
    fn handle<'a, 'k>(&'a self, req: HyperRequest<'a, 'k>,
            res: FreshHyperResponse<'a>) {
        println!("{:?} '{}'", Green.paint(&req.method), Blue.paint(&req.uri));

        let finalize = |mut req: HyperRequest, _res: FreshHyperResponse| {
            let mut buf = vec![];
            // FIXME: Simple DOS attack here. Working around Hyper bug.
            let _ = req.read_to_end(&mut buf);
        };

        if !uri_is_absolute(&req.uri) {
            println!("{}", Red.paint("\t=> Internal failure. Bad URI."));
            println!("{} {:?}", Yellow.paint("\t=> Debug:"), req.uri);
            return finalize(req, res);
        }

        if !method_is_valid(&req.method) {
            println!("{}", Yellow.paint("\t=> Internal failure. Bad method."));
            println!("{} {:?}", Yellow.paint("\t=> Debug:"), req.method);
            return finalize(req, res);
        }

        return self.dispatch(req, res);
    }
}

impl Rocket {
    fn dispatch<'h, 'k>(&self, mut req: HyperRequest<'h, 'k>,
                        mut res: FreshHyperResponse<'h>) {
        // We read all of the contents now because we have to do it at some
        // point thanks to Hyper. FIXME: Simple DOS attack here.
        let mut buf = vec![];
        let _ = req.read_to_end(&mut buf);

        // Extract the method, uri, and try to find a route.
        let method = Method::from_hyp(&req.method).unwrap();
        let uri = unwrap_absolute_path(&req.uri);
        let route = self.router.route(method, uri);

        // A closure which we call when we know there is no route.
        let handle_not_found = |response: FreshHyperResponse| {
            let request = Request::new(vec![], uri, &buf);
            let handler_404 = self.catchers.get(&404).unwrap().handler;
            println!("{}", Red.paint("\t<= Dispatch failed. Returning 404."));
            handler_404(request).respond(response);
        };

        // No route found. Handle the not_found error and return.
        if route.is_none() {
            println!("{}", Red.paint("\t=> No matching routes."));
            return handle_not_found(res);
        }

        // Okay, we've got a route. Unwrap it, generate a request, and try to
        // dispatch. TODO: keep trying lower ranked routes before dispatching a
        // not found error.
        println!("\t=> {}", Magenta.paint("Dispatching request."));
        let route = route.unwrap();
        let params = route.get_params(uri);
        let request = Request::new(params, uri, &buf);
        let outcome = (route.handler)(request).respond(res);

        println!("\t=> {} {}", White.paint("Outcome:"), outcome);
        outcome.map_forward(|res| {
            println!("{}", Red.paint("\t=> No further matching routes."));
            handle_not_found(res);
        });
    }

    pub fn new(address: &'static str, port: isize) -> Rocket {
        Rocket {
            address: address,
            port: port,
            router: Router::new(),
            catchers: catcher::defaults::get(),
        }
    }

    pub fn mount(&mut self, base: &'static str, routes: Vec<Route>)
            -> &mut Self {
        println!("🛰  {} '{}':", Magenta.paint("Mounting"), Blue.paint(base));
        for mut route in routes {
            let path = format!("{}/{}", base, route.path.as_str());
            route.set_path(path);

            println!("\t* {}", route);
            self.router.add(route);
        }

        self
    }

    pub fn catch(&mut self, catchers: Vec<Catcher>) -> &mut Self {
        println!("👾  {}:", Magenta.paint("Catchers"));
        for c in catchers {
            if self.catchers.contains_key(&c.code) &&
                    !self.catchers.get(&c.code).unwrap().is_default() {
                let msg = format!("warning: overrides {} catcher!", c.code);
                println!("\t* {} ({})", c, Yellow.paint(msg.as_str()));
            } else {
                println!("\t* {}", c);
            }

            self.catchers.insert(c.code, c);
        }

        self
    }

    pub fn launch(self) {
        if self.router.has_collisions() {
            println!("{}", Yellow.paint("Warning: route collisions detected!"));
        }

        let full_addr = format!("{}:{}", self.address, self.port);
        println!("🚀  {} {}...", White.paint("Rocket has launched from"),
            White.bold().paint(&full_addr));
        let _ = HyperServer::http(full_addr.as_str()).unwrap().handle(self);
    }

    pub fn mount_and_launch(mut self, base: &'static str, routes: Vec<Route>) {
        self.mount(base, routes);
        self.launch();
    }
}
<commit_msg>Remove unnecessary mut.<commit_after>use super::*;
use response::FreshHyperResponse;
use request::HyperRequest;
use catcher;

use std::io::Read;
use std::collections::HashMap;
use term_painter::Color::*;
use term_painter::ToStyle;

use hyper::uri::RequestUri as HyperRequestUri;
use hyper::method::Method as HyperMethod;
use hyper::server::Server as HyperServer;
use hyper::server::Handler as HyperHandler;

pub struct Rocket {
    address: &'static str,
    port: isize,
    router: Router,
    catchers: HashMap<u16, Catcher>,
}

fn uri_is_absolute(uri: &HyperRequestUri) -> bool {
    match uri {
        &HyperRequestUri::AbsolutePath(_) => true,
        _ => false
    }
}

fn unwrap_absolute_path<'a>(uri: &'a HyperRequestUri) -> &'a str {
    match uri {
        &HyperRequestUri::AbsolutePath(ref s) => s.as_str(),
        _ => panic!("Can only accept absolute paths!")
    }
}

fn method_is_valid(method: &HyperMethod) -> bool {
    Method::from_hyp(method).is_some()
}

impl HyperHandler for Rocket {
    fn handle<'a, 'k>(&'a self, req: HyperRequest<'a, 'k>,
            res: FreshHyperResponse<'a>) {
        println!("{:?} '{}'", Green.paint(&req.method), Blue.paint(&req.uri));

        let finalize = |mut req: HyperRequest, _res: FreshHyperResponse| {
            let mut buf = vec![];
            // FIXME: Simple DOS attack here. Working around Hyper bug.
            let _ = req.read_to_end(&mut buf);
        };

        if !uri_is_absolute(&req.uri) {
            println!("{}", Red.paint("\t=> Internal failure. Bad URI."));
            println!("{} {:?}", Yellow.paint("\t=> Debug:"), req.uri);
            return finalize(req, res);
        }

        if !method_is_valid(&req.method) {
            println!("{}", Yellow.paint("\t=> Internal failure. Bad method."));
            println!("{} {:?}", Yellow.paint("\t=> Debug:"), req.method);
            return finalize(req, res);
        }

        return self.dispatch(req, res);
    }
}

impl Rocket {
    fn dispatch<'h, 'k>(&self, mut req: HyperRequest<'h, 'k>,
                        res: FreshHyperResponse<'h>) {
        // We read all of the contents now because we have to do it at some
        // point thanks to Hyper. FIXME: Simple DOS attack here.
        let mut buf = vec![];
        let _ = req.read_to_end(&mut buf);

        // Extract the method, uri, and try to find a route.
        let method = Method::from_hyp(&req.method).unwrap();
        let uri = unwrap_absolute_path(&req.uri);
        let route = self.router.route(method, uri);

        // A closure which we call when we know there is no route.
        let handle_not_found = |response: FreshHyperResponse| {
            let request = Request::new(vec![], uri, &buf);
            let handler_404 = self.catchers.get(&404).unwrap().handler;
            println!("{}", Red.paint("\t<= Dispatch failed. Returning 404."));
            handler_404(request).respond(response);
        };

        // No route found. Handle the not_found error and return.
        if route.is_none() {
            println!("{}", Red.paint("\t=> No matching routes."));
            return handle_not_found(res);
        }

        // Okay, we've got a route. Unwrap it, generate a request, and try to
        // dispatch. TODO: keep trying lower ranked routes before dispatching a
        // not found error.
        println!("\t=> {}", Magenta.paint("Dispatching request."));
        let route = route.unwrap();
        let params = route.get_params(uri);
        let request = Request::new(params, uri, &buf);
        let outcome = (route.handler)(request).respond(res);

        println!("\t=> {} {}", White.paint("Outcome:"), outcome);
        outcome.map_forward(|res| {
            println!("{}", Red.paint("\t=> No further matching routes."));
            handle_not_found(res);
        });
    }

    pub fn new(address: &'static str, port: isize) -> Rocket {
        Rocket {
            address: address,
            port: port,
            router: Router::new(),
            catchers: catcher::defaults::get(),
        }
    }

    pub fn mount(&mut self, base: &'static str, routes: Vec<Route>)
            -> &mut Self {
        println!("🛰  {} '{}':", Magenta.paint("Mounting"), Blue.paint(base));
        for mut route in routes {
            let path = format!("{}/{}", base, route.path.as_str());
            route.set_path(path);

            println!("\t* {}", route);
            self.router.add(route);
        }

        self
    }

    pub fn catch(&mut self, catchers: Vec<Catcher>) -> &mut Self {
        println!("👾  {}:", Magenta.paint("Catchers"));
        for c in catchers {
            if self.catchers.contains_key(&c.code) &&
                    !self.catchers.get(&c.code).unwrap().is_default() {
                let msg = format!("warning: overrides {} catcher!", c.code);
                println!("\t* {} ({})", c, Yellow.paint(msg.as_str()));
            } else {
                println!("\t* {}", c);
            }

            self.catchers.insert(c.code, c);
        }

        self
    }

    pub fn launch(self) {
        if self.router.has_collisions() {
            println!("{}", Yellow.paint("Warning: route collisions detected!"));
        }

        let full_addr = format!("{}:{}", self.address, self.port);
        println!("🚀  {} {}...", White.paint("Rocket has launched from"),
            White.bold().paint(&full_addr));
        let _ = HyperServer::http(full_addr.as_str()).unwrap().handle(self);
    }

    pub fn mount_and_launch(mut self, base: &'static str, routes: Vec<Route>) {
        self.mount(base, routes);
        self.launch();
    }
}
<|endoftext|>


<commit_before>extern crate nalgebra;

use memoized_flat_time_steward as s;
use {TimeSteward, DeterministicRandomId, Column, ColumnId, RowId, PredictorId, Mutator,
     TimeStewardStaticMethods, Accessor, MomentaryAccessor, PredictorAccessor};
use collision_detection::inefficient as collisions;

use time_functions::QuadraticTrajectory;
use std::rc::Rc;
use rand::Rng;
use nalgebra::Vector2;
use std::thread::sleep;
use std::time::{Instant, Duration};
use glium;
use glium::{DisplayBuild, Surface};

use std::io::Write;
macro_rules! printlnerr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

type Time = i64;
type SpaceCoordinate = i64;

const HOW_MANY_CIRCLES: i32 = 20;
const ARENA_SIZE: SpaceCoordinate = (1 << 20);
const TIME_SHIFT: i32 = 20;
const SECOND: Time = (1 << TIME_SHIFT);

#[derive(Clone)]
struct Basics;
impl ::Basics for Basics {
  type Time = Time;
  type Constants = ();
}
struct CollisionBasics {}
impl ::collision_detection::Basics for CollisionBasics {
  type StewardBasics = Basics;
  type DetectorId =();
  fn nearness_column_id() -> ColumnId {
    ColumnId(0x89ebc3ba9a24c286)
  }
}

type Nearness = ::collision_detection::Nearness<CollisionBasics>;

#[derive(Clone)]
struct Circle {
  position: QuadraticTrajectory,
  radius: SpaceCoordinate,
}
impl Column for Circle {
  type FieldType = Self;
  fn column_id() -> ColumnId {
    ColumnId(0x6422505ce8c8ce8e)
  }
}
struct Intersection {
  induced_acceleration: Vector2<SpaceCoordinate>,
}
impl Column for Intersection {
  type FieldType = Self;
  fn column_id() -> ColumnId {
    ColumnId(0x9357f021339198a1)
  }
}

type Steward = s::Steward<Basics>;

fn get_circle_id(index: i32) -> RowId {
  DeterministicRandomId::new(&(0x86ccbeb2c140cc51u64, index))
}

fn collision_predictor <PA: PredictorAccessor <Basics, <s::Steward <Basics> as TimeStewardStaticMethods < Basics>>::EventFn >> (accessor: &mut PA, id: RowId) {
  let ids = Nearness::get_ids(accessor, id).0;
  let time;
  {

    let us = (accessor.data_and_last_change::<Circle>(ids[0])
                      .expect("a nearness exists for a circle that doesn't"),
              accessor.data_and_last_change::<Circle>(ids[1])
                      .expect("a nearness exists for a circle that doesn't"));

    let relationship = accessor.get::<Intersection>(id);
    time = QuadraticTrajectory::approximately_when_distance_passes((us.0).0.radius +
                                                                   (us.1).0.radius,
                                                                   if relationship.is_none() {
                                                                     -1
                                                                   } else {
                                                                     1
                                                                   },
                                                                   ((us.0).1.clone(),
                                                                    &(us.0).0.position),
                                                                   ((us.1).1.clone(),
                                                                    &(us.1).0.position));
    printlnerr!("Planning for {} At {}, {}", id, (us.0).1, (us.1).1);
  }
  if let Some(yes) = time {
  printlnerr!(" planned for {}", & yes);
    accessor.predict_at_time(&yes,
                             Rc::new(move |mutator| {
                               let new_relationship;
                               let mut new;
                               {
                                 let relationship = mutator.get::<Intersection>(id).clone();
                                 let us = (mutator.data_and_last_change::<Circle>(ids[0])
                                                  .expect("a nearness exists for a circle that \
                                                           doesn't (event)"),
                                           mutator.data_and_last_change::<Circle>(ids[1])
                                                  .expect("a nearness exists for a circle that \
                                                           doesn't (event)"));
                                 new = ((us.0).0.clone(), (us.1).0.clone());
                                 new.0.position.update_by(mutator.now() - (us.0).1);
                                 new.1.position.update_by(mutator.now() - (us.1).1);
                                 if let Some(intersection) = relationship {
                                   new.0
                                      .position
                                      .add_acceleration(-intersection.induced_acceleration);
                                   new.1
                                      .position
                                      .add_acceleration(intersection.induced_acceleration);
                                   new_relationship = None;
                                 } else {
                                   let acceleration = (new.0.position.evaluate() - new.1.position.evaluate())*(ARENA_SIZE*4/(new.0.radius + new.1.radius));
                                   new.0.position.add_acceleration(acceleration);
                                   new.1.position.add_acceleration(-acceleration);
                                   new_relationship = Some(Intersection {
                                     induced_acceleration: acceleration,
                                   });

                                 }
                               }
                               mutator.set::<Intersection>(id, new_relationship);
                               mutator.set::<Circle>(ids[0], Some(new.0));
                               mutator.set::<Circle>(ids[1], Some(new.1));
                             }));
  }
}

fn boundary_predictor <PA: PredictorAccessor <Basics, <s::Steward <Basics> as TimeStewardStaticMethods < Basics>>::EventFn >> (accessor: &mut PA, id: RowId) {
  let time;
  {
let arena_center = QuadraticTrajectory::new(TIME_SHIFT,
                                                        [ ARENA_SIZE/2,
                                                          ARENA_SIZE/2,
0, 0, 0,
                                                         0]);
    let me = accessor.data_and_last_change::<Circle>(id)
                      .expect("a prediction was recorded for a circle that doesn't exist");

    let relationship = accessor.get::<Intersection>(id);
    time = QuadraticTrajectory::approximately_when_distance_passes(ARENA_SIZE - me.0.radius,
                                                                   if relationship.is_some() {
                                                                     -1
                                                                   } else {
                                                                     1
                                                                   },
(me.1.clone(),
                                                                    &(me.0.position)),
(0,
                                                                    &(arena_center )));
  }
  if let Some(yes) = time {
  printlnerr!(" planned for {}", & yes);
    accessor.predict_at_time(&yes,
                             Rc::new(move |mutator| {
                               let new_relationship;
                               let mut new;
                               {
                                 let relationship = mutator.get::<Intersection>(id).clone();
                                 let me = mutator.data_and_last_change::<Circle>(id)
                                                  .expect("a an event was recorded for a circle that doesn't exist)");
                                                  new = me.0.clone();
                                 new.position.update_by(mutator.now() - me.1);
                                 if let Some(intersection) = relationship {
                                   new
                                      .position
                                      .add_acceleration(-intersection.induced_acceleration);
                                   new_relationship = None;
                                 } else {
                                   let acceleration = - (new.position.evaluate() - Vector2::new (ARENA_SIZE/2,
                                                                                ARENA_SIZE/2))*(ARENA_SIZE*4/(ARENA_SIZE - me.0.radius));
                                   new.position.add_acceleration(acceleration);
                                   new_relationship = Some(Intersection {
                                     induced_acceleration: acceleration,
                                   });

                                 }
                               }
                               mutator.set::<Intersection>(id, new_relationship);
                               mutator.set::<Circle>(id, Some(new));
                             }));
  }
}

#[derive(Copy, Clone)]

struct Vertex {
  direction: [f32; 2],
  center: [f32; 2],
  radius: f32,
}
implement_vertex!(Vertex, direction, center, radius);

pub fn testfunc() {

  let mut stew: Steward =
    ::TimeStewardStaticMethods::new_empty((),
                                          vec![s::Predictor {
                                                 predictor_id: PredictorId(0x5375592f4da8682c),
                                                 column_id: Nearness::column_id(),
                                                 function: Rc::new(|accessor, id| {
                                                   collision_predictor(accessor, id)
                                                 }),
                                               },
                                               s::Predictor {
                                                 predictor_id: PredictorId(0x87d8a4a095350d30),
                                                 column_id: Circle::column_id(),
                                                 function: Rc::new(|accessor, id| {
boundary_predictor(accessor, id)
                                                 }),
                                               }
                                               ]);

  stew.insert_fiat_event(-1,
                         DeterministicRandomId::new(&0),
                         Rc::new(|mutator| {
                           for i in 0..HOW_MANY_CIRCLES {
                             let thingy = ARENA_SIZE / 20;
                             let radius = mutator.rng().gen_range(ARENA_SIZE / 30, ARENA_SIZE / 15);
                             let id = get_circle_id(i);

                             let position =
                               QuadraticTrajectory::new(TIME_SHIFT,
                                                        [mutator.rng().gen_range(0, ARENA_SIZE),
                                                         mutator.rng().gen_range(0, ARENA_SIZE),
                                                         mutator.rng().gen_range(-thingy, thingy),
                                                         mutator.rng().gen_range(-thingy, thingy),
                                                         0,
                                                         0]);
                             mutator.set::<Circle>(id,
                                                   Some(Circle {
                                                     position: position,
                                                     radius: radius,
                                                   }));
                             collisions::insert::<CollisionBasics, _>(mutator, id, ());
                           }
                         }));
  let vertex_shader_source = r#"
#version 140
in vec2 direction;
in vec2 center;
in float radius;
out vec2 direction_transfer;

void main() {
direction_transfer = direction*1.5;
gl_Position = vec4 ( center + direction*1.5*radius, 0.0, 1.0);
}

"#;

  let fragment_shader_source = r#"
#version 140
in vec2 direction_transfer;
out vec4 color;

void main() {
if (dot (direction_transfer,direction_transfer) <1.0) {
color = vec4 (1.0, 0.0, 0.0, 1.0);
} else {
color = vec4 (0.0, 0.0, 0.0, 0.0);

}
}

"#;

  let mut snapshots = Vec::new();

if true {
  let display = glium::glutin::WindowBuilder::new()
                  .with_dimensions(600, 600)
                  .build_glium()
                  .expect("failed to create window");
  let program = glium::Program::from_source(&display,
                                            vertex_shader_source,
                                            fragment_shader_source,
                                            None)
                  .expect("glium program generation failed");
  let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);
  let start = Instant::now();
  loop {
    for ev in display.poll_events() {
      match ev {
        glium::glutin::Event::Closed => return,
        _ => (),
      }
    }

    let mut target = display.draw();
    target.clear_color(0.0, 0.0, 0.0, 1.0);
    let mut vertices = Vec::<Vertex>::new();

    let snapshot = stew.snapshot_before(&(((start.elapsed().as_secs() as i64*1000000000i64)+start.elapsed().subsec_nanos() as i64) * SECOND /
                                          1000000000i64))
                       .expect("steward failed to provide snapshot");
    for index in 0..HOW_MANY_CIRCLES {
      let (circle, time) = snapshot.data_and_last_change::<Circle>(get_circle_id(index))
                                   .expect("missing circle")
                                   .clone();
      let position = circle.position.updated_by(snapshot.now() - time).evaluate();
      let center = [position[0] as f32 / ARENA_SIZE as f32 - 0.5, position[1] as f32 / ARENA_SIZE as f32 - 0.5];
      let radius = circle.radius as f32 / ARENA_SIZE as f32;
    //printlnerr!("drawing circ at {}, {}", center[0],center[1]);
      vertices.extend(&[Vertex {
                          center: center,
                          radius: radius,
                          direction: [1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [-1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [0.0, 1.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [-1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [0.0, -1.0],
                        }]);

    }
    target.draw(&glium::VertexBuffer::new(&display, &vertices).expect("failed to generate glium Vertex buffer"),
                &indices,
                &program,
                &glium::uniforms::EmptyUniforms,
                &Default::default())
          .expect("failed target.draw");

    target.finish().expect("failed to finish drawing");

}
    sleep(Duration::from_millis(10));
  }

  for increment in 1..21 {
    snapshots.push(stew.snapshot_before(&(increment * SECOND * 2)));
  }
  for snapshot in snapshots.iter_mut().map(|option| {
    option.as_mut().expect("all these snapshots should have been valid")
  }) {
    printlnerr!("snapshot for {}", snapshot.now());
    for index in 0..HOW_MANY_CIRCLES {
      // printlnerr!("{}", snapshot.get::<Circle> (get_circle_id (index)).expect("missing circle").position);
    }
  }
  // panic!("anyway")
}

#[test]
fn actuallytest() {
  testfunc();
}
<commit_msg>Fix graphical glitch<commit_after>extern crate nalgebra;

use memoized_flat_time_steward as s;
use {TimeSteward, DeterministicRandomId, Column, ColumnId, RowId, PredictorId, Mutator,
     TimeStewardStaticMethods, Accessor, MomentaryAccessor, PredictorAccessor};
use collision_detection::inefficient as collisions;

use time_functions::QuadraticTrajectory;
use std::rc::Rc;
use rand::Rng;
use nalgebra::Vector2;
use std::thread::sleep;
use std::time::{Instant, Duration};
use glium;
use glium::{DisplayBuild, Surface};

use std::io::Write;
macro_rules! printlnerr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

type Time = i64;
type SpaceCoordinate = i64;

const HOW_MANY_CIRCLES: i32 = 20;
const ARENA_SIZE: SpaceCoordinate = (1 << 20);
const TIME_SHIFT: i32 = 20;
const SECOND: Time = (1 << TIME_SHIFT);

#[derive(Clone)]
struct Basics;
impl ::Basics for Basics {
  type Time = Time;
  type Constants = ();
}
struct CollisionBasics {}
impl ::collision_detection::Basics for CollisionBasics {
  type StewardBasics = Basics;
  type DetectorId =();
  fn nearness_column_id() -> ColumnId {
    ColumnId(0x89ebc3ba9a24c286)
  }
}

type Nearness = ::collision_detection::Nearness<CollisionBasics>;

#[derive(Clone)]
struct Circle {
  position: QuadraticTrajectory,
  radius: SpaceCoordinate,
}
impl Column for Circle {
  type FieldType = Self;
  fn column_id() -> ColumnId {
    ColumnId(0x6422505ce8c8ce8e)
  }
}
struct Intersection {
  induced_acceleration: Vector2<SpaceCoordinate>,
}
impl Column for Intersection {
  type FieldType = Self;
  fn column_id() -> ColumnId {
    ColumnId(0x9357f021339198a1)
  }
}

type Steward = s::Steward<Basics>;

fn get_circle_id(index: i32) -> RowId {
  DeterministicRandomId::new(&(0x86ccbeb2c140cc51u64, index))
}

fn collision_predictor <PA: PredictorAccessor <Basics, <s::Steward <Basics> as TimeStewardStaticMethods < Basics>>::EventFn >> (accessor: &mut PA, id: RowId) {
  let ids = Nearness::get_ids(accessor, id).0;
  let time;
  {

    let us = (accessor.data_and_last_change::<Circle>(ids[0])
                      .expect("a nearness exists for a circle that doesn't"),
              accessor.data_and_last_change::<Circle>(ids[1])
                      .expect("a nearness exists for a circle that doesn't"));

    let relationship = accessor.get::<Intersection>(id);
    time = QuadraticTrajectory::approximately_when_distance_passes((us.0).0.radius +
                                                                   (us.1).0.radius,
                                                                   if relationship.is_none() {
                                                                     -1
                                                                   } else {
                                                                     1
                                                                   },
                                                                   ((us.0).1.clone(),
                                                                    &(us.0).0.position),
                                                                   ((us.1).1.clone(),
                                                                    &(us.1).0.position));
    printlnerr!("Planning for {} At {}, {}", id, (us.0).1, (us.1).1);
  }
  if let Some(yes) = time {
  printlnerr!(" planned for {}", & yes);
    accessor.predict_at_time(&yes,
                             Rc::new(move |mutator| {
                               let new_relationship;
                               let mut new;
                               {
                                 let relationship = mutator.get::<Intersection>(id).clone();
                                 let us = (mutator.data_and_last_change::<Circle>(ids[0])
                                                  .expect("a nearness exists for a circle that \
                                                           doesn't (event)"),
                                           mutator.data_and_last_change::<Circle>(ids[1])
                                                  .expect("a nearness exists for a circle that \
                                                           doesn't (event)"));
                                 new = ((us.0).0.clone(), (us.1).0.clone());
                                 new.0.position.update_by(mutator.now() - (us.0).1);
                                 new.1.position.update_by(mutator.now() - (us.1).1);
                                 if let Some(intersection) = relationship {
                                   new.0
                                      .position
                                      .add_acceleration(-intersection.induced_acceleration);
                                   new.1
                                      .position
                                      .add_acceleration(intersection.induced_acceleration);
                                   new_relationship = None;
                                 } else {
                                   let acceleration = (new.0.position.evaluate() - new.1.position.evaluate())*(ARENA_SIZE*4/(new.0.radius + new.1.radius));
                                   new.0.position.add_acceleration(acceleration);
                                   new.1.position.add_acceleration(-acceleration);
                                   new_relationship = Some(Intersection {
                                     induced_acceleration: acceleration,
                                   });

                                 }
                               }
                               mutator.set::<Intersection>(id, new_relationship);
                               mutator.set::<Circle>(ids[0], Some(new.0));
                               mutator.set::<Circle>(ids[1], Some(new.1));
                             }));
  }
}

fn boundary_predictor <PA: PredictorAccessor <Basics, <s::Steward <Basics> as TimeStewardStaticMethods < Basics>>::EventFn >> (accessor: &mut PA, id: RowId) {
  let time;
  {
let arena_center = QuadraticTrajectory::new(TIME_SHIFT,
                                                        [ ARENA_SIZE/2,
                                                          ARENA_SIZE/2,
0, 0, 0,
                                                         0]);
    let me = accessor.data_and_last_change::<Circle>(id)
                      .expect("a prediction was recorded for a circle that doesn't exist");

    let relationship = accessor.get::<Intersection>(id);
    time = QuadraticTrajectory::approximately_when_distance_passes(ARENA_SIZE - me.0.radius,
                                                                   if relationship.is_some() {
                                                                     -1
                                                                   } else {
                                                                     1
                                                                   },
(me.1.clone(),
                                                                    &(me.0.position)),
(0,
                                                                    &(arena_center )));
  }
  if let Some(yes) = time {
  printlnerr!(" planned for {}", & yes);
    accessor.predict_at_time(&yes,
                             Rc::new(move |mutator| {
                               let new_relationship;
                               let mut new;
                               {
                                 let relationship = mutator.get::<Intersection>(id).clone();
                                 let me = mutator.data_and_last_change::<Circle>(id)
                                                  .expect("a an event was recorded for a circle that doesn't exist)");
                                                  new = me.0.clone();
                                 new.position.update_by(mutator.now() - me.1);
                                 if let Some(intersection) = relationship {
                                   new
                                      .position
                                      .add_acceleration(-intersection.induced_acceleration);
                                   new_relationship = None;
                                 } else {
                                   let acceleration = - (new.position.evaluate() - Vector2::new (ARENA_SIZE/2,
                                                                                ARENA_SIZE/2))*(ARENA_SIZE*4/(ARENA_SIZE - me.0.radius));
                                   new.position.add_acceleration(acceleration);
                                   new_relationship = Some(Intersection {
                                     induced_acceleration: acceleration,
                                   });

                                 }
                               }
                               mutator.set::<Intersection>(id, new_relationship);
                               mutator.set::<Circle>(id, Some(new));
                             }));
  }
}

#[derive(Copy, Clone)]

struct Vertex {
  direction: [f32; 2],
  center: [f32; 2],
  radius: f32,
}
implement_vertex!(Vertex, direction, center, radius);

pub fn testfunc() {

  let mut stew: Steward =
    ::TimeStewardStaticMethods::new_empty((),
                                          vec![s::Predictor {
                                                 predictor_id: PredictorId(0x5375592f4da8682c),
                                                 column_id: Nearness::column_id(),
                                                 function: Rc::new(|accessor, id| {
                                                   collision_predictor(accessor, id)
                                                 }),
                                               },
                                               s::Predictor {
                                                 predictor_id: PredictorId(0x87d8a4a095350d30),
                                                 column_id: Circle::column_id(),
                                                 function: Rc::new(|accessor, id| {
boundary_predictor(accessor, id)
                                                 }),
                                               }
                                               ]);

  stew.insert_fiat_event(-1,
                         DeterministicRandomId::new(&0),
                         Rc::new(|mutator| {
                           for i in 0..HOW_MANY_CIRCLES {
                             let thingy = ARENA_SIZE / 20;
                             let radius = mutator.rng().gen_range(ARENA_SIZE / 30, ARENA_SIZE / 15);
                             let id = get_circle_id(i);

                             let position =
                               QuadraticTrajectory::new(TIME_SHIFT,
                                                        [mutator.rng().gen_range(0, ARENA_SIZE),
                                                         mutator.rng().gen_range(0, ARENA_SIZE),
                                                         mutator.rng().gen_range(-thingy, thingy),
                                                         mutator.rng().gen_range(-thingy, thingy),
                                                         0,
                                                         0]);
                             mutator.set::<Circle>(id,
                                                   Some(Circle {
                                                     position: position,
                                                     radius: radius,
                                                   }));
                             collisions::insert::<CollisionBasics, _>(mutator, id, ());
                           }
                         }));
  let vertex_shader_source = r#"
#version 140
in vec2 direction;
in vec2 center;
in float radius;
out vec2 direction_transfer;

void main() {
direction_transfer = direction*1.5;
gl_Position = vec4 ( center + direction*1.5*radius, 0.0, 1.0);
}

"#;

  let fragment_shader_source = r#"
#version 140
in vec2 direction_transfer;
out vec4 color;

void main() {
if (dot (direction_transfer,direction_transfer) <1.0) {
color = vec4 (1.0, 0.0, 0.0, 1.0);
} else {
color = vec4 (0.0, 0.0, 0.0, 0.0);

}
}

"#;

  let mut snapshots = Vec::new();

if true {
  let display = glium::glutin::WindowBuilder::new()
                  .with_dimensions(600, 600)
                  .build_glium()
                  .expect("failed to create window");
  let program = glium::Program::from_source(&display,
                                            vertex_shader_source,
                                            fragment_shader_source,
                                            None)
                  .expect("glium program generation failed");
let parameters = glium::DrawParameters {blend: glium::draw_parameters::Blend::alpha_blending(),..Default::default()};
  let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);
  let start = Instant::now();
  loop {
    for ev in display.poll_events() {
      match ev {
        glium::glutin::Event::Closed => return,
        _ => (),
      }
    }

    let mut target = display.draw();
    target.clear_color(0.0, 0.0, 0.0, 1.0);
    let mut vertices = Vec::<Vertex>::new();

    let snapshot = stew.snapshot_before(&(((start.elapsed().as_secs() as i64*1000000000i64)+start.elapsed().subsec_nanos() as i64) * SECOND /
                                          1000000000i64))
                       .expect("steward failed to provide snapshot");
    for index in 0..HOW_MANY_CIRCLES {
      let (circle, time) = snapshot.data_and_last_change::<Circle>(get_circle_id(index))
                                   .expect("missing circle")
                                   .clone();
      let position = circle.position.updated_by(snapshot.now() - time).evaluate();
      let center = [position[0] as f32 / ARENA_SIZE as f32 - 0.5, position[1] as f32 / ARENA_SIZE as f32 - 0.5];
      let radius = circle.radius as f32 / ARENA_SIZE as f32;
    //printlnerr!("drawing circ at {}, {}", center[0],center[1]);
      vertices.extend(&[Vertex {
                          center: center,
                          radius: radius,
                          direction: [1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [-1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [0.0, 1.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [-1.0, 0.0],
                        },
                        Vertex {
                          center: center,
                          radius: radius,
                          direction: [0.0, -1.0],
                        }]);

    }
    target.draw(&glium::VertexBuffer::new(&display, &vertices).expect("failed to generate glium Vertex buffer"),
                &indices,
                &program,
                &glium::uniforms::EmptyUniforms,
                & parameters)
          .expect("failed target.draw");

    target.finish().expect("failed to finish drawing");

}
    sleep(Duration::from_millis(10));
  }

  for increment in 1..21 {
    snapshots.push(stew.snapshot_before(&(increment * SECOND * 2)));
  }
  for snapshot in snapshots.iter_mut().map(|option| {
    option.as_mut().expect("all these snapshots should have been valid")
  }) {
    printlnerr!("snapshot for {}", snapshot.now());
    for index in 0..HOW_MANY_CIRCLES {
      // printlnerr!("{}", snapshot.get::<Circle> (get_circle_id (index)).expect("missing circle").position);
    }
  }
  // panic!("anyway")
}

#[test]
fn actuallytest() {
  testfunc();
}
<|endoftext|>


<commit_before>extern crate clingo;

use std::env;
use std::ffi::CString;
use clingo::*;

fn error_main() {
    let error_message = safe_clingo_error_message();
    println!("{}", error_message);
    safe_clingo_error_code();
}

fn main() {

    // create a control object and pass command line arguments
    let logger: clingo_logger_t = None;
    let logger_data = std::ptr::null_mut();
    let mut ctl = ClingoControl::new(env::args(), logger, logger_data, 20)
        .expect("Failed creating clingo_control");

println!("ctl: {:?}",ctl);

    // add a logic program to the base part
    let parameters: Vec<&str> = Vec::new();
    let err = ctl.add("base", parameters, "a. {b}. #external c.");
    if !err {
        return error_main();
    }

println!("ctl: {:?}",ctl);

    // ground the base part
    let part = ClingoPart {
        name: CString::new("base").unwrap(),
        params: &[],
    };
    let parts = vec![part];
    let ground_callback = None;
    let ground_callback_data = std::ptr::null_mut();
    let err = ctl.ground(parts, ground_callback, ground_callback_data);
    if !err {
        return error_main();
    }

    // get symbolic atoms
    let atoms = ctl.symbolic_atoms().unwrap();

    println!("Symbolic atoms:{:?}",atoms);

    // get begin and end iterator
    let mut it_a = atoms.begin(None).unwrap();
    let ie_a = atoms.end().unwrap();

    loop {
        if atoms.iterator_is_equal_to(it_a, ie_a).unwrap() {
            break;
        }
        let symbol = atoms.symbol(it_a).unwrap();
        let atom_string = safe_clingo_symbol_to_string(&symbol).unwrap();
        print!("  {}", atom_string.to_str().unwrap());

        if atoms.is_fact(it_a).unwrap() {
            print!(", fact");
        }

        if atoms.is_external(it_a).unwrap() {
            print!(", external");
        }
        println!("");

        it_a = atoms.next(it_a).unwrap();
    }
}
<commit_msg>fix output<commit_after>extern crate clingo;

use std::env;
use std::ffi::CString;
use clingo::*;

fn error_main() {
    let error_message = safe_clingo_error_message();
    println!("{}", error_message);
    safe_clingo_error_code();
}

fn main() {

    // create a control object and pass command line arguments
    let logger: clingo_logger_t = None;
    let logger_data = std::ptr::null_mut();
    let mut ctl = ClingoControl::new(env::args(), logger, logger_data, 20)
        .expect("Failed creating clingo_control");

    // add a logic program to the base part
    let parameters: Vec<&str> = Vec::new();
    let err = ctl.add("base", parameters, "a. {b}. #external c.");
    if !err {
        return error_main();
    }

    // ground the base part
    let part = ClingoPart {
        name: CString::new("base").unwrap(),
        params: &[],
    };
    let parts = vec![part];
    let ground_callback = None;
    let ground_callback_data = std::ptr::null_mut();
    let err = ctl.ground(parts, ground_callback, ground_callback_data);
    if !err {
        return error_main();
    }

    // get symbolic atoms
    let atoms = ctl.symbolic_atoms().unwrap();

    println!("Symbolic atoms:");

    // get begin and end iterator
    let mut it_a = atoms.begin(None).unwrap();
    let ie_a = atoms.end().unwrap();

    loop {
        if atoms.iterator_is_equal_to(it_a, ie_a).unwrap() {
            break;
        }
        let symbol = atoms.symbol(it_a).unwrap();
        let atom_string = safe_clingo_symbol_to_string(&symbol).unwrap();
        print!("  {}", atom_string.to_str().unwrap());

        if atoms.is_fact(it_a).unwrap() {
            print!(", fact");
        }

        if atoms.is_external(it_a).unwrap() {
            print!(", external");
        }
        println!("");

        it_a = atoms.next(it_a).unwrap();
    }
}
<|endoftext|>