<commit_before>use errors::prelude::*;
use services::ledger::merkletree::proof::{Lemma, Proof};
use services::ledger::merkletree::tree::{LeavesIntoIterator, LeavesIterator, Tree, TreeLeafData};
use utils::crypto::hash::{Hash, HASHBYTES, EMPTY_HASH_BYTES};

/// A Merkle tree is a binary tree, with values of type `T` at the leafs,
/// and where every internal node holds the hash of the concatenation of the hashes of its children nodes.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MerkleTree {

    /// The root of the inner binary tree
    pub root: Tree,

    /// The height of the tree
    pub height: usize,

    /// The number of leaf nodes in the tree
    pub count: usize,

    /// The number of nodes in the tree
    pub nodes_count: usize
}

impl Default for MerkleTree {
    fn default() -> Self {
        MerkleTree {
            root: Tree::Empty { hash: EMPTY_HASH_BYTES.to_vec() },
            height: 0,
            count: 0,
            nodes_count: 0,
        }
    }
}

impl MerkleTree {

    /// Constructs a Merkle Tree from a vector of data blocks.
    /// Returns `None` if `values` is empty.
    pub fn from_vec(values: Vec<TreeLeafData>) -> IndyResult<Self> {

        if values.is_empty() {
            return Ok(MerkleTree::default());
        }

        let count = values.len();
        let mut nodes_count = 0;
        let mut height = 0;
        let mut cur    = Vec::with_capacity(count);

        for v in values {
            let leaf = Tree::new_leaf(v)?;
            cur.push(leaf);
        }

        while cur.len() > 1 {
            let mut next = Vec::new();
            while !cur.is_empty() {
                if cur.len() == 1 {
                    next.push(cur.remove(0));
                }
                else {
                    let left  = cur.remove(0);
                    let right = cur.remove(0);

                    let combined_hash = Hash::hash_nodes(
                        left.hash(),
                        right.hash()
                    )?;

                    let node = Tree::Node {
                       hash: combined_hash.to_vec(),
                       left: Box::new(left),
                       right: Box::new(right)
                    };

                    next.push(node);
                    nodes_count+=1;
                }
            }

            height += 1;

            cur = next;
        }

        debug_assert!(cur.len() == 1);

        let root = cur.remove(0);

        Ok(MerkleTree {
            root,
            height,
            count,
            nodes_count
        })
    }

    /// Returns the root hash of Merkle tree
    pub fn root_hash(&self) -> &Vec<u8> {
        self.root.hash()
    }

    /// Returns the hex root hash of Merkle tree
    pub fn root_hash_hex(&self) -> String {
        let rh = self.root.hash();
        let mut ret:String = String::with_capacity(HASHBYTES *2);
        for i in rh {
            ret.push_str(&format!("{:02x}", i));
        }
        ret
    }

    /// Returns the height of Merkle tree
    pub fn height(&self) -> usize {
        self.height
    }

    /// Returns the number of leaves in the Merkle tree
    pub fn count(&self) -> usize {
        self.count
    }

    /// Returns whether the Merkle tree is empty or not
    pub fn is_empty(&self) -> bool {
        self.count() == 0
    }

    /// Generate an inclusion proof for the given value.
    /// Returns `None` if the given value is not found in the tree.
    pub fn gen_proof(&self, value: TreeLeafData) -> IndyResult<Option<Proof>> {

        let root_hash  = self.root_hash().clone();
        let leaf_hash  = Hash::hash_leaf(&value)?;

        Ok(Lemma::new(&self.root, leaf_hash.to_vec().as_slice()).map(|lemma|
            Proof::new(root_hash, lemma, value)
        ))
    }

    /// Creates an `Iterator` over the values contained in this Merkle tree.
    pub fn iter(&self) -> LeavesIterator {
        self.root.iter()
    }

}

impl IntoIterator for MerkleTree {

    type Item     = TreeLeafData;
    type IntoIter = LeavesIntoIterator;

    /// Creates a consuming iterator, that is, one that moves each value out of the Merkle tree.
    /// The tree cannot be used after calling this.
    fn into_iter(self) -> Self::IntoIter {
        self.root.into_iter()
    }

}

impl <'a> IntoIterator for &'a MerkleTree {

    type Item     = &'a TreeLeafData;
    type IntoIter = LeavesIterator<'a>;

    /// Creates a borrowing `Iterator` over the values contained in this Merkle tree.
    fn into_iter(self) -> Self::IntoIter {
        self.root.iter()
    }

}
<commit_msg>use hex::encode<commit_after>use errors::prelude::*;
use services::ledger::merkletree::proof::{Lemma, Proof};
use services::ledger::merkletree::tree::{LeavesIntoIterator, LeavesIterator, Tree, TreeLeafData};
use utils::crypto::hash::{Hash, EMPTY_HASH_BYTES};

/// A Merkle tree is a binary tree, with values of type `T` at the leafs,
/// and where every internal node holds the hash of the concatenation of the hashes of its children nodes.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MerkleTree {

    /// The root of the inner binary tree
    pub root: Tree,

    /// The height of the tree
    pub height: usize,

    /// The number of leaf nodes in the tree
    pub count: usize,

    /// The number of nodes in the tree
    pub nodes_count: usize
}

impl Default for MerkleTree {
    fn default() -> Self {
        MerkleTree {
            root: Tree::Empty { hash: EMPTY_HASH_BYTES.to_vec() },
            height: 0,
            count: 0,
            nodes_count: 0,
        }
    }
}

impl MerkleTree {

    /// Constructs a Merkle Tree from a vector of data blocks.
    /// Returns `None` if `values` is empty.
    pub fn from_vec(values: Vec<TreeLeafData>) -> IndyResult<Self> {

        if values.is_empty() {
            return Ok(MerkleTree::default());
        }

        let count = values.len();
        let mut nodes_count = 0;
        let mut height = 0;
        let mut cur    = Vec::with_capacity(count);

        for v in values {
            let leaf = Tree::new_leaf(v)?;
            cur.push(leaf);
        }

        while cur.len() > 1 {
            let mut next = Vec::new();
            while !cur.is_empty() {
                if cur.len() == 1 {
                    next.push(cur.remove(0));
                }
                else {
                    let left  = cur.remove(0);
                    let right = cur.remove(0);

                    let combined_hash = Hash::hash_nodes(
                        left.hash(),
                        right.hash()
                    )?;

                    let node = Tree::Node {
                       hash: combined_hash.to_vec(),
                       left: Box::new(left),
                       right: Box::new(right)
                    };

                    next.push(node);
                    nodes_count+=1;
                }
            }

            height += 1;

            cur = next;
        }

        debug_assert!(cur.len() == 1);

        let root = cur.remove(0);

        Ok(MerkleTree {
            root,
            height,
            count,
            nodes_count
        })
    }

    /// Returns the root hash of Merkle tree
    pub fn root_hash(&self) -> &Vec<u8> {
        self.root.hash()
    }

    /// Returns the hex root hash of Merkle tree
    pub fn root_hash_hex(&self) -> String {
        hex::encode(self.root.hash())
    }

    /// Returns the height of Merkle tree
    pub fn height(&self) -> usize {
        self.height
    }

    /// Returns the number of leaves in the Merkle tree
    pub fn count(&self) -> usize {
        self.count
    }

    /// Returns whether the Merkle tree is empty or not
    pub fn is_empty(&self) -> bool {
        self.count() == 0
    }

    /// Generate an inclusion proof for the given value.
    /// Returns `None` if the given value is not found in the tree.
    pub fn gen_proof(&self, value: TreeLeafData) -> IndyResult<Option<Proof>> {

        let root_hash  = self.root_hash().clone();
        let leaf_hash  = Hash::hash_leaf(&value)?;

        Ok(Lemma::new(&self.root, leaf_hash.to_vec().as_slice()).map(|lemma|
            Proof::new(root_hash, lemma, value)
        ))
    }

    /// Creates an `Iterator` over the values contained in this Merkle tree.
    pub fn iter(&self) -> LeavesIterator {
        self.root.iter()
    }

}

impl IntoIterator for MerkleTree {

    type Item     = TreeLeafData;
    type IntoIter = LeavesIntoIterator;

    /// Creates a consuming iterator, that is, one that moves each value out of the Merkle tree.
    /// The tree cannot be used after calling this.
    fn into_iter(self) -> Self::IntoIter {
        self.root.into_iter()
    }

}

impl <'a> IntoIterator for &'a MerkleTree {

    type Item     = &'a TreeLeafData;
    type IntoIter = LeavesIterator<'a>;

    /// Creates a borrowing `Iterator` over the values contained in this Merkle tree.
    fn into_iter(self) -> Self::IntoIter {
        self.root.iter()
    }

}
<|endoftext|>


<commit_before>//! A simple crate for executing work on a thread pool, and getting back a
//! future.
//!
//! This crate provides a simple thread pool abstraction for running work
//! externally from the current thread that's running. An instance of `Future`
//! is handed back to represent that the work may be done later, and further
//! computations can be chained along with it as well.
//!
//! ```rust
//! extern crate futures;
//! extern crate futures_cpupool;
//!
//! use futures::Future;
//! use futures_cpupool::CpuPool;
//!
//! # fn long_running_future(a: u32) -> futures::future::BoxFuture<u32, ()> {
//! #     futures::future::result(Ok(a)).boxed()
//! # }
//! # fn main() {
//!
//! // Create a worker thread pool with four threads
//! let pool = CpuPool::new(4);
//!
//! // Execute some work on the thread pool, optionally closing over data.
//! let a = pool.spawn(long_running_future(2));
//! let b = pool.spawn(long_running_future(100));
//!
//! // Express some further computation once the work is completed on the thread
//! // pool.
//! let c = a.join(b).map(|(a, b)| a + b).wait().unwrap();
//!
//! // Print out the result
//! println!("{:?}", c);
//! # }
//! ```

#![deny(missing_docs)]

extern crate futures;
extern crate num_cpus;

use std::panic::{self, AssertUnwindSafe};
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::mpsc;
use std::thread;

use futures::{IntoFuture, Future, Poll, Async};
use futures::future::lazy;
use futures::sync::oneshot::{channel, Sender, Receiver};
use futures::executor::{self, Run, Executor};

/// A thread pool intended to run CPU intensive work.
///
/// This thread pool will hand out futures representing the completed work
/// that happens on the thread pool itself, and the futures can then be later
/// composed with other work as part of an overall computation.
///
/// The worker threads associated with a thread pool are kept alive so long as
/// there is an open handle to the `CpuPool` or there is work running on them. Once
/// all work has been drained and all references have gone away the worker
/// threads will be shut down.
///
/// Currently `CpuPool` implements `Clone` which just clones a new reference to
/// the underlying thread pool.
///
/// **Note:** if you use CpuPool inside a library it's better accept a
/// `Builder` object for thread configuration rather than configuring just
/// pool size.  This not only future proof for other settings but also allows
/// user to attach monitoring tools to lifecycle hooks.
pub struct CpuPool {
    inner: Arc<Inner>,
}

/// Thread pool configuration object
///
/// Builder starts with a number of workers equal to the number
/// of CPUs on the host. But you can change it until you call `create()`.
pub struct Builder {
    pool_size: usize,
    name_prefix: Option<String>,
    after_start: Option<Arc<Fn() + Send + Sync>>,
    before_stop: Option<Arc<Fn() + Send + Sync>>,
}

struct MySender<F, T> {
    fut: F,
    tx: Option<Sender<T>>,
    keep_running_flag: Arc<AtomicBool>,
}

fn _assert() {
    fn _assert_send<T: Send>() {}
    fn _assert_sync<T: Sync>() {}
    _assert_send::<CpuPool>();
    _assert_sync::<CpuPool>();
}

struct Inner {
    tx: Mutex<mpsc::Sender<Message>>,
    rx: Mutex<mpsc::Receiver<Message>>,
    cnt: AtomicUsize,
    size: usize,
    after_start: Option<Arc<Fn() + Send + Sync>>,
    before_stop: Option<Arc<Fn() + Send + Sync>>,
}

/// The type of future returned from the `CpuPool::spawn` function, which
/// proxies the futures running on the thread pool.
///
/// This future will resolve in the same way as the underlying future, and it
/// will propagate panics.
#[must_use]
pub struct CpuFuture<T, E> {
    inner: Receiver<thread::Result<Result<T, E>>>,
    keep_running_flag: Arc<AtomicBool>,
}

enum Message {
    Run(Run),
    Close,
}

impl CpuPool {
    /// Creates a new thread pool with `size` worker threads associated with it.
    ///
    /// The returned handle can use `execute` to run work on this thread pool,
    /// and clones can be made of it to get multiple references to the same
    /// thread pool.
    ///
    /// This is a shortcut for:
    ///
    /// ```rust
    /// Builder::new().pool_size(size).create()
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `size == 0`.
    pub fn new(size: usize) -> CpuPool {
        Builder::new().pool_size(size).create()
    }

    /// Creates a new thread pool with a number of workers equal to the number
    /// of CPUs on the host.
    ///
    /// This is a shortcut for:
    ///
    /// ```rust
    /// Builder::new().create()
    /// ```
    pub fn new_num_cpus() -> CpuPool {
        Builder::new().create()
    }

    /// Spawns a future to run on this thread pool, returning a future
    /// representing the produced value.
    ///
    /// This function will execute the future `f` on the associated thread
    /// pool, and return a future representing the finished computation. The
    /// returned future serves as a proxy to the computation that `F` is
    /// running.
    ///
    /// To simply run an arbitrary closure on a thread pool and extract the
    /// result, you can use the `future::lazy` combinator to defer work to
    /// executing on the thread pool itself.
    ///
    /// Note that if the future `f` panics it will be caught by default and the
    /// returned future will propagate the panic. That is, panics will not tear
    /// down the thread pool and will be propagated to the returned future's
    /// `poll` method if queried.
    ///
    /// If the returned future is dropped then this `CpuPool` will attempt to
    /// cancel the computation, if possible. That is, if the computation is in
    /// the middle of working, it will be interrupted when possible.
    pub fn spawn<F>(&self, f: F) -> CpuFuture<F::Item, F::Error>
        where F: Future + Send + 'static,
              F::Item: Send + 'static,
              F::Error: Send + 'static,
    {
        let (tx, rx) = channel();
        let keep_running_flag = Arc::new(AtomicBool::new(false));
        // AssertUnwindSafe is used here becuase `Send + 'static` is basically
        // an alias for an implementation of the `UnwindSafe` trait but we can't
        // express that in the standard library right now.
        let sender = MySender {
            fut: AssertUnwindSafe(f).catch_unwind(),
            tx: Some(tx),
            keep_running_flag: keep_running_flag.clone(),
        };
        executor::spawn(sender).execute(self.inner.clone());
        CpuFuture { inner: rx , keep_running_flag: keep_running_flag.clone() }
    }

    /// Spawns a closure on this thread pool.
    ///
    /// This function is a convenience wrapper around the `spawn` function above
    /// for running a closure wrapped in `future::lazy`. It will spawn the
    /// function `f` provided onto the thread pool, and continue to run the
    /// future returned by `f` on the thread pool as well.
    ///
    /// The returned future will be a handle to the result produced by the
    /// future that `f` returns.
    pub fn spawn_fn<F, R>(&self, f: F) -> CpuFuture<R::Item, R::Error>
        where F: FnOnce() -> R + Send + 'static,
              R: IntoFuture + 'static,
              R::Future: Send + 'static,
              R::Item: Send + 'static,
              R::Error: Send + 'static,
    {
        self.spawn(lazy(f))
    }
}

impl Inner {
    fn send(&self, msg: Message) {
        self.tx.lock().unwrap().send(msg).unwrap();
    }

    fn work(&self) {
        self.after_start.as_ref().map(|fun| fun());
        loop {
            let msg = self.rx.lock().unwrap().recv().unwrap();
            match msg {
                Message::Run(r) => r.run(),
                Message::Close => break,
            }
        }
        self.before_stop.as_ref().map(|fun| fun());
    }
}

impl Clone for CpuPool {
    fn clone(&self) -> CpuPool {
        self.inner.cnt.fetch_add(1, Ordering::Relaxed);
        CpuPool { inner: self.inner.clone() }
    }
}

impl Drop for CpuPool {
    fn drop(&mut self) {
        if self.inner.cnt.fetch_sub(1, Ordering::Relaxed) == 1 {
            for _ in 0..self.inner.size {
                self.inner.send(Message::Close);
            }
        }
    }
}

impl Executor for Inner {
    fn execute(&self, run: Run) {
        self.send(Message::Run(run))
    }
}

impl<T, E> CpuFuture<T, E> {
    /// Drop this future without canceling the underlying future.
    ///
    /// When `CpuFuture` is dropped, `CpuPool` will try to abort the underlying
    /// future. This function can be used when user wants to drop but keep
    /// executing the underlying future.
    pub fn forget(self) {
        self.keep_running_flag.store(true, Ordering::SeqCst);
    }
}

impl<T: Send + 'static, E: Send + 'static> Future for CpuFuture<T, E> {
    type Item = T;
    type Error = E;

    fn poll(&mut self) -> Poll<T, E> {
        match self.inner.poll().expect("shouldn't be canceled") {
            Async::Ready(Ok(Ok(e))) => Ok(e.into()),
            Async::Ready(Ok(Err(e))) => Err(e),
            Async::Ready(Err(e)) => panic::resume_unwind(e),
            Async::NotReady => Ok(Async::NotReady),
        }
    }
}

impl<F: Future> Future for MySender<F, Result<F::Item, F::Error>> {
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<(), ()> {
        if let Ok(Async::Ready(_)) = self.tx.as_mut().unwrap().poll_cancel() {
            if !self.keep_running_flag.load(Ordering::SeqCst) {
                // Cancelled, bail out
                return Ok(().into())
            }
        }

        let res = match self.fut.poll() {
            Ok(Async::Ready(e)) => Ok(e),
            Ok(Async::NotReady) => return Ok(Async::NotReady),
            Err(e) => Err(e),
        };

        // if the receiving end has gone away then that's ok, we just ignore the
        // send error here.
        drop(self.tx.take().unwrap().send(res));
        Ok(Async::Ready(()))
    }
}

impl Builder {
    /// Create a builder a number of workers equal to the number
    /// of CPUs on the host.
    pub fn new() -> Builder {
        Builder {
            pool_size: num_cpus::get(),
            name_prefix: None,
            after_start: None,
            before_stop: None,
        }
    }

    /// Set size of a future CpuPool
    ///
    /// The size of a thread pool is the number of worker threads spawned
    pub fn pool_size(&mut self, size: usize) -> &mut Self {
        self.pool_size = size;
        self
    }

    /// Set thread name prefix of a future CpuPool
    ///
    /// Thread name prefix is used for generating thread names. For example, if prefix is
    /// `my-pool-`, then threads in the pool will get names like `my-pool-1` etc.
    pub fn name_prefix<S: Into<String>>(&mut self, name_prefix: S) -> &mut Self {
        self.name_prefix = Some(name_prefix.into());
        self
    }

    /// Execute function `f` right after each thread is started but before
    /// running any jobs on it
    ///
    /// This is initially intended for bookkeeping and monitoring uses
    pub fn after_start<F>(&mut self, f: F) -> &mut Self
        where F: Fn() + Send + Sync + 'static
    {
        self.after_start = Some(Arc::new(f));
        self
    }

    /// Execute function `f` before each worker thread stops
    ///
    /// This is initially intended for bookkeeping and monitoring uses
    pub fn before_stop<F>(&mut self, f: F) -> &mut Self
        where F: Fn() + Send + Sync + 'static
    {
        self.before_stop = Some(Arc::new(f));
        self
    }

    /// Create CpuPool with configured parameters
    ///
    /// # Panics
    ///
    /// Panics if `pool_size == 0`.
    pub fn create(&mut self) -> CpuPool {
        let (tx, rx) = mpsc::channel();
        let pool = CpuPool {
            inner: Arc::new(Inner {
                tx: Mutex::new(tx),
                rx: Mutex::new(rx),
                cnt: AtomicUsize::new(1),
                size: self.pool_size,
                after_start: self.after_start.clone(),
                before_stop: self.before_stop.clone(),
            }),
        };
        assert!(self.pool_size > 0);

        for counter in 0..self.pool_size {
            let inner = pool.inner.clone();
            let mut thread_builder = thread::Builder::new();
            if let Some(ref name_prefix) = self.name_prefix {
                thread_builder = thread_builder.name(format!("{}{}", name_prefix, counter));
            }
            thread_builder.spawn(move || inner.work()).unwrap();
        }

        return pool
    }
}
<commit_msg>doc: fix doctest failures<commit_after>//! A simple crate for executing work on a thread pool, and getting back a
//! future.
//!
//! This crate provides a simple thread pool abstraction for running work
//! externally from the current thread that's running. An instance of `Future`
//! is handed back to represent that the work may be done later, and further
//! computations can be chained along with it as well.
//!
//! ```rust
//! extern crate futures;
//! extern crate futures_cpupool;
//!
//! use futures::Future;
//! use futures_cpupool::CpuPool;
//!
//! # fn long_running_future(a: u32) -> futures::future::BoxFuture<u32, ()> {
//! #     futures::future::result(Ok(a)).boxed()
//! # }
//! # fn main() {
//!
//! // Create a worker thread pool with four threads
//! let pool = CpuPool::new(4);
//!
//! // Execute some work on the thread pool, optionally closing over data.
//! let a = pool.spawn(long_running_future(2));
//! let b = pool.spawn(long_running_future(100));
//!
//! // Express some further computation once the work is completed on the thread
//! // pool.
//! let c = a.join(b).map(|(a, b)| a + b).wait().unwrap();
//!
//! // Print out the result
//! println!("{:?}", c);
//! # }
//! ```

#![deny(missing_docs)]

extern crate futures;
extern crate num_cpus;

use std::panic::{self, AssertUnwindSafe};
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::mpsc;
use std::thread;

use futures::{IntoFuture, Future, Poll, Async};
use futures::future::lazy;
use futures::sync::oneshot::{channel, Sender, Receiver};
use futures::executor::{self, Run, Executor};

/// A thread pool intended to run CPU intensive work.
///
/// This thread pool will hand out futures representing the completed work
/// that happens on the thread pool itself, and the futures can then be later
/// composed with other work as part of an overall computation.
///
/// The worker threads associated with a thread pool are kept alive so long as
/// there is an open handle to the `CpuPool` or there is work running on them. Once
/// all work has been drained and all references have gone away the worker
/// threads will be shut down.
///
/// Currently `CpuPool` implements `Clone` which just clones a new reference to
/// the underlying thread pool.
///
/// **Note:** if you use CpuPool inside a library it's better accept a
/// `Builder` object for thread configuration rather than configuring just
/// pool size.  This not only future proof for other settings but also allows
/// user to attach monitoring tools to lifecycle hooks.
pub struct CpuPool {
    inner: Arc<Inner>,
}

/// Thread pool configuration object
///
/// Builder starts with a number of workers equal to the number
/// of CPUs on the host. But you can change it until you call `create()`.
pub struct Builder {
    pool_size: usize,
    name_prefix: Option<String>,
    after_start: Option<Arc<Fn() + Send + Sync>>,
    before_stop: Option<Arc<Fn() + Send + Sync>>,
}

struct MySender<F, T> {
    fut: F,
    tx: Option<Sender<T>>,
    keep_running_flag: Arc<AtomicBool>,
}

fn _assert() {
    fn _assert_send<T: Send>() {}
    fn _assert_sync<T: Sync>() {}
    _assert_send::<CpuPool>();
    _assert_sync::<CpuPool>();
}

struct Inner {
    tx: Mutex<mpsc::Sender<Message>>,
    rx: Mutex<mpsc::Receiver<Message>>,
    cnt: AtomicUsize,
    size: usize,
    after_start: Option<Arc<Fn() + Send + Sync>>,
    before_stop: Option<Arc<Fn() + Send + Sync>>,
}

/// The type of future returned from the `CpuPool::spawn` function, which
/// proxies the futures running on the thread pool.
///
/// This future will resolve in the same way as the underlying future, and it
/// will propagate panics.
#[must_use]
pub struct CpuFuture<T, E> {
    inner: Receiver<thread::Result<Result<T, E>>>,
    keep_running_flag: Arc<AtomicBool>,
}

enum Message {
    Run(Run),
    Close,
}

impl CpuPool {
    /// Creates a new thread pool with `size` worker threads associated with it.
    ///
    /// The returned handle can use `execute` to run work on this thread pool,
    /// and clones can be made of it to get multiple references to the same
    /// thread pool.
    ///
    /// This is a shortcut for:
    ///
    /// ```rust
    /// # use futures_cpupool::{Builder, CpuPool};
    /// #
    /// # fn new(size: usize) -> CpuPool {
    /// Builder::new().pool_size(size).create()
    /// # }
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `size == 0`.
    pub fn new(size: usize) -> CpuPool {
        Builder::new().pool_size(size).create()
    }

    /// Creates a new thread pool with a number of workers equal to the number
    /// of CPUs on the host.
    ///
    /// This is a shortcut for:
    ///
    /// ```rust
    /// # use futures_cpupool::{Builder, CpuPool};
    /// #
    /// # fn new_num_cpus() -> CpuPool {
    /// Builder::new().create()
    /// # }
    /// ```
    pub fn new_num_cpus() -> CpuPool {
        Builder::new().create()
    }

    /// Spawns a future to run on this thread pool, returning a future
    /// representing the produced value.
    ///
    /// This function will execute the future `f` on the associated thread
    /// pool, and return a future representing the finished computation. The
    /// returned future serves as a proxy to the computation that `F` is
    /// running.
    ///
    /// To simply run an arbitrary closure on a thread pool and extract the
    /// result, you can use the `future::lazy` combinator to defer work to
    /// executing on the thread pool itself.
    ///
    /// Note that if the future `f` panics it will be caught by default and the
    /// returned future will propagate the panic. That is, panics will not tear
    /// down the thread pool and will be propagated to the returned future's
    /// `poll` method if queried.
    ///
    /// If the returned future is dropped then this `CpuPool` will attempt to
    /// cancel the computation, if possible. That is, if the computation is in
    /// the middle of working, it will be interrupted when possible.
    pub fn spawn<F>(&self, f: F) -> CpuFuture<F::Item, F::Error>
        where F: Future + Send + 'static,
              F::Item: Send + 'static,
              F::Error: Send + 'static,
    {
        let (tx, rx) = channel();
        let keep_running_flag = Arc::new(AtomicBool::new(false));
        // AssertUnwindSafe is used here becuase `Send + 'static` is basically
        // an alias for an implementation of the `UnwindSafe` trait but we can't
        // express that in the standard library right now.
        let sender = MySender {
            fut: AssertUnwindSafe(f).catch_unwind(),
            tx: Some(tx),
            keep_running_flag: keep_running_flag.clone(),
        };
        executor::spawn(sender).execute(self.inner.clone());
        CpuFuture { inner: rx , keep_running_flag: keep_running_flag.clone() }
    }

    /// Spawns a closure on this thread pool.
    ///
    /// This function is a convenience wrapper around the `spawn` function above
    /// for running a closure wrapped in `future::lazy`. It will spawn the
    /// function `f` provided onto the thread pool, and continue to run the
    /// future returned by `f` on the thread pool as well.
    ///
    /// The returned future will be a handle to the result produced by the
    /// future that `f` returns.
    pub fn spawn_fn<F, R>(&self, f: F) -> CpuFuture<R::Item, R::Error>
        where F: FnOnce() -> R + Send + 'static,
              R: IntoFuture + 'static,
              R::Future: Send + 'static,
              R::Item: Send + 'static,
              R::Error: Send + 'static,
    {
        self.spawn(lazy(f))
    }
}

impl Inner {
    fn send(&self, msg: Message) {
        self.tx.lock().unwrap().send(msg).unwrap();
    }

    fn work(&self) {
        self.after_start.as_ref().map(|fun| fun());
        loop {
            let msg = self.rx.lock().unwrap().recv().unwrap();
            match msg {
                Message::Run(r) => r.run(),
                Message::Close => break,
            }
        }
        self.before_stop.as_ref().map(|fun| fun());
    }
}

impl Clone for CpuPool {
    fn clone(&self) -> CpuPool {
        self.inner.cnt.fetch_add(1, Ordering::Relaxed);
        CpuPool { inner: self.inner.clone() }
    }
}

impl Drop for CpuPool {
    fn drop(&mut self) {
        if self.inner.cnt.fetch_sub(1, Ordering::Relaxed) == 1 {
            for _ in 0..self.inner.size {
                self.inner.send(Message::Close);
            }
        }
    }
}

impl Executor for Inner {
    fn execute(&self, run: Run) {
        self.send(Message::Run(run))
    }
}

impl<T, E> CpuFuture<T, E> {
    /// Drop this future without canceling the underlying future.
    ///
    /// When `CpuFuture` is dropped, `CpuPool` will try to abort the underlying
    /// future. This function can be used when user wants to drop but keep
    /// executing the underlying future.
    pub fn forget(self) {
        self.keep_running_flag.store(true, Ordering::SeqCst);
    }
}

impl<T: Send + 'static, E: Send + 'static> Future for CpuFuture<T, E> {
    type Item = T;
    type Error = E;

    fn poll(&mut self) -> Poll<T, E> {
        match self.inner.poll().expect("shouldn't be canceled") {
            Async::Ready(Ok(Ok(e))) => Ok(e.into()),
            Async::Ready(Ok(Err(e))) => Err(e),
            Async::Ready(Err(e)) => panic::resume_unwind(e),
            Async::NotReady => Ok(Async::NotReady),
        }
    }
}

impl<F: Future> Future for MySender<F, Result<F::Item, F::Error>> {
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<(), ()> {
        if let Ok(Async::Ready(_)) = self.tx.as_mut().unwrap().poll_cancel() {
            if !self.keep_running_flag.load(Ordering::SeqCst) {
                // Cancelled, bail out
                return Ok(().into())
            }
        }

        let res = match self.fut.poll() {
            Ok(Async::Ready(e)) => Ok(e),
            Ok(Async::NotReady) => return Ok(Async::NotReady),
            Err(e) => Err(e),
        };

        // if the receiving end has gone away then that's ok, we just ignore the
        // send error here.
        drop(self.tx.take().unwrap().send(res));
        Ok(Async::Ready(()))
    }
}

impl Builder {
    /// Create a builder a number of workers equal to the number
    /// of CPUs on the host.
    pub fn new() -> Builder {
        Builder {
            pool_size: num_cpus::get(),
            name_prefix: None,
            after_start: None,
            before_stop: None,
        }
    }

    /// Set size of a future CpuPool
    ///
    /// The size of a thread pool is the number of worker threads spawned
    pub fn pool_size(&mut self, size: usize) -> &mut Self {
        self.pool_size = size;
        self
    }

    /// Set thread name prefix of a future CpuPool
    ///
    /// Thread name prefix is used for generating thread names. For example, if prefix is
    /// `my-pool-`, then threads in the pool will get names like `my-pool-1` etc.
    pub fn name_prefix<S: Into<String>>(&mut self, name_prefix: S) -> &mut Self {
        self.name_prefix = Some(name_prefix.into());
        self
    }

    /// Execute function `f` right after each thread is started but before
    /// running any jobs on it
    ///
    /// This is initially intended for bookkeeping and monitoring uses
    pub fn after_start<F>(&mut self, f: F) -> &mut Self
        where F: Fn() + Send + Sync + 'static
    {
        self.after_start = Some(Arc::new(f));
        self
    }

    /// Execute function `f` before each worker thread stops
    ///
    /// This is initially intended for bookkeeping and monitoring uses
    pub fn before_stop<F>(&mut self, f: F) -> &mut Self
        where F: Fn() + Send + Sync + 'static
    {
        self.before_stop = Some(Arc::new(f));
        self
    }

    /// Create CpuPool with configured parameters
    ///
    /// # Panics
    ///
    /// Panics if `pool_size == 0`.
    pub fn create(&mut self) -> CpuPool {
        let (tx, rx) = mpsc::channel();
        let pool = CpuPool {
            inner: Arc::new(Inner {
                tx: Mutex::new(tx),
                rx: Mutex::new(rx),
                cnt: AtomicUsize::new(1),
                size: self.pool_size,
                after_start: self.after_start.clone(),
                before_stop: self.before_stop.clone(),
            }),
        };
        assert!(self.pool_size > 0);

        for counter in 0..self.pool_size {
            let inner = pool.inner.clone();
            let mut thread_builder = thread::Builder::new();
            if let Some(ref name_prefix) = self.name_prefix {
                thread_builder = thread_builder.name(format!("{}{}", name_prefix, counter));
            }
            thread_builder.spawn(move || inner.work()).unwrap();
        }

        return pool
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate simple_bitfield;

use std::mem;

simple_bitfield! {
    FooBar, u32, // newtype name, underlying type
    // getter name, setter name: msb (included), lsb
    foo1, set_foo1: 0, 0,
    foo2, set_foo2: 31, 31,
    foo3, set_foo3: 3, 0,
    foo4, set_foo4: 31, 28,
    // getter name, setter name: msb of first element (included), lsb of first element; count
    foo5, set_foo5: 0, 0; 32,
    foo6, set_foo6: 5, 3; 3,
    getter_only, _: 3, 1,
    _, setter_only: 4, 2,
    getter_only_array, _: 5, 3; 3,
    _, setter_only_array: 6, 4; 3,
}

#[test]
fn test_single_bit() {
    let mut fb = FooBar(0);

    fb.set_foo1(1);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo2(1);
    assert_eq!(0x80000001, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x1, fb.foo2());

    fb.set_foo1(0);
    assert_eq!(0x80000000, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x1, fb.foo2());
}

#[test]
fn test_single_bit_plus_garbage() {
    let mut fb = FooBar(0);

    fb.set_foo1(0b10);
    assert_eq!(0x0, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo1(0b11);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

}

#[test]
fn test_multiple_bit() {
    let mut fb = FooBar(0);

    fb.set_foo3(0x0F);
    assert_eq!(0xF, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0x0, fb.foo4());

    fb.set_foo4(0x0F);
    assert_eq!(0xF000000F, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0);
    assert_eq!(0xF0000000, fb.0);
    assert_eq!(0x0, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0xA);
    assert_eq!(0xF000000A, fb.0);
    assert_eq!(0xA, fb.foo3());
    assert_eq!(0xF, fb.foo4());
}

#[test]
fn test_getter_setter_only() {
    let mut fb = FooBar(0);
    fb.setter_only(0x7);
    assert_eq!(0x1C, fb.0);
    assert_eq!(0x6, fb.getter_only());
}

#[test]
fn test_array_field1() {
    let mut fb = FooBar(0);

    fb.set_foo5(0, 1);
    assert_eq!(0x1, fb.0);
    assert_eq!(1, fb.foo5(0));

    fb.set_foo5(0, 0);
    assert_eq!(0x0, fb.0);
    assert_eq!(0, fb.foo5(0));

    fb.set_foo5(0, 1);
    fb.set_foo5(6, 1);
    fb.set_foo5(31, 1);
    assert_eq!(0x80000041, fb.0);
    assert_eq!(1, fb.foo5(0));
    assert_eq!(1, fb.foo5(6));
    assert_eq!(1, fb.foo5(31));
    assert_eq!(0, fb.foo5(1));
    assert_eq!(0, fb.foo5(5));
    assert_eq!(0, fb.foo5(7));
    assert_eq!(0, fb.foo5(30));
}

#[test]
fn test_array_field2() {
    let mut fb = FooBar(0);

    fb.set_foo6(0, 1);
    assert_eq!(0x8, fb.0);
    assert_eq!(1, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(0, 7);
    assert_eq!(0x38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(2, 7);
    assert_eq!(0xE38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));

    fb.set_foo6(0, 0);
    assert_eq!(0xE00, fb.0);
    assert_eq!(0, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));

}
<commit_msg>Add more tests<commit_after>#[macro_use]
extern crate simple_bitfield;

use std::mem;

simple_bitfield! {
    FooBar, u32, // newtype name, underlying type
    // getter name, setter name: msb (included), lsb
    foo1, set_foo1: 0, 0,
    foo2, set_foo2: 31, 31,
    foo3, set_foo3: 3, 0,
    foo4, set_foo4: 31, 28,
    // getter name, setter name: msb of first element (included), lsb of first element; count
    foo5, set_foo5: 0, 0; 32,
    foo6, set_foo6: 5, 3; 3,
    getter_only, _: 3, 1,
    _, setter_only: 4, 2,
    getter_only_array, _: 5, 3; 3,
    _, setter_only_array: 6, 4; 3,
    all_bits, set_all_bits: 31, 0,
}

#[test]
fn test_single_bit() {
    let mut fb = FooBar(0);

    fb.set_foo1(1);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo2(1);
    assert_eq!(0x80000001, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x1, fb.foo2());

    fb.set_foo1(0);
    assert_eq!(0x80000000, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x1, fb.foo2());
}

#[test]
fn test_single_bit_plus_garbage() {
    let mut fb = FooBar(0);

    fb.set_foo1(0b10);
    assert_eq!(0x0, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo1(0b11);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

}

#[test]
fn test_multiple_bit() {
    let mut fb = FooBar(0);

    fb.set_foo3(0x0F);
    assert_eq!(0xF, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0x0, fb.foo4());

    fb.set_foo4(0x0F);
    assert_eq!(0xF000000F, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0);
    assert_eq!(0xF0000000, fb.0);
    assert_eq!(0x0, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0xA);
    assert_eq!(0xF000000A, fb.0);
    assert_eq!(0xA, fb.foo3());
    assert_eq!(0xF, fb.foo4());
}

#[test]
fn test_getter_setter_only() {
    let mut fb = FooBar(0);
    fb.setter_only(0x7);
    assert_eq!(0x1C, fb.0);
    assert_eq!(0x6, fb.getter_only());
}

#[test]
fn test_array_field1() {
    let mut fb = FooBar(0);

    fb.set_foo5(0, 1);
    assert_eq!(0x1, fb.0);
    assert_eq!(1, fb.foo5(0));

    fb.set_foo5(0, 0);
    assert_eq!(0x0, fb.0);
    assert_eq!(0, fb.foo5(0));

    fb.set_foo5(0, 1);
    fb.set_foo5(6, 1);
    fb.set_foo5(31, 1);
    assert_eq!(0x80000041, fb.0);
    assert_eq!(1, fb.foo5(0));
    assert_eq!(1, fb.foo5(6));
    assert_eq!(1, fb.foo5(31));
    assert_eq!(0, fb.foo5(1));
    assert_eq!(0, fb.foo5(5));
    assert_eq!(0, fb.foo5(7));
    assert_eq!(0, fb.foo5(30));
}

#[test]
fn test_array_field2() {
    let mut fb = FooBar(0);

    fb.set_foo6(0, 1);
    assert_eq!(0x8, fb.0);
    assert_eq!(1, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(0, 7);
    assert_eq!(0x38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(2, 7);
    assert_eq!(0xE38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));

    fb.set_foo6(0, 0);
    assert_eq!(0xE00, fb.0);
    assert_eq!(0, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));
}

#[test]
fn test_all_bits() {
    let mut fb = FooBar(0);

    assert_eq!(0, fb.all_bits());

    fb.set_all_bits(!0u32);
    assert_eq!(!0u32, fb.0);
    assert_eq!(!0u32, fb.all_bits());

    fb.0 = 0x80000001;
    assert_eq!(0x80000001, fb.all_bits());
}
<|endoftext|>


<commit_before>use serde_json;
use sputnikvm;

use sputnikvm::{read_hex, Gas, M256, Address};
use sputnikvm::vm::{VM, Machine, Stack, PC, ExecutionError};

use super::json::{create_machine, create_block, test_machine, apply_to_block, fire_with_block};

use serde_json::{Value, Error};
use std::fs::File;
use std::path::Path;
use std::io::{BufReader, Write, stdout};
use std::str::FromStr;

use rustyline::error::ReadlineError;
use rustyline::Editor;

pub fn test_transaction(name: &str, v: &Value, debug: bool) -> bool {
    print!("Testing {} ... ", name);
    if debug {
        print!("\n");
    }
    stdout().flush();

    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let result = fire_with_block(&mut machine, &block);
    apply_to_block(&machine, &mut block);

    let out = v["out"].as_str();

    if out.is_some() {
        if result.is_ok() {
            if test_machine(v, &machine, &block, debug) {
                println!("OK");
                return true;
            } else {
                println!("Failed (result not match)");
                return false;
            }
        } else {
            println!("Failed {:?}", result.err().unwrap());
            return false;
        }
    } else {
        if result.is_err() {
            println!("OK");
            return true;
        } else {
            println!("Failed");
            return false;
        }
    }
}

pub fn debug_transaction(v: &Value) {
    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let owner = machine.context().address;
    machine.commit_account(block.request_account(owner));
    let mut rl = Editor::<()>::new();

    loop {
        let readline = rl.readline(">> ");
        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                match line.as_ref() {
                    "step" => {
                        if machine.pc().stopped() {
                            println!("Stopped");
                        } else {
                            println!("Running {:?} ... {:?}.", machine.pc().peek_opcode(),
                                     machine.step());
                        }
                    },
                    "fire" => {
                        let result = machine.fire();
                        println!("{:?}", result);
                    },
                    "fire debug" => {
                        while !machine.pc().stopped() {
                            println!("Running {:?} ...", machine.pc().peek_opcode());
                            let gas = match machine.peek_cost() {
                                Ok(gas) => gas,
                                Err(ExecutionError::RequireAccount(address)) => {
                                    machine.commit_account(block.request_account(owner));
                                    machine.peek_cost().unwrap()
                                },
                                _ => unimplemented!(),
                            };
                            if gas < Gas::from(u64::max_value()) {
                                let gas: u64 = gas.into();
                                println!("Cost: {}", gas);
                            } else {
                                println!("Cost: 0x{:x}", gas);
                            }
                            for i in 0..machine.stack().len() {
                                println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                            }
                            println!("Result: {:?}", machine.step());
                            print!("\n");
                        }
                    },
                    "gas" => {
                        let gas = machine.peek_cost();
                        if gas.is_ok() {
                            println!("0x{:x}", gas.unwrap());
                        } else {
                            println!("{:?}", gas);
                        }
                    }
                    "out" => {
                        let ret = machine.return_values();
                        println!("{:?}", ret);
                    }
                    "print stack" => {
                        for i in 0..machine.stack().len() {
                            println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                        }
                    },
                    _ => {
                        println!("Unknown command.");
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
    }
}
<commit_msg>Problem: commit_account might return CommitError Solution: do an unwrap to make sure this is not the case<commit_after>use serde_json;
use sputnikvm;

use sputnikvm::{read_hex, Gas, M256, Address};
use sputnikvm::vm::{VM, Machine, Stack, PC, ExecutionError};

use super::json::{create_machine, create_block, test_machine, apply_to_block, fire_with_block};

use serde_json::{Value, Error};
use std::fs::File;
use std::path::Path;
use std::io::{BufReader, Write, stdout};
use std::str::FromStr;

use rustyline::error::ReadlineError;
use rustyline::Editor;

pub fn test_transaction(name: &str, v: &Value, debug: bool) -> bool {
    print!("Testing {} ... ", name);
    if debug {
        print!("\n");
    }
    stdout().flush();

    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let result = fire_with_block(&mut machine, &block);
    apply_to_block(&machine, &mut block);

    let out = v["out"].as_str();

    if out.is_some() {
        if result.is_ok() {
            if test_machine(v, &machine, &block, debug) {
                println!("OK");
                return true;
            } else {
                println!("Failed (result not match)");
                return false;
            }
        } else {
            println!("Failed {:?}", result.err().unwrap());
            return false;
        }
    } else {
        if result.is_err() {
            println!("OK");
            return true;
        } else {
            println!("Failed");
            return false;
        }
    }
}

pub fn debug_transaction(v: &Value) {
    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let owner = machine.context().address;
    machine.commit_account(block.request_account(owner)).unwrap();
    let mut rl = Editor::<()>::new();

    loop {
        let readline = rl.readline(">> ");
        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                match line.as_ref() {
                    "step" => {
                        if machine.pc().stopped() {
                            println!("Stopped");
                        } else {
                            println!("Running {:?} ... {:?}.", machine.pc().peek_opcode(),
                                     machine.step());
                        }
                    },
                    "fire" => {
                        let result = machine.fire();
                        println!("{:?}", result);
                    },
                    "fire debug" => {
                        while !machine.pc().stopped() {
                            println!("Running {:?} ...", machine.pc().peek_opcode());
                            let gas = match machine.peek_cost() {
                                Ok(gas) => gas,
                                Err(ExecutionError::RequireAccount(address)) => {
                                    machine.commit_account(block.request_account(address)).unwrap();
                                    machine.peek_cost().unwrap()
                                },
                                _ => unimplemented!(),
                            };
                            if gas < Gas::from(u64::max_value()) {
                                let gas: u64 = gas.into();
                                println!("Cost: {}", gas);
                            } else {
                                println!("Cost: 0x{:x}", gas);
                            }
                            for i in 0..machine.stack().len() {
                                println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                            }
                            println!("Result: {:?}", machine.step());
                            print!("\n");
                        }
                    },
                    "gas" => {
                        let gas = machine.peek_cost();
                        if gas.is_ok() {
                            println!("0x{:x}", gas.unwrap());
                        } else {
                            println!("{:?}", gas);
                        }
                    }
                    "out" => {
                        let ret = machine.return_values();
                        println!("{:?}", ret);
                    }
                    "print stack" => {
                        for i in 0..machine.stack().len() {
                            println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                        }
                    },
                    _ => {
                        println!("Unknown command.");
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
    }
}
<|endoftext|>


<commit_before>trait EventHandler<T> {
    type Handler;
    fn handle_event(&mut self, event: T);
    fn handler(&self) -> Self::Handler;
}

trait EventDemultiplexer {
    type Event;
    fn select(&mut self) -> Option<Self::Event>;
}

trait Reactor {
    type Event: Event;
    type Handler;
    fn handle_events(&mut self);
    fn register_handler(&mut self, handler: Box<EventHandler<Self::Event, Handler=Self::Handler>>);
    fn remove_handler(&mut self, handler: &EventHandler<Self::Event, Handler=Self::Handler>);
}

trait Event {
    type Handler;
    fn handler(&self) -> Self::Handler;
}
<commit_msg>reactor: make all traits in reactor public<commit_after>pub trait EventHandler<T> {
    type Handler;
    fn handle_event(&mut self, event: T);
    fn handler(&self) -> Self::Handler;
}

pub trait EventDemultiplexer {
    type Event;
    fn select(&mut self) -> Option<Self::Event>;
}

pub trait Reactor {
    type Event: Event;
    type Handler;
    fn handle_events(&mut self);
    fn register_handler(&mut self, handler: Box<EventHandler<Self::Event, Handler=Self::Handler>>);
    fn remove_handler(&mut self, handler: &EventHandler<Self::Event, Handler=Self::Handler>);
}

pub trait Event {
    type Handler;
    fn handler(&self) -> Self::Handler;
}
<|endoftext|>


<commit_before>use crate::{
    heartbeat::Heartbeat,
    socket_state::{SocketEvent, SocketStateHandle},
    tcp::TcpStream,
    thread::ThreadHandle,
    Result,
};
use log::trace;
use mio::{Events, Interest, Poll, Token};
use std::{
    collections::HashMap,
    fmt,
    sync::{
        atomic::{AtomicBool, AtomicUsize, Ordering},
        Arc,
    },
    thread::Builder as ThreadBuilder,
};

pub type Slot = usize;

pub trait ReactorBuilder: fmt::Debug + Send + Sync {
    fn build(&self, heartbeat: Heartbeat) -> Result<Box<dyn Reactor + Send>>;
}

pub trait Reactor: fmt::Debug + Send {
    fn register(&mut self, socket: &mut TcpStream, socket_state: SocketStateHandle)
        -> Result<Slot>;
    fn handle(&self) -> Box<dyn ReactorHandle + Send> {
        Box::new(DummyHandle)
    }
    #[allow(clippy::boxed_local)]
    fn start(self: Box<Self>) -> Result<ThreadHandle> {
        Ok(ThreadHandle::default())
    }
}

pub trait ReactorHandle {
    fn shutdown(&self) {}
    fn start_heartbeat(&self) {}
    fn poll_read(&self, _slot: Slot) {}
    fn poll_write(&self, _slot: Slot) {}
}

pub(crate) struct DefaultReactorBuilder;

impl ReactorBuilder for DefaultReactorBuilder {
    fn build(&self, heartbeat: Heartbeat) -> Result<Box<dyn Reactor + Send>> {
        Ok(Box::new(DefaultReactor::new(heartbeat)?))
    }
}

pub(crate) struct DefaultReactor {
    slot: AtomicUsize,
    poll: Poll,
    heartbeat: Heartbeat,
    slots: HashMap<Token, SocketStateHandle>,
    handle: DefaultReactorHandle,
}

#[derive(Clone)]
pub(crate) struct DefaultReactorHandle(Arc<AtomicBool>);

impl Reactor for DefaultReactor {
    fn handle(&self) -> Box<dyn ReactorHandle + Send> {
        Box::new(self.handle.clone())
    }

    fn register(
        &mut self,
        socket: &mut TcpStream,
        socket_state: SocketStateHandle,
    ) -> Result<usize> {
        let token = Token(self.slot.fetch_add(1, Ordering::SeqCst));
        self.poll
            .registry()
            .register(socket, token, Interest::READABLE | Interest::WRITABLE)?;
        self.slots.insert(token, socket_state);
        Ok(token.0)
    }

    fn start(mut self: Box<Self>) -> Result<ThreadHandle> {
        Ok(ThreadHandle::new(
            ThreadBuilder::new()
                .name("lapin-reactor".into())
                .spawn(move || {
                    let mut events = Events::with_capacity(16);
                    while self.should_run() {
                        self.run(&mut events)?;
                    }
                    Ok(())
                })?,
        ))
    }
}

impl DefaultReactor {
    fn new(heartbeat: Heartbeat) -> Result<Self> {
        Ok(Self {
            slot: AtomicUsize::new(1),
            poll: Poll::new()?,
            heartbeat,
            slots: HashMap::default(),
            handle: DefaultReactorHandle(Arc::new(AtomicBool::new(true))),
        })
    }

    fn should_run(&self) -> bool {
        self.handle.0.load(Ordering::SeqCst)
    }

    fn run(&mut self, events: &mut Events) -> Result<()> {
        trace!("reactor poll");
        self.poll.poll(events, self.heartbeat.poll_timeout()?)?;
        trace!("reactor poll done");
        for event in events.iter() {
            if let Some(socket) = self.slots.get(&event.token()) {
                if event.is_error() {
                    socket.send(SocketEvent::Error);
                }
                if event.is_read_closed() || event.is_write_closed() {
                    socket.send(SocketEvent::Closed);
                }
                if event.is_readable() {
                    socket.send(SocketEvent::Readable);
                }
                if event.is_writable() {
                    socket.send(SocketEvent::Writable);
                }
            }
        }
        Ok(())
    }
}

impl ReactorHandle for DefaultReactorHandle {
    fn shutdown(&self) {
        self.0.store(false, Ordering::SeqCst);
    }
}

impl fmt::Debug for DefaultReactorBuilder {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("DefaultReactorBuilder").finish()
    }
}

impl fmt::Debug for DefaultReactor {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("DefaultReactor").finish()
    }
}

#[derive(Clone)]
struct DummyHandle;

impl ReactorHandle for DummyHandle {}
<commit_msg>reactor: immediately close thread on shutdown<commit_after>use crate::{
    heartbeat::Heartbeat,
    socket_state::{SocketEvent, SocketStateHandle},
    tcp::TcpStream,
    thread::ThreadHandle,
    Result,
};
use log::trace;
use mio::{Events, Interest, Poll, Token, Waker};
use std::{
    collections::HashMap,
    fmt,
    sync::{
        atomic::{AtomicBool, AtomicUsize, Ordering},
        Arc,
    },
    thread::Builder as ThreadBuilder,
};

pub type Slot = usize;

pub trait ReactorBuilder: fmt::Debug + Send + Sync {
    fn build(&self, heartbeat: Heartbeat) -> Result<Box<dyn Reactor + Send>>;
}

pub trait Reactor: fmt::Debug + Send {
    fn register(&mut self, socket: &mut TcpStream, socket_state: SocketStateHandle)
        -> Result<Slot>;
    fn handle(&self) -> Box<dyn ReactorHandle + Send> {
        Box::new(DummyHandle)
    }
    #[allow(clippy::boxed_local)]
    fn start(self: Box<Self>) -> Result<ThreadHandle> {
        Ok(ThreadHandle::default())
    }
}

pub trait ReactorHandle {
    fn shutdown(&self) {}
    fn start_heartbeat(&self) {}
    fn poll_read(&self, _slot: Slot) {}
    fn poll_write(&self, _slot: Slot) {}
}

pub(crate) struct DefaultReactorBuilder;

impl ReactorBuilder for DefaultReactorBuilder {
    fn build(&self, heartbeat: Heartbeat) -> Result<Box<dyn Reactor + Send>> {
        Ok(Box::new(DefaultReactor::new(heartbeat)?))
    }
}

pub(crate) struct DefaultReactor {
    slot: AtomicUsize,
    poll: Poll,
    heartbeat: Heartbeat,
    slots: HashMap<Token, SocketStateHandle>,
    handle: DefaultReactorHandle,
}

#[derive(Clone)]
pub(crate) struct DefaultReactorHandle{
    run: Arc<AtomicBool>,
    waker: Arc<Waker>,
}

impl Reactor for DefaultReactor {
    fn handle(&self) -> Box<dyn ReactorHandle + Send> {
        Box::new(self.handle.clone())
    }

    fn register(
        &mut self,
        socket: &mut TcpStream,
        socket_state: SocketStateHandle,
    ) -> Result<usize> {
        let token = Token(self.slot.fetch_add(1, Ordering::SeqCst));
        self.poll
            .registry()
            .register(socket, token, Interest::READABLE | Interest::WRITABLE)?;
        self.slots.insert(token, socket_state);
        Ok(token.0)
    }

    fn start(mut self: Box<Self>) -> Result<ThreadHandle> {
        Ok(ThreadHandle::new(
            ThreadBuilder::new()
                .name("lapin-reactor".into())
                .spawn(move || {
                    let mut events = Events::with_capacity(16);
                    while self.should_run() {
                        self.run(&mut events)?;
                    }
                    Ok(())
                })?,
        ))
    }
}

impl DefaultReactor {
    fn new(heartbeat: Heartbeat) -> Result<Self> {
        let poll = Poll::new()?;
        let handle = DefaultReactorHandle {
            run: Arc::new(AtomicBool::new(true)),
            waker: Arc::new(Waker::new(poll.registry(), Token(0))?),
        };
        Ok(Self {
            slot: AtomicUsize::new(1),
            poll,
            heartbeat,
            slots: HashMap::default(),
            handle,
        })
    }

    fn should_run(&self) -> bool {
        self.handle.run.load(Ordering::SeqCst)
    }

    fn run(&mut self, events: &mut Events) -> Result<()> {
        trace!("reactor poll");
        self.poll.poll(events, self.heartbeat.poll_timeout()?)?;
        trace!("reactor poll done");
        for event in events.iter() {
            if let Some(socket) = self.slots.get(&event.token()) {
                if event.is_error() {
                    socket.send(SocketEvent::Error);
                }
                if event.is_read_closed() || event.is_write_closed() {
                    socket.send(SocketEvent::Closed);
                }
                if event.is_readable() {
                    socket.send(SocketEvent::Readable);
                }
                if event.is_writable() {
                    socket.send(SocketEvent::Writable);
                }
            }
        }
        Ok(())
    }
}

impl ReactorHandle for DefaultReactorHandle {
    fn shutdown(&self) {
        self.run.store(false, Ordering::SeqCst);
        self.waker.wake();
    }
}

impl fmt::Debug for DefaultReactorBuilder {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("DefaultReactorBuilder").finish()
    }
}

impl fmt::Debug for DefaultReactor {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("DefaultReactor").finish()
    }
}

#[derive(Clone)]
struct DummyHandle;

impl ReactorHandle for DummyHandle {}
<|endoftext|>


<commit_before>
extern crate rand;
extern crate ndarray;
extern crate ndarray_rand;
extern crate ndarray_linalg;

use std::cmp::min;
use ndarray::prelude::*;
use ndarray_linalg::prelude::*;
use rand::distributions::*;
use ndarray_rand::RandomExt;

fn all_close(a: Array<f64, (Ix, Ix)>, b: Array<f64, (Ix, Ix)>) {
    if !a.all_close(&b, 1.0e-7) {
        panic!("\nTwo matrices are not equal:\na = \n{:?}\nb = \n{:?}\n",
               a,
               b);
    }
}

#[test]
fn svd_square() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 3), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::eye(3);
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
#[test]
fn svd_square_t() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 3), r_dist).reversed_axes();
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::eye(3);
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}

#[test]
fn svd_4x3() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((4, 3), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((4, 3));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
#[test]
fn svd_4x3_t() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 4), r_dist).reversed_axes();
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((4, 3));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}

#[test]
fn svd_3x4() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 4), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((3, 4));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
#[test]
fn svd_3x4_t() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((4, 3), r_dist).reversed_axes();
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((3, 4));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
#[test]
fn svd_large() {
    let n = 2480;
    let m = 4280;
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((n, m), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((n, m));
    for i in 0..min(n, m) {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
<commit_msg>Add ignore flag<commit_after>
extern crate rand;
extern crate ndarray;
extern crate ndarray_rand;
extern crate ndarray_linalg;

use std::cmp::min;
use ndarray::prelude::*;
use ndarray_linalg::prelude::*;
use rand::distributions::*;
use ndarray_rand::RandomExt;

fn all_close(a: Array<f64, (Ix, Ix)>, b: Array<f64, (Ix, Ix)>) {
    if !a.all_close(&b, 1.0e-7) {
        panic!("\nTwo matrices are not equal:\na = \n{:?}\nb = \n{:?}\n",
               a,
               b);
    }
}

#[test]
fn svd_square() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 3), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::eye(3);
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
#[test]
fn svd_square_t() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 3), r_dist).reversed_axes();
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::eye(3);
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}

#[test]
fn svd_4x3() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((4, 3), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((4, 3));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
#[test]
fn svd_4x3_t() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 4), r_dist).reversed_axes();
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((4, 3));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}

#[test]
fn svd_3x4() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((3, 4), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((3, 4));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
#[test]
fn svd_3x4_t() {
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((4, 3), r_dist).reversed_axes();
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((3, 4));
    for i in 0..3 {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}

#[test]
#[ignore]
fn svd_large() {
    let n = 2480;
    let m = 4280;
    let r_dist = Range::new(0., 1.);
    let a = Array::<f64, _>::random((n, m), r_dist);
    let (u, s, vt) = a.clone().svd().unwrap();
    let mut sm = Array::zeros((n, m));
    for i in 0..min(n, m) {
        sm[(i, i)] = s[i];
    }
    all_close(u.dot(&sm).dot(&vt), a);
}
<|endoftext|>


<commit_before>use std::path::Path;

use crate::util;
use crate::version::Version;
use crate::vut::VutError;

mod cargo;
mod npm;
mod version_file;

pub use cargo::*;
pub use npm::*;
pub use version_file::*;

/// Trait representing the authoritative source of a project's version
pub trait VersionSource {
    fn get_path(&self) -> &Path;
    fn exists(&self) -> bool;
    fn get_version(&self) -> Result<Version, VutError>;
    fn set_version(&mut self, version: &Version) -> Result<(), VutError>;
}

pub fn first_version_source_from_path(path: &Path) -> Option<Box<dyn VersionSource>> {
    let source: Option<Box<dyn VersionSource>> = if let Some(source) = VersionFileSource::from_path(path) {
        Some(Box::new(source))
    } else if let Some(source) = CargoSource::from_path(path) {
        Some(Box::new(source))
    } else if let Some(source) = NpmSource::from_path(path) {
        Some(Box::new(source))
    } else {
        None
    };

    source
}

pub fn locate_first_version_source_from(start_path: &Path) -> Option<Box<dyn VersionSource>> {
    util::find_outwards(start_path, |path| first_version_source_from_path(path)).map(|(_, source)| source)
}

macro_rules! generate_build_version_source_checker {
    (
        $fn_name:ident {
            $( $src_name:expr => $src_type:ty ),* $(,)*
        }
    ) => {
        pub fn $fn_name(source_names: &[String]) -> Box<dyn Fn(&Path) -> Vec<Box<dyn VersionSource>>>
        {
            let mut checkers: Vec<Box<dyn Fn(&Path) -> Option<Box<dyn VersionSource>>>> = Vec::new();

            if source_names.iter().any(|n| n == "*") {
                // Source names contains "*" wildcard - add all version source checks
                $( checkers.push(Box::new(move |path: &Path| <$src_type>::from_path(path).map(|s| Box::new(s) as Box<dyn VersionSource>))); )*
            } else {
                // Source names does not contain wildcard. Add sources based on names in the list.
                for name in source_names {
                    let checker: Option<Box<dyn Fn(&Path) -> Option<Box<dyn VersionSource>>>> = match name.as_str() {
                        $( $src_name => Some(Box::new(move |path: &Path| <$src_type>::from_path(path).map(|s| Box::new(s) as Box<dyn VersionSource>))), )*
                        _ => None,
                    };

                    if let Some(checker) = checker {
                        checkers.push(checker);
                    }
                }
            }

            Box::new(move |path: &Path| -> Vec<Box<dyn VersionSource>> {
                let mut sources: Vec<Box<dyn VersionSource>> = Vec::new();

                for checker in checkers.iter() {
                    if let Some(source) = checker(path) {
                        sources.push(source);
                    }
                }

                sources
            })
        }
    };
}

generate_build_version_source_checker! {
    build_version_source_checker {
        "vut" => VersionFileSource,
        "cargo" => CargoSource,
        "npm" => NpmSource,
    }
}
<commit_msg>refactor: Simplify source checker generator<commit_after>use std::collections::HashSet;
use std::path::Path;

use crate::util;
use crate::version::Version;
use crate::vut::VutError;

mod cargo;
mod npm;
mod version_file;

pub use cargo::*;
pub use npm::*;
pub use version_file::*;

/// Trait representing the authoritative source of a project's version
pub trait VersionSource {
    fn get_path(&self) -> &Path;
    fn exists(&self) -> bool;
    fn get_version(&self) -> Result<Version, VutError>;
    fn set_version(&mut self, version: &Version) -> Result<(), VutError>;
}

pub fn first_version_source_from_path(path: &Path) -> Option<Box<dyn VersionSource>> {
    let source: Option<Box<dyn VersionSource>> = if let Some(source) = VersionFileSource::from_path(path) {
        Some(Box::new(source))
    } else if let Some(source) = CargoSource::from_path(path) {
        Some(Box::new(source))
    } else if let Some(source) = NpmSource::from_path(path) {
        Some(Box::new(source))
    } else {
        None
    };

    source
}

pub fn locate_first_version_source_from(start_path: &Path) -> Option<Box<dyn VersionSource>> {
    util::find_outwards(start_path, |path| first_version_source_from_path(path)).map(|(_, source)| source)
}

macro_rules! generate_build_version_source_checker {
    (
        $fn_name:ident {
            $( $src_name:expr => $src_type:ty ),* $(,)*
        }
    ) => {
        pub fn $fn_name(source_names: &[String]) -> Box<dyn Fn(&Path) -> Vec<Box<dyn VersionSource>>>
        {
            let source_types: HashSet<String> = source_names.iter().map(|n| n.clone()).collect();

            if source_types.contains("*") {
                Box::new(move |path: &Path| -> Vec<Box<dyn VersionSource>> {
                    let mut sources: Vec<Box<dyn VersionSource>> = Vec::new();

                    $(
                        if let Some(source) = <$src_type>::from_path(path).map(|s| Box::new(s) as Box<dyn VersionSource>) {
                            sources.push(source);
                        }
                    )*

                    sources
                })
            } else {
                Box::new(move |path: &Path| -> Vec<Box<dyn VersionSource>> {
                    let mut sources: Vec<Box<dyn VersionSource>> = Vec::new();

                    $(
                        if source_types.contains($src_name) {
                            if let Some(source) = <$src_type>::from_path(path).map(|s| Box::new(s) as Box<dyn VersionSource>) {
                                sources.push(source);
                            }
                        }
                    )*

                    sources
                })
            }
        }
    };
}

generate_build_version_source_checker! {
    build_version_source_checker {
        "vut" => VersionFileSource,
        "cargo" => CargoSource,
        "npm" => NpmSource,
    }
}
<|endoftext|>


<commit_before>use std::fmt::{Debug, Formatter, Error};
use std::process::Command;

extern crate log;
use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};

pub use cli::CliConfig;
pub use configuration::Configuration as Cfg;

use storage::Store;

pub struct ImagLogger {
    lvl: LogLevel,
}

impl ImagLogger {

    pub fn new(lvl: LogLevel) -> ImagLogger {
        ImagLogger {
            lvl: lvl,
        }
    }

    pub fn init(config: &CliConfig) -> Result<(), SetLoggerError> {
        let lvl = if config.is_debugging() {
            LogLevelFilter::Debug
        } else if config.is_verbose() {
            LogLevelFilter::Info
        } else {
            LogLevelFilter::Error
        };

        log::set_logger(|max_log_lvl| {
            max_log_lvl.set(lvl);
            debug!("Init logger with: {}", lvl);
            Box::new(ImagLogger::new(lvl.to_log_level().unwrap()))
        })
    }

}

impl log::Log for ImagLogger {

    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.lvl
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("[{}]: {}", record.level(), record.args());
        }
    }
}

/**
 * Runtime object, represents a single interface to both the CLI configuration and the
 * configuration file. Also carries the store object around and is basically an object which
 * contains everything which is required to run a command/module.
 */
pub struct Runtime<'a> {
    pub config : CliConfig<'a>,
    pub configuration : Cfg,
    pub store : Store,
}

impl<'a> Runtime<'a> {

    pub fn new(cfg: Cfg, config : CliConfig<'a>) -> Runtime<'a> {
        let sp = config.store_path().unwrap_or(cfg.store_path());
        Runtime {
            config: config,
            configuration: cfg,
            store: Store::new(sp),
        }
    }

    /**
     * Check whether we run verbose
     */
    pub fn is_verbose(&self) -> bool {
        self.config.is_verbose()
    }

    /**
     * Check whether we run in debugging
     */
    pub fn is_debugging(&self) -> bool {
        self.config.is_debugging()
    }

    /**
     * Get the store path we are currently using
     */
    pub fn store_path(&self) -> String {
        self.config.store_path().unwrap_or(self.configuration.store_path())
    }

    /**
     * Get the store object
     */
    pub fn store(&self) -> &Store {
        &self.store
    }

    /**
     * Get the runtime path we are currently using
     */
    pub fn get_rtp(&self) -> String {
        if let Some(rtp) = self.config.get_rtp() {
            rtp
        } else {
            self.configuration.get_rtp()
        }
    }

    pub fn editor(&self) -> Command {
        use std::env::var;

        let (editor, args) : (String, String) = {
            if let Some(editor) = self.config.editor() {
                (editor, self.config.editor_opts())
            } else if let Some(editor) = self.configuration.editor() {
                (editor, self.configuration.editor_opts())
            } else if let Ok(editor) = var("EDITOR") {
                (editor, String::from(""))
            } else {
                (String::from("vim"), String::from(""))
            }
        };

        let mut e = Command::new(editor);
        for arg in args.split(" ") {
            e.arg(arg);
        }
        e
    }

    pub fn report_exit(&self) -> bool {
        self.config.report_exit() || self.configuration.report_exit()
    }

}

impl<'a> Debug for Runtime<'a> {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Runtime (verbose: {}, debugging: {}, rtp: {})",
            self.is_verbose(),
            self.is_debugging(),
            self.get_rtp())
    }

}

<commit_msg>Remove the Store dependency from the Runtime object<commit_after>use std::fmt::{Debug, Formatter, Error};
use std::process::Command;

extern crate log;
use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};

pub use cli::CliConfig;
pub use configuration::Configuration as Cfg;

pub struct ImagLogger {
    lvl: LogLevel,
}

impl ImagLogger {

    pub fn new(lvl: LogLevel) -> ImagLogger {
        ImagLogger {
            lvl: lvl,
        }
    }

    pub fn init(config: &CliConfig) -> Result<(), SetLoggerError> {
        let lvl = if config.is_debugging() {
            LogLevelFilter::Debug
        } else if config.is_verbose() {
            LogLevelFilter::Info
        } else {
            LogLevelFilter::Error
        };

        log::set_logger(|max_log_lvl| {
            max_log_lvl.set(lvl);
            // debug!("Init logger with: {}", lvl);
            Box::new(ImagLogger::new(lvl.to_log_level().unwrap()))
        })
    }

}

impl log::Log for ImagLogger {

    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.lvl
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("[{}]: {}", record.level(), record.args());
        }
    }
}

/**
 * Runtime object, represents a single interface to both the CLI configuration and the
 * configuration file.
 */
pub struct Runtime<'a> {
    pub config : CliConfig<'a>,
    pub configuration : Cfg,
}

impl<'a> Runtime<'a> {

    pub fn new(cfg: Cfg, config : CliConfig<'a>) -> Runtime<'a> {
        let sp = config.store_path().unwrap_or(cfg.store_path());
        Runtime {
            config: config,
            configuration: cfg,
        }
    }

    /**
     * Check whether we run verbose
     */
    pub fn is_verbose(&self) -> bool {
        self.config.is_verbose()
    }

    /**
     * Check whether we run in debugging
     */
    pub fn is_debugging(&self) -> bool {
        self.config.is_debugging()
    }

    /**
     * Get the store path we are currently using
     */
    pub fn store_path(&self) -> String {
        self.config.store_path().unwrap_or(self.configuration.store_path())
    }

    /**
     * Get the runtime path we are currently using
     */
    pub fn get_rtp(&self) -> String {
        if let Some(rtp) = self.config.get_rtp() {
            rtp
        } else {
            self.configuration.get_rtp()
        }
    }

    pub fn editor(&self) -> Command {
        use std::env::var;

        let (editor, args) : (String, String) = {
            if let Some(editor) = self.config.editor() {
                (editor, self.config.editor_opts())
            } else if let Some(editor) = self.configuration.editor() {
                (editor, self.configuration.editor_opts())
            } else if let Ok(editor) = var("EDITOR") {
                (editor, String::from(""))
            } else {
                (String::from("vim"), String::from(""))
            }
        };

        let mut e = Command::new(editor);
        for arg in args.split(" ") {
            e.arg(arg);
        }
        e
    }

    pub fn report_exit(&self) -> bool {
        self.config.report_exit() || self.configuration.report_exit()
    }

}

impl<'a> Debug for Runtime<'a> {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Runtime (verbose: {}, debugging: {}, rtp: {})",
            self.is_verbose(),
            self.is_debugging(),
            self.get_rtp())
    }

}

<|endoftext|>


<commit_before>use cartridge::Cartridge;

use bus::Bus;
use cpu::{Cpu, Interrupt};
use joypad::Button;
use lcd::{SCREEN_WIDTH, SCREEN_HEIGHT};
use minifb::{Key, Scale, WindowOptions, Window};
use std::time::Instant;

pub struct Rustboy<'a> {
    bus: Bus<'a>,
    cpu: Cpu,
    screen_buffer: [u32; SCREEN_WIDTH * SCREEN_HEIGHT],
    window: Window
}

impl<'a> Rustboy<'a> {
    pub fn new(cartridge: &'a mut Cartridge) -> Self {
        Self {
            bus: Bus::new(cartridge),
            cpu: Cpu::new(),
            screen_buffer: [0; SCREEN_WIDTH * SCREEN_HEIGHT],
            window: create_window(Scale::X4)
        }
    }

    pub fn run(&mut self) {
        // Clear the window
        for i in self.screen_buffer.iter_mut() {
            *i = 0xFFFFFF;
        }

        self.window.update_with_buffer(&self.screen_buffer).expect("Unable to render window");

        // Set the CPU to initial values
        self.cpu.reset();

        // FPS counter variables
        let mut fps_counter_time = Instant::now();
        let mut fps_counter_frames = 0;

        while self.window.is_open() && !self.window.is_key_down(Key::Escape) {
            let buttons = get_button_presses(&self.window);

            // Execute the next CPU instruction. The number of cycles used is returned.
            let cycles = self.cpu.step(&mut self.bus);

            // Step timer
            let timer_result = self.bus.timer.step(cycles);

            // Step LCD
            let lcd_result = self.bus.lcd.step(cycles, &mut self.screen_buffer);

            // Step joypad
            let joypad_result = self.bus.joypad.step(buttons);

            // The timer interrupts when the counter reaches its goal
            if timer_result.interrupt {
                self.cpu.interrupt(&mut self.bus, Interrupt::Timer);
            }

            // LCD can generate a STAT interrupt when modes change or when the cursor reaches a specific line
            if lcd_result.int_stat {
                self.cpu.interrupt(&mut self.bus, Interrupt::Stat);
            }

            // Joypad interrupts when a button is pressed
            if joypad_result.interrupt {
                self.cpu.interrupt(&mut self.bus, Interrupt::Joypad);
            }

            // LCD interrupts when VLANK is reached
            // We'll use this time to update the framebuffer, record any key presses for the next frame, and update the FPS counter
            if lcd_result.int_vblank {
                self.cpu.interrupt(&mut self.bus, Interrupt::VBlank);
                self.window.update_with_buffer(&self.screen_buffer).unwrap();

                fps_counter_frames += 1;

                // If a second has passed, update the FPS counter
                let elapsed = fps_counter_time.elapsed();

                if elapsed.as_secs() > 0 {
                    self.window.set_title(format!("Rustboy ({} FPS)", fps_counter_frames).as_str());
                    fps_counter_time = Instant::now();
                    fps_counter_frames = 0;
                }
            }
        }
    }
}

fn create_window(scale: Scale) -> Window {
    Window::new(
        "Rustboy",
        SCREEN_WIDTH,
        SCREEN_HEIGHT,
        WindowOptions {
            scale: scale,
            ..WindowOptions::default()
        }).expect("Unable to create window")
}

#[inline(always)]
fn get_button_presses(window: &Window) -> Button {
    let mut buttons: Button = Button::empty();

    if window.is_key_down(Key::Enter) {
        buttons |= Button::START;
    }

    if window.is_key_down(Key::RightShift) || window.is_key_down(Key::LeftShift) {
        buttons |= Button::SELECT;
    }

    if window.is_key_down(Key::Up) {
        buttons |= Button::UP;
    }

    if window.is_key_down(Key::Right) {
        buttons |= Button::RIGHT;
    }

    if window.is_key_down(Key::Down) {
        buttons |= Button::DOWN;
    }

    if window.is_key_down(Key::Left) {
        buttons |= Button::LEFT;
    }

    if window.is_key_down(Key::Z) {
        buttons |= Button::B;
    }

    if window.is_key_down(Key::X) {
        buttons |= Button::A;
    }

    buttons
}<commit_msg>Improve performance when getting key presses<commit_after>use cartridge::Cartridge;

use bus::Bus;
use cpu::{Cpu, Interrupt};
use joypad::Button;
use lcd::{SCREEN_WIDTH, SCREEN_HEIGHT};
use minifb::{Key, Scale, WindowOptions, Window};
use std::time::Instant;

pub struct Rustboy<'a> {
    bus: Bus<'a>,
    cpu: Cpu,
    screen_buffer: [u32; SCREEN_WIDTH * SCREEN_HEIGHT],
    window: Window
}

impl<'a> Rustboy<'a> {
    pub fn new(cartridge: &'a mut Cartridge) -> Self {
        Self {
            bus: Bus::new(cartridge),
            cpu: Cpu::new(),
            screen_buffer: [0; SCREEN_WIDTH * SCREEN_HEIGHT],
            window: create_window(Scale::X4)
        }
    }

    pub fn run(&mut self) {
        // Clear the window
        for i in self.screen_buffer.iter_mut() {
            *i = 0xFFFFFF;
        }

        self.window.update_with_buffer(&self.screen_buffer).expect("Unable to render window");

        // Set the CPU to initial values
        self.cpu.reset();

        // FPS counter variables
        let mut fps_counter_time = Instant::now();
        let mut fps_counter_frames = 0;

        let mut buttons = Button::empty();

        while self.window.is_open() && !self.window.is_key_down(Key::Escape) {
            // Execute the next CPU instruction. The number of cycles used is returned.
            let cycles = self.cpu.step(&mut self.bus);

            // Step timer
            let timer_result = self.bus.timer.step(cycles);

            // Step LCD
            let lcd_result = self.bus.lcd.step(cycles, &mut self.screen_buffer);

            // Step joypad
            let joypad_result = self.bus.joypad.step(buttons);

            // The timer interrupts when the counter reaches its goal
            if timer_result.interrupt {
                self.cpu.interrupt(&mut self.bus, Interrupt::Timer);
            }

            // LCD can generate a STAT interrupt when modes change or when the cursor reaches a specific line
            if lcd_result.int_stat {
                self.cpu.interrupt(&mut self.bus, Interrupt::Stat);
            }

            // Joypad interrupts when a button is pressed
            if joypad_result.interrupt {
                self.cpu.interrupt(&mut self.bus, Interrupt::Joypad);
            }

            // LCD interrupts when VLANK is reached
            // We'll use this time to update the framebuffer and FPS counter. Also we'll get the current pressed buttons
            if lcd_result.int_vblank {
                self.cpu.interrupt(&mut self.bus, Interrupt::VBlank);
                self.window.update_with_buffer(&self.screen_buffer).unwrap();

                fps_counter_frames += 1;

                // If a second has passed, update the FPS counter
                let elapsed = fps_counter_time.elapsed();

                if elapsed.as_secs() > 0 {
                    self.window.set_title(format!("Rustboy ({} FPS)", fps_counter_frames).as_str());
                    fps_counter_time = Instant::now();
                    fps_counter_frames = 0;
                }

                self.set_button_presses(&mut buttons);
            }
        }
    }

    fn set_button_presses(&self, buttons: &mut Button) {
        *buttons = Button::empty();

        if self.window.is_key_down(Key::Enter) {
            *buttons |= Button::START;
        }

        if self.window.is_key_down(Key::RightShift) || self.window.is_key_down(Key::LeftShift) {
            *buttons |= Button::SELECT;
        }

        if self.window.is_key_down(Key::Up) {
            *buttons |= Button::UP;
        }

        if self.window.is_key_down(Key::Right) {
            *buttons |= Button::RIGHT;
        }

        if self.window.is_key_down(Key::Down) {
            *buttons |= Button::DOWN;
        }

        if self.window.is_key_down(Key::Left) {
            *buttons |= Button::LEFT;
        }

        if self.window.is_key_down(Key::Z) {
            *buttons |= Button::B;
        }

        if self.window.is_key_down(Key::X) {
            *buttons |= Button::A;
        }
    }
}

fn create_window(scale: Scale) -> Window {
    Window::new(
        "Rustboy",
        SCREEN_WIDTH,
        SCREEN_HEIGHT,
        WindowOptions {
            scale: scale,
            ..WindowOptions::default()
        }).expect("Unable to create window")
}<|endoftext|>