<commit_before>use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

use crossbeam_deque::{self as deque, Pop, Steal, Stealer, Worker};
use rand::distributions::{Distribution, Uniform};
use rand::thread_rng;
use threadpool::ThreadPool;

use gc::root::Slot;
use gc::{Address, Region};

pub fn start(
    rootset: &[Slot],
    heap: Region,
    perm: Region,
    number_workers: usize,
    threadpool: &ThreadPool,
) {
    let mut workers = Vec::with_capacity(number_workers);
    let mut stealers = Vec::with_capacity(number_workers);

    for _ in 0..number_workers {
        let (w, s) = deque::lifo();
        workers.push(w);
        stealers.push(s);
    }

    for root in rootset {
        let root_ptr = root.get();

        if heap.contains(root_ptr) {
            let root_obj = root_ptr.to_mut_obj();

            if !root_obj.header().is_marked_non_atomic() {
                root_obj.header_mut().mark_non_atomic();
                workers[0].push(root_ptr);
            }
        } else {
            debug_assert!(root_ptr.is_null() || perm.contains(root_ptr));
        }
    }

    let nworkers_stage = Arc::new(AtomicUsize::new(number_workers));

    for (task_id, worker) in workers.into_iter().enumerate() {
        let heap_region = heap.clone();
        let perm_region = perm.clone();

        let stealers = stealers.clone();
        let nworkers_stage = nworkers_stage.clone();

        threadpool.execute(move || {
            let mut task = MarkingTask {
                task_id: task_id,
                local: Segment::new(),
                worker: worker,
                stealers: stealers,
                nworkers: nworkers_stage,
                heap_region: heap_region,
                perm_region: perm_region,
            };

            task.run();
        });
    }

    threadpool.join();
}

struct MarkingTask {
    task_id: usize,
    local: Segment,
    worker: Worker<Address>,
    stealers: Vec<Stealer<Address>>,
    nworkers: Arc<AtomicUsize>,
    heap_region: Region,
    perm_region: Region,
}

impl MarkingTask {
    fn pop(&mut self) -> Option<Address> {
        self.pop_local()
            .or_else(|| self.pop_worker())
            .or_else(|| self.steal())
    }

    fn pop_local(&mut self) -> Option<Address> {
        if self.local.is_empty() {
            return None;
        }

        let obj = self.local.pop().expect("should be non-empty");
        Some(obj)
    }

    fn pop_worker(&mut self) -> Option<Address> {
        loop {
            match self.worker.pop() {
                Pop::Empty => break,
                Pop::Data(address) => return Some(address),
                Pop::Retry => continue,
            }
        }

        None
    }

    fn steal(&self) -> Option<Address> {
        if self.stealers.len() == 1 {
            return None;
        }

        let mut rng = thread_rng();
        let range = Uniform::new(0, self.stealers.len());

        for _ in 0..2 * self.stealers.len() {
            let mut stealer_id = self.task_id;

            while stealer_id == self.task_id {
                stealer_id = range.sample(&mut rng);
            }

            let stealer = &self.stealers[stealer_id];

            loop {
                match stealer.steal() {
                    Steal::Empty => break,
                    Steal::Data(address) => return Some(address),
                    Steal::Retry => continue,
                }
            }
        }

        None
    }

    fn run(&mut self) {
        loop {
            let object_addr = if let Some(object_addr) = self.pop() {
                object_addr
            } else if self.try_terminate() {
                break;
            } else {
                continue;
            };

            let object = object_addr.to_mut_obj();

            object.visit_reference_fields(|field| {
                self.trace(field);
            });
        }
    }

    fn try_terminate(&mut self) -> bool {
        decrease_workers(self.nworkers.as_ref());
        thread::sleep(Duration::from_micros(1));
        zero_or_increase_workers(self.nworkers.as_ref())
    }

    fn trace(&mut self, slot: Slot) {
        let field_addr = slot.get();

        if self.heap_region.contains(field_addr) {
            let field_obj = field_addr.to_mut_obj();

            if field_obj.header().try_mark_non_atomic() {
                if self.local.has_capacity() {
                    self.local.push(field_addr);
                } else {
                    self.worker.push(field_addr);
                }
            }
        } else {
            debug_assert!(field_addr.is_null() || self.perm_region.contains(field_addr));
        }
    }
}

fn decrease_workers(atomic: &AtomicUsize) -> bool {
    atomic.fetch_sub(1, Ordering::SeqCst) == 1
}

fn zero_or_increase_workers(atomic: &AtomicUsize) -> bool {
    let mut nworkers = atomic.load(Ordering::Relaxed);

    loop {
        if nworkers == 0 {
            return true;
        }

        let prev_nworkers = atomic.compare_and_swap(nworkers, nworkers + 1, Ordering::SeqCst);

        if nworkers == prev_nworkers {
            return false;
        }

        nworkers = prev_nworkers;
    }
}

const SEGMENT_SIZE: usize = 8;

struct Segment {
    data: Vec<Address>,
}

impl Segment {
    fn new() -> Segment {
        Segment {
            data: Vec::with_capacity(SEGMENT_SIZE),
        }
    }

    fn empty() -> Segment {
        Segment { data: Vec::new() }
    }

    fn with(addr: Address) -> Segment {
        let mut segment = Segment::new();
        segment.data.push(addr);

        segment
    }

    fn has_capacity(&self) -> bool {
        self.data.len() < SEGMENT_SIZE
    }

    fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    fn push(&mut self, addr: Address) {
        debug_assert!(self.has_capacity());
        self.data.push(addr);
    }

    fn pop(&mut self) -> Option<Address> {
        self.data.pop()
    }
}
<commit_msg>swiper: publish entries from time to time<commit_after>use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

use crossbeam_deque::{self as deque, Pop, Steal, Stealer, Worker};
use rand::distributions::{Distribution, Uniform};
use rand::thread_rng;
use threadpool::ThreadPool;

use gc::root::Slot;
use gc::{Address, Region};

pub fn start(
    rootset: &[Slot],
    heap: Region,
    perm: Region,
    number_workers: usize,
    threadpool: &ThreadPool,
) {
    let mut workers = Vec::with_capacity(number_workers);
    let mut stealers = Vec::with_capacity(number_workers);

    for _ in 0..number_workers {
        let (w, s) = deque::lifo();
        workers.push(w);
        stealers.push(s);
    }

    for root in rootset {
        let root_ptr = root.get();

        if heap.contains(root_ptr) {
            let root_obj = root_ptr.to_mut_obj();

            if !root_obj.header().is_marked_non_atomic() {
                root_obj.header_mut().mark_non_atomic();
                workers[0].push(root_ptr);
            }
        } else {
            debug_assert!(root_ptr.is_null() || perm.contains(root_ptr));
        }
    }

    let nworkers_stage = Arc::new(AtomicUsize::new(number_workers));

    for (task_id, worker) in workers.into_iter().enumerate() {
        let heap_region = heap.clone();
        let perm_region = perm.clone();

        let stealers = stealers.clone();
        let nworkers_stage = nworkers_stage.clone();

        threadpool.execute(move || {
            let mut task = MarkingTask {
                task_id: task_id,
                local: Segment::new(),
                worker: worker,
                stealers: stealers,
                nworkers: nworkers_stage,
                heap_region: heap_region,
                perm_region: perm_region,
                marked: 0,
            };

            task.run();
        });
    }

    threadpool.join();
}

struct MarkingTask {
    task_id: usize,
    local: Segment,
    worker: Worker<Address>,
    stealers: Vec<Stealer<Address>>,
    nworkers: Arc<AtomicUsize>,
    heap_region: Region,
    perm_region: Region,
    marked: usize,
}

impl MarkingTask {
    fn pop(&mut self) -> Option<Address> {
        self.pop_local()
            .or_else(|| self.pop_worker())
            .or_else(|| self.steal())
    }

    fn pop_local(&mut self) -> Option<Address> {
        if self.local.is_empty() {
            return None;
        }

        let obj = self.local.pop().expect("should be non-empty");
        Some(obj)
    }

    fn pop_worker(&mut self) -> Option<Address> {
        loop {
            match self.worker.pop() {
                Pop::Empty => break,
                Pop::Data(address) => return Some(address),
                Pop::Retry => continue,
            }
        }

        None
    }

    fn steal(&self) -> Option<Address> {
        if self.stealers.len() == 1 {
            return None;
        }

        let mut rng = thread_rng();
        let range = Uniform::new(0, self.stealers.len());

        for _ in 0..2 * self.stealers.len() {
            let mut stealer_id = self.task_id;

            while stealer_id == self.task_id {
                stealer_id = range.sample(&mut rng);
            }

            let stealer = &self.stealers[stealer_id];

            loop {
                match stealer.steal() {
                    Steal::Empty => break,
                    Steal::Data(address) => return Some(address),
                    Steal::Retry => continue,
                }
            }
        }

        None
    }

    fn run(&mut self) {
        loop {
            let object_addr = if let Some(object_addr) = self.pop() {
                object_addr
            } else if self.try_terminate() {
                break;
            } else {
                continue;
            };

            let object = object_addr.to_mut_obj();

            object.visit_reference_fields(|field| {
                self.trace(field);
            });
        }
    }

    fn try_terminate(&mut self) -> bool {
        decrease_workers(self.nworkers.as_ref());
        thread::sleep(Duration::from_micros(1));
        zero_or_increase_workers(self.nworkers.as_ref())
    }

    fn trace(&mut self, slot: Slot) {
        let field_addr = slot.get();

        if self.heap_region.contains(field_addr) {
            let field_obj = field_addr.to_mut_obj();

            if field_obj.header().try_mark_non_atomic() {
                if self.local.has_capacity() {
                    self.local.push(field_addr);
                } else {
                    self.worker.push(field_addr);
                }

                self.marked += 1;
                if self.marked > 256 && self.local.len() > 16 {
                    let target_len = self.local.len() / 2;

                    while self.local.len() > target_len {
                        let val = self.local.pop().unwrap();
                        self.worker.push(val);
                    }
                }
            }
        } else {
            debug_assert!(field_addr.is_null() || self.perm_region.contains(field_addr));
        }
    }
}

fn decrease_workers(atomic: &AtomicUsize) -> bool {
    atomic.fetch_sub(1, Ordering::SeqCst) == 1
}

fn zero_or_increase_workers(atomic: &AtomicUsize) -> bool {
    let mut nworkers = atomic.load(Ordering::Relaxed);

    loop {
        if nworkers == 0 {
            return true;
        }

        let prev_nworkers = atomic.compare_and_swap(nworkers, nworkers + 1, Ordering::SeqCst);

        if nworkers == prev_nworkers {
            return false;
        }

        nworkers = prev_nworkers;
    }
}

const SEGMENT_SIZE: usize = 64;

struct Segment {
    data: Vec<Address>,
}

impl Segment {
    fn new() -> Segment {
        Segment {
            data: Vec::with_capacity(SEGMENT_SIZE),
        }
    }

    fn empty() -> Segment {
        Segment { data: Vec::new() }
    }

    fn with(addr: Address) -> Segment {
        let mut segment = Segment::new();
        segment.data.push(addr);

        segment
    }

    fn has_capacity(&self) -> bool {
        self.data.len() < SEGMENT_SIZE
    }

    fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    fn push(&mut self, addr: Address) {
        debug_assert!(self.has_capacity());
        self.data.push(addr);
    }

    fn pop(&mut self) -> Option<Address> {
        self.data.pop()
    }

    fn len(&mut self) -> usize {
        self.data.len()
    }
}
<|endoftext|>


<commit_before>//! Generic message handling.
//!
//! This module provides the ability to read SBD messages from and write SBD messages to streams.

use std::path::Path;

use Result;

/// An SBD message.
pub struct Message;

impl Message {

    /// Reads in a message from a file path.
    ///
    /// # Examples
    ///
    /// ```
    /// use sbd::message::Message;
    /// let message = Message::from_path("data/0-mo.sbd").unwrap();
    /// ```
    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Message> {
        Ok(Message)
    }
}

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

    #[test]
    fn read_from_path() {
        Message::from_path("data/0-mo.sbd").unwrap();
    }
}
<commit_msg>Prototype read_from<commit_after>//! Generic message handling.
//!
//! This module provides the ability to read SBD messages from and write SBD messages to streams.

use std::io::Read;
use std::path::Path;

use Result;

/// An SBD message.
pub struct Message;

impl Message {

    /// Reads in a message from a file path.
    ///
    /// # Examples
    ///
    /// ```
    /// use sbd::message::Message;
    /// let message = Message::from_path("data/0-mo.sbd").unwrap();
    /// ```
    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Message> {
        Ok(Message)
    }

    /// Reads in a message from an object that implements `Read`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::fs::File;
    /// use sbd::message::Message;
    /// let mut file = File::open("data/0-mo.sbd").unwrap();
    /// let message = Message::read_from(file).unwrap();
    pub fn read_from<R: Read>(readable: R) -> Result<Message> {
        Ok(Message)
    }
}

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

    use std::fs::File;

    #[test]
    fn from_path() {
        Message::from_path("data/0-mo.sbd").unwrap();
    }

    #[test]
    fn from_read() {
        let mut file = File::open("data/0-mo.sbd").unwrap();
        Message::read_from(file).unwrap();
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 William Light <wrl@illest.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use std::io::Write;
use std::io;

use Argument;

pub struct Message<'a> {
    pub path: &'a str,
    pub arguments: Vec<Argument<'a>>
}

impl<'a> Message<'a> {
    pub fn deserialize(buf: &'a [u8]) -> Result<Message<'a>, ()> {
        let mut msg = Message {
            path: "",
            arguments: vec![]
        };

        let mut slice = buf;

        match Argument::deserialize('s', &mut slice) {
            Ok(Argument::s(st)) => msg.path = st,
            _ => return Err(())
        }

        let typetags = match Argument::deserialize('s', &mut slice) {
            Ok(Argument::s(st)) => st,
            _ => return Err(())
        };

        for typetag in typetags[1 ..].chars() {
            let arg = Argument::deserialize(typetag, &mut slice);

            match arg {
                Ok(arg) => msg.arguments.push(arg),
                Err(_) => return Err(())
            }
        }

        Ok(msg)
    }

    pub fn serialize_into(&self, into: &mut Write) -> io::Result<()> {
        try!(Argument::s(self.path).serialize(into));

        let mut typetags = String::from(",");

        for arg in &self.arguments {
            typetags.push(arg.typetag());
        }

        try!(Argument::s(&*typetags).serialize(into));

        for arg in &self.arguments {
            try!(arg.serialize(into));
        }

        Ok(())
    }

    pub fn serialize(&self) -> io::Result<Vec<u8>> {
        let mut ret: Vec<u8> = vec![];
        try!(self.serialize_into(&mut ret));
        Ok(ret)
    }
}
<commit_msg>make sure typetag string starts with a comma<commit_after>// Copyright (c) 2015 William Light <wrl@illest.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use std::io::Write;
use std::io;

use Argument;

pub struct Message<'a> {
    pub path: &'a str,
    pub arguments: Vec<Argument<'a>>
}

impl<'a> Message<'a> {
    pub fn deserialize(buf: &'a [u8]) -> Result<Message<'a>, ()> {
        let mut msg = Message {
            path: "",
            arguments: vec![]
        };

        let mut slice = buf;

        match Argument::deserialize('s', &mut slice) {
            Ok(Argument::s(st)) => msg.path = st,
            _ => return Err(())
        }

        let typetags = match Argument::deserialize('s', &mut slice) {
            Ok(Argument::s(st)) => st,
            _ => return Err(())
        };

        if typetags.as_bytes()[0] != (',' as u8) {
            return Err(())
        }

        for typetag in typetags[1 ..].chars() {
            let arg = Argument::deserialize(typetag, &mut slice);

            match arg {
                Ok(arg) => msg.arguments.push(arg),
                Err(_) => return Err(())
            }
        }

        Ok(msg)
    }

    pub fn serialize_into(&self, into: &mut Write) -> io::Result<()> {
        try!(Argument::s(self.path).serialize(into));

        let mut typetags = String::from(",");

        for arg in &self.arguments {
            typetags.push(arg.typetag());
        }

        try!(Argument::s(&*typetags).serialize(into));

        for arg in &self.arguments {
            try!(arg.serialize(into));
        }

        Ok(())
    }

    pub fn serialize(&self) -> io::Result<Vec<u8>> {
        let mut ret: Vec<u8> = vec![];
        try!(self.serialize_into(&mut ret));
        Ok(ret)
    }
}
<|endoftext|>


<commit_before>use petgraph::{Graph, Undirected};
use rand;
use rand::distributions::{IndependentSample, Range};

pub type GridIndexType = u16;
pub type GridGraphNodeIndex = ::petgraph::graph::NodeIndex<GridIndexType>;

pub enum GridDirection {
    North,
    South,
    East,
    West,
}

struct AdjacentCells {
    north: Option<GridGraphNodeIndex>,
    south: Option<GridGraphNodeIndex>,
    east: Option<GridGraphNodeIndex>,
    west: Option<GridGraphNodeIndex>,
}
impl AdjacentCells {
    fn new() -> Self {
        AdjacentCells {
            north: None,
            south: None,
            east: None,
            west: None,
        }
    }
}

#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
struct GridCoordinate {
    pub x: isize,
    pub y: isize,
}

pub struct SquareGrid {
    /// For mapping a 2D gridcoordinate (converted to a 1D index) to a graph node index.
    grid_coordinate_to_node_index_lookup: Vec<GridGraphNodeIndex>,
    graph: Graph<AdjacentCells, (), Undirected, GridIndexType>,
    dimension_size: GridIndexType,
}

impl SquareGrid {
    pub fn new(dimension_size: GridIndexType) -> SquareGrid {

        let cells_count = dimension_size * dimension_size;
        let nodes_count_hint = cells_count as usize;
        let edges_count_hint = 4 * cells_count as usize - 4 * dimension_size as usize; // Probably overkill, but don't want any capacity panics

        let mut grid = SquareGrid {
            grid_coordinate_to_node_index_lookup: Vec::with_capacity(nodes_count_hint),
            graph: Graph::with_capacity(nodes_count_hint, edges_count_hint),
            dimension_size: dimension_size,
        };

        // Although it does seem to, there is no guarantee that the index values are monotonically increasing when calling graph.add_node
        // So we maintain our own symbol table mapping gridcoordinates converted to 1d (the implicit Vec indices) to the NodeIndexes created
        // by adding a node to the graph.
        for _ in 0..cells_count {
            let node_index = grid.graph.add_node(AdjacentCells::new());
            grid.grid_coordinate_to_node_index_lookup.push(node_index);
        }

        for (index, node_index) in grid.grid_coordinate_to_node_index_lookup.iter().enumerate() {

            let coord = to_grid_coordinate(index, dimension_size);

            // Limit the lifetime of the find_neighbour_nodeindex closure so we don't get a grid
            // borrow conflict when mutating the adjacent_cells
            let (north_index, south_index, east_index, west_index) = {
                let find_neighbour_nodeindex = |dir: GridDirection| -> Option<GridGraphNodeIndex> {
                    let neighbour_coord = offset_coordinate(&coord, dir);
                    if is_valid_coordinate(&neighbour_coord, dimension_size) {
                        let node_indices_index = to_1d_index(&neighbour_coord, dimension_size);
                        let node_index =
                            grid.grid_coordinate_to_node_index_lookup[node_indices_index as usize];
                        Some(node_index)
                    } else {
                        None
                    }
                };
                (find_neighbour_nodeindex(GridDirection::North),
                 find_neighbour_nodeindex(GridDirection::South),
                 find_neighbour_nodeindex(GridDirection::East),
                 find_neighbour_nodeindex(GridDirection::West))
            };

            let adjacent_cells = grid.graph
                                     .node_weight_mut(node_index.clone())
                                     .unwrap();
            adjacent_cells.north = north_index;
            adjacent_cells.south = south_index;
            adjacent_cells.east = east_index;
            adjacent_cells.west = west_index;
        }

        grid
    }

    pub fn random_cell(&self) -> GridGraphNodeIndex {
        let random_pos = Range::new(0, self.grid_coordinate_to_node_index_lookup.len());
        let mut rng = rand::thread_rng();
        let index = random_pos.ind_sample(&mut rng);
        self.grid_coordinate_to_node_index_lookup[index]
    }

    /// Link two cells
    /// Todo - only allow links between adjacent cells? If `b` not in `g.neighbours(a)`.
    /// neighbours is a wasteful computation? It filters the None adjacents, that's all.
    /// It is so small maybe it could move return an array instead of allocating a vector on the heap
    /// then I'd have no crazy ideas about passing a pre-allocated output container.
    ///
    /// Panics if a cell does not exist.
    pub fn link(&mut self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) {
        if a != b {
            let _ = self.graph.update_edge(a, b, ());
        }
    }

    /// Unlink two cells, if a link exists between them.
    pub fn unlink(&mut self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) {

        if let Some(edge_index) = self.graph.find_edge(a, b) {
            // This will invalidate the last edge index in the graph, which is fine as we
            // are not storing them for any reason.
            self.graph.remove_edge(edge_index);
        }
    }

    /// Cell nodes that are linked to a particular node by a passage.
    pub fn links(&self, node_index: GridGraphNodeIndex) -> Vec<GridGraphNodeIndex> {
        self.graph
            .edges(node_index)
            .map(|index_edge_data_pair| index_edge_data_pair.0.clone())
            .collect()
    }

    /// Cell nodes that are to the North, South, East or West of a particular node, but not
    /// necessarily linked by a passage.
    pub fn neighbours(&self, node_index: GridGraphNodeIndex) -> Vec<GridGraphNodeIndex> {

        if let Some(adj) = self.graph.node_weight(node_index) {
            vec![adj.north, adj.south, adj.east, adj.west]
                .iter()
                .filter_map(|&maybe_adj| maybe_adj.clone())
                .collect()
        } else {
            vec![]
        }
    }

    fn is_neighbour(&self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) -> bool {
        macro_rules! index_node_match {
            ($opt_grid_index:expr) => (if let Some(node_index) = $opt_grid_index {
                                           if node_index == b {
                                               return true;
                                           }
                                       })
        }
        if let Some(adjacents_of_a) = self.graph.node_weight(a) {
            index_node_match!(adjacents_of_a.north);
            index_node_match!(adjacents_of_a.south);
            index_node_match!(adjacents_of_a.east);
            index_node_match!(adjacents_of_a.west);
        }
        false
    }
}

fn offset_coordinate(coord: &GridCoordinate, dir: GridDirection) -> GridCoordinate {
    let (x, y) = (coord.x, coord.y);
    match dir {
        GridDirection::North => GridCoordinate { x: x, y: y - 1 },
        GridDirection::South => GridCoordinate { x: x, y: y + 1 },
        GridDirection::East => GridCoordinate { x: x + 1, y: y },
        GridDirection::West => GridCoordinate { x: x - 1, y: y },
    }
}

fn is_valid_coordinate(coord: &GridCoordinate, dimension_size: GridIndexType) -> bool {
    if coord.x < 0 || coord.y < 0 {
        return false;
    }
    let (x, y) = (coord.x, coord.y);
    if x >= dimension_size as isize || y >= dimension_size as isize {
        return false;
    }
    true
}

fn to_1d_index(coord: &GridCoordinate, dimension_size: GridIndexType) -> GridIndexType {
    ((coord.y * dimension_size as isize) + coord.x) as GridIndexType
}

fn to_grid_coordinate(one_dimensional_index: usize,
                      dimension_size: GridIndexType)
                      -> GridCoordinate {
    let y = one_dimensional_index / dimension_size as usize;
    let x = one_dimensional_index - (y * dimension_size as usize);
    GridCoordinate {
        x: x as isize,
        y: y as isize,
    }
}

#[cfg(test)]
mod test {

    use super::*;
    use itertools::Itertools; // a trait

    #[test]
    fn neighbour_cells() {
        let g = SquareGrid::new(10);

        let check_expected_neighbours = |node_index, vec_expected_neighbour_indices: Vec<usize>| {
            let node_indices = g.neighbours(GridGraphNodeIndex::new(node_index))
                                .into_iter()
                                .sorted();
            let expected_indices =
                vec_expected_neighbour_indices.into_iter()
                                              .sorted()
                                              .into_iter()
                                              .map(|index: usize| GridGraphNodeIndex::new(index))
                                              .collect::<Vec<GridGraphNodeIndex>>();
            assert_eq!(node_indices, expected_indices);
        };

        // corners
        check_expected_neighbours(0, vec![1, 10]);
        check_expected_neighbours(9, vec![8, 19]);
        check_expected_neighbours(90, vec![80, 91]);
        check_expected_neighbours(99, vec![89, 98]);

        // side element examples
        check_expected_neighbours(10, vec![0, 11, 20]);
        check_expected_neighbours(1, vec![0, 2, 11]);
        check_expected_neighbours(80, vec![70, 81, 90]);
        check_expected_neighbours(89, vec![79, 88, 99]);
        check_expected_neighbours(19, vec![9, 18, 29]);
        check_expected_neighbours(8, vec![7, 9, 18]);

        // Some place with 4 neighbours inside the grid
        check_expected_neighbours(12, vec![2, 11, 13, 22]);
    }

    #[test]
    fn random_cell() {
        let g = SquareGrid::new(4);
        let cells_count = 4 * 4;
        for _ in 0..1000 {
            let grid_index = g.random_cell();
            assert!(grid_index.index() >= 0 && grid_index.index() < cells_count);
        }
    }

    #[test]
    fn linking_cells() {
        let mut g = SquareGrid::new(4);
        let a = GridGraphNodeIndex::new(0);
        let b = GridGraphNodeIndex::new(1);
        let c = GridGraphNodeIndex::new(2);

        // I'd rather use a closure, but it needs to borrow the graph immutably until
        // it goes out of scope
        // Passing the graph in allows me to use a plain function:
        // let links_sorted = |n: GridGraphNodeIndex, g: &SquareGrid| -> Vec<GridGraphNodeIndex> {
        //     g.links(n).into_iter().sorted()
        // };
        // but it's uglier in that I need to explicitly pass in the SquareGrid ref all the time
        macro_rules! links_sorted {
            ($x:expr) => (g.links($x).into_iter().sorted())
        }

        // a, b and c start with no links
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);

        g.link(a, b);
        // a - b linked bi-directionally
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a]);

        g.link(b, c);
        // a - b still linked bi-directionally after linking b - c
        // b linked to a & c bi-directionally
        // c linked to b bi-directionally
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // add the same link - ensuring we can't add parallel links
        g.link(a, b);

        // a - b still linked bi-directionally after updating exist link
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);

        // a - b unlinked
        // b still linked to c bi-directionally
        g.unlink(a, b);
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // a, b and c start all unlinked again
        g.unlink(b, c);
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);

        // Deny cycle - self links
        g.link(a, a);
        assert_eq!(links_sorted!(a), vec![]);
    }
}
<commit_msg>is_neighbour comment<commit_after>use petgraph::{Graph, Undirected};
use rand;
use rand::distributions::{IndependentSample, Range};

pub type GridIndexType = u16;
pub type GridGraphNodeIndex = ::petgraph::graph::NodeIndex<GridIndexType>;

pub enum GridDirection {
    North,
    South,
    East,
    West,
}

struct AdjacentCells {
    north: Option<GridGraphNodeIndex>,
    south: Option<GridGraphNodeIndex>,
    east: Option<GridGraphNodeIndex>,
    west: Option<GridGraphNodeIndex>,
}
impl AdjacentCells {
    fn new() -> Self {
        AdjacentCells {
            north: None,
            south: None,
            east: None,
            west: None,
        }
    }
}

#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
struct GridCoordinate {
    pub x: isize,
    pub y: isize,
}

pub struct SquareGrid {
    /// For mapping a 2D gridcoordinate (converted to a 1D index) to a graph node index.
    grid_coordinate_to_node_index_lookup: Vec<GridGraphNodeIndex>,
    graph: Graph<AdjacentCells, (), Undirected, GridIndexType>,
    dimension_size: GridIndexType,
}

impl SquareGrid {
    pub fn new(dimension_size: GridIndexType) -> SquareGrid {

        let cells_count = dimension_size * dimension_size;
        let nodes_count_hint = cells_count as usize;
        let edges_count_hint = 4 * cells_count as usize - 4 * dimension_size as usize; // Probably overkill, but don't want any capacity panics

        let mut grid = SquareGrid {
            grid_coordinate_to_node_index_lookup: Vec::with_capacity(nodes_count_hint),
            graph: Graph::with_capacity(nodes_count_hint, edges_count_hint),
            dimension_size: dimension_size,
        };

        // Although it does seem to, there is no guarantee that the index values are monotonically increasing when calling graph.add_node
        // So we maintain our own symbol table mapping gridcoordinates converted to 1d (the implicit Vec indices) to the NodeIndexes created
        // by adding a node to the graph.
        for _ in 0..cells_count {
            let node_index = grid.graph.add_node(AdjacentCells::new());
            grid.grid_coordinate_to_node_index_lookup.push(node_index);
        }

        for (index, node_index) in grid.grid_coordinate_to_node_index_lookup.iter().enumerate() {

            let coord = to_grid_coordinate(index, dimension_size);

            // Limit the lifetime of the find_neighbour_nodeindex closure so we don't get a grid
            // borrow conflict when mutating the adjacent_cells
            let (north_index, south_index, east_index, west_index) = {
                let find_neighbour_nodeindex = |dir: GridDirection| -> Option<GridGraphNodeIndex> {
                    let neighbour_coord = offset_coordinate(&coord, dir);
                    if is_valid_coordinate(&neighbour_coord, dimension_size) {
                        let node_indices_index = to_1d_index(&neighbour_coord, dimension_size);
                        let node_index =
                            grid.grid_coordinate_to_node_index_lookup[node_indices_index as usize];
                        Some(node_index)
                    } else {
                        None
                    }
                };
                (find_neighbour_nodeindex(GridDirection::North),
                 find_neighbour_nodeindex(GridDirection::South),
                 find_neighbour_nodeindex(GridDirection::East),
                 find_neighbour_nodeindex(GridDirection::West))
            };

            let adjacent_cells = grid.graph
                                     .node_weight_mut(node_index.clone())
                                     .unwrap();
            adjacent_cells.north = north_index;
            adjacent_cells.south = south_index;
            adjacent_cells.east = east_index;
            adjacent_cells.west = west_index;
        }

        grid
    }

    pub fn random_cell(&self) -> GridGraphNodeIndex {
        let random_pos = Range::new(0, self.grid_coordinate_to_node_index_lookup.len());
        let mut rng = rand::thread_rng();
        let index = random_pos.ind_sample(&mut rng);
        self.grid_coordinate_to_node_index_lookup[index]
    }

    /// Link two cells
    /// Todo - only allow links between adjacent cells? If `b` not in `g.neighbours(a)`.
    /// neighbours is a wasteful computation? It filters the None adjacents, that's all.
    /// It is so small maybe it could move return an array instead of allocating a vector on the heap
    /// then I'd have no crazy ideas about passing a pre-allocated output container.
    ///
    /// Panics if a cell does not exist.
    pub fn link(&mut self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) {
        if a != b {
            let _ = self.graph.update_edge(a, b, ());
        }
    }

    /// Unlink two cells, if a link exists between them.
    pub fn unlink(&mut self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) {

        if let Some(edge_index) = self.graph.find_edge(a, b) {
            // This will invalidate the last edge index in the graph, which is fine as we
            // are not storing them for any reason.
            self.graph.remove_edge(edge_index);
        }
    }

    /// Cell nodes that are linked to a particular node by a passage.
    pub fn links(&self, node_index: GridGraphNodeIndex) -> Vec<GridGraphNodeIndex> {
        self.graph
            .edges(node_index)
            .map(|index_edge_data_pair| index_edge_data_pair.0.clone())
            .collect()
    }

    /// Cell nodes that are to the North, South, East or West of a particular node, but not
    /// necessarily linked by a passage.
    pub fn neighbours(&self, node_index: GridGraphNodeIndex) -> Vec<GridGraphNodeIndex> {

        if let Some(adj) = self.graph.node_weight(node_index) {
            vec![adj.north, adj.south, adj.east, adj.west]
                .iter()
                .filter_map(|&maybe_adj| maybe_adj.clone())
                .collect()
        } else {
            vec![]
        }
    }

    // Arguably storing adjacents - N, S, E, W is pointless if we are given a grid index
    // it's probably quicker to calculate the valid adjacent cell indices than store them
    // and lookup from memory. However, we are currently using a grid_coordinate_to_node_index_lookup
    // table on the chance that node indices might not match grid coordinates in the expected
    // natural manner...so we just match the AdjacentCells data structure.
    // We could use `SquareGrid::neighbours` but it allocates a Vec.
    fn is_neighbour(&self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) -> bool {
        macro_rules! index_node_match {
            ($opt_grid_index:expr) => (if let Some(node_index) = $opt_grid_index {
                                           if node_index == b {
                                               return true;
                                           }
                                       })
        }
        if let Some(adjacents_of_a) = self.graph.node_weight(a) {
            index_node_match!(adjacents_of_a.north);
            index_node_match!(adjacents_of_a.south);
            index_node_match!(adjacents_of_a.east);
            index_node_match!(adjacents_of_a.west);
        }
        false
    }
}

fn offset_coordinate(coord: &GridCoordinate, dir: GridDirection) -> GridCoordinate {
    let (x, y) = (coord.x, coord.y);
    match dir {
        GridDirection::North => GridCoordinate { x: x, y: y - 1 },
        GridDirection::South => GridCoordinate { x: x, y: y + 1 },
        GridDirection::East => GridCoordinate { x: x + 1, y: y },
        GridDirection::West => GridCoordinate { x: x - 1, y: y },
    }
}

fn is_valid_coordinate(coord: &GridCoordinate, dimension_size: GridIndexType) -> bool {
    if coord.x < 0 || coord.y < 0 {
        return false;
    }
    let (x, y) = (coord.x, coord.y);
    if x >= dimension_size as isize || y >= dimension_size as isize {
        return false;
    }
    true
}

fn to_1d_index(coord: &GridCoordinate, dimension_size: GridIndexType) -> GridIndexType {
    ((coord.y * dimension_size as isize) + coord.x) as GridIndexType
}

fn to_grid_coordinate(one_dimensional_index: usize,
                      dimension_size: GridIndexType)
                      -> GridCoordinate {
    let y = one_dimensional_index / dimension_size as usize;
    let x = one_dimensional_index - (y * dimension_size as usize);
    GridCoordinate {
        x: x as isize,
        y: y as isize,
    }
}

#[cfg(test)]
mod test {

    use super::*;
    use itertools::Itertools; // a trait

    #[test]
    fn neighbour_cells() {
        let g = SquareGrid::new(10);

        let check_expected_neighbours = |node_index, vec_expected_neighbour_indices: Vec<usize>| {
            let node_indices = g.neighbours(GridGraphNodeIndex::new(node_index))
                                .into_iter()
                                .sorted();
            let expected_indices =
                vec_expected_neighbour_indices.into_iter()
                                              .sorted()
                                              .into_iter()
                                              .map(|index: usize| GridGraphNodeIndex::new(index))
                                              .collect::<Vec<GridGraphNodeIndex>>();
            assert_eq!(node_indices, expected_indices);
        };

        // corners
        check_expected_neighbours(0, vec![1, 10]);
        check_expected_neighbours(9, vec![8, 19]);
        check_expected_neighbours(90, vec![80, 91]);
        check_expected_neighbours(99, vec![89, 98]);

        // side element examples
        check_expected_neighbours(10, vec![0, 11, 20]);
        check_expected_neighbours(1, vec![0, 2, 11]);
        check_expected_neighbours(80, vec![70, 81, 90]);
        check_expected_neighbours(89, vec![79, 88, 99]);
        check_expected_neighbours(19, vec![9, 18, 29]);
        check_expected_neighbours(8, vec![7, 9, 18]);

        // Some place with 4 neighbours inside the grid
        check_expected_neighbours(12, vec![2, 11, 13, 22]);
    }

    #[test]
    fn random_cell() {
        let g = SquareGrid::new(4);
        let cells_count = 4 * 4;
        for _ in 0..1000 {
            let grid_index = g.random_cell();
            assert!(grid_index.index() >= 0 && grid_index.index() < cells_count);
        }
    }

    #[test]
    fn linking_cells() {
        let mut g = SquareGrid::new(4);
        let a = GridGraphNodeIndex::new(0);
        let b = GridGraphNodeIndex::new(1);
        let c = GridGraphNodeIndex::new(2);

        // I'd rather use a closure, but it needs to borrow the graph immutably until
        // it goes out of scope
        // Passing the graph in allows me to use a plain function:
        // let links_sorted = |n: GridGraphNodeIndex, g: &SquareGrid| -> Vec<GridGraphNodeIndex> {
        //     g.links(n).into_iter().sorted()
        // };
        // but it's uglier in that I need to explicitly pass in the SquareGrid ref all the time
        macro_rules! links_sorted {
            ($x:expr) => (g.links($x).into_iter().sorted())
        }

        // a, b and c start with no links
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);

        g.link(a, b);
        // a - b linked bi-directionally
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a]);

        g.link(b, c);
        // a - b still linked bi-directionally after linking b - c
        // b linked to a & c bi-directionally
        // c linked to b bi-directionally
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // add the same link - ensuring we can't add parallel links
        g.link(a, b);

        // a - b still linked bi-directionally after updating exist link
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);

        // a - b unlinked
        // b still linked to c bi-directionally
        g.unlink(a, b);
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // a, b and c start all unlinked again
        g.unlink(b, c);
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);

        // Deny cycle - self links
        g.link(a, a);
        assert_eq!(links_sorted!(a), vec![]);
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::marker::PhantomData;
use std::net::SocketAddr;
use std::sync::Arc;
use std::thread;

use BindServer;
use futures::stream::Stream;
use net2;
use tokio_core::net::{TcpStream, TcpListener};
use tokio_core::reactor::{Core, Handle};
use tokio_service::NewService;

// TODO: Add more options, e.g.:
// - max concurrent requests
// - request timeout
// - read timeout
// - write timeout
// - max idle time
// - max lifetime

/// A builder for TCP servers.
///
/// Setting up a server needs, at minimum:
///
/// - A server protocol implementation
/// - An address
/// - A service to provide
///
/// In addition to those basics, the builder provides some additional
/// configuration, which is expected to grow over time.
///
/// See the crate docs for an example.
pub struct TcpServer<Kind, P> {
    _kind: PhantomData<Kind>,
    proto: Arc<P>,
    threads: usize,
    addr: SocketAddr,
}

impl<Kind, P> TcpServer<Kind, P> where
    P: BindServer<Kind, TcpStream> + Send + Sync + 'static
{
    /// Starts building a server for the given protocol and address, with
    /// default configuration.
    ///
    /// Generally, a protocol is implemented *not* by implementing the
    /// `BindServer` trait directly, but instead by implementing one of the
    /// protocol traits:
    ///
    /// - `pipeline::Server`
    /// - `multiplex::Server`
    /// - `streaming::pipeline::Server`
    /// - `streaming::multiplex::Server`
    ///
    /// See the crate documentation for more details on those traits.
    pub fn new(protocol: P, addr: SocketAddr) -> TcpServer<Kind, P> {
        TcpServer {
            _kind: PhantomData,
            proto: Arc::new(protocol),
            threads: 1,
            addr: addr,
        }
    }

    /// Set the address for the server.
    pub fn addr(&mut self, addr: SocketAddr) {
        self.addr = addr;
    }

    /// Set the number of threads running simultaneous event loops (Unix only).
    pub fn threads(&mut self, threads: usize) {
        assert!(threads > 0);
        if cfg!(unix) {
            self.threads = threads;
        }
    }

    /// Start up the server, providing the given service on it.
    ///
    /// This method will block the current thread until the server is shut down.
    pub fn serve<S>(&self, new_service: S) where
        S: NewService<Request = P::ServiceRequest,
                      Response = P::ServiceResponse,
                      Error = P::ServiceError> + Send + Sync + 'static,
    {
        let proto = self.proto.clone();
        let new_service = Arc::new(new_service);
        let addr = self.addr;
        let workers = self.threads;

        let threads = (0..self.threads - 1).map(|i| {
            let proto = proto.clone();
            let new_service = new_service.clone();

            thread::Builder::new().name(format!("worker{}", i)).spawn(move || {
                serve(proto, addr, workers, &new_service)
            }).unwrap()
        }).collect::<Vec<_>>();

        serve(proto, addr, workers, &new_service);

        for thread in threads {
            thread.join().unwrap();
        }
    }
}

fn serve<P, Kind, S>(binder: Arc<P>, addr: SocketAddr, workers: usize, new_service: &S)
    where P: BindServer<Kind, TcpStream>,
          S: NewService<Request = P::ServiceRequest,
                        Response = P::ServiceResponse,
                        Error = P::ServiceError> + 'static,
{
    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let listener = listener(&addr, workers, &handle).unwrap();

    let server = listener.incoming().for_each(move |(socket, _)| {
        // Create the service
        let service = try!(new_service.new_service());

        // Bind it!
        binder.bind_server(&handle, socket, service);

        Ok(())
    });

    core.run(server).unwrap();
}

fn listener(addr: &SocketAddr,
            workers: usize,
            handle: &Handle) -> io::Result<TcpListener> {
    let listener = match *addr {
        SocketAddr::V4(_) => try!(net2::TcpBuilder::new_v4()),
        SocketAddr::V6(_) => try!(net2::TcpBuilder::new_v6()),
    };
    try!(configure_tcp(workers, &listener));
    try!(listener.reuse_address(true));
    try!(listener.bind(addr));
    listener.listen(1024).and_then(|l| {
        TcpListener::from_listener(l, addr, handle)
    })
}

#[cfg(unix)]
fn configure_tcp(workers: usize, tcp: &net2::TcpBuilder) -> io::Result<()> {
    use net2::unix::*;

    if workers > 1 {
        try!(tcp.reuse_port(true));
    }

    Ok(())
}

#[cfg(windows)]
fn configure_tcp(workers: usize, _tcp: &net2::TcpBuilder) -> io::Result<()> {
    Ok(())
}
<commit_msg>Add `with_handle` endpoint for `TcpServer`<commit_after>use std::io;
use std::marker::PhantomData;
use std::net::SocketAddr;
use std::sync::Arc;
use std::thread;

use BindServer;
use futures::stream::Stream;
use net2;
use tokio_core::net::{TcpStream, TcpListener};
use tokio_core::reactor::{Core, Handle};
use tokio_service::NewService;

// TODO: Add more options, e.g.:
// - max concurrent requests
// - request timeout
// - read timeout
// - write timeout
// - max idle time
// - max lifetime

/// A builder for TCP servers.
///
/// Setting up a server needs, at minimum:
///
/// - A server protocol implementation
/// - An address
/// - A service to provide
///
/// In addition to those basics, the builder provides some additional
/// configuration, which is expected to grow over time.
///
/// See the crate docs for an example.
pub struct TcpServer<Kind, P> {
    _kind: PhantomData<Kind>,
    proto: Arc<P>,
    threads: usize,
    addr: SocketAddr,
}

impl<Kind, P> TcpServer<Kind, P> where
    P: BindServer<Kind, TcpStream> + Send + Sync + 'static
{
    /// Starts building a server for the given protocol and address, with
    /// default configuration.
    ///
    /// Generally, a protocol is implemented *not* by implementing the
    /// `BindServer` trait directly, but instead by implementing one of the
    /// protocol traits:
    ///
    /// - `pipeline::Server`
    /// - `multiplex::Server`
    /// - `streaming::pipeline::Server`
    /// - `streaming::multiplex::Server`
    ///
    /// See the crate documentation for more details on those traits.
    pub fn new(protocol: P, addr: SocketAddr) -> TcpServer<Kind, P> {
        TcpServer {
            _kind: PhantomData,
            proto: Arc::new(protocol),
            threads: 1,
            addr: addr,
        }
    }

    /// Set the address for the server.
    pub fn addr(&mut self, addr: SocketAddr) {
        self.addr = addr;
    }

    /// Set the number of threads running simultaneous event loops (Unix only).
    pub fn threads(&mut self, threads: usize) {
        assert!(threads > 0);
        if cfg!(unix) {
            self.threads = threads;
        }
    }

    /// Start up the server, providing the given service on it.
    ///
    /// This method will block the current thread until the server is shut down.
    pub fn serve<S>(&self, new_service: S) where
        S: NewService<Request = P::ServiceRequest,
                      Response = P::ServiceResponse,
                      Error = P::ServiceError> + Send + Sync + 'static,
    {
        let new_service = Arc::new(new_service);
        self.with_handle(move |_| new_service.clone())
    }

    /// Start up the server, providing the given service on it, and providing
    /// access to the event loop handle.
    ///
    /// The `new_service` argument is a closure that is given an event loop
    /// handle, and produces a value implementing `NewService`. That value is in
    /// turned used to make a new service instance for each incoming connection.
    ///
    /// This method will block the current thread until the server is shut down.
    pub fn with_handle<F, S>(&self, new_service: F) where
        F: Fn(&Handle) -> S + Send + Sync + 'static,
        S: NewService<Request = P::ServiceRequest,
                      Response = P::ServiceResponse,
                      Error = P::ServiceError> + Send + Sync + 'static,
    {
        let proto = self.proto.clone();
        let new_service = Arc::new(new_service);
        let addr = self.addr;
        let workers = self.threads;

        let threads = (0..self.threads - 1).map(|i| {
            let proto = proto.clone();
            let new_service = new_service.clone();

            thread::Builder::new().name(format!("worker{}", i)).spawn(move || {
                serve(proto, addr, workers, &*new_service)
            }).unwrap()
        }).collect::<Vec<_>>();

        serve(proto, addr, workers, &*new_service);

        for thread in threads {
            thread.join().unwrap();
        }
    }
}

fn serve<P, Kind, F, S>(binder: Arc<P>, addr: SocketAddr, workers: usize, new_service: &F)
    where P: BindServer<Kind, TcpStream>,
          F: Fn(&Handle) -> S,
          S: NewService<Request = P::ServiceRequest,
                        Response = P::ServiceResponse,
                        Error = P::ServiceError> + 'static,
{
    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let new_service = new_service(&handle);
    let listener = listener(&addr, workers, &handle).unwrap();

    let server = listener.incoming().for_each(move |(socket, _)| {
        // Create the service
        let service = try!(new_service.new_service());

        // Bind it!
        binder.bind_server(&handle, socket, service);

        Ok(())
    });

    core.run(server).unwrap();
}

fn listener(addr: &SocketAddr,
            workers: usize,
            handle: &Handle) -> io::Result<TcpListener> {
    let listener = match *addr {
        SocketAddr::V4(_) => try!(net2::TcpBuilder::new_v4()),
        SocketAddr::V6(_) => try!(net2::TcpBuilder::new_v6()),
    };
    try!(configure_tcp(workers, &listener));
    try!(listener.reuse_address(true));
    try!(listener.bind(addr));
    listener.listen(1024).and_then(|l| {
        TcpListener::from_listener(l, addr, handle)
    })
}

#[cfg(unix)]
fn configure_tcp(workers: usize, tcp: &net2::TcpBuilder) -> io::Result<()> {
    use net2::unix::*;

    if workers > 1 {
        try!(tcp.reuse_port(true));
    }

    Ok(())
}

#[cfg(windows)]
fn configure_tcp(workers: usize, _tcp: &net2::TcpBuilder) -> io::Result<()> {
    Ok(())
}
<|endoftext|>


<commit_before>#![feature(slice_patterns)]

use std::fs::File;
use std::path::Path;
use std::io::Read;

extern crate tournament;

fn file_equal(output_file: &str, expected_file: &str) {
    let output = match File::open(&Path::new(output_file)) {
        Err(e) => panic!("Couldn't open {}: {}", output_file, e),
        Ok(mut f) => {
            let mut buf = String::new();
            match f.read_to_string(&mut buf) {
                Err(e) => panic!("Couldn't read {}: {}", output_file, e),
                Ok(_) => buf
            }
        }
    };
    let expected = match File::open(&Path::new(expected_file)) {
        Err(e) => panic!("Couldn't open {}: {}", expected_file, e),
        Ok(mut f) => {
            let mut buf = String::new();
            match f.read_to_string(&mut buf) {
                Err(e) => panic!("Couldn't read {}: {}", expected_file, e),
                Ok(_) => buf
            }
        }
    };
    assert_eq!("\n".to_string() + output.as_ref(), "\n".to_string() + expected.as_ref());

}

#[test]
#[ignore]
fn test_good() {
    assert_eq!(tournament::tally(&Path::new("tests/input1.txt"), &Path::new("tests/output1.txt")), Ok(6));
    file_equal("tests/output1.txt", "tests/expected1.txt");
}

#[test]
#[ignore]
fn test_ignore_bad_lines() {
    assert_eq!(tournament::tally(&Path::new("tests/input2.txt"), &Path::new("tests/output2.txt")), Ok(6));
    file_equal("tests/output2.txt", "tests/expected2.txt");
}

#[test]
#[ignore]
fn test_incomplete_competition() {
    assert_eq!(tournament::tally(&Path::new("tests/input3.txt"), &Path::new("tests/output3.txt")), Ok(4));
    file_equal("tests/output3.txt", "tests/expected3.txt");
}
<commit_msg>Change paths to work with cargo and remove an unnecessary flag<commit_after>use std::fs::File;
use std::path::Path;
use std::io::Read;

extern crate tournament;

fn file_equal(output_file: &str, expected_file: &str) {
    let output = match File::open(&Path::new(output_file)) {
        Err(e) => panic!("Couldn't open {}: {}", output_file, e),
        Ok(mut f) => {
            let mut buf = String::new();
            match f.read_to_string(&mut buf) {
                Err(e) => panic!("Couldn't read {}: {}", output_file, e),
                Ok(_) => buf
            }
        }
    };
    let expected = match File::open(&Path::new(expected_file)) {
        Err(e) => panic!("Couldn't open {}: {}", expected_file, e),
        Ok(mut f) => {
            let mut buf = String::new();
            match f.read_to_string(&mut buf) {
                Err(e) => panic!("Couldn't read {}: {}", expected_file, e),
                Ok(_) => buf
            }
        }
    };
    assert_eq!("\n".to_string() + output.as_ref(), "\n".to_string() + expected.as_ref());

}

#[test]
#[ignore]
fn test_good() {
    assert_eq!(tournament::tally(&Path::new("tests/input1.txt"), &Path::new("tests/output1.txt")), Ok(6));
    file_equal("tests/output1.txt", "tests/expected1.txt");
}

#[test]
#[ignore]
fn test_ignore_bad_lines() {
    assert_eq!(tournament::tally(&Path::new("tests/input2.txt"), &Path::new("tests/output2.txt")), Ok(6));
    file_equal("tests/output2.txt", "tests/expected2.txt");
}

#[test]
#[ignore]
fn test_incomplete_competition() {
    assert_eq!(tournament::tally(&Path::new("tests/input3.txt"), &Path::new("tests/output3.txt")), Ok(4));
    file_equal("tests/output3.txt", "tests/expected3.txt");
}
<|endoftext|>


<commit_before>//! Key algorithms used in Matrix spec.

use ruma_macros::StringEnum;

use crate::PrivOwnedStr;

/// The basic key algorithms in the specification.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
#[ruma_enum(rename_all = "snake_case")]
pub enum DeviceKeyAlgorithm {
    /// The Ed25519 signature algorithm.
    Ed25519,

    /// The Curve25519 ECDH algorithm.
    Curve25519,

    /// The Curve25519 ECDH algorithm, but the key also contains signatures
    SignedCurve25519,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

/// The signing key algorithms defined in the Matrix spec.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
#[ruma_enum(rename_all = "snake_case")]
pub enum SigningKeyAlgorithm {
    /// The Ed25519 signature algorithm.
    Ed25519,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

/// An encryption algorithm to be used to encrypt messages sent to a room.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
pub enum EventEncryptionAlgorithm {
    /// Olm version 1 using Curve25519, AES-256, and SHA-256.
    #[ruma_enum(rename = "m.olm.v1.curve25519-aes-sha2")]
    OlmV1Curve25519AesSha2,

    /// Megolm version 1 using AES-256 and SHA-256.
    #[ruma_enum(rename = "m.megolm.v1.aes-sha2")]
    MegolmV1AesSha2,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

/// A key algorithm to be used to generate a key from a passphrase.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(DeserializeFromCowStr, SerializeAsRefStr))]
pub enum KeyDerivationAlgorithm {
    /// PBKDF2
    #[ruma_enum(rename = "m.pbkdf2")]
    Pbkfd2,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

#[cfg(test)]
mod tests {
    use super::{DeviceKeyAlgorithm, SigningKeyAlgorithm};

    #[test]
    fn parse_device_key_algorithm() {
        assert_eq!(DeviceKeyAlgorithm::from("ed25519"), DeviceKeyAlgorithm::Ed25519);
        assert_eq!(DeviceKeyAlgorithm::from("curve25519"), DeviceKeyAlgorithm::Curve25519);
        assert_eq!(
            DeviceKeyAlgorithm::from("signed_curve25519"),
            DeviceKeyAlgorithm::SignedCurve25519
        );
    }

    #[test]
    fn parse_signing_key_algorithm() {
        assert_eq!(SigningKeyAlgorithm::from("ed25519"), SigningKeyAlgorithm::Ed25519);
    }

    #[test]
    fn event_encryption_algorithm_serde() {
        use serde_json::json;

        use super::EventEncryptionAlgorithm;
        use crate::serde::test::serde_json_eq;

        serde_json_eq(EventEncryptionAlgorithm::MegolmV1AesSha2, json!("m.megolm.v1.aes-sha2"));
        serde_json_eq(
            EventEncryptionAlgorithm::OlmV1Curve25519AesSha2,
            json!("m.olm.v1.curve25519-aes-sha2"),
        );
        serde_json_eq(EventEncryptionAlgorithm::from("io.ruma.test"), json!("io.ruma.test"));
    }

    #[test]
    fn key_derivation_algorithm_serde() {
        use serde_json::json;

        use super::KeyDerivationAlgorithm;
        use crate::serde::test::serde_json_eq;

        serde_json_eq(KeyDerivationAlgorithm::Pbkfd2, json!("m.pbkdf2"));
    }
}
<commit_msg>identifiers: Remove dead code<commit_after>//! Key algorithms used in Matrix spec.

use ruma_macros::StringEnum;

use crate::PrivOwnedStr;

/// The basic key algorithms in the specification.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
#[ruma_enum(rename_all = "snake_case")]
pub enum DeviceKeyAlgorithm {
    /// The Ed25519 signature algorithm.
    Ed25519,

    /// The Curve25519 ECDH algorithm.
    Curve25519,

    /// The Curve25519 ECDH algorithm, but the key also contains signatures
    SignedCurve25519,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

/// The signing key algorithms defined in the Matrix spec.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
#[ruma_enum(rename_all = "snake_case")]
pub enum SigningKeyAlgorithm {
    /// The Ed25519 signature algorithm.
    Ed25519,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

/// An encryption algorithm to be used to encrypt messages sent to a room.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
pub enum EventEncryptionAlgorithm {
    /// Olm version 1 using Curve25519, AES-256, and SHA-256.
    #[ruma_enum(rename = "m.olm.v1.curve25519-aes-sha2")]
    OlmV1Curve25519AesSha2,

    /// Megolm version 1 using AES-256 and SHA-256.
    #[ruma_enum(rename = "m.megolm.v1.aes-sha2")]
    MegolmV1AesSha2,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

/// A key algorithm to be used to generate a key from a passphrase.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
pub enum KeyDerivationAlgorithm {
    /// PBKDF2
    #[ruma_enum(rename = "m.pbkdf2")]
    Pbkfd2,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

#[cfg(test)]
mod tests {
    use super::{DeviceKeyAlgorithm, SigningKeyAlgorithm};

    #[test]
    fn parse_device_key_algorithm() {
        assert_eq!(DeviceKeyAlgorithm::from("ed25519"), DeviceKeyAlgorithm::Ed25519);
        assert_eq!(DeviceKeyAlgorithm::from("curve25519"), DeviceKeyAlgorithm::Curve25519);
        assert_eq!(
            DeviceKeyAlgorithm::from("signed_curve25519"),
            DeviceKeyAlgorithm::SignedCurve25519
        );
    }

    #[test]
    fn parse_signing_key_algorithm() {
        assert_eq!(SigningKeyAlgorithm::from("ed25519"), SigningKeyAlgorithm::Ed25519);
    }

    #[test]
    fn event_encryption_algorithm_serde() {
        use serde_json::json;

        use super::EventEncryptionAlgorithm;
        use crate::serde::test::serde_json_eq;

        serde_json_eq(EventEncryptionAlgorithm::MegolmV1AesSha2, json!("m.megolm.v1.aes-sha2"));
        serde_json_eq(
            EventEncryptionAlgorithm::OlmV1Curve25519AesSha2,
            json!("m.olm.v1.curve25519-aes-sha2"),
        );
        serde_json_eq(EventEncryptionAlgorithm::from("io.ruma.test"), json!("io.ruma.test"));
    }

    #[test]
    fn key_derivation_algorithm_serde() {
        use serde_json::json;

        use super::KeyDerivationAlgorithm;
        use crate::serde::test::serde_json_eq;

        serde_json_eq(KeyDerivationAlgorithm::Pbkfd2, json!("m.pbkdf2"));
    }
}
<|endoftext|>


<commit_before>//! Contains test for all types supporting `bind_parameter`
//!
//! These tests assume there is a Stage table with a Varchar in 'A', an Integer in 'B' and a Real
//! in 'C'
extern crate odbc;
use odbc::*;

#[test]
fn exec_direct() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    let stmt = Statement::with_parent(&conn).unwrap();

    // select '你好' as hello
    if let Ok(Data(mut stmt)) = stmt.exec_direct_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 196, 227, 186, 195, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32].as_slice()) {
        while let Some(mut cursor) = stmt.fetch().unwrap() {
            match cursor.get_data::<Vec<u8>>(1).unwrap() {
                Some(val) => assert_eq!(val, vec![196, 227, 186, 195]),  // when  你好 is encoded by gbk, it is [196, 227, 186, 195]
                None => panic!(" NULL"),
            }
        }
    } else {
        panic!("SELECT did not return result set");
    }
}

#[test]
fn prepare_1() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    // select '你好' as hello where 1 = ?
    let stmt = Statement::with_parent(&conn).unwrap().prepare_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 196, 227, 186, 195, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32, 119, 104, 101, 114, 101, 32, 32, 49, 32, 61, 32, 63, 32].as_slice()).unwrap();
    let stmt = stmt.bind_parameter(1, &2).unwrap();

    match stmt.execute().unwrap() {
        Data(mut stmt) => {
            while let Some(mut cursor) = stmt.fetch().unwrap() {
                match cursor.get_data::<Vec<u8>>(1).unwrap() {
                    Some(val) => assert_eq!(val, vec![196, 227, 186, 195]),
                    None => panic!(" NULL"),
                }
            }
        }
        NoData(_) => {
            panic!("SELECT did not return result set");
        }
    }

}

#[test]
fn prepare_2() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    // select '你好' as hello where '你好' = ?
    let stmt = Statement::with_parent(&conn).unwrap().prepare_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 196, 227, 186, 195, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32, 119, 104, 101, 114, 101, 32, 32, 39, 196, 227, 186, 195, 39, 32, 61, 32, 63, 32].as_slice()).unwrap();
    // bind  gbk encoded byte
    let param = vec![196u8, 227u8, 186u8, 195u8];
    let stmt = stmt.bind_parameter(1, &param).unwrap();

    if let Ok(Data(mut stmt)) = stmt.execute() {
        while let Some(mut cursor) = stmt.fetch().unwrap() {
            match cursor.get_data::<Vec<u8>>(1).unwrap() {
                Some(val) => assert_eq!(val, vec![196, 227, 186, 195]),
                None => panic!(" NULL"),
            }
        }
    } else {
        panic!("SELECT did not return result set");
    }
}
<commit_msg>test utf-8 encode bytes in appveyor windows<commit_after>//! Contains test for all types supporting `bind_parameter`
//!
//! These tests assume there is a Stage table with a Varchar in 'A', an Integer in 'B' and a Real
//! in 'C'
extern crate odbc;
use odbc::*;

#[test]
#[ignore]
/// tested in windows中文版
fn _exec_direct() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    let stmt = Statement::with_parent(&conn).unwrap();

    // select '你好' as hello
    if let Ok(Data(mut stmt)) = stmt.exec_direct_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 196, 227, 186, 195, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32].as_slice()) {
        while let Some(mut cursor) = stmt.fetch().unwrap() {
            match cursor.get_data::<Vec<u8>>(1).unwrap() {
                Some(val) => assert_eq!(val, vec![196, 227, 186, 195]),  // when  你好 is encoded by gbk, it is [196, 227, 186, 195]
                None => panic!(" NULL"),
            }
        }
    } else {
        panic!("SELECT did not return result set");
    }
}

#[test]
#[ignore]
/// tested in windows中文版
fn _prepare_1() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    // select '你好' as hello where 1 = ?
    let stmt = Statement::with_parent(&conn).unwrap().prepare_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 196, 227, 186, 195, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32, 119, 104, 101, 114, 101, 32, 32, 49, 32, 61, 32, 63, 32].as_slice()).unwrap();
    let stmt = stmt.bind_parameter(1, &1).unwrap();

    match stmt.execute().unwrap() {
        Data(mut stmt) => {
            while let Some(mut cursor) = stmt.fetch().unwrap() {
                match cursor.get_data::<Vec<u8>>(1).unwrap() {
                    Some(val) => assert_eq!(val, vec![196, 227, 186, 195]),
                    None => panic!(" NULL"),
                }
            }
        }
        NoData(_) => {
            panic!("SELECT did not return result set");
        }
    }

}

#[test]
#[ignore]
/// tested in windows中文版
fn _prepare_2() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    // select '你好' as hello where '你好' = ?
    let stmt = Statement::with_parent(&conn).unwrap().prepare_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 196, 227, 186, 195, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32, 119, 104, 101, 114, 101, 32, 32, 39, 196, 227, 186, 195, 39, 32, 61, 32, 63, 32].as_slice()).unwrap();
    // bind  gbk encoded byte
    let param = vec![196u8, 227u8, 186u8, 195u8];
    let stmt = stmt.bind_parameter(1, &param).unwrap();

    if let Ok(Data(mut stmt)) = stmt.execute() {
        while let Some(mut cursor) = stmt.fetch().unwrap() {
            match cursor.get_data::<Vec<u8>>(1).unwrap() {
                Some(val) => assert_eq!(val, vec![196, 227, 186, 195]),
                None => panic!(" NULL"),
            }
        }
    } else {
        panic!("SELECT did not return result set");
    }
}

#[test]
fn exec_direct() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    let stmt = Statement::with_parent(&conn).unwrap();

    // select '你好' as hello
    if let Ok(Data(mut stmt)) = stmt.exec_direct_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 228, 189, 160, 229, 165, 189, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111].as_slice()) {
        while let Some(mut cursor) = stmt.fetch().unwrap() {
            match cursor.get_data::<Vec<u8>>(1).unwrap() {
                Some(val) => assert_eq!(val, vec![228u8, 189u8, 160u8, 229u8, 165u8, 189u8]),  // when  你好 is encoded by utf8, it is [228, 189, 160, 229, 165, 189]
                None => panic!(" NULL"),
            }
        }
    } else {
        panic!("SELECT did not return result set");
    }
}

#[test]
fn prepare_1() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    // select '你好' as hello where 1 = ?
    let stmt = Statement::with_parent(&conn).unwrap().prepare_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 228, 189, 160, 229, 165, 189, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32, 119, 104, 101, 114, 101, 32, 49, 32, 61, 32, 63, 32].as_slice()).unwrap();
    let stmt = stmt.bind_parameter(1, &1).unwrap();

    match stmt.execute().unwrap() {
        Data(mut stmt) => {
            while let Some(mut cursor) = stmt.fetch().unwrap() {
                match cursor.get_data::<Vec<u8>>(1).unwrap() {
                    Some(val) => assert_eq!(val, vec![228u8, 189u8, 160u8, 229u8, 165u8, 189u8]),
                    None => panic!(" NULL"),
                }
            }
        }
        NoData(_) => {
            panic!("SELECT did not return result set");
        }
    }

}

#[test]
fn prepare_2() {
    let env = create_environment_v3().unwrap();
    let conn = env.connect("TestDataSource", "", "").unwrap();
    // select '你好' as hello where '你好' = ?
    let stmt = Statement::with_parent(&conn).unwrap().prepare_bytes(vec![115, 101, 108, 101, 99, 116, 32, 39, 228, 189, 160, 229, 165, 189, 39, 32, 97, 115, 32, 104, 101, 108, 108, 111, 32, 119, 104, 101, 114, 101, 32, 39, 228, 189, 160, 229, 165, 189, 39, 32, 61, 32, 63, 32].as_slice()).unwrap();
    // bind  gbk encoded byte
    let param = vec![228u8, 189u8, 160u8, 229u8, 165u8, 189u8];
    let stmt = stmt.bind_parameter(1, &param).unwrap();

    if let Ok(Data(mut stmt)) = stmt.execute() {
        while let Some(mut cursor) = stmt.fetch().unwrap() {
            match cursor.get_data::<Vec<u8>>(1).unwrap() {
                Some(val) => assert_eq!(val, vec![228u8, 189u8, 160u8, 229u8, 165u8, 189u8]),
                None => panic!(" NULL"),
            }
        }
    } else {
        panic!("SELECT did not return result set");
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(stainless)]

extern crate proton_cli;
extern crate tempdir;
extern crate git2;
extern crate rustc_serialize;

pub use std::{env, fs};
pub use std::fs::File;
pub use std::path::{Path, PathBuf};
pub use std::io::Read;

pub use git2::{Repository, Signature, Time};
pub use tempdir::TempDir;
pub use rustc_serialize::json;

pub use proton_cli::{Error, Project, initialize_project};

describe! initialize_project {
    before_each {
        let signature = Signature::now(
            "Proton Lights", "proton@teslaworks.net").unwrap();
        let root_dir = TempDir::new("proton_cli_tests").unwrap();
    }

    it "works with an empty directory" {
        let root = root_dir.path();
        initialize_project(root, &signature).expect("Initialization failed");
    }

    after_each {
        // Assert that exactly Protonfile.json and .git exist.
        let protonfile_path = root.join(Path::new("Protonfile.json"));
        let git_path = root.join(Path::new(".git"));
        assert!(protonfile_path.is_file());
        assert!(git_path.is_dir());
        assert_eq!(2, fs::read_dir(root).unwrap().count());

        // Check that protonfile has right content
        let protonfile_project = File::open(&protonfile_path)
            .and_then(|mut protonfile| {
                let mut content = "".to_owned();
                protonfile.read_to_string(&mut content).map(|_| content)
            })
            .map_err(Error::Io)
            .and_then(|content| json::decode(&content).map_err(Error::JsonDecode))
            .expect("Failed to load protonfile into Project");
        assert_eq!(Project::empty(), protonfile_project);

        // Open a git repo
        let repo = Repository::open(root).unwrap();
        match repo.refname_to_id("HEAD")
            .and_then(|oid| repo.find_commit(oid))
            .and_then(|commit| Ok(commit.message().unwrap().to_owned())) {
            Ok(c) => println!("{:?}", c),
            Err(e) => println!("{:?}", e),
        }
        panic!("Hellooerogerv");
        // Check that master has exactly 1 commit
        // Check that it includes the protonfile
        // Check that it has the right signature
    }
}
<commit_msg>Find master<commit_after>#![feature(plugin)]
#![plugin(stainless)]

extern crate proton_cli;
extern crate tempdir;
extern crate git2;
extern crate rustc_serialize;

pub use std::{env, fs};
pub use std::fs::File;
pub use std::path::{Path, PathBuf};
pub use std::io::Read;

pub use git2::{Repository, Signature, Time};
pub use tempdir::TempDir;
pub use rustc_serialize::json;

pub use proton_cli::{Error, Project, initialize_project};

describe! initialize_project {
    before_each {
        let signature = Signature::now("tester", "t@example.com").unwrap();
        let root_dir = TempDir::new("proton_cli_tests").unwrap();
    }

    it "works with an empty directory" {
        let root = root_dir.path();
        initialize_project(root, &signature).expect("Initialization failed");
    }

    after_each {
        // Assert that exactly Protonfile.json and .git exist.
        let protonfile_path = root.join(Path::new("Protonfile.json"));
        let git_path = root.join(Path::new(".git"));
        assert!(protonfile_path.is_file());
        assert!(git_path.is_dir());
        assert_eq!(2, fs::read_dir(root).unwrap().count());

        // Check that protonfile has right content
        assert_eq!(Project::empty(), File::open(&protonfile_path)
            .and_then(|mut protonfile| {
                let mut content = "".to_owned();
                protonfile.read_to_string(&mut content).map(|_| content)
            })
            .map_err(Error::Io)
            .and_then(|content| json::decode(&content).map_err(Error::JsonDecode))
            .expect("Loading protonfile into Project failed"));

        // Open a git repo
        let repo = Repository::open(root).unwrap();
        let master_head = repo.refname_to_id("refs/heads/master")
            .and_then(|oid| repo.find_commit(oid))
            .expect("Finding master failed");
        let master_tree = master_head.tree().expect("Opening master tree failed");

        // Check that master has exactly 1 commit
        assert_eq!(0, master_head.parents().count());;

        // Check that it includes the protonfile

        // Check that it has the right signature
    }
}
<|endoftext|>


<commit_before>//! String-interning facility.
//!
//! This module, initially based on [Servo's string-cache
//! library](https://github.com/servo/string-cache), provides a hash-based
//! string-interning implementation that utilizes the small-string optimization
//! when possible.
//!
//! Unline Servo's string-cache library, this module leverages Rust's
//! lifetime-safety guarantees — instead of mutex-protected static
//! globals — to safely tie symbols to the lifetimes of their parent
//! symbol pools, which allows creation of multiple independent symbol pools.
//!
//! # Examples
//!
//! [`Sym`](struct.Sym.html) is `Copy`:  it can be passed by value without
//! resulting in a move.
//!
//! ```rust
//! extern crate cripes;
//! use cripes::symbol::Pool;
//!
//! /// Take ownership of a value, consuming it.
//! fn consume<T>(v: T) {}
//!
//! fn main() {
//!     let pool = Pool::new();
//!     let sym = pool.sym("a very long string that will almost certainly be stored in the pool");
//!     consume(sym);
//!     println!("The symbol is still valid: {:?}", sym.as_ref());
//! }
//! ```
//!
//! `Sym` is also lifetime-safe: it cannot outlive its parent pool.
//!
//! ```rust,compile_fail
//! extern crate cripes;
//! use cripes::symbol::Pool;
//!
//! fn main() {
//!     let sym = { let pool = Pool::new(); //~ ERROR `pool` does not live long enough
//!                 pool.sym("xyz") };
//! }
//! ```
use std::fmt;
use std::convert::AsRef;
use std::marker::PhantomData;
use std::hash::{Hash, Hasher, SipHasher};
use std::collections::BTreeMap;
use std::borrow::ToOwned;
use std::sync::Mutex;

use super::util::hash::{stdhash as hash};

mod private;                    // implementation details

#[cfg(test)] mod tests;

use self::private::PackFormat;

/* ****************************************************************
 * Pool
 */
/// A collection of symbols.
///
/// See [the module-level documentation](index.html) for more information.
#[derive(Debug)]
pub struct Pool {
    map:  Mutex<BTreeMap<u64,String>>
}

impl Clone for Pool {
    fn clone(&self) -> Self {
        let m = self.map.lock().expect("Failed to lock symbol pool mutex for clone");
        Pool{map: Mutex::new(m.clone())}
    }
}

impl Pool {
    /// Create a new symbol pool.
    #[inline]
    pub fn new() -> Pool {
        Pool{map: Mutex::new(BTreeMap::new())}
    }

    /// Fetch a symbol corresponding to the given string.
    #[inline(always)]
    pub fn sym<'a>(&'a self, name: &str) -> Sym<'a> {
        Sym(unsafe { self.symbol(name) }, PhantomData)
    }

    /// Fetch a lifetime-unsafe symbol corresponding to the given string.
    ///
    /// Care must be taken to ensure that the returned symbol is not used after
    /// the pool goes out of scope.
    ///
    /// This method should remain private, and shouldn't be used unless you're
    /// absolutely certain it's what you want.
    unsafe fn symbol(&self, name: &str) -> private::Symbol {
        if name.len() <= private::INLINE_SYMBOL_MAX_LEN {
            private::Inline::new(name).pack()
        } else {
            let hsh = hash::<_, SipHasher>(&name) << 1;
            let mut map = self.map.lock().expect("Failed to lock symbol pool mutex for insertion");
            if ! map.contains_key(&hsh) {
                map.insert(hsh, name.to_owned());
            }
            private::Pooled::new(hsh, self).pack()
        }
    }
}

impl Default for Pool {
    #[inline]
    fn default() -> Self {
        Pool{map: Default::default()}
    }
}

/* ****************************************************************
 * Symbol
 */
/// Symbol obtained from a symbol pool.
///
/// Instances of `Sym` are created using the `sym` method on
/// [`Pool`](struct.Pool.html).  See [the module-level
/// documentation](index.html) for more information.

// `Sym` is a safe wrapper around the internal `private::Symbol`, which does not carry
// a lifetime parameter and therefore cannot ensure that any pool reference
// carried by an instance is still valid.  By adding a lifetime parameter and
// appropriate `PhantomData` data member, `Sym` prevents this case.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub struct Sym<'a>(private::Symbol, PhantomData<&'a Pool>);

impl<'a> fmt::Display for Sym<'a> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        <private::Symbol as fmt::Display>::fmt(&self.0, f)
    }
}

impl<'a> AsRef<str> for Sym<'a> {
    #[inline]
    fn as_ref(&self) -> &str {
        self.0.as_ref()
    }
}

impl<'a> Hash for Sym<'a>  {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}
<commit_msg>symbol: accept `AsRef<str>` for symbol-name inputs<commit_after>//! String-interning facility.
//!
//! This module, initially based on [Servo's string-cache
//! library](https://github.com/servo/string-cache), provides a hash-based
//! string-interning implementation that utilizes the small-string optimization
//! when possible.
//!
//! Unline Servo's string-cache library, this module leverages Rust's
//! lifetime-safety guarantees — instead of mutex-protected static
//! globals — to safely tie symbols to the lifetimes of their parent
//! symbol pools, which allows creation of multiple independent symbol pools.
//!
//! # Examples
//!
//! [`Sym`](struct.Sym.html) is `Copy`:  it can be passed by value without
//! resulting in a move.
//!
//! ```rust
//! extern crate cripes;
//! use cripes::symbol::Pool;
//!
//! /// Take ownership of a value, consuming it.
//! fn consume<T>(v: T) {}
//!
//! fn main() {
//!     let pool = Pool::new();
//!     let sym = pool.sym("a very long string that will almost certainly be stored in the pool");
//!     consume(sym);
//!     println!("The symbol is still valid: {:?}", sym.as_ref());
//! }
//! ```
//!
//! `Sym` is also lifetime-safe: it cannot outlive its parent pool.
//!
//! ```rust,compile_fail
//! extern crate cripes;
//! use cripes::symbol::Pool;
//!
//! fn main() {
//!     let sym = { let pool = Pool::new(); //~ ERROR `pool` does not live long enough
//!                 pool.sym("xyz") };
//! }
//! ```
use std::fmt;
use std::convert::AsRef;
use std::marker::PhantomData;
use std::hash::{Hash, Hasher, SipHasher};
use std::collections::BTreeMap;
use std::borrow::ToOwned;
use std::sync::Mutex;

use super::util::hash::{stdhash as hash};

mod private;                    // implementation details

#[cfg(test)] mod tests;

use self::private::PackFormat;

/* ****************************************************************
 * Pool
 */
/// A collection of symbols.
///
/// See [the module-level documentation](index.html) for more information.
#[derive(Debug)]
pub struct Pool {
    map:  Mutex<BTreeMap<u64,String>>
}

impl Clone for Pool {
    fn clone(&self) -> Self {
        let m = self.map.lock().expect("Failed to lock symbol pool mutex for clone");
        Pool{map: Mutex::new(m.clone())}
    }
}

impl Pool {
    /// Create a new symbol pool.
    #[inline]
    pub fn new() -> Pool {
        Pool{map: Mutex::new(BTreeMap::new())}
    }

    /// Fetch a symbol corresponding to the given string.
    #[inline(always)]
    pub fn sym<'a, S: AsRef<str>>(&'a self, name: S) -> Sym<'a> {
        Sym(unsafe { self.symbol(name) }, PhantomData)
    }

    /// Fetch a lifetime-unsafe symbol corresponding to the given string.
    ///
    /// Care must be taken to ensure that the returned symbol is not used after
    /// the pool goes out of scope.
    ///
    /// This method should remain private, and shouldn't be used unless you're
    /// absolutely certain it's what you want.
    unsafe fn symbol<S: AsRef<str>>(&self, name: S) -> private::Symbol {
        let name = name.as_ref();
        if name.len() <= private::INLINE_SYMBOL_MAX_LEN {
            private::Inline::new(name).pack()
        } else {
            let hsh = hash::<_, SipHasher>(&name) << 1;
            let mut map = self.map.lock().expect("Failed to lock symbol pool mutex for insertion");
            if ! map.contains_key(&hsh) {
                map.insert(hsh, name.to_owned());
            }
            private::Pooled::new(hsh, self).pack()
        }
    }
}

impl Default for Pool {
    #[inline]
    fn default() -> Self {
        Pool{map: Default::default()}
    }
}

/* ****************************************************************
 * Symbol
 */
/// Symbol obtained from a symbol pool.
///
/// Instances of `Sym` are created using the `sym` method on
/// [`Pool`](struct.Pool.html).  See [the module-level
/// documentation](index.html) for more information.

// `Sym` is a safe wrapper around the internal `private::Symbol`, which does not carry
// a lifetime parameter and therefore cannot ensure that any pool reference
// carried by an instance is still valid.  By adding a lifetime parameter and
// appropriate `PhantomData` data member, `Sym` prevents this case.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub struct Sym<'a>(private::Symbol, PhantomData<&'a Pool>);

impl<'a> fmt::Display for Sym<'a> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        <private::Symbol as fmt::Display>::fmt(&self.0, f)
    }
}

impl<'a> AsRef<str> for Sym<'a> {
    #[inline]
    fn as_ref(&self) -> &str {
        self.0.as_ref()
    }
}

impl<'a> Hash for Sym<'a>  {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}
<|endoftext|>