<commit_before>//! Contains code relating to networking.

#[cfg(test)]
mod test;

use std::error::Error;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::io;
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpListener, ToSocketAddrs};
use std::thread;
use std::sync::{Arc, Mutex, RwLock};
use std::sync::mpsc::{Receiver, Sender, channel};

use bincode::serde::{DeserializeError, deserialize, serialize};
use bincode::SizeLimit;
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};

#[cfg(test)]
use test_util::Tattle;

/// Standard number to ensure network connections are syncronized and the same protocol is being used.
///
/// Reexported incase it is of use for something not-networking.
pub const NET_MAGIC_NUMBER: u32 = 0xCB011043; //0xcafebade + 0x25565, because programming references.

/// The maximum number of clients allowed to be connected at one time.
///
/// Eventually this should be removed and replaced with something configurable.
pub const MAX_CONNECTED_CLIENTS: usize = 30;

/// Holds all state for networking.
///
/// Has no notion of client or server. A client can listen, if that would ever be useful.
#[derive(Debug, Clone)]
pub struct Controller {
    pub raw: Arc<ControllerRaw>,
}

impl Controller {
    /// Contructs a new Controller, without any connection or listeners.
    ///
    /// This spawns a new thread to check multithreading channels.
    pub fn new_empty() -> Controller {
        let (tx, rx) = channel::<ControllerMessage>();
        let self_raw = Arc::from(ControllerRaw {
            connections: RwLock::new(Vec::new()),
            tx: Mutex::new(tx),
        });
        let self_raw_clone = self_raw.clone();
        thread::spawn(move || {
            check_controller_channel(rx, self_raw_clone);
        });
        Controller { raw: self_raw }
    }

    /// Adds a new listener and spins up a new thread to check it.
    ///
    /// The added listener can never be removed, due to the fact that the TcpListener lacks a shutdown method.
    ///
    /// # Errors
    /// * A call to `listener.try_clone()` failed for some reason.
    pub fn add_listener(&mut self, listener: TcpListener) -> Result<(), io::Error> {
        let listener_clone = try!(listener.try_clone());
        let tx_clone = self.raw.tx.lock().unwrap().clone();
        thread::spawn(|| {
            check_listener(listener_clone, tx_clone);
        });
        Ok(())
    }
}

/// Raw representation of a controller. Used internally for things.
#[derive(Debug)]
pub struct ControllerRaw {
    pub connections: RwLock<Vec<Connection>>,
    pub tx: Mutex<Sender<ControllerMessage>>,
}

#[derive(Debug)]
/// Represents a single connection without any notion of client or server.
///
/// It's own struct to allow for hooks and the like.
pub struct Connection {
    pub channel: Mutex<Sender<ConnectionMessage>>,
}

/// Sent in the case of an error that should be sent to the peer.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum NetworkError {
    /// If the versions mismatch sufficently to become incompatible with each other.
    VersionMismatch(String, String),
    /// If both peers have should_crash == false, then this error should be sent.
    ///
    /// Do note that this error should not be rewrapped into a reerror, since it would cause a loop.
    /// Instead, it should be logged and ignored, as the connection will be killed shortly after.
    ShouldCrashBothTrue,
}

impl Display for NetworkError {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            NetworkError::VersionMismatch(ref ver1, ref ver2) => {
                write!(fmt,
                       "VersionMismatch: The versions of the client and server attempting to \
                        connect mismatch. ver1: {}, ver2: {}",
                       ver1,
                       ver2)
            }
            NetworkError::ShouldCrashBothTrue => {
                write!(fmt,
                       "ShouldCrashBothTrue: Both peers have should_crash == false.")
            }
        }
    }
}

impl Error for NetworkError {
    fn description(&self) -> &str {
        match *self {
            NetworkError::VersionMismatch(_, _) => {
                "VersionMismatch: The versions of the client and server attempting to connect \
                 mismatch."
            }
            NetworkError::ShouldCrashBothTrue => {
                "ShouldCrashBothTrue: Both peers have should_crash == false."
            }
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            NetworkError::VersionMismatch(_, _) => None,
            NetworkError::ShouldCrashBothTrue => None,
        }
    }
}

/// Messages that can be sent between peers to facilitate vairous actions.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum NetworkPacket {
    /// Sent on connection to verify everything is in sync.
    Init {
        /// The curent version of the local game.
        ///
        /// Should be formatted according to Scematic Versioning.
        version: String,
        /// If the local game should crash when an error occours.
        ///
        /// Two peers should not have this as false, because should_crash will send the error to the
        /// remote peer and make it crash instead.
        /// This would cause a infinite loop if both were to do it.
        should_crash: bool,
    },
    /// An error that should crash the game and show an error to the user, but only on a client.
    Error(NetworkError),
}

/// Message sent to a connection to do vairous actions.
#[derive(Debug, Clone, Copy)]
pub enum ConnectionMessage {
    DoNothing,
}

/// Channel message sent to controller to dictate certain actions.
#[derive(Debug, Clone)]
pub enum ControllerMessage {
    /// Add a socket, spinning up a new thread in the process.
    AddSocket(Sender<ConnectionMessage>, String),
    /// Used for unit testing.
    #[cfg(test)]
    Test(Tattle),
}

/// Parses a str to a SocketAddr.
///
/// This is a function because while str implements ToSocketAddrs, it requires a good bit of boilerplate to use.
///
/// #Panics
/// * Calling with a localhost ip address: Use 127.0.0.1 instead.
/// * Calling with an ip address that resolves to more than 1 ip address.
pub fn ip(ip_addr: &str) -> SocketAddr {
    if ip_addr.starts_with("localhost") {
        panic!("because localhost can resolve to both 127.0.0.1, and the various IPV6 versions \
                of 127.0.0.1, it may not be used. please instead use 127.0.0.1");
    }
    let mut iter = ip_addr.to_socket_addrs().unwrap();
    let ip = iter.next().unwrap();
    if iter.next() != None {
        panic!("the given ip to net::ip() resolved to more than 1 SocketAddr");
    }
    ip
}

fn check_controller_channel(rx: Receiver<ControllerMessage>, controller: Arc<ControllerRaw>) {
    loop {
        match rx.recv() {
            Ok(msg) => {
                match msg {
                    ControllerMessage::AddSocket(tx_connection, _addr) => {
                        // TODO: Add a hook allowing intersepting the addr and denying the connection.
                        controller.connections
                                  .write()
                                  .unwrap()
                                  .push(Connection { channel: Mutex::new(tx_connection) });
                    }
                    #[cfg(test)]
                    ControllerMessage::Test(tattle) => {
                        tattle.call();
                    }
                }
            }
            Err(_err) => {
                debug!("Channel connected to controller disconnected");
                break;
            }
        }
    }
}

fn check_listener(listener: TcpListener, channel_: Sender<ControllerMessage>) {
    loop {
        match listener.accept() {
            Ok((stream, addr)) => {
                let (tx, rx) = channel();
                match channel_.send(ControllerMessage::AddSocket(tx, addr.to_string())) {
                    Ok(()) => {}
                    Err(_err) => {
                        debug!("listener {:?} stopped accepting because of channel close",
                               listener);
                        break;
                    }
                }
                let stream_clone = stream.try_clone().unwrap();
                thread::spawn(|| check_stream_send(rx, stream));
                thread::spawn(move || check_stream_recv(stream_clone, addr));
            }
            Err(err) => panic!("{}", err),  // TODO: Better handle errors.
        }
    }
}

fn check_stream_send<T: Write>(rx: Receiver<ConnectionMessage>, _stream: T) {
    loop {
        match rx.recv().unwrap() {
            ConnectionMessage::DoNothing => {}
        }
    }
}

fn check_stream_recv<T: Read>(mut stream: T, addr: SocketAddr) {
    'thread: loop {
        let mut header: [u8; 6] = [0; 6];
        'read_header: loop {
            let maybe_err = (&mut stream).take(6).read_exact(&mut header);
            if let Err(err) = maybe_err {
                match err.kind() {
                    io::ErrorKind::ConnectionReset | io::ErrorKind::ConnectionAborted => {
                        info!("Connection with ip {} reset or aborted.", addr);
                        break 'thread;
                    }
                    io::ErrorKind::Interrupted => continue 'read_header,
                    _ => {
                        panic!("error not accounted for occoured on socket with address {}. \
                                display: {}",
                               addr,
                               err)
                    }
                }
            }
            break;
        }
        let len = get_packet_length(header).unwrap();
        let mut bytes: Vec<u8> = Vec::new();
        'read_data: loop {
            let maybe_error = (&mut stream).take(len as u64).read_to_end(&mut bytes);
            if let Err(err) = maybe_error {
                match err.kind() {
                    io::ErrorKind::ConnectionReset | io::ErrorKind::ConnectionAborted => {
                        info!("Connection with ip {} reset or aborted.", addr);
                        break 'thread;
                    }
                    io::ErrorKind::Interrupted => continue 'read_data,
                    _ => {
                        panic!("error not accounted for occoured on socket with address {}. \
                                display: {}",
                               addr,
                               err)
                    }
                }
            }
            break;
        }
        let message = deserialize_packet(&bytes).unwrap();
        handle_message(message);
    }
}

fn deserialize_packet(to_de: &[u8]) -> Result<NetworkPacket, DeserializeError> {
    deserialize(to_de)
}

/// Returns the length of a given packet, or a None if the first four bytes do not match NET_MAGIC_NUMBER.
fn get_packet_length(to_ln: [u8; 6]) -> Option<u16> {
    let (first_four, next_two) = to_ln.split_at(4);
    let should_be_magic_num = LittleEndian::read_u32(&first_four);
    if should_be_magic_num != NET_MAGIC_NUMBER {
        return None;
    }
    let length = LittleEndian::read_u16(&next_two);
    Some(length)
}

fn handle_message(_message: NetworkPacket) {
    unimplemented!()
}

#[allow(unused)]
fn seralize_packet(to_ser: &NetworkPacket) -> Vec<u8> {
    let mut result: Vec<u8> = Vec::new();
    result.write_u32::<LittleEndian>(NET_MAGIC_NUMBER).unwrap();   // No possible errors here.
    // The NET_MAGIC_NUMBER is used before every packet, so incase the stream is desynced for whatever reason, the game doesn't just read arbratrary data and crash badly.
    // Instead, it can either recover somehow, by disconnecting and reconnecting, or just erroring gracefully.
    let mut encoded = serialize(to_ser, SizeLimit::Infinite).unwrap();
    // Since the size limit is infinite and i'm not encoding to a stream, there is no error and I can safely unwrap();
    result.write_u16::<LittleEndian>(encoded.len() as u16).unwrap();
    result.append(&mut encoded);
    result
}
<commit_msg>Rename the channel argument in net::check_listener to controller_tx<commit_after>//! Contains code relating to networking.

#[cfg(test)]
mod test;

use std::error::Error;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::io;
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpListener, ToSocketAddrs};
use std::thread;
use std::sync::{Arc, Mutex, RwLock};
use std::sync::mpsc::{Receiver, Sender, channel};

use bincode::serde::{DeserializeError, deserialize, serialize};
use bincode::SizeLimit;
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};

#[cfg(test)]
use test_util::Tattle;

/// Standard number to ensure network connections are syncronized and the same protocol is being used.
///
/// Reexported incase it is of use for something not-networking.
pub const NET_MAGIC_NUMBER: u32 = 0xCB011043; //0xcafebade + 0x25565, because programming references.

/// The maximum number of clients allowed to be connected at one time.
///
/// Eventually this should be removed and replaced with something configurable.
pub const MAX_CONNECTED_CLIENTS: usize = 30;

/// Holds all state for networking.
///
/// Has no notion of client or server. A client can listen, if that would ever be useful.
#[derive(Debug, Clone)]
pub struct Controller {
    pub raw: Arc<ControllerRaw>,
}

impl Controller {
    /// Contructs a new Controller, without any connection or listeners.
    ///
    /// This spawns a new thread to check multithreading channels.
    pub fn new_empty() -> Controller {
        let (tx, rx) = channel::<ControllerMessage>();
        let self_raw = Arc::from(ControllerRaw {
            connections: RwLock::new(Vec::new()),
            tx: Mutex::new(tx),
        });
        let self_raw_clone = self_raw.clone();
        thread::spawn(move || {
            check_controller_channel(rx, self_raw_clone);
        });
        Controller { raw: self_raw }
    }

    /// Adds a new listener and spins up a new thread to check it.
    ///
    /// The added listener can never be removed, due to the fact that the TcpListener lacks a shutdown method.
    ///
    /// # Errors
    /// * A call to `listener.try_clone()` failed for some reason.
    pub fn add_listener(&mut self, listener: TcpListener) -> Result<(), io::Error> {
        let listener_clone = try!(listener.try_clone());
        let tx_clone = self.raw.tx.lock().unwrap().clone();
        thread::spawn(|| {
            check_listener(listener_clone, tx_clone);
        });
        Ok(())
    }
}

/// Raw representation of a controller. Used internally for things.
#[derive(Debug)]
pub struct ControllerRaw {
    pub connections: RwLock<Vec<Connection>>,
    pub tx: Mutex<Sender<ControllerMessage>>,
}

#[derive(Debug)]
/// Represents a single connection without any notion of client or server.
///
/// It's own struct to allow for hooks and the like.
pub struct Connection {
    pub channel: Mutex<Sender<ConnectionMessage>>,
}

/// Sent in the case of an error that should be sent to the peer.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum NetworkError {
    /// If the versions mismatch sufficently to become incompatible with each other.
    VersionMismatch(String, String),
    /// If both peers have should_crash == false, then this error should be sent.
    ///
    /// Do note that this error should not be rewrapped into a reerror, since it would cause a loop.
    /// Instead, it should be logged and ignored, as the connection will be killed shortly after.
    ShouldCrashBothTrue,
}

impl Display for NetworkError {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            NetworkError::VersionMismatch(ref ver1, ref ver2) => {
                write!(fmt,
                       "VersionMismatch: The versions of the client and server attempting to \
                        connect mismatch. ver1: {}, ver2: {}",
                       ver1,
                       ver2)
            }
            NetworkError::ShouldCrashBothTrue => {
                write!(fmt,
                       "ShouldCrashBothTrue: Both peers have should_crash == false.")
            }
        }
    }
}

impl Error for NetworkError {
    fn description(&self) -> &str {
        match *self {
            NetworkError::VersionMismatch(_, _) => {
                "VersionMismatch: The versions of the client and server attempting to connect \
                 mismatch."
            }
            NetworkError::ShouldCrashBothTrue => {
                "ShouldCrashBothTrue: Both peers have should_crash == false."
            }
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            NetworkError::VersionMismatch(_, _) => None,
            NetworkError::ShouldCrashBothTrue => None,
        }
    }
}

/// Messages that can be sent between peers to facilitate vairous actions.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum NetworkPacket {
    /// Sent on connection to verify everything is in sync.
    Init {
        /// The curent version of the local game.
        ///
        /// Should be formatted according to Scematic Versioning.
        version: String,
        /// If the local game should crash when an error occours.
        ///
        /// Two peers should not have this as false, because should_crash will send the error to the
        /// remote peer and make it crash instead.
        /// This would cause a infinite loop if both were to do it.
        should_crash: bool,
    },
    /// An error that should crash the game and show an error to the user, but only on a client.
    Error(NetworkError),
}

/// Message sent to a connection to do vairous actions.
#[derive(Debug, Clone, Copy)]
pub enum ConnectionMessage {
    DoNothing,
}

/// Channel message sent to controller to dictate certain actions.
#[derive(Debug, Clone)]
pub enum ControllerMessage {
    /// Add a socket, spinning up a new thread in the process.
    AddSocket(Sender<ConnectionMessage>, String),
    /// Used for unit testing.
    #[cfg(test)]
    Test(Tattle),
}

/// Parses a str to a SocketAddr.
///
/// This is a function because while str implements ToSocketAddrs, it requires a good bit of boilerplate to use.
///
/// #Panics
/// * Calling with a localhost ip address: Use 127.0.0.1 instead.
/// * Calling with an ip address that resolves to more than 1 ip address.
pub fn ip(ip_addr: &str) -> SocketAddr {
    if ip_addr.starts_with("localhost") {
        panic!("because localhost can resolve to both 127.0.0.1, and the various IPV6 versions \
                of 127.0.0.1, it may not be used. please instead use 127.0.0.1");
    }
    let mut iter = ip_addr.to_socket_addrs().unwrap();
    let ip = iter.next().unwrap();
    if iter.next() != None {
        panic!("the given ip to net::ip() resolved to more than 1 SocketAddr");
    }
    ip
}

fn check_controller_channel(rx: Receiver<ControllerMessage>, controller: Arc<ControllerRaw>) {
    loop {
        match rx.recv() {
            Ok(msg) => {
                match msg {
                    ControllerMessage::AddSocket(tx_connection, _addr) => {
                        // TODO: Add a hook allowing intersepting the addr and denying the connection.
                        controller.connections
                                  .write()
                                  .unwrap()
                                  .push(Connection { channel: Mutex::new(tx_connection) });
                    }
                    #[cfg(test)]
                    ControllerMessage::Test(tattle) => {
                        tattle.call();
                    }
                }
            }
            Err(_err) => {
                debug!("Channel connected to controller disconnected");
                break;
            }
        }
    }
}

fn check_listener(listener: TcpListener, controller_tx: Sender<ControllerMessage>) {
    loop {
        match listener.accept() {
            Ok((stream, addr)) => {
                let (tx, rx) = channel();
                match controller_tx.send(ControllerMessage::AddSocket(tx, addr.to_string())) {
                    Ok(()) => {}
                    Err(_err) => {
                        debug!("listener {:?} stopped accepting because of channel close",
                               listener);
                        break;
                    }
                }
                let stream_clone = stream.try_clone().unwrap();
                thread::spawn(|| check_stream_send(rx, stream));
                thread::spawn(move || check_stream_recv(stream_clone, addr));
            }
            Err(err) => panic!("{}", err),  // TODO: Better handle errors.
        }
    }
}

fn check_stream_send<T: Write>(rx: Receiver<ConnectionMessage>, _stream: T) {
    loop {
        match rx.recv().unwrap() {
            ConnectionMessage::DoNothing => {}
        }
    }
}

fn check_stream_recv<T: Read>(mut stream: T, addr: SocketAddr) {
    'thread: loop {
        let mut header: [u8; 6] = [0; 6];
        'read_header: loop {
            let maybe_err = (&mut stream).take(6).read_exact(&mut header);
            if let Err(err) = maybe_err {
                match err.kind() {
                    io::ErrorKind::ConnectionReset | io::ErrorKind::ConnectionAborted => {
                        info!("Connection with ip {} reset or aborted.", addr);
                        break 'thread;
                    }
                    io::ErrorKind::Interrupted => continue 'read_header,
                    _ => {
                        panic!("error not accounted for occoured on socket with address {}. \
                                display: {}",
                               addr,
                               err)
                    }
                }
            }
            break;
        }
        let len = get_packet_length(header).unwrap();
        let mut bytes: Vec<u8> = Vec::new();
        'read_data: loop {
            let maybe_error = (&mut stream).take(len as u64).read_to_end(&mut bytes);
            if let Err(err) = maybe_error {
                match err.kind() {
                    io::ErrorKind::ConnectionReset | io::ErrorKind::ConnectionAborted => {
                        info!("Connection with ip {} reset or aborted.", addr);
                        break 'thread;
                    }
                    io::ErrorKind::Interrupted => continue 'read_data,
                    _ => {
                        panic!("error not accounted for occoured on socket with address {}. \
                                display: {}",
                               addr,
                               err)
                    }
                }
            }
            break;
        }
        let message = deserialize_packet(&bytes).unwrap();
        handle_message(message);
    }
}

fn deserialize_packet(to_de: &[u8]) -> Result<NetworkPacket, DeserializeError> {
    deserialize(to_de)
}

/// Returns the length of a given packet, or a None if the first four bytes do not match NET_MAGIC_NUMBER.
fn get_packet_length(to_ln: [u8; 6]) -> Option<u16> {
    let (first_four, next_two) = to_ln.split_at(4);
    let should_be_magic_num = LittleEndian::read_u32(&first_four);
    if should_be_magic_num != NET_MAGIC_NUMBER {
        return None;
    }
    let length = LittleEndian::read_u16(&next_two);
    Some(length)
}

fn handle_message(_message: NetworkPacket) {
    unimplemented!()
}

#[allow(unused)]
fn seralize_packet(to_ser: &NetworkPacket) -> Vec<u8> {
    let mut result: Vec<u8> = Vec::new();
    result.write_u32::<LittleEndian>(NET_MAGIC_NUMBER).unwrap();   // No possible errors here.
    // The NET_MAGIC_NUMBER is used before every packet, so incase the stream is desynced for whatever reason, the game doesn't just read arbratrary data and crash badly.
    // Instead, it can either recover somehow, by disconnecting and reconnecting, or just erroring gracefully.
    let mut encoded = serialize(to_ser, SizeLimit::Infinite).unwrap();
    // Since the size limit is infinite and i'm not encoding to a stream, there is no error and I can safely unwrap();
    result.write_u16::<LittleEndian>(encoded.len() as u16).unwrap();
    result.append(&mut encoded);
    result
}
<|endoftext|>


<commit_before>use super::innovation::{Innovation, InnovationContainer};
use super::traits::{Distance, Genotype};
use super::alignment::Alignment;
use std::cmp;
use super::crossover::Crossover;
use rand::Rng;
use fixedbitset::FixedBitSet;
use std::collections::BTreeMap;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum NodeType {
    Input,
    Output,
    Hidden,
}

impl Default for NodeType {
    fn default() -> Self {
        NodeType::Hidden
    }
}

#[derive(Debug, Clone)]
pub struct NodeGene {
    pub node_type: NodeType,
}

// To avoid node collisions we use Innovation numbers instead of node
// ids.
#[derive(Debug, Clone)]
pub struct LinkGene {
    // This points to the NodeGene of that innovation
    pub source_node_gene: Innovation,
    // This points to the NodeGene of that innovation
    pub target_node_gene: Innovation,
    pub weight: f64,
    pub active: bool,
}

impl LinkGene {
    pub fn disable(&mut self) {
        assert!(self.active);
        self.active = false;
    }
}

#[derive(Debug, Clone)]
pub struct NetworkGenome {
    pub link_genes: InnovationContainer<LinkGene>,
    pub node_genes: InnovationContainer<NodeGene>,
}

#[derive(Debug, Clone)]
struct AdjMatrix {
    n: usize,
    m: FixedBitSet,
}

impl AdjMatrix {
    fn new(n: usize) -> AdjMatrix {
        AdjMatrix {
            n: n,
            m: FixedBitSet::with_capacity(n * n),
        }
    }

    fn set(&mut self, i: usize, j: usize) {
        self.m.insert(i * self.n + j);
    }

    fn contains(&self, i: usize, j: usize) -> bool {
        self.m.contains(i * self.n + j)
    }

    /// This is O(n**4) in worst case.
    fn transitive_closure(mut self) -> AdjMatrix {
        loop {
            let mut counts = 0;
            for i in 0..self.n {
                for j in 0..self.n {
                    if self.contains(i, j) {
                        // look column for j
                        for k in 0..self.n {
                            if self.contains(j, k) {
                                if !self.contains(i, k) {
                                    self.set(i, k);
                                    counts += 1;
                                }
                            }
                        }
                    }
                }
            }
            if counts == 0 {
                break;
            }
        }
        self
    }

    fn unconnected_pairs_no_cycle(&self) -> Vec<(usize, usize)> {
        let mut pairs = Vec::new();
        for i in 0..self.n {
            for j in 0..self.n {
                if i != j {
                    if !(self.contains(i, j) || self.contains(j, i)) {
                        // make sure we don't introduce a cycle
                        pairs.push((i, j));
                    }
                }
            }
        }
        pairs
    }
}

impl NetworkGenome {
    // Uses the crossover method C to recombine left and right.
    pub fn crossover<R: Rng, C: Crossover>(left: &Self, right: &Self, c: &C, rng: &mut R) -> Self {
        let new_link_genes = c.crossover(&left.link_genes, &right.link_genes, rng);
        let mut new_node_genes = c.crossover(&left.node_genes, &right.node_genes, rng);

        // Additionally make sure that all link genes have a correspondant node gene.
        // We do this also for disabled links!
        for link in new_link_genes.map.values() {
            new_node_genes.insert_from_either_or(link.source_node_gene,
                                                 &left.node_genes,
                                                 &right.node_genes);
            new_node_genes.insert_from_either_or(link.target_node_gene,
                                                 &left.node_genes,
                                                 &right.node_genes);
        }

        NetworkGenome {
            link_genes: new_link_genes,
            node_genes: new_node_genes,
        }
    }

    /// Constructs the adjacency matrix from the genome.
    fn adjacency_matrix(&self) -> (AdjMatrix, Vec<Option<Innovation>>) {
        // maps the node innovation to the index in the adjacency matrix
        let mut map_to_indices: BTreeMap<Innovation, usize> = BTreeMap::new();

        for &node_innov in self.node_genes.map.keys() {
            let next_idx = map_to_indices.len();
            let source_idx = *(map_to_indices.entry(node_innov).or_insert(next_idx));
        }

        for link in self.link_genes.map.values() {
            if link.active {
                let next_idx = map_to_indices.len();
                let source_idx = *(map_to_indices.entry(link.source_node_gene).or_insert(next_idx));
                let next_idx = map_to_indices.len();
                let target_idx = *(map_to_indices.entry(link.target_node_gene).or_insert(next_idx));
            }
        }
        let n = map_to_indices.len();
        // XXX: Use node_genes count to create the adj_matrix in one step.
        let mut adj_matrix = AdjMatrix::new(n);
        for link in self.link_genes.map.values() {
            if link.active {
                let source_idx = *map_to_indices.get(&link.source_node_gene).unwrap();
                let target_idx = *map_to_indices.get(&link.target_node_gene).unwrap();
                adj_matrix.set(source_idx, target_idx);
            }
        }
        // construct a reverse map
        let mut rev_map: Vec<Option<Innovation>> = (0..n).map(|_| None).collect();
        for (&k, &v) in map_to_indices.iter() {
            rev_map[v] = Some(k);
        }
        assert!(rev_map.iter().all(Option::is_some));

        (adj_matrix, rev_map)
    }

    /// Returns a random link gene innovation which is active. Or None if no such exists.
    pub fn find_random_active_link_gene<R: Rng>(&self, rng: &mut R) -> Option<Innovation> {
        let mut all_active_link_innovations = Vec::with_capacity(self.link_genes.len());
        for (&innov, link) in self.link_genes.map.iter() {
            if link.active {
                all_active_link_innovations.push(innov);
            }
        }
        rng.choose(&all_active_link_innovations).map(|&i| i)
    }

    /// Returns two node innvovations which are not yet connected and which does not
    /// create a cycle. Return `None` if no such connection exists.
    pub fn find_unconnected_pair<R: Rng>(&self, rng: &mut R) -> Option<(Innovation, Innovation)> {
        // Construct binary adjacency matrix
        let (adj_matrix, rev_map) = self.adjacency_matrix();

        // generate the transitive closure.
        let transitive_closure = adj_matrix.transitive_closure();

        // Construct an array of all currently unconnected nodes.
        let unconnected = transitive_closure.unconnected_pairs_no_cycle();

        // Out of all unconnected pairs, choose a random one.
        rng.choose(&unconnected).map(|&(src, target)| {
            // reverse map src and target to the node innovation
            let src_innovation = rev_map[src].unwrap();
            let target_innovation = rev_map[target].unwrap();

            (src_innovation, target_innovation)
        })
    }
}

impl Genotype for NetworkGenome {}

struct LinkGeneWeightDistance;

impl Distance<LinkGene> for LinkGeneWeightDistance {
    fn distance(&self, a: &LinkGene, b: &LinkGene) -> f64 {
        a.weight - b.weight
    }
}

pub struct LinkGeneListDistance {
    pub excess: f64,
    pub disjoint: f64,
    pub weight: f64,
}

impl Distance<InnovationContainer<LinkGene>> for LinkGeneListDistance {
    fn distance(&self,
                genes_left: &InnovationContainer<LinkGene>,
                genes_right: &InnovationContainer<LinkGene>)
                -> f64 {
        let max_len = cmp::max(genes_left.len(), genes_right.len());
        if max_len == 0 {
            return 0.0;
        }

        let mut matching = 0;
        let mut disjoint = 0;
        let mut excess = 0;
        let mut weight_dist = 0.0;

        genes_left.align(genes_right,
                         &mut |_, alignment| {
                             match alignment {
                                 Alignment::Match(gene_left, gene_right) => {
                                     matching += 1;
                                     weight_dist += LinkGeneWeightDistance.distance(gene_left,
                                                                                gene_right)
                                                                          .abs();
                                 }
                                 Alignment::DisjointLeft(_) | Alignment::DisjointRight(_) => {
                                     disjoint += 1;
                                 }
                                 Alignment::ExcessLeft(_) | Alignment::ExcessRight(_) => {
                                     excess += 1;
                                 }
                             }
                         });

        assert!(2 * matching + disjoint + excess == genes_left.len() + genes_right.len());

        self.excess * (excess as f64) / (max_len as f64) +
        self.disjoint * (disjoint as f64) / (max_len as f64) +
        self.weight *
        if matching > 0 {
            weight_dist / (matching as f64)
        } else {
            0.0
        }
    }
}

pub struct NetworkGenomeDistance {
    pub l: LinkGeneListDistance,
}

impl Distance<NetworkGenome> for NetworkGenomeDistance {
    fn distance(&self, genome_left: &NetworkGenome, genome_right: &NetworkGenome) -> f64 {
        self.l.distance(&genome_left.link_genes, &genome_right.link_genes)
    }
}
<commit_msg>Simplify the adjacencey_matrix creation.<commit_after>use super::innovation::{Innovation, InnovationContainer};
use super::traits::{Distance, Genotype};
use super::alignment::Alignment;
use std::cmp;
use super::crossover::Crossover;
use rand::Rng;
use fixedbitset::FixedBitSet;
use std::collections::BTreeMap;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum NodeType {
    Input,
    Output,
    Hidden,
}

impl Default for NodeType {
    fn default() -> Self {
        NodeType::Hidden
    }
}

#[derive(Debug, Clone)]
pub struct NodeGene {
    pub node_type: NodeType,
}

// To avoid node collisions we use Innovation numbers instead of node
// ids.
#[derive(Debug, Clone)]
pub struct LinkGene {
    // This points to the NodeGene of that innovation
    pub source_node_gene: Innovation,
    // This points to the NodeGene of that innovation
    pub target_node_gene: Innovation,
    pub weight: f64,
    pub active: bool,
}

impl LinkGene {
    pub fn disable(&mut self) {
        assert!(self.active);
        self.active = false;
    }
}

#[derive(Debug, Clone)]
pub struct NetworkGenome {
    pub link_genes: InnovationContainer<LinkGene>,
    pub node_genes: InnovationContainer<NodeGene>,
}

#[derive(Debug, Clone)]
struct AdjMatrix {
    n: usize,
    m: FixedBitSet,
}

impl AdjMatrix {
    fn new(n: usize) -> AdjMatrix {
        AdjMatrix {
            n: n,
            m: FixedBitSet::with_capacity(n * n),
        }
    }

    fn set(&mut self, i: usize, j: usize) {
        self.m.insert(i * self.n + j);
    }

    fn contains(&self, i: usize, j: usize) -> bool {
        self.m.contains(i * self.n + j)
    }

    /// This is O(n**4) in worst case.
    fn transitive_closure(mut self) -> AdjMatrix {
        loop {
            let mut counts = 0;
            for i in 0..self.n {
                for j in 0..self.n {
                    if self.contains(i, j) {
                        // look column for j
                        for k in 0..self.n {
                            if self.contains(j, k) {
                                if !self.contains(i, k) {
                                    self.set(i, k);
                                    counts += 1;
                                }
                            }
                        }
                    }
                }
            }
            if counts == 0 {
                break;
            }
        }
        self
    }

    fn unconnected_pairs_no_cycle(&self) -> Vec<(usize, usize)> {
        let mut pairs = Vec::new();
        for i in 0..self.n {
            for j in 0..self.n {
                if i != j {
                    if !(self.contains(i, j) || self.contains(j, i)) {
                        // make sure we don't introduce a cycle
                        pairs.push((i, j));
                    }
                }
            }
        }
        pairs
    }
}

impl NetworkGenome {
    // Uses the crossover method C to recombine left and right.
    pub fn crossover<R: Rng, C: Crossover>(left: &Self, right: &Self, c: &C, rng: &mut R) -> Self {
        let new_link_genes = c.crossover(&left.link_genes, &right.link_genes, rng);
        let mut new_node_genes = c.crossover(&left.node_genes, &right.node_genes, rng);

        // Additionally make sure that all link genes have a correspondant node gene.
        // We do this also for disabled links!
        for link in new_link_genes.map.values() {
            new_node_genes.insert_from_either_or(link.source_node_gene,
                                                 &left.node_genes,
                                                 &right.node_genes);
            new_node_genes.insert_from_either_or(link.target_node_gene,
                                                 &left.node_genes,
                                                 &right.node_genes);
        }

        NetworkGenome {
            link_genes: new_link_genes,
            node_genes: new_node_genes,
        }
    }

    /// Constructs the adjacency matrix from the genome.
    fn adjacency_matrix(&self) -> (AdjMatrix, Vec<Innovation>) {
        // map the node innovation to the index in the adjacency matrix
        let mut map_to_indices: BTreeMap<Innovation, usize> = BTreeMap::new();
        // and the reverse map from index to Innovation
        let mut rev_map: Vec<Innovation> = Vec::new();

        for &node_innov in self.node_genes.map.keys() {
            let next_idx = rev_map.len();
            rev_map.push(node_innov);
            let prev = map_to_indices.insert(node_innov, next_idx);
            assert!(prev.is_none());
        }

        assert!(rev_map.len() == map_to_indices.len());

        // //The code below is not neccessary, because our genomes contain all node innovation
        // //that occur in the link genes.
        //
        // for link in self.link_genes.map.values() {
        // if link.active {
        // let next_idx = map_to_indices.len();
        // let source_idx = *(map_to_indices.entry(link.source_node_gene).or_insert(next_idx));
        // let next_idx = map_to_indices.len();
        // let target_idx = *(map_to_indices.entry(link.target_node_gene).or_insert(next_idx));
        // }
        // }

        let n = map_to_indices.len();
        let mut adj_matrix = AdjMatrix::new(n);
        for link in self.link_genes.map.values() {
            if link.active {
                adj_matrix.set(map_to_indices[&link.source_node_gene],
                               map_to_indices[&link.target_node_gene]);
            }
        }

        (adj_matrix, rev_map)
    }

    /// Returns a random link gene innovation which is active. Or None if no such exists.
    pub fn find_random_active_link_gene<R: Rng>(&self, rng: &mut R) -> Option<Innovation> {
        let mut all_active_link_innovations = Vec::with_capacity(self.link_genes.len());
        for (&innov, link) in self.link_genes.map.iter() {
            if link.active {
                all_active_link_innovations.push(innov);
            }
        }
        rng.choose(&all_active_link_innovations).map(|&i| i)
    }

    /// Returns two node innvovations which are not yet connected and which does not
    /// create a cycle. Return `None` if no such connection exists.
    pub fn find_unconnected_pair<R: Rng>(&self, rng: &mut R) -> Option<(Innovation, Innovation)> {
        // Construct binary adjacency matrix
        let (adj_matrix, rev_map) = self.adjacency_matrix();

        // Construct an array of all currently unconnected nodes.
        let unconnected = adj_matrix.transitive_closure().unconnected_pairs_no_cycle();

        // Out of all unconnected pairs, choose a random one.
        rng.choose(&unconnected).map(|&(source, target)| {
            // reverse map src and target to the node innovation
            (rev_map[source], rev_map[target])
        })
    }
}

impl Genotype for NetworkGenome {}

struct LinkGeneWeightDistance;

impl Distance<LinkGene> for LinkGeneWeightDistance {
    fn distance(&self, a: &LinkGene, b: &LinkGene) -> f64 {
        a.weight - b.weight
    }
}

pub struct LinkGeneListDistance {
    pub excess: f64,
    pub disjoint: f64,
    pub weight: f64,
}

impl Distance<InnovationContainer<LinkGene>> for LinkGeneListDistance {
    fn distance(&self,
                genes_left: &InnovationContainer<LinkGene>,
                genes_right: &InnovationContainer<LinkGene>)
                -> f64 {
        let max_len = cmp::max(genes_left.len(), genes_right.len());
        if max_len == 0 {
            return 0.0;
        }

        let mut matching = 0;
        let mut disjoint = 0;
        let mut excess = 0;
        let mut weight_dist = 0.0;

        genes_left.align(genes_right,
                         &mut |_, alignment| {
                             match alignment {
                                 Alignment::Match(gene_left, gene_right) => {
                                     matching += 1;
                                     weight_dist += LinkGeneWeightDistance.distance(gene_left,
                                                                                gene_right)
                                                                          .abs();
                                 }
                                 Alignment::DisjointLeft(_) | Alignment::DisjointRight(_) => {
                                     disjoint += 1;
                                 }
                                 Alignment::ExcessLeft(_) | Alignment::ExcessRight(_) => {
                                     excess += 1;
                                 }
                             }
                         });

        assert!(2 * matching + disjoint + excess == genes_left.len() + genes_right.len());

        self.excess * (excess as f64) / (max_len as f64) +
        self.disjoint * (disjoint as f64) / (max_len as f64) +
        self.weight *
        if matching > 0 {
            weight_dist / (matching as f64)
        } else {
            0.0
        }
    }
}

pub struct NetworkGenomeDistance {
    pub l: LinkGeneListDistance,
}

impl Distance<NetworkGenome> for NetworkGenomeDistance {
    fn distance(&self, genome_left: &NetworkGenome, genome_right: &NetworkGenome) -> f64 {
        self.l.distance(&genome_left.link_genes, &genome_right.link_genes)
    }
}
<|endoftext|>


<commit_before>use std::default;
use std::io::Result;

use bytes::{
    Buf,
    BufMut,
    LittleEndian,
    Take,
};

use field::{Field, Type};
use encoding::*;

/// A numeric scalar Protobuf field type.
///
/// The `E` type parameter allows `Numeric` to be implemented multiple times for a
/// single type, in order to provide multiple encoding and decoding options for
/// a single Rust type. For instance, the Protobuf `fixed32` and `uint32` types
/// both correspond to the Rust `u32` type, so `u32` has two impls of `Numeric`
/// with different types for `E`, which correspond to `fixed32` and `uint32`.
/// Repeated numeric fields can optionally use packed encoding, which is
/// controlled using the `Packed` type.
pub trait Numeric<E=Default> : default::Default {
    /// Encodes the scalar field to the buffer, without a key.
    /// The buffer must have enough remaining space to hold the encoded key and field.
    fn encode<B>(self, buf: &mut B) where B: BufMut;

    /// Decodes an instance of the field from the buffer.
    fn decode<B>(buf: &mut B) -> Result<Self> where B: Buf;

    /// Returns the encoded length of the field, without a key.
    fn encoded_len(self) -> usize;

    /// Returns the wire type of the numeric scalar field.
    fn wire_type() -> WireType;
}

// Provides Field, Type, and repeated Field impls for numeric types.
macro_rules! numeric_field {
    ($ty: ty) => { numeric_field!($ty, Default); };
    ($ty: ty, $e: ty) => {
        impl Field<$e> for $ty {
            #[inline]
            fn encode<B>(&self, tag: u32, buf: &mut B) where B: BufMut {
                encode_key(tag, <$ty as Numeric<$e>>::wire_type(), buf);
                <$ty as Numeric<$e>>::encode(*self, buf);
            }
            #[inline]
            fn merge<B>(&mut self, _tag: u32, wire_type: WireType, buf: &mut Take<B>) -> Result<()> where B: Buf {
                check_wire_type(<$ty as Numeric<$e>>::wire_type(), wire_type)?;
                *self = <$ty as Numeric<$e>>::decode(buf)?;
                Ok(())
            }
            #[inline]
            fn encoded_len(&self, tag: u32) -> usize { key_len(tag) + <$ty as Numeric<$e>>::encoded_len(*self) }
        }
        impl Type<$e> for $ty {
            fn empty() -> $ty {
                ::std::default::Default::default()
            }
        }

        impl Field<$e> for Vec<$ty> {
            #[inline]
            fn encode<B>(&self, tag: u32, buf: &mut B) where B: BufMut {
                for value in self {
                    <$ty as Field<$e>>::encode(value, tag, buf);
                }
            }
            #[inline]
            fn merge<B>(&mut self, tag: u32, wire_type: WireType, buf: &mut Take<B>) -> Result<()> where B: Buf {
                if wire_type == WireType::LengthDelimited {
                    // Packed repeated encoding.
                    let len = decode_varint(buf)?;
                    if len > buf.remaining() as u64 {
                        return Err(invalid_data("failed to decode packed repeated field: buffer underflow"));
                    }

                    let limit = buf.limit();
                    buf.set_limit(len as usize);
                    while buf.has_remaining() {
                        self.push(<$ty as Numeric<$e>>::decode(buf)?);
                    }
                    buf.set_limit(limit - len as usize);
                } else {
                    // Default repeated encoding.
                    let mut value = default::Default::default();
                    <$ty as Field<$e>>::merge(&mut value, tag, wire_type, buf)?;
                    self.push(value);
                }
                Ok(())
            }
            #[inline]
            fn encoded_len(&self, tag: u32) -> usize {
                self.iter().map(|f| <$ty as Field<$e>>::encoded_len(f, tag)).sum()
            }
        }

        impl Field<(Packed, $e)> for Vec<$ty> {
            #[inline]
            fn encode<B>(&self, tag: u32, buf: &mut B) where B: BufMut {
                if self.is_empty() { return; }
                encode_key(tag, WireType::LengthDelimited, buf);
                let len: usize = self.iter().cloned().map(<$ty as Numeric<$e>>::encoded_len).sum();
                encode_varint(len as u64, buf);
                for &value in self {
                    <$ty as Numeric<$e>>::encode(value, buf);
                }
            }
            #[inline]
            fn merge<B>(&mut self, tag: u32, wire_type: WireType, buf: &mut Take<B>) -> Result<()> where B: Buf {
                <Vec<$ty> as Field<$e>>::merge(self, tag, wire_type, buf)
            }
            #[inline]
            fn encoded_len(&self, tag: u32) -> usize {
                if self.is_empty() { return 0; }
                let len: usize = self.iter().cloned().map(<$ty as Numeric<$e>>::encoded_len).sum();
                key_len(tag) + encoded_len_varint(len as _) + len
            }
        }
    };
}

// bool
impl Numeric for bool {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut {
        buf.put_u8(if self { 1u8 } else { 0u8 });
    }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<bool> where B: Buf { decode_varint(buf).map(|value| value != 0) }
    #[inline]
    fn encoded_len(self) -> usize { 1 }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(bool);

// int32
impl Numeric for i32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i32> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(i32);

// int64
impl Numeric for i64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i64> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType {
        WireType::Varint
    }
}
numeric_field!(i64);

// uint32
impl Numeric for u32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u32> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(u32);

// uint64
impl Numeric for u64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u64> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(u64);

// float
impl Numeric for f32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_f32::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<f32> where B: Buf {
        if buf.remaining() < 4 {
            return Err(invalid_input("failed to decode float: buffer underflow"));
        }
        Ok(buf.get_f32::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 4 }
    #[inline]
    fn wire_type() -> WireType { WireType::ThirtyTwoBit }
}
numeric_field!(f32);

// double
impl Numeric for f64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_f64::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<f64> where B: Buf {
        if buf.remaining() < 8 {
            return Err(invalid_input("failed to decode double: buffer underflow"));
        }
        Ok(buf.get_f64::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 8 }
    #[inline]
    fn wire_type() -> WireType { WireType::SixtyFourBit }
}
numeric_field!(f64);

// sint32
impl Numeric<Signed> for i32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut {
        encode_varint(((self << 1) ^ (self >> 31)) as u64, buf)
    }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i32> where B: Buf {
        decode_varint(buf).map(|value| {
            let value = value as i32;
            (value >> 1) ^ -(value & 1)
        })
    }
    #[inline]
    fn encoded_len(self) -> usize {
        encoded_len_varint(((self << 1) ^ (self >> 31)) as u64)
    }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(i32, Signed);

// sint64
impl Numeric<Signed> for i64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut {
        encode_varint(((self << 1) ^ (self >> 63)) as u64, buf)
    }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i64> where B: Buf {
        decode_varint(buf).map(|value| {
            let value = value as i64;
            (value >> 1) ^ -(value & 1)
        })
    }
    #[inline]
    fn encoded_len(self) -> usize {
        encoded_len_varint(((self << 1) ^ (self >> 63)) as u64)
    }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(i64, Signed);

// fixed32
impl Numeric<Fixed> for u32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_u32::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u32> where B: Buf {
        if buf.remaining() < 4 {
            return Err(invalid_input("failed to decode fixed32: buffer underflow"));
        }
        Ok(buf.get_u32::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 4 }
    #[inline]
    fn wire_type() -> WireType { WireType::ThirtyTwoBit }
}
numeric_field!(u32, Fixed);

// fixed64
impl Numeric<Fixed> for u64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_u64::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u64> where B: Buf {
        if buf.remaining() < 8 {
            return Err(invalid_input("failed to decode fixed64: buffer underflow"));
        }
        Ok(buf.get_u64::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 8 }
    #[inline]
    fn wire_type() -> WireType { WireType::SixtyFourBit }
}
numeric_field!(u64, Fixed);

// sfixed32
impl Numeric<Fixed> for i32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_i32::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i32> where B: Buf {
        if buf.remaining() < 4 {
            return Err(invalid_input("failed to decode sfixed32: buffer underflow"));
        }
        Ok(buf.get_i32::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 4 }
    #[inline]
    fn wire_type() -> WireType { WireType::ThirtyTwoBit }
}
numeric_field!(i32, Fixed);

// sfixed64
impl Numeric<Fixed> for i64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_i64::<LittleEndian>(self); }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i64> where B: Buf {
        if buf.remaining() < 8 {
            return Err(invalid_input("failed to decode sfixed64 field: buffer underflow"));
        }
        Ok(buf.get_i64::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 8 }
    #[inline]
    fn wire_type() -> WireType { WireType::SixtyFourBit }
}
numeric_field!(i64, Fixed);
<commit_msg>Fix sint decoding<commit_after>use std::default;
use std::io::Result;

use bytes::{
    Buf,
    BufMut,
    LittleEndian,
    Take,
};

use field::{Field, Type};
use encoding::*;

/// A numeric scalar Protobuf field type.
///
/// The `E` type parameter allows `Numeric` to be implemented multiple times for a
/// single type, in order to provide multiple encoding and decoding options for
/// a single Rust type. For instance, the Protobuf `fixed32` and `uint32` types
/// both correspond to the Rust `u32` type, so `u32` has two impls of `Numeric`
/// with different types for `E`, which correspond to `fixed32` and `uint32`.
/// Repeated numeric fields can optionally use packed encoding, which is
/// controlled using the `Packed` type.
pub trait Numeric<E=Default> : default::Default {
    /// Encodes the scalar field to the buffer, without a key.
    /// The buffer must have enough remaining space to hold the encoded key and field.
    fn encode<B>(self, buf: &mut B) where B: BufMut;

    /// Decodes an instance of the field from the buffer.
    fn decode<B>(buf: &mut B) -> Result<Self> where B: Buf;

    /// Returns the encoded length of the field, without a key.
    fn encoded_len(self) -> usize;

    /// Returns the wire type of the numeric scalar field.
    fn wire_type() -> WireType;
}

// Provides Field, Type, and repeated Field impls for numeric types.
macro_rules! numeric_field {
    ($ty: ty) => { numeric_field!($ty, Default); };
    ($ty: ty, $e: ty) => {
        impl Field<$e> for $ty {
            #[inline]
            fn encode<B>(&self, tag: u32, buf: &mut B) where B: BufMut {
                encode_key(tag, <$ty as Numeric<$e>>::wire_type(), buf);
                <$ty as Numeric<$e>>::encode(*self, buf);
            }
            #[inline]
            fn merge<B>(&mut self, _tag: u32, wire_type: WireType, buf: &mut Take<B>) -> Result<()> where B: Buf {
                check_wire_type(<$ty as Numeric<$e>>::wire_type(), wire_type)?;
                *self = <$ty as Numeric<$e>>::decode(buf)?;
                Ok(())
            }
            #[inline]
            fn encoded_len(&self, tag: u32) -> usize { key_len(tag) + <$ty as Numeric<$e>>::encoded_len(*self) }
        }
        impl Type<$e> for $ty {
            fn empty() -> $ty {
                ::std::default::Default::default()
            }
        }

        impl Field<$e> for Vec<$ty> {
            #[inline]
            fn encode<B>(&self, tag: u32, buf: &mut B) where B: BufMut {
                for value in self {
                    <$ty as Field<$e>>::encode(value, tag, buf);
                }
            }
            #[inline]
            fn merge<B>(&mut self, tag: u32, wire_type: WireType, buf: &mut Take<B>) -> Result<()> where B: Buf {
                if wire_type == WireType::LengthDelimited {
                    // Packed repeated encoding.
                    let len = decode_varint(buf)?;
                    if len > buf.remaining() as u64 {
                        return Err(invalid_data("failed to decode packed repeated field: buffer underflow"));
                    }

                    let limit = buf.limit();
                    buf.set_limit(len as usize);
                    while buf.has_remaining() {
                        self.push(<$ty as Numeric<$e>>::decode(buf)?);
                    }
                    buf.set_limit(limit - len as usize);
                } else {
                    // Default repeated encoding.
                    let mut value = default::Default::default();
                    <$ty as Field<$e>>::merge(&mut value, tag, wire_type, buf)?;
                    self.push(value);
                }
                Ok(())
            }
            #[inline]
            fn encoded_len(&self, tag: u32) -> usize {
                self.iter().map(|f| <$ty as Field<$e>>::encoded_len(f, tag)).sum()
            }
        }

        impl Field<(Packed, $e)> for Vec<$ty> {
            #[inline]
            fn encode<B>(&self, tag: u32, buf: &mut B) where B: BufMut {
                if self.is_empty() { return; }
                encode_key(tag, WireType::LengthDelimited, buf);
                let len: usize = self.iter().cloned().map(<$ty as Numeric<$e>>::encoded_len).sum();
                encode_varint(len as u64, buf);
                for &value in self {
                    <$ty as Numeric<$e>>::encode(value, buf);
                }
            }
            #[inline]
            fn merge<B>(&mut self, tag: u32, wire_type: WireType, buf: &mut Take<B>) -> Result<()> where B: Buf {
                <Vec<$ty> as Field<$e>>::merge(self, tag, wire_type, buf)
            }
            #[inline]
            fn encoded_len(&self, tag: u32) -> usize {
                if self.is_empty() { return 0; }
                let len: usize = self.iter().cloned().map(<$ty as Numeric<$e>>::encoded_len).sum();
                key_len(tag) + encoded_len_varint(len as _) + len
            }
        }
    };
}

// bool
impl Numeric for bool {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut {
        buf.put_u8(if self { 1u8 } else { 0u8 });
    }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<bool> where B: Buf { decode_varint(buf).map(|value| value != 0) }
    #[inline]
    fn encoded_len(self) -> usize { 1 }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(bool);

// int32
impl Numeric for i32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i32> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(i32);

// int64
impl Numeric for i64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i64> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType {
        WireType::Varint
    }
}
numeric_field!(i64);

// uint32
impl Numeric for u32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u32> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(u32);

// uint64
impl Numeric for u64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { encode_varint(self as _, buf) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u64> where B: Buf { decode_varint(buf).map(|value| value as _) }
    #[inline]
    fn encoded_len(self) -> usize { encoded_len_varint(self as _) }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(u64);

// float
impl Numeric for f32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_f32::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<f32> where B: Buf {
        if buf.remaining() < 4 {
            return Err(invalid_input("failed to decode float: buffer underflow"));
        }
        Ok(buf.get_f32::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 4 }
    #[inline]
    fn wire_type() -> WireType { WireType::ThirtyTwoBit }
}
numeric_field!(f32);

// double
impl Numeric for f64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_f64::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<f64> where B: Buf {
        if buf.remaining() < 8 {
            return Err(invalid_input("failed to decode double: buffer underflow"));
        }
        Ok(buf.get_f64::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 8 }
    #[inline]
    fn wire_type() -> WireType { WireType::SixtyFourBit }
}
numeric_field!(f64);

// sint32
impl Numeric<Signed> for i32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut {
        encode_varint(((self << 1) ^ (self >> 31)) as u64, buf)
    }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i32> where B: Buf {
        decode_varint(buf).map(|value| {
            let value = value as u32;
            ((value >> 1) as i32) ^ (-((value & 1) as i32))
        })
    }
    #[inline]
    fn encoded_len(self) -> usize {
        encoded_len_varint(((self << 1) ^ (self >> 31)) as u64)
    }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(i32, Signed);

// sint64
impl Numeric<Signed> for i64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut {
        encode_varint(((self << 1) ^ (self >> 63)) as u64, buf)
    }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i64> where B: Buf {
        decode_varint(buf).map(|value| {
            ((value >> 1) as i64) ^ (-((value & 1) as i64))
        })
    }
    #[inline]
    fn encoded_len(self) -> usize {
        encoded_len_varint(((self << 1) ^ (self >> 63)) as u64)
    }
    #[inline]
    fn wire_type() -> WireType { WireType::Varint }
}
numeric_field!(i64, Signed);

// fixed32
impl Numeric<Fixed> for u32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_u32::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u32> where B: Buf {
        if buf.remaining() < 4 {
            return Err(invalid_input("failed to decode fixed32: buffer underflow"));
        }
        Ok(buf.get_u32::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 4 }
    #[inline]
    fn wire_type() -> WireType { WireType::ThirtyTwoBit }
}
numeric_field!(u32, Fixed);

// fixed64
impl Numeric<Fixed> for u64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_u64::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<u64> where B: Buf {
        if buf.remaining() < 8 {
            return Err(invalid_input("failed to decode fixed64: buffer underflow"));
        }
        Ok(buf.get_u64::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 8 }
    #[inline]
    fn wire_type() -> WireType { WireType::SixtyFourBit }
}
numeric_field!(u64, Fixed);

// sfixed32
impl Numeric<Fixed> for i32 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_i32::<LittleEndian>(self) }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i32> where B: Buf {
        if buf.remaining() < 4 {
            return Err(invalid_input("failed to decode sfixed32: buffer underflow"));
        }
        Ok(buf.get_i32::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 4 }
    #[inline]
    fn wire_type() -> WireType { WireType::ThirtyTwoBit }
}
numeric_field!(i32, Fixed);

// sfixed64
impl Numeric<Fixed> for i64 {
    #[inline]
    fn encode<B>(self, buf: &mut B) where B: BufMut { buf.put_i64::<LittleEndian>(self); }
    #[inline]
    fn decode<B>(buf: &mut B) -> Result<i64> where B: Buf {
        if buf.remaining() < 8 {
            return Err(invalid_input("failed to decode sfixed64 field: buffer underflow"));
        }
        Ok(buf.get_i64::<LittleEndian>())
    }
    #[inline]
    fn encoded_len(self) -> usize { 8 }
    #[inline]
    fn wire_type() -> WireType { WireType::SixtyFourBit }
}
numeric_field!(i64, Fixed);
<|endoftext|>


<commit_before>#![macro_escape]

#[deriving(Copy)]
pub struct BestFailure<'a> {
    pub failure: Option<ParseFailure<'a>>
}

impl<'a> BestFailure<'a> {
    pub fn new() -> BestFailure<'a> {
        BestFailure {
            failure: None,
        }
    }

    pub fn with(failure: ParseFailure<'a>) -> BestFailure<'a> {
        BestFailure {
            failure: Some(failure),
        }
    }

    pub fn push(&mut self, failure: ParseFailure<'a>) {
        if let Some(old) = self.failure {
            if failure.point.offset <= old.point.offset {
                return;
            }
        }

        self.failure = Some(failure)
    }

    pub fn pop(&self) -> ParseFailure<'a> {
        self.failure.expect("No errors found")
    }
}

#[deriving(Show,Clone,PartialEq,Copy)]
pub struct StartPoint<'a> {
    pub offset: uint,
    pub s: &'a str,
}

impl<'a> StartPoint<'a> {
    pub fn slice_at(&self, position: uint) -> (&'a str, StartPoint<'a>) {
        (self.s.slice_to(position), StartPoint{offset: self.offset + position,
                                               s: self.s.slice_from(position)})
    }

    pub fn consume_to(&self, l: Option<uint>) -> ParseResult<'a, &'a str> {
        match l {
            None => ParseResult::Failure(ParseFailure{point: self.clone()}),
            Some(position) => {
                let (v, p) = self.slice_at(position);
                ParseResult::Success(v, p)
            },
        }
    }
}

#[deriving(Copy)]
pub struct ParseFailure<'a> {
    pub point: StartPoint<'a>,
}

pub enum ParseResult<'a, T> {
    Success(T, StartPoint<'a>),
    Partial(T, ParseFailure<'a>, StartPoint<'a>),
    Failure(ParseFailure<'a>),
}

macro_rules! try_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::ParseResult::Success(v, p) => (v, p),
            ::document::peresil::ParseResult::Partial(_, pf, _) |
            ::document::peresil::ParseResult::Failure(pf) => return ::document::peresil::ParseResult::Failure(pf),
        }
    })
);

macro_rules! try_partial_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::ParseResult::Success(v, xml) => (v, ::document::peresil::BestFailure::new(), xml),
            ::document::peresil::ParseResult::Partial(v, pf, xml) => (v, ::document::peresil::BestFailure::with(pf), xml),
            ::document::peresil::ParseResult::Failure(pf) => return ::document::peresil::ParseResult::Failure(pf),
        }
    })
);

macro_rules! try_resume_after_partial_failure(
    ($partial:expr, $e:expr) => ({
        match $e {
            ::document::peresil::ParseResult::Success(v, p) => (v, p),
            ::document::peresil::ParseResult::Partial(_, pf, _) |
            ::document::peresil::ParseResult::Failure(pf) => {
                let mut partial = $partial;
                partial.push(pf);
                return ::document::peresil::ParseResult::Failure(partial.pop())
            },
        }
    });
);

// Pattern: zero-or-one
macro_rules! parse_optional(
    ($parser:expr, $start:expr) => ({
        match $parser {
            ::document::peresil::ParseResult::Success(value, next) => (Some(value), next),
            ::document::peresil::ParseResult::Partial(value, _, next) => (Some(value), next),
            ::document::peresil::ParseResult::Failure(_) => (None, $start),
        }
    })
);

// Pattern: alternate
macro_rules! parse_alternate_rec(
    ($start:expr, $errors:expr, {}) => ({
        ::document::peresil::ParseResult::Failure($errors.pop())
    });
    ($start:expr, $errors:expr, {
        [$parser:expr -> $transformer:expr],
        $([$parser_rest:expr -> $transformer_rest:expr],)*
    }) => (
        match $parser($start) {
            ::document::peresil::ParseResult::Success(val, next) => ::document::peresil::ParseResult::Success($transformer(val), next),
            ::document::peresil::ParseResult::Partial(_, pf, _) |
            ::document::peresil::ParseResult::Failure(pf) => {
                $errors.push(pf);
                parse_alternate_rec!($start, $errors, {
                    $([$parser_rest -> $transformer_rest],)*
                })
            },
        }
    );
);

macro_rules! parse_alternate(
    ($start:expr, {
        $([$parser_rest:expr -> $transformer_rest:expr],)*
    }) => ({
        let mut errors = ::document::peresil::BestFailure::new();
        parse_alternate_rec!($start, errors, {
            $([$parser_rest -> $transformer_rest],)*
        })
    });
);

// Pattern: zero-or-more
macro_rules! parse_zero_or_more(
    ($start:expr, $parser:expr) => {{
        let mut err;

        let mut start = $start;
        loop {
            let (_, next_start) = match $parser(start) {
                ::document::peresil::ParseResult::Success(v, p) => (v, p),
                ::document::peresil::ParseResult::Partial(_, pf, _) |
                ::document::peresil::ParseResult::Failure(pf) => {
                    err = Some(pf);
                    break
                }
            };

            start = next_start;
        }

        ::document::peresil::ParseResult::Partial((), err.unwrap(), start)
    }};
);
<commit_msg>Standardize variable names<commit_after>#![macro_escape]

#[deriving(Copy)]
pub struct BestFailure<'a> {
    pub failure: Option<ParseFailure<'a>>
}

impl<'a> BestFailure<'a> {
    pub fn new() -> BestFailure<'a> {
        BestFailure {
            failure: None,
        }
    }

    pub fn with(failure: ParseFailure<'a>) -> BestFailure<'a> {
        BestFailure {
            failure: Some(failure),
        }
    }

    pub fn push(&mut self, failure: ParseFailure<'a>) {
        if let Some(old) = self.failure {
            if failure.point.offset <= old.point.offset {
                return;
            }
        }

        self.failure = Some(failure)
    }

    pub fn pop(&self) -> ParseFailure<'a> {
        self.failure.expect("No errors found")
    }
}

#[deriving(Show,Clone,PartialEq,Copy)]
pub struct StartPoint<'a> {
    pub offset: uint,
    pub s: &'a str,
}

impl<'a> StartPoint<'a> {
    pub fn slice_at(&self, position: uint) -> (&'a str, StartPoint<'a>) {
        (self.s.slice_to(position), StartPoint{offset: self.offset + position,
                                               s: self.s.slice_from(position)})
    }

    pub fn consume_to(&self, l: Option<uint>) -> ParseResult<'a, &'a str> {
        match l {
            None => ParseResult::Failure(ParseFailure{point: self.clone()}),
            Some(position) => {
                let (val, point) = self.slice_at(position);
                ParseResult::Success(val, point)
            },
        }
    }
}

#[deriving(Copy)]
pub struct ParseFailure<'a> {
    pub point: StartPoint<'a>,
}

pub enum ParseResult<'a, T> {
    Success(T, StartPoint<'a>),
    Partial(T, ParseFailure<'a>, StartPoint<'a>),
    Failure(ParseFailure<'a>),
}

macro_rules! try_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::ParseResult::Success(val, point) =>
                (val, point),
            ::document::peresil::ParseResult::Partial(_, pf, _) |
            ::document::peresil::ParseResult::Failure(pf) =>
                return ::document::peresil::ParseResult::Failure(pf),
        }
    })
);

macro_rules! try_partial_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::ParseResult::Success(v, point) =>
                (v, ::document::peresil::BestFailure::new(), point),
            ::document::peresil::ParseResult::Partial(val, pf, point) =>
                (val, ::document::peresil::BestFailure::with(pf), point),
            ::document::peresil::ParseResult::Failure(pf) =>
                return ::document::peresil::ParseResult::Failure(pf),
        }
    })
);

macro_rules! try_resume_after_partial_failure(
    ($partial:expr, $e:expr) => ({
        match $e {
            ::document::peresil::ParseResult::Success(val, point) =>
                (val, point),
            ::document::peresil::ParseResult::Partial(_, pf, _) |
            ::document::peresil::ParseResult::Failure(pf) => {
                let mut partial = $partial;
                partial.push(pf);
                return ::document::peresil::ParseResult::Failure(partial.pop())
            },
        }
    });
);

// Pattern: zero-or-one
macro_rules! parse_optional(
    ($parser:expr, $start:expr) => ({
        match $parser {
            ::document::peresil::ParseResult::Success(val, point) =>
                (Some(val), point),
            ::document::peresil::ParseResult::Partial(val, _, point) =>
                (Some(val), point),
            ::document::peresil::ParseResult::Failure(_) =>
                (None, $start),
        }
    })
);

// Pattern: alternate
macro_rules! parse_alternate_rec(
    ($start:expr, $errors:expr, {}) => ({
        ::document::peresil::ParseResult::Failure($errors.pop())
    });
    ($start:expr, $errors:expr, {
        [$parser:expr -> $transformer:expr],
        $([$parser_rest:expr -> $transformer_rest:expr],)*
    }) => (
        match $parser($start) {
            ::document::peresil::ParseResult::Success(val, point) =>
                ::document::peresil::ParseResult::Success($transformer(val), point),
            ::document::peresil::ParseResult::Partial(_, pf, _) |
            ::document::peresil::ParseResult::Failure(pf) => {
                $errors.push(pf);
                parse_alternate_rec!($start, $errors, {
                    $([$parser_rest -> $transformer_rest],)*
                })
            },
        }
    );
);

macro_rules! parse_alternate(
    ($start:expr, {
        $([$parser_rest:expr -> $transformer_rest:expr],)*
    }) => ({
        let mut errors = ::document::peresil::BestFailure::new();
        parse_alternate_rec!($start, errors, {
            $([$parser_rest -> $transformer_rest],)*
        })
    });
);

// Pattern: zero-or-more
macro_rules! parse_zero_or_more(
    ($start:expr, $parser:expr) => {{
        let mut err;

        let mut start = $start;
        loop {
            let (_, next_start) = match $parser(start) {
                ::document::peresil::ParseResult::Success(val, point) =>
                    (val, point),
                ::document::peresil::ParseResult::Partial(_, pf, _) |
                ::document::peresil::ParseResult::Failure(pf) => {
                    err = Some(pf);
                    break
                }
            };

            start = next_start;
        }

        ::document::peresil::ParseResult::Partial((), err.unwrap(), start)
    }};
);
<|endoftext|>


<commit_before>//! Compiler plugin for Rust-PHF
//!
//! See the documentation for the `phf` crate for more details.
#[crate_id="github.com/sfackler/rust-phf/phf_mac"];
#[crate_type="dylib"];
#[doc(html_root_url="http://www.rust-ci.org/sfackler/rust-phf/doc")];
#[feature(managed_boxes, macro_registrar, quote)];

extern crate collections;
extern crate rand;
extern crate syntax;
extern crate time;
extern crate phf;

use collections::HashMap;
use std::os;
use std::vec_ng::Vec;
use syntax::ast;
use syntax::ast::{Name, TokenTree, LitStr, MutImmutable, Expr, ExprVec, ExprLit};
use syntax::codemap::Span;
use syntax::ext::base::{SyntaxExtension,
                        ExtCtxt,
                        MacResult,
                        MRExpr,
                        NormalTT,
                        BasicMacroExpander};
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::{InternedString, COMMA, EOF, FAT_ARROW};
use rand::{Rng, SeedableRng, XorShiftRng};

static DEFAULT_LAMBDA: uint = 5;

static FIXED_SEED: [u32, ..4] = [3141592653, 589793238, 462643383, 2795028841];

#[macro_registrar]
#[doc(hidden)]
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
    register(token::intern("phf_map"),
             NormalTT(~BasicMacroExpander {
                expander: expand_mphf_map,
                span: None
             },
             None));
}

struct Entry {
    key_str: InternedString,
    key: @Expr,
    value: @Expr
}

fn expand_mphf_map(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> MacResult {
    let entries = match parse_entries(cx, tts) {
        Some(entries) => entries,
        None => return MacResult::dummy_expr(sp)
    };

    if has_duplicates(cx, sp, entries.as_slice()) {
        return MacResult::dummy_expr(sp);
    }

    let mut rng: XorShiftRng = SeedableRng::from_seed(FIXED_SEED);
    let start = time::precise_time_s();
    let state;
    loop {
        match generate_hash(entries.as_slice(), &mut rng) {
            Some(s) => {
                state = s;
                break;
            }
            None => {}
        }
    }
    let time = time::precise_time_s() - start;
    if os::getenv("PHF_STATS").is_some() {
        cx.span_note(sp, format!("PHF generation took {} seconds", time));
    }

    create_map(cx, sp, entries, state)
}

fn parse_entries(cx: &mut ExtCtxt, tts: &[TokenTree]) -> Option<Vec<Entry>> {
    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
                                                tts.iter().map(|x| x.clone())
                                                    .collect());
    let mut entries = Vec::new();

    let mut bad = false;
    while parser.token != EOF {
        let key = cx.expand_expr(parser.parse_expr());

        let key_str = match key.node {
            ExprLit(lit) => {
                match lit.node {
                    LitStr(ref s, _) => s.clone(),
                    _ => {
                        cx.span_err(key.span, "expected string literal");
                        bad = true;
                        InternedString::new("")
                    }
                }
            }
            _ => {
                cx.span_err(key.span, "expected string literal");
                bad = true;
                InternedString::new("")
            }
        };

        if !parser.eat(&FAT_ARROW) {
            cx.span_err(parser.span, "expected `=>`");
            return None;
        }

        let value = parser.parse_expr();

        entries.push(Entry {
            key_str: key_str,
            key: key,
            value: value
        });

        if !parser.eat(&COMMA) && parser.token != EOF {
            cx.span_err(parser.span, "expected `,`");
            return None;
        }
    }

    if entries.len() > phf::MAX_SIZE {
        cx.span_err(parser.span,
                    format!("maps with more than {} entries are not supported",
                            phf::MAX_SIZE));
        return None;
    }

    if bad {
        return None;
    }

    Some(entries)
}

fn has_duplicates(cx: &mut ExtCtxt, sp: Span, entries: &[Entry]) -> bool {
    let mut dups = false;
    let mut strings = HashMap::new();
    for entry in entries.iter() {
        strings.insert_or_update_with(entry.key_str.clone(), (entry, true),
                                      |_, &(orig, ref mut first)| {
                if *first {
                    cx.span_err(sp, format!("duplicate key \"{}\"", entry.key_str));
                    cx.span_note(orig.key.span, "one occurence here");
                    *first = false;
                }
                cx.span_note(entry.key.span, "one occurence here");
                dups = true;
            });
    }

    dups
}

struct HashState {
    k1: u64,
    k2: u64,
    disps: Vec<(uint, uint)>,
    map: Vec<Option<uint>>,
}

fn generate_hash(entries: &[Entry], rng: &mut XorShiftRng) -> Option<HashState> {
    struct Bucket {
        idx: uint,
        keys: Vec<uint>,
    }

    struct Hashes {
        g: uint,
        f1: uint,
        f2: uint,
    }

    let k1 = rng.gen();
    let k2 = rng.gen();

    let hashes: Vec<Hashes> = entries.iter().map(|entry| {
            let (g, f1, f2) = phf::hash(entry.key_str.get(), k1, k2);
            Hashes {
                g: g,
                f1: f1,
                f2: f2
            }
        }).collect();

    let buckets_len = (entries.len() + DEFAULT_LAMBDA - 1) / DEFAULT_LAMBDA;
    let mut buckets = Vec::from_fn(buckets_len,
                                   |i| Bucket { idx: i, keys: Vec::new() });

    for (i, hash) in hashes.iter().enumerate() {
        buckets.get_mut(hash.g % buckets_len).keys.push(i);
    }

    // Sort descending
    buckets.sort_by(|a, b| b.keys.len().cmp(&a.keys.len()));

    let table_len = entries.len();
    let mut map = Vec::from_elem(table_len, None);
    let mut disps = Vec::from_elem(buckets_len, None);
    let mut try_map = HashMap::new();
    'buckets: for bucket in buckets.iter() {
        for d1 in range(0, table_len) {
            'disps_l: for d2 in range(0, table_len) {
                try_map.clear();
                for &key in bucket.keys.iter() {
                    let idx = phf::displace(hashes.get(key).f1,
                                            hashes.get(key).f2,
                                            d1,
                                            d2) % table_len;
                    if try_map.find(&idx).is_some() || map.get(idx).is_some() {
                        continue 'disps_l;
                    }
                    try_map.insert(idx, key);
                }

                // We've picked a good set of disps
                *disps.get_mut(bucket.idx) = Some((d1, d2));
                for (&idx, &key) in try_map.iter() {
                    *map.get_mut(idx) = Some(key);
                }
                continue 'buckets;
            }
        }

        // Unable to find displacements for a bucket
        return None;
    }

    let disps = disps.move_iter().map(|i| i.expect("should have a bucket"))
            .collect();

    Some(HashState {
        k1: k1,
        k2: k2,
        disps: disps,
        map: map,
    })
}

fn create_map(cx: &mut ExtCtxt, sp: Span, entries: Vec<Entry>, state: HashState)
              -> MacResult {
    let len = entries.len();
    let k1 = state.k1;
    let k2 = state.k2;
    let disps = state.disps.iter().map(|&(d1, d2)| {
            quote_expr!(&*cx, ($d1, $d2))
        }).collect();
    let disps = @Expr {
        id: ast::DUMMY_NODE_ID,
        node: ExprVec(disps, MutImmutable),
        span: sp,
    };
    let entries = state.map.iter().map(|&idx| {
            match idx {
                Some(idx) => {
                    let &Entry { key, value, .. } = entries.get(idx);
                    quote_expr!(&*cx, Some(($key, $value)))
                }
                None => quote_expr!(&*cx, None),
            }
        }).collect();
    let entries = @Expr {
        id: ast::DUMMY_NODE_ID,
        node: ExprVec(entries, MutImmutable),
        span: sp,
    };

    MRExpr(quote_expr!(cx, PhfMap {
        len: $len,
        k1: $k1,
        k2: $k2,
        disps: &'static $disps,
        entries: &'static $entries,
    }))
}
<commit_msg>I can spell!<commit_after>//! Compiler plugin for Rust-PHF
//!
//! See the documentation for the `phf` crate for more details.
#[crate_id="github.com/sfackler/rust-phf/phf_mac"];
#[crate_type="dylib"];
#[doc(html_root_url="http://www.rust-ci.org/sfackler/rust-phf/doc")];
#[feature(managed_boxes, macro_registrar, quote)];

extern crate collections;
extern crate rand;
extern crate syntax;
extern crate time;
extern crate phf;

use collections::HashMap;
use std::os;
use std::vec_ng::Vec;
use syntax::ast;
use syntax::ast::{Name, TokenTree, LitStr, MutImmutable, Expr, ExprVec, ExprLit};
use syntax::codemap::Span;
use syntax::ext::base::{SyntaxExtension,
                        ExtCtxt,
                        MacResult,
                        MRExpr,
                        NormalTT,
                        BasicMacroExpander};
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::{InternedString, COMMA, EOF, FAT_ARROW};
use rand::{Rng, SeedableRng, XorShiftRng};

static DEFAULT_LAMBDA: uint = 5;

static FIXED_SEED: [u32, ..4] = [3141592653, 589793238, 462643383, 2795028841];

#[macro_registrar]
#[doc(hidden)]
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
    register(token::intern("phf_map"),
             NormalTT(~BasicMacroExpander {
                expander: expand_mphf_map,
                span: None
             },
             None));
}

struct Entry {
    key_str: InternedString,
    key: @Expr,
    value: @Expr
}

fn expand_mphf_map(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> MacResult {
    let entries = match parse_entries(cx, tts) {
        Some(entries) => entries,
        None => return MacResult::dummy_expr(sp)
    };

    if has_duplicates(cx, sp, entries.as_slice()) {
        return MacResult::dummy_expr(sp);
    }

    let mut rng: XorShiftRng = SeedableRng::from_seed(FIXED_SEED);
    let start = time::precise_time_s();
    let state;
    loop {
        match generate_hash(entries.as_slice(), &mut rng) {
            Some(s) => {
                state = s;
                break;
            }
            None => {}
        }
    }
    let time = time::precise_time_s() - start;
    if os::getenv("PHF_STATS").is_some() {
        cx.span_note(sp, format!("PHF generation took {} seconds", time));
    }

    create_map(cx, sp, entries, state)
}

fn parse_entries(cx: &mut ExtCtxt, tts: &[TokenTree]) -> Option<Vec<Entry>> {
    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
                                                tts.iter().map(|x| x.clone())
                                                    .collect());
    let mut entries = Vec::new();

    let mut bad = false;
    while parser.token != EOF {
        let key = cx.expand_expr(parser.parse_expr());

        let key_str = match key.node {
            ExprLit(lit) => {
                match lit.node {
                    LitStr(ref s, _) => s.clone(),
                    _ => {
                        cx.span_err(key.span, "expected string literal");
                        bad = true;
                        InternedString::new("")
                    }
                }
            }
            _ => {
                cx.span_err(key.span, "expected string literal");
                bad = true;
                InternedString::new("")
            }
        };

        if !parser.eat(&FAT_ARROW) {
            cx.span_err(parser.span, "expected `=>`");
            return None;
        }

        let value = parser.parse_expr();

        entries.push(Entry {
            key_str: key_str,
            key: key,
            value: value
        });

        if !parser.eat(&COMMA) && parser.token != EOF {
            cx.span_err(parser.span, "expected `,`");
            return None;
        }
    }

    if entries.len() > phf::MAX_SIZE {
        cx.span_err(parser.span,
                    format!("maps with more than {} entries are not supported",
                            phf::MAX_SIZE));
        return None;
    }

    if bad {
        return None;
    }

    Some(entries)
}

fn has_duplicates(cx: &mut ExtCtxt, sp: Span, entries: &[Entry]) -> bool {
    let mut dups = false;
    let mut strings = HashMap::new();
    for entry in entries.iter() {
        strings.insert_or_update_with(entry.key_str.clone(), (entry, true),
                                      |_, &(orig, ref mut first)| {
                if *first {
                    cx.span_err(sp, format!("duplicate key \"{}\"", entry.key_str));
                    cx.span_note(orig.key.span, "one occurrence here");
                    *first = false;
                }
                cx.span_note(entry.key.span, "one occurrence here");
                dups = true;
            });
    }

    dups
}

struct HashState {
    k1: u64,
    k2: u64,
    disps: Vec<(uint, uint)>,
    map: Vec<Option<uint>>,
}

fn generate_hash(entries: &[Entry], rng: &mut XorShiftRng) -> Option<HashState> {
    struct Bucket {
        idx: uint,
        keys: Vec<uint>,
    }

    struct Hashes {
        g: uint,
        f1: uint,
        f2: uint,
    }

    let k1 = rng.gen();
    let k2 = rng.gen();

    let hashes: Vec<Hashes> = entries.iter().map(|entry| {
            let (g, f1, f2) = phf::hash(entry.key_str.get(), k1, k2);
            Hashes {
                g: g,
                f1: f1,
                f2: f2
            }
        }).collect();

    let buckets_len = (entries.len() + DEFAULT_LAMBDA - 1) / DEFAULT_LAMBDA;
    let mut buckets = Vec::from_fn(buckets_len,
                                   |i| Bucket { idx: i, keys: Vec::new() });

    for (i, hash) in hashes.iter().enumerate() {
        buckets.get_mut(hash.g % buckets_len).keys.push(i);
    }

    // Sort descending
    buckets.sort_by(|a, b| b.keys.len().cmp(&a.keys.len()));

    let table_len = entries.len();
    let mut map = Vec::from_elem(table_len, None);
    let mut disps = Vec::from_elem(buckets_len, None);
    let mut try_map = HashMap::new();
    'buckets: for bucket in buckets.iter() {
        for d1 in range(0, table_len) {
            'disps_l: for d2 in range(0, table_len) {
                try_map.clear();
                for &key in bucket.keys.iter() {
                    let idx = phf::displace(hashes.get(key).f1,
                                            hashes.get(key).f2,
                                            d1,
                                            d2) % table_len;
                    if try_map.find(&idx).is_some() || map.get(idx).is_some() {
                        continue 'disps_l;
                    }
                    try_map.insert(idx, key);
                }

                // We've picked a good set of disps
                *disps.get_mut(bucket.idx) = Some((d1, d2));
                for (&idx, &key) in try_map.iter() {
                    *map.get_mut(idx) = Some(key);
                }
                continue 'buckets;
            }
        }

        // Unable to find displacements for a bucket
        return None;
    }

    let disps = disps.move_iter().map(|i| i.expect("should have a bucket"))
            .collect();

    Some(HashState {
        k1: k1,
        k2: k2,
        disps: disps,
        map: map,
    })
}

fn create_map(cx: &mut ExtCtxt, sp: Span, entries: Vec<Entry>, state: HashState)
              -> MacResult {
    let len = entries.len();
    let k1 = state.k1;
    let k2 = state.k2;
    let disps = state.disps.iter().map(|&(d1, d2)| {
            quote_expr!(&*cx, ($d1, $d2))
        }).collect();
    let disps = @Expr {
        id: ast::DUMMY_NODE_ID,
        node: ExprVec(disps, MutImmutable),
        span: sp,
    };
    let entries = state.map.iter().map(|&idx| {
            match idx {
                Some(idx) => {
                    let &Entry { key, value, .. } = entries.get(idx);
                    quote_expr!(&*cx, Some(($key, $value)))
                }
                None => quote_expr!(&*cx, None),
            }
        }).collect();
    let entries = @Expr {
        id: ast::DUMMY_NODE_ID,
        node: ExprVec(entries, MutImmutable),
        span: sp,
    };

    MRExpr(quote_expr!(cx, PhfMap {
        len: $len,
        k1: $k1,
        k2: $k2,
        disps: &'static $disps,
        entries: &'static $entries,
    }))
}
<|endoftext|>


<commit_before>//! Reexports of the most common traits, types, and functions.

pub use random::{self, Source};

pub use distribution::Distribution;

pub use distribution::Continuous;
pub use distribution::Discrete;

pub use distribution::Entropy;
pub use distribution::Inverse;
pub use distribution::Kurtosis;
pub use distribution::Mean;
pub use distribution::Median;
pub use distribution::Modes;
pub use distribution::Sample;
pub use distribution::Skewness;
pub use distribution::Variance;

pub use distribution::Bernoulli;
pub use distribution::Beta;
pub use distribution::Binomial;
pub use distribution::Categorical;
pub use distribution::Exponential;
pub use distribution::Gamma;
pub use distribution::Gaussian;
pub use distribution::Uniform;

pub use sampler::Independent;
<commit_msg>Adjust the description of prelude<commit_after>//! Reexports of traits, types, and functions.

pub use random::{self, Source};

pub use distribution::Distribution;

pub use distribution::Continuous;
pub use distribution::Discrete;

pub use distribution::Entropy;
pub use distribution::Inverse;
pub use distribution::Kurtosis;
pub use distribution::Mean;
pub use distribution::Median;
pub use distribution::Modes;
pub use distribution::Sample;
pub use distribution::Skewness;
pub use distribution::Variance;

pub use distribution::Bernoulli;
pub use distribution::Beta;
pub use distribution::Binomial;
pub use distribution::Categorical;
pub use distribution::Exponential;
pub use distribution::Gamma;
pub use distribution::Gaussian;
pub use distribution::Uniform;

pub use sampler::Independent;
<|endoftext|>