<commit_before>use ::game::*;
use super::{print_game_field, player_to_str};

use std::io;
use std::error::Error;

pub fn player_controller(game: &Game) -> Option<Coords> {
    print_game_field(&game.field());
    prompt(&game)
}

fn prompt(game: &Game) -> Option<Coords> {
    loop {
        print!(
            "\nPlayer {}, enter column and row (1..3) separated with whitespace (or print 's' to surrender): ",
            player_to_str(game.current_player()));
        io::Write::flush(&mut io::stdout()).unwrap();

        match read_coords() {
            Ok(Some(coords)) if game.cell_is_empty(coords) => return Some(coords),
            Ok(Some(_)) => println!("Error: you really should not take another's player cell!"),
            Ok(None) => return None,
            Err(error) => println!("Error: {}", error)
        }
    }
}

fn read_coords() -> Result<Option<Coords>, String> {
    fn parse_num(num: &str) -> Result<usize, String> {
        let num: usize = num.parse().map_err(show_error)?;
        match num {
            1 ... 3 => Ok(num),
            _ => Err(parse_error())
        }
    }

    let mut text: String = String::new();
    io::stdin().read_line(&mut text).map_err(show_error).and_then(|_| {
        let text = text.trim_right();
        if text == String::from("s") {
            return Ok(None)
        }

        let coords =
            text.split_whitespace()
                .map(parse_num)
                .collect::<Result<Vec<usize>, _>>()?;

        if coords.len() != 2 {
            return Err(parse_error());
        }

        Ok(Some( (coords[0] - 1, coords[1] - 1) ))
    })
}

fn show_error<T: Error>(err: T) -> String {
    err.description().to_string()
}

fn parse_error() -> String {
    "you have to enter two integers (1..3)".into()
}
<commit_msg>Fix console_player texts<commit_after>use ::game::*;
use super::{print_game_field, player_to_str};

use std::io;
use std::error::Error;

pub fn player_controller(game: &Game) -> Option<Coords> {
    print_game_field(&game.field());
    prompt(&game)
}

fn prompt(game: &Game) -> Option<Coords> {
    loop {
        print!(
            "\nPlayer {}, enter row and column (1..3) separated with whitespace (or print 's' to surrender): ",
            player_to_str(game.current_player()));
        io::Write::flush(&mut io::stdout()).unwrap();

        match read_coords() {
            Ok(Some(coords)) if game.cell_is_empty(coords) => return Some(coords),
            Ok(Some(_)) => println!("Error: you really should not take another player's cell!"),
            Ok(None) => return None,
            Err(error) => println!("Error: {}", error)
        }
    }
}

fn read_coords() -> Result<Option<Coords>, String> {
    fn parse_num(num: &str) -> Result<usize, String> {
        let num: usize = num.parse().map_err(show_error)?;
        match num {
            1 ... 3 => Ok(num),
            _ => Err(parse_error())
        }
    }

    let mut text: String = String::new();
    io::stdin().read_line(&mut text).map_err(show_error).and_then(|_| {
        let text = text.trim_right();
        if text == String::from("s") {
            return Ok(None)
        }

        let coords =
            text.split_whitespace()
                .map(parse_num)
                .collect::<Result<Vec<usize>, _>>()?;

        if coords.len() != 2 {
            return Err(parse_error());
        }

        Ok(Some( (coords[0] - 1, coords[1] - 1) ))
    })
}

fn show_error<T: Error>(err: T) -> String {
    err.description().to_string()
}

fn parse_error() -> String {
    "you have to enter two integers (1..3)".into()
}
<|endoftext|>


<commit_before>//! Functionality for downloading crates and maintaining download counts
//!
//! Crate level functionality is located in `krate::downloads`.

use crate::controllers::prelude::*;

use chrono::{Duration, NaiveDate, Utc};

use crate::models::{Crate, VersionDownload};
use crate::schema::*;
use crate::views::EncodableVersionDownload;

use super::{extract_crate_name, extract_semver};

/// Handles the `GET /crates/:crate_id/:version/download` route.
/// This returns a URL to the location where the crate is stored.
pub fn download(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let version = &req.params()["version"];

    let crate_name = increment_download_counts(req, crate_name, version)?;

    let redirect_url = req
        .app()
        .config
        .uploader
        .crate_location(&crate_name, version);

    if req.wants_json() {
        #[derive(Serialize)]
        struct R {
            url: String,
        }
        Ok(req.json(&R { url: redirect_url }))
    } else {
        Ok(req.redirect(redirect_url))
    }
}

/// Increment the download counts for a given crate version.
///
/// Returns the crate name as stored in the database, or an error if we could
/// not load the version ID from the database.
///
/// This ignores any errors that occur updating the download count. Failure is
/// expected if the application is in read only mode, or for API-only mirrors.
/// Even if failure occurs for unexpected reasons, we would rather have `cargo
/// build` succeed and not count the download than break people's builds.
fn increment_download_counts(
    req: &dyn RequestExt,
    crate_name: &str,
    version: &str,
) -> AppResult<String> {
    use self::versions::dsl::*;

    let conn = req.db_conn()?;
    let (version_id, crate_name) = versions
        .inner_join(crates::table)
        .select((id, crates::name))
        .filter(Crate::with_name(crate_name))
        .filter(num.eq(version))
        .first(&*conn)?;

    // Wrap in a transaction so we don't poison the outer transaction if this
    // fails
    let _ = conn.transaction(|| VersionDownload::create_or_increment(version_id, &conn));
    Ok(crate_name)
}

/// Handles the `GET /crates/:crate_id/:version/downloads` route.
pub fn downloads(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = extract_crate_name(req);
    let semver = extract_semver(req)?;

    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let version = krate.find_version(&conn, semver)?;

    let cutoff_end_date = req
        .query()
        .get("before_date")
        .and_then(|d| NaiveDate::parse_from_str(d, "%F").ok())
        .unwrap_or_else(|| Utc::today().naive_utc());
    let cutoff_start_date = cutoff_end_date - Duration::days(89);

    let downloads = VersionDownload::belonging_to(&version)
        .filter(version_downloads::date.between(cutoff_start_date, cutoff_end_date))
        .order(version_downloads::date)
        .load(&*conn)?
        .into_iter()
        .map(VersionDownload::encodable)
        .collect();

    #[derive(Serialize)]
    struct R {
        version_downloads: Vec<EncodableVersionDownload>,
    }
    Ok(req.json(&R {
        version_downloads: downloads,
    }))
}
<commit_msg>Auto merge of #2988 - jtgeibel:log-uncounted-downloads, r=Turbo87<commit_after>//! Functionality for downloading crates and maintaining download counts
//!
//! Crate level functionality is located in `krate::downloads`.

use crate::controllers::prelude::*;

use chrono::{Duration, NaiveDate, Utc};

use crate::models::{Crate, VersionDownload};
use crate::schema::*;
use crate::views::EncodableVersionDownload;

use super::{extract_crate_name, extract_semver};

/// Handles the `GET /crates/:crate_id/:version/download` route.
/// This returns a URL to the location where the crate is stored.
pub fn download(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let version = &req.params()["version"];

    let (crate_name, was_counted) = increment_download_counts(req, crate_name, version)?;

    let redirect_url = req
        .app()
        .config
        .uploader
        .crate_location(&crate_name, version);

    // Adding log metadata requires &mut access, so we have to defer this step until
    // after the (immutable) query parameters are no longer used.
    if !was_counted {
        req.log_metadata("uncounted_dl", "true");
    }

    if req.wants_json() {
        #[derive(Serialize)]
        struct R {
            url: String,
        }
        Ok(req.json(&R { url: redirect_url }))
    } else {
        Ok(req.redirect(redirect_url))
    }
}

/// Increment the download counts for a given crate version.
///
/// Returns the crate name as stored in the database, or an error if we could
/// not load the version ID from the database.
///
/// This ignores any errors that occur updating the download count. Failure is
/// expected if the application is in read only mode, or for API-only mirrors.
/// Even if failure occurs for unexpected reasons, we would rather have `cargo
/// build` succeed and not count the download than break people's builds.
fn increment_download_counts(
    req: &dyn RequestExt,
    crate_name: &str,
    version: &str,
) -> AppResult<(String, bool)> {
    use self::versions::dsl::*;

    let conn = req.db_conn()?;
    let (version_id, crate_name) = versions
        .inner_join(crates::table)
        .select((id, crates::name))
        .filter(Crate::with_name(crate_name))
        .filter(num.eq(version))
        .first(&*conn)?;

    // Wrap in a transaction so we don't poison the outer transaction if this
    // fails
    let res = conn.transaction(|| VersionDownload::create_or_increment(version_id, &conn));
    Ok((crate_name, res.is_ok()))
}

/// Handles the `GET /crates/:crate_id/:version/downloads` route.
pub fn downloads(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = extract_crate_name(req);
    let semver = extract_semver(req)?;

    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let version = krate.find_version(&conn, semver)?;

    let cutoff_end_date = req
        .query()
        .get("before_date")
        .and_then(|d| NaiveDate::parse_from_str(d, "%F").ok())
        .unwrap_or_else(|| Utc::today().naive_utc());
    let cutoff_start_date = cutoff_end_date - Duration::days(89);

    let downloads = VersionDownload::belonging_to(&version)
        .filter(version_downloads::date.between(cutoff_start_date, cutoff_end_date))
        .order(version_downloads::date)
        .load(&*conn)?
        .into_iter()
        .map(VersionDownload::encodable)
        .collect();

    #[derive(Serialize)]
    struct R {
        version_downloads: Vec<EncodableVersionDownload>,
    }
    Ok(req.json(&R {
        version_downloads: downloads,
    }))
}
<|endoftext|>


<commit_before>//! We maintain invariant that all internal strings use `\n` as line separator.
//! This module does line ending conversion and detection (so that we can
//! convert back to `\r\n` on the way out).

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) enum LineEndings {
    Unix,
    Dos,
}

impl LineEndings {
    /// Replaces `\r\n` with `\n` in-place in `src`.
    pub(crate) fn normalize(src: String) -> (String, LineEndings) {
        if !src.as_bytes().contains(&b'\r') {
            return (src, LineEndings::Unix);
        }

        // We replace `\r\n` with `\n` in-place, which doesn't break utf-8 encoding.
        // While we *can* call `as_mut_vec` and do surgery on the live string
        // directly, let's rather steal the contents of `src`. This makes the code
        // safe even if a panic occurs.

        let mut buf = src.into_bytes();
        let mut gap_len = 0;
        let mut tail = buf.as_mut_slice();
        loop {
            let idx = match find_crlf(&tail[gap_len..]) {
                None => tail.len(),
                Some(idx) => idx + gap_len,
            };
            tail.copy_within(gap_len..idx, 0);
            tail = &mut tail[idx - gap_len..];
            if tail.len() == gap_len {
                break;
            }
            gap_len += 1;
        }

        // Account for removed `\r`.
        // After `set_len`, `buf` is guaranteed to contain utf-8 again.
        let new_len = buf.len() - gap_len;
        let src = unsafe {
            buf.set_len(new_len);
            String::from_utf8_unchecked(buf)
        };
        return (src, LineEndings::Dos);

        fn find_crlf(src: &[u8]) -> Option<usize> {
            src.iter().zip(src.iter().skip(1)).position(|it| it == (&b'\r', &b'\n'))
        }
    }
}
<commit_msg>Simplify find_crlf<commit_after>//! We maintain invariant that all internal strings use `\n` as line separator.
//! This module does line ending conversion and detection (so that we can
//! convert back to `\r\n` on the way out).

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) enum LineEndings {
    Unix,
    Dos,
}

impl LineEndings {
    /// Replaces `\r\n` with `\n` in-place in `src`.
    pub(crate) fn normalize(src: String) -> (String, LineEndings) {
        if !src.as_bytes().contains(&b'\r') {
            return (src, LineEndings::Unix);
        }

        // We replace `\r\n` with `\n` in-place, which doesn't break utf-8 encoding.
        // While we *can* call `as_mut_vec` and do surgery on the live string
        // directly, let's rather steal the contents of `src`. This makes the code
        // safe even if a panic occurs.

        let mut buf = src.into_bytes();
        let mut gap_len = 0;
        let mut tail = buf.as_mut_slice();
        loop {
            let idx = match find_crlf(&tail[gap_len..]) {
                None => tail.len(),
                Some(idx) => idx + gap_len,
            };
            tail.copy_within(gap_len..idx, 0);
            tail = &mut tail[idx - gap_len..];
            if tail.len() == gap_len {
                break;
            }
            gap_len += 1;
        }

        // Account for removed `\r`.
        // After `set_len`, `buf` is guaranteed to contain utf-8 again.
        let new_len = buf.len() - gap_len;
        let src = unsafe {
            buf.set_len(new_len);
            String::from_utf8_unchecked(buf)
        };
        return (src, LineEndings::Dos);

        fn find_crlf(src: &[u8]) -> Option<usize> {
            src.windows(2).position(|it| it == b"\r\n")
        }
    }
}
<|endoftext|>


<commit_before>use std::str;
use std::io::Decorator;
use std::io::mem::{MemWriter, MemReader};
use std::mem;
use std::vec;

use super::types::Oid;

pub static PROTOCOL_VERSION: i32 = 0x0003_0000;
pub static CANCEL_CODE: i32 = 80877102;
pub static SSL_CODE: i32 = 80877103;

#[deriving(ToStr)]
pub enum BackendMessage {
    AuthenticationOk,
    AuthenticationKerberosV5,
    AuthenticationCleartextPassword,
    AuthenticationMD5Password {
        salt: ~[u8]
    },
    AuthenticationSCMCredential,
    AuthenticationGSS,
    AuthenticationSSPI,
    BackendKeyData {
        process_id: i32,
        secret_key: i32
    },
    BindComplete,
    CloseComplete,
    CommandComplete {
        tag: ~str
    },
    DataRow {
        row: ~[Option<~[u8]>]
    },
    EmptyQueryResponse,
    ErrorResponse {
        fields: ~[(u8, ~str)]
    },
    NoData,
    NoticeResponse {
        fields: ~[(u8, ~str)]
    },
    NotificationResponse {
        pid: i32,
        channel: ~str,
        payload: ~str
    },
    ParameterDescription {
        types: ~[Oid]
    },
    ParameterStatus {
        parameter: ~str,
        value: ~str
    },
    ParseComplete,
    PortalSuspended,
    ReadyForQuery {
        state: u8
    },
    RowDescription {
        descriptions: ~[RowDescriptionEntry]
    }
}

#[deriving(ToStr)]
pub struct RowDescriptionEntry {
    name: ~str,
    table_oid: Oid,
    column_id: i16,
    type_oid: Oid,
    type_size: i16,
    type_modifier: i32,
    format: i16
}

pub enum FrontendMessage<'a> {
    Bind {
        portal: &'a str,
        statement: &'a str,
        formats: &'a [i16],
        values: &'a [Option<~[u8]>],
        result_formats: &'a [i16]
    },
    CancelRequest {
        code: i32,
        process_id: i32,
        secret_key: i32,
    },
    Close {
        variant: u8,
        name: &'a str
    },
    Describe {
        variant: u8,
        name: &'a str
    },
    Execute {
        portal: &'a str,
        max_rows: i32
    },
    Parse {
        name: &'a str,
        query: &'a str,
        param_types: &'a [i32]
    },
    PasswordMessage {
        password: &'a str
    },
    Query {
        query: &'a str
    },
    StartupMessage {
        version: i32,
        parameters: &'a [(~str, ~str)]
    },
    SslRequest {
        code: i32
    },
    Sync,
    Terminate
}

trait WriteCStr {
    fn write_cstr(&mut self, s: &str);
}

impl<W: Writer> WriteCStr for W {
    fn write_cstr(&mut self, s: &str) {
        self.write(s.as_bytes());
        self.write_u8(0);
    }
}

pub trait WriteMessage {
    fn write_message(&mut self, &FrontendMessage);
}

impl<W: Writer> WriteMessage for W {
    fn write_message(&mut self, message: &FrontendMessage) {
        debug!("Writing message {:?}", message);
        let mut buf = MemWriter::new();
        let mut ident = None;

        match *message {
            Bind { portal, statement, formats, values, result_formats } => {
                ident = Some('B');
                buf.write_cstr(portal);
                buf.write_cstr(statement);

                buf.write_be_i16(formats.len() as i16);
                for format in formats.iter() {
                    buf.write_be_i16(*format);
                }

                buf.write_be_i16(values.len() as i16);
                for value in values.iter() {
                    match *value {
                        None => {
                            buf.write_be_i32(-1);
                        }
                        Some(ref value) => {
                            buf.write_be_i32(value.len() as i32);
                            buf.write(*value);
                        }
                    }
                }

                buf.write_be_i16(result_formats.len() as i16);
                for format in result_formats.iter() {
                    buf.write_be_i16(*format);
                }
            }
            CancelRequest { code, process_id, secret_key } => {
                buf.write_be_i32(code);
                buf.write_be_i32(process_id);
                buf.write_be_i32(secret_key);
            }
            Close { variant, name } => {
                ident = Some('C');
                buf.write_u8(variant);
                buf.write_cstr(name);
            }
            Describe { variant, name } => {
                ident = Some('D');
                buf.write_u8(variant);
                buf.write_cstr(name);
            }
            Execute { portal, max_rows } => {
                ident = Some('E');
                buf.write_cstr(portal);
                buf.write_be_i32(max_rows);
            }
            Parse { name, query, param_types } => {
                ident = Some('P');
                buf.write_cstr(name);
                buf.write_cstr(query);
                buf.write_be_i16(param_types.len() as i16);
                for ty in param_types.iter() {
                    buf.write_be_i32(*ty);
                }
            }
            PasswordMessage { password } => {
                ident = Some('p');
                buf.write_cstr(password);
            }
            Query { query } => {
                ident = Some('Q');
                buf.write_cstr(query);
            }
            StartupMessage { version, parameters } => {
                buf.write_be_i32(version);
                for &(ref k, ref v) in parameters.iter() {
                    buf.write_cstr(k.as_slice());
                    buf.write_cstr(v.as_slice());
                }
                buf.write_u8(0);
            }
            SslRequest { code } => buf.write_be_i32(code),
            Sync => {
                ident = Some('S');
            }
            Terminate => {
                ident = Some('X');
            }
        }

        match ident {
            Some(ident) => self.write_u8(ident as u8),
            None => ()
        }

        // add size of length value
        self.write_be_i32((buf.inner_ref().len() + mem::size_of::<i32>())
                           as i32);
        self.write(buf.inner());
    }
}

trait ReadString {
    fn read_string(&mut self) -> ~str;
}

impl<R: Buffer> ReadString for R {
    fn read_string(&mut self) -> ~str {
        let mut buf = self.read_until(0).unwrap();
        buf.pop();
        str::from_utf8_owned(buf)
    }
}

pub trait ReadMessage {
    fn read_message(&mut self) -> BackendMessage;
}

impl<R: Reader> ReadMessage for R {
    fn read_message(&mut self) -> BackendMessage {
        debug!("Reading message");

        let ident = self.read_u8();
        // subtract size of length value
        let len = self.read_be_i32() as uint - mem::size_of::<i32>();
        let mut buf = MemReader::new(self.read_bytes(len));

        let ret = match ident as char {
            '1' => ParseComplete,
            '2' => BindComplete,
            '3' => CloseComplete,
            'A' => NotificationResponse {
                pid: buf.read_be_i32(),
                channel: buf.read_string(),
                payload: buf.read_string()
            },
            'C' => CommandComplete { tag: buf.read_string() },
            'D' => read_data_row(&mut buf),
            'E' => ErrorResponse { fields: read_fields(&mut buf) },
            'I' => EmptyQueryResponse,
            'K' => BackendKeyData {
                process_id: buf.read_be_i32(),
                secret_key: buf.read_be_i32()
            },
            'n' => NoData,
            'N' => NoticeResponse { fields: read_fields(&mut buf) },
            'R' => read_auth_message(&mut buf),
            's' => PortalSuspended,
            'S' => ParameterStatus {
                parameter: buf.read_string(),
                value: buf.read_string()
            },
            't' => read_parameter_description(&mut buf),
            'T' => read_row_description(&mut buf),
            'Z' => ReadyForQuery { state: buf.read_u8() },
            ident => fail!("Unknown message identifier `{}`", ident)
        };
        assert!(buf.eof());
        debug!("Read message {:?}", ret);
        ret
    }
}

fn read_fields(buf: &mut MemReader) -> ~[(u8, ~str)] {
    let mut fields = ~[];
    loop {
        let ty = buf.read_u8();
        if ty == 0 {
            break;
        }

        fields.push((ty, buf.read_string()));
    }

    fields
}

fn read_data_row(buf: &mut MemReader) -> BackendMessage {
    let len = buf.read_be_i16() as uint;
    let mut values = vec::with_capacity(len);

    for _ in range(0, len) {
        let val = match buf.read_be_i32() {
            -1 => None,
            len => Some(buf.read_bytes(len as uint))
        };
        values.push(val);
    }

    DataRow { row: values }
}

fn read_auth_message(buf: &mut MemReader) -> BackendMessage {
    match buf.read_be_i32() {
        0 => AuthenticationOk,
        2 => AuthenticationKerberosV5,
        3 => AuthenticationCleartextPassword,
        5 => AuthenticationMD5Password { salt: buf.read_bytes(4) },
        6 => AuthenticationSCMCredential,
        7 => AuthenticationGSS,
        9 => AuthenticationSSPI,
        val => fail!("Invalid authentication identifier `{}`", val)
    }
}

fn read_parameter_description(buf: &mut MemReader) -> BackendMessage {
    let len = buf.read_be_i16() as uint;
    let mut types = vec::with_capacity(len);

    for _ in range(0, len) {
        types.push(buf.read_be_i32());
    }

    ParameterDescription { types: types }
}

fn read_row_description(buf: &mut MemReader) -> BackendMessage {
    let len = buf.read_be_i16() as uint;
    let mut types = vec::with_capacity(len);

    for _ in range(0, len) {
        types.push(RowDescriptionEntry {
            name: buf.read_string(),
            table_oid: buf.read_be_i32(),
            column_id: buf.read_be_i16(),
            type_oid: buf.read_be_i32(),
            type_size: buf.read_be_i16(),
            type_modifier: buf.read_be_i32(),
            format: buf.read_be_i16()
        });
    }

    RowDescription { descriptions: types }
}
<commit_msg>More internal extension method renaming<commit_after>use std::str;
use std::io::Decorator;
use std::io::mem::{MemWriter, MemReader};
use std::mem;
use std::vec;

use super::types::Oid;

pub static PROTOCOL_VERSION: i32 = 0x0003_0000;
pub static CANCEL_CODE: i32 = 80877102;
pub static SSL_CODE: i32 = 80877103;

#[deriving(ToStr)]
pub enum BackendMessage {
    AuthenticationOk,
    AuthenticationKerberosV5,
    AuthenticationCleartextPassword,
    AuthenticationMD5Password {
        salt: ~[u8]
    },
    AuthenticationSCMCredential,
    AuthenticationGSS,
    AuthenticationSSPI,
    BackendKeyData {
        process_id: i32,
        secret_key: i32
    },
    BindComplete,
    CloseComplete,
    CommandComplete {
        tag: ~str
    },
    DataRow {
        row: ~[Option<~[u8]>]
    },
    EmptyQueryResponse,
    ErrorResponse {
        fields: ~[(u8, ~str)]
    },
    NoData,
    NoticeResponse {
        fields: ~[(u8, ~str)]
    },
    NotificationResponse {
        pid: i32,
        channel: ~str,
        payload: ~str
    },
    ParameterDescription {
        types: ~[Oid]
    },
    ParameterStatus {
        parameter: ~str,
        value: ~str
    },
    ParseComplete,
    PortalSuspended,
    ReadyForQuery {
        state: u8
    },
    RowDescription {
        descriptions: ~[RowDescriptionEntry]
    }
}

#[deriving(ToStr)]
pub struct RowDescriptionEntry {
    name: ~str,
    table_oid: Oid,
    column_id: i16,
    type_oid: Oid,
    type_size: i16,
    type_modifier: i32,
    format: i16
}

pub enum FrontendMessage<'a> {
    Bind {
        portal: &'a str,
        statement: &'a str,
        formats: &'a [i16],
        values: &'a [Option<~[u8]>],
        result_formats: &'a [i16]
    },
    CancelRequest {
        code: i32,
        process_id: i32,
        secret_key: i32,
    },
    Close {
        variant: u8,
        name: &'a str
    },
    Describe {
        variant: u8,
        name: &'a str
    },
    Execute {
        portal: &'a str,
        max_rows: i32
    },
    Parse {
        name: &'a str,
        query: &'a str,
        param_types: &'a [i32]
    },
    PasswordMessage {
        password: &'a str
    },
    Query {
        query: &'a str
    },
    StartupMessage {
        version: i32,
        parameters: &'a [(~str, ~str)]
    },
    SslRequest {
        code: i32
    },
    Sync,
    Terminate
}

trait WriteCStr {
    fn write_cstr(&mut self, s: &str);
}

impl<W: Writer> WriteCStr for W {
    fn write_cstr(&mut self, s: &str) {
        self.write(s.as_bytes());
        self.write_u8(0);
    }
}

pub trait WriteMessage {
    fn write_message(&mut self, &FrontendMessage);
}

impl<W: Writer> WriteMessage for W {
    fn write_message(&mut self, message: &FrontendMessage) {
        debug!("Writing message {:?}", message);
        let mut buf = MemWriter::new();
        let mut ident = None;

        match *message {
            Bind { portal, statement, formats, values, result_formats } => {
                ident = Some('B');
                buf.write_cstr(portal);
                buf.write_cstr(statement);

                buf.write_be_i16(formats.len() as i16);
                for format in formats.iter() {
                    buf.write_be_i16(*format);
                }

                buf.write_be_i16(values.len() as i16);
                for value in values.iter() {
                    match *value {
                        None => {
                            buf.write_be_i32(-1);
                        }
                        Some(ref value) => {
                            buf.write_be_i32(value.len() as i32);
                            buf.write(*value);
                        }
                    }
                }

                buf.write_be_i16(result_formats.len() as i16);
                for format in result_formats.iter() {
                    buf.write_be_i16(*format);
                }
            }
            CancelRequest { code, process_id, secret_key } => {
                buf.write_be_i32(code);
                buf.write_be_i32(process_id);
                buf.write_be_i32(secret_key);
            }
            Close { variant, name } => {
                ident = Some('C');
                buf.write_u8(variant);
                buf.write_cstr(name);
            }
            Describe { variant, name } => {
                ident = Some('D');
                buf.write_u8(variant);
                buf.write_cstr(name);
            }
            Execute { portal, max_rows } => {
                ident = Some('E');
                buf.write_cstr(portal);
                buf.write_be_i32(max_rows);
            }
            Parse { name, query, param_types } => {
                ident = Some('P');
                buf.write_cstr(name);
                buf.write_cstr(query);
                buf.write_be_i16(param_types.len() as i16);
                for ty in param_types.iter() {
                    buf.write_be_i32(*ty);
                }
            }
            PasswordMessage { password } => {
                ident = Some('p');
                buf.write_cstr(password);
            }
            Query { query } => {
                ident = Some('Q');
                buf.write_cstr(query);
            }
            StartupMessage { version, parameters } => {
                buf.write_be_i32(version);
                for &(ref k, ref v) in parameters.iter() {
                    buf.write_cstr(k.as_slice());
                    buf.write_cstr(v.as_slice());
                }
                buf.write_u8(0);
            }
            SslRequest { code } => buf.write_be_i32(code),
            Sync => {
                ident = Some('S');
            }
            Terminate => {
                ident = Some('X');
            }
        }

        match ident {
            Some(ident) => self.write_u8(ident as u8),
            None => ()
        }

        // add size of length value
        self.write_be_i32((buf.inner_ref().len() + mem::size_of::<i32>())
                           as i32);
        self.write(buf.inner());
    }
}

trait ReadCStr {
    fn read_cstr(&mut self) -> ~str;
}

impl<R: Buffer> ReadCStr for R {
    fn read_cstr(&mut self) -> ~str {
        let mut buf = self.read_until(0).unwrap();
        buf.pop();
        str::from_utf8_owned(buf)
    }
}

pub trait ReadMessage {
    fn read_message(&mut self) -> BackendMessage;
}

impl<R: Reader> ReadMessage for R {
    fn read_message(&mut self) -> BackendMessage {
        debug!("Reading message");

        let ident = self.read_u8();
        // subtract size of length value
        let len = self.read_be_i32() as uint - mem::size_of::<i32>();
        let mut buf = MemReader::new(self.read_bytes(len));

        let ret = match ident as char {
            '1' => ParseComplete,
            '2' => BindComplete,
            '3' => CloseComplete,
            'A' => NotificationResponse {
                pid: buf.read_be_i32(),
                channel: buf.read_cstr(),
                payload: buf.read_cstr()
            },
            'C' => CommandComplete { tag: buf.read_cstr() },
            'D' => read_data_row(&mut buf),
            'E' => ErrorResponse { fields: read_fields(&mut buf) },
            'I' => EmptyQueryResponse,
            'K' => BackendKeyData {
                process_id: buf.read_be_i32(),
                secret_key: buf.read_be_i32()
            },
            'n' => NoData,
            'N' => NoticeResponse { fields: read_fields(&mut buf) },
            'R' => read_auth_message(&mut buf),
            's' => PortalSuspended,
            'S' => ParameterStatus {
                parameter: buf.read_cstr(),
                value: buf.read_cstr()
            },
            't' => read_parameter_description(&mut buf),
            'T' => read_row_description(&mut buf),
            'Z' => ReadyForQuery { state: buf.read_u8() },
            ident => fail!("Unknown message identifier `{}`", ident)
        };
        assert!(buf.eof());
        debug!("Read message {:?}", ret);
        ret
    }
}

fn read_fields(buf: &mut MemReader) -> ~[(u8, ~str)] {
    let mut fields = ~[];
    loop {
        let ty = buf.read_u8();
        if ty == 0 {
            break;
        }

        fields.push((ty, buf.read_cstr()));
    }

    fields
}

fn read_data_row(buf: &mut MemReader) -> BackendMessage {
    let len = buf.read_be_i16() as uint;
    let mut values = vec::with_capacity(len);

    for _ in range(0, len) {
        let val = match buf.read_be_i32() {
            -1 => None,
            len => Some(buf.read_bytes(len as uint))
        };
        values.push(val);
    }

    DataRow { row: values }
}

fn read_auth_message(buf: &mut MemReader) -> BackendMessage {
    match buf.read_be_i32() {
        0 => AuthenticationOk,
        2 => AuthenticationKerberosV5,
        3 => AuthenticationCleartextPassword,
        5 => AuthenticationMD5Password { salt: buf.read_bytes(4) },
        6 => AuthenticationSCMCredential,
        7 => AuthenticationGSS,
        9 => AuthenticationSSPI,
        val => fail!("Invalid authentication identifier `{}`", val)
    }
}

fn read_parameter_description(buf: &mut MemReader) -> BackendMessage {
    let len = buf.read_be_i16() as uint;
    let mut types = vec::with_capacity(len);

    for _ in range(0, len) {
        types.push(buf.read_be_i32());
    }

    ParameterDescription { types: types }
}

fn read_row_description(buf: &mut MemReader) -> BackendMessage {
    let len = buf.read_be_i16() as uint;
    let mut types = vec::with_capacity(len);

    for _ in range(0, len) {
        types.push(RowDescriptionEntry {
            name: buf.read_cstr(),
            table_oid: buf.read_be_i32(),
            column_id: buf.read_be_i16(),
            type_oid: buf.read_be_i32(),
            type_size: buf.read_be_i16(),
            type_modifier: buf.read_be_i32(),
            format: buf.read_be_i16()
        });
    }

    RowDescription { descriptions: types }
}
<|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 https://mozilla.org/MPL/2.0/. */

use gfx_traits::Epoch;
use ipc_channel::ipc;
use layout::display_list::items::{BaseDisplayItem, CommonDisplayItem, DisplayItem, DisplayList};
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
use msg::constellation_msg::TEST_PIPELINE_ID;
use profile_traits::time::{ProfilerChan, TimerMetadata};
use servo_url::ServoUrl;
use webrender_api::{AlphaType, ColorF, ImageDisplayItem, ImageKey, ImageRendering, LayoutSize};

struct DummyProfilerMetadataFactory {}
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
    fn new_metadata(&self) -> Option<TimerMetadata> {
        None
    }
}

#[test]
fn test_paint_metrics_construction() {
    let (sender, _) = ipc::channel().unwrap();
    let profiler_chan = ProfilerChan(sender);
    let (layout_sender, _) = ipc::channel().unwrap();
    let (script_sender, _) = ipc::channel().unwrap();
    let paint_time_metrics = PaintTimeMetrics::new(
        TEST_PIPELINE_ID,
        profiler_chan,
        layout_sender,
        script_sender,
        ServoUrl::parse("about:blank").unwrap(),
    );
    assert_eq!(
        (&paint_time_metrics).get_navigation_start(),
        None,
        "navigation start is None"
    );
    assert_eq!(
        paint_time_metrics.get_first_paint(),
        None,
        "first paint is None"
    );
    assert_eq!(
        paint_time_metrics.get_first_contentful_paint(),
        None,
        "first contentful paint is None"
    );
}

fn test_common(display_list: &DisplayList, epoch: Epoch) -> PaintTimeMetrics {
    let (sender, _) = ipc::channel().unwrap();
    let profiler_chan = ProfilerChan(sender);
    let (layout_sender, _) = ipc::channel().unwrap();
    let (script_sender, _) = ipc::channel().unwrap();
    let mut paint_time_metrics = PaintTimeMetrics::new(
        TEST_PIPELINE_ID,
        profiler_chan,
        layout_sender,
        script_sender,
        ServoUrl::parse("about:blank").unwrap(),
    );
    let dummy_profiler_metadata_factory = DummyProfilerMetadataFactory {};

    paint_time_metrics.maybe_observe_paint_time(
        &dummy_profiler_metadata_factory,
        epoch,
        &*display_list,
    );

    // Should not set any metric until navigation start is set.
    paint_time_metrics.maybe_set_metric(epoch, 0);
    assert_eq!(
        paint_time_metrics.get_first_paint(),
        None,
        "first paint is None"
    );
    assert_eq!(
        paint_time_metrics.get_first_contentful_paint(),
        None,
        "first contentful paint is None"
    );

    let navigation_start = time::precise_time_ns();
    paint_time_metrics.set_navigation_start(navigation_start);
    assert_eq!(
        (&paint_time_metrics).get_navigation_start().unwrap(),
        navigation_start,
        "navigation start is set"
    );

    paint_time_metrics
}

#[test]
fn test_first_paint_setter() {
    let empty_display_list = DisplayList {
        list: Vec::new(),
        clip_scroll_nodes: Vec::new(),
    };
    let epoch = Epoch(0);
    let paint_time_metrics = test_common(&empty_display_list, epoch);
    let now = time::precise_time_ns();
    paint_time_metrics.maybe_set_metric(epoch, now);
    assert!(
        paint_time_metrics.get_first_paint().is_some(),
        "first paint is set"
    );
    assert_eq!(
        paint_time_metrics.get_first_contentful_paint(),
        None,
        "first contentful paint is None"
    );
}

#[test]
fn test_first_contentful_paint_setter() {
    let image = DisplayItem::Image(CommonDisplayItem::new(
        BaseDisplayItem::empty(),
        ImageDisplayItem {
            image_key: ImageKey::DUMMY,
            stretch_size: LayoutSize::zero(),
            tile_spacing: LayoutSize::zero(),
            image_rendering: ImageRendering::Auto,
            alpha_type: AlphaType::PremultipliedAlpha,
            color: ColorF::WHITE,
        },
    ));
    let display_list = DisplayList {
        list: vec![image],
        clip_scroll_nodes: Vec::new(),
    };
    let epoch = Epoch(0);
    let paint_time_metrics = test_common(&display_list, epoch);
    let now = time::precise_time_ns();
    paint_time_metrics.maybe_set_metric(epoch, now);
    assert!(
        paint_time_metrics.get_first_contentful_paint().is_some(),
        "first contentful paint is set"
    );
    assert!(
        paint_time_metrics.get_first_paint().is_some(),
        "first paint is set"
    );
}
<commit_msg>Fix unit test.<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 https://mozilla.org/MPL/2.0/. */

use gfx_traits::Epoch;
use ipc_channel::ipc;
use layout::display_list::items::{BaseDisplayItem, CommonDisplayItem, DisplayItem, DisplayList};
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
use msg::constellation_msg::TEST_PIPELINE_ID;
use profile_traits::time::{ProfilerChan, TimerMetadata};
use servo_url::ServoUrl;
use webrender_api::units::{LayoutRect, LayoutSize};
use webrender_api::{AlphaType, ColorF, ImageDisplayItem, ImageKey, ImageRendering};

struct DummyProfilerMetadataFactory {}
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
    fn new_metadata(&self) -> Option<TimerMetadata> {
        None
    }
}

#[test]
fn test_paint_metrics_construction() {
    let (sender, _) = ipc::channel().unwrap();
    let profiler_chan = ProfilerChan(sender);
    let (layout_sender, _) = ipc::channel().unwrap();
    let (script_sender, _) = ipc::channel().unwrap();
    let paint_time_metrics = PaintTimeMetrics::new(
        TEST_PIPELINE_ID,
        profiler_chan,
        layout_sender,
        script_sender,
        ServoUrl::parse("about:blank").unwrap(),
    );
    assert_eq!(
        (&paint_time_metrics).get_navigation_start(),
        None,
        "navigation start is None"
    );
    assert_eq!(
        paint_time_metrics.get_first_paint(),
        None,
        "first paint is None"
    );
    assert_eq!(
        paint_time_metrics.get_first_contentful_paint(),
        None,
        "first contentful paint is None"
    );
}

fn test_common(display_list: &DisplayList, epoch: Epoch) -> PaintTimeMetrics {
    let (sender, _) = ipc::channel().unwrap();
    let profiler_chan = ProfilerChan(sender);
    let (layout_sender, _) = ipc::channel().unwrap();
    let (script_sender, _) = ipc::channel().unwrap();
    let mut paint_time_metrics = PaintTimeMetrics::new(
        TEST_PIPELINE_ID,
        profiler_chan,
        layout_sender,
        script_sender,
        ServoUrl::parse("about:blank").unwrap(),
    );
    let dummy_profiler_metadata_factory = DummyProfilerMetadataFactory {};

    paint_time_metrics.maybe_observe_paint_time(
        &dummy_profiler_metadata_factory,
        epoch,
        &*display_list,
    );

    // Should not set any metric until navigation start is set.
    paint_time_metrics.maybe_set_metric(epoch, 0);
    assert_eq!(
        paint_time_metrics.get_first_paint(),
        None,
        "first paint is None"
    );
    assert_eq!(
        paint_time_metrics.get_first_contentful_paint(),
        None,
        "first contentful paint is None"
    );

    let navigation_start = time::precise_time_ns();
    paint_time_metrics.set_navigation_start(navigation_start);
    assert_eq!(
        (&paint_time_metrics).get_navigation_start().unwrap(),
        navigation_start,
        "navigation start is set"
    );

    paint_time_metrics
}

#[test]
fn test_first_paint_setter() {
    let empty_display_list = DisplayList {
        list: Vec::new(),
        clip_scroll_nodes: Vec::new(),
    };
    let epoch = Epoch(0);
    let paint_time_metrics = test_common(&empty_display_list, epoch);
    let now = time::precise_time_ns();
    paint_time_metrics.maybe_set_metric(epoch, now);
    assert!(
        paint_time_metrics.get_first_paint().is_some(),
        "first paint is set"
    );
    assert_eq!(
        paint_time_metrics.get_first_contentful_paint(),
        None,
        "first contentful paint is None"
    );
}

#[test]
fn test_first_contentful_paint_setter() {
    let image = DisplayItem::Image(CommonDisplayItem::new(
        BaseDisplayItem::empty(),
        ImageDisplayItem {
            bounds: LayoutRect::zero(),
            common: layout::display_list::items::empty_common_item_properties(),
            image_key: ImageKey::DUMMY,
            stretch_size: LayoutSize::zero(),
            tile_spacing: LayoutSize::zero(),
            image_rendering: ImageRendering::Auto,
            alpha_type: AlphaType::PremultipliedAlpha,
            color: ColorF::WHITE,
        },
    ));
    let display_list = DisplayList {
        list: vec![image],
        clip_scroll_nodes: Vec::new(),
    };
    let epoch = Epoch(0);
    let paint_time_metrics = test_common(&display_list, epoch);
    let now = time::precise_time_ns();
    paint_time_metrics.maybe_set_metric(epoch, now);
    assert!(
        paint_time_metrics.get_first_contentful_paint().is_some(),
        "first contentful paint is set"
    );
    assert!(
        paint_time_metrics.get_first_paint().is_some(),
        "first paint is set"
    );
}
<|endoftext|>


<commit_before>extern crate num;
extern crate rand;
extern crate time;
extern crate bignum = "bignum#0.1.1-pre";

use bignum::{BigUint, ToBigUint, RandBigInt};
use num::{div_mod_floor, Integer};
use std::num::{Zero, One, pow, Float, FromPrimitive};
use rand::{task_rng, Rng};
use rand::distributions::range::SampleRange;
use std::vec::Vec;
use std::iter;
use std::iter::{FromIterator};
use std::clone::Clone;
use std::ops::{Shr, BitAnd};
use std::bool;

static pow_offsets : &'static[uint] = &[0u, 4u, 6u, 10u, 12u, 16u];

#[inline]
fn big<T: ToBigUint>(i : T) -> BigUint {
    i.to_biguint().unwrap()
}

// Source: https://gist.github.com/jsanders/8739134#file-generate_big_primes-rs-L35
fn mod_exp<T: Integer + Clone + Shr<uint,T> + BitAnd<T,T>>
    (base: &T, exponent: &T, modulus: &T) -> T {

    let (zero, one): (T, T) = (Zero::zero(), One::one());
    let mut result = one.clone();
    let mut baseAcc = base.clone();
    let mut exponentAcc = exponent.clone();

    while exponentAcc > zero {
        // Accumulate current base if current exponent bit is 1
        if (exponentAcc & one) == one {
            result = result.mul(&baseAcc);
            result = result.rem(modulus);
        }
        // Get next base by squaring
        baseAcc = baseAcc * baseAcc;
        baseAcc = baseAcc % *modulus;

        // Get next bit of exponent
        exponentAcc = exponentAcc.shr(&1);
    }
    result

}

// Rabin-Miller primality test, probabilistic
fn try_composite(a : &BigUint, d : &BigUint, n : &BigUint, s : &BigUint) -> bool {

    let one : BigUint = One::one();
    if mod_exp(a, d, n) == one {
        return false
    }
    let mut i = 0u;
    loop {
        if big(i) == *s {
            break
        }
        if mod_exp(a, &(pow(one+one, i) * *d), n) == *n-one {
            return false
        }
        i += 1;
    }
    true

}
fn rm_is_prime(n : &BigUint) -> bool {

    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    assert!(n >= &two);

    let mut s = zero.clone();
    let mut d = *n-one;
    let num_trials = 5;
    if n == &two {
        return true
    } else if n == &one || n.is_even() {
        return false
    } else {
        loop {
            let (quotient, remainder) = div_mod_floor(d.clone(), two.clone());
            if remainder == one { break }
            s = s + one;
            d = quotient;
        }
    }

    let mut rng = task_rng();
    for _ in range(0, num_trials) {
        let a = rng.gen_biguint_range(&two, n);
        if try_composite(&a, &d, n, &s) {
            return false
        }
    }
    true

}

fn fermat_is_prime(n : &BigUint) -> bool {
    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    if n == &two {
        true
    } else if n.is_even() {
        false
    } else if mod_exp(&two, &(n-one), n) == one {
        true
    } else {
        false
    }
}

fn is_valid_pow(prime : &BigUint) -> Option<BigUint> {
    for offset in [big(0u), big(4u), big(6u), big(10u), big(12u), big(16u)].iter() {
        if !fermat_is_prime(&(*prime + *offset)) {
            return None;
        }
    }
    Some(prime.clone())
}

// Simple sieve
fn simple_sieve(primes : &mut Vec<bool>, max_sieve : uint, verbose : bool) -> Vec<uint> {
    #[inline]
    fn int_sqrt(n: uint) -> uint { (n as f64).sqrt() as uint }

    if primes.len() <= max_sieve {
        *primes = Vec::from_elem(max_sieve+1, true);
        *primes.get_mut(0) = false;
        *primes.get_mut(1) = false;
        for prime in range(2, int_sqrt(max_sieve) + 1) {
            if *primes.get(prime) {
                for multiple in iter::range_step(prime * prime, max_sieve + 1, prime) {
                    *primes.get_mut(multiple) = false
                }
                if verbose { println!("Sieved {}", prime) }
            }
        }
    }
    if verbose { println!("Finished sieving") }
    range(2, max_sieve+1).filter(|&n| *primes.get(n)).collect()
}

fn gen_prime(base_val : &BigUint, max_val : &BigUint, max_sieve : uint, verbose : bool) -> uint {

    fn candidate_killed_by(candidate : &BigUint, prime : &BigUint) -> bool {
        let zero : BigUint = Zero::zero();
        for &offset in pow_offsets.iter() {
            let o : BigUint = FromPrimitive::from_uint(offset).unwrap();
            if (*candidate + o) % *prime == zero {
                return true;
            }
        }
        false
    }

    fn add_next_prime (max_val : &BigUint, offsets : Vec<BigUint>, prime : BigUint, primorial : BigUint) -> Vec<BigUint> {
        let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
        let mut base : BigUint = Zero::zero();
        let mut new_offsets : Vec<BigUint> = Vec::new();
        let mut counter = zero.clone();
        while counter < prime {
            if base > *max_val {
                break
            }
            for o in offsets.iter() {
                let val = base + *o;
                if val > *max_val {
                    break
                }
                if !candidate_killed_by(&val, &prime) {
                    new_offsets.push(val);
                }
            }
            base = base + primorial;
            counter = counter + one;
        }
        return new_offsets
    }

    let primorial_start : uint = 7u;
    let mut primorial : uint = 210u;  // 2*3*5*7
    let mut offsets : Vec<BigUint> = Vec::from_slice([big(97u)]);

    let mut primes : Vec<bool> = Vec::new();

    for &i in simple_sieve(&mut primes, max_sieve, verbose).iter() {
        if i <= primorial_start {
            continue
        }
        offsets = add_next_prime(max_val, offsets, big(i), big(primorial));
        primorial = primorial * i;
    }
    offsets.retain(|o| o >= base_val && is_valid_pow(o) != None);
    offsets.len()
}

fn gen_prime_par(base_val : &BigUint, max_val : &BigUint, max_sieve : uint, verbose : bool) -> uint {

    fn candidate_killed_by(candidate : &BigUint, prime : &BigUint) -> bool {
        let zero : BigUint = Zero::zero();
        for &offset in pow_offsets.iter() {
            let o : BigUint = big(offset);
            if (*candidate + o) % *prime == zero {
                return true;
            }
        }
        false
    }

    fn add_next_prime (max_val : &BigUint, offsets : Vec<BigUint>, prime : BigUint, primorial : BigUint) -> Vec<BigUint> {
        let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
        let mut base : BigUint = Zero::zero();
        let mut new_offsets : Vec<BigUint> = Vec::new();
        let mut counter = zero.clone();

        let mut start_time = time::precise_time_s();
        let (tx, rx) = channel();
        while counter < prime {
            let b = counter * primorial + base;
            if b > *max_val {
                break
            }
            let child_tx = tx.clone();
            let p = prime.clone();
            let mv = max_val.clone();
            let offs = offsets.clone();
            spawn(proc() {
                let mut vals = Vec::new();
                for o in offs.iter() {
                    let val = b + *o;
                    if val <= mv {
                        if !candidate_killed_by(&val, &p) {
                            vals.push(val);
                        }
                    }
                }
                child_tx.send(vals);
            });
            counter = counter + one;
        }
        println!("Time to sieve send: {}", time::precise_time_s() - start_time);

        start_time = time::precise_time_s();
        while counter > zero {
            new_offsets.push_all_move(rx.recv());
            counter = counter - one;
        }
        println!("Time to sieve receive: {}", time::precise_time_s() - start_time);

        new_offsets
    }

    let primorial_start : uint = 7u;
    let mut primorial : uint = 210u;  // 2*3*5*7
    let mut offsets : Vec<BigUint> = Vec::from_slice([big(97u)]);

    let mut primes : Vec<bool> = Vec::new();

    let mut start_time = time::precise_time_s();
    let sieve = simple_sieve(&mut primes, max_sieve, verbose);
    println!("Time to sieve: {}", time::precise_time_s() - start_time);
    start_time = time::precise_time_s();
    for &i in sieve.iter() {
        if i <= primorial_start {
            continue
        }
        offsets = add_next_prime(max_val, offsets, big(i), big(primorial));
        primorial = primorial * i;
    }
    println!("Time to sieve sieve: {}", time::precise_time_s() - start_time);

    start_time = time::precise_time_s();
    let (tx, rx) = channel();
    let mut child_count = 0;
    for o in offsets.iter().filter(|&o| o >= base_val) {
        let child_tx = tx.clone();
        let b = o.clone();
        spawn(proc() {
            child_tx.send(is_valid_pow(&b));
        });
        child_count += 1;
    }

    println!("Time to spawn: {}", time::precise_time_s() - start_time);

    let mut cluster_count = 0;
    for _ in range(0, child_count) {
        match rx.recv() {
            Some(p) => cluster_count += 1,
            None => ()
        }
    }
    cluster_count
}

#[cfg(test)]
mod test_primes {
    use super::{big, gen_prime, simple_sieve};

    #[test]
    fn gen_prime_is_correct() {
        assert!(gen_prime(&big(0), &big(100000000), 29, false) == 81u);
    }

    #[test]
    fn simple_sieve_is_correct() {
        assert!(simple_sieve(&mut Vec::new(), 5000000, false).len() == 348513);
    }
}

fn main() {
    println!("{}", gen_prime_par(&big(0), &big(1000000000), 210, true));
}<commit_msg>Add command line args<commit_after>extern crate num;
extern crate rand;
extern crate time;
extern crate bignum = "bignum#0.1.1-pre";

use bignum::{BigUint, ToBigUint, RandBigInt};
use num::{div_mod_floor, Integer};
use std::num::{Zero, One, pow, Float, FromPrimitive};
use rand::{task_rng, Rng};
use rand::distributions::range::SampleRange;
use std::vec::Vec;
use std::iter;
use std::iter::{FromIterator};
use std::clone::Clone;
use std::ops::{Shr, BitAnd};
use std::bool;

static pow_offsets : &'static[uint] = &[0u, 4u, 6u, 10u, 12u, 16u];

#[inline]
fn big<T: ToBigUint>(i : T) -> BigUint {
    i.to_biguint().unwrap()
}

// Source: https://gist.github.com/jsanders/8739134#file-generate_big_primes-rs-L35
fn mod_exp<T: Integer + Clone + Shr<uint,T> + BitAnd<T,T>>
    (base: &T, exponent: &T, modulus: &T) -> T {

    let (zero, one): (T, T) = (Zero::zero(), One::one());
    let mut result = one.clone();
    let mut baseAcc = base.clone();
    let mut exponentAcc = exponent.clone();

    while exponentAcc > zero {
        // Accumulate current base if current exponent bit is 1
        if (exponentAcc & one) == one {
            result = result.mul(&baseAcc);
            result = result.rem(modulus);
        }
        // Get next base by squaring
        baseAcc = baseAcc * baseAcc;
        baseAcc = baseAcc % *modulus;

        // Get next bit of exponent
        exponentAcc = exponentAcc.shr(&1);
    }
    result

}

// Rabin-Miller primality test, probabilistic
fn try_composite(a : &BigUint, d : &BigUint, n : &BigUint, s : &BigUint) -> bool {

    let one : BigUint = One::one();
    if mod_exp(a, d, n) == one {
        return false
    }
    let mut i = 0u;
    loop {
        if big(i) == *s {
            break
        }
        if mod_exp(a, &(pow(one+one, i) * *d), n) == *n-one {
            return false
        }
        i += 1;
    }
    true

}
fn rm_is_prime(n : &BigUint) -> bool {

    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    assert!(n >= &two);

    let mut s = zero.clone();
    let mut d = *n-one;
    let num_trials = 5;
    if n == &two {
        return true
    } else if n == &one || n.is_even() {
        return false
    } else {
        loop {
            let (quotient, remainder) = div_mod_floor(d.clone(), two.clone());
            if remainder == one { break }
            s = s + one;
            d = quotient;
        }
    }

    let mut rng = task_rng();
    for _ in range(0, num_trials) {
        let a = rng.gen_biguint_range(&two, n);
        if try_composite(&a, &d, n, &s) {
            return false
        }
    }
    true

}

fn fermat_is_prime(n : &BigUint) -> bool {
    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    if n == &two {
        true
    } else if n.is_even() {
        false
    } else if mod_exp(&two, &(n-one), n) == one {
        true
    } else {
        false
    }
}

fn is_valid_pow(prime : &BigUint) -> Option<BigUint> {
    for offset in [big(0u), big(4u), big(6u), big(10u), big(12u), big(16u)].iter() {
        if !fermat_is_prime(&(*prime + *offset)) {
            return None;
        }
    }
    Some(prime.clone())
}

// Simple sieve
fn simple_sieve(primes : &mut Vec<bool>, max_sieve : uint, verbose : bool) -> Vec<uint> {
    #[inline]
    fn int_sqrt(n: uint) -> uint { (n as f64).sqrt() as uint }

    if primes.len() <= max_sieve {
        *primes = Vec::from_elem(max_sieve+1, true);
        *primes.get_mut(0) = false;
        *primes.get_mut(1) = false;
        for prime in range(2, int_sqrt(max_sieve) + 1) {
            if *primes.get(prime) {
                for multiple in iter::range_step(prime * prime, max_sieve + 1, prime) {
                    *primes.get_mut(multiple) = false
                }
                if verbose { println!("Sieved {}", prime) }
            }
        }
    }
    if verbose { println!("Finished sieving") }
    range(2, max_sieve+1).filter(|&n| *primes.get(n)).collect()
}

fn gen_prime(base_val : &BigUint, max_val : &BigUint, max_sieve : uint, verbose : bool) -> uint {

    fn candidate_killed_by(candidate : &BigUint, prime : &BigUint) -> bool {
        let zero : BigUint = Zero::zero();
        for &offset in pow_offsets.iter() {
            let o : BigUint = FromPrimitive::from_uint(offset).unwrap();
            if (*candidate + o) % *prime == zero {
                return true;
            }
        }
        false
    }

    fn add_next_prime (max_val : &BigUint, offsets : Vec<BigUint>, prime : BigUint, primorial : BigUint) -> Vec<BigUint> {
        let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
        let mut base : BigUint = Zero::zero();
        let mut new_offsets : Vec<BigUint> = Vec::new();
        let mut counter = zero.clone();
        while counter < prime {
            if base > *max_val {
                break
            }
            for o in offsets.iter() {
                let val = base + *o;
                if val > *max_val {
                    break
                }
                if !candidate_killed_by(&val, &prime) {
                    new_offsets.push(val);
                }
            }
            base = base + primorial;
            counter = counter + one;
        }
        return new_offsets
    }

    let primorial_start : uint = 7u;
    let mut primorial : uint = 210u;  // 2*3*5*7
    let mut offsets : Vec<BigUint> = Vec::from_slice([big(97u)]);

    let mut primes : Vec<bool> = Vec::new();
    let mut start_time = time::precise_time_s();
    for &i in simple_sieve(&mut primes, max_sieve, verbose).iter() {
        if i <= primorial_start {
            continue
        }
        offsets = add_next_prime(max_val, offsets, big(i), big(primorial));
        primorial = primorial * i;
    }
    println!("Time to sieve sieve: {}", time::precise_time_s() - start_time);

    offsets.retain(|o| o >= base_val && is_valid_pow(o) != None);
    offsets.len()
}

fn gen_prime_par(base_val : &BigUint, max_val : &BigUint, max_sieve : uint, verbose : bool) -> uint {

    fn candidate_killed_by(candidate : &BigUint, prime : &BigUint) -> bool {
        let zero : BigUint = Zero::zero();
        for &offset in pow_offsets.iter() {
            let o : BigUint = big(offset);
            if (*candidate + o) % *prime == zero {
                return true;
            }
        }
        false
    }

    fn add_next_prime (max_val : &BigUint, offsets : Vec<BigUint>, prime : BigUint, primorial : BigUint) -> Vec<BigUint> {
        let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
        let mut base : BigUint = Zero::zero();
        let mut new_offsets : Vec<BigUint> = Vec::new();
        let mut counter = zero.clone();

        let mut start_time = time::precise_time_s();
        let (tx, rx) = channel();
        while counter < prime {
            let b = counter * primorial + base;
            if b > *max_val {
                break
            }
            let child_tx = tx.clone();
            let p = prime.clone();
            let mv = max_val.clone();
            let offs = offsets.clone();

            spawn(proc() {
                let mut st = time::precise_time_s();

                let mut vals = Vec::new();
                for o in offs.iter() {
                    let val = b + *o;
                    if val <= mv {
                        if !candidate_killed_by(&val, &p) {
                            vals.push(val);
                        }
                    }
                }
                println!("{}", time::precise_time_s() - st);

                child_tx.send(vals);
            });
            counter = counter + one;
        }
        //println!("Time to sieve send: {}", time::precise_time_s() - start_time);

        start_time = time::precise_time_s();
        while counter > zero {
            new_offsets.push_all_move(rx.recv());
            counter = counter - one;
        }
        //println!("Time to sieve receive: {}", time::precise_time_s() - start_time);

        new_offsets
    }

    let primorial_start : uint = 7u;
    let mut primorial : uint = 210u;  // 2*3*5*7
    let mut offsets : Vec<BigUint> = Vec::from_slice([big(97u)]);

    let mut primes : Vec<bool> = Vec::new();

    let mut start_time = time::precise_time_s();
    let sieve = simple_sieve(&mut primes, max_sieve, verbose);
    println!("Time to sieve: {}", time::precise_time_s() - start_time);
    start_time = time::precise_time_s();
    for &i in sieve.iter() {
        if i <= primorial_start {
            continue
        }
        offsets = add_next_prime(max_val, offsets, big(i), big(primorial));
        primorial = primorial * i;
    }
    println!("Time to sieve sieve: {}", time::precise_time_s() - start_time);

    start_time = time::precise_time_s();
    let (tx, rx) = channel();
    let mut child_count = 0;
    for o in offsets.iter().filter(|&o| o >= base_val) {
        let child_tx = tx.clone();
        let b = o.clone();
        spawn(proc() {
            child_tx.send(is_valid_pow(&b));
        });
        child_count += 1;
    }

    println!("Time to spawn: {}", time::precise_time_s() - start_time);

    let mut cluster_count = 0;
    for _ in range(0, child_count) {
        match rx.recv() {
            Some(p) => cluster_count += 1,
            None => ()
        }
    }
    cluster_count
}

#[cfg(test)]
mod test_primes {
    use super::{big, gen_prime, simple_sieve};

    #[test]
    fn gen_prime_is_correct() {
        assert!(gen_prime(&big(0), &big(100000000), 29, false) == 81u);
    }

    #[test]
    fn simple_sieve_is_correct() {
        assert!(simple_sieve(&mut Vec::new(), 5000000, false).len() == 348513);
    }
}

fn main() {
    let args = std::os::args();
    if args.len() < 2 || args[1] == "-p".to_owned() {
        println!("{}", gen_prime_par(&big(0), &big(1000000000), 210, true));
    } else if args[1] == "-s".to_owned() {
        println!("{}", gen_prime(&big(0), &big(1000000000), 210, true));
    }
}<|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/.

use devicemapper::{DM, DevId, DeviceInfo, DmFlags};

use engine::{EngineError, EngineResult, ErrorEnum};
use engine::strat_engine::thinpooldev::ThinPoolDev;

use std::fmt;
use std::fs::File;
use std::path::PathBuf;

use super::blockdev::BlockDev;
use types::Sectors;

pub struct LinearDev {
    name: String,
    dev_info: DeviceInfo,
}

impl fmt::Debug for LinearDev {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{}", self.name())
    }
}

/// Use DM to concatenate a set of blockdevs together into a
/// /dev/mapper/xxx block device of continuous sectors.
impl LinearDev {
    /// Construct a new block device by concatenating the given block_devs
    /// into linear space.  Use DM to reserve enough space for the stratis
    /// metadata on each BlockDev.
    pub fn new(name: &str, dm: &DM, block_devs: &Vec<&BlockDev>) -> EngineResult<LinearDev> {

        try!(dm.device_create(&name, None, DmFlags::empty()));
        let table = LinearDev::dm_table(block_devs);
        let id = &DevId::Name(&name);
        let dev_info = try!(dm.table_load(id, &table));
        try!(dm.device_suspend(id, DmFlags::empty()));

        ThinPoolDev::wait_for_dm();
        Ok(LinearDev {
            name: name.to_owned(),
            dev_info: dev_info,
        })
    }

    /// Generate a Vec<> to be passed to DM.  The format of the Vec entries is:
    /// <logical start sec> <length> "linear" /dev/xxx <start offset>
    fn dm_table(block_devs: &Vec<&BlockDev>) -> Vec<(u64, u64, String, String)> {
        let mut table = Vec::new();
        let mut logical_start_sector = Sectors(0);
        for block_dev in block_devs {
            let (start, length) = block_dev.avail_range();
            let dstr = block_dev.dstr();
            let line = (*logical_start_sector,
                        *length,
                        "linear".to_owned(),
                        format!("{} {}", dstr, *start));
            debug!("dmtable line : {:?}", line);
            table.push(line);
            logical_start_sector = logical_start_sector + length;
        }

        table
    }

    pub fn name(&self) -> &str {
        self.dev_info.name().clone()
    }

    pub fn path(&self) -> EngineResult<PathBuf> {
        match self.dev_info.device().path() {
            Some(path) => return Ok(path),
            None => {
                return Err(EngineError::Engine(ErrorEnum::Invalid,
                                               "No path associated with dev_info".into()))
            }
        }
    }

    pub fn teardown(&self, dm: &DM) -> EngineResult<()> {
        try!(dm.device_remove(&DevId::Name(&self.name), DmFlags::empty()));

        Ok(())
    }
}
<commit_msg>Add size() to LinearDev<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/.

use devicemapper::{DM, DevId, DeviceInfo, DmFlags};

use engine::{EngineError, EngineResult, ErrorEnum};
use engine::strat_engine::blockdev::blkdev_size;
use engine::strat_engine::thinpooldev::ThinPoolDev;

use std::fmt;
use std::fs::File;
use std::path::PathBuf;

use super::blockdev::BlockDev;
use types::{Bytes, Sectors};

pub struct LinearDev {
    name: String,
    dev_info: DeviceInfo,
}

impl fmt::Debug for LinearDev {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{}", self.name())
    }
}

/// Use DM to concatenate a set of blockdevs together into a
/// /dev/mapper/xxx block device of continuous sectors.
impl LinearDev {
    /// Construct a new block device by concatenating the given block_devs
    /// into linear space.  Use DM to reserve enough space for the stratis
    /// metadata on each BlockDev.
    pub fn new(name: &str, dm: &DM, block_devs: &Vec<&BlockDev>) -> EngineResult<LinearDev> {

        try!(dm.device_create(&name, None, DmFlags::empty()));
        let table = LinearDev::dm_table(block_devs);
        let id = &DevId::Name(&name);
        let dev_info = try!(dm.table_load(id, &table));
        try!(dm.device_suspend(id, DmFlags::empty()));

        ThinPoolDev::wait_for_dm();
        Ok(LinearDev {
            name: name.to_owned(),
            dev_info: dev_info,
        })
    }

    /// Generate a Vec<> to be passed to DM.  The format of the Vec entries is:
    /// <logical start sec> <length> "linear" /dev/xxx <start offset>
    fn dm_table(block_devs: &Vec<&BlockDev>) -> Vec<(u64, u64, String, String)> {
        let mut table = Vec::new();
        let mut logical_start_sector = Sectors(0);
        for block_dev in block_devs {
            let (start, length) = block_dev.avail_range();
            let dstr = block_dev.dstr();
            let line = (*logical_start_sector,
                        *length,
                        "linear".to_owned(),
                        format!("{} {}", dstr, *start));
            debug!("dmtable line : {:?}", line);
            table.push(line);
            logical_start_sector = logical_start_sector + length;
        }

        table
    }

    pub fn name(&self) -> &str {
        self.dev_info.name().clone()
    }

    pub fn size(&self) -> EngineResult<Bytes> {

        let blockdev_path = try!(self.path());
        let f = match File::open(blockdev_path) {
            Ok(file) => file,
            Err(e) => {
                let error_message = format!("{:?} Failed to open blockdev {:?}", e, self.path());
                return Err(EngineError::Engine(ErrorEnum::FailedToOpen, error_message.into()));
            }
        };

        match blkdev_size(&f) {
            Ok(bytes) => return Ok(bytes),
            Err(e) => {
                let error_message = format!("{:?} for device {:?}", e, self.path());
                return Err(EngineError::Engine(ErrorEnum::Error, error_message.into()));
            }
        };
    }

    pub fn path(&self) -> EngineResult<PathBuf> {
        match self.dev_info.device().path() {
            Some(path) => return Ok(path),
            None => {
                return Err(EngineError::Engine(ErrorEnum::Invalid,
                                               "No path associated with dev_info".into()))
            }
        }
    }

    pub fn teardown(&self, dm: &DM) -> EngineResult<()> {
        try!(dm.device_remove(&DevId::Name(&self.name), DmFlags::empty()));

        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>fix conflict<commit_after>extern crate soio;

pub use ports::localhost;

mod custom_event;

mod ports {
    use std::net::SocketAddr;
    use std::str::FromStr;
    use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
    use std::sync::atomic::Ordering::SeqCst;

    // Helper for getting a unique port for the task run
    // TODO: Reuse ports to not spam the system
    static mut NEXT_PORT: AtomicUsize = ATOMIC_USIZE_INIT;
    const FIRST_PORT: usize = 18080;

    fn next_port() -> usize {
        unsafe {
            // If the atomic was never used, set it to the initial port
            NEXT_PORT.compare_and_swap(0, FIRST_PORT, SeqCst);

            // Get and increment the port list
            NEXT_PORT.fetch_add(1, SeqCst)
        }
    }

    pub fn localhost() -> SocketAddr {
        let s = format!("127.0.0.1:{}", next_port());
        FromStr::from_str(&s).unwrap()
    }
}

pub fn sleep_ms(ms: u64) {
    use std::thread;
    use std::time::Duration;
    thread::sleep(Duration::from_millis(ms));
}
<|endoftext|>


<commit_before>use std::str::FromStr;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub enum Type {
    Address,
    Boolean,
    Float,
    Integer,
    Color,
    Char,
    Undefined,
}

impl FromStr for Type {
    type Err = &'static str;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "addr" => Ok(Type::Address),
            "bool" => Ok(Type::Boolean),
            "float" => Ok(Type::Float),
            "int" => Ok(Type::Integer),
            "color" => Ok(Type::Color),
            "char" => Ok(Type::Char),
            _ => Err("unable to parse type"),
        }
    }
}
<commit_msg>Removed undefined<commit_after>use std::str::FromStr;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub enum Type {
    Address,
    Boolean,
    Float,
    Integer,
    Color,
    Char,
}

impl FromStr for Type {
    type Err = &'static str;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "addr" => Ok(Type::Address),
            "bool" => Ok(Type::Boolean),
            "float" => Ok(Type::Float),
            "int" => Ok(Type::Integer),
            "color" => Ok(Type::Color),
            "char" => Ok(Type::Char),
            _ => Err("unable to parse type"),
        }
    }
}
<|endoftext|>