<commit_before>use std::collections::{Bitv, bitv};
use std::{iter, cmp};
use std::num::Float;

use Factors;

/// Stores information about primes up to some limit.
///
/// This uses at least `limit / 16 + O(1)` bytes of storage.
pub struct Primes {
    // This only stores odd numbers, since even numbers are mostly
    // non-prime.
    v: Bitv
}

/// Iterator over the primes stored in a sieve.
#[derive(Clone)]
pub struct PrimeIterator<'a> {
    two: bool,
    iter: iter::Enumerate<bitv::Iter<'a>>,
}

impl Primes {
    /// Construct a `Primes` via a sieve up to at least `limit`.
    ///
    /// This stores all primes less than `limit` (and possibly some
    /// more), allowing for very efficient iteration and primality
    /// testing below this, and guarantees that all numbers up to
    /// `limit^2` can be factorised.
    pub fn sieve(limit: usize) -> Primes {
        // having this out-of-line like this is faster (130 us/iter
        // vs. 111 us/iter on sieve_large), and using a manual while
        // rather than a `range_step` is a similar speedup.
        #[inline(never)]
        fn filter(is_prime: &mut Bitv, limit: usize, check: usize, p: usize) {
            let mut zero = 2 * check * (check + 1);
            while zero < limit / 2 {
                is_prime.set(zero, false);
                zero += p;
            }
        }

        // bad stuff happens for very small bounds.
        let limit = cmp::max(10, limit);

        let mut is_prime = Bitv::from_elem((limit + 1) / 2, true);
        // 1 isn't prime
        is_prime.set(0, false);

        // multiples of 3 aren't prime (3 is handled separately, so
        // the ticking works properly)
        filter(&mut is_prime, limit, 1, 3);

        let bound = (limit as f64).sqrt() as usize + 1;
        // skip 2.
        let mut check = 2;
        let mut tick = if check % 3 == 1 {2} else {1};

        while check <= bound {
            if is_prime[check] {
                filter(&mut is_prime, limit, check, 2 * check + 1)
            }

            check += tick;
            tick = 3 - tick;
        }

        Primes { v: is_prime }
    }

    /// The largest number stored.
    pub fn upper_bound(&self) -> usize {
        (self.v.len() - 1) * 2 + 1
    }

    /// Check if `n` is prime, possibly failing if `n` is larger than
    /// the upper bound of this Primes instance.
    pub fn is_prime(&self, n: usize) -> bool {
        if n % 2 == 0 {
            // 2 is the evenest prime.
            n == 2
        } else {
            assert!(n <= self.upper_bound());
            self.v[n / 2]
        }
    }

    /// Iterator over the primes stored in this map.
    pub fn primes<'a>(&'a self) -> PrimeIterator<'a> {
        PrimeIterator {
            two: true,
            iter: self.v.iter().enumerate()
        }
    }

    /// Factorise `n` into (prime, exponent) pairs.
    ///
    /// Returns `Err((leftover, partial factorisation))` if `n` cannot
    /// be fully factored, or if `n` is zero (`leftover == 0`). A
    /// number can not be completely factored if and only if the prime
    /// factors of `n` are too large for this sieve, that is, if there
    /// is
    ///
    /// - a prime factor larger than `U^2`, or
    /// - more than one prime factor between `U` and `U^2`
    ///
    /// where `U` is the upper bound of the primes stored in this
    /// sieve.
    ///
    /// Notably, any number between `U` and `U^2` can always be fully
    /// factored, since these numbers are guaranteed to only have zero
    /// or one prime factors larger than `U`.
    pub fn factor(&self, mut n: usize) -> Result<Factors, (usize, Factors)> {
        if n == 0 { return Err((0, vec![])) }

        let mut ret = Vec::new();

        for p in self.primes() {
            if n == 1 { break }

            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            if count > 0 {
                ret.push((p,count));
            }
        }
        if n != 1 {
            let b = self.upper_bound();
            if b * b >= n {
                // n is not divisible by anything from 1...sqrt(n), so
                // must be prime itself! (That is, even though we
                // don't know this prime specifically, we can infer
                // that it must be prime.)
                ret.push((n, 1));
            } else {
                // large factors :(
                return Err((n, ret))
            }
        }
        Ok(ret)
    }
}

impl<'a> Iterator for PrimeIterator<'a> {
    type Item = usize;
    #[inline]
    fn next(&mut self) -> Option<usize> {
        if self.two {
            self.two = false;
            Some(2)
        } else {
            for (i, is_prime) in self.iter {
                if is_prime {
                    return Some(2 * i + 1)
                }
            }
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let mut iter = self.clone();
        // TODO: this doesn't run in constant time, is it super-bad?
        match (iter.next(), iter.next_back()) {
            (Some(lo), Some(hi)) => {
                let (below_hi, above_hi) = ::estimate_prime_pi(hi as u64);
                let (below_lo, above_lo) = ::estimate_prime_pi(lo as u64);

                ((below_hi - cmp::min(above_lo, below_hi)) as usize,
                 Some((above_hi - below_lo + 1) as usize))
            }
            (Some(_), None) => (1, Some(1)),
            (None, _) => (0, Some(0))
        }
    }
}

impl<'a> DoubleEndedIterator for PrimeIterator<'a> {
    #[inline]
    fn next_back(&mut self) -> Option<usize> {
        loop {
            match self.iter.next_back() {
                Some((i, true)) => return Some(2 * i + 1),
                Some((_, false)) => {/* continue */}
                None if self.two => {
                    self.two = false;
                    return Some(2)
                }
                None => return None
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use test::Bencher;
    use super::Primes;
    use std::num::Int;
    use std::iter::range_step;

    #[test]
    fn is_prime() {
        let primes = Primes::sieve(1000);
        let tests = [
            (0, false),
            (1, false),
            (2, true),
            (3, true),
            (4, false),
            (5, true),
            (6, false),
            (7, true),
            (8, false),
            (9, false),
            (10, false),
            (11, true)
                ];

        for &(n, expected) in tests.iter() {
            assert_eq!(primes.is_prime(n), expected);
        }
    }

    #[test]
    fn upper_bound() {
        let primes = Primes::sieve(30);
        assert_eq!(primes.upper_bound(), 29);
        let primes = Primes::sieve(31);
        assert_eq!(primes.upper_bound(), 31);

        let primes = Primes::sieve(30000);
        assert_eq!(primes.upper_bound(), 29999);
        let primes = Primes::sieve(30001);
        assert_eq!(primes.upper_bound(), 30001);
    }

    #[test]
    fn primes_iterator() {
        let primes = Primes::sieve(50);
        let mut expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

        assert_eq!(primes.primes().collect::<Vec<usize>>().as_slice(),
                   expected.as_slice());

        expected.reverse();
        assert_eq!(primes.primes().rev().collect::<Vec<usize>>().as_slice(),
                   expected.as_slice());
    }

    #[test]
    fn factor() {
        let primes = Primes::sieve(1000);

        let tests: &[(usize, &[(usize, usize)])] = &[
            (1, &[]),
            (2, &[(2_us, 1)]),
            (3, &[(3, 1)]),
            (4, &[(2, 2)]),
            (5, &[(5, 1)]),
            (6, &[(2, 1), (3, 1)]),
            (7, &[(7, 1)]),
            (8, &[(2, 3)]),
            (9, &[(3, 2)]),
            (10, &[(2, 1), (5, 1)]),

            (2*2*2*2*2 * 3*3*3*3*3, &[(2, 5), (3,5)]),
            (2*3*5*7*11*13*17*19, &[(2,1), (3,1), (5,1), (7,1), (11,1), (13,1), (17,1), (19,1)]),
            // a factor larger than that stored in the map
            (7561, &[(7561, 1)]),
            (2*7561, &[(2, 1), (7561, 1)]),
            (4*5*7561, &[(2, 2), (5,1), (7561, 1)]),
            ];
        for &(n, expected) in tests.iter() {
            assert_eq!(primes.factor(n), Ok(expected.to_vec()));
        }
    }

    #[test]
    fn factor_compare() {
        let short = Primes::sieve(30);
        let long = Primes::sieve(10000);

        let short_lim = short.upper_bound() * short.upper_bound() + 1;

        // every number less than bound^2 can be factored (since they
        // always have a factor <= bound).
        for n in range(0, short_lim) {
            assert_eq!(short.factor(n), long.factor(n))
        }
        // larger numbers can only sometimes be factored
        'next_n: for n in range(short_lim, 10000) {
            let possible = short.factor(n);
            let real = long.factor(n).unwrap();

            let mut seen_small = None;
            for (this_idx, &(p,i)) in real.iter().enumerate() {
                let last_short_prime = if p >= short_lim {
                    this_idx
                } else if p > short.upper_bound() {
                    match seen_small {
                        Some(idx) => idx,
                        None if i > 1 => this_idx,
                        None => {
                            // we can cope with one
                            seen_small = Some(this_idx);
                            continue
                        }
                    }
                } else {
                    // small enough
                    continue
                };

                // break into the two parts
                let (low, hi) = real.as_slice().split_at(last_short_prime);
                let leftover = hi.iter().fold(1, |x, &(p, i)| x * p.pow(i));

                assert_eq!(possible, Err((leftover, low.to_vec())));
                continue 'next_n;
            }

            // if we're here, we know that everything should match
            assert_eq!(possible, Ok(real))
        }
    }

    #[test]
    fn factor_failures() {
        let primes = Primes::sieve(30);

        assert_eq!(primes.factor(0),
                   Err((0, vec![])));
        // can only handle one large factor
        assert_eq!(primes.factor(31 * 31),
                   Err((31 * 31, vec![])));
        assert_eq!(primes.factor(2 * 3 * 31 * 31),
                   Err((31 * 31, vec![(2, 1), (3, 1)])));

        // prime that's too large (bigger than 30*30).
        assert_eq!(primes.factor(7561),
                   Err((7561, vec![])));
        assert_eq!(primes.factor(2 * 3 * 7561),
                   Err((7561, vec![(2, 1), (3, 1)])));
    }

    #[test]
    fn size_hint() {
        for i in range_step(0, 1000, 100) {
            let sieve = Primes::sieve(i);

            let mut primes = sieve.primes();

            // check the size hint at each and every iteration
            loop {
                let (lo, hi) = primes.size_hint();

                let copy = primes.clone();
                let len = copy.count();

                let next = primes.next();

                assert!(lo <= len && len <= hi.unwrap(),
                        "found failing size_hint for {:?} to {}, should satisfy: {} <= {} <= {:?}",
                        next, i, lo, len, hi);

                if next.is_none() {
                    break
                }
            }
        }
    }

    #[bench]
    fn sieve_small(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100))
    }
    #[bench]
    fn sieve_medium(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000))
    }
    #[bench]
    fn sieve_large(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100_000))
    }
    #[bench]
    fn sieve_huge(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000_000))
    }

    fn bench_iterate(b: &mut Bencher, upto: usize) {
        let sieve = Primes::sieve(upto);

        b.iter(|| {
            sieve.primes().count()
        })
    }

    #[bench]
    fn iterate_small(b: &mut Bencher) { bench_iterate(b, 100) }
    #[bench]
    fn iterate_large(b: &mut Bencher) { bench_iterate(b, 100_000) }
}
<commit_msg>Update to 4e4e8cff1 2015-01-24 22:14:14 +0000.<commit_after>use std::collections::{Bitv, bitv};
use std::{iter, cmp};
use std::num::Float;

use Factors;

/// Stores information about primes up to some limit.
///
/// This uses at least `limit / 16 + O(1)` bytes of storage.
pub struct Primes {
    // This only stores odd numbers, since even numbers are mostly
    // non-prime.
    v: Bitv
}

/// Iterator over the primes stored in a sieve.
#[derive(Clone)]
pub struct PrimeIterator<'a> {
    two: bool,
    iter: iter::Enumerate<bitv::Iter<'a>>,
}

impl Primes {
    /// Construct a `Primes` via a sieve up to at least `limit`.
    ///
    /// This stores all primes less than `limit` (and possibly some
    /// more), allowing for very efficient iteration and primality
    /// testing below this, and guarantees that all numbers up to
    /// `limit^2` can be factorised.
    pub fn sieve(limit: usize) -> Primes {
        // having this out-of-line like this is faster (130 us/iter
        // vs. 111 us/iter on sieve_large), and using a manual while
        // rather than a `range_step` is a similar speedup.
        #[inline(never)]
        fn filter(is_prime: &mut Bitv, limit: usize, check: usize, p: usize) {
            let mut zero = 2 * check * (check + 1);
            while zero < limit / 2 {
                is_prime.set(zero, false);
                zero += p;
            }
        }

        // bad stuff happens for very small bounds.
        let limit = cmp::max(10, limit);

        let mut is_prime = Bitv::from_elem((limit + 1) / 2, true);
        // 1 isn't prime
        is_prime.set(0, false);

        // multiples of 3 aren't prime (3 is handled separately, so
        // the ticking works properly)
        filter(&mut is_prime, limit, 1, 3);

        let bound = (limit as f64).sqrt() as usize + 1;
        // skip 2.
        let mut check = 2;
        let mut tick = if check % 3 == 1 {2} else {1};

        while check <= bound {
            if is_prime[check] {
                filter(&mut is_prime, limit, check, 2 * check + 1)
            }

            check += tick;
            tick = 3 - tick;
        }

        Primes { v: is_prime }
    }

    /// The largest number stored.
    pub fn upper_bound(&self) -> usize {
        (self.v.len() - 1) * 2 + 1
    }

    /// Check if `n` is prime, possibly failing if `n` is larger than
    /// the upper bound of this Primes instance.
    pub fn is_prime(&self, n: usize) -> bool {
        if n % 2 == 0 {
            // 2 is the evenest prime.
            n == 2
        } else {
            assert!(n <= self.upper_bound());
            self.v[n / 2]
        }
    }

    /// Iterator over the primes stored in this map.
    pub fn primes<'a>(&'a self) -> PrimeIterator<'a> {
        PrimeIterator {
            two: true,
            iter: self.v.iter().enumerate()
        }
    }

    /// Factorise `n` into (prime, exponent) pairs.
    ///
    /// Returns `Err((leftover, partial factorisation))` if `n` cannot
    /// be fully factored, or if `n` is zero (`leftover == 0`). A
    /// number can not be completely factored if and only if the prime
    /// factors of `n` are too large for this sieve, that is, if there
    /// is
    ///
    /// - a prime factor larger than `U^2`, or
    /// - more than one prime factor between `U` and `U^2`
    ///
    /// where `U` is the upper bound of the primes stored in this
    /// sieve.
    ///
    /// Notably, any number between `U` and `U^2` can always be fully
    /// factored, since these numbers are guaranteed to only have zero
    /// or one prime factors larger than `U`.
    pub fn factor(&self, mut n: usize) -> Result<Factors, (usize, Factors)> {
        if n == 0 { return Err((0, vec![])) }

        let mut ret = Vec::new();

        for p in self.primes() {
            if n == 1 { break }

            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            if count > 0 {
                ret.push((p,count));
            }
        }
        if n != 1 {
            let b = self.upper_bound();
            if b * b >= n {
                // n is not divisible by anything from 1...sqrt(n), so
                // must be prime itself! (That is, even though we
                // don't know this prime specifically, we can infer
                // that it must be prime.)
                ret.push((n, 1));
            } else {
                // large factors :(
                return Err((n, ret))
            }
        }
        Ok(ret)
    }
}

impl<'a> Iterator for PrimeIterator<'a> {
    type Item = usize;
    #[inline]
    fn next(&mut self) -> Option<usize> {
        if self.two {
            self.two = false;
            Some(2)
        } else {
            for (i, is_prime) in self.iter {
                if is_prime {
                    return Some(2 * i + 1)
                }
            }
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let mut iter = self.clone();
        // TODO: this doesn't run in constant time, is it super-bad?
        match (iter.next(), iter.next_back()) {
            (Some(lo), Some(hi)) => {
                let (below_hi, above_hi) = ::estimate_prime_pi(hi as u64);
                let (below_lo, above_lo) = ::estimate_prime_pi(lo as u64);

                ((below_hi - cmp::min(above_lo, below_hi)) as usize,
                 Some((above_hi - below_lo + 1) as usize))
            }
            (Some(_), None) => (1, Some(1)),
            (None, _) => (0, Some(0))
        }
    }
}

impl<'a> DoubleEndedIterator for PrimeIterator<'a> {
    #[inline]
    fn next_back(&mut self) -> Option<usize> {
        loop {
            match self.iter.next_back() {
                Some((i, true)) => return Some(2 * i + 1),
                Some((_, false)) => {/* continue */}
                None if self.two => {
                    self.two = false;
                    return Some(2)
                }
                None => return None
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use test::Bencher;
    use super::Primes;
    use std::num::Int;
    use std::iter::range_step;

    #[test]
    fn is_prime() {
        let primes = Primes::sieve(1000);
        let tests = [
            (0, false),
            (1, false),
            (2, true),
            (3, true),
            (4, false),
            (5, true),
            (6, false),
            (7, true),
            (8, false),
            (9, false),
            (10, false),
            (11, true)
                ];

        for &(n, expected) in tests.iter() {
            assert_eq!(primes.is_prime(n), expected);
        }
    }

    #[test]
    fn upper_bound() {
        let primes = Primes::sieve(30);
        assert_eq!(primes.upper_bound(), 29);
        let primes = Primes::sieve(31);
        assert_eq!(primes.upper_bound(), 31);

        let primes = Primes::sieve(30000);
        assert_eq!(primes.upper_bound(), 29999);
        let primes = Primes::sieve(30001);
        assert_eq!(primes.upper_bound(), 30001);
    }

    #[test]
    fn primes_iterator() {
        let primes = Primes::sieve(50);
        let mut expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

        assert_eq!(primes.primes().collect::<Vec<usize>>().as_slice(),
                   expected.as_slice());

        expected.reverse();
        assert_eq!(primes.primes().rev().collect::<Vec<usize>>().as_slice(),
                   expected.as_slice());
    }

    #[test]
    fn factor() {
        let primes = Primes::sieve(1000);

        let tests: &[(usize, &[(usize, usize)])] = &[
            (1, &[]),
            (2, &[(2_us, 1)]),
            (3, &[(3, 1)]),
            (4, &[(2, 2)]),
            (5, &[(5, 1)]),
            (6, &[(2, 1), (3, 1)]),
            (7, &[(7, 1)]),
            (8, &[(2, 3)]),
            (9, &[(3, 2)]),
            (10, &[(2, 1), (5, 1)]),

            (2*2*2*2*2 * 3*3*3*3*3, &[(2, 5), (3,5)]),
            (2*3*5*7*11*13*17*19, &[(2,1), (3,1), (5,1), (7,1), (11,1), (13,1), (17,1), (19,1)]),
            // a factor larger than that stored in the map
            (7561, &[(7561, 1)]),
            (2*7561, &[(2, 1), (7561, 1)]),
            (4*5*7561, &[(2, 2), (5,1), (7561, 1)]),
            ];
        for &(n, expected) in tests.iter() {
            assert_eq!(primes.factor(n), Ok(expected.to_vec()));
        }
    }

    #[test]
    fn factor_compare() {
        let short = Primes::sieve(30);
        let long = Primes::sieve(10000);

        let short_lim = short.upper_bound() * short.upper_bound() + 1;

        // every number less than bound^2 can be factored (since they
        // always have a factor <= bound).
        for n in range(0, short_lim) {
            assert_eq!(short.factor(n), long.factor(n))
        }
        // larger numbers can only sometimes be factored
        'next_n: for n in range(short_lim, 10000) {
            let possible = short.factor(n);
            let real = long.factor(n).ok().unwrap();

            let mut seen_small = None;
            for (this_idx, &(p,i)) in real.iter().enumerate() {
                let last_short_prime = if p >= short_lim {
                    this_idx
                } else if p > short.upper_bound() {
                    match seen_small {
                        Some(idx) => idx,
                        None if i > 1 => this_idx,
                        None => {
                            // we can cope with one
                            seen_small = Some(this_idx);
                            continue
                        }
                    }
                } else {
                    // small enough
                    continue
                };

                // break into the two parts
                let (low, hi) = real.as_slice().split_at(last_short_prime);
                let leftover = hi.iter().fold(1, |x, &(p, i)| x * p.pow(i));

                assert_eq!(possible, Err((leftover, low.to_vec())));
                continue 'next_n;
            }

            // if we're here, we know that everything should match
            assert_eq!(possible, Ok(real))
        }
    }

    #[test]
    fn factor_failures() {
        let primes = Primes::sieve(30);

        assert_eq!(primes.factor(0),
                   Err((0, vec![])));
        // can only handle one large factor
        assert_eq!(primes.factor(31 * 31),
                   Err((31 * 31, vec![])));
        assert_eq!(primes.factor(2 * 3 * 31 * 31),
                   Err((31 * 31, vec![(2, 1), (3, 1)])));

        // prime that's too large (bigger than 30*30).
        assert_eq!(primes.factor(7561),
                   Err((7561, vec![])));
        assert_eq!(primes.factor(2 * 3 * 7561),
                   Err((7561, vec![(2, 1), (3, 1)])));
    }

    #[test]
    fn size_hint() {
        for i in range_step(0, 1000, 100) {
            let sieve = Primes::sieve(i);

            let mut primes = sieve.primes();

            // check the size hint at each and every iteration
            loop {
                let (lo, hi) = primes.size_hint();

                let copy = primes.clone();
                let len = copy.count();

                let next = primes.next();

                assert!(lo <= len && len <= hi.unwrap(),
                        "found failing size_hint for {:?} to {}, should satisfy: {} <= {} <= {:?}",
                        next, i, lo, len, hi);

                if next.is_none() {
                    break
                }
            }
        }
    }

    #[bench]
    fn sieve_small(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100))
    }
    #[bench]
    fn sieve_medium(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000))
    }
    #[bench]
    fn sieve_large(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100_000))
    }
    #[bench]
    fn sieve_huge(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000_000))
    }

    fn bench_iterate(b: &mut Bencher, upto: usize) {
        let sieve = Primes::sieve(upto);

        b.iter(|| {
            sieve.primes().count()
        })
    }

    #[bench]
    fn iterate_small(b: &mut Bencher) { bench_iterate(b, 100) }
    #[bench]
    fn iterate_large(b: &mut Bencher) { bench_iterate(b, 100_000) }
}
<|endoftext|>


<commit_before>use std::slice::{Iter, IterMut};

#[derive(Clone)]
pub struct Stack<T> {
    vec: Vec<T>,
    focus: Option<usize>,
}

impl<T> Stack<T> {
    pub fn new() -> Stack<T> {
        Stack {
            vec: Vec::new(),
            focus: None,
        }
    }

    pub fn push(&mut self, value: T) {
        self.vec.push(value);
        self.ensure_focus();
    }

    pub fn remove<P>(&mut self, p: P) -> T
        where P: FnMut(&T) -> bool
    {
        let position = self.vec
            .iter()
            .position(p)
            .expect("No element in stack matches predicate");
        let element = self.vec.remove(position);
        // Focus might now be pointing at the wrong element. If we
        self.fix_focus_after_removal(position);
        element
    }

    /// Removes the focused element (if any) and returns it.
    pub fn remove_focused(&mut self) -> Option<T> {
        let element = self.focus.map(|idx| self.vec.remove(idx));
        if let Some(removed_idx) = self.focus {
            self.fix_focus_after_removal(removed_idx);
        }
        element
    }

    /// Updates the focus index into the vector, as it may be pointing at the
    /// wrong element after a removal.
    fn fix_focus_after_removal(&mut self, removed_idx: usize) {
        self.focus = self.focus
            .and_then(|idx| if self.vec.is_empty() { None } else { Some(idx) })
            .map(|idx| if idx > removed_idx || (idx == removed_idx && idx == self.vec.len()) {
                     idx - 1
                 } else {
                     idx
                 });
    }

    pub fn iter(&self) -> Iter<T> {
        self.vec.iter()
    }

    pub fn iter_mut(&mut self) -> IterMut<T> {
        self.vec.iter_mut()
    }

    pub fn focused(&self) -> Option<&T> {
        self.focus
            .and_then(|idx| {
                let item = self.vec.get(idx);
                // `focus` should always point to a valid element of `vec`. If not, we've
                // broken an invariant. Allow execution to continue, as it should be possible
                // for the user to work around this in most cases.
                if item.is_none() {
                    error!("Stack's focus index ({}) is greater than it's length ({})",
                           idx,
                           self.vec.len());
                }
                item
            })
    }

    pub fn focused_mut(&mut self) -> Option<&mut T> {
        self.focus
            .and_then(move |idx| {
                let item = self.vec.get_mut(idx);
                // `focus` should always point to a valid element of `vec`. If not, we've
                // broken an invariant. Allow execution to continue, as it should be possible
                // for the user to work around this in most cases.
                if item.is_none() {
                    error!("Stack's focus index ({}) is greater than it's length", idx);
                }
                item
            })
    }

    /// Focuses the first element in the stack that matches the predicate.
    ///
    /// Panics if no element matches the predicate.
    pub fn focus<P>(&mut self, p: P)
        where P: FnMut(&T) -> bool
    {
        let position = self.vec
            .iter()
            .position(p)
            .expect("No element in stack matches predicate");
        self.focus = Some(position);
    }

    fn ensure_focus(&mut self) {
        self.focus = self.focus
            .or(if self.vec.is_empty() { None } else { Some(0) });
    }

    fn next_index(&self, index: usize) -> usize {
        (index + 1) % self.vec.len()
    }

    fn previous_index(&self, index: usize) -> usize {
        if index == 0 {
            self.vec.len() - 1
        } else {
            (index - 1) % self.vec.len()
        }
    }

    pub fn focus_next(&mut self) {
        self.focus = self.focus.map(|idx| self.next_index(idx));
    }

    pub fn focus_previous(&mut self) {
        self.focus = self.focus.map(|idx| self.previous_index(idx));
    }

    pub fn shuffle_next(&mut self) {
        if let Some(current_idx) = self.focus {
            let next_idx = self.next_index(current_idx);
            if next_idx == 0 {
                let item = self.vec.remove(current_idx);
                self.vec.insert(0, item);
            } else {
                self.vec.swap(current_idx, next_idx);
            }
            self.focus = Some(next_idx);
        }
    }

    pub fn shuffle_previous(&mut self) {
        if let Some(current_idx) = self.focus {
            let prev_idx = self.previous_index(current_idx);
            if prev_idx == self.vec.len() - 1 {
                let item = self.vec.remove(current_idx);
                self.vec.push(item);
            } else {
                self.vec.swap(current_idx, prev_idx);
            }
            self.focus = Some(prev_idx);
        }
    }
}

impl<T> From<Vec<T>> for Stack<T> {
    fn from(vec: Vec<T>) -> Self {
        let mut stack = Stack {
            vec: vec,
            focus: None,
        };
        stack.ensure_focus();
        stack
    }
}

#[cfg(test)]
mod test {
    use super::Stack;

    #[test]
    fn test_from() {
        let vec = vec![1, 2, 3];
        let stack = Stack::from(vec.clone());
        assert_eq!(stack.vec, vec);
        assert_eq!(stack.focused(), Some(&vec[0]));
    }

    #[test]
    fn test_push() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        assert_eq!(stack.vec, vec![2]);
    }

    #[test]
    fn test_remove() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.remove(|v| v == &3);
        assert_eq!(stack.vec, vec![2, 4]);
    }

    #[test]
    fn test_remove_updates_focus() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.focus_next();
        assert_eq!(stack.focused(), Some(&3));

        // Remove element before focused element.
        let mut stack1 = stack.clone();
        stack1.remove(|v| v == &2);
        assert_eq!(stack1.focused(), Some(&3));

        // Remove focused element.
        let mut stack2 = stack.clone();
        stack2.remove(|v| v == &3);
        assert_eq!(stack2.focused(), Some(&4));

        // Remove element after focused element.
        let mut stack3 = stack.clone();
        stack3.remove(|v| v == &4);
        assert_eq!(stack3.focused(), Some(&3));

        // Remove focused element where it is also the final element.
        let mut stack4 = stack.clone();
        stack4.focus_next();
        assert_eq!(stack4.focused(), Some(&4));
        stack4.remove(|v| v == &4);
        assert_eq!(stack4.focused(), Some(&3));

        // Remove only element.
        let mut stack5 = Stack::<u8>::new();
        stack5.push(2);
        assert_eq!(stack5.focused(), Some(&2));
        stack5.remove(|v| v == &2);
        assert_eq!(stack5.focus, None);
    }

    #[test]
    fn test_remove_focused() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&2));

        let element = stack.remove_focused();
        assert_eq!(element, Some(2));
        assert_eq!(stack.focused(), Some(&3));
        assert_eq!(stack.vec, vec![3]);
    }

    #[test]
    fn test_remove_focused_when_no_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        let element = stack.remove_focused();
        assert_eq!(element, None);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_iter() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        let mut iter = stack.iter();
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&4));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn test_set_get_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&2));
        stack.remove(|v| v == &2);
        // A non-empty stack should always have something focused.
        assert_eq!(stack.focused(), Some(&3));
        stack.remove(|v| v == &3);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_focus_next() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&2));

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&3));
        stack.focus_next();
        assert_eq!(stack.focused(), Some(&4));
        stack.focus_next();
        assert_eq!(stack.focused(), Some(&2));
    }

    #[test]
    fn test_focus_previous() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&2));

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&4));
        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&3));
        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&2));
    }

    #[test]
    fn test_shuffle_next() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&2));

        assert_eq!(stack.vec, vec![2, 3, 4]);
        stack.shuffle_next();
        assert_eq!(stack.vec, vec![3, 2, 4]);
        stack.shuffle_next();
        assert_eq!(stack.vec, vec![3, 4, 2]);
        stack.shuffle_next();
        assert_eq!(stack.vec, vec![2, 3, 4]);
    }

    #[test]
    fn test_shuffle_previous() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&2));

        assert_eq!(stack.vec, vec![2, 3, 4]);
        stack.shuffle_previous();
        assert_eq!(stack.vec, vec![3, 4, 2]);
        stack.shuffle_previous();
        assert_eq!(stack.vec, vec![3, 2, 4]);
        stack.shuffle_previous();
        assert_eq!(stack.vec, vec![2, 3, 4]);
    }
}
<commit_msg>Focus element when adding it to stack.<commit_after>use std::slice::{Iter, IterMut};

#[derive(Clone)]
pub struct Stack<T> {
    vec: Vec<T>,
    focus: Option<usize>,
}

impl<T> Stack<T> {
    pub fn new() -> Stack<T> {
        Stack {
            vec: Vec::new(),
            focus: None,
        }
    }

    /// Adds an element to the stack (at the end) and focuses it.
    pub fn push(&mut self, value: T) {
        self.vec.push(value);
        self.focus = Some(self.vec.len() - 1);
    }

    pub fn remove<P>(&mut self, p: P) -> T
        where P: FnMut(&T) -> bool
    {
        let position = self.vec
            .iter()
            .position(p)
            .expect("No element in stack matches predicate");
        let element = self.vec.remove(position);
        // Focus might now be pointing at the wrong element. If we
        self.fix_focus_after_removal(position);
        element
    }

    /// Removes the focused element (if any) and returns it.
    pub fn remove_focused(&mut self) -> Option<T> {
        let element = self.focus.map(|idx| self.vec.remove(idx));
        if let Some(removed_idx) = self.focus {
            self.fix_focus_after_removal(removed_idx);
        }
        element
    }

    /// Updates the focus index into the vector, as it may be pointing at the
    /// wrong element after a removal.
    fn fix_focus_after_removal(&mut self, removed_idx: usize) {
        self.focus = self.focus
            .and_then(|idx| if self.vec.is_empty() { None } else { Some(idx) })
            .map(|idx| if idx > removed_idx || (idx == removed_idx && idx == self.vec.len()) {
                     idx - 1
                 } else {
                     idx
                 });
    }

    pub fn iter(&self) -> Iter<T> {
        self.vec.iter()
    }

    pub fn iter_mut(&mut self) -> IterMut<T> {
        self.vec.iter_mut()
    }

    pub fn focused(&self) -> Option<&T> {
        self.focus
            .and_then(|idx| {
                let item = self.vec.get(idx);
                // `focus` should always point to a valid element of `vec`. If not, we've
                // broken an invariant. Allow execution to continue, as it should be possible
                // for the user to work around this in most cases.
                if item.is_none() {
                    error!("Stack's focus index ({}) is greater than it's length ({})",
                           idx,
                           self.vec.len());
                }
                item
            })
    }

    pub fn focused_mut(&mut self) -> Option<&mut T> {
        self.focus
            .and_then(move |idx| {
                let item = self.vec.get_mut(idx);
                // `focus` should always point to a valid element of `vec`. If not, we've
                // broken an invariant. Allow execution to continue, as it should be possible
                // for the user to work around this in most cases.
                if item.is_none() {
                    error!("Stack's focus index ({}) is greater than it's length", idx);
                }
                item
            })
    }

    /// Focuses the first element in the stack that matches the predicate.
    ///
    /// Panics if no element matches the predicate.
    pub fn focus<P>(&mut self, p: P)
        where P: FnMut(&T) -> bool
    {
        let position = self.vec
            .iter()
            .position(p)
            .expect("No element in stack matches predicate");
        self.focus = Some(position);
    }

    fn ensure_focus(&mut self) {
        self.focus = self.focus
            .or(if self.vec.is_empty() { None } else { Some(0) });
    }

    fn next_index(&self, index: usize) -> usize {
        (index + 1) % self.vec.len()
    }

    fn previous_index(&self, index: usize) -> usize {
        if index == 0 {
            self.vec.len() - 1
        } else {
            (index - 1) % self.vec.len()
        }
    }

    pub fn focus_next(&mut self) {
        self.focus = self.focus.map(|idx| self.next_index(idx));
    }

    pub fn focus_previous(&mut self) {
        self.focus = self.focus.map(|idx| self.previous_index(idx));
    }

    pub fn shuffle_next(&mut self) {
        if let Some(current_idx) = self.focus {
            let next_idx = self.next_index(current_idx);
            if next_idx == 0 {
                let item = self.vec.remove(current_idx);
                self.vec.insert(0, item);
            } else {
                self.vec.swap(current_idx, next_idx);
            }
            self.focus = Some(next_idx);
        }
    }

    pub fn shuffle_previous(&mut self) {
        if let Some(current_idx) = self.focus {
            let prev_idx = self.previous_index(current_idx);
            if prev_idx == self.vec.len() - 1 {
                let item = self.vec.remove(current_idx);
                self.vec.push(item);
            } else {
                self.vec.swap(current_idx, prev_idx);
            }
            self.focus = Some(prev_idx);
        }
    }
}

impl<T> From<Vec<T>> for Stack<T> {
    fn from(vec: Vec<T>) -> Self {
        let mut stack = Stack {
            vec: vec,
            focus: None,
        };
        stack.ensure_focus();
        stack
    }
}

#[cfg(test)]
mod test {
    use super::Stack;

    #[test]
    fn test_from() {
        let vec = vec![1, 2, 3];
        let stack = Stack::from(vec.clone());
        assert_eq!(stack.vec, vec);
        assert_eq!(stack.focused(), Some(&vec[0]));
    }

    #[test]
    fn test_push() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        assert_eq!(stack.vec, vec![2]);
        assert_eq!(stack.focused(), Some(&2));
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));
    }

    #[test]
    fn test_remove() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.remove(|v| v == &3);
        assert_eq!(stack.vec, vec![2, 4]);
    }

    #[test]
    fn test_remove_updates_focus() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&3));

        // Remove element before focused element.
        let mut stack1 = stack.clone();
        stack1.remove(|v| v == &2);
        assert_eq!(stack1.focused(), Some(&3));

        // Remove focused element.
        let mut stack2 = stack.clone();
        stack2.remove(|v| v == &3);
        assert_eq!(stack2.focused(), Some(&4));

        // Remove element after focused element.
        let mut stack3 = stack.clone();
        stack3.remove(|v| v == &4);
        assert_eq!(stack3.focused(), Some(&3));

        // Remove focused element where it is also the final element.
        let mut stack4 = stack.clone();
        stack4.focus_next();
        assert_eq!(stack4.focused(), Some(&4));
        stack4.remove(|v| v == &4);
        assert_eq!(stack4.focused(), Some(&3));

        // Remove only element.
        let mut stack5 = Stack::<u8>::new();
        stack5.push(2);
        assert_eq!(stack5.focused(), Some(&2));
        stack5.remove(|v| v == &2);
        assert_eq!(stack5.focus, None);
    }

    #[test]
    fn test_remove_focused() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));

        let element = stack.remove_focused();
        assert_eq!(element, Some(3));
        assert_eq!(stack.focused(), Some(&2));
        assert_eq!(stack.vec, vec![2]);
    }

    #[test]
    fn test_remove_focused_when_no_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        let element = stack.remove_focused();
        assert_eq!(element, None);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_iter() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        let mut iter = stack.iter();
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&4));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn test_set_get_focus() {
        let mut stack = Stack::<u8>::new();
        assert_eq!(stack.focused(), None);
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.focused(), Some(&3));
        stack.remove(|v| v == &3);
        // A non-empty stack should always have something focused.
        assert_eq!(stack.focused(), Some(&2));
        stack.remove(|v| v == &2);
        assert_eq!(stack.focused(), None);
    }

    #[test]
    fn test_focus_next() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        stack.focus_next();
        assert_eq!(stack.focused(), Some(&2));
        stack.focus_next();
        assert_eq!(stack.focused(), Some(&3));
        stack.focus_next();
        assert_eq!(stack.focused(), Some(&4));
    }

    #[test]
    fn test_focus_previous() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&3));
        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&2));
        stack.focus_previous();
        assert_eq!(stack.focused(), Some(&4));
    }

    #[test]
    fn test_shuffle_next() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        assert_eq!(stack.vec, vec![2, 3, 4]);
        stack.shuffle_next();
        assert_eq!(stack.vec, vec![4, 2, 3]);
        stack.shuffle_next();
        assert_eq!(stack.vec, vec![2, 4, 3]);
        stack.shuffle_next();
        assert_eq!(stack.vec, vec![2, 3, 4]);
    }

    #[test]
    fn test_shuffle_previous() {
        let mut stack = Stack::<u8>::new();
        stack.push(2);
        stack.push(3);
        stack.push(4);
        assert_eq!(stack.focused(), Some(&4));

        assert_eq!(stack.vec, vec![2, 3, 4]);
        stack.shuffle_previous();
        assert_eq!(stack.vec, vec![2, 4, 3]);
        stack.shuffle_previous();
        assert_eq!(stack.vec, vec![4, 2, 3]);
        stack.shuffle_previous();
        assert_eq!(stack.vec, vec![2, 3, 4]);
    }
}
<|endoftext|>


<commit_before>use std::collections::{HashMap, HashSet, VecDeque};

use ClientId;
use LogIndex;
use ServerId;

/// Consensus modules can be in one of three state:
///
/// * `Follower` - which replicates AppendEntries requests and votes for it's leader.
/// * `Leader` - which leads the cluster by serving incoming requests, ensuring
///              data is replicated, and issuing heartbeats.
/// * `Candidate` -  which campaigns in an election and may become a `Leader`
///                  (if it gets enough votes) or a `Follower`, if it hears from
///                  a `Leader`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConsensusState {
    Follower,
    Candidate,
    Leader,
}

/// The state associated with a Raft consensus module in the `Leader` state.
#[derive(Clone, Debug)]
pub struct LeaderState {
    next_index: HashMap<ServerId, LogIndex>,
    match_index: HashMap<ServerId, LogIndex>,
    /// Stores in-flight client proposals.
    pub proposals: VecDeque<(ClientId, LogIndex)>,
}

impl LeaderState {

    /// Returns a new `LeaderState` struct.
    ///
    /// # Arguments
    ///
    /// * `latest_log_index` - The index of the leader's most recent log entry at the
    ///                        time of election.
    /// * `peers` - The set of peer cluster members.
    pub fn new(latest_log_index: LogIndex, peers: &HashSet<ServerId>) -> LeaderState {
        let next_index = peers.iter().cloned().map(|peer| (peer, latest_log_index + 1)).collect();
        let match_index = peers.iter().cloned().map(|peer| (peer, LogIndex::from(0))).collect();

        LeaderState {
            next_index: next_index,
            match_index: match_index,
            proposals: VecDeque::new(),
        }
    }

    /// Returns the next log entry index of the follower.
    pub fn next_index(&mut self, follower: &ServerId) -> LogIndex {
        self.next_index[follower]
    }

    /// Sets the next log entry index of the follower.
    pub fn set_next_index(&mut self, follower: ServerId, index: LogIndex) {
        self.next_index.insert(follower, index);
    }

    // TODO: why is this never used?
    #[allow(dead_code)]
    /// Returns the index of the highest log entry known to be replicated on
    /// the follower.
    pub fn match_index(&self, follower: &ServerId) -> LogIndex {
        self.match_index[follower]
    }

    /// Sets the index of the highest log entry known to be replicated on the
    /// follower.
    pub fn set_match_index(&mut self, follower: ServerId, index: LogIndex) {
        self.match_index.insert(follower, index);
    }

    /// Counts the number of followers containing the given log index.
    pub fn count_match_indexes(&self, index: LogIndex) -> usize {
        // +1 for self.
        self.match_index.values().filter(|&&i| i >= index).count() + 1
    }

    /// Reinitializes the state following an election.
    pub fn reinitialize(&mut self, latest_log_index: LogIndex) {
        for (_, next_index) in self.next_index.iter_mut() {
            *next_index = latest_log_index + 1;
        }
        for (_, match_index) in self.match_index.iter_mut() {
            *match_index = LogIndex::from(0);
        }
        self.proposals.clear();
    }
}

/// The state associated with a Raft consensus module in the `Candidate` state.
#[derive(Clone, Debug)]
pub struct CandidateState {
    granted_votes: HashSet<ServerId>,
}

impl CandidateState {

    /// Creates a new `CandidateState`.
    pub fn new() -> CandidateState {
        CandidateState { granted_votes: HashSet::new() }
    }

    /// Records a vote from `voter`.
    pub fn record_vote(&mut self, voter: ServerId) {
        self.granted_votes.insert(voter);
    }

    /// Returns the number of votes.
    pub fn count_votes(&self) -> usize {
        self.granted_votes.len()
    }

    /// Clears the vote count.
    pub fn clear(&mut self) {
        self.granted_votes.clear();
    }

    /// Returns whether the peer has voted in the current election.
    pub fn peer_voted(&self, voter: ServerId) -> bool {
        self.granted_votes.contains(&voter)
    }
}

/// The state associated with a Raft consensus module in the `Follower` state.
#[derive(Clone, Debug)]
pub struct FollowerState {
    /// The most recent leader of the follower. The leader is not guaranteed to be active, so this
    /// should only be used as a hint.
    pub leader: Option<ServerId>,
}

impl FollowerState {

    /// Returns a new `FollowerState`.
    pub fn new() -> FollowerState {
        FollowerState { leader: None }
    }

    /// Sets a new leader.
    pub fn set_leader(&mut self, leader: ServerId) {
        self.leader = Some(leader)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashSet;

    use {LogIndex, ServerId};
    use state::LeaderState;

    /// Tests the `LeaderState`'s  `.count_match_indexes()` function and makes sure it adequately
    /// produces the correct values.
    #[test]
    fn test_count_match_indexes() {
        let index = LogIndex(0);
        let mut peers = HashSet::new();

        // All peers start at 0 index.
        let leader_state = LeaderState::new(index, &peers);
        // Should be one, since the leader node would be matched always.
        assert_eq!(1, leader_state.count_match_indexes(LogIndex(0)));

        peers.insert(ServerId(1));
        let leader_state = LeaderState::new(index, &peers);
        assert_eq!(2, leader_state.count_match_indexes(LogIndex(0)));

        peers.insert(ServerId(2));
        let leader_state = LeaderState::new(index, &peers);
        assert_eq!(3, leader_state.count_match_indexes(LogIndex(0)));

        peers.insert(ServerId(3));
        let mut leader_state = LeaderState::new(index, &peers);
        assert_eq!(4, leader_state.count_match_indexes(LogIndex(0)));

        leader_state.set_match_index(ServerId(1), LogIndex(1));
        leader_state.set_match_index(ServerId(2), LogIndex(1));
        assert_eq!(3, leader_state.count_match_indexes(LogIndex(1)));
    }
}
<commit_msg>remove obsolete code<commit_after>use std::collections::{HashMap, HashSet, VecDeque};

use ClientId;
use LogIndex;
use ServerId;

/// Consensus modules can be in one of three state:
///
/// * `Follower` - which replicates AppendEntries requests and votes for it's leader.
/// * `Leader` - which leads the cluster by serving incoming requests, ensuring
///              data is replicated, and issuing heartbeats.
/// * `Candidate` -  which campaigns in an election and may become a `Leader`
///                  (if it gets enough votes) or a `Follower`, if it hears from
///                  a `Leader`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConsensusState {
    Follower,
    Candidate,
    Leader,
}

/// The state associated with a Raft consensus module in the `Leader` state.
#[derive(Clone, Debug)]
pub struct LeaderState {
    next_index: HashMap<ServerId, LogIndex>,
    match_index: HashMap<ServerId, LogIndex>,
    /// Stores in-flight client proposals.
    pub proposals: VecDeque<(ClientId, LogIndex)>,
}

impl LeaderState {

    /// Returns a new `LeaderState` struct.
    ///
    /// # Arguments
    ///
    /// * `latest_log_index` - The index of the leader's most recent log entry at the
    ///                        time of election.
    /// * `peers` - The set of peer cluster members.
    pub fn new(latest_log_index: LogIndex, peers: &HashSet<ServerId>) -> LeaderState {
        let next_index = peers.iter().cloned().map(|peer| (peer, latest_log_index + 1)).collect();
        let match_index = peers.iter().cloned().map(|peer| (peer, LogIndex::from(0))).collect();

        LeaderState {
            next_index: next_index,
            match_index: match_index,
            proposals: VecDeque::new(),
        }
    }

    /// Returns the next log entry index of the follower.
    pub fn next_index(&mut self, follower: &ServerId) -> LogIndex {
        self.next_index[follower]
    }

    /// Sets the next log entry index of the follower.
    pub fn set_next_index(&mut self, follower: ServerId, index: LogIndex) {
        self.next_index.insert(follower, index);
    }

    /// Sets the index of the highest log entry known to be replicated on the
    /// follower.
    pub fn set_match_index(&mut self, follower: ServerId, index: LogIndex) {
        self.match_index.insert(follower, index);
    }

    /// Counts the number of followers containing the given log index.
    pub fn count_match_indexes(&self, index: LogIndex) -> usize {
        // +1 for self.
        self.match_index.values().filter(|&&i| i >= index).count() + 1
    }

    /// Reinitializes the state following an election.
    pub fn reinitialize(&mut self, latest_log_index: LogIndex) {
        for (_, next_index) in self.next_index.iter_mut() {
            *next_index = latest_log_index + 1;
        }
        for (_, match_index) in self.match_index.iter_mut() {
            *match_index = LogIndex::from(0);
        }
        self.proposals.clear();
    }
}

/// The state associated with a Raft consensus module in the `Candidate` state.
#[derive(Clone, Debug)]
pub struct CandidateState {
    granted_votes: HashSet<ServerId>,
}

impl CandidateState {

    /// Creates a new `CandidateState`.
    pub fn new() -> CandidateState {
        CandidateState { granted_votes: HashSet::new() }
    }

    /// Records a vote from `voter`.
    pub fn record_vote(&mut self, voter: ServerId) {
        self.granted_votes.insert(voter);
    }

    /// Returns the number of votes.
    pub fn count_votes(&self) -> usize {
        self.granted_votes.len()
    }

    /// Clears the vote count.
    pub fn clear(&mut self) {
        self.granted_votes.clear();
    }

    /// Returns whether the peer has voted in the current election.
    pub fn peer_voted(&self, voter: ServerId) -> bool {
        self.granted_votes.contains(&voter)
    }
}

/// The state associated with a Raft consensus module in the `Follower` state.
#[derive(Clone, Debug)]
pub struct FollowerState {
    /// The most recent leader of the follower. The leader is not guaranteed to be active, so this
    /// should only be used as a hint.
    pub leader: Option<ServerId>,
}

impl FollowerState {

    /// Returns a new `FollowerState`.
    pub fn new() -> FollowerState {
        FollowerState { leader: None }
    }

    /// Sets a new leader.
    pub fn set_leader(&mut self, leader: ServerId) {
        self.leader = Some(leader)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashSet;

    use {LogIndex, ServerId};
    use state::LeaderState;

    /// Tests the `LeaderState`'s  `.count_match_indexes()` function and makes sure it adequately
    /// produces the correct values.
    #[test]
    fn test_count_match_indexes() {
        let index = LogIndex(0);
        let mut peers = HashSet::new();

        // All peers start at 0 index.
        let leader_state = LeaderState::new(index, &peers);
        // Should be one, since the leader node would be matched always.
        assert_eq!(1, leader_state.count_match_indexes(LogIndex(0)));

        peers.insert(ServerId(1));
        let leader_state = LeaderState::new(index, &peers);
        assert_eq!(2, leader_state.count_match_indexes(LogIndex(0)));

        peers.insert(ServerId(2));
        let leader_state = LeaderState::new(index, &peers);
        assert_eq!(3, leader_state.count_match_indexes(LogIndex(0)));

        peers.insert(ServerId(3));
        let mut leader_state = LeaderState::new(index, &peers);
        assert_eq!(4, leader_state.count_match_indexes(LogIndex(0)));

        leader_state.set_match_index(ServerId(1), LogIndex(1));
        leader_state.set_match_index(ServerId(2), LogIndex(1));
        assert_eq!(3, leader_state.count_match_indexes(LogIndex(1)));
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use metrics::*;

/// Internal storage of store data.
pub struct BaseStore {
    counts: HashMap<String, u64>,
    measures: HashMap<String, Vec<f64>>,
    samples: HashMap<String, f64>,

    // TODO: Implement samples
    // samples: HashMap<String, Sample>,

    /// For how long it will collect its metrics before reporting the
    /// accumulated value of the metric.
    flush_interval: Seconds,
}

impl BaseStore {
    pub fn new() -> BaseStore {
        BaseStore {
            counts: HashMap::new(),
            measures: HashMap::new(),
            samples: HashMap::new(),
            flush_interval: 10,
        }
    }

    fn record(&mut self, metrics: Vec<Metric>) {
        for metric in metrics {
            match metric {
                Count(name, value) => {
                    let count = self.counts.entry(name).or_insert(0);
                    *count += value;
                },
                Measure(name, value) => {
                    let values = self.measures.entry(name).or_insert(Vec::new());
                    values.push(value);
                },
                Sample(name, value) => {
                    let entry = self.samples.entry(name).or_insert(0.0);
                    *entry = value;
                }
            }
        }
    } // fn record
}

/// Thread-safe interface to the store. In most cases this is what you
/// want to use.
#[derive(Clone)]
pub struct SharedStore {
    shared: Arc<Mutex<BaseStore>>,
}

impl SharedStore {
    pub fn new() -> SharedStore {
        SharedStore {
            shared: Arc::new(Mutex::new(BaseStore::new())),
        }
    }

    pub fn record(&self, metrics: Vec<Metric>) {
        let mut store = self.shared.lock().unwrap();

        store.record(metrics)
    }
}
<commit_msg>Add tests for base store functionality<commit_after>use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use metrics::*;

/// Internal storage of store data.
pub struct BaseStore {
    counts: HashMap<String, u64>,
    measures: HashMap<String, Vec<f64>>,
    samples: HashMap<String, f64>,

    // TODO: Implement samples
    // samples: HashMap<String, Sample>,

    /// For how long it will collect its metrics before reporting the
    /// accumulated value of the metric.
    flush_interval: Seconds,
}

impl BaseStore {
    pub fn new() -> BaseStore {
        BaseStore {
            counts: HashMap::new(),
            measures: HashMap::new(),
            samples: HashMap::new(),
            flush_interval: 10,
        }
    }

    fn record(&mut self, metrics: Vec<Metric>) {
        for metric in metrics {
            match metric {
                Count(name, value) => {
                    let count = self.counts.entry(name).or_insert(0);
                    *count += value;
                },
                Measure(name, value) => {
                    let values = self.measures.entry(name).or_insert(Vec::new());
                    values.push(value);
                },
                Sample(name, value) => {
                    let entry = self.samples.entry(name).or_insert(0.0);
                    *entry = value;
                }
            }
        }
    } // fn record
}

/// Thread-safe interface to the store. In most cases this is what you
/// want to use.
#[derive(Clone)]
pub struct SharedStore {
    shared: Arc<Mutex<BaseStore>>,
}

impl SharedStore {
    pub fn new() -> SharedStore {
        SharedStore {
            shared: Arc::new(Mutex::new(BaseStore::new())),
        }
    }

    pub fn record(&self, metrics: Vec<Metric>) {
        let mut store = self.shared.lock().unwrap();

        store.record(metrics)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;

    use super::BaseStore;
    use super::super::metrics::*;

    fn get_store_with_metrics() -> BaseStore {
        let metrics = vec![
            Count("foo".to_owned(), 1),
            Count("foo".to_owned(), 2),
            Measure("bar".to_owned(), 3.4),
            Measure("bar".to_owned(), 5.6),
            Sample("baz".to_owned(), 7.8),
            Sample("baz".to_owned(), 9.0),
        ];

        let mut store = BaseStore::new();

        store.record(metrics);

        store
    }

    #[test]
    fn it_records_count() {
        let store = get_store_with_metrics();

        let mut expected_counts = HashMap::new();
        expected_counts.insert("foo".to_owned(), 3);

        assert_eq!(store.counts, expected_counts)
    }

    #[test]
    fn it_records_measure() {
        let store = get_store_with_metrics();

        let mut expected_measures: HashMap<String, Vec<f64>> = HashMap::new();
        expected_measures.insert("bar".to_owned(), vec![3.4, 5.6]);

        assert_eq!(store.measures, expected_measures)
    }

    #[test]
    fn it_records_sample() {
        let store = get_store_with_metrics();

        let mut expected_samples = HashMap::new();
        expected_samples.insert("baz".to_owned(), 9.0);

        assert_eq!(store.samples, expected_samples)
    }
}
<|endoftext|>


<commit_before>use std::io::{BufWriter, Reader};
use std::num::Float;
use error::Ch8Error;
use ops::{Op, Instruction};
use std::slice::Chunks;

use std::rand::Rng;
use std::rand;

const RAM_SIZE: usize = 4096;
const PROGRAM_START: usize = 0x200;

const FONT_ADDR: usize = 0;
const FONT_HEIGHT: usize = 5;
const FONT_BYTES: usize = FONT_HEIGHT * 16;
const FONT: [u8; FONT_BYTES] = [
	0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
	0x20, 0x60, 0x20, 0x20, 0x70, // 1
	0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
	0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
	0x90, 0x90, 0xF0, 0x10, 0x10, // 4
	0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
	0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
	0xF0, 0x10, 0x20, 0x40, 0x40, // 7
	0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
	0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
	0xF0, 0x90, 0xF0, 0x90, 0x90, // A
	0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
	0xF0, 0x80, 0x80, 0x80, 0xF0, // C
	0xE0, 0x90, 0x90, 0x90, 0xE0, // D
	0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
	0xF0, 0x80, 0xF0, 0x80, 0x80, // F
];

pub struct Vm {
    reg: [u8; 16],
    i: usize,
    pc: usize,
    sp: usize,
    stack: [usize; 256],
    ram: [u8; RAM_SIZE],

    timer: u8,
    t_tick: f32,

    sound_timer: u8,
    st_tick: f32,

    screen: [u8; 64 * 32],
    keys: [u8; 16],
}

impl Vm {
    pub fn new() -> Vm {
        let mut vm = Vm {
            reg: [0; 16],
            i: 0,
            pc: PROGRAM_START,
            sp: 0,
            stack: [0; 256],
            ram: [0; RAM_SIZE],

            timer: 0,
            t_tick: 0.0,

            sound_timer: 0,
            st_tick: 0.0,

            screen: [0; 64 * 32],
            keys: [0; 16],
        };
        {
            let mut ram = BufWriter::new(&mut vm.ram[FONT_ADDR..(FONT_ADDR + FONT_BYTES)]);
            ram.write(FONT.as_slice());
        }
        vm
    }

    pub fn load_rom(&mut self, reader: &mut Reader) -> Result<usize, Ch8Error> {
        let rom = try!(reader.read_to_end());
        if rom.len() > (RAM_SIZE - PROGRAM_START) {
           return Err(Ch8Error::Io("Rom was larger than available RAM", None))
        }
        let mut ram = BufWriter::new(&mut self.ram[PROGRAM_START..RAM_SIZE]);
        try!(ram.write(rom.as_slice()));
        return Ok(rom.len());
    }

    pub fn dump_ram(&self, writer: &mut Writer) {
        writer.write(&self.ram).unwrap();
    }

    pub fn set_key(&mut self, idx: u8) {
        self.keys[idx as usize] = 1;
    }

    pub fn unset_key(&mut self, idx: u8) {
        self.keys[idx as usize] = 0;
    }

    fn exec(&mut self, op: &Op) -> bool {
        use ops::Instruction::*;
        let ins = Instruction::from_op(op);
        match ins {
            // Sys(addr) intentionally left unimplemented.
            Clear => {
                for b in self.screen.iter_mut() {
                    *b = 0;
                }
            },
            Return => {
                self.pc = self.stack[self.sp];
                self.sp-=1;
            },
            Jump(addr) => {
                let idle = self.pc-2 == addr as usize;
                self.pc = addr as usize;
                if idle { return true; }
            }
            Call(addr) => {
                self.sp+=1;
                self.stack[self.sp] = self.pc;
                self.pc = addr as usize;
            },
            SkipEqualK(vx, k) => {
                if self.reg[vx as usize] == k {
                    self.pc += 2;
                }
            },
            SkipNotEqualK(vx, k) => {
                if self.reg[vx as usize] != k {
                    self.pc += 2;
                }
            },
            SkipEqual(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];
                if x == y {
                    self.pc += 2;
                }
            },
            SetK(vx, byte) => {
                self.reg[vx as usize] = byte;
            },
            AddK(vx, byte) => {
                self.reg[vx as usize] += byte;
            },
            Set(vx, vy) => self.reg[vx as usize] = self.reg[vy as usize],
            Or(vx, vy)  => self.reg[vx as usize] |= self.reg[vy as usize],
            And(vx, vy) => self.reg[vx as usize] &= self.reg[vy as usize],
            XOr(vx, vy) => self.reg[vx as usize] ^= self.reg[vy as usize],
            Add(vx, vy) => {
                let x = self.reg[vx as usize] as u16;
                let y = self.reg[vy as usize] as u16;
                let res = x + y;

                // VF is carryover
                self.reg[15] = (res > 255) as u8;

                self.reg[vx as usize] = res as u8;
            },
            Sub(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];

                // VF is Not Borrow i.e. x > y
                self.reg[15] = (x > y) as u8;

                self.reg[vx as usize] = x - y;
            },
            ShiftRight(vx, vy) => {
                let y = self.reg[vy as usize];

                // VF is lsb before shift
                self.reg[15] = 0x1 & y;

                self.reg[vx as usize] = y >> 1;
            },
            SubInv(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];

                // VF is Not Borrow i.e. y > x
                self.reg[15] = (y > x) as u8;

                self.reg[vx as usize] = y - x;
            },
            ShiftLeft(vx, vy) => {
                let y = self.reg[vy as usize];

                // VF is msb before shift
                self.reg[15] =  0x80 & y;

                self.reg[vx as usize] = y << 1;
            }
            SkipNotEqual(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];
                if x != y {
                    self.pc += 2;
                }
            },
            LoadI(addr) => {
                self.i = addr as usize;
            },
            LongJump(addr) => {
                self.pc = (self.reg[0] as u16 + addr) as usize;
            },
            Rand(vx, byte) => {
                self.reg[vx as usize] = rand::thread_rng().gen::<u8>() & byte;
            }
            Draw(vx, vy, n) => {
                let x = self.reg[vx as usize] as usize;
                let y = self.reg[vy as usize] as usize;
                let i = self.i as usize;
                let n = n as usize;

                let sprite = &self.ram[i..i+n];

                self.reg[15] = 0;
                for (sy, byte) in sprite.iter().enumerate() {
                    let dy = (y + sy) % 32;
                    for sx in 0us..8 {
                        let px = (*byte >> (7 - sx)) & 0b00000001;
                        let dx = (x + sx) % 64;
                        let idx = dy * 64 + dx;
                        self.screen[idx] ^= px;

                        // Vf is if there was a collision
                        self.reg[15] |= (self.screen[idx] == 0 && px == 1) as u8;
                    }
                }
            },
            SkipPressed(vx) => {
                let idx = self.reg[vx as usize];
                if self.keys[idx as usize] == 1 {
                    self.pc += 2;
                }
            }
            SkipNotPressed(vx) => {
                let idx = self.reg[vx as usize];
                if self.keys[idx  as usize] != 1 {
                    self.pc += 2;
                }
            }
            GetTimer(vx) => {
                self.reg[vx as usize] = self.timer;
            },
            //TODO WaitKey(vx) => {}
            SetTimer(vx) => {
                self.timer = self.reg[vx as usize];
                self.t_tick = 1.0 / 60.0;
            },
            SetSoundTimer(vx) => {
                self.sound_timer = self.reg[vx as usize];
                self.st_tick = 1.0 / 60.0;
            },
            AddToI(vx) => {
                self.i += self.reg[vx as usize] as usize;
            },
            LoadHexGlyph(vx) => {
                let x = self.reg[vx as usize];
                self.i = FONT_ADDR + x as usize * FONT_HEIGHT;
            }
            StoreBCD(vx) => {
                let mut x = self.reg[vx as usize];

                let mut place = 100;
                for i in 0us..3 {
                    let bcd = x / place;
                    self.ram[self.i + i] = bcd;
                    x -= bcd * place;
                    place /= 10;
                }
            }
            StoreRegisters(vx) => {
                let vx = vx as usize;
                let i = self.i as usize;

                let mut dst = &mut self.ram[i..i+vx+1];
                for (x,b) in dst.iter_mut().enumerate() {
                    *b = self.reg[x];
                }
                self.i += vx+1;
            },
            LoadRegisters(vx) => {
                let vx = vx as usize;
                let i = self.i as usize;

                let src = &self.ram[i..i+vx+1];
                for (x,b) in src.iter().enumerate() {
                    self.reg[x] = *b;
                }
                self.i += vx+1;
            },
            other => {
                println!("Instruction not implemented {:?} skipping...", other)
            }
        }
        return false;
    }

    fn time_step(&mut self, dt:f32) {
        if self.timer > 0 {
            self.t_tick -= dt;
            if self.t_tick <= 0.0 {
                self.timer -= 1;
                self.t_tick = 1.0 / 60.0;
            }
        }

        if self.sound_timer > 0 {
            self.st_tick -= dt;
            if self.st_tick <= 0.0 {
                self.sound_timer -= 1;
                self.st_tick = 1.0 / 60.0;
            }
        }
    }

    // dt: Time in seconds since last step
    pub fn step(&mut self, dt:f32) -> bool {
        let mut idle = false;

        let raw = {
            let codes = &self.ram[self.pc..self.pc+2];
            ((codes[0] as u16) << 8) | codes[1] as u16
        };
        let op = Op::new(raw);
        self.pc += 2;
        idle = self.exec(&op);
        self.time_step(dt);
        return idle;
    }

    pub fn screen_rows<'a>(&'a self) -> Chunks<'a, u8> {
        self.screen.chunks(64)
    }

    pub fn print_screen(&self) {
        for row in self.screen.chunks(64) {
            println!("");
            for byte in row.iter() {
                match *byte {
                    0x0 => print!("░"),
                    _ => print!("▓")
                }
            }
        }
    }

    pub fn print_disassembly(&self) {
        for i in self.ram.chunks(2) {
            match i {
                [0, 0] => continue,
                [h, l] => {
                    let op = Op::new(((h as u16) << 8) | l as u16);
                    println!("raw: 0x{:X}", op.raw());
                    println!("instruction: {:?}", Instruction::from_op(&op));
                    println!("addr: 0x{:X}", op.addr());
                    println!("x: 0x{:X}", op.x());
                    println!("y: 0x{:X}", op.y());
                    println!("n_high: 0x{:X}", op.n_high());
                    println!("n_low: 0x{:X}", op.n_low());
                    println!("k: 0x{:X}\n", op.k());
                },
                _ => continue
            }
        }
    }
}
<commit_msg>Last op implemented! W00t<commit_after>use std::io::{BufWriter, Reader};
use std::num::Float;
use error::Ch8Error;
use ops::{Op, Instruction};
use std::slice::Chunks;

use std::rand::Rng;
use std::rand;

const RAM_SIZE: usize = 4096;
const PROGRAM_START: usize = 0x200;

const FONT_ADDR: usize = 0;
const FONT_HEIGHT: usize = 5;
const FONT_BYTES: usize = FONT_HEIGHT * 16;
const FONT: [u8; FONT_BYTES] = [
	0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
	0x20, 0x60, 0x20, 0x20, 0x70, // 1
	0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
	0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
	0x90, 0x90, 0xF0, 0x10, 0x10, // 4
	0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
	0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
	0xF0, 0x10, 0x20, 0x40, 0x40, // 7
	0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
	0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
	0xF0, 0x90, 0xF0, 0x90, 0x90, // A
	0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
	0xF0, 0x80, 0x80, 0x80, 0xF0, // C
	0xE0, 0x90, 0x90, 0x90, 0xE0, // D
	0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
	0xF0, 0x80, 0xF0, 0x80, 0x80, // F
];

pub struct Vm {
    reg: [u8; 16],
    i: usize,
    pc: usize,
    sp: usize,
    stack: [usize; 256],
    ram: [u8; RAM_SIZE],

    timer: u8,
    t_tick: f32,

    sound_timer: u8,
    st_tick: f32,

    screen: [u8; 64 * 32],
    keys: [u8; 16],
    waiting_on_key: Option<u8>,
}

impl Vm {
    pub fn new() -> Vm {
        let mut vm = Vm {
            reg: [0; 16],
            i: 0,
            pc: PROGRAM_START,
            sp: 0,
            stack: [0; 256],
            ram: [0; RAM_SIZE],

            timer: 0,
            t_tick: 0.0,

            sound_timer: 0,
            st_tick: 0.0,

            screen: [0; 64 * 32],
            keys: [0; 16],
            waiting_on_key: None,
        };
        {
            let mut ram = BufWriter::new(&mut vm.ram[FONT_ADDR..(FONT_ADDR + FONT_BYTES)]);
            ram.write(FONT.as_slice());
        }
        vm
    }

    pub fn load_rom(&mut self, reader: &mut Reader) -> Result<usize, Ch8Error> {
        let rom = try!(reader.read_to_end());
        if rom.len() > (RAM_SIZE - PROGRAM_START) {
           return Err(Ch8Error::Io("Rom was larger than available RAM", None))
        }
        let mut ram = BufWriter::new(&mut self.ram[PROGRAM_START..RAM_SIZE]);
        try!(ram.write(rom.as_slice()));
        return Ok(rom.len());
    }

    pub fn dump_ram(&self, writer: &mut Writer) {
        writer.write(&self.ram).unwrap();
    }

    pub fn set_key(&mut self, idx: u8) {
        self.keys[idx as usize] = 1;
        if let Some(vx) = self.waiting_on_key {
            self.reg[vx as usize] = idx;
            self.waiting_on_key = None;
        }
    }

    pub fn unset_key(&mut self, idx: u8) {
        self.keys[idx as usize] = 0;
    }

    fn exec(&mut self, op: &Op) -> bool {
        use ops::Instruction::*;
        let ins = Instruction::from_op(op);
        match ins {
            // Sys(addr) intentionally left unimplemented.
            Clear => {
                for b in self.screen.iter_mut() {
                    *b = 0;
                }
            },
            Return => {
                self.pc = self.stack[self.sp];
                self.sp-=1;
            },
            Jump(addr) => {
                let idle = self.pc-2 == addr as usize;
                self.pc = addr as usize;
                if idle { return true; }
            }
            Call(addr) => {
                self.sp+=1;
                self.stack[self.sp] = self.pc;
                self.pc = addr as usize;
            },
            SkipEqualK(vx, k) => {
                if self.reg[vx as usize] == k {
                    self.pc += 2;
                }
            },
            SkipNotEqualK(vx, k) => {
                if self.reg[vx as usize] != k {
                    self.pc += 2;
                }
            },
            SkipEqual(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];
                if x == y {
                    self.pc += 2;
                }
            },
            SetK(vx, byte) => {
                self.reg[vx as usize] = byte;
            },
            AddK(vx, byte) => {
                self.reg[vx as usize] += byte;
            },
            Set(vx, vy) => self.reg[vx as usize] = self.reg[vy as usize],
            Or(vx, vy)  => self.reg[vx as usize] |= self.reg[vy as usize],
            And(vx, vy) => self.reg[vx as usize] &= self.reg[vy as usize],
            XOr(vx, vy) => self.reg[vx as usize] ^= self.reg[vy as usize],
            Add(vx, vy) => {
                let x = self.reg[vx as usize] as u16;
                let y = self.reg[vy as usize] as u16;
                let res = x + y;

                // VF is carryover
                self.reg[15] = (res > 255) as u8;

                self.reg[vx as usize] = res as u8;
            },
            Sub(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];

                // VF is Not Borrow i.e. x > y
                self.reg[15] = (x > y) as u8;

                self.reg[vx as usize] = x - y;
            },
            ShiftRight(vx, vy) => {
                let y = self.reg[vy as usize];

                // VF is lsb before shift
                self.reg[15] = 0x1 & y;

                self.reg[vx as usize] = y >> 1;
            },
            SubInv(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];

                // VF is Not Borrow i.e. y > x
                self.reg[15] = (y > x) as u8;

                self.reg[vx as usize] = y - x;
            },
            ShiftLeft(vx, vy) => {
                let y = self.reg[vy as usize];

                // VF is msb before shift
                self.reg[15] =  0x80 & y;

                self.reg[vx as usize] = y << 1;
            }
            SkipNotEqual(vx, vy) => {
                let x = self.reg[vx as usize];
                let y = self.reg[vy as usize];
                if x != y {
                    self.pc += 2;
                }
            },
            LoadI(addr) => {
                self.i = addr as usize;
            },
            LongJump(addr) => {
                self.pc = (self.reg[0] as u16 + addr) as usize;
            },
            Rand(vx, byte) => {
                self.reg[vx as usize] = rand::thread_rng().gen::<u8>() & byte;
            }
            Draw(vx, vy, n) => {
                let x = self.reg[vx as usize] as usize;
                let y = self.reg[vy as usize] as usize;
                let i = self.i as usize;
                let n = n as usize;

                let sprite = &self.ram[i..i+n];

                self.reg[15] = 0;
                for (sy, byte) in sprite.iter().enumerate() {
                    let dy = (y + sy) % 32;
                    for sx in 0us..8 {
                        let px = (*byte >> (7 - sx)) & 0b00000001;
                        let dx = (x + sx) % 64;
                        let idx = dy * 64 + dx;
                        self.screen[idx] ^= px;

                        // Vf is if there was a collision
                        self.reg[15] |= (self.screen[idx] == 0 && px == 1) as u8;
                    }
                }
            },
            SkipPressed(vx) => {
                let idx = self.reg[vx as usize];
                if self.keys[idx as usize] == 1 {
                    self.pc += 2;
                }
            }
            SkipNotPressed(vx) => {
                let idx = self.reg[vx as usize];
                if self.keys[idx  as usize] != 1 {
                    self.pc += 2;
                }
            }
            GetTimer(vx) => {
                self.reg[vx as usize] = self.timer;
            },
            WaitKey(vx) => {
                self.waiting_on_key = Some(vx);
            },
            SetTimer(vx) => {
                self.timer = self.reg[vx as usize];
                self.t_tick = 1.0 / 60.0;
            },
            SetSoundTimer(vx) => {
                self.sound_timer = self.reg[vx as usize];
                self.st_tick = 1.0 / 60.0;
            },
            AddToI(vx) => {
                self.i += self.reg[vx as usize] as usize;
            },
            LoadHexGlyph(vx) => {
                let x = self.reg[vx as usize];
                self.i = FONT_ADDR + x as usize * FONT_HEIGHT;
            }
            StoreBCD(vx) => {
                let mut x = self.reg[vx as usize];

                let mut place = 100;
                for i in 0us..3 {
                    let bcd = x / place;
                    self.ram[self.i + i] = bcd;
                    x -= bcd * place;
                    place /= 10;
                }
            }
            StoreRegisters(vx) => {
                let vx = vx as usize;
                let i = self.i as usize;

                let mut dst = &mut self.ram[i..i+vx+1];
                for (x,b) in dst.iter_mut().enumerate() {
                    *b = self.reg[x];
                }
                self.i += vx+1;
            },
            LoadRegisters(vx) => {
                let vx = vx as usize;
                let i = self.i as usize;

                let src = &self.ram[i..i+vx+1];
                for (x,b) in src.iter().enumerate() {
                    self.reg[x] = *b;
                }
                self.i += vx+1;
            },
            other => {
                println!("Instruction not implemented {:?} skipping...", other)
            }
        }
        return false;
    }

    fn time_step(&mut self, dt:f32) {
        if self.timer > 0 {
            self.t_tick -= dt;
            if self.t_tick <= 0.0 {
                self.timer -= 1;
                self.t_tick = 1.0 / 60.0;
            }
        }

        if self.sound_timer > 0 {
            self.st_tick -= dt;
            if self.st_tick <= 0.0 {
                self.sound_timer -= 1;
                self.st_tick = 1.0 / 60.0;
            }
        }
    }

    // dt: Time in seconds since last step
    pub fn step(&mut self, dt:f32) {
        self.time_step(dt);
        if self.waiting_on_key.is_some() {
            return;
        }

        let raw = {
            let codes = &self.ram[self.pc..self.pc+2];
            ((codes[0] as u16) << 8) | codes[1] as u16
        };
        let op = Op::new(raw);
        self.pc += 2;
        self.exec(&op);
    }

    pub fn screen_rows<'a>(&'a self) -> Chunks<'a, u8> {
        self.screen.chunks(64)
    }

    pub fn print_screen(&self) {
        for row in self.screen.chunks(64) {
            println!("");
            for byte in row.iter() {
                match *byte {
                    0x0 => print!("░"),
                    _ => print!("▓")
                }
            }
        }
    }

    pub fn print_disassembly(&self) {
        for i in self.ram.chunks(2) {
            match i {
                [0, 0] => continue,
                [h, l] => {
                    let op = Op::new(((h as u16) << 8) | l as u16);
                    println!("raw: 0x{:X}", op.raw());
                    println!("instruction: {:?}", Instruction::from_op(&op));
                    println!("addr: 0x{:X}", op.addr());
                    println!("x: 0x{:X}", op.x());
                    println!("y: 0x{:X}", op.y());
                    println!("n_high: 0x{:X}", op.n_high());
                    println!("n_low: 0x{:X}", op.n_low());
                    println!("k: 0x{:X}\n", op.k());
                },
                _ => continue
            }
        }
    }
}
<|endoftext|>


<commit_before>use config::{Benchmark, parse_config};
use repo::Workspace;

use std::collections::HashMap;
use std::io;
use std::path::Path;
use std::process::{Command, ExitStatus};
use std::str;
use std::sync::Mutex;

/// `(val, percentage_change)`
#[derive(Debug, Clone)]
pub enum BenchmarkResult<T> {
    Improvement(T, f64),
    Regression(T, f64),
    Neutral(T, f64),
}

#[derive(Debug, Clone)]
pub struct TastingResult {
    pub branch: String,
    pub commit_id: String,
    pub commit_msg: String,
    pub commit_url: String,
    pub build: bool,
    pub test: bool,
    pub bench: bool,
    pub results: Option<Vec<HashMap<String, BenchmarkResult<f64>>>>,
}

fn benchmark(workdir: &str,
             cfg: &Benchmark,
             previous_result: Option<&HashMap<String, BenchmarkResult<f64>>>)
             -> (ExitStatus, HashMap<String, BenchmarkResult<f64>>) {
    let mut cmd = Command::new("cargo");
    cmd.current_dir(workdir)
        .env("RUST_BACKTRACE", "1")
        .arg(&cfg.cmd)
        .args(cfg.args.as_slice());

    let output = cmd.output()
        .expect(&format!("Failed to execute benchmark '{}'!", cfg.name));

    let lines = str::from_utf8(output.stdout.as_slice()).unwrap().lines();
    let mut res = HashMap::new();
    for l in lines {
        for (i, regex) in cfg.result_expr.iter().enumerate() {
            for cap in regex.captures_iter(l) {
                let (metric, value) = if cap.len() > 2 {
                    (String::from(cap.at(1).unwrap()), cap.at(2))
                } else {
                    (format!("{}", i), cap.at(1))
                };
                let bm_name = format!("{}/{}", cfg.name, &metric);
                if let Some(c) = value {
                    use std::str::FromStr;
                    let val = match f64::from_str(&c) {
                        Ok(f) => f,
                        Err(_) => {
                            println!("failed to parse value '{}' for {} into f64 number, ignoring",
                                     c,
                                     bm_name);
                            continue;
                        }
                    };
                    let new_result = match previous_result {
                        None => BenchmarkResult::Neutral(val, 0.0),
                        Some(prev_res) => {
                            let old_val = match *prev_res.get(&bm_name).unwrap() {
                                BenchmarkResult::Improvement(v, _) => v,
                                BenchmarkResult::Regression(v, _) => v,
                                BenchmarkResult::Neutral(v, _) => v,
                            };
                            let new_result = if val >= old_val {
                                BenchmarkResult::Improvement(val, (val / old_val) - 1.0)
                            } else if val < old_val * 0.9 {
                                BenchmarkResult::Regression(val, (val / old_val) - 1.0)
                            } else {
                                BenchmarkResult::Neutral(val, (val / old_val) - 1.0)
                            };
                            new_result
                        }
                    };
                    res.insert(bm_name, new_result);
                }
            }
        }
    }
    (output.status, res)
}

fn build(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("build")
        .arg("--release")
        .env("RUST_BACKTRACE", "1")
        .status()
        .expect("Failed to execute 'cargo build'!")
}

pub fn taste_commit(ws: &Workspace,
                    history: &mut HashMap<String,
                                          HashMap<String, HashMap<String, BenchmarkResult<f64>>>>,
                    commit_ref: &str,
                    id: &str,
                    msg: &str,
                    url: &str)
                    -> Result<TastingResult, String> {
    println!("Tasting commit {}", id);
    ws.checkout_commit(id)?;

    let branch = String::from(&commit_ref[commit_ref.rfind("/").unwrap() + 1..]);

    let build_success = update(&ws.path).success() && build(&ws.path).success();
    let test_success = test(&ws.path).success();

    let cfg = match parse_config(Path::new(&format!("{}/taster.toml", ws.path))) {
        Ok(c) => c,
        Err(e) => {
            match e.kind() {
                io::ErrorKind::NotFound => {
                    println!("Skipping commit {} which doesn't have a Taster config.", id);
                    return Ok(TastingResult {
                        branch: branch,
                        commit_id: String::from(id),
                        commit_msg: String::from(msg),
                        commit_url: String::from(url),
                        build: build_success,
                        test: test_success,
                        bench: false,
                        results: None,
                    });
                }
                _ => unimplemented!(),
            }
        }
    };

    let branch_history = history.entry(branch.clone()).or_insert(HashMap::new());
    let bench_out = cfg.iter()
        .map(|b| {
            let new_result = benchmark(&ws.path, b, branch_history.get(&b.name));
            branch_history.insert(b.name.clone(), new_result.1.clone());
            new_result
        })
        .collect::<Vec<(ExitStatus, HashMap<String, BenchmarkResult<f64>>)>>();
    let bench_success = bench_out.iter().all(|x| x.0.success());
    let bench_results = bench_out.iter().map(|x| x.1.clone()).collect();

    Ok(TastingResult {
        branch: branch,
        commit_id: String::from(id),
        commit_msg: String::from(msg),
        commit_url: String::from(url),
        build: build_success,
        test: test_success,
        bench: bench_success,
        results: Some(bench_results),
    })
}

fn test(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("test")
        .env("RUST_BACKTRACE", "1")
        .env("RUST_TEST_THREADS", "1")
        .status()
        .expect("Failed to execute 'cargo test'!")
}

fn update(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("update")
        .status()
        .expect("Failed to execute 'cargo update'!")
}
<commit_msg>Silence warning<commit_after>use config::{Benchmark, parse_config};
use repo::Workspace;

use std::collections::HashMap;
use std::io;
use std::path::Path;
use std::process::{Command, ExitStatus};
use std::str;

/// `(val, percentage_change)`
#[derive(Debug, Clone)]
pub enum BenchmarkResult<T> {
    Improvement(T, f64),
    Regression(T, f64),
    Neutral(T, f64),
}

#[derive(Debug, Clone)]
pub struct TastingResult {
    pub branch: String,
    pub commit_id: String,
    pub commit_msg: String,
    pub commit_url: String,
    pub build: bool,
    pub test: bool,
    pub bench: bool,
    pub results: Option<Vec<HashMap<String, BenchmarkResult<f64>>>>,
}

fn benchmark(workdir: &str,
             cfg: &Benchmark,
             previous_result: Option<&HashMap<String, BenchmarkResult<f64>>>)
             -> (ExitStatus, HashMap<String, BenchmarkResult<f64>>) {
    let mut cmd = Command::new("cargo");
    cmd.current_dir(workdir)
        .env("RUST_BACKTRACE", "1")
        .arg(&cfg.cmd)
        .args(cfg.args.as_slice());

    let output = cmd.output()
        .expect(&format!("Failed to execute benchmark '{}'!", cfg.name));

    let lines = str::from_utf8(output.stdout.as_slice()).unwrap().lines();
    let mut res = HashMap::new();
    for l in lines {
        for (i, regex) in cfg.result_expr.iter().enumerate() {
            for cap in regex.captures_iter(l) {
                let (metric, value) = if cap.len() > 2 {
                    (String::from(cap.at(1).unwrap()), cap.at(2))
                } else {
                    (format!("{}", i), cap.at(1))
                };
                let bm_name = format!("{}/{}", cfg.name, &metric);
                if let Some(c) = value {
                    use std::str::FromStr;
                    let val = match f64::from_str(&c) {
                        Ok(f) => f,
                        Err(_) => {
                            println!("failed to parse value '{}' for {} into f64 number, ignoring",
                                     c,
                                     bm_name);
                            continue;
                        }
                    };
                    let new_result = match previous_result {
                        None => BenchmarkResult::Neutral(val, 0.0),
                        Some(prev_res) => {
                            let old_val = match *prev_res.get(&bm_name).unwrap() {
                                BenchmarkResult::Improvement(v, _) => v,
                                BenchmarkResult::Regression(v, _) => v,
                                BenchmarkResult::Neutral(v, _) => v,
                            };
                            let new_result = if val >= old_val {
                                BenchmarkResult::Improvement(val, (val / old_val) - 1.0)
                            } else if val < old_val * 0.9 {
                                BenchmarkResult::Regression(val, (val / old_val) - 1.0)
                            } else {
                                BenchmarkResult::Neutral(val, (val / old_val) - 1.0)
                            };
                            new_result
                        }
                    };
                    res.insert(bm_name, new_result);
                }
            }
        }
    }
    (output.status, res)
}

fn build(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("build")
        .arg("--release")
        .env("RUST_BACKTRACE", "1")
        .status()
        .expect("Failed to execute 'cargo build'!")
}

pub fn taste_commit(ws: &Workspace,
                    history: &mut HashMap<String,
                                          HashMap<String, HashMap<String, BenchmarkResult<f64>>>>,
                    commit_ref: &str,
                    id: &str,
                    msg: &str,
                    url: &str)
                    -> Result<TastingResult, String> {
    println!("Tasting commit {}", id);
    ws.checkout_commit(id)?;

    let branch = String::from(&commit_ref[commit_ref.rfind("/").unwrap() + 1..]);

    let build_success = update(&ws.path).success() && build(&ws.path).success();
    let test_success = test(&ws.path).success();

    let cfg = match parse_config(Path::new(&format!("{}/taster.toml", ws.path))) {
        Ok(c) => c,
        Err(e) => {
            match e.kind() {
                io::ErrorKind::NotFound => {
                    println!("Skipping commit {} which doesn't have a Taster config.", id);
                    return Ok(TastingResult {
                        branch: branch,
                        commit_id: String::from(id),
                        commit_msg: String::from(msg),
                        commit_url: String::from(url),
                        build: build_success,
                        test: test_success,
                        bench: false,
                        results: None,
                    });
                }
                _ => unimplemented!(),
            }
        }
    };

    let branch_history = history.entry(branch.clone()).or_insert(HashMap::new());
    let bench_out = cfg.iter()
        .map(|b| {
            let new_result = benchmark(&ws.path, b, branch_history.get(&b.name));
            branch_history.insert(b.name.clone(), new_result.1.clone());
            new_result
        })
        .collect::<Vec<(ExitStatus, HashMap<String, BenchmarkResult<f64>>)>>();
    let bench_success = bench_out.iter().all(|x| x.0.success());
    let bench_results = bench_out.iter().map(|x| x.1.clone()).collect();

    Ok(TastingResult {
        branch: branch,
        commit_id: String::from(id),
        commit_msg: String::from(msg),
        commit_url: String::from(url),
        build: build_success,
        test: test_success,
        bench: bench_success,
        results: Some(bench_results),
    })
}

fn test(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("test")
        .env("RUST_BACKTRACE", "1")
        .env("RUST_TEST_THREADS", "1")
        .status()
        .expect("Failed to execute 'cargo test'!")
}

fn update(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("update")
        .status()
        .expect("Failed to execute 'cargo update'!")
}
<|endoftext|>