<commit_before>use bifrost::vector_clock::{VectorClock, StandardVectorClock, ServerVectorClock};
use bifrost::utils::time::get_time;
use chashmap::{CHashMap, WriteGuard};
use std::collections::{BTreeMap, BTreeSet, HashMap};
use ram::types::{Id};
use ram::cell::{Cell, ReadError, WriteError};
use server::NebServer;
use parking_lot::Mutex;
use std::sync::mpsc::{channel, Sender, Receiver};
use futures;
use super::*;

type TxnAwaits = Arc<Mutex<HashMap<u64, Arc<AwaitingServer>>>>;
type TxnGuard<'a> = WriteGuard<'a, TransactionId, Transaction>;
type ChangedObjs = BTreeMap<u64, Vec<(Id, DataObject)>>;
type DataSiteClients = HashMap<u64, Arc<data_site::AsyncServiceClient>>;

pub static DEFAULT_SERVICE_ID: u64 = hash_ident!(TNX_MANAGER_RPC_SERVICE) as u64;

#[derive(Debug, Serialize, Deserialize)]
pub enum TMError {
    TransactionNotFound,
    CannotLocateCellServer,
    NoResponseFromCellServer,
    AssertionError
}

#[derive(Clone)]
struct DataObject {
    server: u64,
    cell: Option<Cell>,
    new: bool
}

struct Transaction {
    start_time: i64, // use for timeout detecting
    id: TransactionId,
    data: BTreeMap<Id, DataObject>,
    writes: BTreeSet<Id>,
}

service! {
    rpc begin() -> TransactionId;
    rpc read(tid: TransactionId, id: Id) -> TransactionExecResult<Cell, ReadError> | TMError;
    rpc write(tid: TransactionId, id: Id, cell: Cell) -> TransactionExecResult<(), WriteError> | TMError;
    rpc update(tid: TransactionId, cell: Cell) -> TransactionExecResult<(), WriteError> | TMError;
    rpc remove(tid: TransactionId, id: Id) -> TransactionExecResult<(), WriteError> | TMError;

    rpc prepare(tid: TransactionId) -> PrepareResult | TMError;
    rpc commit(tid: TransactionId);
    rpc abort(tid: TransactionId);

    rpc go_ahead(tid: BTreeSet<TransactionId>); // invoked by data site to continue on it's transaction in case of waiting
}

pub struct TransactionManager {
    server: Arc<NebServer>,
    transactions: CHashMap<TransactionId, Transaction>,
    data_sites: CHashMap<u64, Arc<data_site::AsyncServiceClient>>,
}
dispatch_rpc_service_functions!(TransactionManager);

impl TransactionManager {
    pub fn new(server: &Arc<NebServer>) -> Arc<TransactionManager> {
        Arc::new(TransactionManager {
            server: server.clone(),
            transactions: CHashMap::new(),
            data_sites: CHashMap::new()
        })
    }
}

impl TransactionManager {
    fn server_id(&self) -> u64 {
        self.server.server_id
    }
    fn get_data_site(&self, server_id: u64) -> io::Result<Arc<data_site::AsyncServiceClient>> {
        if !self.data_sites.contains_key(&server_id) {
            let client = self.server.get_member_by_server_id(server_id)?;
            self.data_sites.upsert(server_id, || {
                data_site::AsyncServiceClient::new(DEFAULT_SERVICE_ID, &client)
            }, |_| {});
        }
        Ok(self.data_sites .get(&server_id).unwrap().clone())
    }
    fn get_data_site_by_id(&self, id: &Id) -> io::Result<(u64, Arc<data_site::AsyncServiceClient>)> {
        match self.server.get_server_id_by_id(id) {
            Some(id) => match self.get_data_site(id) {
                Ok(site) => Ok((id, site.clone())),
                Err(e) => Err(e)
            },
            _ => Err(io::Error::new(io::ErrorKind::NotFound, "cannot find data site for this id"))
        }
    }
    fn get_clock(&self) -> StandardVectorClock {
        self.server.txn_peer.clock.to_clock()
    }
    fn merge_clock(&self, clock: &StandardVectorClock) {
        self.server.txn_peer.clock.merge_with(clock)
    }
    fn get_transaction(&self, tid: &TransactionId) -> Result<TxnGuard, TMError> {
        match self.transactions.get_mut(tid) {
            Some(tnx) => Ok(tnx),
            _ => {Err(TMError::TransactionNotFound)}
        }
    }
    fn changed_objs(&self, txn: &TxnGuard) -> ChangedObjs {
        let mut changed_objs: BTreeMap<u64, Vec<(Id, DataObject)>> = BTreeMap::new();
        for (id, data_obj) in &txn.data {
            changed_objs.entry(data_obj.server).or_insert_with(|| Vec::new()).push((*id, data_obj.clone()));
        }
        changed_objs
    }
    fn data_sites(&self, changed_objs: &ChangedObjs) -> Result<DataSiteClients, TMError>  {
        let data_sites: HashMap<u64, _> = changed_objs.iter().map(|(server_id, _)| {
            (*server_id, self.get_data_site(*server_id))
        }).collect();
        if data_sites.iter().any(|(_, data_site)| { data_site.is_err() }) {
            return Err(TMError::CannotLocateCellServer)
        }
        Ok(data_sites.into_iter().map(
            |(server_id, data_site)| {
                (server_id, data_site.unwrap())
            }
        ).collect())
    }
    fn site_prepare(
        server: Arc<NebServer>,
        tid: &TransactionId,
        objs: &Vec<(Id, DataObject)>,
        data_site: &Arc<data_site::AsyncServiceClient>
    ) -> Box<futures::Future<Item = PrepareResult, Error = TMError>> {
        let self_server_id = server.server_id;
        let cell_ids: Vec<_> = objs.iter().map(|&(id, _)| id).collect();
        let res_future = data_site
            .prepare(&self_server_id, &server.txn_peer.clock.to_clock(), tid, &cell_ids)
            .map_err(|_| -> TMError {
                TMError::NoResponseFromCellServer
            })
            .map(move |prepare_res| -> PrepareResult {
                let prepare_res = prepare_res.unwrap();
                server.txn_peer.clock.merge_with(&prepare_res.clock);
                prepare_res.payload
            })
            .then(|prepare_payload| {
                match prepare_payload {
                    Ok(payload) => {
                        match payload {
                            PrepareResult::Wait => {
                                return Ok(payload)
                            },
                            _ => {
                                return Ok(payload)
                            }
                        }
                    },
                    Err(e) => Err(e)
                }
            });
        Box::new(res_future)
    }
    fn sites_prepare(&self, tid: &TransactionId, txn: Transaction, changed_objs: &ChangedObjs, data_sites: DataSiteClients) {
        let prepare_futures: Vec<_> = changed_objs.iter().map(|(server, objs)| {
            let data_site = data_sites.get(&server).unwrap();
            TransactionManager::site_prepare(
                self.server.clone(), tid, objs, data_site
            )
        }).collect();
        let prepare_result = future::join_all(prepare_futures).wait();
    }
}

impl Service for TransactionManager {
    fn begin(&self) -> Result<TransactionId, ()> {
        let id = self.server.txn_peer.clock.inc();
        self.transactions.insert(id.clone(), Transaction {
            start_time: get_time(),
            id: id.clone(),
            data: BTreeMap::new(),
            writes: BTreeSet::new()
        });
        Ok(id)
    }
    fn read(&self, tid: &TransactionId, id: &Id) -> Result<TransactionExecResult<Cell, ReadError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        if let Some(dataObj) = txn.data.get(id) {
            match dataObj.cell {
                Some(ref cell) => {
                    return Ok(TransactionExecResult::Accepted(cell.clone())) // read from cache
                },
                None => {
                   return Ok(TransactionExecResult::Error(ReadError::CellDoesNotExisted))
                }
            }
        }
        let server = self.get_data_site_by_id(&id);
        match server {
            Ok((server_id, server)) => {
                let self_server_id = self.server.server_id;
                let read_response = server.read(
                    &self_server_id,
                    &self.get_clock(),
                    tid, id
                ).wait();
                match read_response {
                    Ok(dsr) => {
                        let dsr = dsr.unwrap();
                        self.merge_clock(&dsr.clock);
                        match dsr.payload {
                            TransactionExecResult::Accepted(ref cell) => {
                                txn.data.insert(*id, DataObject {
                                    server: server_id,
                                    cell: Some(cell.clone()),
                                    new: false,
                                });
                            },
                            TransactionExecResult::Error(ReadError::CellDoesNotExisted) => {
                                txn.data.insert(*id, DataObject {
                                    server: server_id,
                                    cell: None,
                                    new: false,
                                });
                            }
                            TransactionExecResult::Wait => {} // TODO: deal with wait
                            _ => {}
                        }
                        Ok(dsr.payload)
                    },
                    Err(e) => {
                        error!("{:?}", e);
                        Err(TMError::NoResponseFromCellServer)
                    }
                }
            },
            Err(e) => {
                error!("{:?}", e);
                Err(TMError::CannotLocateCellServer)
            }
        }
    }
    fn write(&self, tid: &TransactionId, id: &Id, cell: &Cell) -> Result<TransactionExecResult<(), WriteError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        match self.server.get_server_id_by_id(id) {
            Some(server_id) => {
                let have_cached_cell = txn.data.contains_key(id);
                if !have_cached_cell {
                    txn.data.insert(*id, DataObject {
                        server: server_id,
                        cell: Some(cell.clone()),
                        new: true,
                    });
                    Ok(TransactionExecResult::Accepted(()))
                } else {
                    let mut data_obj = txn.data.get_mut(id).unwrap();
                    if !data_obj.cell.is_none() {
                        return Ok(TransactionExecResult::Error(WriteError::CellAlreadyExisted))
                    }
                    data_obj.cell = Some(cell.clone());
                    Ok(TransactionExecResult::Accepted(()))
                }
            },
            None => Err(TMError::CannotLocateCellServer)
        }
    }
    fn update(&self, tid: &TransactionId, cell: &Cell) -> Result<TransactionExecResult<(), WriteError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        let id = cell.id();
        match self.server.get_server_id_by_id(&id) {
            Some(server_id) => {
                let cell = cell.clone();
                if txn.data.contains_key(&id) {
                    txn.data.get_mut(&id).unwrap().cell = Some(cell)
                } else {
                    txn.data.insert(id, DataObject {
                        server: server_id,
                        cell: Some(cell),
                        new: false,
                    });
                }
                Ok(TransactionExecResult::Accepted(()))
            },
            None => Err(TMError::CannotLocateCellServer)
        }
    }
    fn remove(&self, tid: &TransactionId, id: &Id) -> Result<TransactionExecResult<(), WriteError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        match self.server.get_server_id_by_id(&id) {
            Some(server_id) => {
                if txn.data.contains_key(&id) {
                    let data_obj = txn.data.get_mut(&id).unwrap();
                    if data_obj.cell.is_none() {
                        return Ok(TransactionExecResult::Error(WriteError::CellDoesNotExisted))
                    }
                    data_obj.cell = None;
                } else {
                    txn.data.insert(*id, DataObject {
                        server: server_id,
                        cell: None,
                        new: false,
                    });
                }
                Ok(TransactionExecResult::Accepted(()))
            },
            None => Err(TMError::CannotLocateCellServer)
        }
    }
    fn prepare(&self, tid: &TransactionId) -> Result<PrepareResult, TMError> {
        let mut txn = self.get_transaction(tid)?;
        let mut changed_objs = self.changed_objs(&txn);
        let data_sites = self.data_sites(&changed_objs)?;
        Err(TMError::CannotLocateCellServer)
    }
    fn commit(&self, tid: &TransactionId) -> Result<(), ()> {
        Err(())
    }
    fn abort(&self, tid: &TransactionId) -> Result<(), ()> {
        Err(())
    }
    fn go_ahead(&self, tid: &BTreeSet<TransactionId>) -> Result<(), ()> {
        Err(())
    }
}

struct AwaitingServer {
    sender: Sender<()>,
    receiver: Receiver<()>,
}

impl AwaitingServer {
    pub fn new() -> AwaitingServer {
        let (sender, receiver) = channel();
        AwaitingServer {
            sender: sender,
            receiver: receiver
        }
    }
    pub fn send(&self) {
        self.sender.send(());
    }
    pub fn wait(&self) {
        self.receiver.recv();
    }
}

struct AwaitManager {
    channels: Mutex<HashMap<TransactionId, TxnAwaits>>
}

impl AwaitManager {
    pub fn new() -> AwaitManager {
        AwaitManager {
            channels: Mutex::new(HashMap::new())
        }
    }
    pub fn get_txn(&self, tid: &TransactionId) -> TxnAwaits {
        self.channels.lock()
            .entry(tid.clone())
            .or_insert_with(|| Arc::new(Mutex::new(HashMap::new())))
            .clone()
    }
    pub fn server_from_awaits(awaits: TxnAwaits, server_id: u64) -> Arc<AwaitingServer> {
        awaits.lock()
            .entry(server_id)
            .or_insert_with(|| Arc::new(AwaitingServer::new()))
            .clone()
    }
}<commit_msg>resolve sync and send traits<commit_after>use bifrost::vector_clock::{VectorClock, StandardVectorClock, ServerVectorClock};
use bifrost::utils::time::get_time;
use chashmap::{CHashMap, WriteGuard};
use std::collections::{BTreeMap, BTreeSet, HashMap};
use ram::types::{Id};
use ram::cell::{Cell, ReadError, WriteError};
use server::NebServer;
use parking_lot::Mutex;
use std::sync::mpsc::{channel, Sender, Receiver};
use futures;
use super::*;

type TxnAwaits = Arc<Mutex<HashMap<u64, Arc<AwaitingServer>>>>;
type TxnGuard<'a> = WriteGuard<'a, TransactionId, Transaction>;
type ChangedObjs = BTreeMap<u64, Vec<(Id, DataObject)>>;
type DataSiteClients = HashMap<u64, Arc<data_site::AsyncServiceClient>>;

pub static DEFAULT_SERVICE_ID: u64 = hash_ident!(TNX_MANAGER_RPC_SERVICE) as u64;

#[derive(Debug, Serialize, Deserialize)]
pub enum TMError {
    TransactionNotFound,
    CannotLocateCellServer,
    NoResponseFromCellServer,
    AssertionError
}

#[derive(Clone)]
struct DataObject {
    server: u64,
    cell: Option<Cell>,
    new: bool
}

struct Transaction {
    start_time: i64, // use for timeout detecting
    id: TransactionId,
    data: BTreeMap<Id, DataObject>,
    writes: BTreeSet<Id>,
}

service! {
    rpc begin() -> TransactionId;
    rpc read(tid: TransactionId, id: Id) -> TransactionExecResult<Cell, ReadError> | TMError;
    rpc write(tid: TransactionId, id: Id, cell: Cell) -> TransactionExecResult<(), WriteError> | TMError;
    rpc update(tid: TransactionId, cell: Cell) -> TransactionExecResult<(), WriteError> | TMError;
    rpc remove(tid: TransactionId, id: Id) -> TransactionExecResult<(), WriteError> | TMError;

    rpc prepare(tid: TransactionId) -> PrepareResult | TMError;
    rpc commit(tid: TransactionId);
    rpc abort(tid: TransactionId);

    rpc go_ahead(tid: BTreeSet<TransactionId>); // invoked by data site to continue on it's transaction in case of waiting
}

pub struct TransactionManager {
    server: Arc<NebServer>,
    transactions: CHashMap<TransactionId, Transaction>,
    data_sites: CHashMap<u64, Arc<data_site::AsyncServiceClient>>,
    await_manager: AwaitManager
}
dispatch_rpc_service_functions!(TransactionManager);

impl TransactionManager {
    pub fn new(server: &Arc<NebServer>) -> Arc<TransactionManager> {
        Arc::new(TransactionManager {
            server: server.clone(),
            transactions: CHashMap::new(),
            data_sites: CHashMap::new(),
            await_manager: AwaitManager::new()
        })
    }
}

impl TransactionManager {
    fn server_id(&self) -> u64 {
        self.server.server_id
    }
    fn get_data_site(&self, server_id: u64) -> io::Result<Arc<data_site::AsyncServiceClient>> {
        if !self.data_sites.contains_key(&server_id) {
            let client = self.server.get_member_by_server_id(server_id)?;
            self.data_sites.upsert(server_id, || {
                data_site::AsyncServiceClient::new(DEFAULT_SERVICE_ID, &client)
            }, |_| {});
        }
        Ok(self.data_sites .get(&server_id).unwrap().clone())
    }
    fn get_data_site_by_id(&self, id: &Id) -> io::Result<(u64, Arc<data_site::AsyncServiceClient>)> {
        match self.server.get_server_id_by_id(id) {
            Some(id) => match self.get_data_site(id) {
                Ok(site) => Ok((id, site.clone())),
                Err(e) => Err(e)
            },
            _ => Err(io::Error::new(io::ErrorKind::NotFound, "cannot find data site for this id"))
        }
    }
    fn get_clock(&self) -> StandardVectorClock {
        self.server.txn_peer.clock.to_clock()
    }
    fn merge_clock(&self, clock: &StandardVectorClock) {
        self.server.txn_peer.clock.merge_with(clock)
    }
    fn get_transaction(&self, tid: &TransactionId) -> Result<TxnGuard, TMError> {
        match self.transactions.get_mut(tid) {
            Some(tnx) => Ok(tnx),
            _ => {Err(TMError::TransactionNotFound)}
        }
    }
    fn changed_objs(&self, txn: &TxnGuard) -> ChangedObjs {
        let mut changed_objs: BTreeMap<u64, Vec<(Id, DataObject)>> = BTreeMap::new();
        for (id, data_obj) in &txn.data {
            changed_objs.entry(data_obj.server).or_insert_with(|| Vec::new()).push((*id, data_obj.clone()));
        }
        changed_objs
    }
    fn data_sites(&self, changed_objs: &ChangedObjs) -> Result<DataSiteClients, TMError>  {
        let data_sites: HashMap<u64, _> = changed_objs.iter().map(|(server_id, _)| {
            (*server_id, self.get_data_site(*server_id))
        }).collect();
        if data_sites.iter().any(|(_, data_site)| { data_site.is_err() }) {
            return Err(TMError::CannotLocateCellServer)
        }
        Ok(data_sites.into_iter().map(
            |(server_id, data_site)| {
                (server_id, data_site.unwrap())
            }
        ).collect())
    }
    fn site_prepare(
        server: Arc<NebServer>,
        tid: &TransactionId,
        objs: &Vec<(Id, DataObject)>,
        data_site: &Arc<data_site::AsyncServiceClient>
    ) -> Box<futures::Future<Item = PrepareResult, Error = TMError>> {
        let self_server_id = server.server_id;
        let cell_ids: Vec<_> = objs.iter().map(|&(id, _)| id).collect();
        let res_future = data_site
            .prepare(&self_server_id, &server.txn_peer.clock.to_clock(), tid, &cell_ids)
            .map_err(|_| -> TMError {
                TMError::NoResponseFromCellServer
            })
            .map(move |prepare_res| -> PrepareResult {
                let prepare_res = prepare_res.unwrap();
                server.txn_peer.clock.merge_with(&prepare_res.clock);
                prepare_res.payload
            })
            .then(|prepare_payload| {
                match prepare_payload {
                    Ok(payload) => {
                        match payload {
                            PrepareResult::Wait => {
                                return Ok(payload)
                            },
                            _ => {
                                return Ok(payload)
                            }
                        }
                    },
                    Err(e) => Err(e)
                }
            });
        Box::new(res_future)
    }
    fn sites_prepare(&self, tid: &TransactionId, txn: Transaction, changed_objs: &ChangedObjs, data_sites: DataSiteClients) {
        let prepare_futures: Vec<_> = changed_objs.iter().map(|(server, objs)| {
            let data_site = data_sites.get(&server).unwrap();
            TransactionManager::site_prepare(
                self.server.clone(), tid, objs, data_site
            )
        }).collect();
        let prepare_result = future::join_all(prepare_futures).wait();
    }
}

impl Service for TransactionManager {
    fn begin(&self) -> Result<TransactionId, ()> {
        let id = self.server.txn_peer.clock.inc();
        self.transactions.insert(id.clone(), Transaction {
            start_time: get_time(),
            id: id.clone(),
            data: BTreeMap::new(),
            writes: BTreeSet::new()
        });
        Ok(id)
    }
    fn read(&self, tid: &TransactionId, id: &Id) -> Result<TransactionExecResult<Cell, ReadError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        if let Some(dataObj) = txn.data.get(id) {
            match dataObj.cell {
                Some(ref cell) => {
                    return Ok(TransactionExecResult::Accepted(cell.clone())) // read from cache
                },
                None => {
                   return Ok(TransactionExecResult::Error(ReadError::CellDoesNotExisted))
                }
            }
        }
        let server = self.get_data_site_by_id(&id);
        match server {
            Ok((server_id, server)) => {
                let self_server_id = self.server.server_id;
                let read_response = server.read(
                    &self_server_id,
                    &self.get_clock(),
                    tid, id
                ).wait();
                match read_response {
                    Ok(dsr) => {
                        let dsr = dsr.unwrap();
                        self.merge_clock(&dsr.clock);
                        match dsr.payload {
                            TransactionExecResult::Accepted(ref cell) => {
                                txn.data.insert(*id, DataObject {
                                    server: server_id,
                                    cell: Some(cell.clone()),
                                    new: false,
                                });
                            },
                            TransactionExecResult::Error(ReadError::CellDoesNotExisted) => {
                                txn.data.insert(*id, DataObject {
                                    server: server_id,
                                    cell: None,
                                    new: false,
                                });
                            }
                            TransactionExecResult::Wait => {} // TODO: deal with wait
                            _ => {}
                        }
                        Ok(dsr.payload)
                    },
                    Err(e) => {
                        error!("{:?}", e);
                        Err(TMError::NoResponseFromCellServer)
                    }
                }
            },
            Err(e) => {
                error!("{:?}", e);
                Err(TMError::CannotLocateCellServer)
            }
        }
    }
    fn write(&self, tid: &TransactionId, id: &Id, cell: &Cell) -> Result<TransactionExecResult<(), WriteError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        match self.server.get_server_id_by_id(id) {
            Some(server_id) => {
                let have_cached_cell = txn.data.contains_key(id);
                if !have_cached_cell {
                    txn.data.insert(*id, DataObject {
                        server: server_id,
                        cell: Some(cell.clone()),
                        new: true,
                    });
                    Ok(TransactionExecResult::Accepted(()))
                } else {
                    let mut data_obj = txn.data.get_mut(id).unwrap();
                    if !data_obj.cell.is_none() {
                        return Ok(TransactionExecResult::Error(WriteError::CellAlreadyExisted))
                    }
                    data_obj.cell = Some(cell.clone());
                    Ok(TransactionExecResult::Accepted(()))
                }
            },
            None => Err(TMError::CannotLocateCellServer)
        }
    }
    fn update(&self, tid: &TransactionId, cell: &Cell) -> Result<TransactionExecResult<(), WriteError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        let id = cell.id();
        match self.server.get_server_id_by_id(&id) {
            Some(server_id) => {
                let cell = cell.clone();
                if txn.data.contains_key(&id) {
                    txn.data.get_mut(&id).unwrap().cell = Some(cell)
                } else {
                    txn.data.insert(id, DataObject {
                        server: server_id,
                        cell: Some(cell),
                        new: false,
                    });
                }
                Ok(TransactionExecResult::Accepted(()))
            },
            None => Err(TMError::CannotLocateCellServer)
        }
    }
    fn remove(&self, tid: &TransactionId, id: &Id) -> Result<TransactionExecResult<(), WriteError>, TMError> {
        let mut txn = self.get_transaction(tid)?;
        match self.server.get_server_id_by_id(&id) {
            Some(server_id) => {
                if txn.data.contains_key(&id) {
                    let data_obj = txn.data.get_mut(&id).unwrap();
                    if data_obj.cell.is_none() {
                        return Ok(TransactionExecResult::Error(WriteError::CellDoesNotExisted))
                    }
                    data_obj.cell = None;
                } else {
                    txn.data.insert(*id, DataObject {
                        server: server_id,
                        cell: None,
                        new: false,
                    });
                }
                Ok(TransactionExecResult::Accepted(()))
            },
            None => Err(TMError::CannotLocateCellServer)
        }
    }
    fn prepare(&self, tid: &TransactionId) -> Result<PrepareResult, TMError> {
        let mut txn = self.get_transaction(tid)?;
        let mut changed_objs = self.changed_objs(&txn);
        let data_sites = self.data_sites(&changed_objs)?;
        Err(TMError::CannotLocateCellServer)
    }
    fn commit(&self, tid: &TransactionId) -> Result<(), ()> {
        Err(())
    }
    fn abort(&self, tid: &TransactionId) -> Result<(), ()> {
        Err(())
    }
    fn go_ahead(&self, tid: &BTreeSet<TransactionId>) -> Result<(), ()> {
        Err(())
    }
}

struct AwaitingServer {
    sender: Mutex<Sender<()>>,
    receiver: Mutex<Receiver<()>>,
}

impl AwaitingServer {
    pub fn new() -> AwaitingServer {
        let (sender, receiver) = channel();
        AwaitingServer {
            sender: Mutex::new(sender),
            receiver: Mutex::new(receiver)
        }
    }
    pub fn send(&self) {
        self.sender.lock().send(());
    }
    pub fn wait(&self) {
        self.receiver.lock().recv();
    }
}

struct AwaitManager {
    channels: Mutex<HashMap<TransactionId, TxnAwaits>>
}

impl AwaitManager {
    pub fn new() -> AwaitManager {
        AwaitManager {
            channels: Mutex::new(HashMap::new())
        }
    }
    pub fn get_txn(&self, tid: &TransactionId) -> TxnAwaits {
        self.channels.lock()
            .entry(tid.clone())
            .or_insert_with(|| Arc::new(Mutex::new(HashMap::new())))
            .clone()
    }
    pub fn server_from_awaits(awaits: TxnAwaits, server_id: u64) -> Arc<AwaitingServer> {
        awaits.lock()
            .entry(server_id)
            .or_insert_with(|| Arc::new(AwaitingServer::new()))
            .clone()
    }
}<|endoftext|>


<commit_before>use tensor::Tensor;
use num::traits::Num;

impl<T: Copy + Num> Tensor<T> {
    pub fn concat(&self, rhs: &Tensor<T>, axis: usize) -> Tensor<T> {
        debug_assert!(axis < self.ndim());
        debug_assert!(self.ndim() == rhs.ndim());

        let mut shape = Vec::with_capacity(self.ndim());
        for i in 0..self.ndim() {
            if i != axis {
                if self.shape[i] != rhs.shape[i] {
                    panic!("When using concat, all axes must be the same except the joining one");
                }
                shape.push(self.shape[i]);
            } else {
                shape.push(self.shape[i] + rhs.shape[i]);
            }
        }

        let mut t = Tensor::zeros(&shape);
        for i in 0..self.size() {
            let ii = self.unravel_index(i);
            t[&ii] = self.data[i];
        }

        let offset = self.shape[axis];
        for i in 0..rhs.size() {
            let mut ii = rhs.unravel_index(i);
            ii[axis] += offset;
            t[&ii] = rhs.data[i];
        }
        t
    }

}
<commit_msg>Changed concat to static function, just like dot<commit_after>use tensor::Tensor;
use num::traits::Num;

impl<T: Copy + Num> Tensor<T> {
    pub fn concat(lhs: &Tensor<T>, rhs: &Tensor<T>, axis: usize) -> Tensor<T> {
        debug_assert!(axis < lhs.ndim());
        debug_assert!(lhs.ndim() == rhs.ndim());

        let mut shape = Vec::with_capacity(lhs.ndim());
        for i in 0..lhs.ndim() {
            if i != axis {
                if lhs.shape[i] != rhs.shape[i] {
                    panic!("When using concat, all axes must be the same except the joining one");
                }
                shape.push(lhs.shape[i]);
            } else {
                shape.push(lhs.shape[i] + rhs.shape[i]);
            }
        }

        let mut t = Tensor::zeros(&shape);
        for i in 0..lhs.size() {
            let ii = lhs.unravel_index(i);
            t[&ii] = lhs.data[i];
        }

        let offset = lhs.shape[axis];
        for i in 0..rhs.size() {
            let mut ii = rhs.unravel_index(i);
            ii[axis] += offset;
            t[&ii] = rhs.data[i];
        }
        t
    }

}
<|endoftext|>


<commit_before>use gl::types::*;
use id_allocator::IdAllocator;
use nalgebra::{normalize, cross};
use nalgebra::{Pnt3, Vec3};
use ncollide::bounding_volume::{AABB, AABB3};
use noise::source::Perlin;
use noise::model::Plane;
use state::EntityId;
use std::collections::hash_map::HashMap;
use std::num::Float;
use stopwatch::TimerSet;
use terrain::{AMPLITUDE, TerrainType};

pub const BLOCK_WIDTH: i32 = 4;
// Number of samples in a single dimension per block.
pub const SAMPLES_PER_BLOCK: uint = 16;
pub const SAMPLE_WIDTH: f32 = BLOCK_WIDTH as f32 / SAMPLES_PER_BLOCK as f32;

#[deriving(Show, PartialEq, Eq, Hash, Copy, Clone)]
pub struct BlockPosition(Pnt3<i32>);

impl BlockPosition {
  #[inline(always)]
  pub fn new(x: i32, y: i32, z: i32) -> BlockPosition {
    BlockPosition(Pnt3::new(x, y, z))
  }

  #[inline(always)]
  pub fn as_pnt<'a>(&'a self) -> &'a Pnt3<i32> {
    let BlockPosition(ref pnt) = *self;
    pnt
  }

  #[inline(always)]
  pub fn as_mut_pnt3<'a>(&'a mut self) -> &'a mut Pnt3<i32> {
    let BlockPosition(ref mut pnt) = *self;
    pnt
  }

  pub fn from_world_position(world_position: &Pnt3<f32>) -> BlockPosition {
    macro_rules! convert_coordinate(
      ($x: expr) => ({
        let x = $x.floor() as i32;
        let x =
          if x < 0 {
            x - (BLOCK_WIDTH - 1)
          } else {
            x
          };
        x / BLOCK_WIDTH
      })
    );
    BlockPosition(
      Pnt3::new(
        convert_coordinate!(world_position.x),
        convert_coordinate!(world_position.y),
        convert_coordinate!(world_position.z),
      )
    )
  }

  pub fn to_world_position(&self) -> Pnt3<f32> {
    Pnt3::new(
      (self.as_pnt().x * BLOCK_WIDTH) as f32,
      (self.as_pnt().y * BLOCK_WIDTH) as f32,
      (self.as_pnt().z * BLOCK_WIDTH) as f32,
    )
  }
}

impl Add<Vec3<i32>, BlockPosition> for BlockPosition {
  fn add(mut self, rhs: Vec3<i32>) -> Self {
    self.as_mut_pnt3().x += rhs.x;
    self.as_mut_pnt3().y += rhs.y;
    self.as_mut_pnt3().z += rhs.z;
    self
  }
}

pub struct TerrainBlock {
  // These Vecs must all be ordered the same way.

  // vertex coordinates flattened into separate GLfloats (x, y, z order)
  pub vertex_coordinates: Vec<GLfloat>,
  // per-vertex normal vectors flattened into separate GLfloats (x, y, z order)
  pub normals: Vec<GLfloat>,
  // per-triangle terrain types
  pub typs: Vec<GLuint>,

  // per-triangle entity IDs
  pub ids: Vec<EntityId>,
  // per-triangle bounding boxes
  pub bounds: HashMap<EntityId, AABB3<GLfloat>>,
}

impl TerrainBlock {
  pub fn empty() -> TerrainBlock {
    TerrainBlock {
      vertex_coordinates: Vec::new(),
      normals: Vec::new(),
      typs: Vec::new(),
      ids: Vec::new(),
      bounds: HashMap::new(),
    }
  }

  pub fn generate(
    timers: &TimerSet,
    id_allocator: &mut IdAllocator<EntityId>,
    heightmap: &Perlin,
    position: &BlockPosition,
  ) -> TerrainBlock {
    timers.time("update.generate_block", || {
      let mut block = TerrainBlock::empty();
      let heightmap = Plane::new(heightmap);

      let x = (position.as_pnt().x * BLOCK_WIDTH) as f32;
      let y = (position.as_pnt().y * BLOCK_WIDTH) as f32;
      let z = (position.as_pnt().z * BLOCK_WIDTH) as f32;

      for dx in range(0, SAMPLES_PER_BLOCK) {
        let x = x + dx as f32 * SAMPLE_WIDTH;
        for dz in range(0, SAMPLES_PER_BLOCK) {
          let z = z + dz as f32 * SAMPLE_WIDTH;
          let position = Pnt3::new(x, y, z);
          TerrainBlock::add_tile(
            timers,
            &heightmap,
            id_allocator,
            &mut block,
            &position,
          );
        }
      }

      block
    })
  }

  fn add_tile<'a>(
    timers: &TimerSet,
    hm: &Plane<'a, Perlin>,
    id_allocator: &mut IdAllocator<EntityId>,
    block: &mut TerrainBlock,
    position: &Pnt3<f32>,
  ) {
    fn at(hm: &Plane<Perlin>, x: f32, z: f32) -> Pnt3<f32> {
      let y = AMPLITUDE * (hm.get(x, z) + 1.0) / 2.0;
      Pnt3::new(x, y, z)
    }

    fn normal_at(hm: &Plane<Perlin>, x: f32, z: f32) -> Vec3<f32> {
      const DELTA: f32 = 0.2;
      let dx = at(hm, x + DELTA, z).to_vec() - at(hm, x - DELTA, z).to_vec();
      let dz = at(hm, x, z + DELTA).to_vec() - at(hm, x, z - DELTA).to_vec();
      normalize(&cross(&dx, &dz))
    }

    let half_width = SAMPLE_WIDTH / 2.0;
    let center = at(hm, position.x + half_width, position.z + half_width);

    if position.y < center.y && center.y <= position.y + BLOCK_WIDTH as f32 {
      timers.time("update.generate_block.add_tile", || {
        let center_normal = normal_at(hm, position.x + half_width, position.z + half_width);

        let x2 = position.x + SAMPLE_WIDTH;
        let z2 = position.z + SAMPLE_WIDTH;

        let vs: [Pnt3<f32>, ..4] =
          [ at(hm, position.x, position.z)
          , at(hm, position.x, z2)
          , at(hm, x2, z2)
          , at(hm, x2, position.z)
          ];

        let ns: [Vec3<f32>, ..4] =
          [ normal_at(hm, position.x, position.z)
          , normal_at(hm, position.x, x2)
          , normal_at(hm, x2, z2)
          , normal_at(hm, x2, position.z)
          ];

        let center_lower_than = vs.iter().filter(|v| center.y < v.y).count();

        let terrain_type =
          if center_lower_than >= 3 {
            TerrainType::Dirt
          } else {
            TerrainType::Grass
          };

        macro_rules! place_terrain(
          ($v1: expr,
           $v2: expr,
           $n1: expr,
           $n2: expr,
           $minx: expr,
           $minz: expr,
           $maxx: expr,
           $maxz: expr
          ) => ({
            let mut maxy = $v1.y;
            if $v2.y > $v1.y {
              maxy = $v2.y;
            }
            if center.y > maxy {
              maxy = center.y;
            }

            let id = id_allocator.allocate();
            block.vertex_coordinates.push_all(&[
              $v1.x, $v1.y, $v1.z,
              $v2.x, $v2.y, $v2.z,
              center.x, center.y, center.z,
            ]);
            block.normals.push_all(&[
              $n1.x, $n1.y, $n1.z,
              $n2.x, $n2.y, $n2.z,
              center_normal.x, center_normal.y, center_normal.z,
            ]);
            block.typs.push(terrain_type as GLuint);
            block.ids.push(id);
            block.bounds.insert(
              id,
              AABB::new(
                Pnt3::new($minx, $v1.y, $minz),
                Pnt3::new($maxx, maxy, $maxz),
              ),
            );
          });
        );

        let centr = center; // makes alignment nice
        place_terrain!(&vs[0], &vs[1], &ns[0], &ns[1], vs[0].x, vs[0].z, centr.x, vs[1].z);
        place_terrain!(&vs[1], &vs[2], &ns[1], &ns[2], vs[1].x, centr.z, vs[2].x, vs[2].z);
        place_terrain!(&vs[2], &vs[3], &ns[2], &ns[3], centr.x, centr.z, vs[2].x, vs[2].z);
        place_terrain!(&vs[3], &vs[0], &ns[3], &ns[0], vs[0].x, vs[0].z, vs[3].x, centr.z);
      })
    }
  }
}
<commit_msg>use methods!<commit_after>use gl::types::*;
use id_allocator::IdAllocator;
use nalgebra::{normalize, cross};
use nalgebra::{Pnt3, Vec3};
use ncollide::bounding_volume::{AABB, AABB3};
use noise::source::Perlin;
use noise::model::Plane;
use state::EntityId;
use std::collections::hash_map::HashMap;
use std::num::Float;
use stopwatch::TimerSet;
use terrain::{AMPLITUDE, TerrainType};

pub const BLOCK_WIDTH: i32 = 4;
// Number of samples in a single dimension per block.
pub const SAMPLES_PER_BLOCK: uint = 16;
pub const SAMPLE_WIDTH: f32 = BLOCK_WIDTH as f32 / SAMPLES_PER_BLOCK as f32;

#[deriving(Show, PartialEq, Eq, Hash, Copy, Clone)]
pub struct BlockPosition(Pnt3<i32>);

impl BlockPosition {
  #[inline(always)]
  pub fn new(x: i32, y: i32, z: i32) -> BlockPosition {
    BlockPosition(Pnt3::new(x, y, z))
  }

  #[inline(always)]
  pub fn as_pnt<'a>(&'a self) -> &'a Pnt3<i32> {
    let BlockPosition(ref pnt) = *self;
    pnt
  }

  #[inline(always)]
  pub fn as_mut_pnt3<'a>(&'a mut self) -> &'a mut Pnt3<i32> {
    let BlockPosition(ref mut pnt) = *self;
    pnt
  }

  pub fn from_world_position(world_position: &Pnt3<f32>) -> BlockPosition {
    macro_rules! convert_coordinate(
      ($x: expr) => ({
        let x = $x.floor() as i32;
        let x =
          if x < 0 {
            x - (BLOCK_WIDTH - 1)
          } else {
            x
          };
        x / BLOCK_WIDTH
      })
    );
    BlockPosition(
      Pnt3::new(
        convert_coordinate!(world_position.x),
        convert_coordinate!(world_position.y),
        convert_coordinate!(world_position.z),
      )
    )
  }

  pub fn to_world_position(&self) -> Pnt3<f32> {
    Pnt3::new(
      (self.as_pnt().x * BLOCK_WIDTH) as f32,
      (self.as_pnt().y * BLOCK_WIDTH) as f32,
      (self.as_pnt().z * BLOCK_WIDTH) as f32,
    )
  }
}

impl Add<Vec3<i32>, BlockPosition> for BlockPosition {
  fn add(mut self, rhs: Vec3<i32>) -> Self {
    self.as_mut_pnt3().x += rhs.x;
    self.as_mut_pnt3().y += rhs.y;
    self.as_mut_pnt3().z += rhs.z;
    self
  }
}

/// Ductyped heightmap methods.
trait HeightMapExt {
  /// The coordinate of the tile at a given x/z.
  fn point_at(&self, x: f32, z: f32) -> Pnt3<f32>;
  /// The lighting normal of the tile at a given x/z.
  fn normal_at(&self, x: f32, z: f32) -> Vec3<f32>;
}

impl<'a> HeightMapExt for Plane<'a, Perlin> {
  fn point_at(&self, x: f32, z: f32) -> Pnt3<f32> {
    let y = AMPLITUDE * (self.get(x, z) + 1.0) / 2.0;
    Pnt3::new(x, y, z)
  }

  fn normal_at(&self, x: f32, z: f32) -> Vec3<f32> {
    const DELTA: f32 = 0.2;
    let dx = self.point_at(x + DELTA, z).to_vec() - self.point_at(x - DELTA, z).to_vec();
    let dz = self.point_at(x, z + DELTA).to_vec() - self.point_at(x, z - DELTA).to_vec();
    normalize(&cross(&dx, &dz))
  }
}

pub struct TerrainBlock {
  // These Vecs must all be ordered the same way.

  // vertex coordinates flattened into separate GLfloats (x, y, z order)
  pub vertex_coordinates: Vec<GLfloat>,
  // per-vertex normal vectors flattened into separate GLfloats (x, y, z order)
  pub normals: Vec<GLfloat>,
  // per-triangle terrain types
  pub typs: Vec<GLuint>,

  // per-triangle entity IDs
  pub ids: Vec<EntityId>,
  // per-triangle bounding boxes
  pub bounds: HashMap<EntityId, AABB3<GLfloat>>,
}

impl TerrainBlock {
  pub fn empty() -> TerrainBlock {
    TerrainBlock {
      vertex_coordinates: Vec::new(),
      normals: Vec::new(),
      typs: Vec::new(),
      ids: Vec::new(),
      bounds: HashMap::new(),
    }
  }

  pub fn generate(
    timers: &TimerSet,
    id_allocator: &mut IdAllocator<EntityId>,
    heightmap: &Perlin,
    position: &BlockPosition,
  ) -> TerrainBlock {
    timers.time("update.generate_block", || {
      let mut block = TerrainBlock::empty();
      let heightmap = Plane::new(heightmap);

      let x = (position.as_pnt().x * BLOCK_WIDTH) as f32;
      let y = (position.as_pnt().y * BLOCK_WIDTH) as f32;
      let z = (position.as_pnt().z * BLOCK_WIDTH) as f32;

      for dx in range(0, SAMPLES_PER_BLOCK) {
        let x = x + dx as f32 * SAMPLE_WIDTH;
        for dz in range(0, SAMPLES_PER_BLOCK) {
          let z = z + dz as f32 * SAMPLE_WIDTH;
          let position = Pnt3::new(x, y, z);
          TerrainBlock::add_tile(
            timers,
            &heightmap,
            id_allocator,
            &mut block,
            &position,
          );
        }
      }

      block
    })
  }

  fn add_tile<'a>(
    timers: &TimerSet,
    hm: &Plane<'a, Perlin>,
    id_allocator: &mut IdAllocator<EntityId>,
    block: &mut TerrainBlock,
    position: &Pnt3<f32>,
  ) {
    let half_width = SAMPLE_WIDTH / 2.0;
    let center = hm.point_at(position.x + half_width, position.z + half_width);

    if position.y < center.y && center.y <= position.y + BLOCK_WIDTH as f32 {
      timers.time("update.generate_block.add_tile", || {
        let center_normal = hm.normal_at(position.x + half_width, position.z + half_width);

        let x2 = position.x + SAMPLE_WIDTH;
        let z2 = position.z + SAMPLE_WIDTH;

        let ps: [Pnt3<f32>, ..4] =
          [ hm.point_at(position.x, position.z)
          , hm.point_at(position.x, z2)
          , hm.point_at(x2, z2)
          , hm.point_at(x2, position.z)
          ];

        let ns: [Vec3<f32>, ..4] =
          [ hm.normal_at(position.x, position.z)
          , hm.normal_at(position.x, x2)
          , hm.normal_at(x2, z2)
          , hm.normal_at(x2, position.z)
          ];

        let center_lower_than = ps.iter().filter(|v| center.y < v.y).count();

        let terrain_type =
          if center_lower_than >= 3 {
            TerrainType::Dirt
          } else {
            TerrainType::Grass
          };

        macro_rules! place_terrain(
          ($v1: expr,
           $v2: expr,
           $n1: expr,
           $n2: expr,
           $minx: expr,
           $minz: expr,
           $maxx: expr,
           $maxz: expr
          ) => ({
            let mut maxy = $v1.y;
            if $v2.y > $v1.y {
              maxy = $v2.y;
            }
            if center.y > maxy {
              maxy = center.y;
            }

            let id = id_allocator.allocate();
            block.vertex_coordinates.push_all(&[
              $v1.x, $v1.y, $v1.z,
              $v2.x, $v2.y, $v2.z,
              center.x, center.y, center.z,
            ]);
            block.normals.push_all(&[
              $n1.x, $n1.y, $n1.z,
              $n2.x, $n2.y, $n2.z,
              center_normal.x, center_normal.y, center_normal.z,
            ]);
            block.typs.push(terrain_type as GLuint);
            block.ids.push(id);
            block.bounds.insert(
              id,
              AABB::new(
                Pnt3::new($minx, $v1.y, $minz),
                Pnt3::new($maxx, maxy, $maxz),
              ),
            );
          });
        );

        let centr = center; // makes alignment nice
        place_terrain!(&ps[0], &ps[1], &ns[0], &ns[1], ps[0].x, ps[0].z, centr.x, ps[1].z);
        place_terrain!(&ps[1], &ps[2], &ns[1], &ns[2], ps[1].x, centr.z, ps[2].x, ps[2].z);
        place_terrain!(&ps[2], &ps[3], &ns[2], &ns[3], centr.x, centr.z, ps[2].x, ps[2].z);
        place_terrain!(&ps[3], &ps[0], &ns[3], &ns[0], ps[0].x, ps[0].z, ps[3].x, centr.z);
      })
    }
  }
}
<|endoftext|>


<commit_before>//! Entry point for the dummy project.
//! This comment block tests `rust doc`;
//! you should be able to see it from the documentation
//! folder after running the project's rustDoc task
//! in Gradle.

/// Prints a message to test documentation of
/// functions.
///
/// # Parameters
/// * `message`: The message to print.
/// # Examples
///
/// This prints "Hi!":
/// ```
/// sayHello("Hi!");
/// ```
pub fn sayHello(message: &str) {
	println!("{}", message);
}

/// Entry point for the program.
fn main() {
	sayHello("Rust works!");
}<commit_msg>Fix up documentation on dummy-project's main.rs.<commit_after>//! Entry point for the dummy project.
//! This comment block tests `rust doc`;
//! you should be able to see it from the documentation
//! folder after running the project's rustDoc task
//! in Gradle.

/// Prints a message to test documentation of
/// functions.
///
/// # Parameters
/// * `message`: The message to print.
///
/// # Examples
/// This prints "Hi!":
///
/// ```
/// sayHello("Hi!");
/// ```
pub fn sayHello(message: &str) {
	println!("{}", message);
}

/// Entry point for the program.
fn main() {
	sayHello("Rust works!");
}<|endoftext|>


<commit_before>// During tests, we disable the renderer and that causes a bunch of warnings that we just want
// to get rid of.
// See Cargo.toml for an explanation of this attribute
#![cfg_attr(any(feature = "test", test), allow(dead_code, unused_variables, unused_imports))]

use std::thread;
use std::process;
use std::time::Instant;
use std::sync::mpsc::{self, TryRecvError};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

use piston_window::math;

use renderer::{Renderer, DrawingCommand};
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path, Pen};
use radians::{self, Radians};
use {Speed, Distance, Event, color};

use self::DrawingCommand::*;

/// Types that will be shared with another thread
pub type Shared<T> = Arc<RwLock<T>>;
/// Alias to help make the types more understandable without exposing as many implementation details
pub type ReadOnlyRef<'a, T> = RwLockReadGuard<'a, T>;
pub type MutableRef<'a, T> = RwLockWriteGuard<'a, T>;

/// A structure that provides read-only access to shared state
pub struct ReadOnly {
    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl ReadOnly {
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    pub fn temporary_path(&self) -> ReadOnlyRef<Option<Path>> {
        self.temporary_path.read().expect("bug: Lock was poisoned")
    }
}

pub struct TurtleWindow {
    thread_handle: Option<thread::JoinHandle<()>>,
    /// Channel for sending drawing commands to the renderer thread
    drawing_channel: mpsc::Sender<DrawingCommand>,
    /// Channel for receiving events from the rendering thread
    events_channel: mpsc::Receiver<Event>,

    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        let (drawing_tx, drawing_rx) = mpsc::channel();
        let (events_tx, events_rx) = mpsc::channel();

        let mut turtle_window = Self {
            thread_handle: None,
            drawing_channel: drawing_tx,
            events_channel: events_rx,
            turtle: Arc::new(RwLock::new(TurtleState {
                position: [0., 0.],
                heading: Radians::from_degrees_value(90.),
                speed: Speed::Five,
                visible: true,
            })),
            drawing: Arc::new(RwLock::new(DrawingState {
                pen: Pen {
                    enabled: true,
                    thickness: 1.,
                    color: color::BLACK,
                },
                fill_color: color::BLACK,
                background: color::WHITE,
            })),
            temporary_path: Arc::new(RwLock::new(None)),
        };

        let read_only = turtle_window.read_only();
        let handle = thread::spawn(move || {
            // See Cargo.toml for an explanation of this attribute
            #[cfg(not(any(feature = "test", test)))]
            Renderer::new().run(drawing_rx, events_tx, read_only);
        });

        turtle_window.thread_handle = Some(handle);
        turtle_window
    }

    /// Provide a read-only version of the state
    pub fn read_only(&self) -> ReadOnly {
        ReadOnly {
            turtle: self.turtle.clone(),
            drawing: self.drawing.clone(),
            temporary_path: self.temporary_path.clone(),
        }
    }

    /// Provides read-only access to the turtle state
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the turtle state
    pub fn turtle_mut(&mut self) -> MutableRef<TurtleState> {
        self.turtle.write().expect("bug: Lock was poisoned")
    }

    /// Provides read-only access to the drawing
    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the drawing
    pub fn drawing_mut(&mut self) -> MutableRef<DrawingState> {
        self.drawing.write().expect("bug: Lock was poisoned")
    }

    /// Provides read-only access to the temporary path
    fn temporary_path(&self) -> ReadOnlyRef<Option<Path>> {
        self.temporary_path.read().expect("bug: Lock was poisoned")
    }

    fn set_temporary_path(&mut self, path: Option<Path>) {
        let mut temp = self.temporary_path.write().expect("bug: Lock was poisoned");
        *temp = path;
    }

    /// See [`Turtle::poll_event()`](struct.Turtle.html#method.poll_event).
    pub fn poll_event(&mut self) -> Option<Event> {
        match self.events_channel.try_recv() {
            Ok(event) => Some(event),
            Err(TryRecvError::Empty) => None, // Do nothing
            // The window has been closed
            Err(TryRecvError::Disconnected) => process::exit(0), // Quit
        }
    }

    /// Begin filling the shape drawn by the turtle's movements.
    pub fn begin_fill(&mut self) {
        let fill_color = self.drawing().fill_color;
        self.send_drawing_command(BeginFill(fill_color));
    }

    /// Stop filling the current shape
    pub fn end_fill(&mut self) {
        self.send_drawing_command(EndFill);
    }

    /// Clear the turtle's drawings
    pub fn clear(&mut self) {
        assert!(self.temporary_path().is_none(),
            "bug: The temporary path was still set when the renderer was asked to clear the drawing");
        self.send_drawing_command(Clear);
    }

    /// Move the turtle forward by the given distance. To move backwards, use a negative distance.
    ///
    /// The turtle's motion will be animated based on the speed
    pub fn forward(&mut self, distance: Distance) {
        if distance == 0. {
            return;
        }

        let TurtleState {position: start, heading, speed, ..} = *self.turtle();
        let x = distance * heading.cos();
        let y = distance * heading.sin();
        let end = math::add(start, [x, y]);

        let speed = speed.to_absolute(); // px per second
        let total_millis = (distance / speed * 1000.).abs();

        let animation = MoveAnimation {
            path: Path {
                start,
                end,
                pen: self.drawing().pen.clone(),
            },
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Rotate the turtle in place by the given angle in the given direction of rotation
    pub fn rotate(&mut self, angle: Radians, clockwise: bool) {
        if angle == radians::ZERO {
            return;
        }

        let TurtleState {heading, speed, ..} = *self.turtle();
        let speed = speed.to_rotation(); // radians per second
        let total_millis = angle / speed * 1000.;
        let total_millis = total_millis.to_radians();

        let animation = RotateAnimation {
            start: heading,
            delta_angle: angle,
            clockwise,
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    fn play_animation<A: Animation>(&mut self, animation: A) {
        // We only limit the framerate at all to be respectful of the user's CPU. If the framerate
        // is too small, every small movement (say forward(1) or right(1)) will take too long.
        // We use a huge framerate so we can sleep occasionally for longer animations but still
        // finish smaller ones in a reasonable amount of time.
        loop {
            // We want to keep the lock for as little time as possible
            let status = {
                let mut turtle = self.turtle_mut();
                animation.advance(&mut *turtle)
            };
            match status {
                AnimationStatus::Running(path) => self.set_temporary_path(path),
                AnimationStatus::Complete(path) => {
                    if let Some(path) = path {
                        self.set_temporary_path(None);
                        self.send_drawing_command(StorePath(path));
                    }

                    break;
                },
            }
        }
    }

    #[inline]
    fn send_drawing_command(&mut self, command: DrawingCommand) {
        self.drawing_channel.send(command).unwrap_or_else(|_| {
            // The channel is closed which means the window was closed
            // quit immediately
            process::exit(0);
        });
    }
}

impl Drop for TurtleWindow {
    fn drop(&mut self) {
        if let Some(handle) = self.thread_handle.take() {
            handle.join().unwrap();
        }
    }
}
<commit_msg>Forgot to remove huge documentation comment when FPS clock was taken out<commit_after>// During tests, we disable the renderer and that causes a bunch of warnings that we just want
// to get rid of.
// See Cargo.toml for an explanation of this attribute
#![cfg_attr(any(feature = "test", test), allow(dead_code, unused_variables, unused_imports))]

use std::thread;
use std::process;
use std::time::Instant;
use std::sync::mpsc::{self, TryRecvError};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

use piston_window::math;

use renderer::{Renderer, DrawingCommand};
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path, Pen};
use radians::{self, Radians};
use {Speed, Distance, Event, color};

use self::DrawingCommand::*;

/// Types that will be shared with another thread
pub type Shared<T> = Arc<RwLock<T>>;
/// Alias to help make the types more understandable without exposing as many implementation details
pub type ReadOnlyRef<'a, T> = RwLockReadGuard<'a, T>;
pub type MutableRef<'a, T> = RwLockWriteGuard<'a, T>;

/// A structure that provides read-only access to shared state
pub struct ReadOnly {
    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl ReadOnly {
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    pub fn temporary_path(&self) -> ReadOnlyRef<Option<Path>> {
        self.temporary_path.read().expect("bug: Lock was poisoned")
    }
}

pub struct TurtleWindow {
    thread_handle: Option<thread::JoinHandle<()>>,
    /// Channel for sending drawing commands to the renderer thread
    drawing_channel: mpsc::Sender<DrawingCommand>,
    /// Channel for receiving events from the rendering thread
    events_channel: mpsc::Receiver<Event>,

    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        let (drawing_tx, drawing_rx) = mpsc::channel();
        let (events_tx, events_rx) = mpsc::channel();

        let mut turtle_window = Self {
            thread_handle: None,
            drawing_channel: drawing_tx,
            events_channel: events_rx,
            turtle: Arc::new(RwLock::new(TurtleState {
                position: [0., 0.],
                heading: Radians::from_degrees_value(90.),
                speed: Speed::Five,
                visible: true,
            })),
            drawing: Arc::new(RwLock::new(DrawingState {
                pen: Pen {
                    enabled: true,
                    thickness: 1.,
                    color: color::BLACK,
                },
                fill_color: color::BLACK,
                background: color::WHITE,
            })),
            temporary_path: Arc::new(RwLock::new(None)),
        };

        let read_only = turtle_window.read_only();
        let handle = thread::spawn(move || {
            // See Cargo.toml for an explanation of this attribute
            #[cfg(not(any(feature = "test", test)))]
            Renderer::new().run(drawing_rx, events_tx, read_only);
        });

        turtle_window.thread_handle = Some(handle);
        turtle_window
    }

    /// Provide a read-only version of the state
    pub fn read_only(&self) -> ReadOnly {
        ReadOnly {
            turtle: self.turtle.clone(),
            drawing: self.drawing.clone(),
            temporary_path: self.temporary_path.clone(),
        }
    }

    /// Provides read-only access to the turtle state
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the turtle state
    pub fn turtle_mut(&mut self) -> MutableRef<TurtleState> {
        self.turtle.write().expect("bug: Lock was poisoned")
    }

    /// Provides read-only access to the drawing
    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the drawing
    pub fn drawing_mut(&mut self) -> MutableRef<DrawingState> {
        self.drawing.write().expect("bug: Lock was poisoned")
    }

    /// Provides read-only access to the temporary path
    fn temporary_path(&self) -> ReadOnlyRef<Option<Path>> {
        self.temporary_path.read().expect("bug: Lock was poisoned")
    }

    fn set_temporary_path(&mut self, path: Option<Path>) {
        let mut temp = self.temporary_path.write().expect("bug: Lock was poisoned");
        *temp = path;
    }

    /// See [`Turtle::poll_event()`](struct.Turtle.html#method.poll_event).
    pub fn poll_event(&mut self) -> Option<Event> {
        match self.events_channel.try_recv() {
            Ok(event) => Some(event),
            Err(TryRecvError::Empty) => None, // Do nothing
            // The window has been closed
            Err(TryRecvError::Disconnected) => process::exit(0), // Quit
        }
    }

    /// Begin filling the shape drawn by the turtle's movements.
    pub fn begin_fill(&mut self) {
        let fill_color = self.drawing().fill_color;
        self.send_drawing_command(BeginFill(fill_color));
    }

    /// Stop filling the current shape
    pub fn end_fill(&mut self) {
        self.send_drawing_command(EndFill);
    }

    /// Clear the turtle's drawings
    pub fn clear(&mut self) {
        assert!(self.temporary_path().is_none(),
            "bug: The temporary path was still set when the renderer was asked to clear the drawing");
        self.send_drawing_command(Clear);
    }

    /// Move the turtle forward by the given distance. To move backwards, use a negative distance.
    ///
    /// The turtle's motion will be animated based on the speed
    pub fn forward(&mut self, distance: Distance) {
        if distance == 0. {
            return;
        }

        let TurtleState {position: start, heading, speed, ..} = *self.turtle();
        let x = distance * heading.cos();
        let y = distance * heading.sin();
        let end = math::add(start, [x, y]);

        let speed = speed.to_absolute(); // px per second
        let total_millis = (distance / speed * 1000.).abs();

        let animation = MoveAnimation {
            path: Path {
                start,
                end,
                pen: self.drawing().pen.clone(),
            },
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Rotate the turtle in place by the given angle in the given direction of rotation
    pub fn rotate(&mut self, angle: Radians, clockwise: bool) {
        if angle == radians::ZERO {
            return;
        }

        let TurtleState {heading, speed, ..} = *self.turtle();
        let speed = speed.to_rotation(); // radians per second
        let total_millis = angle / speed * 1000.;
        let total_millis = total_millis.to_radians();

        let animation = RotateAnimation {
            start: heading,
            delta_angle: angle,
            clockwise,
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    fn play_animation<A: Animation>(&mut self, animation: A) {
        loop {
            // We want to keep the lock for as little time as possible
            let status = {
                let mut turtle = self.turtle_mut();
                animation.advance(&mut *turtle)
            };
            match status {
                AnimationStatus::Running(path) => self.set_temporary_path(path),
                AnimationStatus::Complete(path) => {
                    if let Some(path) = path {
                        self.set_temporary_path(None);
                        self.send_drawing_command(StorePath(path));
                    }

                    break;
                },
            }
        }
    }

    #[inline]
    fn send_drawing_command(&mut self, command: DrawingCommand) {
        self.drawing_channel.send(command).unwrap_or_else(|_| {
            // The channel is closed which means the window was closed
            // quit immediately
            process::exit(0);
        });
    }
}

impl Drop for TurtleWindow {
    fn drop(&mut self) {
        if let Some(handle) = self.thread_handle.take() {
            handle.join().unwrap();
        }
    }
}
<|endoftext|>


<commit_before>/// Enables the ability to merge two items
pub trait Merge: Ord + Copy {
    /// Returns the result of merging self with other, if possible, and None otherwise.
    fn merge(self, other: Self) -> Option<Self>;
}

/// Enables the ability to coalesce items in a collection
/// Coalescence occurs when two items in the collection are merged
/// in lieu of inserting a new item
pub trait Coalesce<T: Ord + Copy + Merge> {
    /// Inserts or merges, if possible, the item into the collection at the given index.
    fn coalesce(&mut self, index: usize, el: T);
    /// Searches for the index to insert the element in order, then coalesces at the found index;
    fn search_coalesce(&mut self, start: usize, el: T) -> usize;
}

impl<T: Ord + Copy + Merge> Coalesce<T> for Vec<T> {
    fn coalesce(&mut self, index: usize, el: T)  {
        let merge = T::merge;
        if self.is_empty() {
            self.insert(index, el);
        } else if index == 0 {
            if let Some(coalesced) = merge(el, self[0]) {
                self[index] = coalesced;
            } else {
                self.insert(index, el);
            }
        } else if index == self.len() {
            if let Some(coalesced) = merge(self[index - 1], el) {
                self[index - 1] = coalesced;
            } else {
                self.insert(index, el);
            }
        } else {
            if let Some(coalesced) = merge(self[index - 1], el) {
                self[index - 1] = coalesced;
                if let Some(coalesced) = merge(self[index - 1], self[index]) {
                    self[index - 1] = coalesced;
                    self.remove(index);
                }
            } else if let Some(coalesced) = merge(el, self[index]) {
                self[index ] = coalesced;
            } else {
                self.insert(index, el);
            }
        }
    }

    fn search_coalesce(&mut self, start: usize, el: T) -> usize {
        match self[start..].binary_search(&el) {
            Ok(idx) => idx,
            Err(idx) => {
                self.coalesce(idx, el);
                idx
            }
        }
    }
}

macro_rules! impl_merge_tuples {
    ($tp:ident) => (
        impl Merge for ($tp, $tp) {
            fn merge(self, (x2, y2): ($tp, $tp))  -> Option<($tp, $tp)> {
                let (x1, y1) = self;
                if y1 >= x2 {
                    if y1 < y2 { Some((x1, y2)) } else { Some((x1, y1)) }
                } else {
                    None
                }
            }
        }
    )
}

impl_merge_tuples!(isize);
impl_merge_tuples!(usize);
impl_merge_tuples!(u32);
impl_merge_tuples!(u16);
impl_merge_tuples!(u8);
impl_merge_tuples!(i32);
impl_merge_tuples!(i16);
impl_merge_tuples!(i8);

#[test]
fn test_coalesce_empty() {
    let mut v = vec![];
    v.coalesce(0, (0, 1));
    assert_eq!(v, [(0, 1)]);
}

#[test]
fn test_coalesce_first() {
    let mut v = vec![(1, 1)];
    v.coalesce(0, (0, 1));
    assert_eq!(v, [(0, 1)])
}

#[test]
fn test_coalesce_last() {
    let mut v = vec![(1, 1)];
    v.coalesce(1, (1, 2));
    assert_eq!(v, [(1, 2)])
}

#[test]
fn test_coalesce_both() {
    let mut v = vec![(1, 1), (2, 2)];
    v.coalesce(1, (1, 2));
    assert_eq!(v, [(1, 2)])
}

#[test]
fn test_coalesce_none() {
    let mut v = vec![(1, 1), (3, 3)];
    v.coalesce(1, (2, 2));
    assert_eq!(v, [(1, 1), (2, 2), (3, 3)])
}

#[test]
fn test_coalesce_twice() {
    let mut v = vec![];
    v.coalesce(0, (0, 1));
    v.coalesce(0, (-2, -1));
    v.coalesce(1, (-1, 0));
    assert_eq!(v, [(-2, 1)]);
}

#[test]
fn test_search_and_coalesce() {
    let mut v = vec![];
    for el in vec![(0, 1), (-2, -1), (-1, 0)] {
        let index = v.binary_search(&el).err().unwrap();
        v.coalesce(index, el);
    }
    assert_eq!(v, [(-2, 1)]);
}

#[test]
fn test_coalesce_subrange() {
    let mut v = vec![(0, 3)];
    v.coalesce(1, (1, 2));
    assert_eq!(v, [(0, 3)]);
}
<commit_msg>Fix search_coalesce -- the returned index was relative to the slice rather than the whole vec<commit_after>/// Enables the ability to merge two items
pub trait Merge: Ord + Copy {
    /// Returns the result of merging self with other, if possible, and None otherwise.
    fn merge(self, other: Self) -> Option<Self>;
}

/// Enables the ability to coalesce items in a collection
/// Coalescence occurs when two items in the collection are merged
/// in lieu of inserting a new item
pub trait Coalesce<T: Ord + Copy + Merge> {
    /// Inserts or merges, if possible, the item into the collection at the given index.
    fn coalesce(&mut self, index: usize, el: T);
    /// Searches for the index to insert the element in order, then coalesces at the found index;
    fn search_coalesce(&mut self, start: usize, el: T) -> usize;
}

impl<T: Ord + Copy + Merge> Coalesce<T> for Vec<T> {
    fn coalesce(&mut self, index: usize, el: T)  {
        let merge = T::merge;
        if self.is_empty() {
            self.insert(index, el);
        } else if index == 0 {
            if let Some(coalesced) = merge(el, self[0]) {
                self[index] = coalesced;
            } else {
                self.insert(index, el);
            }
        } else if index == self.len() {
            if let Some(coalesced) = merge(self[index - 1], el) {
                self[index - 1] = coalesced;
            } else {
                self.insert(index, el);
            }
        } else {
            if let Some(coalesced) = merge(self[index - 1], el) {
                self[index - 1] = coalesced;
                if let Some(coalesced) = merge(self[index - 1], self[index]) {
                    self[index - 1] = coalesced;
                    self.remove(index);
                }
            } else if let Some(coalesced) = merge(el, self[index]) {
                self[index ] = coalesced;
            } else {
                self.insert(index, el);
            }
        }
    }

    fn search_coalesce(&mut self, start: usize, el: T) -> usize {
        match self[start..].binary_search(&el) {
            Ok(idx) => start + idx,
            Err(idx) => {
                let idx = start + idx;
                self.coalesce(idx, el);
                idx
            }
        }
    }
}

macro_rules! impl_merge_tuples {
    ($tp:ident) => (
        impl Merge for ($tp, $tp) {
            fn merge(self, (x2, y2): ($tp, $tp))  -> Option<($tp, $tp)> {
                let (x1, y1) = self;
                if y1 >= x2 {
                    if y1 < y2 { Some((x1, y2)) } else { Some((x1, y1)) }
                } else {
                    None
                }
            }
        }
    )
}

impl_merge_tuples!(isize);
impl_merge_tuples!(usize);
impl_merge_tuples!(u32);
impl_merge_tuples!(u16);
impl_merge_tuples!(u8);
impl_merge_tuples!(i32);
impl_merge_tuples!(i16);
impl_merge_tuples!(i8);

#[test]
fn test_coalesce_empty() {
    let mut v = vec![];
    v.coalesce(0, (0, 1));
    assert_eq!(v, [(0, 1)]);
}

#[test]
fn test_coalesce_first() {
    let mut v = vec![(1, 1)];
    v.coalesce(0, (0, 1));
    assert_eq!(v, [(0, 1)])
}

#[test]
fn test_coalesce_last() {
    let mut v = vec![(1, 1)];
    v.coalesce(1, (1, 2));
    assert_eq!(v, [(1, 2)])
}

#[test]
fn test_coalesce_both() {
    let mut v = vec![(1, 1), (2, 2)];
    v.coalesce(1, (1, 2));
    assert_eq!(v, [(1, 2)])
}

#[test]
fn test_coalesce_none() {
    let mut v = vec![(1, 1), (3, 3)];
    v.coalesce(1, (2, 2));
    assert_eq!(v, [(1, 1), (2, 2), (3, 3)])
}

#[test]
fn test_coalesce_twice() {
    let mut v = vec![];
    v.coalesce(0, (0, 1));
    v.coalesce(0, (-2, -1));
    v.coalesce(1, (-1, 0));
    assert_eq!(v, [(-2, 1)]);
}

#[test]
fn test_search_and_coalesce() {
    let mut v = vec![];
    for el in vec![(0, 1), (-2, -1), (-1, 0)] {
        let index = v.binary_search(&el).err().unwrap();
        v.coalesce(index, el);
    }
    assert_eq!(v, [(-2, 1)]);
}

#[test]
fn test_coalesce_subrange() {
    let mut v = vec![(0, 3)];
    v.coalesce(1, (1, 2));
    assert_eq!(v, [(0, 3)]);
}

#[test]
fn test_search_coalesce() {
    let mut v = vec![(0, 1), (2, 3), (4, 5), (6, 7)];
    assert_eq!(2, v.search_coalesce(1, (4, 5)));
}

#[test]
fn test_search_coalesce_2() {
    let mut v = vec![(0, 1), (2, 3), (4, 5), (6, 7)];
    assert_eq!(3, v.search_coalesce(1, (5, 6)));
    assert_eq!(v, [(0, 1), (2, 3), (4, 7)]);
}
<|endoftext|>


<commit_before>use nom::{Err, IResult, Needed};

use std::io;
use std::io::Read;
use std::ptr;
use std::cmp;

use super::StreamProducer;

#[derive(Debug)]
pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  EndOfInput,
  Unknown,
}

// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  // Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  // Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  // Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        if let Err::Position(_, i) = e {
          let consumed = self.len() - i.len();

          self.offset += consumed;

          Err(ErrorKind::Consumed(consumed))
        } else {
          Err(ErrorKind::Unknown)
        }
      }
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      if let Err::Position(_, i) = e {
        Err(ErrorKind::Consumed(buffer.len() - i.len()))
      } else {
        Err(ErrorKind::Unknown)
      }
    }
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        match kind {
          ErrorKind::Incomplete(needed) => self.needed = needed,
          ErrorKind::Consumed(consumed) => buffer.consume(consumed),
          _                             => (),
        }

        Err(kind)
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::be_u32;

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<commit_msg>Add documentation for `ReadStream::new`<commit_after>use nom::{Err, IResult, Needed};

use std::io;
use std::io::Read;
use std::ptr;
use std::cmp;

use super::StreamProducer;

#[derive(Debug)]
pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  EndOfInput,
  Unknown,
}

// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  // Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  // Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  // Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        if let Err::Position(_, i) = e {
          let consumed = self.len() - i.len();

          self.offset += consumed;

          Err(ErrorKind::Consumed(consumed))
        } else {
          Err(ErrorKind::Unknown)
        }
      }
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  // Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      if let Err::Position(_, i) = e {
        Err(ErrorKind::Consumed(buffer.len() - i.len()))
      } else {
        Err(ErrorKind::Unknown)
      }
    }
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        match kind {
          ErrorKind::Incomplete(needed) => self.needed = needed,
          ErrorKind::Consumed(consumed) => buffer.consume(consumed),
          _                             => (),
        }

        Err(kind)
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::be_u32;

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<|endoftext|>