<commit_before>use crate::path::Path;
use serde::{de, ser};
use std::error;
use std::fmt::{self, Debug, Display};
use std::io;
use std::result;
use std::str;
use std::string;
use yaml_rust::emitter;
use yaml_rust::scanner::{self, Marker, ScanError};

/// An error that happened serializing or deserializing YAML data.
pub struct Error(Box<ErrorImpl>);

/// Alias for a `Result` with the error type `serde_yaml::Error`.
pub type Result<T> = result::Result<T, Error>;

#[derive(Debug)]
pub enum ErrorImpl {
    Message(String, Option<Pos>),

    Emit(emitter::EmitError),
    Scan(scanner::ScanError),
    Io(io::Error),
    Utf8(str::Utf8Error),
    FromUtf8(string::FromUtf8Error),

    EndOfStream,
    MoreThanOneDocument,
    RecursionLimitExceeded,
}

#[derive(Debug)]
pub struct Pos {
    marker: Marker,
    path: String,
}

/// The input location that an error occured.
#[derive(Debug)]
pub struct Location {
    index: usize,
    line: usize,
    column: usize,
}

impl Location {
    /// The byte index of the error
    pub fn index(&self) -> usize {
        self.index
    }

    /// The line of the error
    pub fn line(&self) -> usize {
        self.line
    }

    /// The column of the error
    pub fn column(&self) -> usize {
        self.column
    }

    // This is to keep decoupled with the yaml crate
    #[doc(hidden)]
    fn from_marker(marker: &Marker) -> Self {
        Location {
            // `col` returned from the `yaml` crate is 0-indexed but all error messages add + 1 to this value
            column: marker.col() + 1,
            index: marker.index(),
            line: marker.line(),
        }
    }
}

impl Error {
    /// Returns the Location from the error if one exists.
    ///
    /// Not all types of errors have a location so this can return `None`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::{Value, Error};
    /// #
    /// // The `@` character as the first character makes this invalid yaml
    /// let invalid_yaml: Result<Value, Error> = serde_yaml::from_str("@invalid_yaml");
    ///
    /// let location = invalid_yaml.unwrap_err().location().unwrap();
    ///
    /// assert_eq!(location.line(), 1);
    /// assert_eq!(location.column(), 1);
    /// ```
    pub fn location(&self) -> Option<Location> {
        match self.0.as_ref() {
            ErrorImpl::Message(_, Some(pos)) => Some(Location::from_marker(&pos.marker)),
            ErrorImpl::Scan(scan) => Some(Location::from_marker(scan.marker())),
            _ => None,
        }
    }
}

pub(crate) fn end_of_stream() -> Error {
    Error(Box::new(ErrorImpl::EndOfStream))
}

pub(crate) fn more_than_one_document() -> Error {
    Error(Box::new(ErrorImpl::MoreThanOneDocument))
}

pub(crate) fn io(err: io::Error) -> Error {
    Error(Box::new(ErrorImpl::Io(err)))
}

pub(crate) fn emitter(err: emitter::EmitError) -> Error {
    Error(Box::new(ErrorImpl::Emit(err)))
}

pub(crate) fn scanner(err: scanner::ScanError) -> Error {
    Error(Box::new(ErrorImpl::Scan(err)))
}

pub(crate) fn str_utf8(err: str::Utf8Error) -> Error {
    Error(Box::new(ErrorImpl::Utf8(err)))
}

pub(crate) fn string_utf8(err: string::FromUtf8Error) -> Error {
    Error(Box::new(ErrorImpl::FromUtf8(err)))
}

pub(crate) fn recursion_limit_exceeded() -> Error {
    Error(Box::new(ErrorImpl::RecursionLimitExceeded))
}

pub(crate) fn fix_marker(mut error: Error, marker: Marker, path: Path) -> Error {
    if let ErrorImpl::Message(_, none @ None) = error.0.as_mut() {
        *none = Some(Pos {
            marker,
            path: path.to_string(),
        });
    }
    error
}

impl error::Error for Error {
    // TODO: deprecated, remove in next major version.
    #[allow(deprecated)]
    fn description(&self) -> &str {
        match self.0.as_ref() {
            ErrorImpl::Message(msg, _) => msg,
            ErrorImpl::Emit(_) => "emit error",
            ErrorImpl::Scan(_) => "scan error",
            ErrorImpl::Io(err) => err.description(),
            ErrorImpl::Utf8(err) => err.description(),
            ErrorImpl::FromUtf8(err) => err.description(),
            ErrorImpl::EndOfStream => "EOF while parsing a value",
            ErrorImpl::MoreThanOneDocument => {
                "deserializing from YAML containing more than one document is not supported"
            }
            ErrorImpl::RecursionLimitExceeded => "recursion limit exceeded",
        }
    }

    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match self.0.as_ref() {
            ErrorImpl::Scan(err) => Some(err),
            ErrorImpl::Io(err) => Some(err),
            ErrorImpl::Utf8(err) => Some(err),
            ErrorImpl::FromUtf8(err) => Some(err),
            _ => None,
        }
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0.as_ref() {
            ErrorImpl::Message(msg, None) => Display::fmt(msg, f),
            ErrorImpl::Message(msg, Some(Pos { marker, path })) => {
                if path == "." {
                    write!(f, "{}", ScanError::new(*marker, msg))
                } else {
                    write!(f, "{}: {}", path, ScanError::new(*marker, msg))
                }
            }
            ErrorImpl::Emit(emitter::EmitError::FmtError(_)) => f.write_str("yaml-rust fmt error"),
            ErrorImpl::Emit(emitter::EmitError::BadHashmapKey) => f.write_str("bad hash map key"),
            ErrorImpl::Scan(err) => Display::fmt(err, f),
            ErrorImpl::Io(err) => Display::fmt(err, f),
            ErrorImpl::Utf8(err) => Display::fmt(err, f),
            ErrorImpl::FromUtf8(err) => Display::fmt(err, f),
            ErrorImpl::EndOfStream => f.write_str("EOF while parsing a value"),
            ErrorImpl::MoreThanOneDocument => f.write_str(
                "deserializing from YAML containing more than one document is not supported",
            ),
            ErrorImpl::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
        }
    }
}

// Remove two layers of verbosity from the debug representation. Humans often
// end up seeing this representation because it is what unwrap() shows.
impl Debug for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.0.as_ref() {
            ErrorImpl::Message(msg, pos) => formatter
                .debug_tuple("Message")
                .field(msg)
                .field(pos)
                .finish(),
            ErrorImpl::Emit(emit) => formatter.debug_tuple("Emit").field(emit).finish(),
            ErrorImpl::Scan(scan) => formatter.debug_tuple("Scan").field(scan).finish(),
            ErrorImpl::Io(io) => formatter.debug_tuple("Io").field(io).finish(),
            ErrorImpl::Utf8(utf8) => formatter.debug_tuple("Utf8").field(utf8).finish(),
            ErrorImpl::FromUtf8(from_utf8) => {
                formatter.debug_tuple("FromUtf8").field(from_utf8).finish()
            }
            ErrorImpl::EndOfStream => formatter.debug_tuple("EndOfStream").finish(),
            ErrorImpl::MoreThanOneDocument => formatter.debug_tuple("MoreThanOneDocument").finish(),
            ErrorImpl::RecursionLimitExceeded => {
                formatter.debug_tuple("RecursionLimitExceeded").finish()
            }
        }
    }
}

impl ser::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
    }
}

impl de::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
    }
}
<commit_msg>Factor out error trait impls to work without outer Error wrapper<commit_after>use crate::path::Path;
use serde::{de, ser};
use std::error;
use std::fmt::{self, Debug, Display};
use std::io;
use std::result;
use std::str;
use std::string;
use yaml_rust::emitter;
use yaml_rust::scanner::{self, Marker, ScanError};

/// An error that happened serializing or deserializing YAML data.
pub struct Error(Box<ErrorImpl>);

/// Alias for a `Result` with the error type `serde_yaml::Error`.
pub type Result<T> = result::Result<T, Error>;

#[derive(Debug)]
pub enum ErrorImpl {
    Message(String, Option<Pos>),

    Emit(emitter::EmitError),
    Scan(scanner::ScanError),
    Io(io::Error),
    Utf8(str::Utf8Error),
    FromUtf8(string::FromUtf8Error),

    EndOfStream,
    MoreThanOneDocument,
    RecursionLimitExceeded,
}

#[derive(Debug)]
pub struct Pos {
    marker: Marker,
    path: String,
}

/// The input location that an error occured.
#[derive(Debug)]
pub struct Location {
    index: usize,
    line: usize,
    column: usize,
}

impl Location {
    /// The byte index of the error
    pub fn index(&self) -> usize {
        self.index
    }

    /// The line of the error
    pub fn line(&self) -> usize {
        self.line
    }

    /// The column of the error
    pub fn column(&self) -> usize {
        self.column
    }

    // This is to keep decoupled with the yaml crate
    #[doc(hidden)]
    fn from_marker(marker: &Marker) -> Self {
        Location {
            // `col` returned from the `yaml` crate is 0-indexed but all error messages add + 1 to this value
            column: marker.col() + 1,
            index: marker.index(),
            line: marker.line(),
        }
    }
}

impl Error {
    /// Returns the Location from the error if one exists.
    ///
    /// Not all types of errors have a location so this can return `None`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::{Value, Error};
    /// #
    /// // The `@` character as the first character makes this invalid yaml
    /// let invalid_yaml: Result<Value, Error> = serde_yaml::from_str("@invalid_yaml");
    ///
    /// let location = invalid_yaml.unwrap_err().location().unwrap();
    ///
    /// assert_eq!(location.line(), 1);
    /// assert_eq!(location.column(), 1);
    /// ```
    pub fn location(&self) -> Option<Location> {
        match self.0.as_ref() {
            ErrorImpl::Message(_, Some(pos)) => Some(Location::from_marker(&pos.marker)),
            ErrorImpl::Scan(scan) => Some(Location::from_marker(scan.marker())),
            _ => None,
        }
    }
}

pub(crate) fn end_of_stream() -> Error {
    Error(Box::new(ErrorImpl::EndOfStream))
}

pub(crate) fn more_than_one_document() -> Error {
    Error(Box::new(ErrorImpl::MoreThanOneDocument))
}

pub(crate) fn io(err: io::Error) -> Error {
    Error(Box::new(ErrorImpl::Io(err)))
}

pub(crate) fn emitter(err: emitter::EmitError) -> Error {
    Error(Box::new(ErrorImpl::Emit(err)))
}

pub(crate) fn scanner(err: scanner::ScanError) -> Error {
    Error(Box::new(ErrorImpl::Scan(err)))
}

pub(crate) fn str_utf8(err: str::Utf8Error) -> Error {
    Error(Box::new(ErrorImpl::Utf8(err)))
}

pub(crate) fn string_utf8(err: string::FromUtf8Error) -> Error {
    Error(Box::new(ErrorImpl::FromUtf8(err)))
}

pub(crate) fn recursion_limit_exceeded() -> Error {
    Error(Box::new(ErrorImpl::RecursionLimitExceeded))
}

pub(crate) fn fix_marker(mut error: Error, marker: Marker, path: Path) -> Error {
    if let ErrorImpl::Message(_, none @ None) = error.0.as_mut() {
        *none = Some(Pos {
            marker,
            path: path.to_string(),
        });
    }
    error
}

impl error::Error for Error {
    // TODO: deprecated, remove in next major version.
    fn description(&self) -> &str {
        self.0.description()
    }

    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        self.0.source()
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.display(f)
    }
}

// Remove two layers of verbosity from the debug representation. Humans often
// end up seeing this representation because it is what unwrap() shows.
impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.debug(f)
    }
}

impl ser::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
    }
}

impl de::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
    }
}

impl ErrorImpl {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        match self {
            ErrorImpl::Message(msg, _) => msg,
            ErrorImpl::Emit(_) => "emit error",
            ErrorImpl::Scan(_) => "scan error",
            ErrorImpl::Io(err) => error::Error::description(err),
            ErrorImpl::Utf8(err) => error::Error::description(err),
            ErrorImpl::FromUtf8(err) => error::Error::description(err),
            ErrorImpl::EndOfStream => "EOF while parsing a value",
            ErrorImpl::MoreThanOneDocument => {
                "deserializing from YAML containing more than one document is not supported"
            }
            ErrorImpl::RecursionLimitExceeded => "recursion limit exceeded",
        }
    }

    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match self {
            ErrorImpl::Scan(err) => Some(err),
            ErrorImpl::Io(err) => Some(err),
            ErrorImpl::Utf8(err) => Some(err),
            ErrorImpl::FromUtf8(err) => Some(err),
            _ => None,
        }
    }

    fn display(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            ErrorImpl::Message(msg, None) => Display::fmt(msg, f),
            ErrorImpl::Message(msg, Some(Pos { marker, path })) => {
                if path == "." {
                    write!(f, "{}", ScanError::new(*marker, msg))
                } else {
                    write!(f, "{}: {}", path, ScanError::new(*marker, msg))
                }
            }
            ErrorImpl::Emit(emitter::EmitError::FmtError(_)) => f.write_str("yaml-rust fmt error"),
            ErrorImpl::Emit(emitter::EmitError::BadHashmapKey) => f.write_str("bad hash map key"),
            ErrorImpl::Scan(err) => Display::fmt(err, f),
            ErrorImpl::Io(err) => Display::fmt(err, f),
            ErrorImpl::Utf8(err) => Display::fmt(err, f),
            ErrorImpl::FromUtf8(err) => Display::fmt(err, f),
            ErrorImpl::EndOfStream => f.write_str("EOF while parsing a value"),
            ErrorImpl::MoreThanOneDocument => f.write_str(
                "deserializing from YAML containing more than one document is not supported",
            ),
            ErrorImpl::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
        }
    }

    fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            ErrorImpl::Message(msg, pos) => f.debug_tuple("Message").field(msg).field(pos).finish(),
            ErrorImpl::Emit(emit) => f.debug_tuple("Emit").field(emit).finish(),
            ErrorImpl::Scan(scan) => f.debug_tuple("Scan").field(scan).finish(),
            ErrorImpl::Io(io) => f.debug_tuple("Io").field(io).finish(),
            ErrorImpl::Utf8(utf8) => f.debug_tuple("Utf8").field(utf8).finish(),
            ErrorImpl::FromUtf8(from_utf8) => f.debug_tuple("FromUtf8").field(from_utf8).finish(),
            ErrorImpl::EndOfStream => f.debug_tuple("EndOfStream").finish(),
            ErrorImpl::MoreThanOneDocument => f.debug_tuple("MoreThanOneDocument").finish(),
            ErrorImpl::RecursionLimitExceeded => f.debug_tuple("RecursionLimitExceeded").finish(),
        }
    }
}
<|endoftext|>


<commit_before>extern crate cursive;

use cursive::{Cursive, Printer};
use cursive::traits::*;
use cursive::vec::Vec2;
use std::collections::VecDeque;
use std::iter::Chain;
use std::slice::Iter;

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    // As usual, create the Cursive root
    let mut siv = Cursive::new();

    // We want to refresh the page even when no input is given.
    siv.set_fps(10);
    siv.add_global_callback('q', |s| s.quit());

    // A channel will communicate data from our running task to the UI.
    let (tx, rx) = mpsc::channel();

    // Generate data in a separate thread.
    thread::spawn(move || { generate_logs(&tx); });

    // And sets the view to read from the other end of the channel.
    siv.add_layer(BufferView::new(200, rx).full_screen());

    siv.run();
}

// We will only simulate log generation here.
// In real life, this may come from a running task, a separate process, ...
fn generate_logs(tx: &mpsc::Sender<String>) {
    let mut i = 1;
    loop {
        let line = format!("Interesting log line {}", i);
        i += 1;
        // The send will fail when the other side is dropped.
        // (When the application ends).
        if tx.send(line).is_err() {
            return;
        }
        thread::sleep(Duration::from_millis(30));
    }
}

// Let's define a buffer view, that shows the last lines from a stream.
struct BufferView {
    // We'll use a ring buffer
    buffer: VecDeque<String>,
    // Receiving end of the stream
    rx: mpsc::Receiver<String>,
}

impl BufferView {
    // Creates a new view with the given buffer size
    fn new(size: usize, rx: mpsc::Receiver<String>) -> Self {
        let mut buffer = VecDeque::new();
        buffer.resize(size, String::new());
        BufferView {
            rx: rx,
            buffer: buffer,
        }
    }

    // Reads available data from the stream into the buffer
    fn update(&mut self) {
        // Add each available line to the end of the buffer.
        while let Ok(line) = self.rx.try_recv() {
            self.buffer.push_back(line);
            self.buffer.pop_front();
        }
    }
}

impl View for BufferView {
    fn layout(&mut self, _: Vec2) {
        // Before drawing, we'll want to update the buffer
        self.update();
    }

    fn draw(&self, printer: &Printer) {
        // Print the end of the buffer
        for (i, line) in self.buffer
                .iter()
                .rev()
                .take(printer.size.y)
                .enumerate() {
            printer.print((0, printer.size.y - 1 - i), line);
        }
    }
}
<commit_msg>Remove unused imports<commit_after>extern crate cursive;

use cursive::{Cursive, Printer};
use cursive::traits::*;
use cursive::vec::Vec2;
use std::collections::VecDeque;

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    // As usual, create the Cursive root
    let mut siv = Cursive::new();

    // We want to refresh the page even when no input is given.
    siv.set_fps(10);
    siv.add_global_callback('q', |s| s.quit());

    // A channel will communicate data from our running task to the UI.
    let (tx, rx) = mpsc::channel();

    // Generate data in a separate thread.
    thread::spawn(move || { generate_logs(&tx); });

    // And sets the view to read from the other end of the channel.
    siv.add_layer(BufferView::new(200, rx).full_screen());

    siv.run();
}

// We will only simulate log generation here.
// In real life, this may come from a running task, a separate process, ...
fn generate_logs(tx: &mpsc::Sender<String>) {
    let mut i = 1;
    loop {
        let line = format!("Interesting log line {}", i);
        i += 1;
        // The send will fail when the other side is dropped.
        // (When the application ends).
        if tx.send(line).is_err() {
            return;
        }
        thread::sleep(Duration::from_millis(30));
    }
}

// Let's define a buffer view, that shows the last lines from a stream.
struct BufferView {
    // We'll use a ring buffer
    buffer: VecDeque<String>,
    // Receiving end of the stream
    rx: mpsc::Receiver<String>,
}

impl BufferView {
    // Creates a new view with the given buffer size
    fn new(size: usize, rx: mpsc::Receiver<String>) -> Self {
        let mut buffer = VecDeque::new();
        buffer.resize(size, String::new());
        BufferView {
            rx: rx,
            buffer: buffer,
        }
    }

    // Reads available data from the stream into the buffer
    fn update(&mut self) {
        // Add each available line to the end of the buffer.
        while let Ok(line) = self.rx.try_recv() {
            self.buffer.push_back(line);
            self.buffer.pop_front();
        }
    }
}

impl View for BufferView {
    fn layout(&mut self, _: Vec2) {
        // Before drawing, we'll want to update the buffer
        self.update();
    }

    fn draw(&self, printer: &Printer) {
        // Print the end of the buffer
        for (i, line) in self.buffer
                .iter()
                .rev()
                .take(printer.size.y)
                .enumerate() {
            printer.print((0, printer.size.y - 1 - i), line);
        }
    }
}
<|endoftext|>


<commit_before>use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

#[cfg(backtrace)]
use std::backtrace::{Backtrace, BacktraceStatus};

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` functions a lot like `Box<dyn std::error::Error>`, with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`
/// - `Error` guarantees that a backtrace will exist, even if the error type
///   did not provide one
/// - `Error` is represented as a narrow pointer - exactly one word in size,
///   instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        Error::construct(error, TypeId::of::<E>())
    }

    #[doc(hidden)]
    pub fn new_adhoc<M>(message: M) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::construct(MessageError(message), TypeId::of::<M>())
    }

    fn construct<E>(error: E, type_id: TypeId) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        #[cfg(backtrace)]
        let backtrace = match error.backtrace() {
            Some(_) => None,
            None => Some(Backtrace::capture()),
        };

        unsafe {
            let obj = mem::transmute::<&dyn StdError, TraitObject>(&error);
            let vtable = obj.vtable;
            let inner = Box::new(ErrorImpl {
                vtable,
                type_id,
                #[cfg(backtrace)]
                backtrace,
                error,
            });
            Error {
                inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
            }
        }
    }

    /// Wrap the error value with additional context.
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::from(ContextError {
            error: self,
            context,
        })
    }

    /// View this error object as the underlying error.
    pub fn as_dyn_error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        self.inner.error()
    }

    /// View this error object as the underlying error, mutably.
    pub fn as_dyn_error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        self.inner.error_mut()
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;
    fn deref(&self) -> &Self::Target {
        self.inner.error()
    }
}

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate();
        if let Some((n, error)) = chain.next() {
            writeln!(f, "\ncaused by:")?;
            writeln!(f, "\t{}: {}", n, error)?;
            for (n, error) in chain {
                writeln!(f, "\t{}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nbacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.inner.error())
    }
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: *const (),
    type_id: TypeId,
    #[cfg(backtrace)]
    backtrace: Option<Backtrace>,
    error: E,
}

// repr C to ensure that transmuting from trait objects is safe
#[repr(C)]
struct TraitObject {
    data: *const (),
    vtable: *const (),
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &self.error,
            vtable: self.vtable,
        };

        unsafe { mem::transmute::<TraitObject, &(dyn StdError + Send + Sync + 'static)>(object) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &mut self.error,
            vtable: self.vtable,
        };

        unsafe {
            mem::transmute::<TraitObject, &mut (dyn StdError + Send + Sync + 'static)>(object)
        }
    }
}

/// Iterator of a chain of source errors.
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

        impl Display for DetectDrop {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "does something")
            }
        }

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::from(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<commit_msg>Remove as_dyn_error methods from Error<commit_after>use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

#[cfg(backtrace)]
use std::backtrace::{Backtrace, BacktraceStatus};

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` functions a lot like `Box<dyn std::error::Error>`, with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`
/// - `Error` guarantees that a backtrace will exist, even if the error type
///   did not provide one
/// - `Error` is represented as a narrow pointer - exactly one word in size,
///   instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        Error::construct(error, TypeId::of::<E>())
    }

    #[doc(hidden)]
    pub fn new_adhoc<M>(message: M) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::construct(MessageError(message), TypeId::of::<M>())
    }

    fn construct<E>(error: E, type_id: TypeId) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        #[cfg(backtrace)]
        let backtrace = match error.backtrace() {
            Some(_) => None,
            None => Some(Backtrace::capture()),
        };

        unsafe {
            let obj = mem::transmute::<&dyn StdError, TraitObject>(&error);
            let vtable = obj.vtable;
            let inner = Box::new(ErrorImpl {
                vtable,
                type_id,
                #[cfg(backtrace)]
                backtrace,
                error,
            });
            Error {
                inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
            }
        }
    }

    /// Wrap the error value with additional context.
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::from(ContextError {
            error: self,
            context,
        })
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;

    fn deref(&self) -> &Self::Target {
        self.inner.error()
    }
}

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate();
        if let Some((n, error)) = chain.next() {
            writeln!(f, "\ncaused by:")?;
            writeln!(f, "\t{}: {}", n, error)?;
            for (n, error) in chain {
                writeln!(f, "\t{}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nbacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.inner.error())
    }
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: *const (),
    type_id: TypeId,
    #[cfg(backtrace)]
    backtrace: Option<Backtrace>,
    error: E,
}

// repr C to ensure that transmuting from trait objects is safe
#[repr(C)]
struct TraitObject {
    data: *const (),
    vtable: *const (),
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &self.error,
            vtable: self.vtable,
        };

        unsafe { mem::transmute::<TraitObject, &(dyn StdError + Send + Sync + 'static)>(object) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &mut self.error,
            vtable: self.vtable,
        };

        unsafe {
            mem::transmute::<TraitObject, &mut (dyn StdError + Send + Sync + 'static)>(object)
        }
    }
}

/// Iterator of a chain of source errors.
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

        impl Display for DetectDrop {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "does something")
            }
        }

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::from(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<|endoftext|>


<commit_before>//! Error manipulations.
extern crate libc;
extern crate rdkafka_sys as rdkafka;
extern crate std;

use self::rdkafka::types::*;

/// Kafka result
pub type KafkaResult<T> = Result<T, KafkaError>;

/// Verify if the value represents an error condition.
pub trait IsError {
    /// Return true if the value represents an error.
    fn is_error(self) -> bool;
}

impl IsError for RDKafkaRespErr {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaRespErr::RD_KAFKA_RESP_ERR_NO_ERROR as i32
    }
}

impl IsError for RDKafkaConfRes {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaConfRes::RD_KAFKA_CONF_OK as i32
    }
}

#[derive(Debug)]
/// Represents all Kafka errors.
pub enum KafkaError {
    ClientConfig((RDKafkaConfRes, String, String, String)),
    ClientCreation(String),
    ConsumerCreation(String),
    MessageConsumption(RDKafkaRespErr),
    MessageProduction(RDKafkaRespErr),
    MetadataFetch(RDKafkaRespErr),
    Nul(std::ffi::NulError),
    Subscription(String),
    TopicConfig((RDKafkaConfRes, String, String, String)),
    TopicCreation(String),
    PartitionEof
}

impl From<std::ffi::NulError> for KafkaError {
    fn from(err: std::ffi::NulError) -> KafkaError {
        KafkaError::Nul(err)
    }
}
<commit_msg>Implement Error, Debug and Display for KafkaError<commit_after>//! Error manipulations.
extern crate libc;
extern crate rdkafka_sys as rdkafka;
extern crate std;

use self::rdkafka::types::*;

use util::cstr_to_owned;

/// Kafka result
pub type KafkaResult<T> = Result<T, KafkaError>;

/// Verify if the value represents an error condition.
pub trait IsError {
    /// Return true if the value represents an error.
    fn is_error(self) -> bool;
}

impl IsError for RDKafkaRespErr {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaRespErr::RD_KAFKA_RESP_ERR_NO_ERROR as i32
    }
}

impl IsError for RDKafkaConfRes {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaConfRes::RD_KAFKA_CONF_OK as i32
    }
}

/// Represents all Kafka errors.
pub enum KafkaError {
    ClientConfig((RDKafkaConfRes, String, String, String)),
    ClientCreation(String),
    ConsumerCreation(String),
    MessageConsumption(RDKafkaRespErr),
    MessageProduction(RDKafkaRespErr),
    MetadataFetch(RDKafkaRespErr),
    Nul(std::ffi::NulError),
    Subscription(String),
    TopicConfig((RDKafkaConfRes, String, String, String)),
    TopicCreation(String),
    PartitionEof
}

impl std::fmt::Debug for KafkaError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match *self {
            KafkaError::ClientConfig(ref err) => write!(f, "KafkaError (Client config error: {} {} {})", err.1, err.2, err.3),
            KafkaError::ClientCreation(ref err) => write!(f, "KafkaError (Client creation error: {})", err),
            KafkaError::ConsumerCreation(ref err) => write!(f, "KafkaError (Consumer creation error: {})", err),
            KafkaError::MessageConsumption(err) => write!(f, "KafkaError (Message consumption error: {})", resp_err_description(err)),
            KafkaError::MessageProduction(err) => write!(f, "KafkaError (Message production error: {})", resp_err_description(err)),
            KafkaError::MetadataFetch(err) => write!(f, "KafkaError (Metadata fetch error: {})", resp_err_description(err)),
            KafkaError::Nul(_) => write!(f, "KafkaError (FFI nul error)"),
            KafkaError::Subscription(ref err) => write!(f, "KafkaError (Subscription error: {})", err),
            KafkaError::TopicConfig(ref err) => write!(f, "KafkaError (Topic config error: {} {} {})", err.1, err.2, err.3),
            KafkaError::TopicCreation(ref err) => write!(f, "KafkaError (Topic creation error: {})", err),
            KafkaError::PartitionEof => write!(f, "KafkaError (Partition Eof error)")
        }
    }
}

impl std::fmt::Display for KafkaError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match *self {
            KafkaError::ClientConfig(ref err) => write!(f, "Client config error: {} {} {}", err.1, err.2, err.3),
            KafkaError::ClientCreation(ref err) => write!(f, "Client creation error: {}", err),
            KafkaError::ConsumerCreation(ref err) => write!(f, "Consumer creation error: {}", err),
            KafkaError::MessageConsumption(err) => write!(f, "Message consumption error: {}", resp_err_description(err)),
            KafkaError::MessageProduction(err) => write!(f, "Message production error: {}", resp_err_description(err)),
            KafkaError::MetadataFetch(err) => write!(f, "Meta data fetch error: {}", resp_err_description(err)),
            KafkaError::Nul(_) => write!(f, "FFI nul error"),
            KafkaError::Subscription(ref err) => write!(f, "Subscription error: {}", err),
            KafkaError::TopicConfig(ref err) => write!(f, "Topic config error: {} {} {}", err.1, err.2, err.3),
            KafkaError::TopicCreation(ref err) => write!(f, "Topic creation error: {}", err),
            KafkaError::PartitionEof => write!(f, "Partition Eof error")
        }
    }
}

impl std::error::Error for KafkaError {
    fn description(&self) -> &str {
        match *self {
            KafkaError::ClientConfig(_) => "Client config error",
            KafkaError::ClientCreation(_) => "Client creation error",
            KafkaError::ConsumerCreation(_) => "Consumer creation error",
            KafkaError::MessageConsumption(_) => "Message consumption error",
            KafkaError::MessageProduction(_) => "Message production error",
            KafkaError::MetadataFetch(_) => "Meta data fetch error",
            KafkaError::Nul(_) => "FFI nul error",
            KafkaError::Subscription(_) => "Subscription error",
            KafkaError::TopicConfig(_) => "Topic config error",
            KafkaError::TopicCreation(_) => "Topic creation error",
            KafkaError::PartitionEof => "Partition Eof error"
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            KafkaError::Nul(ref err) => Some(err),
            _ => None
        }
    }
}

impl From<std::ffi::NulError> for KafkaError {
    fn from(err: std::ffi::NulError) -> KafkaError {
        KafkaError::Nul(err)
    }
}

fn resp_err_description(err: RDKafkaRespErr) -> String {
    unsafe {
        cstr_to_owned(rdkafka::rd_kafka_err2str(err))
    }
}
<|endoftext|>


<commit_before>//! Molecular dynamics simulation of a crystal NaCl, reading system and
//! potentials from files.
extern crate lumol;
extern crate lumol_input as input;

use lumol::Logger;
use lumol::sys::{UnitCell, Trajectory};
use lumol::sys::veloc::{BoltzmannVelocities, InitVelocities};
use lumol::sim::Simulation;
use lumol::sim::md::{MolecularDynamics, RescaleThermostat};
use lumol::units;

use input::InteractionsInput;

fn main() {
    Logger::stdout();

    // Read the system fromt the `data/nacl.xyz` file
    let mut trajectory = Trajectory::open("data/nacl.xyz").unwrap();
    let mut system = trajectory.read().unwrap();
    // Set the unit cell, as there is no unit cell data in XYZ files
    system.set_cell(UnitCell::cubic(units::from(22.5608, "A").unwrap()));
    // Read the interactions from the `data/NaCl.toml` TOML file
    let input = InteractionsInput::new("data/nacl.toml").unwrap();
    input.read(&mut system).unwrap();

    let mut velocities = BoltzmannVelocities::new(units::from(300.0, "K").unwrap());
    velocities.init(&mut system);

    let mut md = MolecularDynamics::new(units::from(1.0, "fs").unwrap());
    // Use a velocity rescaling thermostat
    md.set_thermostat(Box::new(
        RescaleThermostat::new(units::from(300.0, "K").unwrap())
    ));

    let mut simulation = Simulation::new(Box::new(md));
    simulation.run(&mut system, 1000);
}
<commit_msg>Fix file name in NaCl example<commit_after>//! Molecular dynamics simulation of a crystal NaCl, reading system and
//! potentials from files.
extern crate lumol;
extern crate lumol_input as input;

use lumol::Logger;
use lumol::sys::{UnitCell, Trajectory};
use lumol::sys::veloc::{BoltzmannVelocities, InitVelocities};
use lumol::sim::Simulation;
use lumol::sim::md::{MolecularDynamics, RescaleThermostat};
use lumol::units;

use input::InteractionsInput;

fn main() {
    Logger::stdout();

    // Read the system fromt the `data/NaCl.xyz` file
    let mut trajectory = Trajectory::open("data/NaCl.xyz").unwrap();
    let mut system = trajectory.read().unwrap();
    // Set the unit cell, as there is no unit cell data in XYZ files
    system.set_cell(UnitCell::cubic(units::from(22.5608, "A").unwrap()));
    // Read the interactions from the `data/NaCl.toml` TOML file
    let input = InteractionsInput::new("data/NaCl.toml").unwrap();
    input.read(&mut system).unwrap();

    let mut velocities = BoltzmannVelocities::new(units::from(300.0, "K").unwrap());
    velocities.init(&mut system);

    let mut md = MolecularDynamics::new(units::from(1.0, "fs").unwrap());
    // Use a velocity rescaling thermostat
    md.set_thermostat(Box::new(
        RescaleThermostat::new(units::from(300.0, "K").unwrap())
    ));

    let mut simulation = Simulation::new(Box::new(md));
    simulation.run(&mut system, 1000);
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// A port of the simplistic benchmark from
//
//    http://github.com/PaulKeeble/ScalaVErlangAgents
//
// I *think* it's the same, more or less.

extern mod std;
use io::Writer;
use io::WriterUtil;

enum request {
    get_count,
    bytes(uint),
    stop
}

fn server(requests: comm::Port<request>, responses: comm::Chan<uint>) {
    let mut count = 0u;
    let mut done = false;
    while !done {
        match comm::recv(requests) {
          get_count => { comm::send(responses, copy count); }
          bytes(b) => { count += b; }
          stop => { done = true; }
        }
    }
    comm::send(responses, count);
}

fn run(args: ~[~str]) {
    let (from_child, to_child) = do task::spawn_conversation |po, ch| {
        server(po, ch);
    };
    let size = uint::from_str(args[1]).get();
    let workers = uint::from_str(args[2]).get();
    let start = std::time::precise_time_s();
    let mut worker_results = ~[];
    for uint::range(0, workers) |_i| {
        do task::task().future_result(|+r| {
            worker_results.push(move r);
        }).spawn {
            for uint::range(0, size / workers) |_i| {
                comm::send(to_child, bytes(100));
            }
        };
    }
    for vec::each(worker_results) |r| {
        r.recv();
    }
    comm::send(to_child, stop);
    let result = comm::recv(from_child);
    let end = std::time::precise_time_s();
    let elapsed = end - start;
    io::stdout().write_str(fmt!("Count is %?\n", result));
    io::stdout().write_str(fmt!("Test took %? seconds\n", elapsed));
    let thruput = ((size / workers * workers) as float) / (elapsed as float);
    io::stdout().write_str(fmt!("Throughput=%f per sec\n", thruput));
}

fn main() {
    let args = os::args();
    let args = if os::getenv(~"RUST_BENCH").is_some() {
        ~[~"", ~"1000000", ~"10000"]
    } else if args.len() <= 1u {
        ~[~"", ~"10000", ~"4"]
    } else {
        args
    };

    debug!("%?", args);
    run(args);
}

<commit_msg>Remove two comm-oriented benchmarks that have pipe equivs<commit_after><|endoftext|>


<commit_before>use super::node::write_node;
use super::node::NodeWriteGuard;
use super::search::MutSearchResult;
use super::BPlusTree;
use super::LevelTree;
use super::NodeCellRef;
use super::*;
use itertools::Itertools;
use std::collections::HashSet;
use std::fmt::Debug;
use std::{char::MAX, cmp::min};

pub const LEVEL_TREE_DEPTH: u32 = 2;

pub const LEVEL_M: usize = 8;
pub const LEVEL_0: usize = LEVEL_M * LEVEL_M; // Smaller can be faster but more fragmented
pub const LEVEL_1: usize = LEVEL_0 * LEVEL_M;

pub const NUM_LEVELS: usize = 2;

enum NodeSelection<KS, PS>
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    WholePage(Vec<NodeReadHandler<KS, PS>>, NodeReadHandler<KS, PS>),
    PartialPage(Vec<NodeReadHandler<KS, PS>>, NodeReadHandler<KS, PS>),
}

fn merge_prune<KS, PS>(
    level: usize,
    node: &NodeCellRef,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    boundary: &EntryKey,
    deleted: &mut HashSet<EntryKey>,
    prune_src: bool,
    lsm: usize,
) -> (usize, Option<NodeCellRef>)
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let search = mut_first::<KS, PS>(node);
    match search {
        MutSearchResult::External => {
            debug!(
                "Selecting external nodes in boundary {:?}, tree level {}, lsm {}",
                boundary, level, lsm
            );
            if let NodeSelection::WholePage(nodes, new_first) =
                select_nodes_in_boundary::<KS, PS>(node, boundary, level, lsm)
            {
                let head_id = nodes[0].ext_id();
                debug_assert!(
                    !nodes.is_empty(),
                    "Cannot find any keys in range in external with boundary {:?}",
                    boundary
                );
                debug!("Selected {} pages to merge", nodes.len());
                // Update deleted key set
                nodes
                    .iter()
                    .map(|node| {
                        node.keys()
                            .iter()
                            .filter(|k| src_tree.deletion.contains(k))
                            .cloned()
                    })
                    .flatten()
                    .for_each(|k| {
                        deleted.insert(k);
                    });
                // Collect keys to merge to next level
                let merging_keys = nodes
                    .iter()
                    .map(|node| {
                        node.keys()
                            .iter()
                            .filter(|k| !src_tree.deletion.contains(k))
                            .map(|k| k.clone())
                    })
                    .flatten()
                    .collect_vec();
                let num_keys_merged = merging_keys.len();
                debug!(
                    "Collected {} keys at level {}, merging to destination tree",
                    num_keys_merged, level
                );
                dest_tree.merge_with_keys(merging_keys);
                debug!("Merge completed in external level");
                if prune_src {
                    debug!("Pruning source tree for {} external pages", nodes.len());
                    debug_assert!(!new_first.node_ref().is_default());
                    for node in nodes.into_iter() {
                        let node_ref = node.node_ref().clone();
                        drop(node); // unlock read
                        let node = write_node::<KS, PS>(&node_ref);
                        clear_node(node, new_first.node_ref());
                    }
                    let new_first_ref = new_first.node_ref().clone();
                    drop(new_first);
                    let mut new_first = write_node::<KS, PS>(&new_first_ref);
                    new_first.extnode_mut(src_tree).id = head_id;
                    *new_first.left_ref_mut().unwrap() = NodeCellRef::default();
                    debug!("Source tree external nodes pruned with head {:?}", head_id);
                }
                return (num_keys_merged, None);
            } else {
                error!("Found partial external node in selection");
                unreachable!();
            }
        }
        MutSearchResult::Internal(sub_node) => {
            #[derive(Debug)]
            enum RightCheck {
                SinglePtr,
                LevelTerminal(NodeCellRef),
                Normal,
            }
            let check_right = |node: NodeReadHandler<KS, PS>| {
                if node.right_ref().unwrap().is_default() {
                    debug_assert_eq!(node.right_bound(), &EntryKey::max());
                    if node.len() == 0 {
                        // This level should be canceled
                        debug_assert!(node.keys().len() == 0);
                        RightCheck::SinglePtr
                    } else {
                        // This level and the tree should be the new root
                        debug_assert!(node.keys().len() > 0);
                        RightCheck::LevelTerminal(node.node_ref().clone())
                    }
                } else {
                    debug_assert_ne!(node.right_bound(), &EntryKey::max());
                    debug_assert!(node.len() > 0);
                    // General cases
                    RightCheck::Normal
                }
            };
            let (num_keys_merged, sub_level_new_root) = merge_prune(
                level + 1,
                &sub_node,
                src_tree,
                dest_tree,
                boundary,
                deleted,
                prune_src,
                lsm,
            );
            let mut new_root = None;
            if prune_src {
                let right_node =
                    match select_nodes_in_boundary::<KS, PS>(node, boundary, level, lsm) {
                        NodeSelection::WholePage(nodes, right_node) => {
                            clear_nodes(nodes, right_node.node_ref());
                            check_right(right_node)
                        }
                        NodeSelection::PartialPage(nodes, mut terminal_node) => {
                            clear_nodes(nodes, terminal_node.node_ref());
                            let search_pos = terminal_node.keys().binary_search(boundary);
                            let pos = match search_pos {
                                Ok(n) => n + 1,
                                Err(n) => n,
                            };
                            let mut new_keys = KS::init();
                            let mut new_ptrs = PS::init();
                            let mut num_keys = 0;
                            for (i, k) in terminal_node.keys()[pos..].iter().enumerate() {
                                new_keys.as_slice()[i] = k.clone();
                                num_keys += 1;
                            }
                            for (i, p) in terminal_node.ptrs()[pos..].iter().enumerate() {
                                new_ptrs.as_slice()[i] = p.clone();
                            }
                            let terminal_ref = terminal_node.node_ref().clone();
                            let right_stat = check_right(terminal_node);
                            {
                                let mut terminal_node = write_node(&terminal_ref);
                                let innode = terminal_node.innode_mut();
                                innode.keys = new_keys;
                                innode.ptrs = new_ptrs;
                                innode.len = num_keys;
                            }
                            right_stat
                        }
                    };
                new_root = {
                    if let Some(sub_level_new_root) = sub_level_new_root {
                        if cfg!(debug_assertions) {
                            match right_node {
                                RightCheck::SinglePtr => {}
                                RightCheck::LevelTerminal(ref r) => panic!(
                                    "Unexpected internal level terminal {:?}, tree level {}, lsm {}, {:?}, keys {:?}",
                                    r, level, lsm, src_tree.head_id(), read_unchecked::<KS, PS>(r).keys()
                                ),
                                _ => panic!(
                                    "Unexpected internal node status {:?}, tree level {}, lsm {}, {:?}",
                                    &right_node, level, lsm, src_tree.head_id()
                                ),
                            }
                        }
                        Some(sub_level_new_root)
                    } else {
                        match right_node {
                            RightCheck::Normal => None,
                            RightCheck::LevelTerminal(node) => Some(node),
                            RightCheck::SinglePtr => unreachable!(),
                        }
                    }
                };
            }
            return (num_keys_merged, new_root);
        }
    }
}

fn clear_node<KS, PS>(mut node: NodeWriteGuard<KS, PS>, right_ref: &NodeCellRef)
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    node.make_empty_node(false);
    *node.right_ref_mut().unwrap() = right_ref.clone();
    node.left_ref_mut().map(|r| *r = right_ref.clone());
}

fn clear_nodes<KS, PS>(nodes: Vec<NodeReadHandler<KS, PS>>, right_ref: &NodeCellRef)
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    for node in nodes.into_iter() {
        let node_ref = node.node_ref().clone();
        drop(node);
        let node = write_node::<KS, PS>(&node_ref);
        clear_node(node, right_ref);
    }
}

fn select_nodes_in_boundary<KS, PS>(
    first_node: &NodeCellRef,
    right_boundary: &EntryKey,
    level: usize,
    lsm: usize,
) -> NodeSelection<KS, PS>
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let first_node = read_unchecked(first_node);
    if first_node.right_bound() > right_boundary {
        return NodeSelection::PartialPage(vec![], first_node);
    }
    let mut next_node = read_unchecked(first_node.right_ref().unwrap());
    let mut collected = vec![first_node];
    loop {
        {
            let last_collected = &collected[collected.len() - 1];
            if last_collected.right_bound() == right_boundary {
                return NodeSelection::WholePage(collected, next_node);
            }
            if next_node.right_bound() > right_boundary {
                // For partial page, next node is the node need to remove
                // partial of the nodes
                return NodeSelection::PartialPage(collected, next_node);
            }
            if last_collected.right_bound() > right_boundary {
                // We don't expect this
                error!(
                    "Node selection enters unordered state, level {}, lsm {}",
                    level, lsm
                );
                unreachable!();
            }
            if next_node.right_ref().unwrap().is_default() {
                if right_boundary == &*MAX_ENTRY_KEY {
                    // Special case, there will be no next node
                    collected.push(next_node);
                    return NodeSelection::WholePage(collected, NodeReadHandler::default());
                } else {
                    error!(
                        "Node selection reaches to end without matching, level {}, lsm {}",
                        level, lsm
                    );
                    unreachable!();
                }
            }
            debug_assert!(!next_node.right_ref().unwrap().is_default());
            debug_assert_ne!(next_node.right_bound(), &*MAX_ENTRY_KEY);
            let new_next = read_unchecked(next_node.right_ref().unwrap());
            collected.push(next_node);
            next_node = new_next;
        }
    }
}

fn select_boundary<KS, PS>(node: &NodeCellRef) -> EntryKey
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let res = read_node(node, |node: &NodeReadHandler<KS, PS>| {
        let node_keys = node.keys();
        let node_len = node_keys.len();
        if node.len() < 1 {
            return Err(node.ptrs()[0].clone());
        }
        // Pick half of the keys in the root
        // Genreally, higher level sub tree in LSM tree will select more keys to merged
        // into next level
        let mid_idx = min(node_len / 2, 8);
        // Return the mid key as the boundary for selection (cut)
        Ok(node_keys[mid_idx].clone())
    });
    match res {
        Ok(key) => key.clone(),
        Err(r) => select_boundary::<KS, PS>(&r),
    }
}

pub fn level_merge<KS, PS>(
    level: usize,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    deleted: &mut HashSet<EntryKey>,
    prune: bool,
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    debug!("Merging LSM tree level {}", level);
    let root = src_tree.get_root();
    let key_boundary = select_boundary::<KS, PS>(&root);
    merge_with_boundary(level, src_tree, dest_tree, &key_boundary, deleted, prune)
}

pub fn merge_with_boundary<KS, PS>(
    level: usize,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    key_boundary: &EntryKey,
    deleted: &mut HashSet<EntryKey>,
    prune: bool,
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    debug!(
        "Level merge level {} with boundary {:?}",
        level, key_boundary
    );
    if cfg!(debug_assertions) {
        debug!("Pre-merge verification at level {}", level);
        verification::tree_has_no_empty_node(&src_tree);
        verification::is_tree_in_order(&src_tree, level);
        debug!(
            "Pre-merge verification for source at level {} completed",
            level
        );
    }
    let num_keys = {
        debug!("Start merge prune level {}", level);
        let (num_keys, new_root) = merge_prune(
            0,
            &src_tree.get_root(),
            src_tree,
            dest_tree,
            &key_boundary,
            deleted,
            prune,
            level,
        );
        debug!("Merged {} keys, pruning: {}", num_keys, prune);
        if let Some(new_root_ref) = new_root {
            debug!("Level merge update source root {:?}", &new_root_ref);
            *src_tree.root.write() = new_root_ref;
        }
        num_keys
    };
    if prune {
        debug!("Post-merge verification at level {}", level);
        debug_assert!(verification::tree_has_no_empty_node(&src_tree));
        debug_assert!(verification::is_tree_in_order(&src_tree, level));
        debug!(
            "Post-merge verification for pruned source at level {} completed",
            level
        );
    }
    debug!("MERGE LEVEL {} COMPLETED", level);
    return num_keys;
}
<commit_msg>fixed<commit_after>use super::node::write_node;
use super::node::NodeWriteGuard;
use super::search::MutSearchResult;
use super::BPlusTree;
use super::LevelTree;
use super::NodeCellRef;
use super::*;
use itertools::Itertools;
use std::collections::HashSet;
use std::fmt::Debug;
use std::{char::MAX, cmp::min};

pub const LEVEL_TREE_DEPTH: u32 = 2;

pub const LEVEL_M: usize = 8;
pub const LEVEL_0: usize = LEVEL_M * LEVEL_M; // Smaller can be faster but more fragmented
pub const LEVEL_1: usize = LEVEL_0 * LEVEL_M;

pub const NUM_LEVELS: usize = 2;

enum NodeSelection<KS, PS>
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    WholePage(Vec<NodeReadHandler<KS, PS>>, NodeReadHandler<KS, PS>),
    PartialPage(Vec<NodeReadHandler<KS, PS>>, NodeReadHandler<KS, PS>),
}

fn merge_prune<KS, PS>(
    level: usize,
    node: &NodeCellRef,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    boundary: &EntryKey,
    deleted: &mut HashSet<EntryKey>,
    prune_src: bool,
    lsm: usize,
) -> (usize, Option<NodeCellRef>)
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let search = mut_first::<KS, PS>(node);
    match search {
        MutSearchResult::External => {
            debug!(
                "Selecting external nodes in boundary {:?}, tree level {}, lsm {}",
                boundary, level, lsm
            );
            if let NodeSelection::WholePage(nodes, new_first) =
                select_nodes_in_boundary::<KS, PS>(node, boundary, level, lsm)
            {
                let head_id = nodes[0].ext_id();
                debug_assert!(
                    !nodes.is_empty(),
                    "Cannot find any keys in range in external with boundary {:?}",
                    boundary
                );
                debug!("Selected {} pages to merge", nodes.len());
                // Update deleted key set
                nodes
                    .iter()
                    .map(|node| {
                        node.keys()
                            .iter()
                            .filter(|k| src_tree.deletion.contains(k))
                            .cloned()
                    })
                    .flatten()
                    .for_each(|k| {
                        deleted.insert(k);
                    });
                // Collect keys to merge to next level
                let merging_keys = nodes
                    .iter()
                    .map(|node| {
                        node.keys()
                            .iter()
                            .filter(|k| !src_tree.deletion.contains(k))
                            .map(|k| k.clone())
                    })
                    .flatten()
                    .collect_vec();
                let num_keys_merged = merging_keys.len();
                debug!(
                    "Collected {} keys at level {}, merging to destination tree",
                    num_keys_merged, level
                );
                dest_tree.merge_with_keys(merging_keys);
                debug!("Merge completed in external level");
                if prune_src {
                    debug!("Pruning source tree for {} external pages", nodes.len());
                    debug_assert!(!new_first.node_ref().is_default());
                    for node in nodes.into_iter() {
                        let node_ref = node.node_ref().clone();
                        drop(node); // unlock read
                        let node = write_node::<KS, PS>(&node_ref);
                        clear_node(node, new_first.node_ref());
                    }
                    let new_first_ref = new_first.node_ref().clone();
                    drop(new_first);
                    let mut new_first = write_node::<KS, PS>(&new_first_ref);
                    new_first.extnode_mut(src_tree).id = head_id;
                    *new_first.left_ref_mut().unwrap() = NodeCellRef::default();
                    debug!("Source tree external nodes pruned with head {:?}", head_id);
                }
                return (num_keys_merged, None);
            } else {
                error!("Found partial external node in selection");
                unreachable!();
            }
        }
        MutSearchResult::Internal(sub_node) => {
            #[derive(Debug)]
            enum RightCheck {
                SinglePtr,
                LevelTerminal(NodeCellRef),
                Normal,
            }
            let check_right = |node: NodeReadHandler<KS, PS>| {
                if node.right_ref().unwrap().is_default() {
                    debug_assert_eq!(node.right_bound(), &EntryKey::max());
                    if node.len() == 0 {
                        // This level should be canceled
                        debug_assert!(node.keys().len() == 0);
                        debug!("The node is a single pointer node {:?}", node.node_ref());
                        RightCheck::SinglePtr
                    } else {
                        // This level and the tree should be the new root
                        debug_assert!(node.keys().len() > 0);
                        debug!("The node is a level terminal {:?} with length {}", node.node_ref(), node.len());
                        RightCheck::LevelTerminal(node.node_ref().clone())
                    }
                } else {
                    debug_assert_ne!(node.right_bound(), &EntryKey::max());
                    debug_assert!(node.len() > 0);
                    // General cases
                    RightCheck::Normal
                }
            };
            let (num_keys_merged, sub_level_new_root) = merge_prune(
                level + 1,
                &sub_node,
                src_tree,
                dest_tree,
                boundary,
                deleted,
                prune_src,
                lsm,
            );
            let mut new_root = None;
            if prune_src {
                let right_node =
                    match select_nodes_in_boundary::<KS, PS>(node, boundary, level, lsm) {
                        NodeSelection::WholePage(nodes, right_node) => {
                            clear_nodes(nodes, right_node.node_ref());
                            check_right(right_node)
                        }
                        NodeSelection::PartialPage(nodes, mut terminal_node) => {
                            clear_nodes(nodes, terminal_node.node_ref());
                            let search_pos = terminal_node.keys().binary_search(boundary);
                            let pos = match search_pos {
                                Ok(n) => n + 1,
                                Err(n) => n,
                            };
                            let mut new_keys = KS::init();
                            let mut new_ptrs = PS::init();
                            let mut num_keys = 0;
                            for (i, k) in terminal_node.keys()[pos..].iter().enumerate() {
                                new_keys.as_slice()[i] = k.clone();
                                num_keys += 1;
                            }
                            for (i, p) in terminal_node.ptrs()[pos..].iter().enumerate() {
                                new_ptrs.as_slice()[i] = p.clone();
                            }
                            let terminal_ref = terminal_node.node_ref().clone();
                            {
                                let mut terminal_node = write_node(&terminal_ref);
                                let innode = terminal_node.innode_mut();
                                innode.keys = new_keys;
                                innode.ptrs = new_ptrs;
                                innode.len = num_keys;
                            }
                            check_right(terminal_node)
                        }
                    };
                new_root = {
                    if let Some(sub_level_new_root) = sub_level_new_root {
                        if cfg!(debug_assertions) {
                            match right_node {
                                RightCheck::SinglePtr => {}
                                RightCheck::LevelTerminal(ref r) => panic!(
                                    "Unexpected internal level terminal {:?}, tree level {}, lsm {}, {:?}, keys {:?}",
                                    r, level, lsm, src_tree.head_id(), read_unchecked::<KS, PS>(r).keys()
                                ),
                                _ => panic!(
                                    "Unexpected internal node status {:?}, tree level {}, lsm {}, {:?}",
                                    &right_node, level, lsm, src_tree.head_id()
                                ),
                            }
                        }
                        Some(sub_level_new_root)
                    } else {
                        match right_node {
                            RightCheck::Normal => None,
                            RightCheck::LevelTerminal(node) => Some(node),
                            RightCheck::SinglePtr => unreachable!(),
                        }
                    }
                };
            }
            return (num_keys_merged, new_root);
        }
    }
}

fn clear_node<KS, PS>(mut node: NodeWriteGuard<KS, PS>, right_ref: &NodeCellRef)
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    node.make_empty_node(false);
    *node.right_ref_mut().unwrap() = right_ref.clone();
    node.left_ref_mut().map(|r| *r = right_ref.clone());
}

fn clear_nodes<KS, PS>(nodes: Vec<NodeReadHandler<KS, PS>>, right_ref: &NodeCellRef)
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    for node in nodes.into_iter() {
        let node_ref = node.node_ref().clone();
        drop(node);
        let node = write_node::<KS, PS>(&node_ref);
        clear_node(node, right_ref);
    }
}

fn select_nodes_in_boundary<KS, PS>(
    first_node: &NodeCellRef,
    right_boundary: &EntryKey,
    level: usize,
    lsm: usize,
) -> NodeSelection<KS, PS>
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let first_node = read_unchecked(first_node);
    if first_node.right_bound() > right_boundary {
        return NodeSelection::PartialPage(vec![], first_node);
    }
    let mut next_node = read_unchecked(first_node.right_ref().unwrap());
    let mut collected = vec![first_node];
    loop {
        {
            let last_collected = &collected[collected.len() - 1];
            if last_collected.right_bound() == right_boundary {
                return NodeSelection::WholePage(collected, next_node);
            }
            if next_node.right_bound() > right_boundary {
                // For partial page, next node is the node need to remove
                // partial of the nodes
                return NodeSelection::PartialPage(collected, next_node);
            }
            if last_collected.right_bound() > right_boundary {
                // We don't expect this
                error!(
                    "Node selection enters unordered state, level {}, lsm {}",
                    level, lsm
                );
                unreachable!();
            }
            if next_node.right_ref().unwrap().is_default() {
                if right_boundary == &*MAX_ENTRY_KEY {
                    // Special case, there will be no next node
                    collected.push(next_node);
                    return NodeSelection::WholePage(collected, NodeReadHandler::default());
                } else {
                    error!(
                        "Node selection reaches to end without matching, level {}, lsm {}",
                        level, lsm
                    );
                    unreachable!();
                }
            }
            debug_assert!(!next_node.right_ref().unwrap().is_default());
            debug_assert_ne!(next_node.right_bound(), &*MAX_ENTRY_KEY);
            let new_next = read_unchecked(next_node.right_ref().unwrap());
            collected.push(next_node);
            next_node = new_next;
        }
    }
}

fn select_boundary<KS, PS>(node: &NodeCellRef) -> EntryKey
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let res = read_node(node, |node: &NodeReadHandler<KS, PS>| {
        let node_keys = node.keys();
        let node_len = node_keys.len();
        if node.len() < 1 {
            return Err(node.ptrs()[0].clone());
        }
        // Pick half of the keys in the root
        // Genreally, higher level sub tree in LSM tree will select more keys to merged
        // into next level
        let mid_idx = min(node_len / 2, 8);
        // Return the mid key as the boundary for selection (cut)
        Ok(node_keys[mid_idx].clone())
    });
    match res {
        Ok(key) => key.clone(),
        Err(r) => select_boundary::<KS, PS>(&r),
    }
}

pub fn level_merge<KS, PS>(
    level: usize,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    deleted: &mut HashSet<EntryKey>,
    prune: bool,
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    debug!("Merging LSM tree level {}", level);
    let root = src_tree.get_root();
    let key_boundary = select_boundary::<KS, PS>(&root);
    merge_with_boundary(level, src_tree, dest_tree, &key_boundary, deleted, prune)
}

pub fn merge_with_boundary<KS, PS>(
    level: usize,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    key_boundary: &EntryKey,
    deleted: &mut HashSet<EntryKey>,
    prune: bool,
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    debug!(
        "Level merge level {} with boundary {:?}",
        level, key_boundary
    );
    if cfg!(debug_assertions) {
        debug!("Pre-merge verification at level {}", level);
        verification::tree_has_no_empty_node(&src_tree);
        verification::is_tree_in_order(&src_tree, level);
        debug!(
            "Pre-merge verification for source at level {} completed",
            level
        );
    }
    let num_keys = {
        debug!("Start merge prune level {}", level);
        let (num_keys, new_root) = merge_prune(
            0,
            &src_tree.get_root(),
            src_tree,
            dest_tree,
            &key_boundary,
            deleted,
            prune,
            level,
        );
        debug!("Merged {} keys, pruning: {}", num_keys, prune);
        if let Some(new_root_ref) = new_root {
            debug!("Level merge update source root {:?}", &new_root_ref);
            *src_tree.root.write() = new_root_ref;
        }
        num_keys
    };
    if prune {
        debug!("Post-merge verification at level {}", level);
        debug_assert!(verification::tree_has_no_empty_node(&src_tree));
        debug_assert!(verification::is_tree_in_order(&src_tree, level));
        debug!(
            "Post-merge verification for pruned source at level {} completed",
            level
        );
    }
    debug!("MERGE LEVEL {} COMPLETED", level);
    return num_keys;
}
<|endoftext|>


<commit_before>#![feature(globs)]
extern crate tox;

use tox::core::*;

fn main() {
    let tox = Tox::new(ToxOptions::new()).unwrap();
    let av = tox.av(2).unwrap();

    let ids = [
        ("192.254.75.98"   , 33445 , "951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F"),
        ("37.187.46.132"   , 33445 , "A9D98212B3F972BD11DA52BEB0658C326FCCC1BFD49F347F9C2D3D8B61E1B927"),
        ("144.76.60.215"   , 33445 , "04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F"),
        ("23.226.230.47"   , 33445 , "A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074"),
        ("54.199.139.199"  , 33445 , "7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029"),
        ("192.210.149.121" , 33445 , "F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67"),
        ("37.59.102.176"   , 33445 , "B98A2CEAA6C6A2FADC2C3632D284318B60FE5375CCB41EFA081AB67F500C1B0B"),
        ("178.21.112.187"  , 33445 , "4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057"),
        ("107.161.17.51"   , 33445 , "7BE3951B97CA4B9ECDDA768E8C52BA19E9E2690AB584787BF4C90E04DBB75111"),
        ("31.7.57.236"     , 443   , "2A4B50D1D525DA2E669592A20C327B5FAD6C7E5962DC69296F9FEC77C4436E4E"),
        ("63.165.243.15"   , 443   , "8CD087E31C67568103E8C2A28653337E90E6B8EDA0D765D57C6B5172B4F1F04C"),
    ];

    for &(ip, port, id) in ids.iter() {
        let id = id.parse().unwrap();
        tox.bootstrap_from_address(ip.to_string(), port, box id).unwrap();
    }

    let groupbot = "56A1ADE4B65B86BCD51CC73E2CD4E542179F47959FE3E0E21B4B0ACDADE51855D34D34D37CB5".parse().unwrap();
    tox.set_name("test".to_string()).ok().unwrap();
    tox.add_friend(box groupbot, "Hello".to_string()).ok().unwrap();
    for ev in tox.events().iter() {
        match ev {
            FriendRequest(..)       => println!("FriendRequest(..)       "),
            FriendMessage(..)       => println!("FriendMessage(..)       "),
            FriendAction(..)        => println!("FriendAction(..)        "),
            NameChange(..)          => println!("NameChange(..)          "),
            StatusMessage(id, _)       => {
                println!("StatusMessage(..)       ");
                let _ = tox.send_message(id, "invite".to_string());
            },
            UserStatusVar(..)       => println!("UserStatusVar(..)       "),
            TypingChange(..)        => println!("TypingChange(..)        "),
            ReadReceipt(..)         => println!("ReadReceipt(..)         "),
            ConnectionStatusVar(..) => println!("ConnectionStatusVar(..) "),
            GroupInvite(id, ty, data)  => {
                println!("GroupInvite(_, {}, _)         ", ty);
                match ty {
                    GroupchatType::Text => tox.join_groupchat(id, data).unwrap(),
                    GroupchatType::Av => av.join_av_groupchat(id, data).unwrap(),
                };
            },
            GroupMessage(_, _, msg) => println!("GroupMessage(_, _, {})", msg),
            GroupNamelistChange(..) => println!("GroupNamelistChange(..) "),
            FileSendRequest(..)     => println!("FileSendRequest(..)     "),
            FileControl(..)         => println!("FileControl(..)         "),
            FileData(..)            => println!("FileData(..)            "),
            AvatarInfo(..)          => println!("AvatarInfo(..)          "),
            AvatarData(..)          => println!("AvatarData(..)          "),
        }
    }
}
<commit_msg>play music in test.rs<commit_after>#![feature(globs)]
extern crate tox;
extern crate libc;

use tox::core::*;
use tox::av::Event::*;

use std::comm::{Select};
use std::collections::{HashMap};

fn main() {
    let tox = Tox::new(ToxOptions::new()).unwrap();
    let av = tox.av(2).unwrap();

    let mut audiomap = HashMap::new();

    let ids = [
        ("192.254.75.98"   , 33445 , "951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F"),
        ("37.187.46.132"   , 33445 , "A9D98212B3F972BD11DA52BEB0658C326FCCC1BFD49F347F9C2D3D8B61E1B927"),
        ("144.76.60.215"   , 33445 , "04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F"),
        ("23.226.230.47"   , 33445 , "A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074"),
        ("54.199.139.199"  , 33445 , "7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029"),
        ("192.210.149.121" , 33445 , "F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67"),
        ("37.59.102.176"   , 33445 , "B98A2CEAA6C6A2FADC2C3632D284318B60FE5375CCB41EFA081AB67F500C1B0B"),
        ("178.21.112.187"  , 33445 , "4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057"),
        ("107.161.17.51"   , 33445 , "7BE3951B97CA4B9ECDDA768E8C52BA19E9E2690AB584787BF4C90E04DBB75111"),
        ("31.7.57.236"     , 443   , "2A4B50D1D525DA2E669592A20C327B5FAD6C7E5962DC69296F9FEC77C4436E4E"),
        ("63.165.243.15"   , 443   , "8CD087E31C67568103E8C2A28653337E90E6B8EDA0D765D57C6B5172B4F1F04C"),
    ];

    for &(ip, port, id) in ids.iter() {
        let id = id.parse().unwrap();
        tox.bootstrap_from_address(ip.to_string(), port, box id).unwrap();
    }

    let groupbot = "56A1ADE4B65B86BCD51CC73E2CD4E542179F47959FE3E0E21B4B0ACDADE51855D34D34D37CB5".parse().unwrap();
    tox.set_name("test".to_string()).ok().unwrap();
    tox.add_friend(box groupbot, "Hello".to_string()).ok().unwrap();

    let sel = Select::new();
    let mut tox_rx = sel.handle(tox.events());
    let mut av_rx = sel.handle(av.events());
    unsafe {
        tox_rx.add();
        av_rx.add();
    }

    loop {
        sel.wait();

        while let Ok(ev) = tox.events().try_recv() {
            match ev {
                FriendRequest(..)       => println!("FriendRequest(..)       "),
                FriendMessage(..)       => println!("FriendMessage(..)       "),
                FriendAction(..)        => println!("FriendAction(..)        "),
                NameChange(..)          => println!("NameChange(..)          "),
                StatusMessage(id, _)       => {
                    println!("StatusMessage(..)       ");
                    let _ = tox.send_message(id, "invite".to_string());
                },
                UserStatusVar(..)       => println!("UserStatusVar(..)       "),
                TypingChange(..)        => println!("TypingChange(..)        "),
                ReadReceipt(..)         => println!("ReadReceipt(..)         "),
                ConnectionStatusVar(..) => println!("ConnectionStatusVar(..) "),
                GroupInvite(id, ty, data)  => {
                    println!("GroupInvite(_, {}, _)         ", ty);
                    match ty {
                        GroupchatType::Text => tox.join_groupchat(id, data).unwrap(),
                        GroupchatType::Av => av.join_av_groupchat(id, data).unwrap(),
                    };
                },
                GroupMessage(_, _, msg) => println!("GroupMessage(_, _, {})", msg),
                GroupNamelistChange(gnum, pnum, change) => {
                    println!("GroupNamelistChange(..) ");
                    if change == ChatChange::PeerDel {
                        audiomap.remove(&(gnum, pnum));
                    }
                },
                FileSendRequest(..)     => println!("FileSendRequest(..)     "),
                FileControl(..)         => println!("FileControl(..)         "),
                FileData(..)            => println!("FileData(..)            "),
                AvatarInfo(..)          => println!("AvatarInfo(..)          "),
                AvatarData(..)          => println!("AvatarData(..)          "),
            }
        }

        while let Ok(ev) = av.events().try_recv() {
            match ev {
                Invite(..)             => println!("Av::Invite(..)"),
                Ringing(..)            => println!("Av::Ringing(..)"),
                Start(..)              => println!("Av::Start(..)"),
                Cancel(..)             => println!("Av::Cancel(..)"),
                Reject(..)             => println!("Av::Reject(..)"),
                End(..)                => println!("Av::End(..)"),
                RequestTimeout(..)     => println!("Av::RequestTimeout(..)"),
                PeerTimeout(..)        => println!("Av::PeerTimeout(..)"),
                PeerCsChange(..)       => println!("Av::PeerCsChange(..)"),
                SelfCsChange(..)       => println!("Av::SelfCsChange(..)"),
                GroupAudio(gnum, pnum, bit)  => {
                    //println!("Av::GroupAudio(..) SR: {} CH: {} N: {}", bit.sample_rate,
                    //         bit.channels, bit.samples);
                    if audiomap.get(&(gnum, pnum)).is_none() {
                        audiomap.insert((gnum, pnum), alsa::open().unwrap());
                    }
                    let alsa = *audiomap.get(&(gnum, pnum)).unwrap();
                    alsa::write(alsa, &bit).unwrap();
                }
            }
        }
    }
}

mod alsa {
    use libc::{c_int, c_uint, c_void, c_ulong, c_long, c_char, puts, EPIPE};
    use tox::av::{AudioBit};

    pub const RATE: u32 = 48000;
    pub const CHANNELS: u8 = 2;

    #[repr(C)]
    pub struct snd_pcm_t;

    pub const SND_PCM_STREAM_PLAYBACK: c_uint = 0;
    pub const SND_PCM_FORMAT_S16_LE: c_uint = 2;
    pub const SND_PCM_ACCESS_RW_INTERLEAVED: c_int = 3;

    #[link(name = "asound")]
    extern {
        fn snd_pcm_open(pcm: *mut *mut snd_pcm_t, name: *const u8, stream: c_uint,
                        mode: c_int) -> c_int;
        fn snd_pcm_set_params(pcm: *mut snd_pcm_t, format: c_uint, access: c_int,
                              channels: c_uint, rate: c_uint, soft_resample: c_int,
                              latency: c_uint) -> c_int;
        fn snd_pcm_writei(pcm: *mut snd_pcm_t, buffer: *const c_void,
                          size: c_ulong) -> c_long;
        fn snd_strerror(e: c_int) -> *const c_char;
        fn snd_pcm_prepare(pcm: *mut snd_pcm_t) -> c_int;
    }

    pub fn open() -> Option<*mut snd_pcm_t> {
        unsafe {
            let mut ptr = 0 as *mut snd_pcm_t;
            let e = snd_pcm_open(&mut ptr, b"default\0".as_ptr(), SND_PCM_STREAM_PLAYBACK,
                                 0);
            if e != 0 {
                puts(snd_strerror(e));
                return None;
            }
            let e = snd_pcm_set_params(ptr, SND_PCM_FORMAT_S16_LE,
                                  SND_PCM_ACCESS_RW_INTERLEAVED, CHANNELS as c_uint,
                                  RATE as c_uint, 1, 500000);
            if e != 0 {
                puts(snd_strerror(e));
                return None;
            }
            Some(ptr)
        }
    }

    pub fn write(p: *mut snd_pcm_t, bit: &AudioBit) -> Option<()> {
        unsafe {
            if bit.sample_rate != RATE || bit.channels != CHANNELS {
                return None;
            }
            let e = snd_pcm_writei(p, bit.pcm.as_ptr() as *const c_void,
                                   bit.samples as c_ulong);
            if e < 0 {
                if e as c_int == -EPIPE {
                    snd_pcm_prepare(p);
                    Some(())
                } else {
                    None
                }
            } else {
                Some(())
            }
        }
    }
}
<|endoftext|>


<commit_before>/// Walking example.

use naming::Naming;
use rsure::{
    Estimate,
    Result,
    node::{
        self,
        fs,
        load,
        HashUpdater,
        NodeWriter,
        Source,
        SureNode,
    },
};
use std::{
    path::Path,
};

fn main() -> Result<()> {
    rsure::log_init();

    let base = ".";

    let mut naming = Naming::new(".", "haha", "dat", true);

    let mut estimate = Estimate { files: 0, bytes: 0 };
    let tmp_name = {
        let mut nf = naming.new_temp(true)?;
        naming.add_cleanup(nf.name.clone());
        let src = fs::scan_fs(base)?
            .inspect(|node| {
                match node {
                    Ok(n @ SureNode::File { .. }) => {
                        if n.needs_hash() {
                            estimate.files += 1;
                            estimate.bytes += n.size();
                        }
                    }
                    _ => (),
                }
            });
        node::save_to(&mut nf.writer, src)?;
        nf.name
    };
    println!("name: {:?}", tmp_name);

    // Update the hashes.
    let loader = Loader { name: &tmp_name };
    let hu = HashUpdater::new(loader, &mut naming);
    let hm = hu.compute(base, &estimate)?;
    let nf = naming.new_temp(true)?;
    hm.merge(&mut NodeWriter::new(nf.writer)?)?;

    naming.rename_to_main(&nf.name)?;

    Ok(())
}

struct Loader<'a> {
    name: &'a Path,
}

impl<'a> Source for Loader<'a> {
    fn iter(&mut self) -> Result<Box<dyn Iterator<Item = Result<SureNode>> + Send>> {
        Ok(Box::new(load(self.name)?))
    }
}
<commit_msg>Remove the no-longer-working walk example<commit_after><|endoftext|>