<commit_before>use std::iter::repeat;

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

    #[test]
    fn zeros_creates_zero_filled_vector_of_correct_size_and_length() {
        let a1 = zeros(vec![0]);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = zeros(vec![1]);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![0]);

        let a3 = zeros(vec![10]);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

        let a4 = zeros(vec![1, 2, 3]);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);

        let a5 = zeros(vec![3, 3]);
        assert_eq!(a5.shape, vec![3, 3]);
        assert_eq!(a5.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn full_test() {
        let a1 = full(vec![0], 1);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = full(vec![1], -3);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![-3]);

        let a3 = full(vec![10], 5);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![5, 5, 5, 5, 5, 5, 5, 5, 5, 5]);

        let a4 = full(vec![1, 2, 3], 0);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn index_test_1() {
        let array = QArray {
            shape: vec![1, 1, 1],
            data: vec![1],
        };

        assert_eq!(array.index(vec![0, 0, 0].as_slice()), Some(1));
    }

    #[test]
    fn index_test_2() {
        let array = QArray {
            shape: vec![2, 2, 1],
            data: vec![1, 2, 3, 4],
        };

        assert_eq!(array.index(vec![1, 0, 0].as_slice()), Some(2));
        assert_eq!(array.index(vec![0, 1, 0].as_slice()), Some(3));
    }

    #[test]
    fn index_test_3() {
        let array = QArray {
            shape: vec![2, 4, 3],
            data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                       22, 23, 24],
        };

        assert_eq!(array.index(vec![1, 2, 1].as_slice()), Some(14));
        assert_eq!(array.index(vec![0, 2, 2].as_slice()), Some(21));
    }

    #[test]
    fn test_1d_vec_to_qarray() {
        let v = vec![1, 2, 3];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![3]);
        assert_eq!(array.data, vec![1, 2, 3]);
    }

    #[test]
    fn test_2d_vec_to_qarray() {
        let v1 = vec![vec![1, 2], vec![3, 4]];
        let array1 = v1.to_qarray();

        assert_eq!(array1.shape, vec![2, 2]);
        assert_eq!(array1.data, vec![1, 2, 3, 4]);

        let v2 = vec![vec![1, 2, 3], vec![4, 5, 6]];
        let array2 = v2.to_qarray();

        assert_eq!(array2.shape, vec![2, 3]);
        assert_eq!(array2.data, vec![1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn test_3d_vec_to_qarray() {
        let v = vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![2, 2, 2]);
        assert_eq!(array.data, vec![1, 2, 3, 4, 5, 6, 7, 8]);
    }

    #[test]
    fn test_identity() {
        let a1 = identity(1);
        assert_eq!(a1.shape, vec![1, 1]);
        assert_eq!(a1.data, vec![1]);

        let a2 = identity(2);
        assert_eq!(a2.shape, vec![2, 2]);
        assert_eq!(a2.data, vec![1, 0, 0, 1]);

        let a3 = identity(0);
        assert_eq!(a3.shape, vec![0, 0]);
        assert_eq!(a3.data, vec![]);
    }
}

/// Return a new QArray of the given shape, filled with zeroes.
///
/// ```
/// use quota::zeros;
/// let qarray = zeros(vec![1, 2, 3]);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![0, 0, 0, 0, 0, 0])
/// ```
pub fn zeros(shape: Vec<usize>) -> QArray {
    full(shape, 0)
}

/// Return a new QArray of the given shape, filled with the given fill value.
///
/// ```
/// use quota::full;
/// let qarray = full(vec![1, 2, 3], 2);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![2, 2, 2, 2, 2, 2])
/// ```
pub fn full(shape: Vec<usize>, fill_value: isize) -> QArray {
    let data = repeat(fill_value).take(shape.iter().product()).collect::<Vec<isize>>();
    QArray { shape, data }
}

/// Return a new square QArray of the given size, with ones on the main diagonal
///
/// ```
/// use quota::identity;
///
/// let qarray = identity(3);
/// assert_eq!(qarray.shape, vec![3, 3]);
/// assert_eq!(qarray.data, vec![1, 0, 0, 0, 1, 0, 0, 0, 1]);
/// ```
pub fn identity(num_rows: usize) -> QArray {
    let QArray { shape, mut data } = zeros(vec![num_rows, num_rows]);
    {
        for x in 0..num_rows {
            let offset = offset(shape.as_slice(), &[x, x]);
            data[offset] = 1;
        }
    }
    QArray { shape, data }
}

#[derive(Debug)]
pub struct QArray {
    pub shape: Vec<usize>,
    pub data: Vec<isize>,
}

impl QArray {
    /// Return the element at the given coordinates.
    /// If the coordinates don't specify a single element (e.g. 2D coordinates
    /// are given for a 3D array), or the coordinates are invalid,
    /// this function will return None.
    ///
    /// ```
    /// use quota::*;
    ///
    /// let qarray = zeros(vec![2, 2]);
    /// assert_eq!(qarray.index(vec![0, 0].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![1, 1].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![3, 3].as_slice()), None);
    /// assert_eq!(qarray.index(vec![1].as_slice()), None);
    /// ```
    pub fn index(&self, coordinates: &[usize]) -> Option<isize> {
        // Check that the coordinates are valid
        // The number of coordinates should match the shape of the array.
        // Each coordinate should be less than the length of the array
        // in that dimension.
        if coordinates.len() != self.shape.len() { return None }
        for (coord, dim) in coordinates.iter().zip(self.shape.as_slice()) {
            if *coord >= *dim { return None }
        }

        return Some(self.data[offset(self.shape.as_slice(), coordinates)])
    }
}

fn offset(shape: &[usize], coordinates: &[usize]) -> usize {
    coordinates
        .into_iter()
        .enumerate()
        .map(|(idx, coord)| {
                 shape
                     .iter()
                     .take(idx)
                     .fold(*coord, |acc, x| acc * x)
             })
        .fold(0, |acc, x| acc + x)
}

trait ToQArray {
    fn to_qarray(&self) -> QArray;
}

impl ToQArray for Vec<isize> {
    fn to_qarray(&self) -> QArray {
        QArray {
            shape: vec![self.len()],
            data: self.clone(),
        }
    }
}

impl ToQArray for Vec<Vec<isize>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let l2 = match self.first() {
            Some(fst) => fst.len(),
            None => 0,
        };
        let shape = vec![l1, l2];

        let mut data = Vec::new();

        for row in self {
            for e in row {
                data.push(*e);
            }
        }

        QArray { shape, data }
    }
}

impl ToQArray for Vec<Vec<Vec<isize>>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let (l2, l3) = match self.first() {
            Some(fst) => match fst.first() {
                Some(ffst) => (fst.len(), ffst.len()),
                None => (fst.len(), 0)
            },
            None => (0, 0)
        };
        let shape = vec![l1, l2, l3];

        let mut data = Vec::new();

        for row in self {
            for col in row {
                for e in col {
                    data.push(*e)
                }
            }
        };

        QArray { shape, data }
    }
}
<commit_msg>Add benchmark tests<commit_after>#![feature(test)]

extern crate test;

use std::iter::repeat;

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

    #[bench]
    fn bench_zeros(b: &mut Bencher) {
        b.iter(|| zeros(vec![1, 2, 3]))
    }

    #[bench]
    fn bench_full(b: &mut Bencher) {
        b.iter(|| full(vec![1, 2, 3], 0))
    }

    #[bench]
    fn bench_identity(b: &mut Bencher) {
        b.iter(|| identity(3))
    }

    #[bench]
    fn bench_index(b: &mut Bencher) {
        let a = zeros(vec![3, 3, 3]);
        let coord = vec![2, 2, 2];
        b.iter(|| a.index(coord.as_slice()))
    }

    #[bench]
    fn bench_1d_vec_to_qarray(b: &mut Bencher) {
        let v = vec![1, 2, 3];
        b.iter(|| v.to_qarray() )
    }

    #[bench]
    fn bench_2d_vec_to_qarray(b: &mut Bencher) {
        let v = vec![vec![1, 2], vec![3, 4]];
        b.iter(|| v.to_qarray() )
    }

    #[bench]
    fn bench_3d_vec_to_qarray(b: &mut Bencher) {
        let v = vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]];
        b.iter(|| v.to_qarray() )
    }

    #[test]
    fn test_zeros() {
        let a1 = zeros(vec![0]);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = zeros(vec![1]);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![0]);

        let a3 = zeros(vec![10]);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

        let a4 = zeros(vec![1, 2, 3]);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);

        let a5 = zeros(vec![3, 3]);
        assert_eq!(a5.shape, vec![3, 3]);
        assert_eq!(a5.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn test_full() {
        let a1 = full(vec![0], 1);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = full(vec![1], -3);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![-3]);

        let a3 = full(vec![10], 5);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![5, 5, 5, 5, 5, 5, 5, 5, 5, 5]);

        let a4 = full(vec![1, 2, 3], 0);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn test_index() {
        let a1 = QArray {
            shape: vec![1, 1, 1],
            data: vec![1],
        };

        assert_eq!(a1.index(vec![0, 0, 0].as_slice()), Some(1));

        let a2 = QArray {
            shape: vec![2, 2, 1],
            data: vec![1, 2, 3, 4],
        };

        assert_eq!(a2.index(vec![1, 0, 0].as_slice()), Some(2));
        assert_eq!(a2.index(vec![0, 1, 0].as_slice()), Some(3));

        let a3 = QArray {
            shape: vec![2, 4, 3],
            data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                       22, 23, 24],
        };

        assert_eq!(a3.index(vec![1, 2, 1].as_slice()), Some(14));
        assert_eq!(a3.index(vec![0, 2, 2].as_slice()), Some(21));
    }

    #[test]
    fn test_1d_vec_to_qarray() {
        let v = vec![1, 2, 3];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![3]);
        assert_eq!(array.data, vec![1, 2, 3]);
    }

    #[test]
    fn test_2d_vec_to_qarray() {
        let v1 = vec![vec![1, 2], vec![3, 4]];
        let array1 = v1.to_qarray();

        assert_eq!(array1.shape, vec![2, 2]);
        assert_eq!(array1.data, vec![1, 2, 3, 4]);

        let v2 = vec![vec![1, 2, 3], vec![4, 5, 6]];
        let array2 = v2.to_qarray();

        assert_eq!(array2.shape, vec![2, 3]);
        assert_eq!(array2.data, vec![1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn test_3d_vec_to_qarray() {
        let v = vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![2, 2, 2]);
        assert_eq!(array.data, vec![1, 2, 3, 4, 5, 6, 7, 8]);
    }

    #[test]
    fn test_identity() {
        let a1 = identity(1);
        assert_eq!(a1.shape, vec![1, 1]);
        assert_eq!(a1.data, vec![1]);

        let a2 = identity(2);
        assert_eq!(a2.shape, vec![2, 2]);
        assert_eq!(a2.data, vec![1, 0, 0, 1]);

        let a3 = identity(0);
        assert_eq!(a3.shape, vec![0, 0]);
        assert_eq!(a3.data, vec![]);
    }
}

/// Return a new QArray of the given shape, filled with zeroes.
///
/// ```
/// use quota::zeros;
/// let qarray = zeros(vec![1, 2, 3]);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![0, 0, 0, 0, 0, 0])
/// ```
pub fn zeros(shape: Vec<usize>) -> QArray {
    full(shape, 0)
}

/// Return a new QArray of the given shape, filled with the given fill value.
///
/// ```
/// use quota::full;
/// let qarray = full(vec![1, 2, 3], 2);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![2, 2, 2, 2, 2, 2])
/// ```
pub fn full(shape: Vec<usize>, fill_value: isize) -> QArray {
    let data = repeat(fill_value)
        .take(shape.iter().product())
        .collect::<Vec<isize>>();
    QArray { shape, data }
}

/// Return a new square QArray of the given size, with ones on the main diagonal
///
/// ```
/// use quota::identity;
///
/// let qarray = identity(3);
/// assert_eq!(qarray.shape, vec![3, 3]);
/// assert_eq!(qarray.data, vec![1, 0, 0, 0, 1, 0, 0, 0, 1]);
/// ```
pub fn identity(num_rows: usize) -> QArray {
    let QArray { shape, mut data } = zeros(vec![num_rows, num_rows]);
    {
        for x in 0..num_rows {
            let offset = offset(shape.as_slice(), &[x, x]);
            data[offset] = 1;
        }
    }
    QArray { shape, data }
}

#[derive(Debug)]
pub struct QArray {
    pub shape: Vec<usize>,
    pub data: Vec<isize>,
}

impl QArray {
    /// Return the element at the given coordinates.
    /// If the coordinates don't specify a single element (e.g. 2D coordinates
    /// are given for a 3D array), or the coordinates are invalid,
    /// this function will return None.
    ///
    /// ```
    /// use quota::*;
    ///
    /// let qarray = zeros(vec![2, 2]);
    /// assert_eq!(qarray.index(vec![0, 0].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![1, 1].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![3, 3].as_slice()), None);
    /// assert_eq!(qarray.index(vec![1].as_slice()), None);
    /// ```
    pub fn index(&self, coordinates: &[usize]) -> Option<isize> {
        // Check that the coordinates are valid
        // The number of coordinates should match the shape of the array.
        // Each coordinate should be less than the length of the array
        // in that dimension.
        if coordinates.len() != self.shape.len() {
            return None;
        }
        for (coord, dim) in coordinates.iter().zip(self.shape.as_slice()) {
            if *coord >= *dim {
                return None;
            }
        }

        return Some(self.data[offset(self.shape.as_slice(), coordinates)]);
    }
}

fn offset(shape: &[usize], coordinates: &[usize]) -> usize {
    coordinates
        .into_iter()
        .enumerate()
        .map(|(idx, coord)| shape.iter().take(idx).fold(*coord, |acc, x| acc * x))
        .fold(0, |acc, x| acc + x)
}

trait ToQArray {
    fn to_qarray(&self) -> QArray;
}

impl ToQArray for Vec<isize> {
    fn to_qarray(&self) -> QArray {
        QArray {
            shape: vec![self.len()],
            data: self.clone(),
        }
    }
}

impl ToQArray for Vec<Vec<isize>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let l2 = match self.first() {
            Some(fst) => fst.len(),
            None => 0,
        };
        let shape = vec![l1, l2];

        let mut data = Vec::new();

        for row in self {
            for e in row {
                data.push(*e);
            }
        }

        QArray { shape, data }
    }
}

impl ToQArray for Vec<Vec<Vec<isize>>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let (l2, l3) = match self.first() {
            Some(fst) => {
                match fst.first() {
                    Some(ffst) => (fst.len(), ffst.len()),
                    None => (fst.len(), 0),
                }
            }
            None => (0, 0),
        };
        let shape = vec![l1, l2, l3];

        let mut data = Vec::new();

        for row in self {
            for col in row {
                for e in col {
                    data.push(*e)
                }
            }
        }

        QArray { shape, data }
    }
}
<|endoftext|>


<commit_before>#[macro_use(bson, doc)]
extern crate bson;
extern crate mongodb;
extern crate chrono;

use bson::ValueAccessError;
use mongodb::{Client, ThreadedClient};
use mongodb::cursor::Cursor;
use mongodb::db::ThreadedDatabase;
use mongodb::coll::options::{FindOptions, CursorType};
use chrono::*;

pub struct Oplog {
    cursor: Cursor,
}

#[derive(PartialEq, Debug)]
pub enum Operation<'a> {
    Insert { id: i64, namespace: &'a str },
    Update { id: i64, namespace: &'a str },
    Delete { id: i64, namespace: &'a str },
    Command { id: i64, namespace: &'a str },
    Database { id: i64, namespace: &'a str },
    Noop { id: i64, timestamp: DateTime<UTC> },
    Unknown
}

impl<'a> Operation<'a> {
    pub fn new(document: bson::Document) -> Result<Operation<'a>, ValueAccessError> {
        match document.get_str("op") {
            Ok("n") => Operation::noop(document),
            _ => Err(ValueAccessError::UnexpectedType),
        }
    }

    pub fn noop(document: bson::Document) -> Result<Operation<'a>, ValueAccessError> {
        let h = try!(document.get_i64("h"));
        let ts = try!(document.get_time_stamp("ts"));

        let seconds = ts >> 32;
        let nanoseconds = ((ts & 0xFFFFFFFF) * 1000000) as u32;

        Ok(Operation::Noop { id: h, timestamp: UTC.timestamp(seconds, nanoseconds) })
    }
}

impl Iterator for Oplog {
    type Item = bson::Document;

    fn next(&mut self) -> Option<bson::Document> {
        loop {
            if let Some(Ok(op)) = self.cursor.next() {
                return Some(op);
            }
        }
    }
}

impl Oplog {
    pub fn new(client: Client) -> Result<Oplog, mongodb::Error> {
        let coll = client.db("local").collection("oplog.rs");

        let mut opts = FindOptions::new();
        opts.cursor_type = CursorType::TailableAwait;
        opts.no_cursor_timeout = true;

        coll.find(None, Some(opts)).map(|cursor| Oplog { cursor: cursor })
    }
}

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

    #[test]
    fn operation_converts_noops() {
        let doc = doc! {
            "ts" => (Bson::TimeStamp(1479419535 << 32)),
            "h" => (-2135725856567446411i64),
            "v" => 2,
            "op" => "n",
            "ns" => "",
            "o" => {
                "msg" => "initiating set"
            }
        };

        match Operation::new(doc).unwrap() {
            Operation::Noop { id, timestamp } => {
                assert_eq!(-2135725856567446411i64, id);
                assert_eq!(UTC.timestamp(1479419535, 0), timestamp);
            },
            _ => panic!("Unexpected type of operation"),
        }
    }
}
<commit_msg>Wrap BSON errors in custom types<commit_after>#[macro_use(bson, doc)]
extern crate bson;
extern crate mongodb;
extern crate chrono;

use std::result;
use mongodb::{Client, ThreadedClient};
use mongodb::cursor::Cursor;
use mongodb::db::ThreadedDatabase;
use mongodb::coll::options::{FindOptions, CursorType};
use chrono::{DateTime, UTC, TimeZone};

#[derive(Debug)]
pub enum OplogError {
    MissingField(bson::ValueAccessError),
    Database(mongodb::Error),
    UnknownOperation(String),
}

type Result<T> = result::Result<T, OplogError>;

pub struct Oplog {
    cursor: Cursor,
}

#[derive(PartialEq, Debug)]
pub enum Operation<'a> {
    Insert { id: i64, timestamp: DateTime<UTC>, namespace: &'a str, document: &'a bson::Document },
    Update { id: i64, namespace: &'a str },
    Delete { id: i64, namespace: &'a str },
    Command { id: i64, namespace: &'a str },
    Database { id: i64, namespace: &'a str },
    Noop { id: i64, timestamp: DateTime<UTC>, document: &'a bson::Document },
    Unknown
}

impl<'a> Operation<'a> {
    pub fn new(document: &'a bson::Document) -> Result<Operation<'a>> {
        let op = try!(document.get_str("op").map_err(OplogError::MissingField));

        match op {
            "n" => document_to_noop(document),
            "i" => document_to_insert(document),
            _ => Err(OplogError::UnknownOperation(op.to_owned())),
        }
    }
}

fn document_to_noop(document: &bson::Document) -> Result<Operation> {
    let h = try!(document.get_i64("h").map_err(OplogError::MissingField));
    let ts = try!(document.get_time_stamp("ts").map_err(OplogError::MissingField));
    let o = try!(document.get_document("o").map_err(OplogError::MissingField));

    Ok(Operation::Noop { id: h, timestamp: timestamp_to_datetime(ts), document: o })
}

fn document_to_insert(document: &bson::Document) -> Result<Operation> {
    let h = try!(document.get_i64("h").map_err(OplogError::MissingField));
    let ts = try!(document.get_time_stamp("ts").map_err(OplogError::MissingField));
    let o = try!(document.get_document("o").map_err(OplogError::MissingField));
    let ns = try!(document.get_str("ns").map_err(OplogError::MissingField));

    Ok(Operation::Insert { id: h, timestamp: timestamp_to_datetime(ts), document: o, namespace: ns })
}

fn timestamp_to_datetime(timestamp: i64) -> DateTime<UTC> {
    let seconds = timestamp >> 32;
    let nanoseconds = ((timestamp & 0xFFFFFFFF) * 1000000) as u32;

    UTC.timestamp(seconds, nanoseconds)
}

impl Iterator for Oplog {
    type Item = bson::Document;

    fn next(&mut self) -> Option<bson::Document> {
        loop {
            if let Some(Ok(op)) = self.cursor.next() {
                return Some(op);
            }
        }
    }
}

impl Oplog {
    pub fn new(client: Client) -> Result<Oplog> {
        let coll = client.db("local").collection("oplog.rs");

        let mut opts = FindOptions::new();
        opts.cursor_type = CursorType::TailableAwait;
        opts.no_cursor_timeout = true;

        coll.find(None, Some(opts)).map(|cursor| Oplog { cursor: cursor }).map_err(OplogError::Database)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use bson::Bson;
    use bson::oid::ObjectId;
    use chrono::{UTC, TimeZone};

    #[test]
    fn operation_converts_noops() {
        let doc = doc! {
            "ts" => (Bson::TimeStamp(1479419535 << 32)),
            "h" => (-2135725856567446411i64),
            "v" => 2,
            "op" => "n",
            "ns" => "",
            "o" => {
                "msg" => "initiating set"
            }
        };
        let operation = Operation::new(&doc).unwrap();

        match operation {
            Operation::Noop { id, timestamp, document } => {
                assert_eq!(-2135725856567446411i64, id);
                assert_eq!(UTC.timestamp(1479419535, 0), timestamp);
                assert_eq!("initiating set", document.get_str("msg").unwrap());
            },
            _ => panic!("Unexpected type of operation"),
        }
    }

    #[test]
    fn operation_converts_inserts() {
        let oid = ObjectId::with_string("583050b26813716e505a5bf2").unwrap();
        let doc = doc! {
            "ts" => (Bson::TimeStamp(1479561394 << 32)),
            "h" => (-1742072865587022793i64),
            "v" => 2,
            "op" => "i",
            "ns" => "foo.bar",
            "o" => {
                "_id" => (Bson::ObjectId(oid)),
                "foo" => "bar"
            }
        };
        let operation = Operation::new(&doc).unwrap();

        match operation {
            Operation::Insert { id, timestamp, namespace, document } => {
                assert_eq!(-1742072865587022793i64, id);
                assert_eq!(UTC.timestamp(1479561394, 0), timestamp);
                assert_eq!("foo.bar", namespace);
                assert_eq!("bar", document.get_str("foo").unwrap());
            },
            _ => panic!("Unexpected type of operation"),
        }
    }
}
<|endoftext|>


<commit_before>/*!

A basic library for finding primes, providing a basic Iterator over all primes. It is not as fast as
`slow_primes`, but it is meant to be easy to use!

The simplest usage is simply to create an `Iterator`:

```
use primes::PrimeSet;

let mut pset = PrimeSet::new();

for (ix, n) in pset.iter().enumerate().take(10) {
    println!("Prime {}: {}", ix, n);
}
```

This library provides methods for generating primes, testing whether a number is prime, and
factorizing numbers. Most methods generate primes lazily, so only enough primes will be generated
for the given test, and primes are cached for later use.

[*Source*](https://github.com/wackywendell/primes)

# Example: Find the first prime after 1 million

```
use primes::PrimeSet;

let mut pset = PrimeSet::new();
let (ix, n) = pset.find(1_000_000);

println!("Prime {}: {}", ix, n);
```

# Example: Find the first ten primes *after* the thousandth prime
```
use primes::PrimeSet;

let mut pset = PrimeSet::new();
for (ix, n) in pset.iter().enumerate().skip(1_000).take(10) {
    println!("Prime {}: {}", ix, n);
}
```

# Example: Find the first prime greater than 1000
```
use primes::PrimeSet;

let mut pset = PrimeSet::new();
let (ix, n) = pset.find(1_000);
println!("The first prime after 1000 is the {}th prime: {}", ix, n);

assert_eq!(pset.find(n), (ix, n));
```

For more info on use, see `PrimeSet`, a class which handles the Sieve and has multiple methods for
iterating over primes.

This also provides a few functions unconnected to `PrimeSet`, which will be faster for the first
case, but slower in the long term as they do not use any caching of primes.

*/
#![doc(html_root_url = "https://wackywendell.github.io/primes/")]

use std::cmp::Ordering::{Equal, Greater, Less};
use std::ops::Index;
use std::slice;

/** A prime generator, using the Sieve of Eratosthenes.

Create with `let mut pset = PrimeSet::new()`, and then use `pset.iter()` to iterate over all primes.
**/
#[derive(Default)]
pub struct PrimeSet {
    lst: Vec<u64>,
}

/// An iterator over generated primes. Created by `PrimeSet::iter` or
/// `PrimeSet::generator`
pub struct PrimeSetIter<'a> {
    p: &'a mut PrimeSet,
    n: usize,
    expand: bool,
}

impl PrimeSet {
    /// A new prime generator, primed with 2 and 3
    pub fn new() -> PrimeSet {
        PrimeSet { lst: vec![2, 3] }
    }

    /// Finds one more prime, and adds it to the list
    pub fn expand(&mut self) {
        let mut l: u64 = self.lst[self.lst.len() - 1] + 2;
        let mut remainder = 0;
        loop {
            for &n in &self.lst {
                remainder = l % n;
                if remainder == 0 || n * n > l {
                    break;
                }
            }

            if remainder != 0 {
                self.lst.push(l);
                break;
            };

            l += 2;
        }
    }

    /// Number of primes found so far
    pub fn len(&self) -> usize {
        self.lst.len()
    }

    pub fn is_empty(&self) -> bool {
        false
    }

    /// Return all primes found so far as a slice
    pub fn list(&self) -> &[u64] {
        &self.lst[..]
    }

    /// Iterator over all primes not yet found
    pub fn generator(&mut self) -> PrimeSetIter {
        let myn = self.len();
        PrimeSetIter {
            p: self,
            n: myn,
            expand: true,
        }
    }

    /// Iterator over all primes, starting with 2. If you don't care about the "state" of the
    /// `PrimeSet`, this is what you want!
    pub fn iter(&mut self) -> PrimeSetIter {
        PrimeSetIter {
            p: self,
            n: 0,
            expand: true,
        }
    }

    /// Iterator over just the primes found so far
    pub fn iter_vec(&self) -> slice::Iter<u64> {
        self.lst.iter()
    }

    /// Find the next largest prime from a number
    ///
    /// Returns `(idx, prime)`
    ///
    /// Note that if `n` is prime, then the output will be `(idx, n)`
    pub fn find(&mut self, n: u64) -> (usize, u64) {
        while n > *(self.lst.last().unwrap_or(&0)) {
            self.expand();
        }
        self.find_vec(n).unwrap()
    }

    /// Check if a number is prime
    ///
    /// Note that this only requires primes up to `n.sqrt()` to be generated, and will generate
    /// them as necessary on its own.
    #[cfg_attr(feature = "cargo-clippy", allow(wrong_self_convention))]
    pub fn is_prime(&mut self, n: u64) -> bool {
        if n <= 1 {
            return false;
        }
        if n == 2 {
            return true;
        } // otherwise we get 2 % 2 == 0!
        for m in self.iter() {
            if n % m == 0 {
                return false;
            };
            if m * m > n {
                return true;
            };
        }
        unreachable!("This iterator should not be empty.");
    }

    /// Find the next largest prime from a number, if it is within the already-found list
    ///
    /// Returns `(idx, prime)`
    ///
    /// Note that if `n` is prime, then the output will be `(idx, n)`
    pub fn find_vec(&self, n: u64) -> Option<(usize, u64)> {
        if n > *(self.lst.last().unwrap_or(&0)) {
            return None;
        }

        let mut base: usize = 0;
        let mut lim: usize = self.len();

        // Binary search algorithm
        while lim != 0 {
            let ix = base + (lim >> 1);
            match self.lst[ix].cmp(&n) {
                Equal => return Some((ix, self.lst[ix])),
                Less => {
                    base = ix + 1;
                    lim -= 1;
                }
                Greater => (),
            }
            lim >>= 1;
        }
        Some((base, self.lst[base]))
    }

    /// Get the nth prime, even if we haven't yet found it
    pub fn get(&mut self, index: usize) -> u64 {
        for _ in 0..(index as isize) + 1 - (self.lst.len() as isize) {
            self.expand();
        }
        self.lst[index]
    }

    /// Get the prime factors of a number, starting from 2, including repeats
    pub fn prime_factors(&mut self, n: u64) -> Vec<u64> {
        if n == 1 {
            return Vec::new();
        }
        let mut curn = n;
        let mut lst: Vec<u64> = Vec::new();
        for p in self.iter() {
            while curn % p == 0 {
                println!("Pushing {} ({} / {})", p, curn, n);
                lst.push(p);
                curn /= p;
                if curn == 1 {
                    return lst;
                }
            }

            if p * p > curn {
                println!("Final push {} ({} / {})", p, curn, n);
                lst.push(curn);
                return lst;
            }
        }
        unreachable!("This should be unreachable.");
    }
}

impl Index<usize> for PrimeSet {
    type Output = u64;
    fn index(&self, index: usize) -> &u64 {
        &self.lst[index]
    }
}

impl<'a> Iterator for PrimeSetIter<'a> {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        while self.n >= self.p.len() {
            if self.expand {
                self.p.expand()
            } else {
                return None;
            }
        }
        self.n += 1;

        let m = self.p.lst[self.n - 1];

        Some(m)
    }
}

/// Find the first factor (other than 1) of a number
fn firstfac(x: u64) -> u64 {
    if x % 2 == 0 {
        return 2;
    };
    // TODO: return to step_by
    // for n in (3..).step_by(2).take_while(|m| m*m <= x) {
    for n in (1..).map(|m| 2 * m + 1).take_while(|m| m * m <= x) {
        if x % n == 0 {
            return n;
        };
    }
    // No factor found. It must be prime.
    x
}

/// Find all prime factors of a number
/// Does not use a `PrimeSet`, but simply counts upwards
pub fn factors(x: u64) -> Vec<u64> {
    if x <= 1 {
        return vec![];
    };
    let mut lst: Vec<u64> = Vec::new();
    let mut curn = x;
    loop {
        let m = firstfac(curn);
        lst.push(m);
        if m == curn {
            break;
        } else {
            curn /= m
        };
    }
    lst
}

/// Find all unique prime factors of a number
pub fn factors_uniq(x: u64) -> Vec<u64> {
    if x <= 1 {
        return vec![];
    };
    let mut lst: Vec<u64> = Vec::new();
    let mut curn = x;
    loop {
        let m = firstfac(curn);
        lst.push(m);
        if curn == m {
            break;
        }
        while curn % m == 0 {
            curn /= m;
        }
        if curn == 1 {
            break;
        }
    }
    lst
}

/// Test whether a number is prime. Checks every odd number up to `sqrt(n)`.
pub fn is_prime(n: u64) -> bool {
    if n <= 1 {
        return false;
    }
    firstfac(n) == n
}
<commit_msg>Remove extraneous prints<commit_after>/*!

A basic library for finding primes, providing a basic Iterator over all primes. It is not as fast as
`slow_primes`, but it is meant to be easy to use!

The simplest usage is simply to create an `Iterator`:

```
use primes::PrimeSet;

let mut pset = PrimeSet::new();

for (ix, n) in pset.iter().enumerate().take(10) {
    println!("Prime {}: {}", ix, n);
}
```

This library provides methods for generating primes, testing whether a number is prime, and
factorizing numbers. Most methods generate primes lazily, so only enough primes will be generated
for the given test, and primes are cached for later use.

[*Source*](https://github.com/wackywendell/primes)

# Example: Find the first prime after 1 million

```
use primes::PrimeSet;

let mut pset = PrimeSet::new();
let (ix, n) = pset.find(1_000_000);

println!("Prime {}: {}", ix, n);
```

# Example: Find the first ten primes *after* the thousandth prime
```
use primes::PrimeSet;

let mut pset = PrimeSet::new();
for (ix, n) in pset.iter().enumerate().skip(1_000).take(10) {
    println!("Prime {}: {}", ix, n);
}
```

# Example: Find the first prime greater than 1000
```
use primes::PrimeSet;

let mut pset = PrimeSet::new();
let (ix, n) = pset.find(1_000);
println!("The first prime after 1000 is the {}th prime: {}", ix, n);

assert_eq!(pset.find(n), (ix, n));
```

For more info on use, see `PrimeSet`, a class which handles the Sieve and has multiple methods for
iterating over primes.

This also provides a few functions unconnected to `PrimeSet`, which will be faster for the first
case, but slower in the long term as they do not use any caching of primes.

*/
#![doc(html_root_url = "https://wackywendell.github.io/primes/")]

use std::cmp::Ordering::{Equal, Greater, Less};
use std::ops::Index;
use std::slice;

/** A prime generator, using the Sieve of Eratosthenes.

Create with `let mut pset = PrimeSet::new()`, and then use `pset.iter()` to iterate over all primes.
**/
#[derive(Default)]
pub struct PrimeSet {
    lst: Vec<u64>,
}

/// An iterator over generated primes. Created by `PrimeSet::iter` or
/// `PrimeSet::generator`
pub struct PrimeSetIter<'a> {
    p: &'a mut PrimeSet,
    n: usize,
    expand: bool,
}

impl PrimeSet {
    /// A new prime generator, primed with 2 and 3
    pub fn new() -> PrimeSet {
        PrimeSet { lst: vec![2, 3] }
    }

    /// Finds one more prime, and adds it to the list
    pub fn expand(&mut self) {
        let mut l: u64 = self.lst[self.lst.len() - 1] + 2;
        let mut remainder = 0;
        loop {
            for &n in &self.lst {
                remainder = l % n;
                if remainder == 0 || n * n > l {
                    break;
                }
            }

            if remainder != 0 {
                self.lst.push(l);
                break;
            };

            l += 2;
        }
    }

    /// Number of primes found so far
    pub fn len(&self) -> usize {
        self.lst.len()
    }

    pub fn is_empty(&self) -> bool {
        false
    }

    /// Return all primes found so far as a slice
    pub fn list(&self) -> &[u64] {
        &self.lst[..]
    }

    /// Iterator over all primes not yet found
    pub fn generator(&mut self) -> PrimeSetIter {
        let myn = self.len();
        PrimeSetIter {
            p: self,
            n: myn,
            expand: true,
        }
    }

    /// Iterator over all primes, starting with 2. If you don't care about the "state" of the
    /// `PrimeSet`, this is what you want!
    pub fn iter(&mut self) -> PrimeSetIter {
        PrimeSetIter {
            p: self,
            n: 0,
            expand: true,
        }
    }

    /// Iterator over just the primes found so far
    pub fn iter_vec(&self) -> slice::Iter<u64> {
        self.lst.iter()
    }

    /// Find the next largest prime from a number
    ///
    /// Returns `(idx, prime)`
    ///
    /// Note that if `n` is prime, then the output will be `(idx, n)`
    pub fn find(&mut self, n: u64) -> (usize, u64) {
        while n > *(self.lst.last().unwrap_or(&0)) {
            self.expand();
        }
        self.find_vec(n).unwrap()
    }

    /// Check if a number is prime
    ///
    /// Note that this only requires primes up to `n.sqrt()` to be generated, and will generate
    /// them as necessary on its own.
    #[cfg_attr(feature = "cargo-clippy", allow(wrong_self_convention))]
    pub fn is_prime(&mut self, n: u64) -> bool {
        if n <= 1 {
            return false;
        }
        if n == 2 {
            return true;
        } // otherwise we get 2 % 2 == 0!
        for m in self.iter() {
            if n % m == 0 {
                return false;
            };
            if m * m > n {
                return true;
            };
        }
        unreachable!("This iterator should not be empty.");
    }

    /// Find the next largest prime from a number, if it is within the already-found list
    ///
    /// Returns `(idx, prime)`
    ///
    /// Note that if `n` is prime, then the output will be `(idx, n)`
    pub fn find_vec(&self, n: u64) -> Option<(usize, u64)> {
        if n > *(self.lst.last().unwrap_or(&0)) {
            return None;
        }

        let mut base: usize = 0;
        let mut lim: usize = self.len();

        // Binary search algorithm
        while lim != 0 {
            let ix = base + (lim >> 1);
            match self.lst[ix].cmp(&n) {
                Equal => return Some((ix, self.lst[ix])),
                Less => {
                    base = ix + 1;
                    lim -= 1;
                }
                Greater => (),
            }
            lim >>= 1;
        }
        Some((base, self.lst[base]))
    }

    /// Get the nth prime, even if we haven't yet found it
    pub fn get(&mut self, index: usize) -> u64 {
        for _ in 0..(index as isize) + 1 - (self.lst.len() as isize) {
            self.expand();
        }
        self.lst[index]
    }

    /// Get the prime factors of a number, starting from 2, including repeats
    pub fn prime_factors(&mut self, n: u64) -> Vec<u64> {
        if n == 1 {
            return Vec::new();
        }
        let mut curn = n;
        let mut lst: Vec<u64> = Vec::new();
        for p in self.iter() {
            while curn % p == 0 {
                lst.push(p);
                curn /= p;
                if curn == 1 {
                    return lst;
                }
            }

            if p * p > curn {
                lst.push(curn);
                return lst;
            }
        }
        unreachable!("This should be unreachable.");
    }
}

impl Index<usize> for PrimeSet {
    type Output = u64;
    fn index(&self, index: usize) -> &u64 {
        &self.lst[index]
    }
}

impl<'a> Iterator for PrimeSetIter<'a> {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        while self.n >= self.p.len() {
            if self.expand {
                self.p.expand()
            } else {
                return None;
            }
        }
        self.n += 1;

        let m = self.p.lst[self.n - 1];

        Some(m)
    }
}

/// Find the first factor (other than 1) of a number
fn firstfac(x: u64) -> u64 {
    if x % 2 == 0 {
        return 2;
    };
    // TODO: return to step_by
    // for n in (3..).step_by(2).take_while(|m| m*m <= x) {
    for n in (1..).map(|m| 2 * m + 1).take_while(|m| m * m <= x) {
        if x % n == 0 {
            return n;
        };
    }
    // No factor found. It must be prime.
    x
}

/// Find all prime factors of a number
/// Does not use a `PrimeSet`, but simply counts upwards
pub fn factors(x: u64) -> Vec<u64> {
    if x <= 1 {
        return vec![];
    };
    let mut lst: Vec<u64> = Vec::new();
    let mut curn = x;
    loop {
        let m = firstfac(curn);
        lst.push(m);
        if m == curn {
            break;
        } else {
            curn /= m
        };
    }
    lst
}

/// Find all unique prime factors of a number
pub fn factors_uniq(x: u64) -> Vec<u64> {
    if x <= 1 {
        return vec![];
    };
    let mut lst: Vec<u64> = Vec::new();
    let mut curn = x;
    loop {
        let m = firstfac(curn);
        lst.push(m);
        if curn == m {
            break;
        }
        while curn % m == 0 {
            curn /= m;
        }
        if curn == 1 {
            break;
        }
    }
    lst
}

/// Test whether a number is prime. Checks every odd number up to `sqrt(n)`.
pub fn is_prime(n: u64) -> bool {
    if n <= 1 {
        return false;
    }
    firstfac(n) == n
}
<|endoftext|>


<commit_before>//! A basic ZipReader/Writer crate

#![feature(phase)]
#![feature(unsafe_destructor)]
#![warn(missing_doc)]

#[phase(plugin, link)] extern crate log;
extern crate time;
extern crate flate2;

pub use reader::ZipReader;
pub use writer::ZipWriter;
pub use types::ZipFile;

mod util;
mod spec;
mod reader_spec;
mod writer_spec;
mod crc32;
mod reader;
mod types;
pub mod compression;
mod writer;
mod cp437;
<commit_msg>Rename missing_doc to missing_docs<commit_after>//! A basic ZipReader/Writer crate

#![feature(phase)]
#![feature(unsafe_destructor)]
#![warn(missing_docs)]

#[phase(plugin, link)] extern crate log;
extern crate time;
extern crate flate2;

pub use reader::ZipReader;
pub use writer::ZipWriter;
pub use types::ZipFile;

mod util;
mod spec;
mod reader_spec;
mod writer_spec;
mod crc32;
mod reader;
mod types;
pub mod compression;
mod writer;
mod cp437;
<|endoftext|>


<commit_before>#![crate_name = "spinlock"]
#![experimental]
#![crate_type = "lib"]
#![feature(unsafe_destructor)]
#![warn(missing_docs)]

#![no_std]

//! This crate provides a thread-safe data container.
//!
//! # Description
//!
//! This structure behaves a lot like a normal Mutex. There are some differences:
//!
//! - It may be used outside the runtime.
//!   - A normal mutex will fail when used without the runtime, this will just lock
//!   - When the runtime is present, it will call the deschedule function when appropriate
//! - No lock poisoning. When a fail occurs when the lock is held, no guarantees are made
//!
//! When calling rust functions from bare threads, such as C `pthread`s, this lock will be very
//! helpfull. In other cases however, you are encouraged to use the locks from the standard
//! library.
//!
//! # Simple example
//!
//! ```
//! use spinlock::Spinlock;
//! let spinlock = Spinlock::new(0u);
//!
//! // Modify the data
//! {
//!     let mut data = spinlock.lock();
//!     *data = 2;
//! }
//!
//! // Read the data
//! let answer =
//! {
//!     let data = spinlock.lock();
//!     *data
//! };
//!
//! assert_eq!(answer, 2u);
//! ```
//!
//! # Thread-safety example
//!
//! ```
//! use spinlock::Spinlock;
//! use std::sync::{Arc, Barrier};
//!
//! let numthreads = 1000;
//! let spinlock = Arc::new(Spinlock::new(0u));
//!
//! // We use a barrier to ensure the readout happens after all writing
//! let barrier = Arc::new(Barrier::new(numthreads + 1));
//!
//! for _ in range(0, numthreads)
//! {
//!     let my_barrier = barrier.clone();
//!     let my_lock = spinlock.clone();
//!     std::thread::Thread::spawn(move||
//!     {
//!         let mut guard = my_lock.lock();
//!         *guard += 1;
//!
//!         // Release the lock to prevent a deadlock
//!         drop(guard);
//!         my_barrier.wait();
//!     }).detach();
//! }
//!
//! barrier.wait();
//!
//! let answer = { *spinlock.lock() };
//! assert_eq!(answer, numthreads);
//! ```

#[cfg(test)] extern crate std;
extern crate core;

use core::atomic::{AtomicBool, SeqCst};
use core::cell::UnsafeCell;
use core::kinds::Send;
use core::ops::{Drop, Deref, DerefMut};

/// A wrapper for the data giving access in a thread-safe manner
pub struct Spinlock<T>
{
    lock: AtomicBool,
    data: UnsafeCell<T>,
}

/// A guard to which the protected data can be accessed
///
/// When the guard falls out of scope it will release the lock.
#[experimental]
pub struct SpinlockGuard<'a, T:'a>
{
    lock: &'a AtomicBool,
    data: &'a mut T,
}

impl<T: Send> Spinlock<T>
{
    /// Creates a new spinlock wrapping the supplied data.
    #[unstable]
    pub fn new(user_data: T) -> Spinlock<T>
    {
        Spinlock
        {
            lock: AtomicBool::new(false),
            data: UnsafeCell::new(user_data),
        }
    }

    fn obtain_lock(&self)
    {
        while self.lock.compare_and_swap(false, true, SeqCst) != false
        {
            // Do nothing
        }
    }

    /// Locks the spinlock and returns a guard.
    ///
    /// The returned value may be dereferenced for data access
    /// and the lock will be dropped when the guard falls out of scope.
    ///
    /// ```
    /// let mylock = spinlock::Spinlock::new(0u);
    /// {
    ///     let mut data = mylock.lock();
    ///     // The lock is now locked and the data can be accessed
    ///     *data += 1;
    /// }
    /// // The lock is dropped
    /// ```
    pub fn lock(&self) -> SpinlockGuard<T>
    {
        self.obtain_lock();
        SpinlockGuard
        {
            lock: &self.lock,
            data: unsafe { &mut *self.data.get() },
        }
    }
}

impl<'a, T: Send> Deref<T> for SpinlockGuard<'a, T>
{
    fn deref<'b>(&'b self) -> &'b T { &*self.data }
}

impl<'a, T: Send> DerefMut<T> for SpinlockGuard<'a, T>
{
    fn deref_mut<'b>(&'b mut self) -> &'b mut T { &mut *self.data }
}

#[unsafe_destructor]
impl<'a, T: Send> Drop for SpinlockGuard<'a, T>
{
    /// The dropping of the SpinlockGuard will release the lock it was created from.
    fn drop(&mut self)
    {
        self.lock.store(false, SeqCst);
    }
}
<commit_msg>Sync and Send are now opt-ins<commit_after>#![crate_name = "spinlock"]
#![experimental]
#![crate_type = "lib"]
#![feature(unsafe_destructor)]
#![warn(missing_docs)]

#![no_std]

//! This crate provides a thread-safe data container.
//!
//! # Description
//!
//! This structure behaves a lot like a normal Mutex. There are some differences:
//!
//! - It may be used outside the runtime.
//!   - A normal mutex will fail when used without the runtime, this will just lock
//!   - When the runtime is present, it will call the deschedule function when appropriate
//! - No lock poisoning. When a fail occurs when the lock is held, no guarantees are made
//!
//! When calling rust functions from bare threads, such as C `pthread`s, this lock will be very
//! helpfull. In other cases however, you are encouraged to use the locks from the standard
//! library.
//!
//! # Simple example
//!
//! ```
//! use spinlock::Spinlock;
//! let spinlock = Spinlock::new(0u);
//!
//! // Modify the data
//! {
//!     let mut data = spinlock.lock();
//!     *data = 2;
//! }
//!
//! // Read the data
//! let answer =
//! {
//!     let data = spinlock.lock();
//!     *data
//! };
//!
//! assert_eq!(answer, 2u);
//! ```
//!
//! # Thread-safety example
//!
//! ```
//! use spinlock::Spinlock;
//! use std::sync::{Arc, Barrier};
//!
//! let numthreads = 1000;
//! let spinlock = Arc::new(Spinlock::new(0u));
//!
//! // We use a barrier to ensure the readout happens after all writing
//! let barrier = Arc::new(Barrier::new(numthreads + 1));
//!
//! for _ in range(0, numthreads)
//! {
//!     let my_barrier = barrier.clone();
//!     let my_lock = spinlock.clone();
//!     std::thread::Thread::spawn(move||
//!     {
//!         let mut guard = my_lock.lock();
//!         *guard += 1;
//!
//!         // Release the lock to prevent a deadlock
//!         drop(guard);
//!         my_barrier.wait();
//!     }).detach();
//! }
//!
//! barrier.wait();
//!
//! let answer = { *spinlock.lock() };
//! assert_eq!(answer, numthreads);
//! ```

#[cfg(test)] extern crate std;
extern crate core;

use core::atomic::{AtomicBool, SeqCst};
use core::cell::UnsafeCell;
use core::kinds::Sync;
use core::ops::{Drop, Deref, DerefMut};

/// A wrapper for the data giving access in a thread-safe manner
pub struct Spinlock<T>
{
    lock: AtomicBool,
    data: UnsafeCell<T>,
}

/// A guard to which the protected data can be accessed
///
/// When the guard falls out of scope it will release the lock.
#[experimental]
pub struct SpinlockGuard<'a, T:'a>
{
    lock: &'a AtomicBool,
    data: &'a mut T,
}

unsafe impl<T> Sync for Spinlock<T> {}

impl<T> Spinlock<T>
{
    /// Creates a new spinlock wrapping the supplied data.
    #[unstable]
    pub fn new(user_data: T) -> Spinlock<T>
    {
        Spinlock
        {
            lock: AtomicBool::new(false),
            data: UnsafeCell::new(user_data),
        }
    }

    fn obtain_lock(&self)
    {
        while self.lock.compare_and_swap(false, true, SeqCst) != false
        {
            // Do nothing
        }
    }

    /// Locks the spinlock and returns a guard.
    ///
    /// The returned value may be dereferenced for data access
    /// and the lock will be dropped when the guard falls out of scope.
    ///
    /// ```
    /// let mylock = spinlock::Spinlock::new(0u);
    /// {
    ///     let mut data = mylock.lock();
    ///     // The lock is now locked and the data can be accessed
    ///     *data += 1;
    /// }
    /// // The lock is dropped
    /// ```
    pub fn lock(&self) -> SpinlockGuard<T>
    {
        self.obtain_lock();
        SpinlockGuard
        {
            lock: &self.lock,
            data: unsafe { &mut *self.data.get() },
        }
    }
}

impl<'a, T> Deref<T> for SpinlockGuard<'a, T>
{
    fn deref<'b>(&'b self) -> &'b T { &*self.data }
}

impl<'a, T> DerefMut<T> for SpinlockGuard<'a, T>
{
    fn deref_mut<'b>(&'b mut self) -> &'b mut T { &mut *self.data }
}

#[unsafe_destructor]
impl<'a, T> Drop for SpinlockGuard<'a, T>
{
    /// The dropping of the SpinlockGuard will release the lock it was created from.
    fn drop(&mut self)
    {
        self.lock.store(false, SeqCst);
    }
}
<|endoftext|>


<commit_before>//! This crate implements a structure that can be used as a generic array type.use
//! Core Rust array types `[T; N]` can't be used generically with respect to `N`, so for example this:
//!
//! ```{should_fail}
//! struct Foo<T, N> {
//!     data: [T; N]
//! }
//! ```
//!
//! won't work.
//!
//! **generic-array** exports a `GenericArray<T,N>` type, which lets the above be implemented as:
//!
//! ```
//!# use generic_array::{ArrayLength, GenericArray};
//! struct Foo<T, N: ArrayLength<T>> {
//!     data: GenericArray<T,N>
//! }
//! ```
//!
//! The `ArrayLength<T>` trait is implemented by default for [unsigned integer types](../typenum/uint/index.html) from [typenum](../typenum/index.html).
//!
//! For ease of use, an `arr!` macro is provided - example below:
//!
//! ```
//! # #[macro_use]
//! # extern crate generic_array;
//! # extern crate typenum;
//! # fn main() {
//! let array = arr![u32; 1, 2, 3];
//! assert_eq!(array[2], 3);
//! # }
//! ```
#![cfg_attr(feature="no_std", no_std)]
#[cfg(feature="no_std")]
extern crate core as std;
extern crate typenum;
pub mod arr;
use typenum::uint::{Unsigned, UTerm, UInt};
use typenum::bit::{B0, B1};
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;
use std::slice;

/// Trait making GenericArray work, marking types to be used as length of an array
pub unsafe trait ArrayLength<T> : Unsigned {
    /// Associated type representing the array type for the number
    type ArrayType;
}

unsafe impl<T> ArrayLength<T> for UTerm {
    type ArrayType = ();
}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplEven<T, U> {
    parent1: U,
    parent2: U,
    _marker: PhantomData<T>
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
    fn clone(&self) -> GenericArrayImplEven<T, U> {
        GenericArrayImplEven {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            _marker: PhantomData
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplOdd<T, U> {
    parent1: U,
    parent2: U,
    data: T
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
    fn clone(&self) -> GenericArrayImplOdd<T, U> {
        GenericArrayImplOdd {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            data: self.data.clone()
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
}

/// Struct representing a generic array - GenericArray<T, N> works like [T; N]
#[allow(dead_code)]
pub struct GenericArray<T, U: ArrayLength<T>> {
    data: U::ArrayType
}

impl<T, N> Deref for GenericArray<T, N> where N: ArrayLength<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self as *const Self as *const T, N::to_usize())
        }
    }
}

impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize())
        }
    }
}

impl<T: Default, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array filled with default values
    pub fn new() -> GenericArray<T, N> {
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            for r in res.iter_mut() { ptr::write(r, T::default()) }
            res
        }
    }

}

impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
    pub fn from_slice(list: &[T]) -> GenericArray<T, N> {
        assert_eq!(list.len(), N::to_usize());
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            for i in 0..N::to_usize() { ptr::write(&mut res[i], list[i].clone()) }
            res
        }
    }

}

impl<T: Clone, N> Clone for GenericArray<T, N> where N: ArrayLength<T> {
    fn clone(&self) -> GenericArray<T, N> {
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            for i in 0..N::to_usize() { ptr::write(&mut res[i], self[i].clone()) }
            res
        }
    }
}
impl<T: Copy, N> Copy for GenericArray<T, N> where N: ArrayLength<T>, N::ArrayType: Copy {}
<commit_msg>impl { PartialEq, Eq } for GenericArray<commit_after>//! This crate implements a structure that can be used as a generic array type.use
//! Core Rust array types `[T; N]` can't be used generically with respect to `N`, so for example this:
//!
//! ```{should_fail}
//! struct Foo<T, N> {
//!     data: [T; N]
//! }
//! ```
//!
//! won't work.
//!
//! **generic-array** exports a `GenericArray<T,N>` type, which lets the above be implemented as:
//!
//! ```
//!# use generic_array::{ArrayLength, GenericArray};
//! struct Foo<T, N: ArrayLength<T>> {
//!     data: GenericArray<T,N>
//! }
//! ```
//!
//! The `ArrayLength<T>` trait is implemented by default for [unsigned integer types](../typenum/uint/index.html) from [typenum](../typenum/index.html).
//!
//! For ease of use, an `arr!` macro is provided - example below:
//!
//! ```
//! # #[macro_use]
//! # extern crate generic_array;
//! # extern crate typenum;
//! # fn main() {
//! let array = arr![u32; 1, 2, 3];
//! assert_eq!(array[2], 3);
//! # }
//! ```
#![cfg_attr(feature="no_std", no_std)]
#[cfg(feature="no_std")]
extern crate core as std;
extern crate typenum;
pub mod arr;
use typenum::uint::{Unsigned, UTerm, UInt};
use typenum::bit::{B0, B1};
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;
use std::slice;

/// Trait making GenericArray work, marking types to be used as length of an array
pub unsafe trait ArrayLength<T> : Unsigned {
    /// Associated type representing the array type for the number
    type ArrayType;
}

unsafe impl<T> ArrayLength<T> for UTerm {
    type ArrayType = ();
}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplEven<T, U> {
    parent1: U,
    parent2: U,
    _marker: PhantomData<T>
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
    fn clone(&self) -> GenericArrayImplEven<T, U> {
        GenericArrayImplEven {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            _marker: PhantomData
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplOdd<T, U> {
    parent1: U,
    parent2: U,
    data: T
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
    fn clone(&self) -> GenericArrayImplOdd<T, U> {
        GenericArrayImplOdd {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            data: self.data.clone()
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
}

/// Struct representing a generic array - GenericArray<T, N> works like [T; N]
#[allow(dead_code)]
pub struct GenericArray<T, U: ArrayLength<T>> {
    data: U::ArrayType
}

impl<T, N> Deref for GenericArray<T, N> where N: ArrayLength<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self as *const Self as *const T, N::to_usize())
        }
    }
}

impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize())
        }
    }
}

impl<T: Default, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array filled with default values
    pub fn new() -> GenericArray<T, N> {
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            for r in res.iter_mut() { ptr::write(r, T::default()) }
            res
        }
    }

}

impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
    pub fn from_slice(list: &[T]) -> GenericArray<T, N> {
        assert_eq!(list.len(), N::to_usize());
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            for i in 0..N::to_usize() { ptr::write(&mut res[i], list[i].clone()) }
            res
        }
    }

}

impl<T: Clone, N> Clone for GenericArray<T, N> where N: ArrayLength<T> {
    fn clone(&self) -> GenericArray<T, N> {
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            for i in 0..N::to_usize() { ptr::write(&mut res[i], self[i].clone()) }
            res
        }
    }
}
impl<T: Copy, N> Copy for GenericArray<T, N> where N: ArrayLength<T>, N::ArrayType: Copy {}

impl<T: PartialEq, N> PartialEq for GenericArray<T, N> where N: ArrayLength<T> {
    fn eq(&self, other: &Self) -> bool { **self == **other }
}
impl<T: Eq, N> Eq for GenericArray<T, N> where N: ArrayLength<T> {}
<|endoftext|>


<commit_before>//! Atomic counting semaphore that can help you control access to a common resource
//! by multiple processes in a concurrent system.
//!
//! ## Features
//!
//! - Effectively lock-free* semantics
//! - Provides RAII-style acquire/release API
//! - Implements `Send`, `Sync` and `Clone`
//!
//! _* lock-free when not using the `shutdown` API_

extern crate parking_lot;

use std::ops::Deref;
use std::sync::Arc;

use parking_lot::RwLock;

mod raw;
use raw::RawSemaphore;

/// Result returned from `Semaphore::try_access`.
pub type TryAccessResult<T> = Result<SemaphoreGuard<T>, TryAccessError>;

#[derive(Copy, Clone, Debug, PartialEq)]
/// Error indicating a failure to acquire access to the resource
/// behind the semaphore.
///
/// Returned from `Semaphore::try_access`.
pub enum TryAccessError {
    /// This semaphore has shut down and will no longer grant access to the underlying resource.
    Shutdown,
    /// This semaphore has no more capacity to grant further access.
    /// Other access needs to be released before this semaphore can grant more.
    NoCapacity
}

/// Counting semaphore to control concurrent access to a common resource.
pub struct Semaphore<T> {
    raw: Arc<RawSemaphore>,
    resource: Arc<RwLock<Option<Arc<T>>>>
}

impl<T> Clone for Semaphore<T> {
    fn clone(&self) -> Semaphore<T> {
        Semaphore {
            raw: self.raw.clone(),
            resource: self.resource.clone()
        }
    }
}

impl<T> Semaphore<T> {
    /// Create a new semaphore around a resource.
    ///
    /// The semaphore will limit the number of processes that can access
    /// the underlying resource at every point in time to the specified capacity.
    pub fn new(capacity: usize, resource: T) -> Self {
        Semaphore {
            raw: Arc::new(RawSemaphore::new(capacity)),
            resource: Arc::new(RwLock::new(Some(Arc::new(resource))))
        }
    }

    #[inline]
    /// Attempt to access the underlying resource of this semaphore.
    ///
    /// This function will try to acquire access, and then return an RAII
    /// guard structure which will release the access when it falls out of scope.
    /// If the semaphore is out of capacity or shut down, a `TryAccessError` will be returned.
    pub fn try_access(&self) -> TryAccessResult<T> {
        if let Some(ref resource) = *self.resource.read() {
            if self.raw.try_acquire() {
                Ok(SemaphoreGuard {
                    raw: self.raw.clone(),
                    resource: resource.clone()
                })
            } else {
                Err(TryAccessError::NoCapacity)
            }
        } else {
            Err(TryAccessError::Shutdown)
        }
    }

    /// Shut down the semaphore.
    ///
    /// This prevents any further access from being granted to the underlying resource.
    /// As soon as the last access is released and the returned handle goes out of scope,
    /// the resource will be dropped.
    ///
    /// Does _not_ block until the resource is no longer in use. If you would like to do that,
    /// you can call `wait` on the returned handle.
    pub fn shutdown(&self) -> ShutdownHandle<T> {
        ShutdownHandle {
            raw: self.raw.clone(),
            resource: self.resource.write().take()
        }
    }
}

/// Handle representing the shutdown process of a semaphore,
/// allowing for extraction of the underlying resource.
///
/// Returned from `Semaphore::shutdown`.
pub struct ShutdownHandle<T> {
    raw: Arc<RawSemaphore>,
    resource: Option<Arc<T>>
}

impl<T> ShutdownHandle<T> {
    /// Block until all access has been released to the semaphore,
    /// and extract the underlying resource.
    ///
    /// When `Semaphore::shutdown` has been called multiple times,
    /// only the first shutdown handle will return the resource.
    /// All others will return `None`.
    pub fn wait(self) -> Option<T> {
        self.raw.wait_until_inactive();
        self.resource.map(|arc| {
            let mut local_arc = arc;
            loop {
                match Arc::try_unwrap(local_arc) {
                    Ok(resource) => {
                        return resource;
                    },
                    Err(arc) => {
                        local_arc = arc;
                    }
                }
            }
        })
    }

    #[doc(hidden)]
    pub fn is_complete(&self) -> bool {
        !self.raw.is_active()
    }
}

/// RAII guard used to release access to the semaphore automatically when it falls out of scope.
///
/// Returned from `Semaphore::try_access`.
///
/// ## Sharing guards
///
/// There are cases where, once acquired, you want to share a guard between multiple threads
/// of execution. This pattern can be implemented by wrapping the acquired guard into an [`Rc`][1]
/// or [`Arc`][2] reference.
///
/// [1]: https://doc.rust-lang.org/std/rc/struct.Rc.html
/// [2]: https://doc.rust-lang.org/std/sync/struct.Arc.html
pub struct SemaphoreGuard<T> {
    raw: Arc<RawSemaphore>,
    resource: Arc<T>
}

impl<T> Drop for SemaphoreGuard<T> {
    #[inline]
    fn drop(&mut self) {
        self.raw.release()
    }
}

impl<T: Sized> Deref for SemaphoreGuard<T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        self.resource.deref()
    }
}

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

    #[test]
    fn succeeds_to_acquire_when_empty() {
        let sema = Semaphore::new(1, ());
        assert!(sema.try_access().ok().is_some());
    }

    #[test]
    fn fails_to_acquire_when_full() {
        let sema = Semaphore::new(4, ());
        let guards = (0..4).map(|_| {
            sema.try_access().expect("guard acquisition failed")
        }).collect::<Vec<_>>();
        assert_eq!(sema.try_access().err().unwrap(),
            TryAccessError::NoCapacity);
        drop(guards);
    }

    #[test]
    fn dropping_guard_frees_capacity() {
        let sema = Semaphore::new(1, ());
        let guard = sema.try_access().expect("guard acquisition failed");
        drop(guard);
        assert!(sema.try_access().ok().is_some());
    }

    #[test]
    fn fails_to_acquire_when_shut_down() {
        let sema = Semaphore::new(4, ());
        sema.shutdown();
        assert_eq!(sema.try_access().err().unwrap(),
            TryAccessError::Shutdown);
    }

    #[test]
    fn shutdown_complete_when_empty() {
        let sema = Semaphore::new(1, ());
        let handle = sema.shutdown();
        assert_eq!(true, handle.is_complete());
        assert_eq!(Some(()), handle.wait());
    }

    #[test]
    fn shutdown_complete_when_guard_drops() {
        let sema = Semaphore::new(1, ());
        let guard = sema.try_access().expect("guard acquisition failed");
        let handle = sema.shutdown();
        assert_eq!(false, handle.is_complete());
        drop(guard);
        assert_eq!(true, handle.is_complete());
        assert_eq!(Some(()), handle.wait());
    }

    #[test]
    fn first_shutdown_can_extract_resource() {
        let sema = Semaphore::new(1, ());
        let first_handle = sema.shutdown();
        let second_handle = sema.shutdown();
        let third_handle = sema.shutdown();
        assert_eq!(None, second_handle.wait());
        assert_eq!(Some(()), first_handle.wait());
        assert_eq!(None, third_handle.wait());
    }
}
<commit_msg>slight refactor of ShutdownHandle::wait<commit_after>//! Atomic counting semaphore that can help you control access to a common resource
//! by multiple processes in a concurrent system.
//!
//! ## Features
//!
//! - Effectively lock-free* semantics
//! - Provides RAII-style acquire/release API
//! - Implements `Send`, `Sync` and `Clone`
//!
//! _* lock-free when not using the `shutdown` API_

extern crate parking_lot;

use std::ops::Deref;
use std::sync::Arc;

use parking_lot::RwLock;

mod raw;
use raw::RawSemaphore;

/// Result returned from `Semaphore::try_access`.
pub type TryAccessResult<T> = Result<SemaphoreGuard<T>, TryAccessError>;

#[derive(Copy, Clone, Debug, PartialEq)]
/// Error indicating a failure to acquire access to the resource
/// behind the semaphore.
///
/// Returned from `Semaphore::try_access`.
pub enum TryAccessError {
    /// This semaphore has shut down and will no longer grant access to the underlying resource.
    Shutdown,
    /// This semaphore has no more capacity to grant further access.
    /// Other access needs to be released before this semaphore can grant more.
    NoCapacity
}

/// Counting semaphore to control concurrent access to a common resource.
pub struct Semaphore<T> {
    raw: Arc<RawSemaphore>,
    resource: Arc<RwLock<Option<Arc<T>>>>
}

impl<T> Clone for Semaphore<T> {
    fn clone(&self) -> Semaphore<T> {
        Semaphore {
            raw: self.raw.clone(),
            resource: self.resource.clone()
        }
    }
}

impl<T> Semaphore<T> {
    /// Create a new semaphore around a resource.
    ///
    /// The semaphore will limit the number of processes that can access
    /// the underlying resource at every point in time to the specified capacity.
    pub fn new(capacity: usize, resource: T) -> Self {
        Semaphore {
            raw: Arc::new(RawSemaphore::new(capacity)),
            resource: Arc::new(RwLock::new(Some(Arc::new(resource))))
        }
    }

    #[inline]
    /// Attempt to access the underlying resource of this semaphore.
    ///
    /// This function will try to acquire access, and then return an RAII
    /// guard structure which will release the access when it falls out of scope.
    /// If the semaphore is out of capacity or shut down, a `TryAccessError` will be returned.
    pub fn try_access(&self) -> TryAccessResult<T> {
        if let Some(ref resource) = *self.resource.read() {
            if self.raw.try_acquire() {
                Ok(SemaphoreGuard {
                    raw: self.raw.clone(),
                    resource: resource.clone()
                })
            } else {
                Err(TryAccessError::NoCapacity)
            }
        } else {
            Err(TryAccessError::Shutdown)
        }
    }

    /// Shut down the semaphore.
    ///
    /// This prevents any further access from being granted to the underlying resource.
    /// As soon as the last access is released and the returned handle goes out of scope,
    /// the resource will be dropped.
    ///
    /// Does _not_ block until the resource is no longer in use. If you would like to do that,
    /// you can call `wait` on the returned handle.
    pub fn shutdown(&self) -> ShutdownHandle<T> {
        ShutdownHandle {
            raw: self.raw.clone(),
            resource: self.resource.write().take()
        }
    }
}

/// Handle representing the shutdown process of a semaphore,
/// allowing for extraction of the underlying resource.
///
/// Returned from `Semaphore::shutdown`.
pub struct ShutdownHandle<T> {
    raw: Arc<RawSemaphore>,
    resource: Option<Arc<T>>
}

impl<T> ShutdownHandle<T> {
    /// Block until all access has been released to the semaphore,
    /// and extract the underlying resource.
    ///
    /// When `Semaphore::shutdown` has been called multiple times,
    /// only the first shutdown handle will return the resource.
    /// All others will return `None`.
    pub fn wait(self) -> Option<T> {
        self.raw.wait_until_inactive();
        self.resource.map(|mut arc| {
            loop {
                match Arc::try_unwrap(arc) {
                    Ok(resource) => {
                        return resource;
                    },
                    Err(returned_arc) => {
                        arc = returned_arc;
                    }
                }
            }
        })
    }

    #[doc(hidden)]
    pub fn is_complete(&self) -> bool {
        !self.raw.is_active()
    }
}

/// RAII guard used to release access to the semaphore automatically when it falls out of scope.
///
/// Returned from `Semaphore::try_access`.
///
/// ## Sharing guards
///
/// There are cases where, once acquired, you want to share a guard between multiple threads
/// of execution. This pattern can be implemented by wrapping the acquired guard into an [`Rc`][1]
/// or [`Arc`][2] reference.
///
/// [1]: https://doc.rust-lang.org/std/rc/struct.Rc.html
/// [2]: https://doc.rust-lang.org/std/sync/struct.Arc.html
pub struct SemaphoreGuard<T> {
    raw: Arc<RawSemaphore>,
    resource: Arc<T>
}

impl<T> Drop for SemaphoreGuard<T> {
    #[inline]
    fn drop(&mut self) {
        self.raw.release()
    }
}

impl<T: Sized> Deref for SemaphoreGuard<T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        self.resource.deref()
    }
}

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

    #[test]
    fn succeeds_to_acquire_when_empty() {
        let sema = Semaphore::new(1, ());
        assert!(sema.try_access().ok().is_some());
    }

    #[test]
    fn fails_to_acquire_when_full() {
        let sema = Semaphore::new(4, ());
        let guards = (0..4).map(|_| {
            sema.try_access().expect("guard acquisition failed")
        }).collect::<Vec<_>>();
        assert_eq!(sema.try_access().err().unwrap(),
            TryAccessError::NoCapacity);
        drop(guards);
    }

    #[test]
    fn dropping_guard_frees_capacity() {
        let sema = Semaphore::new(1, ());
        let guard = sema.try_access().expect("guard acquisition failed");
        drop(guard);
        assert!(sema.try_access().ok().is_some());
    }

    #[test]
    fn fails_to_acquire_when_shut_down() {
        let sema = Semaphore::new(4, ());
        sema.shutdown();
        assert_eq!(sema.try_access().err().unwrap(),
            TryAccessError::Shutdown);
    }

    #[test]
    fn shutdown_complete_when_empty() {
        let sema = Semaphore::new(1, ());
        let handle = sema.shutdown();
        assert_eq!(true, handle.is_complete());
        assert_eq!(Some(()), handle.wait());
    }

    #[test]
    fn shutdown_complete_when_guard_drops() {
        let sema = Semaphore::new(1, ());
        let guard = sema.try_access().expect("guard acquisition failed");
        let handle = sema.shutdown();
        assert_eq!(false, handle.is_complete());
        drop(guard);
        assert_eq!(true, handle.is_complete());
        assert_eq!(Some(()), handle.wait());
    }

    #[test]
    fn first_shutdown_can_extract_resource() {
        let sema = Semaphore::new(1, ());
        let first_handle = sema.shutdown();
        let second_handle = sema.shutdown();
        let third_handle = sema.shutdown();
        assert_eq!(None, second_handle.wait());
        assert_eq!(Some(()), first_handle.wait());
        assert_eq!(None, third_handle.wait());
    }
}
<|endoftext|>


<commit_before>//#![allow(dead_code, unused_must_use, unused_imports, unstable)]

#[macro_use] extern crate log;

use factory::{Record, RecordResult};
use std::string::ToString;
use std::old_io::IoError;

pub mod controller;
pub mod factory;
mod utils;

struct Txtdb {
    factory: factory::Factory,
}

impl Txtdb {

    pub fn new(factory: factory::Factory) -> Txtdb {
        Txtdb {
            factory: factory,
        }
    }

    /// Add a new record to the database. Returns the id of the record added.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn add<T: ToString>(&mut self, record: T) -> RecordResult<u64, String> {
        Ok(1)
    }

    /// Removes a record with the id provided if it exists.
    /// Returns a `RecordResult` of the record removed.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn remove_id(&mut self, id: u64) -> RecordResult<Record, String> {
        Err("Not implemented yet")
    }

    /// Finds and removes the first instance of a record that matches the one provided.
    /// Returns the id of the record it removes.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn remove(&mut self, record: Record) -> RecordResult<u64, String> {
        Err("Not implemented yet")
    }

    /// Searches for a record with the id provided.
    /// Returns a copy of the record.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn find_id(id: u64) -> RecordResult<Record, String> {
        // 1. Read each line?
        // 2. Check if the ID matches
        // 3. Return
        Err("Not implemented yet")
    }

    /// Searches for the first instance of a record that matches the one provided.
    /// Returns the id of the record in the database.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn find(&self, record: Record) -> RecordResult<u64, String> {
        // TODO, how do you create a `Record` if you don't know the id?
        //  Since we aren't using it, should we document not having the id in there?
        //
        // 1. Base64 encode the Record
        // 2. Read each line to find the match encoded value
        // 3. Return id
        Err("Not implemented yet")
    }
}
<commit_msg>Fixed remaining changes the temp return type<commit_after>//#![allow(dead_code, unused_must_use, unused_imports, unstable)]

#[macro_use] extern crate log;

use factory::{Record, RecordResult};
use std::string::ToString;
use std::old_io::IoError;

pub mod controller;
pub mod factory;
mod utils;

struct Txtdb {
    factory: factory::Factory,
}

impl Txtdb {

    pub fn new(factory: factory::Factory) -> Txtdb {
        Txtdb {
            factory: factory,
        }
    }

    /// Add a new record to the database. Returns the id of the record added.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn add<T: ToString>(&mut self, record: T) -> RecordResult<u64, String> {
        Ok(1)
    }

    /// Removes a record with the id provided if it exists.
    /// Returns a `RecordResult` of the record removed.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn remove_id(&mut self, id: u64) -> RecordResult<Record, String> {
        Err("Not implemented yet".to_string())
    }

    /// Finds and removes the first instance of a record that matches the one provided.
    /// Returns the id of the record it removes.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn remove(&mut self, record: Record) -> RecordResult<u64, String> {
        Err("Not implemented yet".to_string())
    }

    /// Searches for a record with the id provided.
    /// Returns a copy of the record.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn find_id(id: u64) -> RecordResult<Record, String> {
        // 1. Read each line?
        // 2. Check if the ID matches
        // 3. Return
        Err("Not implemented yet".to_string())
    }

    /// Searches for the first instance of a record that matches the one provided.
    /// Returns the id of the record in the database.
    #[allow(dead_code, unused_must_use, unused_variables)]
    fn find(&self, record: Record) -> RecordResult<u64, String> {
        // TODO, how do you create a `Record` if you don't know the id?
        //  Since we aren't using it, should we document not having the id in there?
        //
        // 1. Base64 encode the Record
        // 2. Read each line to find the match encoded value
        // 3. Return id
        Err("Not implemented yet".to_string())
    }
}
<|endoftext|>


<commit_before>#![crate_id = "image"]
#![crate_type = "rlib"]

#![allow(missing_doc)]
#![feature(macro_rules)]

extern crate flate;
extern crate collections;

pub use ColorType = colortype::ColorType;
pub use Grey = colortype::Grey;
pub use RGB = colortype::RGB;
pub use Palette = colortype::Palette;
pub use GreyA = colortype::GreyA;
pub use RGBA = colortype::RGBA;

pub use ImageDecoder = image::ImageDecoder;
pub use ImageError   = image::ImageError;
pub use ImageResult  = image::ImageResult;
pub use ImageFormat  = image::ImageFormat;
pub use image::{PNG, JPEG, GIF, WEBP, PPM};

pub use Image = image::Image;

pub use JPEGDecoder = jpeg::JPEGDecoder;
pub use JPEGEncoder = jpeg::JPEGEncoder;
pub use PNGDecoder  = png::PNGDecoder;
pub use PNGEncoder  = png::PNGEncoder;
pub use GIFDecoder  = gif::GIFDecoder;
pub use PPMEncoder  = ppm::PPMEncoder;
pub use WebpDecoder = webp::WebpDecoder;

pub mod vp8;
pub mod colortype;
pub mod jpeg;
pub mod png;
pub mod gif;
pub mod webp;
pub mod ppm;

mod hash;
mod image;
mod pixels;
mod transform;
mod deflate;
mod zlib;
mod lzw;
<commit_msg>update<commit_after>#![crate_id = "image"]
#![crate_type = "rlib"]

#![allow(missing_doc)]
#![feature(macro_rules)]

extern crate flate;
extern crate collections;

pub use ColorType = colortype::ColorType;
pub use Grey = colortype::Grey;
pub use RGB = colortype::RGB;
pub use Palette = colortype::Palette;
pub use GreyA = colortype::GreyA;
pub use RGBA = colortype::RGBA;

pub use ImageDecoder = image::ImageDecoder;
pub use ImageError   = image::ImageError;
pub use ImageResult  = image::ImageResult;
pub use ImageFormat  = image::ImageFormat;
pub use image::{PNG, JPEG, GIF, WEBP, PPM};

pub use Image = image::Image;

pub use JPEGDecoder = jpeg::JPEGDecoder;
pub use JPEGEncoder = jpeg::JPEGEncoder;
pub use PNGDecoder  = png::PNGDecoder;
pub use PNGEncoder  = png::PNGEncoder;
pub use GIFDecoder  = gif::GIFDecoder;
pub use PPMEncoder  = ppm::PPMEncoder;
pub use WebpDecoder = webp::WebpDecoder;

pub mod vp8;
pub mod colortype;
pub mod jpeg;
pub mod png;
pub mod gif;
pub mod webp;
pub mod ppm;

mod hash;
mod image;
mod transform;
mod deflate;
mod zlib;
mod lzw;
<|endoftext|>