<commit_before>//! Propagates scope-specific information to `into_model` transformations.

use core::{Context, RpName, RpPackage, RpVersionedPackage};
use naming::Naming;
use std::collections::HashMap;
use std::rc::Rc;

/// Root of the scope.
struct Root {
    ctx: Rc<Context>,
    package_prefix: Option<RpPackage>,
    package: RpVersionedPackage,
    prefixes: HashMap<String, RpVersionedPackage>,
    endpoint_naming: Option<Box<Naming>>,
    field_naming: Option<Box<Naming>>,
    keywords: Rc<HashMap<String, String>>,
    safe_packages: bool,
}

/// Model of a scope.
enum Inner {
    Root(Rc<Root>),
    Child {
        root: Rc<Root>,
        name: String,
        parent: Rc<Inner>,
    },
}

pub struct Scope(Rc<Inner>);

impl Scope {
    pub fn new(
        ctx: Rc<Context>,
        package_prefix: Option<RpPackage>,
        package: RpVersionedPackage,
        prefixes: HashMap<String, RpVersionedPackage>,
        endpoint_naming: Option<Box<Naming>>,
        field_naming: Option<Box<Naming>>,
        keywords: Rc<HashMap<String, String>>,
        safe_packages: bool,
    ) -> Scope {
        Scope(Rc::new(Inner::Root(Rc::new(Root {
            ctx,
            package_prefix,
            package,
            prefixes,
            endpoint_naming,
            field_naming,
            keywords,
            safe_packages,
        }))))
    }

    #[inline(always)]
    fn root(&self) -> &Rc<Root> {
        match *self.0 {
            Inner::Root(ref root) |
            Inner::Child { ref root, .. } => root,
        }
    }

    /// Walk the entire path of the scope.
    pub fn walk(&self) -> ScopeWalker {
        ScopeWalker { current: self.0.clone() }
    }

    /// Create a new child scope.
    pub fn child<S: AsRef<str>>(&self, name: S) -> Scope {
        Scope(Rc::new(Inner::Child {
            root: self.root().clone(),
            name: name.as_ref().to_owned(),
            parent: self.0.clone(),
        }))
    }

    /// Access the error context.
    pub fn ctx(&self) -> &Context {
        self.root().ctx.as_ref()
    }

    /// Lookup what package a given prefix belongs to.
    pub fn lookup_prefix(&self, prefix: &String) -> Option<RpVersionedPackage> {
        let root = self.root();

        root.prefixes.get(prefix).map(|p| if root.safe_packages {
            p.clone().with_replacements(&root.keywords)
        } else {
            p.clone()
        })
    }

    /// Get the package that this scope belongs to.
    pub fn package(&self) -> RpVersionedPackage {
        let root = self.root();

        let package = root.package_prefix
            .as_ref()
            .map(|prefix| prefix.join_versioned(&root.package))
            .unwrap_or_else(|| root.package.clone());

        if root.safe_packages {
            return package.with_replacements(&root.keywords);
        }

        package
    }

    /// Get the current path as a name.
    pub fn as_name(&self) -> RpName {
        let mut parts: Vec<_> = self.walk().collect();
        parts.reverse();

        RpName {
            prefix: None,
            package: self.package(),
            parts: parts,
        }
    }

    /// Access active endpoint naming.
    pub fn endpoint_naming(&self) -> Option<&Naming> {
        self.root().endpoint_naming.as_ref().map(AsRef::as_ref)
    }

    /// Access active field naming.
    pub fn field_naming(&self) -> Option<&Naming> {
        self.root().field_naming.as_ref().map(AsRef::as_ref)
    }

    /// Lookup if the given identifier matches a language keyword.
    pub fn keyword(&self, identifier: &str) -> Option<&str> {
        self.root().keywords.get(identifier).map(|s| s.as_str())
    }
}

/// Walker over all components of the scope.
pub struct ScopeWalker {
    current: Rc<Inner>,
}

impl Iterator for ScopeWalker {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        let (next, current) = match *self.current {
            Inner::Root(_) => {
                return None;
            }
            Inner::Child {
                ref name,
                ref parent,
                ..
            } => (Some(name.to_owned()), parent.clone()),
        };

        self.current = current;
        next
    }
}

#[cfg(test)]
mod tests {
    use core::{RpPackage, RpVersionedPackage};
    use core::CapturingFilesystem;
    use core::Context;
    use scope::Scope;
    use std::collections::HashMap;
    use std::rc::Rc;

    #[test]
    pub fn test_scope() {
        let ctx = Rc::new(Context::new(Box::new(CapturingFilesystem::new())));
        let package = RpVersionedPackage::new(RpPackage::empty(), None);
        let prefixes = HashMap::new();
        let keywords = Rc::new(HashMap::new());
        let s = Scope::new(ctx, None, package, prefixes, None, None, keywords);

        let s2 = s.child("foo");
        let s3 = s2.child("bar");

        let parts: Vec<_> = s3.walk().collect();

        assert_eq!(vec!["bar".to_owned(), "foo".to_owned()], parts);
    }
}
<commit_msg>Fix for scope test<commit_after>//! Propagates scope-specific information to `into_model` transformations.

use core::{Context, RpName, RpPackage, RpVersionedPackage};
use naming::Naming;
use std::collections::HashMap;
use std::rc::Rc;

/// Root of the scope.
struct Root {
    ctx: Rc<Context>,
    package_prefix: Option<RpPackage>,
    package: RpVersionedPackage,
    prefixes: HashMap<String, RpVersionedPackage>,
    endpoint_naming: Option<Box<Naming>>,
    field_naming: Option<Box<Naming>>,
    keywords: Rc<HashMap<String, String>>,
    safe_packages: bool,
}

/// Model of a scope.
enum Inner {
    Root(Rc<Root>),
    Child {
        root: Rc<Root>,
        name: String,
        parent: Rc<Inner>,
    },
}

pub struct Scope(Rc<Inner>);

impl Scope {
    pub fn new(
        ctx: Rc<Context>,
        package_prefix: Option<RpPackage>,
        package: RpVersionedPackage,
        prefixes: HashMap<String, RpVersionedPackage>,
        endpoint_naming: Option<Box<Naming>>,
        field_naming: Option<Box<Naming>>,
        keywords: Rc<HashMap<String, String>>,
        safe_packages: bool,
    ) -> Scope {
        Scope(Rc::new(Inner::Root(Rc::new(Root {
            ctx,
            package_prefix,
            package,
            prefixes,
            endpoint_naming,
            field_naming,
            keywords,
            safe_packages,
        }))))
    }

    #[inline(always)]
    fn root(&self) -> &Rc<Root> {
        match *self.0 {
            Inner::Root(ref root) |
            Inner::Child { ref root, .. } => root,
        }
    }

    /// Walk the entire path of the scope.
    pub fn walk(&self) -> ScopeWalker {
        ScopeWalker { current: self.0.clone() }
    }

    /// Create a new child scope.
    pub fn child<S: AsRef<str>>(&self, name: S) -> Scope {
        Scope(Rc::new(Inner::Child {
            root: self.root().clone(),
            name: name.as_ref().to_owned(),
            parent: self.0.clone(),
        }))
    }

    /// Access the error context.
    pub fn ctx(&self) -> &Context {
        self.root().ctx.as_ref()
    }

    /// Lookup what package a given prefix belongs to.
    pub fn lookup_prefix(&self, prefix: &String) -> Option<RpVersionedPackage> {
        let root = self.root();

        root.prefixes.get(prefix).map(|p| if root.safe_packages {
            p.clone().with_replacements(&root.keywords)
        } else {
            p.clone()
        })
    }

    /// Get the package that this scope belongs to.
    pub fn package(&self) -> RpVersionedPackage {
        let root = self.root();

        let package = root.package_prefix
            .as_ref()
            .map(|prefix| prefix.join_versioned(&root.package))
            .unwrap_or_else(|| root.package.clone());

        if root.safe_packages {
            return package.with_replacements(&root.keywords);
        }

        package
    }

    /// Get the current path as a name.
    pub fn as_name(&self) -> RpName {
        let mut parts: Vec<_> = self.walk().collect();
        parts.reverse();

        RpName {
            prefix: None,
            package: self.package(),
            parts: parts,
        }
    }

    /// Access active endpoint naming.
    pub fn endpoint_naming(&self) -> Option<&Naming> {
        self.root().endpoint_naming.as_ref().map(AsRef::as_ref)
    }

    /// Access active field naming.
    pub fn field_naming(&self) -> Option<&Naming> {
        self.root().field_naming.as_ref().map(AsRef::as_ref)
    }

    /// Lookup if the given identifier matches a language keyword.
    pub fn keyword(&self, identifier: &str) -> Option<&str> {
        self.root().keywords.get(identifier).map(|s| s.as_str())
    }
}

/// Walker over all components of the scope.
pub struct ScopeWalker {
    current: Rc<Inner>,
}

impl Iterator for ScopeWalker {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        let (next, current) = match *self.current {
            Inner::Root(_) => {
                return None;
            }
            Inner::Child {
                ref name,
                ref parent,
                ..
            } => (Some(name.to_owned()), parent.clone()),
        };

        self.current = current;
        next
    }
}

#[cfg(test)]
mod tests {
    use core::{RpPackage, RpVersionedPackage};
    use core::CapturingFilesystem;
    use core::Context;
    use scope::Scope;
    use std::collections::HashMap;
    use std::rc::Rc;

    #[test]
    pub fn test_scope() {
        let ctx = Rc::new(Context::new(Box::new(CapturingFilesystem::new())));
        let package = RpVersionedPackage::new(RpPackage::empty(), None);
        let prefixes = HashMap::new();
        let keywords = Rc::new(HashMap::new());
        let s = Scope::new(ctx, None, package, prefixes, None, None, keywords, false);

        let s2 = s.child("foo");
        let s3 = s2.child("bar");

        let parts: Vec<_> = s3.walk().collect();

        assert_eq!(vec!["bar".to_owned(), "foo".to_owned()], parts);
    }
}
<|endoftext|>


<commit_before>#[derive(Copy, Clone)]
pub enum IncomingMsg<'a> {
    Invite(&'a Invite),
    Join(&'a Join),
    Kick(&'a Kick),
    Mode(&'a Mode),
    Nick(&'a Nick),
    Notice(&'a Notice),
    Part(&'a Part),
    Ping(&'a Ping),
    Pong(&'a Pong),
    Privmsg(&'a Privmsg),
    Quit(&'a Quit),
    Topic(&'a Topic),

    // Others
    Unknown(&'a IrcMsg),
}

use ::parse::IrcMsg as IrcMsgLegacy;
use ::parse::parse2::IrcMsg;
use ::parse_helpers;

macro_rules! impl_irc_msg_subtype {
    ($id:ident) => {
        pub struct $id {
            inner: IrcMsg,
        }

        impl $id {
            pub fn from_irc_msg(msg: &IrcMsg) -> Result<&Self, ()> {
                try!($id::validate(msg));
                Ok(unsafe {::std::mem::transmute(msg) })
            }

            pub fn to_irc_msg(&self) -> &IrcMsg {
                &self.inner
            }
        }
    }
}

macro_rules! irc_msg_legacy_validator {
    ($on:ident, $from:ident) => {
        impl $on {
            fn validate(msg: &IrcMsg) -> Result<(), ()> {
                use message_types::server;

                let legacy = IrcMsgLegacy::new(msg.as_bytes().to_vec()).unwrap();
                match server::IncomingMsg::from_msg(legacy.clone()) {
                    server::IncomingMsg::$from(ref _msg) => (),
                    _ => return Err(()),
                };
                Ok(())
            }
        }
    }
}

impl_irc_msg_subtype!(Invite);
irc_msg_legacy_validator!(Invite, Invite);

impl_irc_msg_subtype!(Join);
irc_msg_legacy_validator!(Join, Join);

impl Join {
    pub fn get_channel(&self) -> &[u8] {
        let buf = self.inner.as_bytes();
        let (_prefix, rest) = parse_helpers::split_prefix(buf);
        let (_command, rest) = parse_helpers::split_command(rest);
        let (channel, _rest) = parse_helpers::split_arg(rest);

        channel
    }

    pub fn get_nick(&self) -> &str {
        let buf = self.inner.as_bytes();
        let (prefix, _rest) = parse_helpers::split_prefix(buf);
        let (nick, _, _) = parse_helpers::parse_prefix(prefix).unwrap();
        unsafe { ::std::str::from_utf8_unchecked(nick) }
    }
}

impl_irc_msg_subtype!(Kick);
irc_msg_legacy_validator!(Kick, Kick);

impl_irc_msg_subtype!(Mode);
irc_msg_legacy_validator!(Mode, Mode);

impl_irc_msg_subtype!(Nick);
irc_msg_legacy_validator!(Nick, Nick);

impl_irc_msg_subtype!(Notice);
irc_msg_legacy_validator!(Notice, Notice);

impl_irc_msg_subtype!(Part);
irc_msg_legacy_validator!(Part, Part);

impl_irc_msg_subtype!(Ping);
irc_msg_legacy_validator!(Ping, Ping);

impl_irc_msg_subtype!(Pong);
irc_msg_legacy_validator!(Pong, Pong);

impl_irc_msg_subtype!(Privmsg);
irc_msg_legacy_validator!(Privmsg, Privmsg);

impl_irc_msg_subtype!(Topic);
irc_msg_legacy_validator!(Topic, Topic);

impl_irc_msg_subtype!(Quit);
irc_msg_legacy_validator!(Quit, Quit);

// impl_irc_msg_subtype!(Numeric);

// impl Numeric {
//     fn validate(msg: &IrcMsg) -> Result<(), ()> {
//         use message_types::server;

//         let legacy = IrcMsgLegacy::new(msg.as_bytes().to_vec()).unwrap();
//         match server::IncomingMsg::from_msg(legacy.clone()) {
//             server::IncomingMsg::Numeric(num, ref _msg) => (),
//             _ => return Err(()),
//         };
//         Ok(())
//     }
// }

<commit_msg>mtype2: panic instead of UB<commit_after>#[derive(Copy, Clone)]
pub enum IncomingMsg<'a> {
    Invite(&'a Invite),
    Join(&'a Join),
    Kick(&'a Kick),
    Mode(&'a Mode),
    Nick(&'a Nick),
    Notice(&'a Notice),
    Part(&'a Part),
    Ping(&'a Ping),
    Pong(&'a Pong),
    Privmsg(&'a Privmsg),
    Quit(&'a Quit),
    Topic(&'a Topic),

    // Others
    Unknown(&'a IrcMsg),
}

use ::parse::IrcMsg as IrcMsgLegacy;
use ::parse::parse2::IrcMsg;
use ::parse_helpers;

macro_rules! impl_irc_msg_subtype {
    ($id:ident) => {
        pub struct $id {
            inner: IrcMsg,
        }

        impl $id {
            pub fn from_irc_msg(msg: &IrcMsg) -> Result<&Self, ()> {
                try!($id::validate(msg));
                Ok(unsafe {::std::mem::transmute(msg) })
            }

            pub fn to_irc_msg(&self) -> &IrcMsg {
                &self.inner
            }
        }
    }
}

macro_rules! irc_msg_legacy_validator {
    ($on:ident, $from:ident) => {
        impl $on {
            fn validate(msg: &IrcMsg) -> Result<(), ()> {
                use message_types::server;

                let legacy = IrcMsgLegacy::new(msg.as_bytes().to_vec()).unwrap();
                match server::IncomingMsg::from_msg(legacy.clone()) {
                    server::IncomingMsg::$from(ref _msg) => (),
                    _ => return Err(()),
                };
                Ok(())
            }
        }
    }
}

impl_irc_msg_subtype!(Invite);
irc_msg_legacy_validator!(Invite, Invite);

impl_irc_msg_subtype!(Join);
irc_msg_legacy_validator!(Join, Join);

impl Join {
    pub fn get_channel(&self) -> &[u8] {
        let buf = self.inner.as_bytes();
        let (_prefix, rest) = parse_helpers::split_prefix(buf);
        let (_command, rest) = parse_helpers::split_command(rest);
        let (channel, _rest) = parse_helpers::split_arg(rest);

        channel
    }

    pub fn get_nick(&self) -> &str {
        let buf = self.inner.as_bytes();
        let (prefix, _rest) = parse_helpers::split_prefix(buf);
        let (nick, _, _) = parse_helpers::parse_prefix(prefix).unwrap();
        ::std::str::from_utf8(nick).unwrap()
    }
}

impl_irc_msg_subtype!(Kick);
irc_msg_legacy_validator!(Kick, Kick);

impl_irc_msg_subtype!(Mode);
irc_msg_legacy_validator!(Mode, Mode);

impl_irc_msg_subtype!(Nick);
irc_msg_legacy_validator!(Nick, Nick);

impl_irc_msg_subtype!(Notice);
irc_msg_legacy_validator!(Notice, Notice);

impl_irc_msg_subtype!(Part);
irc_msg_legacy_validator!(Part, Part);

impl_irc_msg_subtype!(Ping);
irc_msg_legacy_validator!(Ping, Ping);

impl_irc_msg_subtype!(Pong);
irc_msg_legacy_validator!(Pong, Pong);

impl_irc_msg_subtype!(Privmsg);
irc_msg_legacy_validator!(Privmsg, Privmsg);

impl_irc_msg_subtype!(Topic);
irc_msg_legacy_validator!(Topic, Topic);

impl_irc_msg_subtype!(Quit);
irc_msg_legacy_validator!(Quit, Quit);

// impl_irc_msg_subtype!(Numeric);

// impl Numeric {
//     fn validate(msg: &IrcMsg) -> Result<(), ()> {
//         use message_types::server;

//         let legacy = IrcMsgLegacy::new(msg.as_bytes().to_vec()).unwrap();
//         match server::IncomingMsg::from_msg(legacy.clone()) {
//             server::IncomingMsg::Numeric(num, ref _msg) => (),
//             _ => return Err(()),
//         };
//         Ok(())
//     }
// }

<|endoftext|>


<commit_before>//! Definition of various types related to connexions
<commit_msg>net/conn: Add definition of type EtherType, ProtocolIdType and PortType<commit_after>//! Definition of various types related to connexions

/// Type of the ether_type
pub type EtherType = u16;
/// Type that represent a protocol id
pub type ProtocolIdType = u8;
/// Type that represent a port
pub type PortType = u16;
<|endoftext|>


<commit_before>use rusqlite::{SqliteConnection, SqliteError};
use rusqlite::types::{ToSql, FromSql};
use rustc_serialize::json::{Json, ParserError};
use jmap::util::{FromJson, ParseError};
use jmap::contact::Contact;
use std::error::Error;
use std::convert::From;
use std::cell::Cell;
use std::fmt;
use std::cmp;
use self::DbError::*;

use std::path::Path;

const VERSION: u32 = 1;

const CREATE_SQL: [&'static str; 6] = [
r###"
CREATE TABLE records (
    rowid       INTEGER PRIMARY KEY,
    id          TEXT NOT NULL,
    userid      INTEGER NOT NULL,
    type        INTEGER NOT NULL,
    modseq      INTEGER NOT NULL,
    json        TEXT NOT NULL,
    UNIQUE( id, userid )
);
"###,
r###"
CREATE INDEX idx_record_id_userid          ON records ( id, userid );
"###,
r###"
CREATE INDEX idx_record_userid_type        ON records ( userid, type );
"###,
r###"
CREATE INDEX idx_record_userid_type_modseq ON records ( userid, type, modseq );
"###,
r###"
CREATE TABLE modseq (
    userid      INTEGER NOT NULL,
    type        INTEGER NOT NULL,
    modseq      INTEGER NOT NULL,
    UNIQUE( userid, type )
);
"###,
r###"
CREATE INDEX idx_userid_type ON modseq ( userid, type );
"###,
];

/*
const UPGRADE_SQL: [&'static str; 1] = [
    // v1
    ""
];
*/

#[derive(Clone, PartialEq, Debug)]
pub enum DbError {
    InternalError(String),
}

impl Error for DbError {
    fn description(&self) -> &str {
        match *self {
            InternalError(_) => "internal database error",
        }
    }
}

impl fmt::Display for DbError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            InternalError(ref e) => format!("internal database error: {}", e),
        }.to_string())
    }
}

impl From<SqliteError> for DbError {
    fn from(e: SqliteError) -> DbError {
        InternalError(format!("sqlite: {}", e))
    }
}

impl From<ParserError> for DbError {
    fn from(e: ParserError) -> DbError {
        InternalError(format!("json: {}", e))
    }
}

impl From<ParseError> for DbError {
    fn from(e: ParseError) -> DbError {
        InternalError(format!("jmap: {}", e))
    }
}

#[derive(Debug)]
pub struct Db {
    conn:   SqliteConnection,
    in_txn: Cell<bool>,
}

impl Db {
    pub fn open() -> Result<Db,Box<Error>> {
        //let conn = try!(SqliteConnection::open_in_memory());
        let conn = try!(SqliteConnection::open(&Path::new("db.sqlite")));
        let db = Db {
            conn:   conn,
            in_txn: Cell::new(false),
        };

        try!(db.upgrade());

        Ok(db)
    }

    pub fn transaction<F,T>(&self, f: F) -> Result<T,Box<Error>> where F: Fn() -> Result<T,Box<Error>> {
        let nested;

        match self.in_txn.get() {
            false => {
                try!(self.exec("BEGIN DEFERRED"));
                self.in_txn.set(true);
                nested = false;
            },
            true  => {
                try!(self.exec("SAVEPOINT sp"));
                nested = true;
            },
        };

        let r = f();

        match r {
            Ok(_) => match nested {
                false => {
                    try!(self.exec("COMMIT"));
                    self.in_txn.set(false);
                },
                true => try!(self.exec("RELEASE sp")),
            },
            Err(_) => match nested {
                false => {
                    try!(self.exec("ROLLBACK"));
                    self.in_txn.set(false);
                },
                true => try!(self.exec("ROLLBACK TO sp")),
            },
        };

        r
    }

    fn exec(&self, sql: &str) -> Result<(),Box<Error>> {
        let mut stmt = try!(self.conn.prepare(sql));
        try!(stmt.execute(&[]));
        Ok(())
    }

    fn exec_value<T>(&self, sql: &str, params: &[&ToSql]) -> Result<Option<T>,Box<Error>> where T: FromSql {
        let mut stmt = try!(self.conn.prepare(sql));
        let mut res = try!(stmt.query(params));

        match res.next() {
            None       => Ok(None),
            Some(next) =>
                match next {
                    Err(e)   => Err(Box::new(InternalError(format!("sqlite: {}", e)))),
                    Ok(next) => {
                        let v: T = next.get(0);
                        Ok(Some(v))
                    },
            }
        }
    }

    fn version(&self) -> Result<u32,Box<Error>> {
        let v = try!(self.exec_value::<i32>("PRAGMA user_version", &[]));
        match v {
            Some(v) => Ok(v as u32),
            None    => Ok(0),
        }
    }

    fn set_version(&self, v: u32) -> Result<(),Box<Error>> {
        try!(self.exec(format!("PRAGMA user_version = {}", v as i32).as_ref()));
        Ok(())
    }

    fn upgrade(&self) -> Result<(),Box<Error>> {
        self.transaction(|| {
            let ver = try!(self.version());
            if ver == VERSION { return Ok(()) }

            // new database
            if ver == 0 {
                for sql in CREATE_SQL.iter() {
                    try!(self.exec(sql));
                }
            }

            /*
            // existing database, upgrade required
            else {
                // XXX
            }
            */

            try!(self.set_version(VERSION));

            println!("upgraded db to version {}", VERSION);

            Ok(())
        })
    }

    pub fn get_state(&self, userid: i64) -> Result<String,Box<Error>> {
        let objtype = 1; // XXX contacts are type 1 for now

        let params: Vec<&ToSql> = vec!(&userid, &objtype);
        let sv = try!(self.exec_value::<i64>("SELECT modseq FROM modseq WHERE userid = ? AND type = ?", params.as_ref()));
        match sv {
            None    => Ok("0".to_string()),
            Some(v) => Ok(v.to_string()),
        }
    }

    pub fn get_records(&self, userid: i64, ids: Option<&Vec<String>>, since_state: Option<&String>) -> Result<Vec<Contact>,Box<Error>> {
        let objtype = 1; // XXX contacts are type 1 for now

        let modseq: i64;

        let mut sql = "SELECT json FROM records WHERE userid = ? AND type = ?".to_string();
        let mut params: Vec<&ToSql> = vec!(&userid, &objtype);

        if let Some(ref ids) = ids {
            sql.push_str(" AND id IN ( ");

            let mut i = ids.iter();
            if let Some(id) = i.next() {
                sql.push_str("?");
                params.push(id);
            }
            for id in i {
                sql.push_str(",?");
                params.push(id);
            }

            sql.push_str(" )");
        }

        if let Some(ref since_state) = since_state {
            let parsed = since_state.parse::<i64>();
            modseq = match parsed {
                Err(_) => 0,
                Ok(i)  => cmp::max(i,0),
            };

            sql.push_str(" AND modseq > ?");
            params.push(&modseq);
        }

        let mut stmt = try!(self.conn.prepare(sql.as_ref()));
        let res = try!(stmt.query(params.as_ref()));

        let mut records: Vec<Contact> = Vec::new();
        for row in res {
            if let Ok(ref r) = row {
                let json = try!(Json::from_str((r.get::<String>(0)).as_ref()));
                records.push(try!(Contact::from_json(&json)));
            }
        }

        Ok(records)
    }
}
<commit_msg>Pass params to SQL execute<commit_after>use rusqlite::{SqliteConnection, SqliteError};
use rusqlite::types::{ToSql, FromSql};
use rustc_serialize::json::{Json, ParserError};
use jmap::util::{FromJson, ParseError};
use jmap::contact::Contact;
use std::error::Error;
use std::convert::From;
use std::cell::Cell;
use std::fmt;
use std::cmp;
use self::DbError::*;

use std::path::Path;

const VERSION: u32 = 1;

const CREATE_SQL: [&'static str; 6] = [
r###"
CREATE TABLE records (
    rowid       INTEGER PRIMARY KEY,
    id          TEXT NOT NULL,
    userid      INTEGER NOT NULL,
    type        INTEGER NOT NULL,
    modseq      INTEGER NOT NULL,
    json        TEXT NOT NULL,
    UNIQUE( id, userid )
);
"###,
r###"
CREATE INDEX idx_record_id_userid          ON records ( id, userid );
"###,
r###"
CREATE INDEX idx_record_userid_type        ON records ( userid, type );
"###,
r###"
CREATE INDEX idx_record_userid_type_modseq ON records ( userid, type, modseq );
"###,
r###"
CREATE TABLE modseq (
    userid      INTEGER NOT NULL,
    type        INTEGER NOT NULL,
    modseq      INTEGER NOT NULL,
    UNIQUE( userid, type )
);
"###,
r###"
CREATE INDEX idx_userid_type ON modseq ( userid, type );
"###,
];

/*
const UPGRADE_SQL: [&'static str; 1] = [
    // v1
    ""
];
*/

#[derive(Clone, PartialEq, Debug)]
pub enum DbError {
    InternalError(String),
}

impl Error for DbError {
    fn description(&self) -> &str {
        match *self {
            InternalError(_) => "internal database error",
        }
    }
}

impl fmt::Display for DbError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            InternalError(ref e) => format!("internal database error: {}", e),
        }.to_string())
    }
}

impl From<SqliteError> for DbError {
    fn from(e: SqliteError) -> DbError {
        InternalError(format!("sqlite: {}", e))
    }
}

impl From<ParserError> for DbError {
    fn from(e: ParserError) -> DbError {
        InternalError(format!("json: {}", e))
    }
}

impl From<ParseError> for DbError {
    fn from(e: ParseError) -> DbError {
        InternalError(format!("jmap: {}", e))
    }
}

#[derive(Debug)]
pub struct Db {
    conn:   SqliteConnection,
    in_txn: Cell<bool>,
}

impl Db {
    pub fn open() -> Result<Db,Box<Error>> {
        //let conn = try!(SqliteConnection::open_in_memory());
        let conn = try!(SqliteConnection::open(&Path::new("db.sqlite")));
        let db = Db {
            conn:   conn,
            in_txn: Cell::new(false),
        };

        try!(db.upgrade());

        Ok(db)
    }

    pub fn transaction<F,T>(&self, f: F) -> Result<T,Box<Error>> where F: Fn() -> Result<T,Box<Error>> {
        let nested;

        match self.in_txn.get() {
            false => {
                try!(self.exec("BEGIN DEFERRED", &[]));
                self.in_txn.set(true);
                nested = false;
            },
            true  => {
                try!(self.exec("SAVEPOINT sp", &[]));
                nested = true;
            },
        };

        let r = f();

        match r {
            Ok(_) => match nested {
                false => {
                    try!(self.exec("COMMIT", &[]));
                    self.in_txn.set(false);
                },
                true => try!(self.exec("RELEASE sp", &[])),
            },
            Err(_) => match nested {
                false => {
                    try!(self.exec("ROLLBACK", &[]));
                    self.in_txn.set(false);
                },
                true => try!(self.exec("ROLLBACK TO sp", &[])),
            },
        };

        r
    }

    fn exec(&self, sql: &str, params: &[&ToSql]) -> Result<(),Box<Error>> {
        let mut stmt = try!(self.conn.prepare(sql));
        try!(stmt.execute(params));
        Ok(())
    }

    fn exec_value<T>(&self, sql: &str, params: &[&ToSql]) -> Result<Option<T>,Box<Error>> where T: FromSql {
        let mut stmt = try!(self.conn.prepare(sql));
        let mut res = try!(stmt.query(params));

        match res.next() {
            None       => Ok(None),
            Some(next) =>
                match next {
                    Err(e)   => Err(Box::new(InternalError(format!("sqlite: {}", e)))),
                    Ok(next) => {
                        let v: T = next.get(0);
                        Ok(Some(v))
                    },
            }
        }
    }

    fn version(&self) -> Result<u32,Box<Error>> {
        let v = try!(self.exec_value::<i32>("PRAGMA user_version", &[]));
        match v {
            Some(v) => Ok(v as u32),
            None    => Ok(0),
        }
    }

    fn set_version(&self, v: u32) -> Result<(),Box<Error>> {
        try!(self.exec(format!("PRAGMA user_version = {}", v as i32).as_ref(), &[]));
        Ok(())
    }

    fn upgrade(&self) -> Result<(),Box<Error>> {
        self.transaction(|| {
            let ver = try!(self.version());
            if ver == VERSION { return Ok(()) }

            // new database
            if ver == 0 {
                for sql in CREATE_SQL.iter() {
                    try!(self.exec(sql, &[]));
                }
            }

            /*
            // existing database, upgrade required
            else {
                // XXX
            }
            */

            try!(self.set_version(VERSION));

            println!("upgraded db to version {}", VERSION);

            Ok(())
        })
    }

    pub fn get_state(&self, userid: i64) -> Result<String,Box<Error>> {
        let objtype = 1; // XXX contacts are type 1 for now

        let params: Vec<&ToSql> = vec!(&userid, &objtype);
        let sv = try!(self.exec_value::<i64>("SELECT modseq FROM modseq WHERE userid = ? AND type = ?", params.as_ref()));
        match sv {
            None    => Ok("0".to_string()),
            Some(v) => Ok(v.to_string()),
        }
    }

    pub fn get_records(&self, userid: i64, ids: Option<&Vec<String>>, since_state: Option<&String>) -> Result<Vec<Contact>,Box<Error>> {
        let objtype = 1; // XXX contacts are type 1 for now

        let modseq: i64;

        let mut sql = "SELECT json FROM records WHERE userid = ? AND type = ?".to_string();
        let mut params: Vec<&ToSql> = vec!(&userid, &objtype);

        if let Some(ref ids) = ids {
            sql.push_str(" AND id IN ( ");

            let mut i = ids.iter();
            if let Some(id) = i.next() {
                sql.push_str("?");
                params.push(id);
            }
            for id in i {
                sql.push_str(",?");
                params.push(id);
            }

            sql.push_str(" )");
        }

        if let Some(ref since_state) = since_state {
            let parsed = since_state.parse::<i64>();
            modseq = match parsed {
                Err(_) => 0,
                Ok(i)  => cmp::max(i,0),
            };

            sql.push_str(" AND modseq > ?");
            params.push(&modseq);
        }

        let mut stmt = try!(self.conn.prepare(sql.as_ref()));
        let res = try!(stmt.query(params.as_ref()));

        let mut records: Vec<Contact> = Vec::new();
        for row in res {
            if let Ok(ref r) = row {
                let json = try!(Json::from_str((r.get::<String>(0)).as_ref()));
                records.push(try!(Contact::from_json(&json)));
            }
        }

        Ok(records)
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::Error;

extern crate std;
use std::thread_local;

use js_sys::{global, Uint8Array};
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};

// Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const BROWSER_CRYPTO_BUFFER_SIZE: usize = 256;

enum RngSource {
    Node(NodeCrypto),
    Browser(BrowserCrypto, Uint8Array),
}

// JsValues are always per-thread, so we initialize RngSource for each thread.
//   See: https://github.com/rustwasm/wasm-bindgen/pull/955
thread_local!(
    static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);

pub(crate) fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    RNG_SOURCE.with(|result| {
        let source = result.as_ref().map_err(|&e| e)?;

        match source {
            RngSource::Node(n) => {
                if n.random_fill_sync(dest).is_err() {
                    return Err(Error::NODE_RANDOM_FILL_SYNC);
                }
            }
            RngSource::Browser(crypto, buf) => {
                // getRandomValues does not work with all types of WASM memory,
                // so we initially write to browser memory to avoid exceptions.
                for chunk in dest.chunks_mut(BROWSER_CRYPTO_BUFFER_SIZE) {
                    // The chunk can be smaller than buf's length, so we call to
                    // JS to create a smaller view of buf without allocation.
                    let sub_buf = buf.subarray(0, chunk.len() as u32);

                    if crypto.get_random_values(&sub_buf).is_err() {
                        return Err(Error::WEB_GET_RANDOM_VALUES);
                    }
                    sub_buf.copy_to(chunk);
                }
            }
        };
        Ok(())
    })
}

fn getrandom_init() -> Result<RngSource, Error> {
    let global: Global = global().unchecked_into();
    if is_node(&global) {
        let crypto = require("crypto").map_err(|_| Error::NODE_CRYPTO)?;
        return Ok(RngSource::Node(crypto));
    }

    // Assume we are in some Web environment (browser or web worker). We get
    // `self.crypto` (called `msCrypto` on IE), so we can call
    // `crypto.getRandomValues`. If `crypto` isn't defined, we assume that
    // we are in an older web browser and the OS RNG isn't available.
    let crypto = match (global.crypto(), global.ms_crypto()) {
        (c, _) if c.is_object() => c,
        (_, c) if c.is_object() => c,
        _ => return Err(Error::WEB_CRYPTO),
    };

    let buf = Uint8Array::new_with_length(BROWSER_CRYPTO_BUFFER_SIZE as u32);
    Ok(RngSource::Browser(crypto, buf))
}

// Taken from https://www.npmjs.com/package/browser-or-node
fn is_node(global: &Global) -> bool {
    let process = global.process();
    if process.is_object() {
        let versions = process.versions();
        if versions.is_object() {
            return versions.node().is_string();
        }
    }
    false
}

#[wasm_bindgen]
extern "C" {
    type Global; // Return type of js_sys::global()

    // Web Crypto API (https://www.w3.org/TR/WebCryptoAPI/)
    #[wasm_bindgen(method, getter, js_name = "msCrypto")]
    fn ms_crypto(this: &Global) -> BrowserCrypto;
    #[wasm_bindgen(method, getter)]
    fn crypto(this: &Global) -> BrowserCrypto;
    type BrowserCrypto;
    #[wasm_bindgen(method, js_name = getRandomValues, catch)]
    fn get_random_values(this: &BrowserCrypto, buf: &Uint8Array) -> Result<(), JsValue>;

    // Node JS crypto module (https://nodejs.org/api/crypto.html)
    #[wasm_bindgen(catch, js_name = "module.require")]
    fn require(s: &str) -> Result<NodeCrypto, JsValue>;
    type NodeCrypto;
    #[wasm_bindgen(method, js_name = randomFillSync, catch)]
    fn random_fill_sync(this: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>;

    // Node JS process Object (https://nodejs.org/api/process.html)
    #[wasm_bindgen(method, getter)]
    fn process(this: &Global) -> Process;
    type Process;
    #[wasm_bindgen(method, getter)]
    fn versions(this: &Process) -> Versions;
    type Versions;
    #[wasm_bindgen(method, getter)]
    fn node(this: &Versions) -> JsValue;
}
<commit_msg>Fix Webpack warning caused by dynamic require<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::Error;

extern crate std;
use std::thread_local;

use js_sys::{global, Uint8Array};
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};

// Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const BROWSER_CRYPTO_BUFFER_SIZE: usize = 256;

enum RngSource {
    Node(NodeCrypto),
    Browser(BrowserCrypto, Uint8Array),
}

// JsValues are always per-thread, so we initialize RngSource for each thread.
//   See: https://github.com/rustwasm/wasm-bindgen/pull/955
thread_local!(
    static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);

pub(crate) fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    RNG_SOURCE.with(|result| {
        let source = result.as_ref().map_err(|&e| e)?;

        match source {
            RngSource::Node(n) => {
                if n.random_fill_sync(dest).is_err() {
                    return Err(Error::NODE_RANDOM_FILL_SYNC);
                }
            }
            RngSource::Browser(crypto, buf) => {
                // getRandomValues does not work with all types of WASM memory,
                // so we initially write to browser memory to avoid exceptions.
                for chunk in dest.chunks_mut(BROWSER_CRYPTO_BUFFER_SIZE) {
                    // The chunk can be smaller than buf's length, so we call to
                    // JS to create a smaller view of buf without allocation.
                    let sub_buf = buf.subarray(0, chunk.len() as u32);

                    if crypto.get_random_values(&sub_buf).is_err() {
                        return Err(Error::WEB_GET_RANDOM_VALUES);
                    }
                    sub_buf.copy_to(chunk);
                }
            }
        };
        Ok(())
    })
}

fn getrandom_init() -> Result<RngSource, Error> {
    let global: Global = global().unchecked_into();
    if is_node(&global) {
        let crypto = NODE_MODULE
            .require("crypto")
            .map_err(|_| Error::NODE_CRYPTO)?;
        return Ok(RngSource::Node(crypto));
    }

    // Assume we are in some Web environment (browser or web worker). We get
    // `self.crypto` (called `msCrypto` on IE), so we can call
    // `crypto.getRandomValues`. If `crypto` isn't defined, we assume that
    // we are in an older web browser and the OS RNG isn't available.
    let crypto = match (global.crypto(), global.ms_crypto()) {
        (c, _) if c.is_object() => c,
        (_, c) if c.is_object() => c,
        _ => return Err(Error::WEB_CRYPTO),
    };

    let buf = Uint8Array::new_with_length(BROWSER_CRYPTO_BUFFER_SIZE as u32);
    Ok(RngSource::Browser(crypto, buf))
}

// Taken from https://www.npmjs.com/package/browser-or-node
fn is_node(global: &Global) -> bool {
    let process = global.process();
    if process.is_object() {
        let versions = process.versions();
        if versions.is_object() {
            return versions.node().is_string();
        }
    }
    false
}

#[wasm_bindgen]
extern "C" {
    type Global; // Return type of js_sys::global()

    // Web Crypto API (https://www.w3.org/TR/WebCryptoAPI/)
    #[wasm_bindgen(method, getter, js_name = "msCrypto")]
    fn ms_crypto(this: &Global) -> BrowserCrypto;
    #[wasm_bindgen(method, getter)]
    fn crypto(this: &Global) -> BrowserCrypto;
    type BrowserCrypto;
    #[wasm_bindgen(method, js_name = getRandomValues, catch)]
    fn get_random_values(this: &BrowserCrypto, buf: &Uint8Array) -> Result<(), JsValue>;

    type NodeModule;
    #[wasm_bindgen(js_name = module)]
    static NODE_MODULE: NodeModule;
    // Node JS crypto module (https://nodejs.org/api/crypto.html)
    #[wasm_bindgen(method, catch)]
    fn require(this: &NodeModule, s: &str) -> Result<NodeCrypto, JsValue>;
    type NodeCrypto;
    #[wasm_bindgen(method, js_name = randomFillSync, catch)]
    fn random_fill_sync(this: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>;

    // Node JS process Object (https://nodejs.org/api/process.html)
    #[wasm_bindgen(method, getter)]
    fn process(this: &Global) -> Process;
    type Process;
    #[wasm_bindgen(method, getter)]
    fn versions(this: &Process) -> Versions;
    type Versions;
    #[wasm_bindgen(method, getter)]
    fn node(this: &Versions) -> JsValue;
}
<|endoftext|>


<commit_before>//! This module contains neural network implementations.
extern crate collenchyma as co;
extern crate collenchyma_nn as nn;
use self::co::backend::{Backend, BackendConfig};
use self::co::framework::IFramework;
use self::co::frameworks::{Cuda, Native};
use self::co::memory::MemoryType;
use self::co::tensor::SharedTensor;
use self::nn::*;
use super::{SISO, Learning};
<commit_msg>remove nn temporarily<commit_after><|endoftext|>


<commit_before>use crate::schema::*;
use diesel::result::Error;
use diesel::*;

#[test]
#[cfg(not(feature = "sqlite"))] // FIXME: This test is only valid when operating on a file and not :memory:
fn transaction_executes_fn_in_a_sql_transaction() {
    const TEST_NAME: &'static str = "transaction_executes_fn_in_a_sql_transaction";
    let conn1 = &mut connection_without_transaction();
    let conn2 = &mut connection_without_transaction();
    setup_test_table(conn1, TEST_NAME);

    fn get_count(conn: &mut TestConnection) -> i64 {
        count_test_table(conn, TEST_NAME)
    }

    conn1
        .transaction::<_, Error, _>(|conn1| {
            assert_eq!(0, get_count(conn1));
            assert_eq!(0, get_count(conn2));
            conn1.execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))?;
            assert_eq!(1, get_count(conn1));
            assert_eq!(0, get_count(conn2));
            Ok(())
        })
        .unwrap();

    assert_eq!(1, get_count(conn1));
    assert_eq!(1, get_count(conn2));

    drop_test_table(conn1, TEST_NAME);
}

#[test]
fn transaction_returns_the_returned_value() {
    let conn1 = &mut connection_without_transaction();

    assert_eq!(Ok(1), conn1.transaction::<_, Error, _>(|_| Ok(1)));
}

#[test]
fn transaction_is_rolled_back_when_returned_an_error() {
    let connection = &mut connection_without_transaction();
    let test_name = "transaction_is_rolled_back_when_returned_an_error";
    setup_test_table(connection, test_name);

    let _ = connection.transaction::<(), _, _>(|connection| {
        connection
            .execute(&format!("INSERT INTO {} DEFAULT VALUES", test_name))
            .unwrap();
        Err(Error::RollbackTransaction)
    });
    assert_eq!(0, count_test_table(connection, test_name));

    drop_test_table(connection, test_name);
}

#[test]
fn transaction_rollback_returns_error() {
    let connection = &mut connection_without_transaction();
    let test_name = "transaction_rollback_returns_error";
    setup_test_table(connection, test_name);

    // Create a transaction that will fail to rollback.
    let r = connection.transaction::<usize, _, _>(|connection| {
        connection
            .execute(&format!("INSERT INTO {} DEFAULT VALUES", test_name))
            .unwrap();

        // This rollback would succeed, and cause any rollback later to fail.
        connection.execute("ROLLBACK").unwrap();

        // Return any error to trigger a rollback that fails in this case.
        Err(Error::NotFound)
    });

    // Verify that the transaction failed with `RollbackError`.
    assert!(r.is_err());
    assert!(matches!(r.unwrap_err(), Error::RollbackError(_)));

    assert_eq!(0, count_test_table(connection, test_name));
    drop_test_table(connection, test_name);
}

#[test]
fn transactions_can_be_nested() {
    let connection = &mut connection_without_transaction();
    const TEST_NAME: &'static str = "transactions_can_be_nested";
    setup_test_table(connection, TEST_NAME);
    fn get_count(connection: &mut TestConnection) -> i64 {
        count_test_table(connection, TEST_NAME)
    }

    let _ = connection.transaction::<(), _, _>(|connection| {
        connection
            .execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))
            .unwrap();
        assert_eq!(1, get_count(connection));
        let _ = connection.transaction::<(), _, _>(|connection| {
            connection
                .execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))
                .unwrap();
            assert_eq!(2, get_count(connection));
            Err(Error::RollbackTransaction)
        });
        assert_eq!(1, get_count(connection));
        let _ = connection.transaction::<(), Error, _>(|connection| {
            connection
                .execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))
                .unwrap();
            assert_eq!(2, get_count(connection));
            Ok(())
        });
        assert_eq!(2, get_count(connection));
        Err(Error::RollbackTransaction)
    });
    assert_eq!(0, get_count(connection));

    drop_test_table(connection, TEST_NAME);
}

#[test]
fn test_transaction_always_rolls_back() {
    let connection = &mut connection_without_transaction();
    let test_name = "test_transaction_always_rolls_back";
    setup_test_table(connection, test_name);

    let result = connection.test_transaction::<_, Error, _>(|connection| {
        connection.execute(&format!("INSERT INTO {} DEFAULT VALUES", test_name))?;
        assert_eq!(1, count_test_table(connection, test_name));
        Ok("success")
    });
    assert_eq!(0, count_test_table(connection, test_name));
    assert_eq!("success", result);

    drop_test_table(connection, test_name);
}

#[test]
#[should_panic(expected = "Transaction did not succeed")]
fn test_transaction_panics_on_error() {
    let connection = &mut connection_without_transaction();
    connection.test_transaction::<(), _, _>(|_| Err(()));
}

fn setup_test_table(connection: &mut TestConnection, table_name: &str) {
    use crate::schema_dsl::*;
    create_table(table_name, (integer("id").primary_key().auto_increment(),))
        .execute(connection)
        .unwrap();
}

fn drop_test_table(connection: &mut TestConnection, table_name: &str) {
    connection
        .execute(&format!("DROP TABLE {}", table_name))
        .unwrap();
}

fn count_test_table(connection: &mut TestConnection, table_name: &str) -> i64 {
    use diesel::dsl::sql;
    select(sql::<sql_types::BigInt>(&format!(
        "COUNT(*) FROM {}",
        table_name
    )))
    .first(connection)
    .unwrap()
}

#[test]
#[cfg(feature = "postgres")]
fn regression_test_for_2123() {
    let conn = &mut connection_without_transaction();
    // fail once
    let ret = conn.transaction(|conn| {
        let _ = conn.transaction(|conn| {
            // handling error
            match conn.execute("SELECT foo") {
                // do nothing
                Ok(_) => unreachable!("This query should fail"),
                // ignore the error
                Err(e) => eprintln!("error occurred: {}", e),
            };
            Ok::<_, Error>(())
        });

        conn.transaction(|conn| {
            let ret = conn.execute("SELECT 1");
            assert_eq!(Ok(1), ret);
            Ok::<_, Error>(())
        })
    });
    println!("{:?}", ret);
    // other transaction
    let ret = conn
        .build_transaction()
        .serializable()
        .run(|conn| conn.execute("SELECT 1"));
    // must be Ok(1), but get Err(AlreadyInTransaction)
    println!("{:?}", ret);
    assert_eq!(Ok(1), ret);
}
<commit_msg>test for sqlite at this moment<commit_after>use crate::schema::*;
use diesel::result::Error;
use diesel::*;

#[test]
#[cfg(not(feature = "sqlite"))] // FIXME: This test is only valid when operating on a file and not :memory:
fn transaction_executes_fn_in_a_sql_transaction() {
    const TEST_NAME: &'static str = "transaction_executes_fn_in_a_sql_transaction";
    let conn1 = &mut connection_without_transaction();
    let conn2 = &mut connection_without_transaction();
    setup_test_table(conn1, TEST_NAME);

    fn get_count(conn: &mut TestConnection) -> i64 {
        count_test_table(conn, TEST_NAME)
    }

    conn1
        .transaction::<_, Error, _>(|conn1| {
            assert_eq!(0, get_count(conn1));
            assert_eq!(0, get_count(conn2));
            conn1.execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))?;
            assert_eq!(1, get_count(conn1));
            assert_eq!(0, get_count(conn2));
            Ok(())
        })
        .unwrap();

    assert_eq!(1, get_count(conn1));
    assert_eq!(1, get_count(conn2));

    drop_test_table(conn1, TEST_NAME);
}

#[test]
fn transaction_returns_the_returned_value() {
    let conn1 = &mut connection_without_transaction();

    assert_eq!(Ok(1), conn1.transaction::<_, Error, _>(|_| Ok(1)));
}

#[test]
fn transaction_is_rolled_back_when_returned_an_error() {
    let connection = &mut connection_without_transaction();
    let test_name = "transaction_is_rolled_back_when_returned_an_error";
    setup_test_table(connection, test_name);

    let _ = connection.transaction::<(), _, _>(|connection| {
        connection
            .execute(&format!("INSERT INTO {} DEFAULT VALUES", test_name))
            .unwrap();
        Err(Error::RollbackTransaction)
    });
    assert_eq!(0, count_test_table(connection, test_name));

    drop_test_table(connection, test_name);
}

#[test]
#[cfg(feature = "sqlite")]
fn transaction_rollback_returns_error() {
    let connection = &mut connection_without_transaction();
    let test_name = "transaction_rollback_returns_error";
    setup_test_table(connection, test_name);

    // Create a transaction that will fail to rollback.
    let r = connection.transaction::<usize, _, _>(|connection| {
        connection
            .execute(&format!("INSERT INTO {} DEFAULT VALUES", test_name))
            .unwrap();

        // This rollback would succeed, and cause any rollback later to fail.
        connection.execute("ROLLBACK").unwrap();

        // Return any error to trigger a rollback that fails in this case.
        Err(Error::NotFound)
    });

    // Verify that the transaction failed with `RollbackError`.
    assert!(r.is_err());
    assert!(matches!(r.unwrap_err(), Error::RollbackError(_)));

    assert_eq!(0, count_test_table(connection, test_name));
    drop_test_table(connection, test_name);
}

#[test]
fn transactions_can_be_nested() {
    let connection = &mut connection_without_transaction();
    const TEST_NAME: &'static str = "transactions_can_be_nested";
    setup_test_table(connection, TEST_NAME);
    fn get_count(connection: &mut TestConnection) -> i64 {
        count_test_table(connection, TEST_NAME)
    }

    let _ = connection.transaction::<(), _, _>(|connection| {
        connection
            .execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))
            .unwrap();
        assert_eq!(1, get_count(connection));
        let _ = connection.transaction::<(), _, _>(|connection| {
            connection
                .execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))
                .unwrap();
            assert_eq!(2, get_count(connection));
            Err(Error::RollbackTransaction)
        });
        assert_eq!(1, get_count(connection));
        let _ = connection.transaction::<(), Error, _>(|connection| {
            connection
                .execute(&format!("INSERT INTO {} DEFAULT VALUES", TEST_NAME))
                .unwrap();
            assert_eq!(2, get_count(connection));
            Ok(())
        });
        assert_eq!(2, get_count(connection));
        Err(Error::RollbackTransaction)
    });
    assert_eq!(0, get_count(connection));

    drop_test_table(connection, TEST_NAME);
}

#[test]
fn test_transaction_always_rolls_back() {
    let connection = &mut connection_without_transaction();
    let test_name = "test_transaction_always_rolls_back";
    setup_test_table(connection, test_name);

    let result = connection.test_transaction::<_, Error, _>(|connection| {
        connection.execute(&format!("INSERT INTO {} DEFAULT VALUES", test_name))?;
        assert_eq!(1, count_test_table(connection, test_name));
        Ok("success")
    });
    assert_eq!(0, count_test_table(connection, test_name));
    assert_eq!("success", result);

    drop_test_table(connection, test_name);
}

#[test]
#[should_panic(expected = "Transaction did not succeed")]
fn test_transaction_panics_on_error() {
    let connection = &mut connection_without_transaction();
    connection.test_transaction::<(), _, _>(|_| Err(()));
}

fn setup_test_table(connection: &mut TestConnection, table_name: &str) {
    use crate::schema_dsl::*;
    create_table(table_name, (integer("id").primary_key().auto_increment(),))
        .execute(connection)
        .unwrap();
}

fn drop_test_table(connection: &mut TestConnection, table_name: &str) {
    connection
        .execute(&format!("DROP TABLE {}", table_name))
        .unwrap();
}

fn count_test_table(connection: &mut TestConnection, table_name: &str) -> i64 {
    use diesel::dsl::sql;
    select(sql::<sql_types::BigInt>(&format!(
        "COUNT(*) FROM {}",
        table_name
    )))
    .first(connection)
    .unwrap()
}

#[test]
#[cfg(feature = "postgres")]
fn regression_test_for_2123() {
    let conn = &mut connection_without_transaction();
    // fail once
    let ret = conn.transaction(|conn| {
        let _ = conn.transaction(|conn| {
            // handling error
            match conn.execute("SELECT foo") {
                // do nothing
                Ok(_) => unreachable!("This query should fail"),
                // ignore the error
                Err(e) => eprintln!("error occurred: {}", e),
            };
            Ok::<_, Error>(())
        });

        conn.transaction(|conn| {
            let ret = conn.execute("SELECT 1");
            assert_eq!(Ok(1), ret);
            Ok::<_, Error>(())
        })
    });
    println!("{:?}", ret);
    // other transaction
    let ret = conn
        .build_transaction()
        .serializable()
        .run(|conn| conn.execute("SELECT 1"));
    // must be Ok(1), but get Err(AlreadyInTransaction)
    println!("{:?}", ret);
    assert_eq!(Ok(1), ret);
}
<|endoftext|>


<commit_before>use serde_json;

use line::Line;

pub enum OpType {
    Cpy,
    Skip,
    Invalidate,
    Update,
    Ins,
}

impl OpType {
    fn from_str(op: &str) -> OpType {
        if op == "copy" {
            OpType::Cpy
        } else if op == "skip" {
            OpType::Skip
        } else if op == "invalidate" {
            OpType::Invalidate
        } else if op == "update" {
            OpType::Update
        } else if op == "ins" {
            OpType::Ins
        } else {
            panic!("Unknown Op type {:?}", op);
        }
    }
}

pub struct Op {
    op: OpType,
    n: u64,
    lines: Option<Vec<Line>>,
}

impl Op {
    pub fn from_value(value: &serde_json::Value) -> Op {
        let obj = value.as_object().unwrap();
        let lines = match obj.get("lines") {
            Some(line_value) => {
                let line_list = line_value.as_array().unwrap();
                Some(line_list.iter().map(|line| Line::from_value(line)).collect())
            },
            _ => None,
        };
        Op {
            op: OpType::from_str(obj.get("op").unwrap().as_str().unwrap()),
            n: obj.get("n").unwrap().as_u64().unwrap(),
            lines: lines,
        }
    }
}
<commit_msg>Adds `apply()` function to Op implementation<commit_after>use serde_json;

use line::Line;

pub enum OpType {
    Cpy,
    Skip,
    Invalidate,
    Update,
    Ins,
}

impl OpType {
    fn from_str(op: &str) -> OpType {
        if op == "copy" {
            OpType::Cpy
        } else if op == "skip" {
            OpType::Skip
        } else if op == "invalidate" {
            OpType::Invalidate
        } else if op == "update" {
            OpType::Update
        } else if op == "ins" {
            OpType::Ins
        } else {
            panic!("Unknown Op type {:?}", op);
        }
    }
}

pub struct Op {
    op: OpType,
    n: u64,
    lines: Option<Vec<Line>>,
}

impl Op {
    pub fn from_value(value: &serde_json::Value) -> Op {
        let obj = value.as_object().unwrap();
        let lines = match obj.get("lines") {
            Some(line_value) => {
                let line_list = line_value.as_array().unwrap();
                Some(line_list.iter().map(|line| Line::from_value(line)).collect())
            },
            _ => None,
        };
        Op {
            op: OpType::from_str(obj.get("op").unwrap().as_str().unwrap()),
            n: obj.get("n").unwrap().as_u64().unwrap(),
            lines: lines,
        }
    }

    pub fn apply(&self, old_lines: &Vec<Line>, old_line_index: u64, new_lines: &mut Vec<Line>) -> u64 {
        match self.op {
            OpType::Cpy => {
                let new_index = old_line_index + self.n;
                for i in old_line_index..new_index {
                    new_lines.push(old_lines[i as usize].clone());
                }
                new_index
            },
            OpType::Skip => {
                old_line_index + self.n
            },
            OpType::Invalidate => {
                let new_index = old_line_index + self.n;
                for i in old_line_index..new_index {
                    let mut line = old_lines[i as usize].clone();
                    line.cursor = Some(vec![]);
                    new_lines.push(line);
                }
                new_index
            },
            OpType::Update => {
                let new_index = old_line_index + self.n;
                let lines = self.lines.clone().unwrap();
                for i in old_line_index..new_index {
                    let mut line = old_lines[i as usize].clone();
                    line.cursor = lines[i as usize].cursor.clone();
                    line.styles = lines[i as usize].styles.clone();
                    new_lines.push(line);
                }
                new_index
            },
            OpType::Ins => {
                let lines = self.lines.clone().unwrap();
                new_lines.extend(lines.iter().cloned());
                old_line_index + self.n
            },
        }
    }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! Volume Groups

use std::io::Result;
use std::io::Error;
use std::io::ErrorKind::Other;
use std::collections::BTreeMap;
use std::str::FromStr;

use uuid::Uuid;
use time::now;
use nix;

use lv::{LV, Segment};
use pv::{PV, Device};
use pvlabel::PvHeader;
use parser::{LvmTextMap, Entry};
use lvmetad::vg_update_lvmetad;
use dm::DM;

/// A Volume Group.
#[derive(Debug, PartialEq, Clone)]
pub struct VG {
    /// Name.
    pub name: String,
    /// Uuid.
    pub id: String,
    /// The generation of metadata this VG represents.
    pub seqno: u64,
    /// Always "LVM2".
    pub format: String,
    /// Status.
    pub status: Vec<String>,
    /// Flags.
    pub flags: Vec<String>,
    /// Size of each extent, in 512-byte sectors.
    pub extent_size: u64,
    /// Maximum number of LVs, 0 means no limit.
    pub max_lv: u64,
    /// Maximum number of PVs, 0 means no limit.
    pub max_pv: u64,
    /// How many metadata copies (?)
    pub metadata_copies: u64,
    /// Physical Volumes within this volume group.
    pub pvs: BTreeMap<String, PV>,
    /// Logical Volumes within this volume group.
    pub lvs: BTreeMap<String, LV>,
}

impl VG {
    /// The total number of extents in use in the volume group.
    pub fn extents_in_use(&self) -> u64 {
        self.lvs
            .values()
            .map(|x| x.used_extents())
            .sum()
    }

    /// The total number of free extents in the volume group.
    pub fn extents_free(&self) -> u64 {
        self.extents() - self.extents_in_use()
    }

    /// The total number of extents in the volume group.
    pub fn extents(&self) -> u64 {
        self.pvs
            .values()
            .map(|x| x.pe_count)
            .sum()
    }

    /// Add a non-affiliated PV to this VG.
    pub fn add_pv(&mut self, pvh: &PvHeader) -> Result<()> {
        // add_pv_to_vg
        // check pv is not on an LV from the vg:
        // 1) is pv's major a devicemapper major?
        // 2) equiv. of dev_manager_device_uses_vg()
        let dev = try!(Device::from_str(&pvh.dev_path.to_string_lossy()));
        if DM::is_dm_major(dev.major) {
            println!("gotta check more against recursion");
        }

        // check pv is not already in the VG or another VG
        // 1) does it have text metadata??

        // figure out how many extents fit in the PV's data area
        // pe_start = da.offset
        // area_size = dev_size - da.offset - maybe(mda1.size)
        // pe_count = area_size / vg.extent_size

        // make a PV and add it to self

        Ok(())
    }

    /// Create a new linear logical volume in the volume group.
    pub fn new_linear_lv(&mut self, name: &str, extent_size: u64) -> Result<()> {
        if self.lvs.contains_key(name) {
            return Err(Error::new(Other, "LV already exists"));
        }

        let mut contig_area = None;
        for (pvname, areas) in self.free_areas() {
            for (start, len) in areas {
                if len >= extent_size {
                    contig_area = Some((pvname, start));
                    break;
                }
            }
        }

        // we don't support multiple segments yet
        let (pv_with_area, area_start) = match contig_area {
            None => return Err(Error::new(Other, "no contiguous area for new LV")),
            Some(x) => x,
        };

        let segment = Segment {
            name: "segment1".to_string(),
            start_extent: 0,
            extent_count: extent_size,
            ty: "striped".to_string(),
            stripes: vec![(pv_with_area, area_start)],
        };

        let mut lv = LV {
            name: name.to_string(),
            id: Uuid::new_v4().to_hyphenated_string(),
            status: vec!["READ".to_string(),
                         "WRITE".to_string(),
                         "VISIBLE".to_string()],
            flags: Vec::new(),
            creation_host: nix::sys::utsname::uname().nodename().to_string(),
            creation_time: now().to_timespec().sec,
            segments: vec![segment],
            device: None,
        };

        // poke dm and tell it about a new device
        {
            let dm = try!(DM::new(self));
            try!(dm.activate_device(&mut lv));
        }

        self.lvs.insert(name.to_string(), lv);

        self.commit()
    }

    /// Destroy a logical volume.
    pub fn lv_remove(&mut self, name: &str) -> Result<()> {
        match self.lvs.remove(name) {
            Some(_) => {
                // TODO: poke dm; remove device
                self.commit()
            },
            None => Err(Error::new(Other, "LV not found in VG")),
        }
    }

    fn commit(&mut self) -> Result<()> {
        let map = self.clone().into();

        // TODO: atomicity of updating pvs, metad, dm
        for pv in self.pvs.values() {
            if let Some(path) = pv.device.path() {
                let mut pvheader = PvHeader::find_in_dev(&path)
                    .expect("could not find pvheader");

                try!(pvheader.write_metadata(&map));
            }
        }

        // tell lvmetad
        vg_update_lvmetad(&map)
    }

    // Returns e.g. {"pv0": {0: 45, 47: 100, 100: 200} }
    // This means extents 0-44 are used, 45 and 46 are not,
    // 47-99 are used, then 100-199 are used.
    //
    // Adjacent used areas are not merged.
    //
    // PVs with no used areas are not in the outer map at all.
    //
    fn used_areas(&self) -> BTreeMap<String, BTreeMap<u64, u64>> {
        let mut used_map = BTreeMap::new();

        for lv in self.lvs.values() {
            for seg in &lv.segments {
                for &(ref pvname, start) in &seg.stripes {
                    used_map.entry(pvname.to_string())
                        .or_insert(BTreeMap::new())
                        .insert(start as u64, seg.extent_count);
                }
            }
        }

        used_map
    }

    // Returns e.g. {"pv0": {45: 47, 200: 1000} }
    // (assuming pv0 has 1000 extents)
    //
    // PVs with no used areas are not in the outer map at all.
    //
    fn free_areas(&self) -> BTreeMap<String, BTreeMap<u64, u64>> {
        let mut free_map = BTreeMap::new();

        for (pvname, mut area_map) in self.used_areas() {

            // Insert an entry to mark the end of the PV so the fold works
            // correctly
            let pv = self.pvs.get(&pvname)
                .expect("area map name refers to nonexistent PV");
            area_map.insert(pv.pe_count, 0);

            area_map.iter()
                .fold(0, |prev_end, (start, len)| {
                    if prev_end < *start {
                        free_map.entry(pvname.clone())
                            .or_insert(BTreeMap::new())
                            .insert(prev_end, start-prev_end);
                    }
                    start + len
                });
        }

        // Also return completely-unused PVs
        for (pvname, pv) in &self.pvs {
            if !free_map.contains_key(pvname) {
                let mut map = BTreeMap::new();
                map.insert(0, pv.pe_count);
                free_map.insert(pvname.clone(), map);
            }
        }

        free_map
    }
}

impl From<VG> for LvmTextMap {
    fn from(vg: VG) -> Self {
        let mut map = LvmTextMap::new();

        map.insert("id".to_string(), Entry::String(vg.id));
        map.insert("seqno".to_string(),
                   Entry::Number(vg.seqno as i64 + 1));
        map.insert("format".to_string(), Entry::String(vg.format));

        map.insert("max_pv".to_string(), Entry::Number(0));
        map.insert("max_lv".to_string(), Entry::Number(0));

        map.insert("status".to_string(),
                   Entry::List(
                       Box::new(
                           vg.status
                               .into_iter()
                               .map(|x| Entry::String(x))
                               .collect())));

        map.insert("flags".to_string(),
                   Entry::List(
                       Box::new(
                           vg.flags
                               .into_iter()
                               .map(|x| Entry::String(x))
                               .collect())));

        map.insert("extent_size".to_string(),
                   Entry::Number(vg.extent_size as i64));
        map.insert("metadata_copies".to_string(),
                   Entry::Number(vg.metadata_copies as i64));
        map.insert("physical_volumes".to_string(),
                   Entry::TextMap(
                       Box::new(
                           vg.pvs
                               .into_iter()
                               .map(|(k, v)|
                                    (k, Entry::TextMap(Box::new(v.into()))))
                               .collect())));

        map.insert("logical_volumes".to_string(),
                   Entry::TextMap(
                       Box::new(
                           vg.lvs
                               .into_iter()
                               .map(|(k, v)|
                                    (k, Entry::TextMap(Box::new(v.into()))))
                               .collect())));

        let mut outer_map = LvmTextMap::new();

        outer_map.insert(vg.name, Entry::TextMap(Box::new(map)));

        outer_map
    }
}
<commit_msg>Remove accidentally cut n pasted comment<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! Volume Groups

use std::io::Result;
use std::io::Error;
use std::io::ErrorKind::Other;
use std::collections::BTreeMap;
use std::str::FromStr;

use uuid::Uuid;
use time::now;
use nix;

use lv::{LV, Segment};
use pv::{PV, Device};
use pvlabel::PvHeader;
use parser::{LvmTextMap, Entry};
use lvmetad::vg_update_lvmetad;
use dm::DM;

/// A Volume Group.
#[derive(Debug, PartialEq, Clone)]
pub struct VG {
    /// Name.
    pub name: String,
    /// Uuid.
    pub id: String,
    /// The generation of metadata this VG represents.
    pub seqno: u64,
    /// Always "LVM2".
    pub format: String,
    /// Status.
    pub status: Vec<String>,
    /// Flags.
    pub flags: Vec<String>,
    /// Size of each extent, in 512-byte sectors.
    pub extent_size: u64,
    /// Maximum number of LVs, 0 means no limit.
    pub max_lv: u64,
    /// Maximum number of PVs, 0 means no limit.
    pub max_pv: u64,
    /// How many metadata copies (?)
    pub metadata_copies: u64,
    /// Physical Volumes within this volume group.
    pub pvs: BTreeMap<String, PV>,
    /// Logical Volumes within this volume group.
    pub lvs: BTreeMap<String, LV>,
}

impl VG {
    /// The total number of extents in use in the volume group.
    pub fn extents_in_use(&self) -> u64 {
        self.lvs
            .values()
            .map(|x| x.used_extents())
            .sum()
    }

    /// The total number of free extents in the volume group.
    pub fn extents_free(&self) -> u64 {
        self.extents() - self.extents_in_use()
    }

    /// The total number of extents in the volume group.
    pub fn extents(&self) -> u64 {
        self.pvs
            .values()
            .map(|x| x.pe_count)
            .sum()
    }

    /// Add a non-affiliated PV to this VG.
    pub fn add_pv(&mut self, pvh: &PvHeader) -> Result<()> {
        // add_pv_to_vg
        // check pv is not on an LV from the vg:
        // 1) is pv's major a devicemapper major?
        // 2) equiv. of dev_manager_device_uses_vg()
        let dev = try!(Device::from_str(&pvh.dev_path.to_string_lossy()));
        if DM::is_dm_major(dev.major) {
            println!("gotta check more against recursion");
        }

        // check pv is not already in the VG or another VG
        // 1) does it have text metadata??

        // figure out how many extents fit in the PV's data area
        // pe_start = da.offset
        // area_size = dev_size - da.offset - maybe(mda1.size)
        // pe_count = area_size / vg.extent_size

        // make a PV and add it to self

        Ok(())
    }

    /// Create a new linear logical volume in the volume group.
    pub fn new_linear_lv(&mut self, name: &str, extent_size: u64) -> Result<()> {
        if self.lvs.contains_key(name) {
            return Err(Error::new(Other, "LV already exists"));
        }

        let mut contig_area = None;
        for (pvname, areas) in self.free_areas() {
            for (start, len) in areas {
                if len >= extent_size {
                    contig_area = Some((pvname, start));
                    break;
                }
            }
        }

        // we don't support multiple segments yet
        let (pv_with_area, area_start) = match contig_area {
            None => return Err(Error::new(Other, "no contiguous area for new LV")),
            Some(x) => x,
        };

        let segment = Segment {
            name: "segment1".to_string(),
            start_extent: 0,
            extent_count: extent_size,
            ty: "striped".to_string(),
            stripes: vec![(pv_with_area, area_start)],
        };

        let mut lv = LV {
            name: name.to_string(),
            id: Uuid::new_v4().to_hyphenated_string(),
            status: vec!["READ".to_string(),
                         "WRITE".to_string(),
                         "VISIBLE".to_string()],
            flags: Vec::new(),
            creation_host: nix::sys::utsname::uname().nodename().to_string(),
            creation_time: now().to_timespec().sec,
            segments: vec![segment],
            device: None,
        };

        // poke dm and tell it about a new device
        {
            let dm = try!(DM::new(self));
            try!(dm.activate_device(&mut lv));
        }

        self.lvs.insert(name.to_string(), lv);

        self.commit()
    }

    /// Destroy a logical volume.
    pub fn lv_remove(&mut self, name: &str) -> Result<()> {
        match self.lvs.remove(name) {
            Some(_) => {
                // TODO: poke dm; remove device
                self.commit()
            },
            None => Err(Error::new(Other, "LV not found in VG")),
        }
    }

    fn commit(&mut self) -> Result<()> {
        let map = self.clone().into();

        // TODO: atomicity of updating pvs, metad, dm
        for pv in self.pvs.values() {
            if let Some(path) = pv.device.path() {
                let mut pvheader = PvHeader::find_in_dev(&path)
                    .expect("could not find pvheader");

                try!(pvheader.write_metadata(&map));
            }
        }

        // tell lvmetad
        vg_update_lvmetad(&map)
    }

    // Returns e.g. {"pv0": {0: 45, 47: 100, 100: 200} }
    // This means extents 0-44 are used, 45 and 46 are not,
    // 47-99 are used, then 100-199 are used.
    //
    // Adjacent used areas are not merged.
    //
    // PVs with no used areas are not in the outer map at all.
    //
    fn used_areas(&self) -> BTreeMap<String, BTreeMap<u64, u64>> {
        let mut used_map = BTreeMap::new();

        for lv in self.lvs.values() {
            for seg in &lv.segments {
                for &(ref pvname, start) in &seg.stripes {
                    used_map.entry(pvname.to_string())
                        .or_insert(BTreeMap::new())
                        .insert(start as u64, seg.extent_count);
                }
            }
        }

        used_map
    }

    // Returns e.g. {"pv0": {45: 47, 200: 1000} }
    // (assuming pv0 has 1000 extents)
    //
    fn free_areas(&self) -> BTreeMap<String, BTreeMap<u64, u64>> {
        let mut free_map = BTreeMap::new();

        for (pvname, mut area_map) in self.used_areas() {

            // Insert an entry to mark the end of the PV so the fold works
            // correctly
            let pv = self.pvs.get(&pvname)
                .expect("area map name refers to nonexistent PV");
            area_map.insert(pv.pe_count, 0);

            area_map.iter()
                .fold(0, |prev_end, (start, len)| {
                    if prev_end < *start {
                        free_map.entry(pvname.clone())
                            .or_insert(BTreeMap::new())
                            .insert(prev_end, start-prev_end);
                    }
                    start + len
                });
        }

        // Also return completely-unused PVs
        for (pvname, pv) in &self.pvs {
            if !free_map.contains_key(pvname) {
                let mut map = BTreeMap::new();
                map.insert(0, pv.pe_count);
                free_map.insert(pvname.clone(), map);
            }
        }

        free_map
    }
}

impl From<VG> for LvmTextMap {
    fn from(vg: VG) -> Self {
        let mut map = LvmTextMap::new();

        map.insert("id".to_string(), Entry::String(vg.id));
        map.insert("seqno".to_string(),
                   Entry::Number(vg.seqno as i64 + 1));
        map.insert("format".to_string(), Entry::String(vg.format));

        map.insert("max_pv".to_string(), Entry::Number(0));
        map.insert("max_lv".to_string(), Entry::Number(0));

        map.insert("status".to_string(),
                   Entry::List(
                       Box::new(
                           vg.status
                               .into_iter()
                               .map(|x| Entry::String(x))
                               .collect())));

        map.insert("flags".to_string(),
                   Entry::List(
                       Box::new(
                           vg.flags
                               .into_iter()
                               .map(|x| Entry::String(x))
                               .collect())));

        map.insert("extent_size".to_string(),
                   Entry::Number(vg.extent_size as i64));
        map.insert("metadata_copies".to_string(),
                   Entry::Number(vg.metadata_copies as i64));
        map.insert("physical_volumes".to_string(),
                   Entry::TextMap(
                       Box::new(
                           vg.pvs
                               .into_iter()
                               .map(|(k, v)|
                                    (k, Entry::TextMap(Box::new(v.into()))))
                               .collect())));

        map.insert("logical_volumes".to_string(),
                   Entry::TextMap(
                       Box::new(
                           vg.lvs
                               .into_iter()
                               .map(|(k, v)|
                                    (k, Entry::TextMap(Box::new(v.into()))))
                               .collect())));

        let mut outer_map = LvmTextMap::new();

        outer_map.insert(vg.name, Entry::TextMap(Box::new(map)));

        outer_map
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::io::Read;
use command::Command;

type Cell = u8;

pub struct VM {
    pub cells: [Cell; 30_000],
    pub data_pointer: usize,
}

impl VM {
    pub fn new() -> VM {
        VM { cells: [0; 30_000], data_pointer: 0 }
    }

    pub fn output(&self) {
        print!("{}", self.cells[self.data_pointer] as char);
    }

    pub fn input(&mut self) {
        match io::stdin().bytes().next() {
            Some(res) => match res {
                Ok(value) => self.cells[self.data_pointer] = value,
                Err(error) => panic!(error),
            },
            None => {}
        }
        println!("");
    }

    pub fn increment(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer].checked_add(1).unwrap_or(0);
    }

    pub fn decrement(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer]
            .checked_sub(1)
            .unwrap_or(Cell::max_value());
    }

    pub fn right_shift(&mut self) {
        self.data_pointer += 1;
    }

    pub fn left_shift(&mut self) {
        self.data_pointer += 1;
    }

    pub fn apply(&mut self, command: Command) {
        match command {
            Command::Output => self.output(),
            Command::Input => self.input(),
            Command::Increment => self.increment(),
            Command::Decrement => self.decrement(),
            Command::RightShift => self.right_shift(),
            Command::LeftShift => self.left_shift(),
            _ => {},
        }
    }
}
<commit_msg>Fix typo<commit_after>use std::io;
use std::io::Read;
use command::Command;

type Cell = u8;

pub struct VM {
    pub cells: [Cell; 30_000],
    pub data_pointer: usize,
}

impl VM {
    pub fn new() -> VM {
        VM { cells: [0; 30_000], data_pointer: 0 }
    }

    pub fn output(&self) {
        print!("{}", self.cells[self.data_pointer] as char);
    }

    pub fn input(&mut self) {
        match io::stdin().bytes().next() {
            Some(res) => match res {
                Ok(value) => self.cells[self.data_pointer] = value,
                Err(error) => panic!(error),
            },
            None => {}
        }
        println!("");
    }

    pub fn increment(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer].checked_add(1).unwrap_or(0);
    }

    pub fn decrement(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer]
            .checked_sub(1)
            .unwrap_or(Cell::max_value());
    }

    pub fn right_shift(&mut self) {
        self.data_pointer += 1;
    }

    pub fn left_shift(&mut self) {
        self.data_pointer -= 1;
    }

    pub fn apply(&mut self, command: Command) {
        match command {
            Command::Output => self.output(),
            Command::Input => self.input(),
            Command::Increment => self.increment(),
            Command::Decrement => self.decrement(),
            Command::RightShift => self.right_shift(),
            Command::LeftShift => self.left_shift(),
            _ => {},
        }
    }
}
<|endoftext|>


<commit_before>//! Memory layout of matrices

use ndarray::*;

use super::error::*;

pub type LDA = i32;
pub type LEN = i32;
pub type Col = i32;
pub type Row = i32;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum MatrixLayout {
    C((Row, LDA)),
    F((Col, LDA)),
}

impl MatrixLayout {
    pub fn size(&self) -> (Row, Col) {
        match *self {
            MatrixLayout::C((row, lda)) => (row, lda),
            MatrixLayout::F((col, lda)) => (lda, col),
        }
    }

    pub fn resized(&self, row: Row, col: Col) -> MatrixLayout {
        match *self {
            MatrixLayout::C(_) => MatrixLayout::C((row, col)),
            MatrixLayout::F(_) => MatrixLayout::F((col, row)),
        }
    }

    pub fn lda(&self) -> LDA {
        std::cmp::max(
            1,
            match *self {
                MatrixLayout::C((_, lda)) | MatrixLayout::F((_, lda)) => lda,
            },
        )
    }

    pub fn len(&self) -> LEN {
        match *self {
            MatrixLayout::C((row, _)) => row,
            MatrixLayout::F((col, _)) => col,
        }
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn lapacke_layout(&self) -> lapacke::Layout {
        match *self {
            MatrixLayout::C(_) => lapacke::Layout::RowMajor,
            MatrixLayout::F(_) => lapacke::Layout::ColumnMajor,
        }
    }

    pub fn same_order(&self, other: &MatrixLayout) -> bool {
        self.lapacke_layout() == other.lapacke_layout()
    }

    pub fn as_shape(&self) -> Shape<Ix2> {
        match *self {
            MatrixLayout::C((row, col)) => (row as usize, col as usize).into_shape(),
            MatrixLayout::F((col, row)) => (row as usize, col as usize).f().into_shape(),
        }
    }

    pub fn toggle_order(&self) -> Self {
        match *self {
            MatrixLayout::C((row, col)) => MatrixLayout::F((col, row)),
            MatrixLayout::F((col, row)) => MatrixLayout::C((row, col)),
        }
    }
}

pub trait AllocatedArray {
    type Elem;
    fn layout(&self) -> Result<MatrixLayout>;
    fn square_layout(&self) -> Result<MatrixLayout>;
    /// Returns Ok iff the matrix is square (without computing the layout).
    fn ensure_square(&self) -> Result<()>;
    fn as_allocated(&self) -> Result<&[Self::Elem]>;
}

pub trait AllocatedArrayMut: AllocatedArray {
    fn as_allocated_mut(&mut self) -> Result<&mut [Self::Elem]>;
}

impl<A, S> AllocatedArray for ArrayBase<S, Ix2>
where
    S: Data<Elem = A>,
{
    type Elem = A;

    fn layout(&self) -> Result<MatrixLayout> {
        let shape = self.shape();
        let strides = self.strides();
        if shape[0] == strides[1] as usize {
            return Ok(MatrixLayout::F((self.ncols() as i32, self.nrows() as i32)));
        }
        if shape[1] == strides[0] as usize {
            return Ok(MatrixLayout::C((self.nrows() as i32, self.ncols() as i32)));
        }
        Err(LinalgError::InvalidStride {
            s0: strides[0],
            s1: strides[1],
        })
    }

    fn square_layout(&self) -> Result<MatrixLayout> {
        let l = self.layout()?;
        let (n, m) = l.size();
        if n == m {
            Ok(l)
        } else {
            Err(LinalgError::NotSquare { rows: n, cols: m })
        }
    }

    fn ensure_square(&self) -> Result<()> {
        if self.is_square() {
            Ok(())
        } else {
            Err(LinalgError::NotSquare {
                rows: self.nrows() as i32,
                cols: self.ncols() as i32,
            })
        }
    }

    fn as_allocated(&self) -> Result<&[A]> {
        Ok(self
            .as_slice_memory_order()
            .ok_or_else(|| LinalgError::MemoryNotCont)?)
    }
}

impl<A, S> AllocatedArrayMut for ArrayBase<S, Ix2>
where
    S: DataMut<Elem = A>,
{
    fn as_allocated_mut(&mut self) -> Result<&mut [A]> {
        Ok(self
            .as_slice_memory_order_mut()
            .ok_or_else(|| LinalgError::MemoryNotCont)?)
    }
}
<commit_msg>Replace ndarray_linalg::MatrixLayout by lax:: one<commit_after>//! Memory layout of matrices

use super::error::*;
use ndarray::*;

pub use lapack::layout::MatrixLayout;

pub trait AllocatedArray {
    type Elem;
    fn layout(&self) -> Result<MatrixLayout>;
    fn square_layout(&self) -> Result<MatrixLayout>;
    /// Returns Ok iff the matrix is square (without computing the layout).
    fn ensure_square(&self) -> Result<()>;
    fn as_allocated(&self) -> Result<&[Self::Elem]>;
}

pub trait AllocatedArrayMut: AllocatedArray {
    fn as_allocated_mut(&mut self) -> Result<&mut [Self::Elem]>;
}

impl<A, S> AllocatedArray for ArrayBase<S, Ix2>
where
    S: Data<Elem = A>,
{
    type Elem = A;

    fn layout(&self) -> Result<MatrixLayout> {
        let shape = self.shape();
        let strides = self.strides();
        if shape[0] == strides[1] as usize {
            return Ok(MatrixLayout::F((self.ncols() as i32, self.nrows() as i32)));
        }
        if shape[1] == strides[0] as usize {
            return Ok(MatrixLayout::C((self.nrows() as i32, self.ncols() as i32)));
        }
        Err(LinalgError::InvalidStride {
            s0: strides[0],
            s1: strides[1],
        })
    }

    fn square_layout(&self) -> Result<MatrixLayout> {
        let l = self.layout()?;
        let (n, m) = l.size();
        if n == m {
            Ok(l)
        } else {
            Err(LinalgError::NotSquare { rows: n, cols: m })
        }
    }

    fn ensure_square(&self) -> Result<()> {
        if self.is_square() {
            Ok(())
        } else {
            Err(LinalgError::NotSquare {
                rows: self.nrows() as i32,
                cols: self.ncols() as i32,
            })
        }
    }

    fn as_allocated(&self) -> Result<&[A]> {
        Ok(self
            .as_slice_memory_order()
            .ok_or_else(|| LinalgError::MemoryNotCont)?)
    }
}

impl<A, S> AllocatedArrayMut for ArrayBase<S, Ix2>
where
    S: DataMut<Elem = A>,
{
    fn as_allocated_mut(&mut self) -> Result<&mut [A]> {
        Ok(self
            .as_slice_memory_order_mut()
            .ok_or_else(|| LinalgError::MemoryNotCont)?)
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Metered_concurrency
// Rust has a perfectly good Semaphore type already.  It lacks count(), though, so we can't use it
// directly.

#![feature(unsafe_destructor)]

use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::thread::{self, spawn};
use std::sync::mpsc::channel;

pub struct CountingSemaphore {
    count: AtomicUsize, // Remaining resource count
    backoff: u32, // How long to sleep if a resource is being contended
}

pub struct CountingSemaphoreGuard<'a> {
    sem: &'a CountingSemaphore, // A reference to the owning semaphore.
}

impl CountingSemaphore {
    // Create a semaphore with `max` available resources and a linearly increasing backoff of
    // `backoff` (used during spinlock contention).
    pub fn new(max: usize, backoff: u32) -> CountingSemaphore {
        CountingSemaphore { count: AtomicUsize::new(max), backoff: backoff }
    }

    // Acquire a resource, returning a RAII CountingSemaphoreGuard.
    pub fn acquire(&self) -> CountingSemaphoreGuard {
        // Spinlock until remaining resource count is at least 1
        let mut backoff = self.backoff;
        loop {
            // Probably don't need SeqCst here, but it doesn't hurt.
            let count = self.count.load(SeqCst);
            // The check for 0 is necessary to make sure we don't go negative, which is why this
            // must be a compare-and-swap rather than a straight decrement.
            if count == 0 || self.count.compare_and_swap(count, count-1, SeqCst) != count {
                // Linear backoff a la Servo's spinlock contention.
                thread::sleep_ms(backoff);
                backoff = backoff + self.backoff;
            } else {
                // We successfully acquired the resource.
                break
            }
        }
        CountingSemaphoreGuard { sem: self }
    }

    // Return remaining resource count
    pub fn count(&self) -> usize {
        self.count.load(SeqCst)
    }
}

#[unsafe_destructor]
impl<'a> Drop for CountingSemaphoreGuard<'a> {
    // When the guard is dropped, a resource is released back to the pool.
    fn drop(&mut self) {
        self.sem.count.fetch_add(1, SeqCst);
    }
}

fn metered(duration: u32) {
    static MAX_COUNT: usize = 4; // Total available resources
    static NUM_WORKERS: u8 = 10; // Number of workers contending for the resources
    let backoff = 1; // Linear backoff time
    // Create a shared reference to the semaphore
    let sem = Arc::new(CountingSemaphore::new(MAX_COUNT, backoff));
    // Create a channel for notifying the main task that the workers are done
    let (tx, rx) = channel();
    for i in (0..NUM_WORKERS) {
        let sem = sem.clone();
        let tx = tx.clone();
        spawn(move || -> () {
            // Acquire the resource
            let guard = sem.acquire();
            let count = sem.count();
            // Make sure the count is legal
            assert!(count < MAX_COUNT);
            println!("Worker {} after acquire: count = {}", i, count);
            // Sleep for `duration`
            thread::sleep_ms(duration);
            // Release the resource
            drop(guard);
            // Make sure the count is legal
            let count = sem.count();
            assert!(count <= MAX_COUNT);
            println!("Worker {} after release: count = {}", i, count);
            // Notify the main task of completion
            tx.send(()).unwrap();
        });
    }
    drop(tx);
    // Wait for all the subtasks to finish
    for _ in (0..NUM_WORKERS) {
        rx.recv().unwrap();
    }
}

#[test]
fn test_metered_concurrency() {
    // Hold each resource for 1/20 of a second per worker
    metered(1000 / 20);
}

#[cfg(not(test))]
fn main() {
    // Hold each resource for 2 seconds per worker
    metered(2000);
}
<commit_msg>Fix metered_concurrency<commit_after>// Implements http://rosettacode.org/wiki/Metered_concurrency
// Rust has a perfectly good Semaphore type already.  It lacks count(), though, so we can't use it
// directly.

use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::thread::{self, spawn};
use std::sync::mpsc::channel;

pub struct CountingSemaphore {
    count: AtomicUsize, // Remaining resource count
    backoff: u32, // How long to sleep if a resource is being contended
}

pub struct CountingSemaphoreGuard<'a> {
    sem: &'a CountingSemaphore, // A reference to the owning semaphore.
}

impl CountingSemaphore {
    // Create a semaphore with `max` available resources and a linearly increasing backoff of
    // `backoff` (used during spinlock contention).
    pub fn new(max: usize, backoff: u32) -> CountingSemaphore {
        CountingSemaphore { count: AtomicUsize::new(max), backoff: backoff }
    }

    // Acquire a resource, returning a RAII CountingSemaphoreGuard.
    pub fn acquire(&self) -> CountingSemaphoreGuard {
        // Spinlock until remaining resource count is at least 1
        let mut backoff = self.backoff;
        loop {
            // Probably don't need SeqCst here, but it doesn't hurt.
            let count = self.count.load(SeqCst);
            // The check for 0 is necessary to make sure we don't go negative, which is why this
            // must be a compare-and-swap rather than a straight decrement.
            if count == 0 || self.count.compare_and_swap(count, count-1, SeqCst) != count {
                // Linear backoff a la Servo's spinlock contention.
                thread::sleep_ms(backoff);
                backoff = backoff + self.backoff;
            } else {
                // We successfully acquired the resource.
                break
            }
        }
        CountingSemaphoreGuard { sem: self }
    }

    // Return remaining resource count
    pub fn count(&self) -> usize {
        self.count.load(SeqCst)
    }
}

impl<'a> Drop for CountingSemaphoreGuard<'a> {
    // When the guard is dropped, a resource is released back to the pool.
    fn drop(&mut self) {
        self.sem.count.fetch_add(1, SeqCst);
    }
}

fn metered(duration: u32) {
    static MAX_COUNT: usize = 4; // Total available resources
    static NUM_WORKERS: u8 = 10; // Number of workers contending for the resources
    let backoff = 1; // Linear backoff time
    // Create a shared reference to the semaphore
    let sem = Arc::new(CountingSemaphore::new(MAX_COUNT, backoff));
    // Create a channel for notifying the main task that the workers are done
    let (tx, rx) = channel();
    for i in (0..NUM_WORKERS) {
        let sem = sem.clone();
        let tx = tx.clone();
        spawn(move || -> () {
            // Acquire the resource
            let guard = sem.acquire();
            let count = sem.count();
            // Make sure the count is legal
            assert!(count < MAX_COUNT);
            println!("Worker {} after acquire: count = {}", i, count);
            // Sleep for `duration`
            thread::sleep_ms(duration);
            // Release the resource
            drop(guard);
            // Make sure the count is legal
            let count = sem.count();
            assert!(count <= MAX_COUNT);
            println!("Worker {} after release: count = {}", i, count);
            // Notify the main task of completion
            tx.send(()).unwrap();
        });
    }
    drop(tx);
    // Wait for all the subtasks to finish
    for _ in (0..NUM_WORKERS) {
        rx.recv().unwrap();
    }
}

#[test]
fn test_metered_concurrency() {
    // Hold each resource for 1/20 of a second per worker
    metered(1000 / 20);
}

#[cfg(not(test))]
fn main() {
    // Hold each resource for 2 seconds per worker
    metered(2000);
}
<|endoftext|>