<commit_before>use std::thread;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::collections::VecDeque;

// MIO
use mio::tcp::{listen, TcpListener, TcpStream};
use mio::util::Slab;
use mio::Socket;
use mio::buf::{RingBuf};
use mio::{Interest, PollOpt, NonBlock, Token, EventLoop, Handler, ReadHint};
use mio::buf::Buf;
use mio::{TryRead, TryWrite};

use rand::{self, Rng};

// Data structures.
use store::Store;
use replica::{Replica, Emit, Broadcast};
use state_machine::StateMachine;

// Cap'n Proto
use capnp::serialize_packed;
use capnp::{
    MessageBuilder,
    MessageReader,
    ReaderOptions,
    MallocMessageBuilder,
    OwnedSpaceMessageReader,
};
use messages_capnp::{
    rpc_request,
    rpc_response,
    client_request,
    client_response,
    request_vote_response,
    append_entries_response,
    append_entries_request,
};
use super::{Error, Result};

// MIO Tokens
const ELECTION_TIMEOUT: Token = Token(0);
const HEARTBEAT_TIMEOUT: Token = Token(1);
const LISTENER:  Token = Token(2);

const ELECTION_MIN: u64 = 150;
const ELECTION_MAX: u64 = 300;
const HEARTBEAT_DURATION: u64 = 50;
const RINGBUF_SIZE: usize = 4096;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
/// A `Server` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
///
/// Currently, the `Server` API is not well defined. **We are looking for feedback and suggestions.**
pub struct Server<S, M> where S: Store, M: StateMachine {
    replica: Replica<S, M>,
    // Channels and Sockets
    listener: NonBlock<TcpListener>,
    connections: Slab<Connection>,
}

/// The implementation of the Server. In most use cases, creating a `Server` should just be
/// done via `::new()`.
impl<S, M> Server<S, M> where S: Store, M: StateMachine {

    /// Creates a new Raft node with the cluster members specified.
    ///
    /// # Arguments
    ///
    /// * `addr` - The address of the new node.
    /// * `peers` - The address of all peers in the Raft cluster.
    /// * `store` - The persitent log store.
    /// * `state_machine` - The client state machine to which client commands will be applied.
    pub fn spawn(addr: SocketAddr,
                 peers: HashSet<SocketAddr>,
                 store: S,
                 state_machine: M) {
        // Create an event loop
        let mut event_loop = EventLoop::<Server<S, M>>::new().unwrap();
        // Setup the socket, make it not block.
        let listener = listen(&addr).unwrap();
        listener.set_reuseaddr(true).unwrap();
        event_loop.register(&listener, LISTENER).unwrap();
        let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
        event_loop.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
        event_loop.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
        let replica = Replica::new(addr, peers, store, state_machine);
        // Fire up the thread.
        thread::Builder::new().name(format!("Server {}", addr)).spawn(move || {
            let mut raft_node = Server {
                listener: listener,
                replica: replica,
                connections: Slab::new_starting_at(Token(2), 128),
            };
            event_loop.run(&mut raft_node).unwrap();
        }).unwrap();
    }
}

impl<S, M> Handler for Server<S, M> where S: Store, M: StateMachine {

    type Message = RingBuf;
    type Timeout = Token;

    /// A registered IoHandle has available writing space.
    fn writable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => unreachable!(),
            tok => {
                self.connections[tok].writable(reactor, &mut self.replica).unwrap();
            }
        }
    }

    /// A registered IoHandle has available data to read
    fn readable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token, _hint: ReadHint) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => {
                let stream = match self.listener.accept().unwrap() {
                    Some(s) => s,
                    None => return, // Socket isn't quite ready.
                }; // Result<Option<_>,_>
                let conn = Connection::new(stream);
                let tok = self.connections.insert(conn)
                    .ok().expect("Could not add connection to slab.");

                // Register the connection
                self.connections[tok].token = tok;
                reactor.register_opt(&self.connections[tok].stream, tok, Interest::readable(), PollOpt::edge() | PollOpt::oneshot())
                    .ok().expect("Could not register socket with event loop.");
            },
            tok => {
                self.connections[tok].readable(reactor, &mut self.replica).unwrap();
            }
        }
    }

    /// A registered timer has expired
    fn timeout(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        let mut message = MallocMessageBuilder::new_default();
        let mut send_message = None;
        match token {
            ELECTION_TIMEOUT => {
                let request = message.init_root::<rpc_request::Builder>();
                send_message = self.replica.election_timeout(request.init_request_vote());
                // Set timeout.
                let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
                reactor.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();

            },
            HEARTBEAT_TIMEOUT => {
                let request = message.init_root::<rpc_request::Builder>();
                send_message = self.replica.heartbeat_timeout(request.init_append_entries());
                // Set Timeout
                reactor.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
            },
            _ => unreachable!(),
        }
        // Send if necessary.
        match send_message {
            Some(Broadcast) => {
                let mut buf = RingBuf::new(RINGBUF_SIZE);
                serialize_packed::write_packed_message_unbuffered(
                    &mut buf,
                    &mut message
                ).unwrap();
                for connection in self.connections.iter_mut() {
                    connection.add_write(buf.clone());
                }
            },
            None => (),
        }
    }
}

struct Connection {
    stream: NonBlock<TcpStream>,
    token: Token,
    interest: Interest,
    current_read: RingBuf,
    current_write: RingBuf,
    next_write: VecDeque<RingBuf>,
}

impl Connection {
    /// Note: The caller must manually assign `token` to what is desired.
    fn new(sock: NonBlock<TcpStream>) -> Connection {
        Connection {
            stream: sock,
            token: Token(0), // Effectively a `null`. This needs to be assigned by the caller.
            interest: Interest::hup(),
            current_read: RingBuf::new(4096),
            current_write: RingBuf::new(4096),
            next_write: VecDeque::with_capacity(10),
        }
    }

    fn writable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        // Attempt to write data.
        // The `current_write` buffer will be advanced based on how much we wrote.
        match self.stream.write(&mut self.current_write) {
            Ok(None) => {
                // This is a buffer flush. WOULDBLOCK
                self.interest.insert(Interest::writable());
            },
            Ok(Some(r)) => {
                // We managed to write data!
                match (self.current_write.has_remaining(), self.next_write.is_empty()) {
                    // Need to write more of what we have.
                    (true, _) => (),
                    // Need to roll over.
                    (false, false) => self.current_write = self.next_write.pop_front().unwrap(),
                    // We're done writing for now.
                    (false, true) => self.interest.remove(Interest::writable()),

                }
            },
            Err(e) => return Err(Error::from(e)),
        }

        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge() | PollOpt::oneshot()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from(e)),
        }
    }

    fn readable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        let mut read = 0;
        match self.stream.read(&mut self.current_read) {
            Ok(Some(r)) => {
                // Just read `r` bytes.
                read = r;
            },
            Ok(None) => panic!("We just got readable, but were unable to read from the socket?"),
            Err(e) => return Err(Error::from(e)),
        };
        if read > 0 {
            match serialize_packed::new_reader_unbuffered(&mut self.current_read, ReaderOptions::new()) {
                // We have something reasonably interesting in the buffer!
                Ok(reader) => {
                    self.handle_reader(reader, event_loop, replica);
                },
                // It's not read entirely yet.
                // Should roll back, pending changes to bytes upstream.
                Err(_) => unimplemented!(),
            }
        }
        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from(e)),
        }
    }

    fn handle_reader<S, M>(&mut self, reader: OwnedSpaceMessageReader,
                           event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
    where S: Store, M: StateMachine {
        let mut builder_message = MallocMessageBuilder::new_default();
        let from = self.stream.peer_addr().unwrap();
        if let Ok(request) = reader.get_root::<rpc_request::Reader>() {
            match request.which().unwrap() {
                // TODO: Move these into replica?
                rpc_request::Which::AppendEntries(Ok(call)) => {
                    let builder = builder_message.init_root::<append_entries_response::Builder>();
                    match replica.append_entries_request(from, call, builder) {
                        Some(Emit) => {
                            // Special Cirsumstance Detection
                            unimplemented!();
                        },
                        None => (),
                    }
                },
                rpc_request::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<request_vote_response::Builder>();
                        replica.request_vote_request(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(builder_message);
                        },
                        None            => (),
                    }
                },
                _ => unimplemented!(),
            };
        } else if let Ok(response) = reader.get_root::<rpc_response::Reader>() {
            // We won't be responding. This is already a response.
            match response.which().unwrap() {
                rpc_response::Which::AppendEntries(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.append_entries_response(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(builder_message);
                        },
                        None => (),
                    }
                },
                rpc_response::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.request_vote_response(from, call, builder)
                    };
                    match respond {
                        Some(Broadcast) => {
                            // Won an election!
                            self.broadcast(builder_message);
                        },
                        None => (),
                    }

                },
                _ => unimplemented!(),
            }
        } else if let Ok(client_req) = reader.get_root::<client_request::Reader>() {
            let mut should_die = false;
            // We will be responding.
            match client_req.which().unwrap() {
                client_request::Which::Append(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_append(from, call, builder)
                    };
                    match respond {
                        Some(emit) => {
                            self.emit(builder_message);
                        },
                        None => (),
                    }

                },
                client_request::Which::Die(Ok(call)) => {
                    should_die = true;
                    let mut builder = builder_message.init_root::<client_response::Builder>();
                    builder.set_success(());
                    self.interest.insert(Interest::writable());
                    debug!("Got a Die request from Client({}). Reason: {}", from, call);
                },
                client_request::Which::LeaderRefresh(()) => {
                    let respond = {
                        let builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_leader_refresh(from, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            self.emit(builder_message);
                        },
                        None => (),
                    }
                },
                _ => unimplemented!(),
            };

            // Do this here so that we can send the response.
            if should_die {
                panic!("Got a Die request.");
            }

        } else {
            // It's something we don't understand.
            unimplemented!();
        }
    }

    fn broadcast(&mut self, builder: MallocMessageBuilder) {
        unimplemented!();
    }

    /// Push the new message into `self.next_write`.
    pub fn emit(&mut self, mut builder: MallocMessageBuilder) {
        let mut buf = RingBuf::new(RINGBUF_SIZE);
        serialize_packed::write_packed_message_unbuffered(
            &mut buf,
            &mut builder
        ).unwrap();
        self.add_write(buf);
    }

    pub fn add_write(&mut self, buf: RingBuf) {
        self.next_write.push_back(buf);
    }
}
<commit_msg>Some comments.<commit_after>use std::thread;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::collections::VecDeque;

// MIO
use mio::tcp::{listen, TcpListener, TcpStream};
use mio::util::Slab;
use mio::Socket;
use mio::buf::{RingBuf};
use mio::{Interest, PollOpt, NonBlock, Token, EventLoop, Handler, ReadHint};
use mio::buf::Buf;
use mio::{TryRead, TryWrite};

use rand::{self, Rng};

// Data structures.
use store::Store;
use replica::{Replica, Emit, Broadcast};
use state_machine::StateMachine;

// Cap'n Proto
use capnp::serialize_packed;
use capnp::{
    MessageBuilder,
    MessageReader,
    ReaderOptions,
    MallocMessageBuilder,
    OwnedSpaceMessageReader,
};
use messages_capnp::{
    rpc_request,
    rpc_response,
    client_request,
    client_response,
    request_vote_response,
    append_entries_response,
    append_entries_request,
};
use super::{Error, Result};

// MIO Tokens
const ELECTION_TIMEOUT: Token = Token(0);
const HEARTBEAT_TIMEOUT: Token = Token(1);
const LISTENER:  Token = Token(2);

const ELECTION_MIN: u64 = 150;
const ELECTION_MAX: u64 = 300;
const HEARTBEAT_DURATION: u64 = 50;
const RINGBUF_SIZE: usize = 4096;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
/// A `Server` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
///
/// Currently, the `Server` API is not well defined. **We are looking for feedback and suggestions.**
pub struct Server<S, M> where S: Store, M: StateMachine {
    replica: Replica<S, M>,
    // Channels and Sockets
    listener: NonBlock<TcpListener>,
    connections: Slab<Connection>,
}

/// The implementation of the Server. In most use cases, creating a `Server` should just be
/// done via `::new()`.
impl<S, M> Server<S, M> where S: Store, M: StateMachine {

    /// Creates a new Raft node with the cluster members specified.
    ///
    /// # Arguments
    ///
    /// * `addr` - The address of the new node.
    /// * `peers` - The address of all peers in the Raft cluster.
    /// * `store` - The persitent log store.
    /// * `state_machine` - The client state machine to which client commands will be applied.
    pub fn spawn(addr: SocketAddr,
                 peers: HashSet<SocketAddr>,
                 store: S,
                 state_machine: M) {
        // Create an event loop
        let mut event_loop = EventLoop::<Server<S, M>>::new().unwrap();
        // Setup the socket, make it not block.
        let listener = listen(&addr).unwrap();
        listener.set_reuseaddr(true).unwrap();
        event_loop.register(&listener, LISTENER).unwrap();
        let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
        event_loop.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
        event_loop.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
        let replica = Replica::new(addr, peers, store, state_machine);
        // Fire up the thread.
        thread::Builder::new().name(format!("Server {}", addr)).spawn(move || {
            let mut raft_node = Server {
                listener: listener,
                replica: replica,
                connections: Slab::new_starting_at(Token(2), 128),
            };
            event_loop.run(&mut raft_node).unwrap();
        }).unwrap();
    }
}

impl<S, M> Handler for Server<S, M> where S: Store, M: StateMachine {

    type Message = RingBuf;
    type Timeout = Token;

    /// A registered IoHandle has available writing space.
    fn writable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => unreachable!(),
            tok => {
                self.connections[tok].writable(reactor, &mut self.replica).unwrap();
            }
        }
    }

    /// A registered IoHandle has available data to read
    fn readable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token, _hint: ReadHint) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => {
                let stream = match self.listener.accept().unwrap() {
                    Some(s) => s,
                    None => return, // Socket isn't quite ready.
                }; // Result<Option<_>,_>
                let conn = Connection::new(stream);
                let tok = self.connections.insert(conn)
                    .ok().expect("Could not add connection to slab.");

                // Register the connection
                self.connections[tok].token = tok;
                reactor.register_opt(&self.connections[tok].stream, tok, Interest::readable(), PollOpt::edge() | PollOpt::oneshot())
                    .ok().expect("Could not register socket with event loop.");
            },
            tok => {
                self.connections[tok].readable(reactor, &mut self.replica).unwrap();
            }
        }
    }

    /// A registered timer has expired. This is either:
    ///
    /// * An election timeout, when a `Follower` node has waited too long for a heartbeat and doing
    /// to become a `Candidate`.
    /// * A heartbeat timeout, when the `Leader` node needs to refresh it's authority over the
    /// followers. Initializes and sends an `AppendEntries` request to all followers.
    fn timeout(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        let mut message = MallocMessageBuilder::new_default();
        let mut send_message = None;
        match token {
            ELECTION_TIMEOUT => {
                let request = message.init_root::<rpc_request::Builder>();
                send_message = self.replica.election_timeout(request.init_request_vote());
                // Set timeout.
                let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
                reactor.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();

            },
            HEARTBEAT_TIMEOUT => {
                let request = message.init_root::<rpc_request::Builder>();
                send_message = self.replica.heartbeat_timeout(request.init_append_entries());
                // Set Timeout
                reactor.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
            },
            _ => unreachable!(),
        }
        // Send if necessary.
        match send_message {
            Some(Broadcast) => {
                let mut buf = RingBuf::new(RINGBUF_SIZE);
                serialize_packed::write_packed_message_unbuffered(
                    &mut buf,
                    &mut message
                ).unwrap();
                for connection in self.connections.iter_mut() {
                    connection.add_write(buf.clone());
                }
            },
            None => (),
        }
    }
}

struct Connection {
    stream: NonBlock<TcpStream>,
    token: Token,
    interest: Interest,
    current_read: RingBuf,
    current_write: RingBuf,
    next_write: VecDeque<RingBuf>,
}

impl Connection {
    /// Note: The caller must manually assign `token` to what is desired.
    fn new(sock: NonBlock<TcpStream>) -> Connection {
        Connection {
            stream: sock,
            token: Token(0), // Effectively a `null`. This needs to be assigned by the caller.
            interest: Interest::hup(),
            current_read: RingBuf::new(4096),
            current_write: RingBuf::new(4096),
            next_write: VecDeque::with_capacity(10),
        }
    }

    /// A registered IoHandle has available writing space.
    fn writable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        // Attempt to write data.
        // The `current_write` buffer will be advanced based on how much we wrote.
        match self.stream.write(&mut self.current_write) {
            Ok(None) => {
                // This is a buffer flush. WOULDBLOCK
                self.interest.insert(Interest::writable());
            },
            Ok(Some(r)) => {
                // We managed to write data!
                match (self.current_write.has_remaining(), self.next_write.is_empty()) {
                    // Need to write more of what we have.
                    (true, _) => (),
                    // Need to roll over.
                    (false, false) => self.current_write = self.next_write.pop_front().unwrap(),
                    // We're done writing for now.
                    (false, true) => self.interest.remove(Interest::writable()),

                }
            },
            Err(e) => return Err(Error::from(e)),
        }

        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge() | PollOpt::oneshot()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from(e)),
        }
    }

    /// A registered IoHandle has available data to read.
    /// This does not necessarily mean that there is an entire packed item on the stream. We could
    /// get some, all of it, or none. We'll use the buffer to read in until we can find one.
    fn readable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        let mut read = 0;
        match self.stream.read(&mut self.current_read) {
            Ok(Some(r)) => {
                // Just read `r` bytes.
                read = r;
            },
            Ok(None) => panic!("We just got readable, but were unable to read from the socket?"),
            Err(e) => return Err(Error::from(e)),
        };
        if read > 0 {
            match serialize_packed::new_reader_unbuffered(&mut self.current_read, ReaderOptions::new()) {
                // We have something reasonably interesting in the buffer!
                Ok(reader) => {
                    self.handle_reader(reader, event_loop, replica);
                },
                // It's not read entirely yet.
                // Should roll back, pending changes to bytes upstream.
                // TODO: This was fixed.
                Err(_) => unimplemented!(),
            }
        }
        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from(e)),
        }
    }

    /// This is called when there is a full reader available in the buffer.
    /// It handles what to do with the data.
    fn handle_reader<S, M>(&mut self, reader: OwnedSpaceMessageReader,
                           event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
    where S: Store, M: StateMachine {
        let mut builder_message = MallocMessageBuilder::new_default();
        let from = self.stream.peer_addr().unwrap();
        if let Ok(request) = reader.get_root::<rpc_request::Reader>() {
            match request.which().unwrap() {
                // TODO: Move these into replica?
                rpc_request::Which::AppendEntries(Ok(call)) => {
                    let builder = builder_message.init_root::<append_entries_response::Builder>();
                    match replica.append_entries_request(from, call, builder) {
                        Some(Emit) => {
                            // Special Cirsumstance Detection
                            unimplemented!();
                        },
                        None => (),
                    }
                },
                rpc_request::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<request_vote_response::Builder>();
                        replica.request_vote_request(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(builder_message);
                        },
                        None            => (),
                    }
                },
                _ => unimplemented!(),
            };
        } else if let Ok(response) = reader.get_root::<rpc_response::Reader>() {
            // We won't be responding. This is already a response.
            match response.which().unwrap() {
                rpc_response::Which::AppendEntries(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.append_entries_response(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(builder_message);
                        },
                        None => (),
                    }
                },
                rpc_response::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.request_vote_response(from, call, builder)
                    };
                    match respond {
                        Some(Broadcast) => {
                            // Won an election!
                            self.broadcast(builder_message);
                        },
                        None => (),
                    }

                },
                _ => unimplemented!(),
            }
        } else if let Ok(client_req) = reader.get_root::<client_request::Reader>() {
            let mut should_die = false;
            // We will be responding.
            match client_req.which().unwrap() {
                client_request::Which::Append(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_append(from, call, builder)
                    };
                    match respond {
                        Some(emit) => {
                            self.emit(builder_message);
                        },
                        None => (),
                    }

                },
                client_request::Which::Die(Ok(call)) => {
                    should_die = true;
                    let mut builder = builder_message.init_root::<client_response::Builder>();
                    builder.set_success(());
                    self.interest.insert(Interest::writable());
                    debug!("Got a Die request from Client({}). Reason: {}", from, call);
                },
                client_request::Which::LeaderRefresh(()) => {
                    let respond = {
                        let builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_leader_refresh(from, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            self.emit(builder_message);
                        },
                        None => (),
                    }
                },
                _ => unimplemented!(),
            };

            // Do this here so that we can send the response.
            if should_die {
                panic!("Got a Die request.");
            }

        } else {
            // It's something we don't understand.
            unimplemented!();
        }
    }

    fn broadcast(&mut self, builder: MallocMessageBuilder) {
        unimplemented!();
    }

    /// Push the new message into `self.next_write`. This does not actually send the message, it
    /// just queues it up.
    pub fn emit(&mut self, mut builder: MallocMessageBuilder) {
        let mut buf = RingBuf::new(RINGBUF_SIZE);
        serialize_packed::write_packed_message_unbuffered(
            &mut buf,
            &mut builder
        ).unwrap();
        self.add_write(buf);
    }

    /// This queues a byte buffer into the write queue. This is used primarily when message has
    /// already been packed.
    pub fn add_write(&mut self, buf: RingBuf) {
        self.next_write.push_back(buf);
    }
}
<|endoftext|>


<commit_before>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

use std::fmt;
use std::marker;
use std::mem;
use std::ops::{Index, IndexMut};

/// Stride is similar to the slice iterator, but with a certain number of steps
/// (the stride) skipped per iteration.
///
/// Stride does not support zero-sized types for `A`.
///
/// Iterator element type is `&'a A`.
pub struct Stride<'a, A: 'a> {
    /// base pointer -- does not change during iteration
    begin: *const A,
    /// current offset from begin
    offset: isize,
    /// offset where we end (exclusive end).
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a A>,
}

impl<'a, A> Copy for Stride<'a, A> {}

/// StrideMut is like Stride, but with mutable elements.
///
/// Iterator element type is `&'a mut A`.
pub struct StrideMut<'a, A: 'a> {
    begin: *mut A,
    offset: isize,
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a A>,
}

impl<'a, A> Stride<'a, A>
{
    /// Create a Stride iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *const A, nelem: usize, stride: isize) -> Stride<'a, A>
    {
        Stride {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

impl<'a, A> StrideMut<'a, A>
{
    /// Create a StrideMut iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *mut A, nelem: usize, stride: isize) -> StrideMut<'a, A>
    {
        StrideMut {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

fn div_rem(x: usize, d: usize) -> (usize, usize)
{
    (x / d, x % d)
}

macro_rules! stride_impl {
    (struct $name:ident -> $slice:ty, $getptr:ident, $ptr:ty, $elem:ty) => {
        impl<'a, A> $name<'a, A>
        {
            /// Create Stride iterator from a slice and the element step count.
            ///
            /// If `step` is negative, start from the back.
            ///
            /// ## Example
            ///
            /// ```
            /// use itertools::Stride;
            ///
            /// let xs = [0, 1, 2, 3, 4, 5];
            ///
            /// let front = Stride::from_slice(&xs, 2);
            /// assert_eq!(front[0], 0);
            /// assert_eq!(front[1], 2);
            ///
            /// let back = Stride::from_slice(&xs, -2);
            /// assert_eq!(back[0], 5);
            /// assert_eq!(back[1], 3);
            /// ```
            ///
            /// **Panics** if values of type `A` are zero-sized.

            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_slice(xs: $slice, step: isize) -> $name<'a, A>
            {
                assert!(mem::size_of::() != 0);
                let ustep = if step < 0 { -step } else { step } as usize;
                let nelem = if ustep <= 1 {
                    xs.len()
                } else {
                    let (d, r) = div_rem(xs.len(), ustep);
                    d + if r > 0 { 1 } else { 0 }
                };
                let mut begin = xs. $getptr ();
                unsafe {
                    if step > 0 {
                        $name::from_ptr_len(begin, nelem, step)
                    } else {
                        if nelem != 0 {
                            begin = begin.offset(xs.len() as isize - 1)
                        }
                        $name::from_ptr_len(begin, nelem, step)
                    }
                }
            }

            /// Create Stride iterator from an existing Stride iterator
            ///
            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_stride(mut it: $name<'a, A>, mut step: isize) -> $name<'a, A>
            {
                assert!(step != 0);
                if step < 0 {
                    it.swap_ends();
                    step = -step;
                }
                let len = (it.end - it.offset) / it.stride;
                let newstride = it.stride * step;
                let (d, r) = div_rem(len as usize, step as usize);
                let len = d as usize + if r > 0 { 1 } else { 0 };
                unsafe {
                    $name::from_ptr_len(it.begin, len, newstride)
                }
            }

            /// Swap the begin and end and reverse the stride,
            /// in effect reversing the iterator.
            #[inline]
            pub fn swap_ends(&mut self) {
                let len = (self.end - self.offset) / self.stride;
                if len > 0 {
                    unsafe {
                        let endptr = self.begin.offset((len - 1) * self.stride);
                        *self = $name::from_ptr_len(endptr, len as usize, -self.stride);
                    }
                }
            }

            /// Return the number of elements in the iterator.
            #[inline]
            pub fn len(&self) -> usize {
                ((self.end - self.offset) / self.stride) as usize
            }
        }

        impl<'a, A> Iterator for $name<'a, A>
        {
            type Item = $elem;
            #[inline]
            fn next(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        let elt: $elem =
                            mem::transmute(self.begin.offset(self.offset));
                        self.offset += self.stride;
                        Some(elt)
                    }
                }
            }

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

        impl<'a, A> DoubleEndedIterator for $name<'a, A>
        {
            #[inline]
            fn next_back(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        self.end -= self.stride;
                        let elt = mem::transmute(self.begin.offset(self.end));
                        Some(elt)
                    }
                }
            }
        }

        impl<'a, A> ExactSizeIterator for $name<'a, A> { }

        impl<'a, A> Index<usize> for $name<'a, A>
        {
            type Output = A;
            /// Return a reference to the element at a given index.
            ///
            /// **Panics** if the index is out of bounds.
            fn index<'b>(&'b self, i: &usize) -> &'b A
            {
                assert!(*i < self.len());
                unsafe {
                    let ptr = self.begin.offset(self.offset + self.stride * (*i as isize));
                    mem::transmute(ptr)
                }
            }
        }

        impl<'a, A: fmt::Debug> fmt::Debug for $name<'a, A>
        {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
            {
                try!(write!(f, "["));
                for i in 0..self.len() {
                    if i != 0 {
                        try!(write!(f, ", "));
                    }
                    try!(write!(f, "{:?}", (*self)[i]));
                }
                write!(f, "]")
            }
        }
    }
}

stride_impl!{struct Stride -> &'a [A], as_ptr, *const A, &'a A}
stride_impl!{struct StrideMut -> &'a mut [A], as_mut_ptr, *mut A, &'a mut A}

impl<'a, A> Clone for Stride<'a, A>
{
    fn clone(&self) -> Stride<'a, A>
    {
        *self
    }
}

impl<'a, A> IndexMut<usize> for StrideMut<'a, A>
{
    /// Return a mutable reference to the element at a given index.
    ///
    /// **Panics** if the index is out of bounds.
    fn index_mut<'b>(&'b mut self, i: &usize) -> &'b mut A
    {
        assert!(*i < self.len());
        unsafe {
            let ptr = self.begin.offset(self.offset + self.stride * (*i as isize));
            mem::transmute(ptr)
        }
    }
}
<commit_msg>Mark Stride/StrideMut Send & Sync as appropriate<commit_after>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

use std::fmt;
use std::marker;
use std::mem;
use std::ops::{Index, IndexMut};

/// Stride is similar to the slice iterator, but with a certain number of steps
/// (the stride) skipped per iteration.
///
/// Stride does not support zero-sized types for `A`.
///
/// Iterator element type is `&'a A`.
pub struct Stride<'a, A: 'a> {
    /// base pointer -- does not change during iteration
    begin: *const A,
    /// current offset from begin
    offset: isize,
    /// offset where we end (exclusive end).
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a A>,
}

impl<'a, A> Copy for Stride<'a, A> {}
unsafe impl<'a, A: Send> marker::Send for Stride<'a, A> {}
unsafe impl<'a, A: Sync> marker::Sync for Stride<'a, A> {}

/// StrideMut is like Stride, but with mutable elements.
///
/// Iterator element type is `&'a mut A`.
pub struct StrideMut<'a, A: 'a> {
    begin: *mut A,
    offset: isize,
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a mut A>,
}

unsafe impl<'a, A: Send> marker::Send for StrideMut<'a, A> {}
unsafe impl<'a, A: Sync> marker::Sync for StrideMut<'a, A> {}

impl<'a, A> Stride<'a, A>
{
    /// Create a Stride iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *const A, nelem: usize, stride: isize) -> Stride<'a, A>
    {
        Stride {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

impl<'a, A> StrideMut<'a, A>
{
    /// Create a StrideMut iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *mut A, nelem: usize, stride: isize) -> StrideMut<'a, A>
    {
        StrideMut {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

fn div_rem(x: usize, d: usize) -> (usize, usize)
{
    (x / d, x % d)
}

macro_rules! stride_impl {
    (struct $name:ident -> $slice:ty, $getptr:ident, $ptr:ty, $elem:ty) => {
        impl<'a, A> $name<'a, A>
        {
            /// Create Stride iterator from a slice and the element step count.
            ///
            /// If `step` is negative, start from the back.
            ///
            /// ## Example
            ///
            /// ```
            /// use itertools::Stride;
            ///
            /// let xs = [0, 1, 2, 3, 4, 5];
            ///
            /// let front = Stride::from_slice(&xs, 2);
            /// assert_eq!(front[0], 0);
            /// assert_eq!(front[1], 2);
            ///
            /// let back = Stride::from_slice(&xs, -2);
            /// assert_eq!(back[0], 5);
            /// assert_eq!(back[1], 3);
            /// ```
            ///
            /// **Panics** if values of type `A` are zero-sized.

            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_slice(xs: $slice, step: isize) -> $name<'a, A>
            {
                assert!(mem::size_of::() != 0);
                let ustep = if step < 0 { -step } else { step } as usize;
                let nelem = if ustep <= 1 {
                    xs.len()
                } else {
                    let (d, r) = div_rem(xs.len(), ustep);
                    d + if r > 0 { 1 } else { 0 }
                };
                let mut begin = xs. $getptr ();
                unsafe {
                    if step > 0 {
                        $name::from_ptr_len(begin, nelem, step)
                    } else {
                        if nelem != 0 {
                            begin = begin.offset(xs.len() as isize - 1)
                        }
                        $name::from_ptr_len(begin, nelem, step)
                    }
                }
            }

            /// Create Stride iterator from an existing Stride iterator
            ///
            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_stride(mut it: $name<'a, A>, mut step: isize) -> $name<'a, A>
            {
                assert!(step != 0);
                if step < 0 {
                    it.swap_ends();
                    step = -step;
                }
                let len = (it.end - it.offset) / it.stride;
                let newstride = it.stride * step;
                let (d, r) = div_rem(len as usize, step as usize);
                let len = d as usize + if r > 0 { 1 } else { 0 };
                unsafe {
                    $name::from_ptr_len(it.begin, len, newstride)
                }
            }

            /// Swap the begin and end and reverse the stride,
            /// in effect reversing the iterator.
            #[inline]
            pub fn swap_ends(&mut self) {
                let len = (self.end - self.offset) / self.stride;
                if len > 0 {
                    unsafe {
                        let endptr = self.begin.offset((len - 1) * self.stride);
                        *self = $name::from_ptr_len(endptr, len as usize, -self.stride);
                    }
                }
            }

            /// Return the number of elements in the iterator.
            #[inline]
            pub fn len(&self) -> usize {
                ((self.end - self.offset) / self.stride) as usize
            }
        }

        impl<'a, A> Iterator for $name<'a, A>
        {
            type Item = $elem;
            #[inline]
            fn next(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        let elt: $elem =
                            mem::transmute(self.begin.offset(self.offset));
                        self.offset += self.stride;
                        Some(elt)
                    }
                }
            }

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

        impl<'a, A> DoubleEndedIterator for $name<'a, A>
        {
            #[inline]
            fn next_back(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        self.end -= self.stride;
                        let elt = mem::transmute(self.begin.offset(self.end));
                        Some(elt)
                    }
                }
            }
        }

        impl<'a, A> ExactSizeIterator for $name<'a, A> { }

        impl<'a, A> Index<usize> for $name<'a, A>
        {
            type Output = A;
            /// Return a reference to the element at a given index.
            ///
            /// **Panics** if the index is out of bounds.
            fn index<'b>(&'b self, i: &usize) -> &'b A
            {
                assert!(*i < self.len());
                unsafe {
                    let ptr = self.begin.offset(self.offset + self.stride * (*i as isize));
                    mem::transmute(ptr)
                }
            }
        }

        impl<'a, A: fmt::Debug> fmt::Debug for $name<'a, A>
        {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
            {
                try!(write!(f, "["));
                for i in 0..self.len() {
                    if i != 0 {
                        try!(write!(f, ", "));
                    }
                    try!(write!(f, "{:?}", (*self)[i]));
                }
                write!(f, "]")
            }
        }
    }
}

stride_impl!{struct Stride -> &'a [A], as_ptr, *const A, &'a A}
stride_impl!{struct StrideMut -> &'a mut [A], as_mut_ptr, *mut A, &'a mut A}

impl<'a, A> Clone for Stride<'a, A>
{
    fn clone(&self) -> Stride<'a, A>
    {
        *self
    }
}

impl<'a, A> IndexMut<usize> for StrideMut<'a, A>
{
    /// Return a mutable reference to the element at a given index.
    ///
    /// **Panics** if the index is out of bounds.
    fn index_mut<'b>(&'b mut self, i: &usize) -> &'b mut A
    {
        assert!(*i < self.len());
        unsafe {
            let ptr = self.begin.offset(self.offset + self.stride * (*i as isize));
            mem::transmute(ptr)
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Fedor Gogolev <knsd@knsd.net>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::{VecDeque};
use std::char::{from_u32};

use unicode_names::{character};
use from_ascii::{FromAsciiRadix, ParseIntError};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        InvalidValue {
            from(ParseIntError)
        }
        UnexpectedEnd
    }
}

pub fn unescape(s: &[u8], unicode: bool) -> Result<Vec<u8>, Error> {
    let mut buf = Vec::with_capacity(s.len());
    let mut oct_buf = VecDeque::with_capacity(3);

    let mut i = 0;

    macro_rules! read {
        () => ({
            match s.get(i) {
                None => return Err(Error::UnexpectedEnd),
                Some(c) => {
                    i += 1;
                    *c
                }
            }
        })
    }

    macro_rules! peek {
        () => ({
            s.get(i).map(|c| *c)
        })
    }

    macro_rules! push_char {
        ($c: ident) => ({
            let mut s = String::new();
            s.push($c);
            buf.extend_from_slice(s.as_bytes());
        })
    }

    loop {
        if i >= s.len() {
            return Ok(buf)
        }

        let c = read!();

        if c != b'\\' {
            buf.push(c);
            continue
        }

        let marker = read!();

        match marker {
            b'\n' => (),
            b'\\' => buf.push(b'\\'),
            b'\'' => buf.push(b'\''),
            b'"' => buf.push(b'"'),
            b'a' => buf.push(b'\x07'),
            b'b' => buf.push(b'\x08'),
            b'f' => buf.push(b'\x0c'),
            b'n' => buf.push(b'\n'),
            b'r' => buf.push(b'\r'),
            b't' => buf.push(b'\t'),
            b'v' => buf.push(b'\x0b'),
            b'x' => {
                let hex_buf = [read!(), read!()];
                buf.push(try!(u8::from_ascii_radix(&hex_buf, 16)))
            }
            b'0' ... b'7' => {
                oct_buf.push_back(marker);
                peek!().map(|c| {
                    if c >= b'0' && c <= b'7' {
                        oct_buf.push_back(c);
                        i += 1;

                        peek!().map(|c| {
                            if c >= b'0' && c <= b'7' {
                                oct_buf.push_back(c);
                                i += 1;
                            }
                        });
                    }
                });

                let value = try!(u16::from_ascii_radix(oct_buf.as_slices().0, 8));
                oct_buf.clear();
                buf.push(if value > 255 {
                    255
                } else {
                    value as u8
                });
                continue
            },
            b'u' if unicode => {
                let hex_buf = [read!(), read!(), read!(), read!()];
                let value = try!(u16::from_ascii_radix(&hex_buf, 16));
                let s = match String::from_utf16(&[value]) {
                    Ok(s) => s,
                    Err(_) => return Err(Error::InvalidValue),
                };
                buf.extend_from_slice(s.as_bytes());
            },
            b'U' if unicode => {
                let hex_buf = [read!(), read!(), read!(), read!(), read!(), read!(), read!(), read!()];
                let value = try!(u32::from_ascii_radix(&hex_buf, 16));
                match from_u32(value) {
                    Some(character) => push_char!(character),
                    None => return Err(Error::InvalidValue),
                };
            },
            b'N' if unicode => {
                if read!() != b'{' {
                    return Err(Error::InvalidValue)
                }
                let mut char_name = String::new();
                loop {
                    match read!() {
                        b'}' => break,
                        n => match from_u32(n as u32) {
                            None => return Err(Error::InvalidValue),
                            Some(c) => char_name.push(c),
                        }
                    }
                }
                match character(&char_name) {
                    None => return Err(Error::InvalidValue),
                    Some(character) => push_char!(character),
                }

            },
            _ => {
                buf.push(b'\\');
                buf.push(marker);
            }
        }
    }
}

#[cfg(test)]
mod tests {

    use super::{unescape};

    #[test]
    fn test_unescape() {
        assert_eq!(unescape(b"foo", false).unwrap(), b"foo");
        assert_eq!(unescape(b"f\\noo", false).unwrap(), b"f\noo");
        assert_eq!(unescape(b"f\\x01oo", false).unwrap(), b"f\x01oo");
        assert_eq!(unescape(b"f\\375oo", false).unwrap(), b"f\xfdoo");
        assert_eq!(unescape(b"f\\75oo", false).unwrap(), b"f\x3doo");
        assert_eq!(unescape(b"f\\5oo", false).unwrap(), b"f\x05oo");
        assert_eq!(unescape(b"f\\oo", false).unwrap(), b"f\\oo");
        assert_eq!(unescape(b"f\\coo", false).unwrap(), b"f\\coo");
        assert_eq!(unescape(b"f\\U00002663oo", true).unwrap(), b"f\xe2\x99\xa3oo");
        assert_eq!(unescape(b"f\\u2663oo", true).unwrap(), b"f\xe2\x99\xa3oo");
        assert_eq!(unescape(b"f\\N{SNOWMAN}oo", true).unwrap(), b"f\xe2\x98\x83oo");
    }
}
<commit_msg>Use cloned instead of dereference in map<commit_after>// Copyright (c) 2016 Fedor Gogolev <knsd@knsd.net>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::{VecDeque};
use std::char::{from_u32};

use unicode_names::{character};
use from_ascii::{FromAsciiRadix, ParseIntError};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        InvalidValue {
            from(ParseIntError)
        }
        UnexpectedEnd
    }
}

pub fn unescape(s: &[u8], unicode: bool) -> Result<Vec<u8>, Error> {
    let mut buf = Vec::with_capacity(s.len());
    let mut oct_buf = VecDeque::with_capacity(3);

    let mut i = 0;

    macro_rules! read {
        () => ({
            match s.get(i) {
                None => return Err(Error::UnexpectedEnd),
                Some(c) => {
                    i += 1;
                    *c
                }
            }
        })
    }

    macro_rules! peek {
        () => ({
            s.get(i).cloned()
        })
    }

    macro_rules! push_char {
        ($c: ident) => ({
            let mut s = String::new();
            s.push($c);
            buf.extend_from_slice(s.as_bytes());
        })
    }

    loop {
        if i >= s.len() {
            return Ok(buf)
        }

        let c = read!();

        if c != b'\\' {
            buf.push(c);
            continue
        }

        let marker = read!();

        match marker {
            b'\n' => (),
            b'\\' => buf.push(b'\\'),
            b'\'' => buf.push(b'\''),
            b'"' => buf.push(b'"'),
            b'a' => buf.push(b'\x07'),
            b'b' => buf.push(b'\x08'),
            b'f' => buf.push(b'\x0c'),
            b'n' => buf.push(b'\n'),
            b'r' => buf.push(b'\r'),
            b't' => buf.push(b'\t'),
            b'v' => buf.push(b'\x0b'),
            b'x' => {
                let hex_buf = [read!(), read!()];
                buf.push(try!(u8::from_ascii_radix(&hex_buf, 16)))
            }
            b'0' ... b'7' => {
                oct_buf.push_back(marker);
                peek!().map(|c| {
                    if c >= b'0' && c <= b'7' {
                        oct_buf.push_back(c);
                        i += 1;

                        peek!().map(|c| {
                            if c >= b'0' && c <= b'7' {
                                oct_buf.push_back(c);
                                i += 1;
                            }
                        });
                    }
                });

                let value = try!(u16::from_ascii_radix(oct_buf.as_slices().0, 8));
                oct_buf.clear();
                buf.push(if value > 255 {
                    255
                } else {
                    value as u8
                });
                continue
            },
            b'u' if unicode => {
                let hex_buf = [read!(), read!(), read!(), read!()];
                let value = try!(u16::from_ascii_radix(&hex_buf, 16));
                let s = match String::from_utf16(&[value]) {
                    Ok(s) => s,
                    Err(_) => return Err(Error::InvalidValue),
                };
                buf.extend_from_slice(s.as_bytes());
            },
            b'U' if unicode => {
                let hex_buf = [read!(), read!(), read!(), read!(), read!(), read!(), read!(), read!()];
                let value = try!(u32::from_ascii_radix(&hex_buf, 16));
                match from_u32(value) {
                    Some(character) => push_char!(character),
                    None => return Err(Error::InvalidValue),
                };
            },
            b'N' if unicode => {
                if read!() != b'{' {
                    return Err(Error::InvalidValue)
                }
                let mut char_name = String::new();
                loop {
                    match read!() {
                        b'}' => break,
                        n => match from_u32(n as u32) {
                            None => return Err(Error::InvalidValue),
                            Some(c) => char_name.push(c),
                        }
                    }
                }
                match character(&char_name) {
                    None => return Err(Error::InvalidValue),
                    Some(character) => push_char!(character),
                }

            },
            _ => {
                buf.push(b'\\');
                buf.push(marker);
            }
        }
    }
}

#[cfg(test)]
mod tests {

    use super::{unescape};

    #[test]
    fn test_unescape() {
        assert_eq!(unescape(b"foo", false).unwrap(), b"foo");
        assert_eq!(unescape(b"f\\noo", false).unwrap(), b"f\noo");
        assert_eq!(unescape(b"f\\x01oo", false).unwrap(), b"f\x01oo");
        assert_eq!(unescape(b"f\\375oo", false).unwrap(), b"f\xfdoo");
        assert_eq!(unescape(b"f\\75oo", false).unwrap(), b"f\x3doo");
        assert_eq!(unescape(b"f\\5oo", false).unwrap(), b"f\x05oo");
        assert_eq!(unescape(b"f\\oo", false).unwrap(), b"f\\oo");
        assert_eq!(unescape(b"f\\coo", false).unwrap(), b"f\\coo");
        assert_eq!(unescape(b"f\\U00002663oo", true).unwrap(), b"f\xe2\x99\xa3oo");
        assert_eq!(unescape(b"f\\u2663oo", true).unwrap(), b"f\xe2\x99\xa3oo");
        assert_eq!(unescape(b"f\\N{SNOWMAN}oo", true).unwrap(), b"f\xe2\x98\x83oo");
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use geometry::{DevicePixel, LayerPixel};
use layers::{BufferRequest, ContentAge, LayerBuffer};
use platform::surface::{NativeCompositingGraphicsContext, NativeSurfaceMethods};
use texturegl::Texture;

use geom::length::Length;
use geom::matrix::{Matrix4, identity};
use geom::point::Point2D;
use geom::rect::{Rect, TypedRect};
use geom::size::{Size2D, TypedSize2D};
use std::collections::HashMap;
use std::collections::hash_map::{Occupied, Vacant};
use std::iter::range_inclusive;
use std::mem;
use std::num::Zero;

pub struct Tile {
    /// The buffer displayed by this tile.
    buffer: Option<Box<LayerBuffer>>,

    /// The content age of any pending buffer request to avoid re-requesting
    /// a buffer while waiting for it to come back from rendering.
    content_age_of_pending_buffer: Option<ContentAge>,

    /// A handle to the GPU texture.
    pub texture: Texture,

    /// The transformation applied to this tiles texture.
    pub transform: Matrix4<f32>,

    /// The tile boundaries in the parent layer coordinates.
    pub bounds: Option<TypedRect<LayerPixel,f32>>,
}

impl Tile {
    fn new() -> Tile {
        Tile {
            buffer: None,
            texture: Zero::zero(),
            transform: identity(),
            content_age_of_pending_buffer: None,
            bounds: None,
        }
    }

    fn should_use_new_buffer(&self, new_buffer: &Box<LayerBuffer>) -> bool {
        match self.buffer {
            Some(ref buffer) => new_buffer.content_age >= buffer.content_age,
            None => true,
        }
    }

    fn replace_buffer(&mut self, buffer: Box<LayerBuffer>) -> Option<Box<LayerBuffer>> {
        if !self.should_use_new_buffer(&buffer) {
            warn!("Layer received an old buffer.");
            return Some(buffer);
        }

        let old_buffer = self.buffer.take();
        self.buffer = Some(buffer);
        self.texture = Zero::zero(); // The old texture is bound to the old buffer.
        self.content_age_of_pending_buffer = None;
        return old_buffer;
    }

    fn create_texture(&mut self, graphics_context: &NativeCompositingGraphicsContext) {
        match self.buffer {
            Some(ref buffer) => {
                let size = Size2D(buffer.screen_pos.size.width as int,
                                  buffer.screen_pos.size.height as int);

                // If we already have a texture it should still be valid.
                if !self.texture.is_zero() {
                    return;
                }

                // Make a new texture and bind the LayerBuffer's surface to it.
                self.texture = Texture::new_with_buffer(buffer);
                debug!("Tile: binding to native surface {:d}",
                       buffer.native_surface.get_id() as int);
                buffer.native_surface.bind_to_texture(graphics_context, &self.texture, size);

                // Set the layer's transform.
                let rect = buffer.rect;
                let transform = identity().translate(rect.origin.x, rect.origin.y, 0.0);
                self.transform = transform.scale(rect.size.width, rect.size.height, 1.0);
                self.bounds = Some(Rect::from_untyped(&rect));
            },
            None => {},
        }
    }

    fn should_request_buffer(&self, content_age: ContentAge) -> bool {
        // Don't resend a request if our buffer's content age matches the current content age.
        match self.buffer {
            Some(ref buffer) => {
                if buffer.content_age >= content_age {
                    return false;
                }
            }
            None => {}
        }

        // Don't resend a request, if we already have one pending.
        match self.content_age_of_pending_buffer {
            Some(pending_content_age) => pending_content_age != content_age,
            None => true,
        }
    }
}

pub struct TileGrid {
    pub tiles: HashMap<Point2D<uint>, Tile>,

    /// The size of tiles in this grid in device pixels.
    tile_size: Length<DevicePixel, uint>,

    // Buffers that are currently unused.
    unused_buffers: Vec<Box<LayerBuffer>>,
}

pub fn rect_uint_as_rect_f32(rect: Rect<uint>) -> Rect<f32> {
    Rect(Point2D(rect.origin.x as f32, rect.origin.y as f32),
         Size2D(rect.size.width as f32, rect.size.height as f32))
}

impl TileGrid {
    pub fn new(tile_size: uint) -> TileGrid {
        TileGrid {
            tiles: HashMap::new(),
            tile_size: Length(tile_size),
            unused_buffers: Vec::new(),
        }
    }

    pub fn get_tile_index_range_for_rect(&self,
                                         rect: TypedRect<DevicePixel, f32>)
                                         -> (Point2D<uint>, Point2D<uint>) {
        let rect = rect.to_untyped();

        // NB: Even in the case of an empty rect, the semantics of Rust floating-point-to-integer
        // casts mean this will corrently round to zero.
        (Point2D((rect.origin.x / self.tile_size.get() as f32) as uint,
                 (rect.origin.y / self.tile_size.get() as f32) as uint),
         Point2D(((rect.origin.x + rect.size.width - 1.0) / self.tile_size.get() as f32) as uint,
                 ((rect.origin.y + rect.size.height - 1.0) / self.tile_size.get() as f32) as uint))
    }

    pub fn get_rect_for_tile_index(&self,
                                   tile_index: Point2D<uint>,
                                   current_layer_size: TypedSize2D<DevicePixel, f32>)
                                   -> TypedRect<DevicePixel, uint> {

        let origin = Point2D(self.tile_size.get() * tile_index.x,
                             self.tile_size.get() * tile_index.y);

        // Don't let tiles extend beyond the layer boundaries.
        let tile_size = self.tile_size.get() as f32;
        let size = Size2D(tile_size.min(current_layer_size.width.get() - origin.x as f32),
                          tile_size.min(current_layer_size.height.get() - origin.y as f32));

        // Round up to texture pixels.
        let size = Size2D(size.width.ceil() as uint, size.height.ceil() as uint);

        Rect::from_untyped(&Rect(origin, size))
    }

    pub fn take_unused_buffers(&mut self) -> Vec<Box<LayerBuffer>> {
        let mut unused_buffers = Vec::new();
        mem::swap(&mut unused_buffers, &mut self.unused_buffers);
        return unused_buffers;
    }

    pub fn add_unused_buffer(&mut self, buffer: Option<Box<LayerBuffer>>) {
        match buffer {
            Some(buffer) => self.unused_buffers.push(buffer),
            None => {},
        }
    }

    pub fn mark_tiles_outside_of_rect_as_unused(&mut self,
                                                rect: TypedRect<DevicePixel, f32>,
                                                current_layer_size: TypedSize2D<DevicePixel, f32>) {
        let mut tile_indexes_to_take = Vec::new();
        for tile_index in self.tiles.keys() {
            let tile_rect = self.get_rect_for_tile_index(*tile_index, current_layer_size);
            if !tile_rect.as_f32().intersects(&rect) {
                tile_indexes_to_take.push(tile_index.clone());
            }
        }

        for tile_index in tile_indexes_to_take.iter() {
            match self.tiles.remove(tile_index) {
                Some(ref mut tile) => self.add_unused_buffer(tile.buffer.take()),
                None => {},
            }
        }
    }

    pub fn get_buffer_request_for_tile(&mut self,
                                       tile_index: Point2D<uint>,
                                       current_layer_size: TypedSize2D<DevicePixel, f32>,
                                       current_content_age: ContentAge)
                                       -> Option<BufferRequest> {
        let tile_rect = self.get_rect_for_tile_index(tile_index, current_layer_size);
        let tile = match self.tiles.entry(tile_index) {
            Occupied(occupied) => occupied.into_mut(),
            Vacant(vacant) => vacant.set(Tile::new()),
        };
        if !tile.should_request_buffer(current_content_age) {
            return None;
        }

        tile.content_age_of_pending_buffer = Some(current_content_age);

        return Some(BufferRequest::new(tile_rect.to_untyped(),
                                       tile_rect.as_f32().to_untyped(),
                                       current_content_age));
    }

    pub fn get_buffer_requests_in_rect(&mut self,
                                       rect_in_layer: TypedRect<DevicePixel, f32>,
                                       current_layer_size: TypedSize2D<DevicePixel, f32>,
                                       current_content_age: ContentAge)
                                       -> Vec<BufferRequest> {
        let mut buffer_requests = Vec::new();
        let (top_left_index, bottom_right_index) =
            self.get_tile_index_range_for_rect(rect_in_layer);

        for x in range_inclusive(top_left_index.x, bottom_right_index.x) {
            for y in range_inclusive(top_left_index.y, bottom_right_index.y) {
                match self.get_buffer_request_for_tile(Point2D(x, y),
                                                       current_layer_size,
                                                       current_content_age) {
                    Some(buffer) => buffer_requests.push(buffer),
                    None => {},
                }
            }
        }

        self.mark_tiles_outside_of_rect_as_unused(rect_in_layer, current_layer_size);
        return buffer_requests;
    }

    pub fn get_tile_index_for_point(&self, point: Point2D<uint>) -> Point2D<uint> {
        assert!(point.x % self.tile_size.get() == 0);
        assert!(point.y % self.tile_size.get() == 0);
        Point2D((point.x / self.tile_size.get()) as uint,
                (point.y / self.tile_size.get()) as uint)
    }

    pub fn add_buffer(&mut self, buffer: Box<LayerBuffer>) {
        let index = self.get_tile_index_for_point(buffer.screen_pos.origin.clone());
        if !self.tiles.contains_key(&index) {
            warn!("Received buffer for non-existent tile!");
            self.add_unused_buffer(Some(buffer));
            return;
        }

        let replaced_buffer = self.tiles.get_mut(&index).unwrap().replace_buffer(buffer);
        self.add_unused_buffer(replaced_buffer);
    }

    pub fn do_for_all_tiles(&self, f: |&Tile|) {
        for tile in self.tiles.values() {
            f(tile);
        }
    }

    pub fn collect_buffers(&mut self) -> Vec<Box<LayerBuffer>> {
        let mut collected_buffers = Vec::new();

        collected_buffers.extend(self.take_unused_buffers().into_iter());

        // We need to replace the HashMap since it cannot be used again after move_iter().
        let mut tile_map = HashMap::new();
        mem::swap(&mut tile_map, &mut self.tiles);

        for (_, mut tile) in tile_map.into_iter() {
            match tile.buffer.take() {
                Some(buffer) => collected_buffers.push(buffer),
                None => {},
            }
        }

        return collected_buffers;
    }

    pub fn create_textures(&mut self, graphics_context: &NativeCompositingGraphicsContext) {
        for (_, ref mut tile) in self.tiles.iter_mut() {
            tile.create_texture(graphics_context);
        }
    }
}
<commit_msg>Avoid sending empty buffer requests<commit_after>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use geometry::{DevicePixel, LayerPixel};
use layers::{BufferRequest, ContentAge, LayerBuffer};
use platform::surface::{NativeCompositingGraphicsContext, NativeSurfaceMethods};
use texturegl::Texture;

use geom::length::Length;
use geom::matrix::{Matrix4, identity};
use geom::point::Point2D;
use geom::rect::{Rect, TypedRect};
use geom::size::{Size2D, TypedSize2D};
use std::collections::HashMap;
use std::collections::hash_map::{Occupied, Vacant};
use std::iter::range_inclusive;
use std::mem;
use std::num::Zero;

pub struct Tile {
    /// The buffer displayed by this tile.
    buffer: Option<Box<LayerBuffer>>,

    /// The content age of any pending buffer request to avoid re-requesting
    /// a buffer while waiting for it to come back from rendering.
    content_age_of_pending_buffer: Option<ContentAge>,

    /// A handle to the GPU texture.
    pub texture: Texture,

    /// The transformation applied to this tiles texture.
    pub transform: Matrix4<f32>,

    /// The tile boundaries in the parent layer coordinates.
    pub bounds: Option<TypedRect<LayerPixel,f32>>,
}

impl Tile {
    fn new() -> Tile {
        Tile {
            buffer: None,
            texture: Zero::zero(),
            transform: identity(),
            content_age_of_pending_buffer: None,
            bounds: None,
        }
    }

    fn should_use_new_buffer(&self, new_buffer: &Box<LayerBuffer>) -> bool {
        match self.buffer {
            Some(ref buffer) => new_buffer.content_age >= buffer.content_age,
            None => true,
        }
    }

    fn replace_buffer(&mut self, buffer: Box<LayerBuffer>) -> Option<Box<LayerBuffer>> {
        if !self.should_use_new_buffer(&buffer) {
            warn!("Layer received an old buffer.");
            return Some(buffer);
        }

        let old_buffer = self.buffer.take();
        self.buffer = Some(buffer);
        self.texture = Zero::zero(); // The old texture is bound to the old buffer.
        self.content_age_of_pending_buffer = None;
        return old_buffer;
    }

    fn create_texture(&mut self, graphics_context: &NativeCompositingGraphicsContext) {
        match self.buffer {
            Some(ref buffer) => {
                let size = Size2D(buffer.screen_pos.size.width as int,
                                  buffer.screen_pos.size.height as int);

                // If we already have a texture it should still be valid.
                if !self.texture.is_zero() {
                    return;
                }

                // Make a new texture and bind the LayerBuffer's surface to it.
                self.texture = Texture::new_with_buffer(buffer);
                debug!("Tile: binding to native surface {:d}",
                       buffer.native_surface.get_id() as int);
                buffer.native_surface.bind_to_texture(graphics_context, &self.texture, size);

                // Set the layer's transform.
                let rect = buffer.rect;
                let transform = identity().translate(rect.origin.x, rect.origin.y, 0.0);
                self.transform = transform.scale(rect.size.width, rect.size.height, 1.0);
                self.bounds = Some(Rect::from_untyped(&rect));
            },
            None => {},
        }
    }

    fn should_request_buffer(&self, content_age: ContentAge) -> bool {
        // Don't resend a request if our buffer's content age matches the current content age.
        match self.buffer {
            Some(ref buffer) => {
                if buffer.content_age >= content_age {
                    return false;
                }
            }
            None => {}
        }

        // Don't resend a request, if we already have one pending.
        match self.content_age_of_pending_buffer {
            Some(pending_content_age) => pending_content_age != content_age,
            None => true,
        }
    }
}

pub struct TileGrid {
    pub tiles: HashMap<Point2D<uint>, Tile>,

    /// The size of tiles in this grid in device pixels.
    tile_size: Length<DevicePixel, uint>,

    // Buffers that are currently unused.
    unused_buffers: Vec<Box<LayerBuffer>>,
}

pub fn rect_uint_as_rect_f32(rect: Rect<uint>) -> Rect<f32> {
    Rect(Point2D(rect.origin.x as f32, rect.origin.y as f32),
         Size2D(rect.size.width as f32, rect.size.height as f32))
}

impl TileGrid {
    pub fn new(tile_size: uint) -> TileGrid {
        TileGrid {
            tiles: HashMap::new(),
            tile_size: Length(tile_size),
            unused_buffers: Vec::new(),
        }
    }

    pub fn get_tile_index_range_for_rect(&self,
                                         rect: TypedRect<DevicePixel, f32>)
                                         -> (Point2D<uint>, Point2D<uint>) {
        let rect = rect.to_untyped();

        // NB: Even in the case of an empty rect, the semantics of Rust floating-point-to-integer
        // casts mean this will corrently round to zero.
        (Point2D((rect.origin.x / self.tile_size.get() as f32) as uint,
                 (rect.origin.y / self.tile_size.get() as f32) as uint),
         Point2D(((rect.origin.x + rect.size.width - 1.0) / self.tile_size.get() as f32) as uint,
                 ((rect.origin.y + rect.size.height - 1.0) / self.tile_size.get() as f32) as uint))
    }

    pub fn get_rect_for_tile_index(&self,
                                   tile_index: Point2D<uint>,
                                   current_layer_size: TypedSize2D<DevicePixel, f32>)
                                   -> TypedRect<DevicePixel, uint> {

        let origin = Point2D(self.tile_size.get() * tile_index.x,
                             self.tile_size.get() * tile_index.y);

        // Don't let tiles extend beyond the layer boundaries.
        let tile_size = self.tile_size.get() as f32;
        let size = Size2D(tile_size.min(current_layer_size.width.get() - origin.x as f32),
                          tile_size.min(current_layer_size.height.get() - origin.y as f32));

        // Round up to texture pixels.
        let size = Size2D(size.width.ceil() as uint, size.height.ceil() as uint);

        Rect::from_untyped(&Rect(origin, size))
    }

    pub fn take_unused_buffers(&mut self) -> Vec<Box<LayerBuffer>> {
        let mut unused_buffers = Vec::new();
        mem::swap(&mut unused_buffers, &mut self.unused_buffers);
        return unused_buffers;
    }

    pub fn add_unused_buffer(&mut self, buffer: Option<Box<LayerBuffer>>) {
        match buffer {
            Some(buffer) => self.unused_buffers.push(buffer),
            None => {},
        }
    }

    pub fn mark_tiles_outside_of_rect_as_unused(&mut self,
                                                rect: TypedRect<DevicePixel, f32>,
                                                current_layer_size: TypedSize2D<DevicePixel, f32>) {
        let mut tile_indexes_to_take = Vec::new();
        for tile_index in self.tiles.keys() {
            let tile_rect = self.get_rect_for_tile_index(*tile_index, current_layer_size);
            if !tile_rect.as_f32().intersects(&rect) {
                tile_indexes_to_take.push(tile_index.clone());
            }
        }

        for tile_index in tile_indexes_to_take.iter() {
            match self.tiles.remove(tile_index) {
                Some(ref mut tile) => self.add_unused_buffer(tile.buffer.take()),
                None => {},
            }
        }
    }

    pub fn get_buffer_request_for_tile(&mut self,
                                       tile_index: Point2D<uint>,
                                       current_layer_size: TypedSize2D<DevicePixel, f32>,
                                       current_content_age: ContentAge)
                                       -> Option<BufferRequest> {
        let tile_rect = self.get_rect_for_tile_index(tile_index, current_layer_size);
        let tile = match self.tiles.entry(tile_index) {
            Occupied(occupied) => occupied.into_mut(),
            Vacant(vacant) => vacant.set(Tile::new()),
        };

        if tile_rect.is_empty() {
            return None;
        }

        if !tile.should_request_buffer(current_content_age) {
            return None;
        }

        tile.content_age_of_pending_buffer = Some(current_content_age);

        return Some(BufferRequest::new(tile_rect.to_untyped(),
                                       tile_rect.as_f32().to_untyped(),
                                       current_content_age));
    }

    pub fn get_buffer_requests_in_rect(&mut self,
                                       rect_in_layer: TypedRect<DevicePixel, f32>,
                                       current_layer_size: TypedSize2D<DevicePixel, f32>,
                                       current_content_age: ContentAge)
                                       -> Vec<BufferRequest> {
        let mut buffer_requests = Vec::new();
        let (top_left_index, bottom_right_index) =
            self.get_tile_index_range_for_rect(rect_in_layer);

        for x in range_inclusive(top_left_index.x, bottom_right_index.x) {
            for y in range_inclusive(top_left_index.y, bottom_right_index.y) {
                match self.get_buffer_request_for_tile(Point2D(x, y),
                                                       current_layer_size,
                                                       current_content_age) {
                    Some(buffer) => buffer_requests.push(buffer),
                    None => {},
                }
            }
        }

        self.mark_tiles_outside_of_rect_as_unused(rect_in_layer, current_layer_size);
        return buffer_requests;
    }

    pub fn get_tile_index_for_point(&self, point: Point2D<uint>) -> Point2D<uint> {
        assert!(point.x % self.tile_size.get() == 0);
        assert!(point.y % self.tile_size.get() == 0);
        Point2D((point.x / self.tile_size.get()) as uint,
                (point.y / self.tile_size.get()) as uint)
    }

    pub fn add_buffer(&mut self, buffer: Box<LayerBuffer>) {
        let index = self.get_tile_index_for_point(buffer.screen_pos.origin.clone());
        if !self.tiles.contains_key(&index) {
            warn!("Received buffer for non-existent tile!");
            self.add_unused_buffer(Some(buffer));
            return;
        }

        let replaced_buffer = self.tiles.get_mut(&index).unwrap().replace_buffer(buffer);
        self.add_unused_buffer(replaced_buffer);
    }

    pub fn do_for_all_tiles(&self, f: |&Tile|) {
        for tile in self.tiles.values() {
            f(tile);
        }
    }

    pub fn collect_buffers(&mut self) -> Vec<Box<LayerBuffer>> {
        let mut collected_buffers = Vec::new();

        collected_buffers.extend(self.take_unused_buffers().into_iter());

        // We need to replace the HashMap since it cannot be used again after move_iter().
        let mut tile_map = HashMap::new();
        mem::swap(&mut tile_map, &mut self.tiles);

        for (_, mut tile) in tile_map.into_iter() {
            match tile.buffer.take() {
                Some(buffer) => collected_buffers.push(buffer),
                None => {},
            }
        }

        return collected_buffers;
    }

    pub fn create_textures(&mut self, graphics_context: &NativeCompositingGraphicsContext) {
        for (_, ref mut tile) in self.tiles.iter_mut() {
            tile.create_texture(graphics_context);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Élisabeth HENRY.
//
// This file is part of Caribon.
//
// Caribon is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caribon.  If not, see <http://www.gnu.org/licenses/>.

use super::Parser;
extern crate test;
use self::test::Bencher;

static TEST:&'static str = "This is some text string. We want to detect repetitions in it.
Why? Because repetitions are bad, very bad, so we want to highlight them. In order to have benches
that are not utterly worthless, it is required to have some variance in the text, so even if we are gonna repeat
this string quite a while it must be a bit longer, so I am writing senseless stuff. I guess this is long enough now ?
Well, alright, let's say it is. ";
static N_REPET:u32 = 100;

fn get_input() -> String {
    let mut s = TEST.to_string();
    for _ in 1..N_REPET {
        s = s + TEST;
    }

    s
}

#[bench]
fn bench_clone(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        ast.clone();
    });
}

#[bench]
fn bench_html(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(true);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_html2(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(false);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_terminal(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_terminal(&ast.clone());
    });
}

#[bench]
fn bench_markdown(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_markdown(&mut ast.clone());
    });
}

#[bench]
fn bench_tokenize(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    b.iter(|| {
        parser.tokenize(&s).unwrap();
    });
}

#[bench]
fn bench_local(b:&mut Bencher) {
    let s = get_input();
//    let s = include_str!("../README.md");
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_fuzzy(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_total(b:&mut Bencher) {
    let s = get_input();
    b.iter(|| {
        let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
        let mut ast = parser.tokenize(&s).unwrap();
        parser.detect_local(&mut ast, 1.9);
        parser.ast_to_html(&mut ast, true);
    });
}

#[bench]
fn bench_local_readme(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../README.md");
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_readme_fuzzy(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../README.md");
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_global(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_global(&mut ast.clone(), 0.01);
    });
}

<commit_msg>bench: corrected now invalid location to README.md<commit_after>// Copyright (C) 2015 Élisabeth HENRY.
//
// This file is part of Caribon.
//
// Caribon is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caribon.  If not, see <http://www.gnu.org/licenses/>.

use super::Parser;
extern crate test;
use self::test::Bencher;

static TEST:&'static str = "This is some text string. We want to detect repetitions in it.
Why? Because repetitions are bad, very bad, so we want to highlight them. In order to have benches
that are not utterly worthless, it is required to have some variance in the text, so even if we are gonna repeat
this string quite a while it must be a bit longer, so I am writing senseless stuff. I guess this is long enough now ?
Well, alright, let's say it is. ";
static N_REPET:u32 = 100;

fn get_input() -> String {
    let mut s = TEST.to_string();
    for _ in 1..N_REPET {
        s = s + TEST;
    }

    s
}

#[bench]
fn bench_clone(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        ast.clone();
    });
}

#[bench]
fn bench_html(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(true);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_html2(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(false);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_terminal(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_terminal(&ast.clone());
    });
}

#[bench]
fn bench_markdown(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_markdown(&mut ast.clone());
    });
}

#[bench]
fn bench_tokenize(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    b.iter(|| {
        parser.tokenize(&s).unwrap();
    });
}

#[bench]
fn bench_local(b:&mut Bencher) {
    let s = get_input();
//    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_fuzzy(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_total(b:&mut Bencher) {
    let s = get_input();
    b.iter(|| {
        let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
        let mut ast = parser.tokenize(&s).unwrap();
        parser.detect_local(&mut ast, 1.9);
        parser.ast_to_html(&mut ast, true);
    });
}

#[bench]
fn bench_local_readme(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_readme_fuzzy(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_global(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_global(&mut ast.clone(), 0.01);
    });
}

<|endoftext|>