<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! This crates provides an API for logging in libra.
//!
//! # Instrumenting with Logs
//!
//! A set of logging macros (`info!`, `error!`, `warn!`, `debug!`, and `trace!`) is provided for
//! emitting logs at different levels. All of these macros support the addition of providing
//! structured data along with a formatted text message.
//!
//! ```
//! use libra_logger::info;
//!
//! let world = "world!";
//!
//! // formatted message
//! info!("hello {}", world);
//!
//! // structured data can be logged using the format 'key = value'
//! // where value implements Serialize
//! let value1 = 5;
//! info!(key1 = value1);
//!
//! // You can even set multiple key/value pairs and a format message
//! let value2 = false;
//! info!(key1 = value1, key2 = value2, "hello {}", world);
//! ```
//!
//! ### Note
//!
//! Arguments used in a formatted message are **not** captured and included as structured data.
//!
//! ## Typed Schema's
//!
//! The `Schema` trait can be used to implement typed logging schemas. This can either be
//! implemented by hand or derived using the `Schema` derive proc-macro, implementing the `Schema`
//! trait for the struct as well as providing setters for all fields.
//!
//! ```
//! use libra_logger::{info, Schema};
//!
//! #[derive(Schema)]
//! struct LogSchema<'a> {
//!     // Log using this type's Serialize impl
//!     a: usize,
//!     // Log using this type's Debug impl
//!     #[schema(debug)]
//!     b: Option<Vec<bool>>,
//!     // Log using this type's Display impl
//!     #[schema(display)]
//!     c: Option<&'a str>,
//! }
//!
//! let log = LogSchema { a: 5, b: None, c: None };
//!
//! info!(log.c("radiant"));
//! ```
//!
//! # Configuration
//!
//! In order for logs to be captured and emitted a Logger needs to be instantiated. This can be
//! done by using the `Logger` type:
//!
//! ```
//! use libra_logger::{Level, Logger};
//!
//! Logger::builder().level(Level::Info).build();
//! ```

#![forbid(unsafe_code)]

pub mod prelude {
    pub use crate::{
        debug, error, event, info,
        libra_logger::FileWriter,
        sample,
        sample::{SampleRate, Sampling},
        security::SecurityEvent,
        trace, warn,
    };
}
pub mod json_log;

mod event;
mod filter;
mod kv;
mod libra_logger;
mod logger;
mod macros;
mod metadata;
pub mod sample;

mod security;
mod struct_log;

pub use crate::libra_logger::{
    LibraLogger, LibraLogger as Logger, LibraLoggerBuilder, Writer, CHANNEL_SIZE,
};
pub use event::Event;
pub use filter::{Filter, LevelFilter};
pub use metadata::{Level, Metadata};

pub use kv::{Key, KeyValue, Schema, Value, Visitor};
pub use libra_log_derive::Schema;
pub use security::SecurityEvent;

mod counters;
<commit_msg>[logging] Added more detailed rust docs for structured logs<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! This crates provides an API for logging in libra.
//! # Instrumenting with Logs
//! ## Basic instrumenting with Logs
//!
//! A set of logging macros (`info!`, `error!`, `warn!`, `debug!`, and `trace!`) is provided for
//! emitting logs at different levels. All of these macros support the addition of providing
//! structured data along with a formatted text message.  For guidelines on which level to use,
//! see the [coding guidelines](https://developers.libra.org/docs/community/coding-guidelines#logging).
//!
//! The below examples do no type checking for structured log fields, and instead just serialize
//! whatever is given.
//! ```
//! use libra_logger::info;
//!
//! let world = "world!";
//!
//! // Formatted message, similar to `printf!`
//! info!("hello {}", world);
//! // => '{"level":"info", "message": "hello world!"}'
//!
//! // Structured data can be logged using the format 'key = value'
//! // where value implements Serialize.  This can be used for indexing and search later.
//! let value1 = 5;
//! info!(key1 = value1);
//! // => '{"level":"info", "data": {"key1": 5}}'
//!
//! // You can even set multiple key/value pairs and a format message together
//! let value2 = false;
//! info!(key1 = value1, key2 = value2, "hello {}", world);
//! // => '{"level":"info", "data": {"key1": 5, "key2": false}, "message": "hello world!"}'
//! ```
//!
//! ### Note
//!
//! Arguments used in a formatted message are **not** captured and included as structured data.
//! Everything after the format string literal e.g. `"hello {}"` are only used in the format string.
//!
//! ## Preferred instrumenting with Logs (Typed Schemas)
//!
//! The `Schema` trait can be used to implement typed logging schemas. This can either be
//! implemented by hand or derived using the `Schema` derive proc-macro, implementing the `Schema`
//! trait for the struct as well as providing setters for all fields.
//!
//! ```
//! use libra_logger::{info, Schema};
//!
//! #[derive(Schema)]
//! struct LogSchema<'a> {
//!     // Log using this type's Serialize impl
//!     a: usize,
//!     // Log using this type's Debug impl
//!     #[schema(debug)]
//!     b: Option<Vec<bool>>,
//!     // Log using this type's Display impl
//!     #[schema(display)]
//!     c: Option<&'a str>,
//! }
//!
//! let log = LogSchema { a: 5, b: None, c: None };
//!
//! // Automatic setters are named based on the field names, and handle `Option`
//! // None fields will be ignored
//! info!(log.c("radiant"));
//! // => '{"level":"info", "data": { "a": 5, "c": "radiant"}}'
//!
//!
//! #[derive(Schema)]
//! struct OtherSchema<'a> {
//!   val: Option<&'a str>
//! }
//!
//! let log = LogSchema { a: 5, b: None, c: None };
//! let other = OtherSchema { val: None };
//!
//! // Schemas can be combined
//! info!(
//!   other.val("awesome"), // First schema
//!   log // Second schema has fields added to it all
//! );
//! // => '{"level":"info", "data": { "a": 5, "val":"awesome"}}'
//!
//! let log = LogSchema { a: 5, b: None, c: None };
//! let other = OtherSchema { val: None };
//!
//! // Schemas can be combined with one off fields and messages like above
//! info!(
//!    other.val("awesome"), // First schema
//!    log, // Second schema has fields added to it all
//!    new_field = "new", // Basic structured fields
//!    "Message: {}", // Format messages
//!    "Some message" // Format message fields (not added to indexed fields)
//! );
//! // => {"level":"info", "message": "Message: Some message",
//! //     "data": { "a": 5, "val":"awesome", "new_field": "new"}}'
//! ```
//!
//! ## Sampling logs
//!
//! Sometimes logging a large amount of data is expensive.  In order to log information only part
//! of the time, we've added a `sample!` macro that's configurable on how often we want to execute some code.
//!
//! `SampleRate` determines how often the sampled statement will occur.
//!
//! ```
//! use libra_logger::{info, sample, sample::{SampleRate, Sampling}};
//! use std::time::Duration;
//!
//! // Sampled based on frequency of events, log only every 2 logs
//! sample!(SampleRate::Frequency(2), info!("Long log"));
//!
//! // Sampled based on time passed, log at most once a minute
//! sample!(SampleRate::Duration(Duration::from_secs(60)), info!("Long log"));
//! ```
//! # Configuration
//!
//! In order for logs to be captured and emitted a Logger needs to be instantiated. This can be
//! done by using the `Logger` type:
//!
//! ```
//! use libra_logger::{Level, Logger};
//!
//! Logger::builder().level(Level::Info).build();
//! ```

#![forbid(unsafe_code)]

pub mod prelude {
    pub use crate::{
        debug, error, event, info,
        libra_logger::FileWriter,
        sample,
        sample::{SampleRate, Sampling},
        security::SecurityEvent,
        trace, warn,
    };
}
pub mod json_log;

mod event;
mod filter;
mod kv;
mod libra_logger;
mod logger;
mod macros;
mod metadata;
pub mod sample;

mod security;
mod struct_log;

pub use crate::libra_logger::{
    LibraLogger, LibraLogger as Logger, LibraLoggerBuilder, Writer, CHANNEL_SIZE,
};
pub use event::Event;
pub use filter::{Filter, LevelFilter};
pub use metadata::{Level, Metadata};

pub use kv::{Key, KeyValue, Schema, Value, Visitor};
pub use libra_log_derive::Schema;
pub use security::SecurityEvent;

mod counters;
<|endoftext|>


<commit_before>use std::error;
use std::fmt;

use cairo;
use cssparser::BasicParseError;

use attributes::Attribute;
use parsers::ParseError;

/// A simple error which refers to an attribute's value
#[derive(Debug, Clone, PartialEq)]
pub enum ValueErrorKind {
    /// The value could not be parsed
    Parse(ParseError),

    // The value could be parsed, but is invalid
    Value(String),
}

/// A complete error for an attribute and its erroneous value
#[derive(Debug, Clone, PartialEq)]
pub struct NodeError {
    attr: Attribute,
    err: ValueErrorKind,
}

impl NodeError {
    pub fn parse_error(attr: Attribute, error: ParseError) -> NodeError {
        NodeError {
            attr,
            err: ValueErrorKind::Parse(error),
        }
    }

    pub fn value_error(attr: Attribute, description: &str) -> NodeError {
        NodeError {
            attr,
            err: ValueErrorKind::Value(description.to_string()),
        }
    }

    pub fn attribute_error(attr: Attribute, error: ValueErrorKind) -> NodeError {
        NodeError { attr, err: error }
    }
}

impl error::Error for NodeError {
    fn description(&self) -> &str {
        match self.err {
            ValueErrorKind::Parse(_) => "parse error",
            ValueErrorKind::Value(_) => "invalid attribute value",
        }
    }
}

impl fmt::Display for NodeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.err {
            ValueErrorKind::Parse(ref n) => write!(
                f,
                "error parsing value for attribute \"{}\": {}",
                self.attr.to_string(),
                n.display
            ),

            ValueErrorKind::Value(ref s) => write!(
                f,
                "invalid value for attribute \"{}\": {}",
                self.attr.to_string(),
                s
            ),
        }
    }
}

impl From<ParseError> for ValueErrorKind {
    fn from(pe: ParseError) -> ValueErrorKind {
        ValueErrorKind::Parse(pe)
    }
}

impl<'a> From<BasicParseError<'a>> for ValueErrorKind {
    fn from(e: BasicParseError<'_>) -> ValueErrorKind {
        ValueErrorKind::from(ParseError::from(e))
    }
}

#[derive(Clone)]
pub enum RenderingError {
    Cairo(cairo::Status),
    CircularReference,
    InstancingLimit,
}

impl From<cairo::Status> for RenderingError {
    fn from(e: cairo::Status) -> RenderingError {
        assert!(e != cairo::Status::Success);

        RenderingError::Cairo(e)
    }
}

#[cfg(test)]
pub fn is_parse_error<T>(r: &Result<T, ValueErrorKind>) -> bool {
    match *r {
        Err(ValueErrorKind::Parse(_)) => true,
        _ => false,
    }
}

#[cfg(test)]
pub fn is_value_error<T>(r: &Result<T, ValueErrorKind>) -> bool {
    match *r {
        Err(ValueErrorKind::Value(_)) => true,
        _ => false,
    }
}
<commit_msg>error::LoadingError: new error enum for the loading stage<commit_after>use std::error;
use std::fmt;

use cairo;
use cssparser::BasicParseError;

use attributes::Attribute;
use parsers::ParseError;

/// A simple error which refers to an attribute's value
#[derive(Debug, Clone, PartialEq)]
pub enum ValueErrorKind {
    /// The value could not be parsed
    Parse(ParseError),

    // The value could be parsed, but is invalid
    Value(String),
}

/// A complete error for an attribute and its erroneous value
#[derive(Debug, Clone, PartialEq)]
pub struct NodeError {
    attr: Attribute,
    err: ValueErrorKind,
}

impl NodeError {
    pub fn parse_error(attr: Attribute, error: ParseError) -> NodeError {
        NodeError {
            attr,
            err: ValueErrorKind::Parse(error),
        }
    }

    pub fn value_error(attr: Attribute, description: &str) -> NodeError {
        NodeError {
            attr,
            err: ValueErrorKind::Value(description.to_string()),
        }
    }

    pub fn attribute_error(attr: Attribute, error: ValueErrorKind) -> NodeError {
        NodeError { attr, err: error }
    }
}

impl error::Error for NodeError {
    fn description(&self) -> &str {
        match self.err {
            ValueErrorKind::Parse(_) => "parse error",
            ValueErrorKind::Value(_) => "invalid attribute value",
        }
    }
}

impl fmt::Display for NodeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.err {
            ValueErrorKind::Parse(ref n) => write!(
                f,
                "error parsing value for attribute \"{}\": {}",
                self.attr.to_string(),
                n.display
            ),

            ValueErrorKind::Value(ref s) => write!(
                f,
                "invalid value for attribute \"{}\": {}",
                self.attr.to_string(),
                s
            ),
        }
    }
}

impl From<ParseError> for ValueErrorKind {
    fn from(pe: ParseError) -> ValueErrorKind {
        ValueErrorKind::Parse(pe)
    }
}

impl<'a> From<BasicParseError<'a>> for ValueErrorKind {
    fn from(e: BasicParseError<'_>) -> ValueErrorKind {
        ValueErrorKind::from(ParseError::from(e))
    }
}

#[derive(Clone)]
pub enum RenderingError {
    Cairo(cairo::Status),
    CircularReference,
    InstancingLimit,
}

impl From<cairo::Status> for RenderingError {
    fn from(e: cairo::Status) -> RenderingError {
        assert!(e != cairo::Status::Success);

        RenderingError::Cairo(e)
    }
}

#[derive(Clone)]
pub enum LoadingError {
    Cairo(cairo::Status),
    EmptyData,
}

impl From<cairo::Status> for LoadingError {
    fn from(e: cairo::Status) -> LoadingError {
        assert!(e != cairo::Status::Success);

        LoadingError::Cairo(e)
    }
}

#[cfg(test)]
pub fn is_parse_error<T>(r: &Result<T, ValueErrorKind>) -> bool {
    match *r {
        Err(ValueErrorKind::Parse(_)) => true,
        _ => false,
    }
}

#[cfg(test)]
pub fn is_value_error<T>(r: &Result<T, ValueErrorKind>) -> bool {
    match *r {
        Err(ValueErrorKind::Value(_)) => true,
        _ => false,
    }
}
<|endoftext|>


<commit_before>//! A presence event is represented by a struct with a set content field.
//!
//! The only content valid for this event is `PresenceEventContent.

use js_int::UInt;
pub use ruma_common::presence::PresenceState;
use ruma_events_macros::{Event, EventContent};
use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

/// Presence event.
#[derive(Clone, Debug, Event)]
pub struct PresenceEvent {
    /// Data specific to the event type.
    pub content: PresenceEventContent,

    /// Contains the fully-qualified ID of the user who sent this event.
    pub sender: UserId,
}

/// Informs the room of members presence.
///
/// This is the only event content a `PresenceEvent` can contain as it's
/// `content` field.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[ruma_event(type = "m.presence")]
pub struct PresenceEventContent {
    /// The current avatar URL for this user.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,

    /// Whether or not the user is currently active.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub currently_active: Option<bool>,

    /// The current display name for this user.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub displayname: Option<String>,

    /// The last time since this user performed some action, in milliseconds.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub last_active_ago: Option<UInt>,

    /// The presence state for this user.
    pub presence: PresenceState,

    /// An optional description to accompany the presence.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status_msg: Option<String>,
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use js_int::UInt;
    use matches::assert_matches;
    use ruma_identifiers::UserId;
    use serde_json::{from_value as from_json_value, json, to_value as to_json_value};

    use super::{PresenceEvent, PresenceEventContent, PresenceState};
    use crate::EventJson;

    #[test]
    fn serialization() {
        let event = PresenceEvent {
            content: PresenceEventContent {
                avatar_url: Some("mxc://localhost:wefuiwegh8742w".to_string()),
                currently_active: Some(false),
                displayname: None,
                last_active_ago: Some(UInt::try_from(2_478_593).unwrap()),
                presence: PresenceState::Online,
                status_msg: Some("Making cupcakes".to_string()),
            },
            sender: UserId::try_from("@example:localhost").unwrap(),
        };

        let json = json!({
            "content": {
                "avatar_url": "mxc://localhost:wefuiwegh8742w",
                "currently_active": false,
                "last_active_ago": 2_478_593,
                "presence": "online",
                "status_msg": "Making cupcakes"
            },
            "sender": "@example:localhost",
            "type": "m.presence"
        });

        assert_eq!(to_json_value(&event).unwrap(), json);
    }

    #[test]
    fn deserialization() {
        let json = json!({
            "content": {
                "avatar_url": "mxc://localhost:wefuiwegh8742w",
                "currently_active": false,
                "last_active_ago": 2_478_593,
                "presence": "online",
                "status_msg": "Making cupcakes"
            },
            "sender": "@example:localhost",
            "type": "m.presence"
        });

        assert_matches!(
            from_json_value::<EventJson<PresenceEvent>>(json)
                .unwrap()
                .deserialize()
                .unwrap(),
            PresenceEvent {
                content: PresenceEventContent {
                    avatar_url: Some(avatar_url),
                    currently_active: Some(false),
                    displayname: None,
                    last_active_ago: Some(last_active_ago),
                    presence: PresenceState::Online,
                    status_msg: Some(status_msg),
                },
                sender,
            } if avatar_url == "mxc://localhost:wefuiwegh8742w"
                && status_msg == "Making cupcakes"
                && sender == "@example:localhost"
                && last_active_ago == UInt::from(2_478_593u32)
        );
    }
}
<commit_msg>events: Remove EventJson from presence tests<commit_after>//! A presence event is represented by a struct with a set content field.
//!
//! The only content valid for this event is `PresenceEventContent.

use js_int::UInt;
pub use ruma_common::presence::PresenceState;
use ruma_events_macros::{Event, EventContent};
use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

/// Presence event.
#[derive(Clone, Debug, Event)]
pub struct PresenceEvent {
    /// Data specific to the event type.
    pub content: PresenceEventContent,

    /// Contains the fully-qualified ID of the user who sent this event.
    pub sender: UserId,
}

/// Informs the room of members presence.
///
/// This is the only event content a `PresenceEvent` can contain as it's
/// `content` field.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[ruma_event(type = "m.presence")]
pub struct PresenceEventContent {
    /// The current avatar URL for this user.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,

    /// Whether or not the user is currently active.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub currently_active: Option<bool>,

    /// The current display name for this user.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub displayname: Option<String>,

    /// The last time since this user performed some action, in milliseconds.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub last_active_ago: Option<UInt>,

    /// The presence state for this user.
    pub presence: PresenceState,

    /// An optional description to accompany the presence.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status_msg: Option<String>,
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use js_int::UInt;
    use matches::assert_matches;
    use ruma_identifiers::UserId;
    use serde_json::{from_value as from_json_value, json, to_value as to_json_value};

    use super::{PresenceEvent, PresenceEventContent, PresenceState};

    #[test]
    fn serialization() {
        let event = PresenceEvent {
            content: PresenceEventContent {
                avatar_url: Some("mxc://localhost:wefuiwegh8742w".to_string()),
                currently_active: Some(false),
                displayname: None,
                last_active_ago: Some(UInt::try_from(2_478_593).unwrap()),
                presence: PresenceState::Online,
                status_msg: Some("Making cupcakes".to_string()),
            },
            sender: UserId::try_from("@example:localhost").unwrap(),
        };

        let json = json!({
            "content": {
                "avatar_url": "mxc://localhost:wefuiwegh8742w",
                "currently_active": false,
                "last_active_ago": 2_478_593,
                "presence": "online",
                "status_msg": "Making cupcakes"
            },
            "sender": "@example:localhost",
            "type": "m.presence"
        });

        assert_eq!(to_json_value(&event).unwrap(), json);
    }

    #[test]
    fn deserialization() {
        let json = json!({
            "content": {
                "avatar_url": "mxc://localhost:wefuiwegh8742w",
                "currently_active": false,
                "last_active_ago": 2_478_593,
                "presence": "online",
                "status_msg": "Making cupcakes"
            },
            "sender": "@example:localhost",
            "type": "m.presence"
        });

        assert_matches!(
            from_json_value::<PresenceEvent>(json).unwrap(),
            PresenceEvent {
                content: PresenceEventContent {
                    avatar_url: Some(avatar_url),
                    currently_active: Some(false),
                    displayname: None,
                    last_active_ago: Some(last_active_ago),
                    presence: PresenceState::Online,
                    status_msg: Some(status_msg),
                },
                sender,
            } if avatar_url == "mxc://localhost:wefuiwegh8742w"
                && status_msg == "Making cupcakes"
                && sender == "@example:localhost"
                && last_active_ago == UInt::from(2_478_593u32)
        );
    }
}
<|endoftext|>


<commit_before>use util::*;

use handlebars::{Handlebars, Helper, RenderContext, RenderError};

#[derive(Debug)]
pub struct AMQPTemplates {
    pub main:     String,
    pub domain:   String,
    pub constant: String,
    pub klass:    String,
    pub method:   String,
    pub argument: String,
    pub property: String,
}

pub fn camel_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to camel").value().as_str().expect("non-string param given to camel");
    rc.writer.write(camel_name(param).as_bytes())?;
    Ok(())
}

pub fn snake_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to snake").value().as_str().expect("non-string param given to snake");
    rc.writer.write(snake_name(param).as_bytes())?;
    Ok(())
}
<commit_msg>codegen: impl Default for AMQPTemplates<commit_after>use util::*;

use handlebars::{Handlebars, Helper, RenderContext, RenderError};

#[derive(Debug)]
pub struct AMQPTemplates {
    pub main:     String,
    pub domain:   String,
    pub constant: String,
    pub klass:    String,
    pub method:   String,
    pub argument: String,
    pub property: String,
}

impl Default for AMQPTemplates {
    fn default() -> AMQPTemplates {
        AMQPTemplates {
            main:     String::new(),
            domain:   String::new(),
            constant: String::new(),
            klass:    String::new(),
            method:   String::new(),
            argument: String::new(),
            property: String::new(),
        }
    }
}

pub fn camel_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to camel").value().as_str().expect("non-string param given to camel");
    rc.writer.write(camel_name(param).as_bytes())?;
    Ok(())
}

pub fn snake_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to snake").value().as_str().expect("non-string param given to snake");
    rc.writer.write(snake_name(param).as_bytes())?;
    Ok(())
}
<|endoftext|>


<commit_before>use codec::{
    eyre::Result, stencila_schema::Node, utils::vec_string, Codec, CodecTrait, DecodeOptions,
    EncodeOptions,
};

#[cfg(feature = "decode")]
mod decode;

#[cfg(feature = "encode")]
mod encode;

#[cfg(feature = "translate")]
mod translate;
use codec_md::MdCodec;
pub use translate::*;

// A codec for Jupyter Notebook (.ipynb) files
pub struct IpynbCodec {}

#[cfg(any(feature = "decode", feature = "encode"))]
impl CodecTrait for IpynbCodec {
    fn spec() -> Codec {
        let md_codec = MdCodec::spec();
        Codec {
            status: "beta".to_string(),
            formats: vec_string!["ipynb"],
            root_types: vec_string!["*"],
            from_string: cfg!(feature = "decode"),
            from_path: cfg!(feature = "decode"),
            to_string: cfg!(feature = "encode"),
            to_path: cfg!(feature = "encode"),
            unsupported_types: md_codec.unsupported_types,
            unsupported_properties: md_codec.unsupported_properties,
        }
    }

    #[cfg(feature = "decode")]
    fn from_str(str: &str, _options: Option<DecodeOptions>) -> Result<Node> {
        decode::decode(str)
    }

    #[cfg(feature = "encode")]
    fn to_string(node: &Node, _options: Option<EncodeOptions>) -> Result<String> {
        encode::encode(node)
    }
}
<commit_msg>fix(IPYNB codec): Change `root_types` to `Article` only<commit_after>use codec::{
    eyre::Result, stencila_schema::Node, utils::vec_string, Codec, CodecTrait, DecodeOptions,
    EncodeOptions,
};

#[cfg(feature = "decode")]
mod decode;

#[cfg(feature = "encode")]
mod encode;

#[cfg(feature = "translate")]
mod translate;
use codec_md::MdCodec;
pub use translate::*;

// A codec for Jupyter Notebook (.ipynb) files
pub struct IpynbCodec {}

#[cfg(any(feature = "decode", feature = "encode"))]
impl CodecTrait for IpynbCodec {
    fn spec() -> Codec {
        let md_codec = MdCodec::spec();
        Codec {
            status: "beta".to_string(),
            formats: vec_string!["ipynb"],
            root_types: vec_string!["Article"],
            from_string: cfg!(feature = "decode"),
            from_path: cfg!(feature = "decode"),
            to_string: cfg!(feature = "encode"),
            to_path: cfg!(feature = "encode"),
            unsupported_types: md_codec.unsupported_types,
            unsupported_properties: md_codec.unsupported_properties,
        }
    }

    #[cfg(feature = "decode")]
    fn from_str(str: &str, _options: Option<DecodeOptions>) -> Result<Node> {
        decode::decode(str)
    }

    #[cfg(feature = "encode")]
    fn to_string(node: &Node, _options: Option<EncodeOptions>) -> Result<String> {
        encode::encode(node)
    }
}
<|endoftext|>


<commit_before>//! This module implements a database that stores results of
//! previously performed searches.
//!
//! Using such a database (called "transposition table") is a way to
//! greatly reduce the search space of a chess tree with little
//! negative impact. Chess programs, during their brute-force search,
//! encounter the same positions again and again, but from different
//! sequences of moves, which is called a transposition.
//!
//! When the search encounters a transposition, it is beneficial to
//! "remember" what was determined last time the position was
//! examined, rather than redoing the entire search again. For this
//! reason, chess programs have a transposition table, which is a
//! large hash table storing information about positions previously
//! searched, how deeply they were searched, and what we concluded
//! about them.

use std;
use std::cell::UnsafeCell;
use std::mem::transmute;

/// Stores information about a particular position.
#[derive(Copy, Clone)]
pub struct EntryData {
    move16: u16,
    value: i16,
    eval_value: i16,
    gen_bound: u8,
    depth: u8,
}

impl EntryData {
    /// Creates a new instance.
    ///
    /// The following information can be stored:
    ///
    /// * `value` -- the value assigned to the position,
    ///
    /// * `bound` -- the meaning of the assigned value ("Exact",
    ///    "Upper Bound", or "Lower Bound"),
    ///
    /// * `depth` -- the depth of search,
    ///
    /// * `move16` -- best or refutation move,
    ///
    /// * `eval_value` -- the calculated static evaluation for the
    ///    position.
    pub fn new(value: i16, bound: u8, depth: u8, move16: u16, eval_value: i16) -> EntryData {
        assert!(bound <= 0b11);
        assert!(depth < 128);
        EntryData {
            move16: move16,
            value: value,
            eval_value: eval_value,
            gen_bound: bound, // Stores the entry's generation and the bound.
            depth: depth,
        }
    }

    #[inline(always)]
    pub fn move16(&self) -> u16 {
        self.move16
    }

    #[inline(always)]
    pub fn value(&self) -> i16 {
        self.value
    }

    #[inline(always)]
    pub fn eval_value(&self) -> i16 {
        self.eval_value
    }

    #[inline(always)]
    pub fn bound(&self) -> u8 {
        self.gen_bound & 0b11
    }

    #[inline(always)]
    pub fn depth(&self) -> u8 {
        self.depth
    }
}

// Represents transposition table entry.
//
// It is 16 bytes, defined as below:
//
// * key        64 bit
// * move16     16 bit
// * value      16 bit
// * eval value 16 bit
// * generation  6 bit
// * bound type  2 bit
// * depth       8 bit
#[derive(Copy, Clone)]
struct Entry {
    key: u64,
    data: EntryData,
}

impl Default for Entry {
    fn default() -> Entry {
        Entry {
            key: 0,
            data: unsafe { transmute(0u64) },
        }
    }
}

impl Entry {
    // Returns the whole entry data as `u64`.
    //
    // This is needed for implementing the lock-less probing and
    // storing.
    #[inline(always)]
    fn data_u64(&self) -> u64 {
        unsafe { transmute(self.data) }
    }

    #[inline(always)]
    fn generation(&self) -> u8 {
        self.data.gen_bound & 0b11111100
    }

    #[inline(always)]
    fn set_generation(&mut self, generation: u8) {
        assert_eq!(generation & 0b11, 0);
        self.data.gen_bound = generation | self.data.bound()
    }
}

/// A large hash-table that stores results of previously performed
/// searches.
pub struct TranspositionTable {
    generation: u8,
    cluster_count: usize,
    table: UnsafeCell<Vec<[Entry; 4]>>,
}

impl TranspositionTable {
    /// Creates a new transposition table.
    ///
    /// The newly created table has the minimum possible size. Before
    /// using the new table for anything, `resize()` should be called
    /// on it, specifying the desired size.
    pub fn new() -> TranspositionTable {
        TranspositionTable {
            generation: 0,
            cluster_count: 1,
            table: UnsafeCell::new(vec![Default::default()]),
        }
    }

    /// Signals that a new search is about to begin.
    ///
    /// Internally, the transposition table maintains a generation
    /// counter that is used to implement an efficient replacement
    /// strategy. This method increases this counter.
    pub fn new_search(&mut self) {
        self.generation += 0b100;  // Lower 2 bits are used by bound type
        assert_eq!(self.generation & 0b11, 0);
    }

    /// Resizes the transpositon table.
    ///
    /// `size_mb` is the desired new size in Mbytes. All entries in
    /// the table will be lost.
    pub fn resize(&mut self, size_mb: usize) {
        // The cluster count should be in the form "2**n", so the best
        // we can do is to ensure that the new cluster count will be
        // as close as possible but no greater than the requested one.
        let requested_cluster_count = (size_mb * 1024 * 1024) / std::mem::size_of::<[Entry; 4]>();

        // First, make sure `requested_cluster_count` is exceeded.
        let mut new_cluster_count = 1;
        while requested_cluster_count >= new_cluster_count {
            new_cluster_count <<= 1;
        }

        // Then make one step back, being careful so that the new
        // cluster count is not zero.
        if new_cluster_count > 1 {
            new_cluster_count >>= 1;
        } else {
            new_cluster_count = 1;
        }

        // Finally, reallocate the vector of clusters.
        if new_cluster_count != self.cluster_count {
            self.cluster_count = new_cluster_count;
            self.table = UnsafeCell::new(vec![Default::default(); new_cluster_count]);
        }
    }

    /// Clears the transpositon table.
    ///
    /// All remaining entries in the table will be removed.
    pub fn clear(&mut self) {
        self.table = UnsafeCell::new(vec![Default::default(); self.cluster_count]);
    }

    /// Probes for data by a specific key.
    #[inline]
    pub fn probe(&self, key: u64) -> Option<EntryData> {
        // `probe` and `store` implement a clever lock-less hashing
        // method. Rather than to store two disjoint items, the key is
        // stored xored with data, while data is stored additionally
        // as usual.
        let cluster = unsafe { self.cluster_mut(key) };
        for entry in cluster.iter_mut() {
            if entry.key ^ entry.data_u64() == key {
                // If `key` and `data` were written simultaneously by
                // different search instances with different keys, the
                // error will yield in a mismatch of the comparison
                // (except the rare and inherent key collisions).
                entry.set_generation(self.generation);  // Update the generation.!!! bug!!!!
                return Some(entry.data);
            }
        }
        None
    }

    /// Stores data by a specific key.
    ///
    /// After being stored, the data might be retrieved by
    /// `probe(key)`. This is not guaranteed though, because in the
    /// meantime it might have been overwritten.
    #[inline]
    pub fn store(&self, key: u64, mut data: EntryData) {
        data.gen_bound |= self.generation;  // Set the generation.
        let mut cluster = unsafe { self.cluster_mut(key) };
        let mut replace_index = 0;
        let mut replace_score = 0xff;
        for (i, entry) in cluster.iter_mut().enumerate() {
            // Check if this is an empty entry, or an old entry for
            // the same key.
            if entry.key == 0 || entry.key ^ entry.data_u64() == key {
                if data.move16 == 0 {
                    data.move16 = entry.data.move16;  // Preserve any existing move.
                }
                replace_index = i;
                break;
            }
            // The replaced entry will be the entry with the lowest
            // score.
            let entry_score = self.calc_score(entry);
            if entry_score < replace_score {
                replace_index = i;
                replace_score = entry_score;
            }
        }
        unsafe {
            cluster.get_unchecked_mut(replace_index).key = key ^ transmute::<EntryData, u64>(data);
            cluster.get_unchecked_mut(replace_index).data = data;
        }
    }

    // A helper method for `store`.
    //
    // Implements our replacement strategy. Should return higher
    // values for the entries that are move likely to save CPU work.
    #[inline]
    fn calc_score(&self, entry: &Entry) -> u8 {
        (if entry.generation() == self.generation {
            128
        } else {
            0
        }) + entry.data.depth
    }

    // A helper method for `probe` and `store`.
    #[inline]
    unsafe fn cluster_mut(&self, key: u64) -> &mut [Entry; 4] {
        let cluster_index = (key & (self.cluster_count - 1) as u64) as usize;
        self.table.get().as_mut().unwrap().get_unchecked_mut(cluster_index)
    }
}

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

    #[test]
    fn test_cluster_size() {
        assert_eq!(std::mem::size_of::<[Entry; 4]>(), 64);
        assert_eq!(std::mem::size_of::<Entry>(), 16);
    }

    #[test]
    fn test_tt_resize() {
        let mut tt = TranspositionTable::new();
        assert_eq!(unsafe { &*tt.table.get() }.capacity(), 1);
        tt.resize(1);
        assert_eq!(unsafe { &*tt.table.get() }.capacity(),
                   1024 * 1024 / std::mem::size_of::<[Entry; 4]>());
        tt.clear();
    }

    #[test]
    fn test_store_and_probe() {
        let mut tt = TranspositionTable::new();
        assert!(tt.probe(1).is_none());
        let data = EntryData::new(0, 0, 100, 666, 0);
        assert_eq!(data.depth(), 100);
        assert_eq!(data.move16(), 666);
        tt.store(1, data);
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        tt.store(1, EntryData::new(0, 0, 100, 666, 0));
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(1).unwrap().move16(), 666);
        for i in 2..100 {
            tt.store(i, EntryData::new(i as i16, 0, i as u8, i as u16, i as i16));
        }
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(99).unwrap().depth(), 99);
        assert_eq!(tt.probe(98).unwrap().depth(), 98);
        assert_eq!(tt.probe(97).unwrap().depth(), 97);
        tt.clear();
        assert!(tt.probe(1).is_none());
        tt.store(1, data);
        tt.new_search();
        tt.probe(1);
        assert!(tt.probe(1).is_some());
    }
}
<commit_msg>almost finished tt.rs<commit_after>//! This module implements a database that stores results of
//! previously performed searches.
//!
//! Using such a database (called "transposition table") is a way to
//! greatly reduce the search space of a chess tree with little
//! negative impact. Chess programs, during their brute-force search,
//! encounter the same positions again and again, but from different
//! sequences of moves, which is called a transposition.
//!
//! When the search encounters a transposition, it is beneficial to
//! "remember" what was determined last time the position was
//! examined, rather than redoing the entire search again. For this
//! reason, chess programs have a transposition table, which is a
//! large hash table storing information about positions previously
//! searched, how deeply they were searched, and what we concluded
//! about them.

use std;
use std::cell::UnsafeCell;
use std::mem::transmute;

/// The value is void.
pub const BOUND_NONE: u8 = 0;

/// All-Node, the value is "Upper Bound".
pub const BOUND_UPPER: u8 = 0b10;

/// Cut-Node, the value is "Lower Bound".
pub const BOUND_LOWER: u8 = 0b01;

/// PV-Node, the value is "Exact".
pub const BOUND_EXACT: u8 = BOUND_UPPER | BOUND_LOWER;

/// Stores information about a particular position.
#[derive(Copy, Clone)]
pub struct EntryData {
    move16: u16,
    value: i16,
    eval_value: i16,
    gen_bound: u8,
    depth: u8,
}

impl EntryData {
    /// Creates a new instance.
    ///
    /// The following information can be stored:
    ///
    /// * `value` -- the value assigned to the position,
    ///
    /// * `bound` -- the meaning of the assigned value (`BOUND_EXACT`,
    ///    `BOUND_LOWER`, `BOUND_UPPER`, or `BOUND_NONE`),
    ///
    /// * `depth` -- the depth of search,
    ///
    /// * `move16` -- best or refutation move,
    ///
    /// * `eval_value` -- the calculated static evaluation for the
    ///    position.
    pub fn new(value: i16, bound: u8, depth: u8, move16: u16, eval_value: i16) -> EntryData {
        assert!(bound <= 0b11);
        assert!(depth < 128);
        EntryData {
            move16: move16,
            value: value,
            eval_value: eval_value,
            gen_bound: bound, // Stores the entry's generation and the bound.
            depth: depth,
        }
    }

    #[inline(always)]
    pub fn move16(&self) -> u16 {
        self.move16
    }

    #[inline(always)]
    pub fn value(&self) -> i16 {
        self.value
    }

    #[inline(always)]
    pub fn eval_value(&self) -> i16 {
        self.eval_value
    }

    #[inline(always)]
    pub fn bound(&self) -> u8 {
        self.gen_bound & 0b11
    }

    #[inline(always)]
    pub fn depth(&self) -> u8 {
        self.depth
    }
}

// Represents transposition table entry.
//
// It is 16 bytes, defined as below:
//
// * key        64 bit
// * move16     16 bit
// * value      16 bit
// * eval value 16 bit
// * generation  6 bit
// * bound type  2 bit
// * depth       8 bit
#[derive(Copy, Clone)]
struct Entry {
    key: u64,
    data: EntryData,
}

impl Default for Entry {
    fn default() -> Entry {
        Entry {
            key: 0,
            data: unsafe { transmute(0u64) },
        }
    }
}

impl Entry {
    // Returns the whole contained data as one `u64` value.
    //
    // This is needed for implementing the lock-less probing and
    // storing.
    #[inline(always)]
    fn data_u64(&self) -> u64 {
        unsafe { transmute(self.data) }
    }

    // Returns entry's generation.
    #[inline(always)]
    fn generation(&self) -> u8 {
        self.data.gen_bound & 0b11111100
    }

    // Updates entry's generation.
    //
    // Since the `key` is saved xored with the data, when we change
    // the data, we have to change the stored `key` as well.
    #[inline(always)]
    fn update_generation(&mut self, generation: u8) {
        assert_eq!(generation & 0b11, 0);
        let old_data_u64 = self.data_u64();
        self.data.gen_bound = generation | self.data.bound();
        self.key ^= old_data_u64 ^ self.data_u64();
    }
}

/// A large hash-table that stores results of previously performed
/// searches.
pub struct TranspositionTable {
    generation: u8,
    cluster_count: usize,
    table: UnsafeCell<Vec<[Entry; 4]>>,
}

impl TranspositionTable {
    /// Creates a new transposition table.
    ///
    /// The newly created table has the minimum possible size. Before
    /// using the new table for anything, `resize()` should be called
    /// on it, specifying the desired size.
    pub fn new() -> TranspositionTable {
        TranspositionTable {
            generation: 0,
            cluster_count: 1,
            table: UnsafeCell::new(vec![Default::default()]),
        }
    }

    /// Signals that a new search is about to begin.
    ///
    /// Internally, the transposition table maintains a generation
    /// counter that is used to implement an efficient replacement
    /// strategy. This method increases this counter.
    pub fn new_search(&mut self) {
        self.generation += 0b100;  // Lower 2 bits are used by bound type
        assert_eq!(self.generation & 0b11, 0);
    }

    /// Resizes the transpositon table.
    ///
    /// `size_mb` is the desired new size in Mbytes. All entries in
    /// the table will be lost.
    pub fn resize(&mut self, size_mb: usize) {
        // The cluster count should be in the form "2**n", so the best
        // we can do is to ensure that the new cluster count will be
        // as close as possible but no greater than the requested one.
        let requested_cluster_count = (size_mb * 1024 * 1024) / std::mem::size_of::<[Entry; 4]>();

        // First, make sure `requested_cluster_count` is exceeded.
        let mut new_cluster_count = 1;
        while requested_cluster_count >= new_cluster_count {
            new_cluster_count <<= 1;
        }

        // Then make one step back, being careful so that the new
        // cluster count is not zero.
        if new_cluster_count > 1 {
            new_cluster_count >>= 1;
        } else {
            new_cluster_count = 1;
        }

        // Finally, reallocate the vector of clusters.
        if new_cluster_count != self.cluster_count {
            self.cluster_count = new_cluster_count;
            self.table = UnsafeCell::new(vec![Default::default(); new_cluster_count]);
        }
    }

    /// Clears the transpositon table.
    ///
    /// All remaining entries in the table will be removed.
    pub fn clear(&mut self) {
        self.table = UnsafeCell::new(vec![Default::default(); self.cluster_count]);
    }

    /// Probes for data by a specific key.
    #[inline]
    pub fn probe(&self, key: u64) -> Option<EntryData> {
        let cluster = unsafe { self.cluster_mut(key) };
        for entry in cluster.iter_mut() {
            if entry.key ^ entry.data_u64() == key {
                // If `key` and `data` were written simultaneously by
                // different search instances with different keys,
                // this will yield in a mismatch of the above
                // comparison (except for the rare and inherent key
                // collisions).
                entry.update_generation(self.generation);
                return Some(entry.data);
            }
        }
        None
    }

    /// Stores data by a specific key.
    ///
    /// After being stored, the data might be retrieved by
    /// `probe(key)`. This is not guaranteed though, because in the
    /// meantime it might have been overwritten.
    #[inline]
    pub fn store(&self, key: u64, mut data: EntryData) {
        // `store` and `probe` jointly implement a clever lock-less
        // hashing method. Rather than to store two disjoint items,
        // the key is stored xored with data, while data is stored
        // additionally as usual.

        data.gen_bound |= self.generation;  // Sets the generation.
        let mut cluster = unsafe { self.cluster_mut(key) };
        let mut replace_index = 0;
        let mut replace_score = 0xff;
        for (i, entry) in cluster.iter_mut().enumerate() {
            // Check if this is an empty slot, or an old entry for the
            // same key. If this this is the case we will use this
            // slot for the new entry.
            if entry.key == 0 || entry.key ^ entry.data_u64() == key {
                if data.move16 == 0 {
                    data.move16 = entry.data.move16;  // Preserve any existing move.
                }
                replace_index = i;
                break;
            }
            // If we can not find empty/old slot, the replaced entry
            // will be the entry with the lowest score.
            let entry_score = self.calc_score(entry);
            if entry_score < replace_score {
                replace_index = i;
                replace_score = entry_score;
            }
        }
        unsafe {
            cluster.get_unchecked_mut(replace_index).key = key ^ transmute::<EntryData, u64>(data);
            cluster.get_unchecked_mut(replace_index).data = data;
        }
    }

    // A helper method for `store`.
    //
    // Implements our replacement strategy. Should return higher
    // values for the entries that are move likely to save CPU work in
    // the future.
    #[inline]
    fn calc_score(&self, entry: &Entry) -> u8 {
        (if entry.generation() == self.generation {
            128
        } else {
            0
        }) + entry.data.depth
    }

    // A helper method for `probe` and `store`.
    #[inline]
    unsafe fn cluster_mut(&self, key: u64) -> &mut [Entry; 4] {
        let cluster_index = (key & (self.cluster_count - 1) as u64) as usize;
        self.table.get().as_mut().unwrap().get_unchecked_mut(cluster_index)
    }
}

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

    #[test]
    fn test_cluster_size() {
        assert_eq!(std::mem::size_of::<[Entry; 4]>(), 64);
        assert_eq!(std::mem::size_of::<Entry>(), 16);
    }

    #[test]
    fn test_tt_resize() {
        let mut tt = TranspositionTable::new();
        assert_eq!(unsafe { &*tt.table.get() }.capacity(), 1);
        tt.resize(1);
        assert_eq!(unsafe { &*tt.table.get() }.capacity(),
                   1024 * 1024 / std::mem::size_of::<[Entry; 4]>());
        tt.clear();
    }

    #[test]
    fn test_store_and_probe() {
        let mut tt = TranspositionTable::new();
        assert!(tt.probe(1).is_none());
        let data = EntryData::new(0, 0, 100, 666, 0);
        assert_eq!(data.depth(), 100);
        assert_eq!(data.move16(), 666);
        tt.store(1, data);
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        tt.store(1, EntryData::new(0, 0, 100, 666, 0));
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(1).unwrap().move16(), 666);
        for i in 2..100 {
            tt.store(i, EntryData::new(i as i16, 0, i as u8, i as u16, i as i16));
        }
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(99).unwrap().depth(), 99);
        assert_eq!(tt.probe(98).unwrap().depth(), 98);
        assert_eq!(tt.probe(97).unwrap().depth(), 97);
        tt.clear();
        assert!(tt.probe(1).is_none());
        tt.store(1, data);
        tt.new_search();
        tt.probe(1);
        assert!(tt.probe(1).is_some());
    }
}
<|endoftext|>


<commit_before>#![feature(test)]
#![cfg_attr(test, deny(warnings))]

extern crate futures;
extern crate test;
extern crate tokio_sync;

mod tokio {
    use futures::{future, Async, Future, Sink, Stream};
    use std::thread;
    use test::{self, Bencher};
    use tokio_sync::mpsc::*;

    #[bench]
    fn bounded_new(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&channel::<i32>(1_000));
        })
    }

    #[bench]
    fn unbounded_new(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&unbounded_channel::<i32>());
        })
    }

    #[bench]
    fn send_one_message(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1_000);

            // Send
            tx.try_send(1).unwrap();

            // Receive
            assert_eq!(Async::Ready(Some(1)), rx.poll().unwrap());
        })
    }

    #[bench]
    fn bounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = channel::<i32>(1_000);
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(1);
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_not_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(1);
        tx.try_send(1).unwrap();
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded_channel::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready_x5(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded_channel::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_uncontended_1(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1_000);

            for i in 0..1000 {
                tx.try_send(i).unwrap();
                // No need to create a task, because poll is not going to park.
                assert_eq!(Async::Ready(Some(i)), rx.poll().unwrap());
            }
        })
    }

    #[bench]
    fn bounded_uncontended_2(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1000);

            for i in 0..1000 {
                tx.try_send(i).unwrap();
            }

            for i in 0..1000 {
                // No need to create a task, because poll is not going to park.
                assert_eq!(Async::Ready(Some(i)), rx.poll().unwrap());
            }
        })
    }

    #[bench]
    fn contended_unbounded_tx(b: &mut Bencher) {
        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..4 {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for mut tx in rx.iter() {
                    for i in 0..1_000 {
                        tx.try_send(i).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            // TODO make unbounded
            let (tx, rx) = channel::<i32>(1_000_000);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(4 * 1_000);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

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

    #[bench]
    fn contended_bounded_tx(b: &mut Bencher) {
        const THREADS: usize = 4;
        const ITERS: usize = 100;

        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..THREADS {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for tx in rx.iter() {
                    let mut tx = tx.wait();
                    for i in 0..ITERS {
                        tx.send(i as i32).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            let (tx, rx) = channel::<i32>(1);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(THREADS * ITERS);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

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

mod legacy {
    use futures::sync::mpsc::*;
    use futures::{future, Async, Future, Sink, Stream};
    use std::thread;
    use test::{self, Bencher};

    #[bench]
    fn bounded_new(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&channel::<i32>(1_000));
        })
    }

    #[bench]
    fn unbounded_new(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&unbounded::<i32>());
        })
    }

    #[bench]
    fn send_one_message(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1_000);

            // Send
            tx.try_send(1).unwrap();

            // Receive
            assert_eq!(Ok(Async::Ready(Some(1))), rx.poll());
        })
    }

    #[bench]
    fn bounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = channel::<i32>(1_000);
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(0);
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_not_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(0);
        tx.try_send(1).unwrap();
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready_x5(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_uncontended_1(b: &mut Bencher) {
        b.iter(|| {
            let (tx, mut rx) = unbounded();

            for i in 0..1000 {
                UnboundedSender::unbounded_send(&tx, i).expect("send");
                // No need to create a task, because poll is not going to park.
                assert_eq!(Ok(Async::Ready(Some(i))), rx.poll());
            }
        })
    }

    #[bench]
    fn unbounded_uncontended_2(b: &mut Bencher) {
        b.iter(|| {
            let (tx, mut rx) = unbounded();

            for i in 0..1000 {
                UnboundedSender::unbounded_send(&tx, i).expect("send");
            }

            for i in 0..1000 {
                // No need to create a task, because poll is not going to park.
                assert_eq!(Ok(Async::Ready(Some(i))), rx.poll());
            }
        })
    }

    #[bench]
    fn multi_thread_unbounded_tx(b: &mut Bencher) {
        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..4 {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for mut tx in rx.iter() {
                    for i in 0..1_000 {
                        tx.try_send(i).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            let (tx, rx) = channel::<i32>(1_000_000);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(4 * 1_000);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

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

    #[bench]
    fn contended_bounded_tx(b: &mut Bencher) {
        const THREADS: usize = 4;
        const ITERS: usize = 100;

        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..THREADS {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for tx in rx.iter() {
                    let mut tx = tx.wait();
                    for i in 0..ITERS {
                        tx.send(i as i32).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            let (tx, rx) = channel::<i32>(1);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(THREADS * ITERS);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

        for th in threads {
            th.join().unwrap();
        }
    }
}
<commit_msg>sync: add mpsc benchmarks of small, medium, and large message types (#982)<commit_after>#![feature(test)]
#![cfg_attr(test, deny(warnings))]

extern crate futures;
extern crate test;
extern crate tokio_sync;

type Medium = [usize; 64];
type Large = [Medium; 64];

mod tokio {
    use futures::{future, Async, Future, Sink, Stream};
    use std::thread;
    use test::{self, Bencher};
    use tokio_sync::mpsc::*;

    #[bench]
    fn bounded_new_medium(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&channel::<super::Medium>(1_000));
        })
    }

    #[bench]
    fn unbounded_new_medium(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&unbounded_channel::<super::Medium>());
        })
    }
    #[bench]
    fn bounded_new_large(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&channel::<super::Large>(1_000));
        })
    }

    #[bench]
    fn unbounded_new_large(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&unbounded_channel::<super::Large>());
        })
    }

    #[bench]
    fn send_one_message(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1_000);

            // Send
            tx.try_send(1).unwrap();

            // Receive
            assert_eq!(Async::Ready(Some(1)), rx.poll().unwrap());
        })
    }

    #[bench]
    fn send_one_message_large(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel::<super::Large>(1_000);

            // Send
            let _ = tx.try_send([[0; 64]; 64]);

            // Receive
            let _ = test::black_box(&rx.poll());
        })
    }

    #[bench]
    fn bounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = channel::<i32>(1_000);
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(1);
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_not_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(1);
        tx.try_send(1).unwrap();
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded_channel::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready_x5(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded_channel::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_uncontended_1(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1_000);

            for i in 0..1000 {
                tx.try_send(i).unwrap();
                // No need to create a task, because poll is not going to park.
                assert_eq!(Async::Ready(Some(i)), rx.poll().unwrap());
            }
        })
    }

    #[bench]
    fn bounded_uncontended_1_large(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel::<super::Large>(1_000);

            for i in 0..1000 {
                let _ = tx.try_send([[i; 64]; 64]);
                // No need to create a task, because poll is not going to park.
                let _ = test::black_box(&rx.poll());
            }
        })
    }

    #[bench]
    fn bounded_uncontended_2(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1000);

            for i in 0..1000 {
                tx.try_send(i).unwrap();
            }

            for i in 0..1000 {
                // No need to create a task, because poll is not going to park.
                assert_eq!(Async::Ready(Some(i)), rx.poll().unwrap());
            }
        })
    }

    #[bench]
    fn contended_unbounded_tx(b: &mut Bencher) {
        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..4 {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for mut tx in rx.iter() {
                    for i in 0..1_000 {
                        tx.try_send(i).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            // TODO make unbounded
            let (tx, rx) = channel::<i32>(1_000_000);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(4 * 1_000);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

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

    #[bench]
    fn contended_bounded_tx(b: &mut Bencher) {
        const THREADS: usize = 4;
        const ITERS: usize = 100;

        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..THREADS {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for tx in rx.iter() {
                    let mut tx = tx.wait();
                    for i in 0..ITERS {
                        tx.send(i as i32).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            let (tx, rx) = channel::<i32>(1);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(THREADS * ITERS);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

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

mod legacy {
    use futures::sync::mpsc::*;
    use futures::{future, Async, Future, Sink, Stream};
    use std::thread;
    use test::{self, Bencher};

    #[bench]
    fn bounded_new_medium(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&channel::<super::Medium>(1_000));
        })
    }

    #[bench]
    fn unbounded_new_medium(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&unbounded::<super::Medium>());
        })
    }

    #[bench]
    fn bounded_new_large(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&channel::<super::Large>(1_000));
        })
    }

    #[bench]
    fn unbounded_new_large(b: &mut Bencher) {
        b.iter(|| {
            let _ = test::black_box(&unbounded::<super::Large>());
        })
    }

    #[bench]
    fn send_one_message(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel(1_000);

            // Send
            tx.try_send(1).unwrap();

            // Receive
            assert_eq!(Ok(Async::Ready(Some(1))), rx.poll());
        })
    }

    #[bench]
    fn send_one_message_large(b: &mut Bencher) {
        b.iter(|| {
            let (mut tx, mut rx) = channel::<super::Large>(1_000);

            // Send
            let _ = tx.try_send([[0; 64]; 64]);

            // Receive
            let _ = test::black_box(&rx.poll());
        })
    }

    #[bench]
    fn bounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = channel::<i32>(1_000);
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(0);
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn bounded_tx_poll_not_ready(b: &mut Bencher) {
        let (mut tx, _rx) = channel::<i32>(0);
        tx.try_send(1).unwrap();
        b.iter(|| {
            future::lazy(|| {
                assert!(tx.poll_ready().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_rx_not_ready_x5(b: &mut Bencher) {
        let (_tx, mut rx) = unbounded::<i32>();
        b.iter(|| {
            future::lazy(|| {
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());
                assert!(rx.poll().unwrap().is_not_ready());

                Ok::<_, ()>(())
            })
            .wait()
            .unwrap();
        })
    }

    #[bench]
    fn unbounded_uncontended_1(b: &mut Bencher) {
        b.iter(|| {
            let (tx, mut rx) = unbounded();

            for i in 0..1000 {
                UnboundedSender::unbounded_send(&tx, i).expect("send");
                // No need to create a task, because poll is not going to park.
                assert_eq!(Ok(Async::Ready(Some(i))), rx.poll());
            }
        })
    }

    #[bench]
    fn unbounded_uncontended_1_large(b: &mut Bencher) {
        b.iter(|| {
            let (tx, mut rx) = unbounded::<super::Large>();

            for i in 0..1000 {
                let _ = UnboundedSender::unbounded_send(&tx, [[i; 64]; 64]);
                // No need to create a task, because poll is not going to park.
                let _ = test::black_box(&rx.poll());
            }
        })
    }

    #[bench]
    fn unbounded_uncontended_2(b: &mut Bencher) {
        b.iter(|| {
            let (tx, mut rx) = unbounded();

            for i in 0..1000 {
                UnboundedSender::unbounded_send(&tx, i).expect("send");
            }

            for i in 0..1000 {
                // No need to create a task, because poll is not going to park.
                assert_eq!(Ok(Async::Ready(Some(i))), rx.poll());
            }
        })
    }

    #[bench]
    fn multi_thread_unbounded_tx(b: &mut Bencher) {
        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..4 {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for mut tx in rx.iter() {
                    for i in 0..1_000 {
                        tx.try_send(i).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            let (tx, rx) = channel::<i32>(1_000_000);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(4 * 1_000);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

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

    #[bench]
    fn contended_bounded_tx(b: &mut Bencher) {
        const THREADS: usize = 4;
        const ITERS: usize = 100;

        let mut threads = vec![];
        let mut txs = vec![];

        for _ in 0..THREADS {
            let (tx, rx) = ::std::sync::mpsc::channel::<Sender<i32>>();
            txs.push(tx);

            threads.push(thread::spawn(move || {
                for tx in rx.iter() {
                    let mut tx = tx.wait();
                    for i in 0..ITERS {
                        tx.send(i as i32).unwrap();
                    }
                }
            }));
        }

        b.iter(|| {
            let (tx, rx) = channel::<i32>(1);

            for th in &txs {
                th.send(tx.clone()).unwrap();
            }

            drop(tx);

            let rx = rx.wait().take(THREADS * ITERS);

            for v in rx {
                let _ = test::black_box(v);
            }
        });

        drop(txs);

        for th in threads {
            th.join().unwrap();
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::fs::File;
use std::io::Read;

const MEMORY_SIZE: usize = 1024 * 1024;

type Register = (usize, &'static str);

trait RegisterHelpers {
    fn addr(&self) -> usize;
    fn name(&self) -> &'static str;
}

impl RegisterHelpers for Register {
    fn addr(&self) -> usize {
        self.0
    }

    fn name(&self) -> &'static str {
        self.1
    }
}

const EAX: Register = (0, "EAX");
const ECX: Register = (1, "ECX");
const EDX: Register = (2, "EDX");
const EBX: Register = (3, "EBX");
const ESP: Register = (4, "ESP");
const EBP: Register = (5, "EBP");
const ESI: Register = (6, "ESI");
const EDI: Register = (7, "EDI");
const REGISTERS: [Register; 8] = [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI];

struct Emulator {
    registers: [u32; REGISTERS.len()],
    eflags: u32,
    memory: Vec<u8>,
    eip: u32,
}

impl Emulator {
    fn create(size: usize, eip: u32, esp: u32) -> Emulator {
        let mut regs = [0; REGISTERS.len()];
        regs[ESP.addr()] = esp;
        Emulator {
            registers: regs,
            memory: Vec::with_capacity(size),
            eflags: 0,
            eip: eip,
        }
    }

    fn dump_registers(&self) {
        for i in REGISTERS.iter() {
            println!("{} = {}", i.name(), self.registers[i.addr()]);
        }

        println!("EIP = {}", self.eip);
    }

    fn get_code8(&self, index: usize) -> u32 {
        self.memory[self.eip as usize + index] as u32
    }

    fn get_sign_code8(&self, index: usize) -> i32 {
        self.memory[self.eip as usize + index] as i32
    }

    fn get_code32(&self, index: usize) -> u32 {
        let mut ret: u32 = 0;
        for i in 0..4 {
            ret |= self.get_code8(index + i) << (i * 8)
        }
        return ret;
    }

    fn mov_r32_imm32(&self) {
    }

    fn short_jump(&self) {
    }
}

fn main() {

    let args: Vec<String> = env::args().collect();
    let mut buffer = String::new();

    if args.len() != 2 {
        println!("usage: vm filename");
        return;
    }

    let filename: & String = & args[1];

    match File::open(filename) {
        Ok(mut file) => match file.read_to_string(&mut buffer) {
            Ok(_) => {}
            Err(e) => {
                panic!(e);
            }
        },
        Err(e) => {
            panic!(e);
        }
    };
    println!("hello {:?}", buffer);
}
<commit_msg>Update vm.<commit_after>use std::env;
use std::fs::File;
use std::io::Read;

const MEMORY_SIZE: usize = 1024 * 1024;

type Register = (usize, &'static str);

trait RegisterHelpers {
    fn addr(&self) -> usize;
    fn name(&self) -> &'static str;
}

impl RegisterHelpers for Register {
    fn addr(&self) -> usize {
        self.0
    }

    fn name(&self) -> &'static str {
        self.1
    }
}

const EAX: Register = (0, "EAX");
const ECX: Register = (1, "ECX");
const EDX: Register = (2, "EDX");
const EBX: Register = (3, "EBX");
const ESP: Register = (4, "ESP");
const EBP: Register = (5, "EBP");
const ESI: Register = (6, "ESI");
const EDI: Register = (7, "EDI");
const REGISTERS: [Register; 8] = [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI];

struct Emulator {
    registers: [u32; REGISTERS.len()],
    eflags: u32,
    memory: Vec<u8>,
    eip: u32,
}

impl Emulator {
    fn create(size: usize, eip: u32, esp: u32) -> Emulator {
        let mut regs = [0; REGISTERS.len()];
        regs[ESP.addr()] = esp;
        Emulator {
            registers: regs,
            memory: Vec::with_capacity(size),
            eflags: 0,
            eip: eip,
        }
    }

    fn dump_registers(&self) {
        for i in REGISTERS.iter() {
            println!("{} = {}", i.name(), self.registers[i.addr()]);
        }

        println!("EIP = {}", self.eip);
    }

    fn get_code8(&self, index: usize) -> u32 {
        self.memory[self.eip as usize + index] as u32
    }

    fn get_sign_code8(&self, index: usize) -> i32 {
        self.memory[self.eip as usize + index] as i32
    }

    fn get_code32(&self, index: usize) -> u32 {
        let mut ret: u32 = 0;
        for i in 0..4 {
            ret |= self.get_code8(index + i) << (i * 8)
        }
        return ret;
    }

    fn mov_r32_imm32(&self) {
    }

    fn short_jump(&self) {
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        println!("usage: vm filename");
        return;
    }

    let mut emu = Emulator::create(MEMORY_SIZE, 0x0000, 0x7c00);

    let filename: & String = & args[1];
    let mut buffer = String::new();

    let mut f = File::open(filename).unwrap();

    for byte in f.bytes() {
        emu.memory.push(byte.unwrap());
    }

    /*
    match File::open(filename) {
        Ok(mut file) => match file.read_to_string(&mut buffer) {
            Ok(_) => {}
            Err(e) => {
                panic!(e);
            }
        },
        Err(e) => {
            panic!(e);
        }
    };

    println!("hello {:?}", buffer);
    */
}
<|endoftext|>


<commit_before>use actix::prelude::*;
use actix_web::*;
use actors::{ForwardA2AMsg, GetEndpoint};
use actors::forward_agent::ForwardAgent;
use bytes::Bytes;
use domain::config::AppConfig;
use futures::*;

const MAX_PAYLOAD_SIZE: usize = 105_906_176;

pub struct AppState {
    pub forward_agent: Addr<ForwardAgent>,
}

pub fn new(config: AppConfig, forward_agent: Addr<ForwardAgent>) -> App<AppState> {
    App::with_state(AppState { forward_agent })
        .prefix(config.prefix.as_ref())
        .middleware(middleware::Logger::default()) // enable logger
        .resource("", |r| r.method(http::Method::GET).with(_get_endpoint_details))
        .resource("/msg", |r| r.method(http::Method::POST).with(_forward_message))
}

fn _get_endpoint_details(state: State<AppState>) -> FutureResponse<HttpResponse> {
    state.forward_agent
        .send(GetEndpoint {})
        .from_err()
        .map(|res| match res {
            Ok(endpoint) => HttpResponse::Ok().json(&endpoint),
            Err(err) => HttpResponse::InternalServerError().body(format!("{:?}", err)).into(), // FIXME: Better error
        })
        .responder()
}

fn _forward_message((state, req): (State<AppState>, HttpRequest<AppState>)) -> FutureResponse<HttpResponse> {
    req
        .body()
        .limit(MAX_PAYLOAD_SIZE)
        .from_err()
        .and_then(move |body| {
            state.forward_agent
                .send(ForwardA2AMsg(body.to_vec()))
                .from_err()
                .and_then(|res| match res {
                    Ok(msg) => Ok(Bytes::from(msg).into()),
                    Err(err) => Ok(HttpResponse::InternalServerError().body(format!("{:?}", err)).into()), // FIXME: Better error
                })
        })
        .responder()
}

<commit_msg>remove strange as_ref()<commit_after>use actix::prelude::*;
use actix_web::*;
use actors::{ForwardA2AMsg, GetEndpoint};
use actors::forward_agent::ForwardAgent;
use bytes::Bytes;
use domain::config::AppConfig;
use futures::*;

const MAX_PAYLOAD_SIZE: usize = 105_906_176;

pub struct AppState {
    pub forward_agent: Addr<ForwardAgent>,
}

pub fn new(config: AppConfig, forward_agent: Addr<ForwardAgent>) -> App<AppState> {
    App::with_state(AppState { forward_agent })
        .prefix(config.prefix)
        .middleware(middleware::Logger::default()) // enable logger
        .resource("", |r| r.method(http::Method::GET).with(_get_endpoint_details))
        .resource("/msg", |r| r.method(http::Method::POST).with(_forward_message))
}

fn _get_endpoint_details(state: State<AppState>) -> FutureResponse<HttpResponse> {
    state.forward_agent
        .send(GetEndpoint {})
        .from_err()
        .map(|res| match res {
            Ok(endpoint) => HttpResponse::Ok().json(&endpoint),
            Err(err) => HttpResponse::InternalServerError().body(format!("{:?}", err)).into(), // FIXME: Better error
        })
        .responder()
}

fn _forward_message((state, req): (State<AppState>, HttpRequest<AppState>)) -> FutureResponse<HttpResponse> {
    req
        .body()
        .limit(MAX_PAYLOAD_SIZE)
        .from_err()
        .and_then(move |body| {
            state.forward_agent
                .send(ForwardA2AMsg(body.to_vec()))
                .from_err()
                .and_then(|res| match res {
                    Ok(msg) => Ok(Bytes::from(msg).into()),
                    Err(err) => Ok(HttpResponse::InternalServerError().body(format!("{:?}", err)).into()), // FIXME: Better error
                })
        })
        .responder()
}

<|endoftext|>