<commit_before>use super::capabilities::Capabilities;
use super::environment::jvm::{JVMF, JVMAgent};
use super::environment::jvmti::JVMTI;
use super::event::*;
use super::error::*;
use super::native::JavaVMPtr;
use super::version::VersionNumber;

pub struct Agent {
    jvm: Box<JVMF>,
    pub capabilities: Capabilities,
    callbacks: EventCallbacks,
    environment: Box<JVMTI>
}

impl Agent {

    ///
    /// Create a newly initialised but blank JVM `Agent` instance using the provided Java VM pointer.
    ///
    pub fn new(vm: JavaVMPtr) -> Agent {
        let jvm_agent = JVMAgent::new(vm);

        match jvm_agent.get_environment() {
            Ok(environment) => Agent {
                jvm: Box::new(jvm_agent),
                capabilities: Capabilities::new(),
                callbacks: EventCallbacks::new(),
                environment: environment
            },
            Err(err) => panic!("FATAL: Could not get JVMTI environment: {}", translate_error(&err))
        }

    }

    ///
    /// Create a newly initialised but blank JVM `Agent` instance using the provided JVM agent.
    pub fn new_from(jvm: Box<JVMF>) -> Agent {

        match jvm.get_environment() {
            Ok(environment) => Agent {
                jvm: jvm,
                capabilities: Capabilities::new(),
                callbacks: EventCallbacks::new(),
                environment: environment
            },
            Err(err) => panic!("FATAL: Could not get JVMTI environment: {}", translate_error(&err))
        }
    }

    pub fn get_version(&self) -> VersionNumber {
        self.environment.get_version_number()
    }

    pub fn shutdown(&self) {
        // TODO implement this method
    }

    pub fn destroy(&self) -> Result<(), NativeError> {
        self.jvm.destroy()
    }

    pub fn update(&self) {
    }

    pub fn on_method_entry(&mut self, handler: Option<FnMethodEntry>) {
        self.callbacks.method_entry = handler;
        self.capabilities.can_generate_method_entry_events = handler.is_some();
    }

    pub fn on_method_exit(&mut self, handler: Option<FnMethodExit>) {
        self.callbacks.method_exit = handler;
        self.capabilities.can_generate_method_exit_events = handler.is_some();
    }

    pub fn on_vm_init(&mut self, handler: Option<FnVMInit>) {
        self.callbacks.vm_init = handler;
    }

    pub fn on_vm_death(&mut self, handler: Option<FnVMDeath>) {
        self.callbacks.vm_death = handler;
    }

    pub fn on_vm_start(&mut self, handler: Option<FnVMStart>) {
        self.callbacks.vm_start = handler;
    }

    pub fn on_vm_object_alloc(&mut self, handler: Option<FnVMObjectAlloc>) {
        self.callbacks.vm_object_alloc = handler;
        self.capabilities.can_generate_vm_object_alloc_events = handler.is_some();
    }

    pub fn on_thread_start(&mut self, handler: Option<FnThreadStart>) {
        self.callbacks.thread_start = handler;
    }

    pub fn on_thread_end(&mut self, handler: Option<FnThreadEnd>) {
        self.callbacks.thread_end = handler;
    }

    pub fn on_exception(&mut self, handler: Option<FnException>) {
        self.callbacks.exception = handler;
        self.capabilities.can_generate_exception_events = handler.or(self.callbacks.exception_catch).is_some();
    }

    pub fn on_exception_catch(&mut self, handler: Option<FnExceptionCatch>) {
        self.callbacks.exception_catch = handler;
        self.capabilities.can_generate_exception_events = handler.or(self.callbacks.exception).is_some();
    }

    pub fn on_monitor_wait(&mut self, handler: Option<FnMonitorWait>) {
        self.callbacks.monitor_wait = handler;

        let has_some = handler
            .or(self.callbacks.monitor_waited)
            .or(self.callbacks.monitor_contended_enter)
            .or(self.callbacks.monitor_contended_entered).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_monitor_waited(&mut self, handler: Option<FnMonitorWaited>) {
        self.callbacks.monitor_waited = handler;

        let has_some = handler
            .or(self.callbacks.monitor_wait)
            .or(self.callbacks.monitor_contended_enter)
            .or(self.callbacks.monitor_contended_entered).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_monitor_contended_enter(&mut self, handler: Option<FnMonitorContendedEnter>) {
        self.callbacks.monitor_contended_enter = handler;

        let has_some = handler
            .or(self.callbacks.monitor_wait)
            .or(self.callbacks.monitor_waited)
            .or(self.callbacks.monitor_contended_entered).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_monitor_contended_entered(&mut self, handler: Option<FnMonitorContendedEntered>) {
        self.callbacks.monitor_contended_entered = handler;

        let has_some = handler
            .or(self.callbacks.monitor_wait)
            .or(self.callbacks.monitor_waited)
            .or(self.callbacks.monitor_contended_enter).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_field_access(&mut self, handler: Option<FnFieldAccess>) {
        self.callbacks.field_access = handler;
        self.capabilities.can_generate_field_access_events = handler.is_some();
    }

    pub fn on_field_modification(&mut self, handler: Option<FnFieldModitification>) {
        self.callbacks.field_modification = handler;
        self.capabilities.can_generate_field_modification_events = handler.is_some();
    }

    pub fn on_garbage_collection_start(&mut self, handler: Option<FnGarbageCollectionStart>) {
        self.callbacks.garbage_collection_start = handler;
        self.capabilities.can_generate_garbage_collection_events = handler.or(self.callbacks.garbage_collection_finish).is_some();
    }

    pub fn on_garbage_collection_finish(&mut self, handler: Option<FnGarbageCollectionFinish>) {
        self.callbacks.garbage_collection_finish = handler;
        self.capabilities.can_generate_garbage_collection_events = handler.or(self.callbacks.garbage_collection_start).is_some();
    }
}
<commit_msg>Improved capability adding<commit_after>use super::capabilities::Capabilities;
use super::environment::jvm::{JVMF, JVMAgent};
use super::environment::jvmti::JVMTI;
use super::event::*;
use super::error::*;
use super::native::JavaVMPtr;
use super::version::VersionNumber;

pub struct Agent {
    jvm: Box<JVMF>,
    pub capabilities: Capabilities,
    callbacks: EventCallbacks,
    environment: Box<JVMTI>
}

impl Agent {

    ///
    /// Create a newly initialised but blank JVM `Agent` instance using the provided Java VM pointer.
    ///
    pub fn new(vm: JavaVMPtr) -> Agent {
        let jvm_agent = JVMAgent::new(vm);

        match jvm_agent.get_environment() {
            Ok(environment) => Agent {
                jvm: Box::new(jvm_agent),
                capabilities: Capabilities::new(),
                callbacks: EventCallbacks::new(),
                environment: environment
            },
            Err(err) => panic!("FATAL: Could not get JVMTI environment: {}", translate_error(&err))
        }

    }

    ///
    /// Create a newly initialised but blank JVM `Agent` instance using the provided JVM agent.
    pub fn new_from(jvm: Box<JVMF>) -> Agent {

        match jvm.get_environment() {
            Ok(environment) => Agent {
                jvm: jvm,
                capabilities: Capabilities::new(),
                callbacks: EventCallbacks::new(),
                environment: environment
            },
            Err(err) => panic!("FATAL: Could not get JVMTI environment: {}", translate_error(&err))
        }
    }

    pub fn get_version(&self) -> VersionNumber {
        self.environment.get_version_number()
    }

    pub fn shutdown(&self) {
        // TODO implement this method
    }

    pub fn destroy(&self) -> Result<(), NativeError> {
        self.jvm.destroy()
    }

    pub fn update(&self) {
        self.environment.add_capabilities(&self.capabilities);
    }

    pub fn on_method_entry(&mut self, handler: Option<FnMethodEntry>) {
        self.callbacks.method_entry = handler;
        self.capabilities.can_generate_method_entry_events = handler.is_some();
    }

    pub fn on_method_exit(&mut self, handler: Option<FnMethodExit>) {
        self.callbacks.method_exit = handler;
        self.capabilities.can_generate_method_exit_events = handler.is_some();
    }

    pub fn on_vm_init(&mut self, handler: Option<FnVMInit>) {
        self.callbacks.vm_init = handler;
    }

    pub fn on_vm_death(&mut self, handler: Option<FnVMDeath>) {
        self.callbacks.vm_death = handler;
    }

    pub fn on_vm_start(&mut self, handler: Option<FnVMStart>) {
        self.callbacks.vm_start = handler;
    }

    pub fn on_vm_object_alloc(&mut self, handler: Option<FnVMObjectAlloc>) {
        self.callbacks.vm_object_alloc = handler;
        self.capabilities.can_generate_vm_object_alloc_events = handler.is_some();
    }

    pub fn on_thread_start(&mut self, handler: Option<FnThreadStart>) {
        self.callbacks.thread_start = handler;
    }

    pub fn on_thread_end(&mut self, handler: Option<FnThreadEnd>) {
        self.callbacks.thread_end = handler;
    }

    pub fn on_exception(&mut self, handler: Option<FnException>) {
        self.callbacks.exception = handler;
        self.capabilities.can_generate_exception_events = handler.or(self.callbacks.exception_catch).is_some();
    }

    pub fn on_exception_catch(&mut self, handler: Option<FnExceptionCatch>) {
        self.callbacks.exception_catch = handler;
        self.capabilities.can_generate_exception_events = handler.or(self.callbacks.exception).is_some();
    }

    pub fn on_monitor_wait(&mut self, handler: Option<FnMonitorWait>) {
        self.callbacks.monitor_wait = handler;

        let has_some = handler
            .or(self.callbacks.monitor_waited)
            .or(self.callbacks.monitor_contended_enter)
            .or(self.callbacks.monitor_contended_entered).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_monitor_waited(&mut self, handler: Option<FnMonitorWaited>) {
        self.callbacks.monitor_waited = handler;

        let has_some = handler
            .or(self.callbacks.monitor_wait)
            .or(self.callbacks.monitor_contended_enter)
            .or(self.callbacks.monitor_contended_entered).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_monitor_contended_enter(&mut self, handler: Option<FnMonitorContendedEnter>) {
        self.callbacks.monitor_contended_enter = handler;

        let has_some = handler
            .or(self.callbacks.monitor_wait)
            .or(self.callbacks.monitor_waited)
            .or(self.callbacks.monitor_contended_entered).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_monitor_contended_entered(&mut self, handler: Option<FnMonitorContendedEntered>) {
        self.callbacks.monitor_contended_entered = handler;

        let has_some = handler
            .or(self.callbacks.monitor_wait)
            .or(self.callbacks.monitor_waited)
            .or(self.callbacks.monitor_contended_enter).is_some();

        self.capabilities.can_generate_monitor_events = has_some;
    }

    pub fn on_field_access(&mut self, handler: Option<FnFieldAccess>) {
        self.callbacks.field_access = handler;
        self.capabilities.can_generate_field_access_events = handler.is_some();
    }

    pub fn on_field_modification(&mut self, handler: Option<FnFieldModitification>) {
        self.callbacks.field_modification = handler;
        self.capabilities.can_generate_field_modification_events = handler.is_some();
    }

    pub fn on_garbage_collection_start(&mut self, handler: Option<FnGarbageCollectionStart>) {
        self.callbacks.garbage_collection_start = handler;
        self.capabilities.can_generate_garbage_collection_events = handler.or(self.callbacks.garbage_collection_finish).is_some();
    }

    pub fn on_garbage_collection_finish(&mut self, handler: Option<FnGarbageCollectionFinish>) {
        self.callbacks.garbage_collection_finish = handler;
        self.capabilities.can_generate_garbage_collection_events = handler.or(self.callbacks.garbage_collection_start).is_some();
    }
}
<|endoftext|>


<commit_before>/*
    This file is part of trig-rs, a library for doing typesafe trigonometry
    with a variety of angle formats (radians, degrees, grad, turns, and so on).
*/

use std::fmt;

/// Base floating point types
pub trait BaseFloat: Primitive + fmt::Show + fmt::Float + Float + FloatMath {}

impl BaseFloat for f32 {}
impl BaseFloat for f64 {}

/// Encompasses representations of angles in the Euclidean plane.
#[deriving(Clone, PartialEq, PartialOrd, Hash)]
pub enum Angle<S> {
    /// An angle in radians.
    Rad(S),
    /// An angle in degrees.
    Deg(S),
    /// An angle in [gradians](http://en.wikipedia.org/wiki/Grad_(angle)).
    Grad(S),
    /// An angle in [turns](http://en.wikipedia.org/wiki/Turn_(geometry)).
    Turn(S),
    /// An angle as it would appear on the face of a clock.
    Clock {
        /// The hours portion.
        hour: S,
        /// The minutes portion.
        minute: S,
        /// The seconds portion.
        second: S
    },
}

impl<S: BaseFloat> Angle<S> {
    /// Returns an angle in radians.
    pub fn radians(s: S) -> Angle<S> { Rad(s) }

    /// Returns an angle in degrees.
    pub fn degrees(s: S) -> Angle<S> { Deg(s) }

    /// Returns an angle in gradians.
    pub fn gradians(s: S) -> Angle<S> { Grad(s) }

    /// Returns an angle in turns.
    pub fn turns(s: S) -> Angle<S> { Turn(s) }

    /// Returns an angle as it would appear on a clock.
    pub fn clock_face(hour: S, minute: S, second: S) -> Angle<S> {
        Clock { hour: hour, minute: minute, second: second }
    }

    /// Converts an angle to radians.
    pub fn to_radians(&self) -> Angle<S> {
        match self {
            &Rad(val) => Angle::radians(val),
            &Deg(val) => Angle::radians(val.to_radians()),
            _ => fail!("Not yet implemented.")
        }
    }

    /// Converts an angle to degrees.
    pub fn to_degrees(&self) -> Angle<S> {
        match self {
            &Rad(val) => Angle::degrees(val.to_degrees()),
            &Deg(val) => Angle::degrees(val),
            _ => fail!("Not yet implemented.")
        }
    }

    /// One half of the domain. In radians, this is `π`.
    pub fn half() -> Angle<S> { Rad(Float::pi()) }

    /// One quarter of the domain. In radians, this is `π/2`.
    pub fn quarter() -> Angle<S> { Rad(Float::frac_pi_2()) }

    /// One sixth of the domain. In radians, this is `π/3`.
    pub fn sixth() -> Angle<S> { Rad(Float::frac_pi_3()) }

    /// One eighth of the domain. In radians, this is `π/4`.
    pub fn eighth() -> Angle<S> { Rad(Float::frac_pi_4()) }
}

/// Represents an object for which trigonometric methods are sensible and return
/// values of type `S`.
pub trait Trigonometry<S> {
    /// Compute the sine of the object.
    fn sin(&self) -> S;
    /// Compute the cosine of the object.
    fn cos(&self) -> S;
    /// Compute the tangent of the object.
    fn tan(&self) -> S;
    // /// Compute the cosecant of the object.
    // fn csc(&self) -> S;
    // /// Compute the secant of the object.
    // fn sec(&self) -> S;
    // /// Compute the cotangent of the object.
    // fn cot(&self) -> S;
}

macro_rules! angle_trigonometry (
    ($($method:ident),+ ) => (
        impl<S: BaseFloat> Trigonometry<S> for Angle<S> {
            $(fn $method(&self) -> S {
                match self {
                    &Rad(val) => val.$method(),
                    &Deg(val) => val.to_radians().$method(),
                    _ => fail!("Not yet implemented.")
                }
            }
            )+
        }
    )
)

angle_trigonometry!(sin, cos, tan)

macro_rules! angle_ops (
    ($Trait:ident, $method:ident) => (
        impl<S: BaseFloat> $Trait<Angle<S>, Angle<S>> for Angle<S> {
            #[inline]
            fn $method(&self, other: &Angle<S>) -> Angle<S> {
                match (self, other) {
                    (&Deg(s1), &Deg(s2)) => Angle::degrees(s1.$method(&s2)),
                    (&Deg(s1), &Rad(s2)) => Angle::degrees(s1.$method(&s2.to_degrees())),
                    (&Rad(s1), &Rad(s2)) => Angle::radians(s1.$method(&s2)),
                    (&Rad(s1), &Deg(s2)) => Angle::radians(s1.$method(&s2.to_radians())),
                    _ => fail!("Not yet implemented.")
                }
            }
        }
    )
)

angle_ops!(Add, add)
angle_ops!(Sub, sub)
angle_ops!(Mul, mul)
angle_ops!(Div, div)

impl<S: BaseFloat + fmt::Show> fmt::Show for Angle<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Deg(val) => write!(f, "{}°", val),
            &Rad(val) => write!(f, "{} rad", val),
            &Grad(val) => write!(f, "{} gon", val),
            &Turn(val) => write!(f, "{} turns", val),
            _ => fail!("Not yet implemented.")
        }
    }
}
<commit_msg>Trying out an internal conversion method.<commit_after>/*
    This file is part of trig-rs, a library for doing typesafe trigonometry
    with a variety of angle formats (radians, degrees, grad, turns, and so on).
*/

use std::fmt;

/// Base floating point types
pub trait BaseFloat: Primitive + fmt::Show + fmt::Float + Float + FloatMath {
    fn gradians_to_radians(self) -> Self;
    fn gradians_to_degrees(self) -> Self;
    fn gradians_to_turns(self) -> Self;
}

impl BaseFloat for f32 {
    fn gradians_to_radians(self) -> f32 {
        self * Float::pi() / 200.0f32
    }

    fn gradians_to_degrees(self) -> f32 {
        self * 360.0f32 / 400.0f32
    }

    fn gradians_to_turns(self) -> f32 {
        self / 400.0f32
    }
}

impl BaseFloat for f64 {
    fn gradians_to_radians(self) -> f64 {
        self * Float::pi() / 200.0f64
    }

    fn gradians_to_degrees(self) -> f64 {
        self * 360.0f64 / 400.0f64
    }

    fn gradians_to_turns(self) -> f64 {
        self / 400.0f64
    }
}

/// Encompasses representations of angles in the Euclidean plane.
#[deriving(Clone, PartialEq, PartialOrd, Hash)]
pub enum Angle<S> {
    /// An angle in radians.
    Rad(S),
    /// An angle in degrees.
    Deg(S),
    /// An angle in [gradians](http://en.wikipedia.org/wiki/Grad_(angle)).
    Grad(S),
    /// An angle in [turns](http://en.wikipedia.org/wiki/Turn_(geometry)).
    Turn(S),
    /// An angle as it would appear on the face of a clock.
    Clock {
        /// The hours portion.
        hour: S,
        /// The minutes portion.
        minute: S,
        /// The seconds portion.
        second: S
    },
}

impl<S: BaseFloat> Angle<S> {
    /// Returns an angle in radians.
    pub fn radians(s: S) -> Angle<S> { Rad(s) }

    /// Returns an angle in degrees.
    pub fn degrees(s: S) -> Angle<S> { Deg(s) }

    /// Returns an angle in gradians.
    pub fn gradians(s: S) -> Angle<S> { Grad(s) }

    /// Returns an angle in turns.
    pub fn turns(s: S) -> Angle<S> { Turn(s) }

    /// Returns an angle as it would appear on a clock.
    pub fn clock_face(hour: S, minute: S, second: S) -> Angle<S> {
        Clock { hour: hour, minute: minute, second: second }
    }

    /// Converts an angle to radians.
    pub fn to_radians(&self) -> Angle<S> {
        match self {
            &Rad(val) => Angle::radians(val),
            &Deg(val) => Angle::radians(val.to_radians()),
            &Grad(val) => Angle::radians(val.gradians_to_radians()),
            _ => fail!("Not yet implemented.")
        }
    }

    /// Converts an angle to degrees.
    pub fn to_degrees(&self) -> Angle<S> {
        match self {
            &Rad(val) => Angle::degrees(val.to_degrees()),
            &Deg(val) => Angle::degrees(val),
            _ => fail!("Not yet implemented.")
        }
    }

    /// One half of the domain. In radians, this is `π`.
    pub fn half() -> Angle<S> { Rad(Float::pi()) }

    /// One quarter of the domain. In radians, this is `π/2`.
    pub fn quarter() -> Angle<S> { Rad(Float::frac_pi_2()) }

    /// One sixth of the domain. In radians, this is `π/3`.
    pub fn sixth() -> Angle<S> { Rad(Float::frac_pi_3()) }

    /// One eighth of the domain. In radians, this is `π/4`.
    pub fn eighth() -> Angle<S> { Rad(Float::frac_pi_4()) }
}

/// Represents an object for which trigonometric methods are sensible and return
/// values of type `S`.
pub trait Trigonometry<S> {
    /// Compute the sine of the object.
    fn sin(&self) -> S;
    /// Compute the cosine of the object.
    fn cos(&self) -> S;
    /// Compute the tangent of the object.
    fn tan(&self) -> S;
    // /// Compute the cosecant of the object.
    // fn csc(&self) -> S;
    // /// Compute the secant of the object.
    // fn sec(&self) -> S;
    // /// Compute the cotangent of the object.
    // fn cot(&self) -> S;
}

macro_rules! angle_trigonometry (
    ($($method:ident),+ ) => (
        impl<S: BaseFloat> Trigonometry<S> for Angle<S> {
            $(fn $method(&self) -> S {
                match self {
                    &Rad(val) => val.$method(),
                    &Deg(val) => val.to_radians().$method(),
                    _ => fail!("Not yet implemented.")
                }
            }
            )+
        }
    )
)

angle_trigonometry!(sin, cos, tan)

macro_rules! angle_ops (
    ($Trait:ident, $method:ident) => (
        impl<S: BaseFloat> $Trait<Angle<S>, Angle<S>> for Angle<S> {
            #[inline]
            fn $method(&self, other: &Angle<S>) -> Angle<S> {
                match (self, other) {
                    (&Deg(s1), &Deg(s2)) => Angle::degrees(s1.$method(&s2)),
                    (&Deg(s1), &Rad(s2)) => Angle::degrees(s1.$method(&s2.to_degrees())),
                    (&Rad(s1), &Rad(s2)) => Angle::radians(s1.$method(&s2)),
                    (&Rad(s1), &Deg(s2)) => Angle::radians(s1.$method(&s2.to_radians())),
                    _ => fail!("Not yet implemented.")
                }
            }
        }
    )
)

angle_ops!(Add, add)
angle_ops!(Sub, sub)
angle_ops!(Mul, mul)
angle_ops!(Div, div)

impl<S: BaseFloat + fmt::Show> fmt::Show for Angle<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Deg(val) => write!(f, "{}°", val),
            &Rad(val) => write!(f, "{} rad", val),
            &Grad(val) => write!(f, "{} gon", val),
            &Turn(val) => write!(f, "{} turns", val),
            _ => fail!("Not yet implemented.")
        }
    }
}
<|endoftext|>


<commit_before>use super::{AsStr, Element, XmlReader, XmlWriter};
use super::Event::*;
use super::error::Result;
use std::str::from_utf8;
use std::io::Cursor;

macro_rules! next_eq {
    ($r: expr, $($t:path, $bytes:expr),*) => {
        $(
            match $r.next() {
                Some(Ok($t(ref e))) => {
                    assert!(e.name() == $bytes, "expecting {:?}, found {:?}",
                            from_utf8($bytes), e.content().as_str());
                },
                Some(Ok(e)) => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(), 0, $bytes.len(), $bytes.len())), e);
                },
                Some(Err((e, pos))) => {
                    assert!(false, "{:?} at buffer position {}", e, pos);
                },
                p => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(), 0, $bytes.len(), $bytes.len())), p);
                }
            }
        )*
    }
}

#[test]
fn test_start() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_start_end() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_attr() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_comment() {
    let mut r = XmlReader::from_str(" ").trim_text(true);
    next_eq!(r,
             Start, b"b",
             Start, b"a",
             End, b"a",
             Start, b"a",
             End, b"a",
             Comment, b"t",
             End, b"b"
            );
}

#[test]
fn test_start_txt_end() {
    let mut r = XmlReader::from_str("test").trim_text(true);
    next_eq!(r, Start, b"a", Text, b"test", End, b"a");
}

#[test]
fn test_comment() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Comment, b"test");
}

#[test]
fn test_header() {
    let mut r = XmlReader::from_str("<?header?>").trim_text(true);
    next_eq!(r, Header, b"header");
}

#[test]
fn test_trim_test() {
    let txt = "  ";
    let mut r = XmlReader::from_str(&txt).trim_text(true);
    next_eq!(r, Start, b"a",
                Start, b"b",
                End, b"b",
                End, b"a");

    let mut r = XmlReader::from_str(&txt).trim_text(false);
    next_eq!(r, Text, b"",
                Start, b"a",
                Text, b"",
                Start, b"b",
                Text, b"  ",
                End, b"b",
                Text, b"",
                End, b"a");
}

#[test]
fn test_cdata() {
    let mut r = XmlReader::from_str("<![CDATA[test]]>").trim_text(true);
    next_eq!(r, CData, b"test");
}

#[test]
fn test_cdata_open_close() {
    let mut r = XmlReader::from_str("<![CDATA[test <> test]]>").trim_text(true);
    next_eq!(r, CData, b"test <> test");
}

#[test]
fn test_start_attr() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_nested() {
    let mut r = XmlReader::from_str("test<c/>").trim_text(true);
    next_eq!(r,
             Start, b"a",
             Start, b"b",
             Text, b"test",
             End, b"b",
             Start, b"c",
             End, b"c",
             End, b"a"
            );
}

#[test]
fn test_writer() {
    let str = r#"<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.github.sample" android:versionName="Lollipop" android:versionCode="5.1"><application android:label="SampleApplication"></application></manifest>"#;
    let reader = XmlReader::from_str(&str).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        assert!(writer.write(event.unwrap()).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, str.as_bytes());
}

#[test]
fn test_write_attrs() {
    let str_from = r#"<source attr="val"></source>"#;
    let expected = r#"<copy attr="val" a="b" c="d" x="y"></copy>"#;
    let reader = XmlReader::from_str(&str_from).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        let event = event.unwrap();
        let event = match event {
            Start(elem) => {
                let mut attrs = elem.attributes().collect::<Result<Vec<_>>>().unwrap();
                attrs.extend_from_slice(&[(b"a", b"b"), (b"c", b"d")]);
                let mut elem = Element::new("copy").with_attributes(attrs);
                elem.push_attribute("x", "y");
                Start(elem)
            },
            End(_elem) => End(Element::new("copy")),
            _ => event
        };
        assert!(writer.write(event).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, expected.as_bytes());
}

#[test]
fn test_buf_position() {
    let mut r = XmlReader::from_str("")
        .trim_text(true).with_check(true);
    match r.next() {
        Some(Err((_, 4))) => assert!(true),
        Some(Err((_, n))) => assert!(false, "expecting buf_pos = 4, found {}", n),
        e => assert!(false, "expecting error, found {:?}", e),
    }
}

<commit_msg>add test for buffer pos<commit_after>use super::{AsStr, Element, XmlReader, XmlWriter};
use super::Event::*;
use super::error::Result;
use std::str::from_utf8;
use std::io::Cursor;

macro_rules! next_eq {
    ($r: expr, $($t:path, $bytes:expr),*) => {
        $(
            match $r.next() {
                Some(Ok($t(ref e))) => {
                    assert!(e.name() == $bytes, "expecting {:?}, found {:?}",
                            from_utf8($bytes), e.content().as_str());
                },
                Some(Ok(e)) => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(), 0, $bytes.len(), $bytes.len())), e);
                },
                Some(Err((e, pos))) => {
                    assert!(false, "{:?} at buffer position {}", e, pos);
                },
                p => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(), 0, $bytes.len(), $bytes.len())), p);
                }
            }
        )*
    }
}

#[test]
fn test_start() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_start_end() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_attr() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_comment() {
    let mut r = XmlReader::from_str(" ").trim_text(true);
    next_eq!(r,
             Start, b"b",
             Start, b"a",
             End, b"a",
             Start, b"a",
             End, b"a",
             Comment, b"t",
             End, b"b"
            );
}

#[test]
fn test_start_txt_end() {
    let mut r = XmlReader::from_str("test").trim_text(true);
    next_eq!(r, Start, b"a", Text, b"test", End, b"a");
}

#[test]
fn test_comment() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Comment, b"test");
}

#[test]
fn test_header() {
    let mut r = XmlReader::from_str("<?header?>").trim_text(true);
    next_eq!(r, Header, b"header");
}

#[test]
fn test_trim_test() {
    let txt = "  ";
    let mut r = XmlReader::from_str(&txt).trim_text(true);
    next_eq!(r, Start, b"a",
                Start, b"b",
                End, b"b",
                End, b"a");

    let mut r = XmlReader::from_str(&txt).trim_text(false);
    next_eq!(r, Text, b"",
                Start, b"a",
                Text, b"",
                Start, b"b",
                Text, b"  ",
                End, b"b",
                Text, b"",
                End, b"a");
}

#[test]
fn test_cdata() {
    let mut r = XmlReader::from_str("<![CDATA[test]]>").trim_text(true);
    next_eq!(r, CData, b"test");
}

#[test]
fn test_cdata_open_close() {
    let mut r = XmlReader::from_str("<![CDATA[test <> test]]>").trim_text(true);
    next_eq!(r, CData, b"test <> test");
}

#[test]
fn test_start_attr() {
    let mut r = XmlReader::from_str("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_nested() {
    let mut r = XmlReader::from_str("test<c/>").trim_text(true);
    next_eq!(r,
             Start, b"a",
             Start, b"b",
             Text, b"test",
             End, b"b",
             Start, b"c",
             End, b"c",
             End, b"a"
            );
}

#[test]
fn test_writer() {
    let str = r#"<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.github.sample" android:versionName="Lollipop" android:versionCode="5.1"><application android:label="SampleApplication"></application></manifest>"#;
    let reader = XmlReader::from_str(&str).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        assert!(writer.write(event.unwrap()).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, str.as_bytes());
}

#[test]
fn test_write_attrs() {
    let str_from = r#"<source attr="val"></source>"#;
    let expected = r#"<copy attr="val" a="b" c="d" x="y"></copy>"#;
    let reader = XmlReader::from_str(&str_from).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        let event = event.unwrap();
        let event = match event {
            Start(elem) => {
                let mut attrs = elem.attributes().collect::<Result<Vec<_>>>().unwrap();
                attrs.extend_from_slice(&[(b"a", b"b"), (b"c", b"d")]);
                let mut elem = Element::new("copy").with_attributes(attrs);
                elem.push_attribute("x", "y");
                Start(elem)
            },
            End(_elem) => End(Element::new("copy")),
            _ => event
        };
        assert!(writer.write(event).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, expected.as_bytes());
}

#[test]
fn test_buf_position() {
    let mut r = XmlReader::from_str("")
        .trim_text(true).with_check(true);

    match r.next() {
        Some(Err((_, 4))) => assert!(true),
        Some(Err((_, n))) => assert!(false, "expecting buf_pos = 4, found {}", n),
        e => assert!(false, "expecting error, found {:?}", e),
    }

}

<|endoftext|>


<commit_before>#[macro_use]
extern crate bencher;
extern crate kdtree;
extern crate rand;

use bencher::Bencher;

#[derive(Copy, Clone, PartialEq)]
pub struct Point2WithId {
    dims: [f64; 2],
    pub id: i32,
}

impl Point2WithId {
    pub fn new(id: i32, x: f64, y: f64) -> Point2WithId {
        Point2WithId {
            dims: [x, y],
            id: id,
        }
    }
}

impl kdtree::kdtree::KdtreePointTrait for Point2WithId {
    fn dims(&self) -> &[f64] {
        return &self.dims;
    }
}

#[derive(Copy, Clone, PartialEq)]
pub struct Point3WithId {
    dims: [f64; 3],
    pub id: i32,
}

impl Point3WithId {
    pub fn new(id: i32, x: f64, y: f64, z: f64) -> Point3WithId {
        Point3WithId {
            dims: [x, y, z],
            id: id,
        }
    }
}

impl kdtree::kdtree::KdtreePointTrait for Point3WithId {
    fn dims(&self) -> &[f64] {
        return &self.dims;
    }
}

fn bench_creating_1000_node_tree(b: &mut Bencher) {
    let len = 1000usize;
    let mut points : Vec<Point2WithId> = vec![];
    for id in 0..len {
        let x : f64 = rand::random();
        points.push(Point2WithId::new(id as i32, x, x));
    }

    b.iter(|| {
        kdtree::kdtree::Kdtree::new(points.clone());
    });
}

fn bench_single_loop_times_for_1000_node_tree(b: &mut Bencher) {
    let len = 1000usize;
    let mut points : Vec<Point3WithId> = vec![];

    for i in 0..len {
        points.push(Point3WithId::new(i as i32, rand::random(),rand::random(),rand::random()))

    }

    let tree = kdtree::kdtree::Kdtree::new(points.clone());

    b.iter(||  tree.nearest_search(&points[0]));
}

benchmark_group!(benches, bench_creating_1000_node_tree,bench_single_loop_times_for_1000_node_tree);
benchmark_main!(benches);<commit_msg>Temporarly add 1mln tree create bench<commit_after>#[macro_use] extern crate bencher;
extern crate kdtree;
extern crate rand;

use bencher::Bencher;

#[derive(Copy, Clone, PartialEq)]
pub struct Point2WithId {
    dims: [f64; 2],
    pub id: i32,
}

impl Point2WithId {
    pub fn new(id: i32, x: f64, y: f64) -> Point2WithId {
        Point2WithId {
            dims: [x, y],
            id: id,
        }
    }
}

impl kdtree::kdtree::KdtreePointTrait for Point2WithId {
    fn dims(&self) -> &[f64] {
        return &self.dims;
    }
}

#[derive(Copy, Clone, PartialEq)]
pub struct Point3WithId {
    dims: [f64; 3],
    pub id: i32,
}

impl Point3WithId {
    pub fn new(id: i32, x: f64, y: f64, z: f64) -> Point3WithId {
        Point3WithId {
            dims: [x, y, z],
            id: id,
        }
    }
}

impl kdtree::kdtree::KdtreePointTrait for Point3WithId {
    fn dims(&self) -> &[f64] {
        return &self.dims;
    }
}

fn bench_creating_1000_node_tree(b: &mut Bencher) {
    let len = 1000usize;
    let mut points: Vec<Point2WithId> = vec![];
    for id in 0..len {
        let x: f64 = rand::random();
        points.push(Point2WithId::new(id as i32, x, x));
    }

    b.iter(|| {
        kdtree::kdtree::Kdtree::new(points.clone());
    });
}

fn bench_single_loop_times_for_1000_node_tree(b: &mut Bencher) {
    let len = 1000usize;
    let mut points: Vec<Point3WithId> = vec![];

    for i in 0..len {
        points.push(Point3WithId::new(i as i32, rand::random(), rand::random(), rand::random()))
    }

    let tree = kdtree::kdtree::Kdtree::new(points.clone());

    b.iter(|| tree.nearest_search(&points[0]));
}

fn bench_creating_1000_000_node_tree(b: &mut Bencher) {
    let len = 1000_000usize;
    let mut points: Vec<Point2WithId> = vec![];
    for id in 0..len {
        let x: f64 = rand::random();
        points.push(Point2WithId::new(id as i32, x, x));
    }

    b.iter(|| {
        kdtree::kdtree::Kdtree::new(points.clone());
    });
}

benchmark_group!(benches, bench_creating_1000_node_tree,bench_single_loop_times_for_1000_node_tree, bench_creating_1000_000_node_tree);
benchmark_main!(benches);<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

//! A handler and associated types for the startup action.
//!
//! The startup action collects basic information about the system (e.g. its
//! boot time) and metadata about the agent (e.g. it's name and version). It is
//! special in a sense that generally it should be not invoked by flows, but be
//! called explicitly during agent startup.

use std::fmt::{Display, Formatter};
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use log::error;

use crate::metadata::{Metadata};
use crate::session::{self, Session};

#[derive(Debug)]
struct Error {
    boot_time_error: sys_info::Error,
}

impl std::error::Error for Error {

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

impl Display for Error {

    fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
        write!(fmt, "failed to obtain boot time: {}", self.boot_time_error)
    }
}

impl From<Error> for session::Error {

    fn from(error: Error) -> session::Error {
        session::Error::action(error)
    }
}

/// A response type for the startup action.
pub struct Response {
    /// Time of last system boot.
    boot_time: SystemTime,
    /// Metadata about the RRG agent.
    metadata: Metadata,
}

/// Handles requests for the startup action.
pub fn handle<S: Session>(session: &mut S, _: ()) -> session::Result<()> {
    let boot_time = boot_time()?;

    session.send(session::Sink::STARTUP, Response {
        boot_time: boot_time,
        metadata: Metadata::from_cargo(),
    })?;

    Ok(())
}

/// Returns information about the system boot time.
fn boot_time() -> std::result::Result<SystemTime, Error> {
    // TODO: Consider not failing on failures to obtain the boot time. This is
    // really not that critical and sending the rest of the client metadata is
    // more important.
    let timeval = match sys_info::boottime() {
        Ok(timeval) => timeval,
        Err(error) => return Err(Error { boot_time_error: error }),
    };

    let secs = timeval.tv_sec as u64;
    let micros = timeval.tv_usec as u64;

    Ok(UNIX_EPOCH + Duration::from_secs(secs) + Duration::from_micros(micros))
}

impl super::Response for Response {

    const RDF_NAME: Option<&'static str> = Some("StartupInfo");

    type Proto = rrg_proto::StartupInfo;

    fn into_proto(self) -> rrg_proto::StartupInfo {
        let boot_time_micros = match rrg_proto::micros(self.boot_time) {
            Ok(boot_time_micros) => boot_time_micros,
            Err(error) => {
                error!("failed to convert boot time: {}", error);
                0
            }
        };

        rrg_proto::StartupInfo {
            client_info: Some(self.metadata.into()),
            boot_time: Some(boot_time_micros),
        }
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn test_boot_time() {
        let mut session = session::test::Fake::new();
        assert!(handle(&mut session, ()).is_ok());

        assert_eq!(session.reply_count(), 0);
        assert_eq!(session.response_count(session::Sink::STARTUP), 1);

        let response = session.response::<Response>(session::Sink::STARTUP, 0);
        assert!(response.boot_time > std::time::UNIX_EPOCH);
        assert!(response.boot_time < std::time::SystemTime::now());
    }

    #[test]
    fn test_metadata() {
        let mut session = session::test::Fake::new();
        assert!(handle(&mut session, ()).is_ok());

        assert_eq!(session.reply_count(), 0);
        assert_eq!(session.response_count(session::Sink::STARTUP), 1);

        let response = session.response::<Response>(session::Sink::STARTUP, 0);
        assert!(response.metadata.version.as_numeric() > 0);
        assert_eq!(response.metadata.name, "rrg");
    }
}
<commit_msg>Add missing doc comment for startup action errors.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

//! A handler and associated types for the startup action.
//!
//! The startup action collects basic information about the system (e.g. its
//! boot time) and metadata about the agent (e.g. it's name and version). It is
//! special in a sense that generally it should be not invoked by flows, but be
//! called explicitly during agent startup.

use std::fmt::{Display, Formatter};
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use log::error;

use crate::metadata::{Metadata};
use crate::session::{self, Session};

/// An error type for failures that can occur when collecting startup data.
#[derive(Debug)]
struct Error {
    boot_time_error: sys_info::Error,
}

impl std::error::Error for Error {

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

impl Display for Error {

    fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
        write!(fmt, "failed to obtain boot time: {}", self.boot_time_error)
    }
}

impl From<Error> for session::Error {

    fn from(error: Error) -> session::Error {
        session::Error::action(error)
    }
}

/// A response type for the startup action.
pub struct Response {
    /// Time of last system boot.
    boot_time: SystemTime,
    /// Metadata about the RRG agent.
    metadata: Metadata,
}

/// Handles requests for the startup action.
pub fn handle<S: Session>(session: &mut S, _: ()) -> session::Result<()> {
    let boot_time = boot_time()?;

    session.send(session::Sink::STARTUP, Response {
        boot_time: boot_time,
        metadata: Metadata::from_cargo(),
    })?;

    Ok(())
}

/// Returns information about the system boot time.
fn boot_time() -> std::result::Result<SystemTime, Error> {
    // TODO: Consider not failing on failures to obtain the boot time. This is
    // really not that critical and sending the rest of the client metadata is
    // more important.
    let timeval = match sys_info::boottime() {
        Ok(timeval) => timeval,
        Err(error) => return Err(Error { boot_time_error: error }),
    };

    let secs = timeval.tv_sec as u64;
    let micros = timeval.tv_usec as u64;

    Ok(UNIX_EPOCH + Duration::from_secs(secs) + Duration::from_micros(micros))
}

impl super::Response for Response {

    const RDF_NAME: Option<&'static str> = Some("StartupInfo");

    type Proto = rrg_proto::StartupInfo;

    fn into_proto(self) -> rrg_proto::StartupInfo {
        let boot_time_micros = match rrg_proto::micros(self.boot_time) {
            Ok(boot_time_micros) => boot_time_micros,
            Err(error) => {
                error!("failed to convert boot time: {}", error);
                0
            }
        };

        rrg_proto::StartupInfo {
            client_info: Some(self.metadata.into()),
            boot_time: Some(boot_time_micros),
        }
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn test_boot_time() {
        let mut session = session::test::Fake::new();
        assert!(handle(&mut session, ()).is_ok());

        assert_eq!(session.reply_count(), 0);
        assert_eq!(session.response_count(session::Sink::STARTUP), 1);

        let response = session.response::<Response>(session::Sink::STARTUP, 0);
        assert!(response.boot_time > std::time::UNIX_EPOCH);
        assert!(response.boot_time < std::time::SystemTime::now());
    }

    #[test]
    fn test_metadata() {
        let mut session = session::test::Fake::new();
        assert!(handle(&mut session, ()).is_ok());

        assert_eq!(session.reply_count(), 0);
        assert_eq!(session.response_count(session::Sink::STARTUP), 1);

        let response = session.response::<Response>(session::Sink::STARTUP, 0);
        assert!(response.metadata.version.as_numeric() > 0);
        assert_eq!(response.metadata.name, "rrg");
    }
}
<|endoftext|>


<commit_before>use time;
use num::ToPrimitive;

/// Return current time in microseconds since the UNIX epoch.
pub fn now_microseconds() -> u32 {
    let t = time::get_time();
    (t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32
}

/// Calculate the exponential weighted moving average for a vector of numbers, with a smoothing
/// factor `alpha` between 0 and 1. A higher `alpha` discounts older observations faster.
pub fn ewma<T: ToPrimitive>(samples: Vec<T>, alpha: f64) -> f64 {
    let (prev_sample, prev_avg) = samples.iter().fold((0.0, 0.0), |acc, sample| match acc {
        (0.0, 0.0) => (sample.to_f64().unwrap(), sample.to_f64().unwrap()),
        (prev_sample, prev_avg) => (sample.to_f64().unwrap(),
                                    alpha * prev_sample + (1.0 - alpha) * prev_avg)
    });
    alpha * prev_sample + (1.0 - alpha) * prev_avg
}

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

    #[test]
    fn test_ewma_empty_vector() {
        let empty: Vec<u32> = vec!();
        let alpha = 1.0/3.0;
        assert_eq!(ewma(empty, alpha), 0.0);
    }

    #[test]
    fn test_ewma_one_element() {
        let input = vec!(1u32);
        let alpha = 1.0/3.0;
        assert_eq!(ewma(input, alpha), 1.0);
    }

    #[test]
    fn test_exponential_smoothed_moving_average() {
        let input = (1u32..11).collect();
        let alpha = 1.0/3.0;
        let expected = [1.0, 4.0/3.0, 17.0/9.0,
        70.0/27.0, 275.0/81.0, 1036.0/243.0, 3773.0/729.0, 13378.0/2187.0,
        46439.0/6561.0, 158488.0/19683.0];
        assert_eq!(ewma(input, alpha), expected[expected.len() - 1]);
    }
}
<commit_msg>Simplify `ewma`.<commit_after>use time;
use num::ToPrimitive;

/// Return current time in microseconds since the UNIX epoch.
pub fn now_microseconds() -> u32 {
    let t = time::get_time();
    (t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32
}

/// Calculate the exponential weighted moving average for a vector of numbers, with a smoothing
/// factor `alpha` between 0 and 1. A higher `alpha` discounts older observations faster.
pub fn ewma<T: ToPrimitive>(samples: Vec<T>, alpha: f64) -> f64 {
    samples.iter().fold(samples.first().map_or(0.0, |v| v.to_f64().unwrap()),
                        |avg, sample| alpha * sample.to_f64().unwrap() + (1.0 - alpha) * avg)
}

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

    #[test]
    fn test_ewma_empty_vector() {
        let empty: Vec<u32> = vec!();
        let alpha = 1.0/3.0;
        assert_eq!(ewma(empty, alpha), 0.0);
    }

    #[test]
    fn test_ewma_one_element() {
        let input = vec!(1u32);
        let alpha = 1.0/3.0;
        assert_eq!(ewma(input, alpha), 1.0);
    }

    #[test]
    fn test_exponential_smoothed_moving_average() {
        let input = (1u32..11).collect();
        let alpha = 1.0/3.0;
        let expected = [1.0, 4.0/3.0, 17.0/9.0,
        70.0/27.0, 275.0/81.0, 1036.0/243.0, 3773.0/729.0, 13378.0/2187.0,
        46439.0/6561.0, 158488.0/19683.0];
        assert_eq!(ewma(input, alpha), expected[expected.len() - 1]);
    }
}
<|endoftext|>


<commit_before>use std::error;
use std::fmt::{self, Display, Formatter};
use std::time::Duration;

use bytes::Bytes;
use futures::stream::Fuse;
use futures::{try_ready, Async, Future, Poll, Stream};
use tokio_timer::clock::Clock;
use tokio_timer::Delay;

use error::{Error, HyperError};

// Synonym of `twitter_stream_message::util::string_enums`
macro_rules! string_enums {
    (
        $(
            $(#[$attr:meta])*
            pub enum $E:ident {
                $(
                    $(#[$v_attr:meta])*
                    $V:ident($by:expr)
                ),*;
                $(#[$u_attr:meta])*
                $U:ident(_),
            }
        )*
    ) => {
        $(
            $(#[$attr])*
            pub enum $E {
                $(
                    $(#[$v_attr])*
                    $V,
                )*
                $(#[$u_attr])*
                $U(String),
            }

            impl std::convert::AsRef<str> for $E {
                fn as_ref(&self) -> &str {
                    match *self {
                        $($E::$V => $by,)*
                        $E::$U(ref s) => s,
                    }
                }
            }

            impl std::cmp::PartialEq for $E {
                fn eq(&self, other: &$E) -> bool {
                    match *self {
                        $($E::$V => match *other {
                            $E::$V => true,
                            $E::$U(ref s) if $by == s => true,
                            _ => false,
                        },)*
                        $E::$U(ref s) => match *other {
                            $($E::$V => $by == s,)*
                            $E::$U(ref t) => s == t,
                        },
                    }
                }
            }

            impl std::hash::Hash for $E {
                fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
                    match *self {
                        $($E::$V => $by.hash(state),)*
                        $E::$U(ref s) => s.hash(state),
                    }
                }
            }

            impl std::cmp::Eq for $E {}
        )*
    }
}

pub enum EitherStream<A, B> {
    A(A),
    B(B),
}

pub struct Timeout {
    inner: Option<TimeoutInner>,
}

struct TimeoutInner {
    dur: Duration,
    timer: Delay,
    clock: Clock,
}

/// Adds a timeout to a `Stream`.
/// Inspired by `tokio_timer::TimeoutStream` (v0.1).
pub struct TimeoutStream<S> {
    stream: S,
    timeout: Timeout,
}

pub struct JoinDisplay<'a, D: 'a, Sep: ?Sized + 'a>(pub &'a [D], pub &'a Sep);

/// A stream over the lines (delimited by CRLF) of a `Body`.
pub struct Lines<B>
where
    B: Stream,
{
    inner: Fuse<B>,
    buf: Bytes,
}

/// Represents an infallible operation in `default_connector::new`.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum Never {}

impl<A, B> Stream for EitherStream<A, B>
where
    A: Stream,
    B: Stream<Item = A::Item, Error = A::Error>,
{
    type Item = A::Item;
    type Error = A::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match self {
            EitherStream::A(ref mut a) => a.poll(),
            EitherStream::B(ref mut b) => b.poll(),
        }
    }
}

impl Timeout {
    pub fn new(dur: Duration) -> Self {
        Timeout::with_clock(Clock::system(), dur)
    }
}

impl Timeout {
    pub fn cancel(&mut self) {
        self.inner = None;
    }
}

impl Timeout {
    pub fn never() -> Self {
        Timeout { inner: None }
    }

    fn with_clock(clock: Clock, dur: Duration) -> Self {
        Timeout {
            inner: Some(TimeoutInner {
                dur,
                timer: Delay::new(clock.now() + dur),
                clock,
            }),
        }
    }

    pub fn reset(&mut self) {
        if let Some(ref mut inner) = self.inner {
            inner.timer.reset(inner.clock.now() + inner.dur)
        }
    }

    pub fn take(&mut self) -> Self {
        Timeout {
            inner: self.inner.take(),
        }
    }

    pub fn for_stream<S>(mut self, stream: S) -> TimeoutStream<S> {
        self.reset();
        TimeoutStream {
            stream,
            timeout: self,
        }
    }
}

impl Future for Timeout {
    type Item = ();
    type Error = Never;

    fn poll(&mut self) -> Poll<(), Never> {
        if let Some(ref mut inner) = self.inner {
            match inner.timer.poll() {
                Ok(async) => return Ok(async),
                Err(e) => if !e.is_shutdown() {
                    return Ok(Async::NotReady);
                },
            }
        }
        // if `e.is_shutdown`:
        self.cancel();
        Ok(Async::NotReady)
    }
}

impl<S> Stream for TimeoutStream<S>
where
    S: Stream<Error = HyperError>,
{
    type Item = S::Item;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<S::Item>, Error> {
        self.stream
            .poll()
            .map_err(Error::Hyper)
            .and_then(|async| match async {
                Async::Ready(Some(v)) => {
                    self.timeout.reset();
                    Ok(Some(v).into())
                }
                Async::Ready(None) => Ok(Async::Ready(None)),
                Async::NotReady => match self.timeout.poll() {
                    Ok(Async::Ready(())) => Err(Error::TimedOut),
                    Ok(Async::NotReady) => Ok(Async::NotReady),
                    Err(never) => match never {},
                },
            })
    }
}

impl<'a, D, Sep> Display for JoinDisplay<'a, D, Sep>
where
    D: Display + 'a,
    Sep: Display + ?Sized + 'a,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        let mut iter = self.0.iter();
        if let Some(d) = iter.next() {
            Display::fmt(d, f)?;
            for d in iter {
                write!(f, "{}{}", self.1, d)?;
            }
        }
        Ok(())
    }
}

impl<B> Lines<B>
where
    B: Stream,
{
    pub fn new(body: B) -> Self {
        Lines {
            inner: body.fuse(),
            buf: Bytes::new(),
        }
    }
}

impl<B> Stream for Lines<B>
where
    B: Stream,
    B::Item: Into<Bytes>,
{
    type Item = Bytes;
    type Error = B::Error;

    fn poll(&mut self) -> Poll<Option<Bytes>, B::Error> {
        use std::mem;

        macro_rules! try_ready_some {
            ($poll:expr) => {{
                let poll = $poll;
                match try_ready!(poll) {
                    Some(v) => v,
                    None => return Ok(None.into()),
                }
            }};
        }

        if self.buf.is_empty() {
            self.buf = try_ready_some!(self.inner.poll()).into();
        }

        fn remove_first_line(buf: &mut Bytes) -> Option<Bytes> {
            (buf as &Bytes)
                .into_iter()
                .enumerate()
                .find(|&(i, b)| b'\r' == b && Some(&b'\n') == buf.get(i + 1))
                .map(|(i, _)| buf.split_to(i + 2))
        }

        if let Some(buf) = remove_first_line(&mut self.buf) {
            return Ok(Some(buf).into());
        }

        if self.buf.is_empty() {
            self.buf = try_ready_some!(self.inner.poll()).into();
        }

        // Extend the buffer until a newline is found:
        loop {
            match try_ready!(self.inner.poll()) {
                Some(chunk) => {
                    let mut chunk = chunk.into();
                    if b'\r' == *self.buf.last().unwrap() && Some(&b'\n') == chunk.first() {
                        let i = self.buf.len() + 1;
                        self.buf.extend_from_slice(&chunk);
                        let next = self.buf.split_off(i);
                        let ret = mem::replace(&mut self.buf, next);
                        return Ok(Some(ret).into());
                    } else if let Some(tail) = remove_first_line(&mut chunk) {
                        self.buf.extend_from_slice(&tail);
                        let ret = mem::replace(&mut self.buf, chunk);
                        return Ok(Some(ret).into());
                    } else {
                        self.buf.extend_from_slice(&chunk);
                    }
                }
                None => {
                    let ret = mem::replace(&mut self.buf, Bytes::new());
                    return Ok(Some(ret).into());
                }
            };
        }
    }
}

impl error::Error for Never {
    fn description(&self) -> &str {
        match *self {}
    }
}

impl Display for Never {
    fn fmt(&self, _: &mut Formatter<'_>) -> fmt::Result {
        match *self {}
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use bytes::Bytes;
    use futures::stream;

    #[test]
    fn lines() {
        let lines = vec![
            "abc\r\n",
            "d\r\n",
            "efg\r\n",
            "hijk\r\n",
            "\r\n",
            "lmn\r\n",
            "opq\rrs\r\n",
            "\n\rtuv\r\r\n",
            "wxyz",
        ];
        let body = vec![
            Bytes::from(b"abc\r\n".to_vec()),
            Bytes::from(b"d\r\nefg\r\n".to_vec()),
            Bytes::from(b"hi".to_vec()),
            Bytes::from(b"jk".to_vec()),
            Bytes::from(b"".to_vec()),
            Bytes::from(b"\r\n".to_vec()),
            Bytes::from(b"\r\n".to_vec()),
            Bytes::from(b"lmn\r\nop".to_vec()),
            Bytes::from(b"q\rrs\r".to_vec()),
            Bytes::from(b"\n\n\rtuv\r\r\n".to_vec()),
            Bytes::from(b"wxyz".to_vec()),
        ];

        let mut iter1 = lines.iter().cloned();
        let mut iter2 = Lines::new(stream::iter_ok::<_, ()>(body))
            .wait()
            .map(|s| String::from_utf8(s.unwrap().to_vec()).unwrap());

        for _ in 0..(lines.len() + 1) {
            assert_eq!(iter1.next(), iter2.next().as_ref().map(String::as_str));
        }
    }
}
<commit_msg>Use `tokio_timer::clock::now()` instead of `Clock::now()`<commit_after>use std::error;
use std::fmt::{self, Display, Formatter};
use std::time::Duration;

use bytes::Bytes;
use futures::stream::Fuse;
use futures::{try_ready, Async, Future, Poll, Stream};
use tokio_timer::{clock, Delay};

use error::{Error, HyperError};

// Synonym of `twitter_stream_message::util::string_enums`
macro_rules! string_enums {
    (
        $(
            $(#[$attr:meta])*
            pub enum $E:ident {
                $(
                    $(#[$v_attr:meta])*
                    $V:ident($by:expr)
                ),*;
                $(#[$u_attr:meta])*
                $U:ident(_),
            }
        )*
    ) => {
        $(
            $(#[$attr])*
            pub enum $E {
                $(
                    $(#[$v_attr])*
                    $V,
                )*
                $(#[$u_attr])*
                $U(String),
            }

            impl std::convert::AsRef<str> for $E {
                fn as_ref(&self) -> &str {
                    match *self {
                        $($E::$V => $by,)*
                        $E::$U(ref s) => s,
                    }
                }
            }

            impl std::cmp::PartialEq for $E {
                fn eq(&self, other: &$E) -> bool {
                    match *self {
                        $($E::$V => match *other {
                            $E::$V => true,
                            $E::$U(ref s) if $by == s => true,
                            _ => false,
                        },)*
                        $E::$U(ref s) => match *other {
                            $($E::$V => $by == s,)*
                            $E::$U(ref t) => s == t,
                        },
                    }
                }
            }

            impl std::hash::Hash for $E {
                fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
                    match *self {
                        $($E::$V => $by.hash(state),)*
                        $E::$U(ref s) => s.hash(state),
                    }
                }
            }

            impl std::cmp::Eq for $E {}
        )*
    }
}

pub enum EitherStream<A, B> {
    A(A),
    B(B),
}

pub struct Timeout {
    inner: Option<TimeoutInner>,
}

struct TimeoutInner {
    dur: Duration,
    timer: Delay,
}

/// Adds a timeout to a `Stream`.
/// Inspired by `tokio_timer::TimeoutStream` (v0.1).
pub struct TimeoutStream<S> {
    stream: S,
    timeout: Timeout,
}

pub struct JoinDisplay<'a, D: 'a, Sep: ?Sized + 'a>(pub &'a [D], pub &'a Sep);

/// A stream over the lines (delimited by CRLF) of a `Body`.
pub struct Lines<B>
where
    B: Stream,
{
    inner: Fuse<B>,
    buf: Bytes,
}

/// Represents an infallible operation in `default_connector::new`.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum Never {}

impl<A, B> Stream for EitherStream<A, B>
where
    A: Stream,
    B: Stream<Item = A::Item, Error = A::Error>,
{
    type Item = A::Item;
    type Error = A::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match self {
            EitherStream::A(ref mut a) => a.poll(),
            EitherStream::B(ref mut b) => b.poll(),
        }
    }
}

impl Timeout {
    pub fn new(dur: Duration) -> Self {
        Timeout {
            inner: Some(TimeoutInner {
                dur,
                timer: Delay::new(clock::now() + dur),
            }),
        }
    }
}

impl Timeout {
    pub fn cancel(&mut self) {
        self.inner = None;
    }
}

impl Timeout {
    pub fn never() -> Self {
        Timeout { inner: None }
    }

    pub fn reset(&mut self) {
        if let Some(ref mut inner) = self.inner {
            inner.timer.reset(clock::now() + inner.dur)
        }
    }

    pub fn take(&mut self) -> Self {
        Timeout {
            inner: self.inner.take(),
        }
    }

    pub fn for_stream<S>(mut self, stream: S) -> TimeoutStream<S> {
        self.reset();
        TimeoutStream {
            stream,
            timeout: self,
        }
    }
}

impl Future for Timeout {
    type Item = ();
    type Error = Never;

    fn poll(&mut self) -> Poll<(), Never> {
        if let Some(ref mut inner) = self.inner {
            match inner.timer.poll() {
                Ok(async) => return Ok(async),
                Err(e) => if !e.is_shutdown() {
                    return Ok(Async::NotReady);
                },
            }
        }
        // if `e.is_shutdown`:
        self.cancel();
        Ok(Async::NotReady)
    }
}

impl<S> Stream for TimeoutStream<S>
where
    S: Stream<Error = HyperError>,
{
    type Item = S::Item;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<S::Item>, Error> {
        self.stream
            .poll()
            .map_err(Error::Hyper)
            .and_then(|async| match async {
                Async::Ready(Some(v)) => {
                    self.timeout.reset();
                    Ok(Some(v).into())
                }
                Async::Ready(None) => Ok(Async::Ready(None)),
                Async::NotReady => match self.timeout.poll() {
                    Ok(Async::Ready(())) => Err(Error::TimedOut),
                    Ok(Async::NotReady) => Ok(Async::NotReady),
                    Err(never) => match never {},
                },
            })
    }
}

impl<'a, D, Sep> Display for JoinDisplay<'a, D, Sep>
where
    D: Display + 'a,
    Sep: Display + ?Sized + 'a,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        let mut iter = self.0.iter();
        if let Some(d) = iter.next() {
            Display::fmt(d, f)?;
            for d in iter {
                write!(f, "{}{}", self.1, d)?;
            }
        }
        Ok(())
    }
}

impl<B> Lines<B>
where
    B: Stream,
{
    pub fn new(body: B) -> Self {
        Lines {
            inner: body.fuse(),
            buf: Bytes::new(),
        }
    }
}

impl<B> Stream for Lines<B>
where
    B: Stream,
    B::Item: Into<Bytes>,
{
    type Item = Bytes;
    type Error = B::Error;

    fn poll(&mut self) -> Poll<Option<Bytes>, B::Error> {
        use std::mem;

        macro_rules! try_ready_some {
            ($poll:expr) => {{
                let poll = $poll;
                match try_ready!(poll) {
                    Some(v) => v,
                    None => return Ok(None.into()),
                }
            }};
        }

        if self.buf.is_empty() {
            self.buf = try_ready_some!(self.inner.poll()).into();
        }

        fn remove_first_line(buf: &mut Bytes) -> Option<Bytes> {
            (buf as &Bytes)
                .into_iter()
                .enumerate()
                .find(|&(i, b)| b'\r' == b && Some(&b'\n') == buf.get(i + 1))
                .map(|(i, _)| buf.split_to(i + 2))
        }

        if let Some(buf) = remove_first_line(&mut self.buf) {
            return Ok(Some(buf).into());
        }

        if self.buf.is_empty() {
            self.buf = try_ready_some!(self.inner.poll()).into();
        }

        // Extend the buffer until a newline is found:
        loop {
            match try_ready!(self.inner.poll()) {
                Some(chunk) => {
                    let mut chunk = chunk.into();
                    if b'\r' == *self.buf.last().unwrap() && Some(&b'\n') == chunk.first() {
                        let i = self.buf.len() + 1;
                        self.buf.extend_from_slice(&chunk);
                        let next = self.buf.split_off(i);
                        let ret = mem::replace(&mut self.buf, next);
                        return Ok(Some(ret).into());
                    } else if let Some(tail) = remove_first_line(&mut chunk) {
                        self.buf.extend_from_slice(&tail);
                        let ret = mem::replace(&mut self.buf, chunk);
                        return Ok(Some(ret).into());
                    } else {
                        self.buf.extend_from_slice(&chunk);
                    }
                }
                None => {
                    let ret = mem::replace(&mut self.buf, Bytes::new());
                    return Ok(Some(ret).into());
                }
            };
        }
    }
}

impl error::Error for Never {
    fn description(&self) -> &str {
        match *self {}
    }
}

impl Display for Never {
    fn fmt(&self, _: &mut Formatter<'_>) -> fmt::Result {
        match *self {}
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use bytes::Bytes;
    use futures::stream;

    #[test]
    fn lines() {
        let lines = vec![
            "abc\r\n",
            "d\r\n",
            "efg\r\n",
            "hijk\r\n",
            "\r\n",
            "lmn\r\n",
            "opq\rrs\r\n",
            "\n\rtuv\r\r\n",
            "wxyz",
        ];
        let body = vec![
            Bytes::from(b"abc\r\n".to_vec()),
            Bytes::from(b"d\r\nefg\r\n".to_vec()),
            Bytes::from(b"hi".to_vec()),
            Bytes::from(b"jk".to_vec()),
            Bytes::from(b"".to_vec()),
            Bytes::from(b"\r\n".to_vec()),
            Bytes::from(b"\r\n".to_vec()),
            Bytes::from(b"lmn\r\nop".to_vec()),
            Bytes::from(b"q\rrs\r".to_vec()),
            Bytes::from(b"\n\n\rtuv\r\r\n".to_vec()),
            Bytes::from(b"wxyz".to_vec()),
        ];

        let mut iter1 = lines.iter().cloned();
        let mut iter2 = Lines::new(stream::iter_ok::<_, ()>(body))
            .wait()
            .map(|s| String::from_utf8(s.unwrap().to_vec()).unwrap());

        for _ in 0..(lines.len() + 1) {
            assert_eq!(iter1.next(), iter2.next().as_ref().map(String::as_str));
        }
    }
}
<|endoftext|>


<commit_before>pub enum Type {
    Int32(i32)
}

pub struct Format {
}

pub struct Row {
    cells: Vec<Type>
}

pub struct Table {
    rows: Vec<Row>
}
<commit_msg>Types prototype<commit_after>use std::option::Option;

type OptInt32 = Option<i32>;
type OptInt64 = Option<i64>;
type OptString = Option<String>;

pub enum CellType {
    Int32 (OptInt32),
    Int64 (OptInt64),
    Text  (OptString)
}

trait Metainf {
    fn name(&self) -> String;
}

impl Metainf for CellType {
    fn name(&self) -> String {
        return match *self {
            CellType::Int32(_) => "INT32".to_string(),
            CellType::Int64(_) => "INT64".to_string(),
            CellType::Text(_) => "TEXT".to_string()
        }
    }
}

//pub struct Format {
//}

pub struct Row {
    cells: Vec<CellType>
}

pub struct Table {
    rows: Vec<Row>
}

trait ISet {
    fn size(&self) -> usize;
    fn add(&mut self, row: Row);
    fn remove(&mut self, index: usize); // FIXME
}
<|endoftext|>


<commit_before>use std::cmp;

use lz77::LongestMatch;
use util::{ZOPFLI_CACHE_LENGTH, ZOPFLI_MAX_MATCH, ZOPFLI_MIN_MATCH};

// Cache used by ZopfliFindLongestMatch to remember previously found length/dist
// values.
// This is needed because the squeeze runs will ask these values multiple times for
// the same position.
// Uses large amounts of memory, since it has to remember the distance belonging
// to every possible shorter-than-the-best length (the so called "sublen" array).
pub struct ZopfliLongestMatchCache {
    length: Vec<u16>,
    dist: Vec<u16>,
    sublen: Vec<u8>,
}

impl ZopfliLongestMatchCache {
    pub fn new(blocksize: usize) -> ZopfliLongestMatchCache {
        ZopfliLongestMatchCache {
            /* length > 0 and dist 0 is invalid combination, which indicates on purpose
            that this cache value is not filled in yet. */
            length: vec![1; blocksize],
            dist: vec![0; blocksize],
            /* Rather large amount of memory. */
            sublen: vec![0; ZOPFLI_CACHE_LENGTH * blocksize * 3],
        }
    }

    pub fn length_at(&self, pos: usize) -> u16 {
        self.length[pos]
    }

    pub fn dist_at(&self, pos: usize) -> u16 {
        self.dist[pos]
    }

    pub fn store_length_at(&mut self, pos: usize, val: u16) {
        self.length[pos] = val;
    }

    pub fn store_dist_at(&mut self, pos: usize, val: u16) {
        self.dist[pos] = val;
    }

    /// Returns the length up to which could be stored in the cache.
    pub fn max_sublen(&self, pos: usize) -> u32 {
        let start = ZOPFLI_CACHE_LENGTH * pos * 3;
        if self.sublen[start + 1] == 0 && self.sublen[start + 2] == 0 {
            return 0;  // No sublen cached.
        }
        self.sublen[start + ((ZOPFLI_CACHE_LENGTH - 1) * 3)] as u32 + 3
    }

    /// Stores sublen array in the cache.
    pub fn store_sublen(&mut self, sublen: &[u16], pos: usize, length: usize) {
        if length < 3 {
            return;
        }

        let start = ZOPFLI_CACHE_LENGTH * pos * 3;
        let mut i = 3;
        let mut j = 0;
        let mut bestlength = 0;
        while i <= length {
            if i == length || sublen[i] != sublen[i + 1] {
                self.sublen[start + (j * 3)] = (i - 3) as u8;
                self.sublen[start + (j * 3 + 1)] = sublen[i].wrapping_rem(256) as u8;
                self.sublen[start + (j * 3 + 2)] = ((sublen[i] >> 8)).wrapping_rem(256) as u8;
                bestlength = i as u32;
                j += 1;
                if j >= ZOPFLI_CACHE_LENGTH {
                    break;
                }
            }
            i += 1;
        }

        if j < ZOPFLI_CACHE_LENGTH {
            assert!(bestlength == length as u32);
            self.sublen[start + ((ZOPFLI_CACHE_LENGTH - 1) * 3)] = (bestlength - 3) as u8;
        } else {
            assert!(bestlength <= length as u32);
        }
        assert!(bestlength == self.max_sublen(pos));
    }

    /// Extracts sublen array from the cache.
    fn fetch_sublen(&self, pos: usize, length: usize, sublen: &mut [u16]) {
        if length < 3 {
            return;
        }

        let start = ZOPFLI_CACHE_LENGTH * pos * 3;
        let maxlength = self.max_sublen(pos) as usize;
        let mut prevlength = 0;

        for j in 0..ZOPFLI_CACHE_LENGTH {
            let length = self.sublen[start + (j * 3)] as usize + 3;
            let dist = self.sublen[start + (j * 3 + 1)] as u16 + 256 * self.sublen[start + (j * 3 + 2)] as u16;

            let mut i = prevlength;
            while i <= length {
                sublen[i] = dist;
                i += 1;
            }
            if length == maxlength {
                break;
            }
            prevlength = length + 1;
        }
    }
}

pub trait Cache {
    fn try_get(&self, pos: usize, limit: usize, sublen: &mut Option<&mut [u16]>, blockstart: usize) -> LongestMatch;
    fn store(&mut self, pos: usize, limit: usize, sublen: &mut Option<&mut [u16]>, distance: u16, length: u16, blockstart: usize);
}

pub struct NoCache;

impl Cache for NoCache {
    fn try_get(&self, _: usize, limit: usize, _: &mut Option<&mut [u16]>, _: usize) -> LongestMatch {
        LongestMatch::new(limit)
    }

    fn store(&mut self, _: usize, _: usize, _: &mut Option<&mut [u16]>, _: u16, _: u16, _: usize) {
        // Nowhere to store
    }
}

impl Cache for ZopfliLongestMatchCache {
    fn try_get(&self, pos: usize, mut limit: usize, sublen: &mut Option<&mut [u16]>, blockstart: usize) -> LongestMatch {
        let mut longest_match = LongestMatch::new(limit);

        /* The LMC cache starts at the beginning of the block rather than the
        beginning of the whole array. */
        let lmcpos = pos - blockstart;

        /* Length > 0 and dist 0 is invalid combination, which indicates on purpose
        that this cache value is not filled in yet. */
        let length_lmcpos = self.length_at(lmcpos);
        let dist_lmcpos = self.dist_at(lmcpos);
        let cache_available = length_lmcpos == 0 || dist_lmcpos != 0;
        let max_sublen = self.max_sublen(lmcpos);
        let limit_ok_for_cache = limit == ZOPFLI_MAX_MATCH || length_lmcpos <= limit as u16 || ( sublen.is_some() && max_sublen >= limit as u32);

        if limit_ok_for_cache && cache_available {
            if sublen.is_none() || length_lmcpos as u32 <= max_sublen {
                let length = cmp::min(length_lmcpos, limit as u16);
                let distance;
                if let &mut Some(ref mut subl) = sublen {
                    self.fetch_sublen(lmcpos, length as usize, subl);
                    distance = subl[length as usize];

                    if limit == ZOPFLI_MAX_MATCH && length >= ZOPFLI_MIN_MATCH as u16 {
                        assert!(subl[length as usize] == dist_lmcpos);
                    }
                } else {
                    distance = dist_lmcpos;
                }
                longest_match.distance = distance;
                longest_match.length = length;
                longest_match.from_cache = true;
                return longest_match;
            }
            /* Can't use much of the cache, since the "sublens" need to be calculated,
            but at least we already know when to stop. */
            limit = length_lmcpos as usize;
            longest_match.limit = limit;
        }

        longest_match
    }

    fn store(&mut self, pos: usize, limit: usize, sublen: &mut Option<&mut [u16]>, distance: u16, length: u16, blockstart: usize) {
        if let &mut Some(ref mut subl) = sublen {
            /* Length > 0 and dist 0 is invalid combination, which indicates on purpose
            that this cache value is not filled in yet. */
            let lmcpos = pos - blockstart;
            let cache_available = self.length_at(lmcpos) == 0 || self.dist_at(lmcpos) != 0;

            if limit == ZOPFLI_MAX_MATCH && !cache_available {
                assert!(self.length_at(lmcpos) == 1 && self.dist_at(lmcpos) == 0);
                if length < ZOPFLI_MIN_MATCH as u16 {
                    self.store_dist_at(lmcpos, 0);
                    self.store_length_at(lmcpos, 0);
                } else {
                    self.store_dist_at(lmcpos, distance);
                    self.store_length_at(lmcpos, length);
                }
                assert!(!(self.length_at(lmcpos) == 1 && self.dist_at(lmcpos) == 0));
                self.store_sublen(subl, lmcpos, length as usize);
            }
        }
    }
}
<commit_msg>Remove more pubs<commit_after>use std::cmp;

use lz77::LongestMatch;
use util::{ZOPFLI_CACHE_LENGTH, ZOPFLI_MAX_MATCH, ZOPFLI_MIN_MATCH};

// Cache used by ZopfliFindLongestMatch to remember previously found length/dist
// values.
// This is needed because the squeeze runs will ask these values multiple times for
// the same position.
// Uses large amounts of memory, since it has to remember the distance belonging
// to every possible shorter-than-the-best length (the so called "sublen" array).
pub struct ZopfliLongestMatchCache {
    length: Vec<u16>,
    dist: Vec<u16>,
    sublen: Vec<u8>,
}

impl ZopfliLongestMatchCache {
    pub fn new(blocksize: usize) -> ZopfliLongestMatchCache {
        ZopfliLongestMatchCache {
            /* length > 0 and dist 0 is invalid combination, which indicates on purpose
            that this cache value is not filled in yet. */
            length: vec![1; blocksize],
            dist: vec![0; blocksize],
            /* Rather large amount of memory. */
            sublen: vec![0; ZOPFLI_CACHE_LENGTH * blocksize * 3],
        }
    }

    fn length_at(&self, pos: usize) -> u16 {
        self.length[pos]
    }

    fn dist_at(&self, pos: usize) -> u16 {
        self.dist[pos]
    }

    fn store_length_at(&mut self, pos: usize, val: u16) {
        self.length[pos] = val;
    }

    fn store_dist_at(&mut self, pos: usize, val: u16) {
        self.dist[pos] = val;
    }

    /// Returns the length up to which could be stored in the cache.
    fn max_sublen(&self, pos: usize) -> u32 {
        let start = ZOPFLI_CACHE_LENGTH * pos * 3;
        if self.sublen[start + 1] == 0 && self.sublen[start + 2] == 0 {
            return 0;  // No sublen cached.
        }
        self.sublen[start + ((ZOPFLI_CACHE_LENGTH - 1) * 3)] as u32 + 3
    }

    /// Stores sublen array in the cache.
    fn store_sublen(&mut self, sublen: &[u16], pos: usize, length: usize) {
        if length < 3 {
            return;
        }

        let start = ZOPFLI_CACHE_LENGTH * pos * 3;
        let mut i = 3;
        let mut j = 0;
        let mut bestlength = 0;
        while i <= length {
            if i == length || sublen[i] != sublen[i + 1] {
                self.sublen[start + (j * 3)] = (i - 3) as u8;
                self.sublen[start + (j * 3 + 1)] = sublen[i].wrapping_rem(256) as u8;
                self.sublen[start + (j * 3 + 2)] = ((sublen[i] >> 8)).wrapping_rem(256) as u8;
                bestlength = i as u32;
                j += 1;
                if j >= ZOPFLI_CACHE_LENGTH {
                    break;
                }
            }
            i += 1;
        }

        if j < ZOPFLI_CACHE_LENGTH {
            assert!(bestlength == length as u32);
            self.sublen[start + ((ZOPFLI_CACHE_LENGTH - 1) * 3)] = (bestlength - 3) as u8;
        } else {
            assert!(bestlength <= length as u32);
        }
        assert!(bestlength == self.max_sublen(pos));
    }

    /// Extracts sublen array from the cache.
    fn fetch_sublen(&self, pos: usize, length: usize, sublen: &mut [u16]) {
        if length < 3 {
            return;
        }

        let start = ZOPFLI_CACHE_LENGTH * pos * 3;
        let maxlength = self.max_sublen(pos) as usize;
        let mut prevlength = 0;

        for j in 0..ZOPFLI_CACHE_LENGTH {
            let length = self.sublen[start + (j * 3)] as usize + 3;
            let dist = self.sublen[start + (j * 3 + 1)] as u16 + 256 * self.sublen[start + (j * 3 + 2)] as u16;

            let mut i = prevlength;
            while i <= length {
                sublen[i] = dist;
                i += 1;
            }
            if length == maxlength {
                break;
            }
            prevlength = length + 1;
        }
    }
}

pub trait Cache {
    fn try_get(&self, pos: usize, limit: usize, sublen: &mut Option<&mut [u16]>, blockstart: usize) -> LongestMatch;
    fn store(&mut self, pos: usize, limit: usize, sublen: &mut Option<&mut [u16]>, distance: u16, length: u16, blockstart: usize);
}

pub struct NoCache;

impl Cache for NoCache {
    fn try_get(&self, _: usize, limit: usize, _: &mut Option<&mut [u16]>, _: usize) -> LongestMatch {
        LongestMatch::new(limit)
    }

    fn store(&mut self, _: usize, _: usize, _: &mut Option<&mut [u16]>, _: u16, _: u16, _: usize) {
        // Nowhere to store
    }
}

impl Cache for ZopfliLongestMatchCache {
    fn try_get(&self, pos: usize, mut limit: usize, sublen: &mut Option<&mut [u16]>, blockstart: usize) -> LongestMatch {
        let mut longest_match = LongestMatch::new(limit);

        /* The LMC cache starts at the beginning of the block rather than the
        beginning of the whole array. */
        let lmcpos = pos - blockstart;

        /* Length > 0 and dist 0 is invalid combination, which indicates on purpose
        that this cache value is not filled in yet. */
        let length_lmcpos = self.length_at(lmcpos);
        let dist_lmcpos = self.dist_at(lmcpos);
        let cache_available = length_lmcpos == 0 || dist_lmcpos != 0;
        let max_sublen = self.max_sublen(lmcpos);
        let limit_ok_for_cache = limit == ZOPFLI_MAX_MATCH || length_lmcpos <= limit as u16 || ( sublen.is_some() && max_sublen >= limit as u32);

        if limit_ok_for_cache && cache_available {
            if sublen.is_none() || length_lmcpos as u32 <= max_sublen {
                let length = cmp::min(length_lmcpos, limit as u16);
                let distance;
                if let &mut Some(ref mut subl) = sublen {
                    self.fetch_sublen(lmcpos, length as usize, subl);
                    distance = subl[length as usize];

                    if limit == ZOPFLI_MAX_MATCH && length >= ZOPFLI_MIN_MATCH as u16 {
                        assert!(subl[length as usize] == dist_lmcpos);
                    }
                } else {
                    distance = dist_lmcpos;
                }
                longest_match.distance = distance;
                longest_match.length = length;
                longest_match.from_cache = true;
                return longest_match;
            }
            /* Can't use much of the cache, since the "sublens" need to be calculated,
            but at least we already know when to stop. */
            limit = length_lmcpos as usize;
            longest_match.limit = limit;
        }

        longest_match
    }

    fn store(&mut self, pos: usize, limit: usize, sublen: &mut Option<&mut [u16]>, distance: u16, length: u16, blockstart: usize) {
        if let &mut Some(ref mut subl) = sublen {
            /* Length > 0 and dist 0 is invalid combination, which indicates on purpose
            that this cache value is not filled in yet. */
            let lmcpos = pos - blockstart;
            let cache_available = self.length_at(lmcpos) == 0 || self.dist_at(lmcpos) != 0;

            if limit == ZOPFLI_MAX_MATCH && !cache_available {
                assert!(self.length_at(lmcpos) == 1 && self.dist_at(lmcpos) == 0);
                if length < ZOPFLI_MIN_MATCH as u16 {
                    self.store_dist_at(lmcpos, 0);
                    self.store_length_at(lmcpos, 0);
                } else {
                    self.store_dist_at(lmcpos, distance);
                    self.store_length_at(lmcpos, length);
                }
                assert!(!(self.length_at(lmcpos) == 1 && self.dist_at(lmcpos) == 0));
                self.store_sublen(subl, lmcpos, length as usize);
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Prepared statements cache for faster execution.

use std::cell::RefCell;
use std::collections::VecDeque;
use std::ops::{Deref, DerefMut};
use {Result, Connection, Statement};

/// Prepared statements LRU cache.
#[derive(Debug)]
pub struct StatementCache<'conn> {
    conn: &'conn Connection,
    cache: RefCell<VecDeque<Statement<'conn>>>, // back = LRU
}

/// Cacheable statement.
///
/// Statement will return automatically to the cache by default.
/// If you want the statement to be discarded, you can set the `cacheable` flag to `false`.
pub struct CachedStatement<'c: 's, 's> {
    stmt: Option<Statement<'c>>,
    cache: &'s StatementCache<'c>,
    pub cacheable: bool,
}

impl<'c, 's> Deref for CachedStatement<'c, 's> {
    type Target = Statement<'c>;

    fn deref(&self) -> &Statement<'c> {
        self.stmt.as_ref().unwrap()
    }
}

impl<'c, 's> DerefMut for CachedStatement<'c, 's> {
    fn deref_mut(&mut self) -> &mut Statement<'c> {
        self.stmt.as_mut().unwrap()
    }
}

impl<'c, 's> Drop for CachedStatement<'c, 's> {
    #[allow(unused_must_use)]
    fn drop(&mut self) {
        if self.cacheable {
            self.cache.release(self.stmt.take().unwrap());
        } else {
            self.stmt.take().unwrap().finalize();
        }
    }
}

impl<'c, 's> CachedStatement<'c, 's> {
    fn new(stmt: Statement<'c>, cache: &'s StatementCache<'c>) -> CachedStatement<'c, 's> {
        CachedStatement {
            stmt: Some(stmt),
            cache: cache,
            cacheable: true,
        }
    }
}

impl<'conn> StatementCache<'conn> {
    /// Create a statement cache.
    pub fn new(conn: &'conn Connection, capacity: usize) -> StatementCache<'conn> {
        StatementCache {
            conn: conn,
            cache: RefCell::new(VecDeque::with_capacity(capacity)),
        }
    }

    /// Search the cache for a prepared-statement object that implements `sql`.
    // If no such prepared-statement can be found, allocate and prepare a new one.
    ///
    /// # Failure
    ///
    /// Will return `Err` if no cached statement can be found and the underlying SQLite prepare call fails.
    pub fn get<'s>(&'s self, sql: &str) -> Result<CachedStatement<'conn, 's>> {
        let mut cache = self.cache.borrow_mut();
        let stmt = match cache.iter().rposition(|entry| entry.eq(sql)) {
            Some(index) => Ok(cache.swap_remove_front(index).unwrap()), // FIXME Not LRU compliant
            _ => self.conn.prepare(sql),
        };
        stmt.map(|stmt| CachedStatement::new(stmt, self))
    }

    /// If `discard` is true, then the statement is deleted immediately.
    /// Otherwise it is added to the LRU list and may be returned
    /// by a subsequent call to `get()`.
    ///
    /// # Failure
    ///
    /// Will return `Err` if `stmt` (or the already cached statement implementing the same SQL) statement is `discard`ed
    /// and the underlying SQLite finalize call fails.
    fn release(&self, mut stmt: Statement<'conn>) {
        let mut cache = self.cache.borrow_mut();
        if cache.capacity() == cache.len() {
            // is full
            cache.pop_back(); // LRU dropped
        }
        stmt.reset_if_needed();
        stmt.clear_bindings();
        cache.push_front(stmt)
    }

    /// Flush the prepared statement cache
    pub fn clear(&self) {
        self.cache.borrow_mut().clear();
    }

    /// Return current cache size.
    pub fn len(&self) -> usize {
        self.cache.borrow().len()
    }

    /// Return maximum cache size.
    pub fn capacity(&self) -> usize {
        self.cache.borrow().capacity()
    }
}

#[cfg(test)]
mod test {
    use Connection;
    use super::StatementCache;

    #[test]
    fn test_cache() {
        let db = Connection::open_in_memory().unwrap();
        let cache = StatementCache::new(&db, 15);
        assert_eq!(0, cache.len());
        assert_eq!(15, cache.capacity());

        let sql = "PRAGMA schema_version";
        {
            let mut stmt = cache.get(sql).unwrap();
            assert_eq!(0, cache.len());
            assert_eq!(0,
                       stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32,i64>(0));
        }
        assert_eq!(1, cache.len());

        {
            let mut stmt = cache.get(sql).unwrap();
            assert_eq!(0, cache.len());
            assert_eq!(0,
                       stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32,i64>(0));
        }
        assert_eq!(1, cache.len());

        cache.clear();
        assert_eq!(0, cache.len());
        assert_eq!(15, cache.capacity());
    }

    #[test]
    fn test_cacheable() {
        let db = Connection::open_in_memory().unwrap();
        let cache = StatementCache::new(&db, 15);

        let sql = "PRAGMA schema_version";
        {
            let mut stmt = cache.get(sql).unwrap();
            assert_eq!(0, cache.len());
            assert_eq!(0,
                       stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32,i64>(0));
            stmt.cacheable = false;
        }
        assert_eq!(0, cache.len());
    }
}
<commit_msg>Use `discard()` instead of `cacheable = false` to avoid prevent cached statements from returning to the cache.<commit_after>//! Prepared statements cache for faster execution.

use std::cell::RefCell;
use std::collections::VecDeque;
use std::ops::{Deref, DerefMut};
use {Result, Connection, Statement};

/// Prepared statements LRU cache.
#[derive(Debug)]
pub struct StatementCache<'conn> {
    conn: &'conn Connection,
    cache: RefCell<VecDeque<Statement<'conn>>>, // back = LRU
}

/// Cacheable statement.
///
/// Statement will return automatically to the cache by default.
/// If you want the statement to be discarded, call `discard()` on it.
pub struct CachedStatement<'c: 's, 's> {
    stmt: Option<Statement<'c>>,
    cache: &'s StatementCache<'c>,
}

impl<'c, 's> Deref for CachedStatement<'c, 's> {
    type Target = Statement<'c>;

    fn deref(&self) -> &Statement<'c> {
        self.stmt.as_ref().unwrap()
    }
}

impl<'c, 's> DerefMut for CachedStatement<'c, 's> {
    fn deref_mut(&mut self) -> &mut Statement<'c> {
        self.stmt.as_mut().unwrap()
    }
}

impl<'c, 's> Drop for CachedStatement<'c, 's> {
    #[allow(unused_must_use)]
    fn drop(&mut self) {
        if let Some(stmt) = self.stmt.take() {
            self.cache.release(stmt);
        }
    }
}

impl<'c, 's> CachedStatement<'c, 's> {
    fn new(stmt: Statement<'c>, cache: &'s StatementCache<'c>) -> CachedStatement<'c, 's> {
        CachedStatement {
            stmt: Some(stmt),
            cache: cache,
        }
    }

    pub fn discard(mut self) {
        self.stmt = None;
    }
}

impl<'conn> StatementCache<'conn> {
    /// Create a statement cache.
    pub fn new(conn: &'conn Connection, capacity: usize) -> StatementCache<'conn> {
        StatementCache {
            conn: conn,
            cache: RefCell::new(VecDeque::with_capacity(capacity)),
        }
    }

    /// Search the cache for a prepared-statement object that implements `sql`.
    /// If no such prepared-statement can be found, allocate and prepare a new one.
    ///
    /// # Failure
    ///
    /// Will return `Err` if no cached statement can be found and the underlying SQLite prepare call fails.
    pub fn get<'s>(&'s self, sql: &str) -> Result<CachedStatement<'conn, 's>> {
        let mut cache = self.cache.borrow_mut();
        let stmt = match cache.iter().rposition(|entry| entry.eq(sql)) {
            Some(index) => Ok(cache.swap_remove_front(index).unwrap()), // FIXME Not LRU compliant
            _ => self.conn.prepare(sql),
        };
        stmt.map(|stmt| CachedStatement::new(stmt, self))
    }

    /// If `discard` is true, then the statement is deleted immediately.
    /// Otherwise it is added to the LRU list and may be returned
    /// by a subsequent call to `get()`.
    ///
    /// # Failure
    ///
    /// Will return `Err` if `stmt` (or the already cached statement implementing the same SQL) statement is `discard`ed
    /// and the underlying SQLite finalize call fails.
    fn release(&self, mut stmt: Statement<'conn>) {
        let mut cache = self.cache.borrow_mut();
        if cache.capacity() == cache.len() {
            // is full
            cache.pop_back(); // LRU dropped
        }
        stmt.reset_if_needed();
        stmt.clear_bindings();
        cache.push_front(stmt)
    }

    /// Flush the prepared statement cache
    pub fn clear(&self) {
        self.cache.borrow_mut().clear();
    }

    /// Return current cache size.
    pub fn len(&self) -> usize {
        self.cache.borrow().len()
    }

    /// Return maximum cache size.
    pub fn capacity(&self) -> usize {
        self.cache.borrow().capacity()
    }
}

#[cfg(test)]
mod test {
    use Connection;
    use super::StatementCache;

    #[test]
    fn test_cache() {
        let db = Connection::open_in_memory().unwrap();
        let cache = StatementCache::new(&db, 15);
        assert_eq!(0, cache.len());
        assert_eq!(15, cache.capacity());

        let sql = "PRAGMA schema_version";
        {
            let mut stmt = cache.get(sql).unwrap();
            assert_eq!(0, cache.len());
            assert_eq!(0,
                       stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32,i64>(0));
        }
        assert_eq!(1, cache.len());

        {
            let mut stmt = cache.get(sql).unwrap();
            assert_eq!(0, cache.len());
            assert_eq!(0,
                       stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32,i64>(0));
        }
        assert_eq!(1, cache.len());

        cache.clear();
        assert_eq!(0, cache.len());
        assert_eq!(15, cache.capacity());
    }

    #[test]
    fn test_discard() {
        let db = Connection::open_in_memory().unwrap();
        let cache = StatementCache::new(&db, 15);

        let sql = "PRAGMA schema_version";
        {
            let mut stmt = cache.get(sql).unwrap();
            assert_eq!(0, cache.len());
            assert_eq!(0,
                       stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32,i64>(0));
            stmt.discard();
        }
        assert_eq!(0, cache.len());
    }
}
<|endoftext|>