<commit_before>// This is a part of rust-encoding.
// Copyright (c) 2013-2015, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

//! Internal utilities.

use std::{str, char, mem};
use std::marker::PhantomData;
use std::convert::Into;
use std::default::Default;
use types;

/// Unchecked conversion to `char`.
pub fn as_char(ch: u32) -> char {
    debug_assert!(char::from_u32(ch).is_some());
    unsafe { mem::transmute(ch) }
}

/// External iterator for a string's characters with its corresponding byte offset range.
pub struct StrCharIndexIterator<'r> {
    index: usize,
    chars: str::Chars<'r>,
}

impl<'r> Iterator for StrCharIndexIterator<'r> {
    type Item = ((usize,usize), char);

    #[inline]
    fn next(&mut self) -> Option<((usize,usize), char)> {
        if let Some(ch) = self.chars.next() {
            let prev = self.index;
            let next = prev + ch.len_utf8();
            self.index = next;
            Some(((prev, next), ch))
        } else {
            None
        }
    }
}

/// A trait providing an `index_iter` method.
pub trait StrCharIndex<'r> {
    fn index_iter(&self) -> StrCharIndexIterator<'r>;
}

impl<'r> StrCharIndex<'r> for &'r str {
    /// Iterates over each character with corresponding byte offset range.
    fn index_iter(&self) -> StrCharIndexIterator<'r> {
        StrCharIndexIterator { index: 0, chars: self.chars() }
    }
}

/// A helper struct for the stateful decoder DSL.
pub struct StatefulDecoderHelper<'a, St> {
    /// The current buffer.
    pub buf: &'a [u8],
    /// The current index to the buffer.
    pub pos: usize,
    /// The output buffer.
    pub output: &'a mut (types::StringWriter + 'a),
    /// The last codec error. The caller will later collect this.
    pub err: Option<types::CodecError>,
    /// A marker for the phantom type parameter `St`.
    _marker: PhantomData<St>,
}

impl<'a, St: Default> StatefulDecoderHelper<'a, St> {
    /// Makes a new decoder context out of given buffer and output callback.
    #[inline(always)]
    pub fn new(buf: &'a [u8],
               output: &'a mut (types::StringWriter + 'a)) -> StatefulDecoderHelper<'a, St> {
        StatefulDecoderHelper { buf: buf, pos: 0, output: output, err: None, _marker: PhantomData }
    }

    /// Reads one byte from the buffer if any.
    #[inline(always)]
    pub fn read(&mut self) -> Option<u8> {
        match self.buf.get(self.pos) {
            Some(&c) => { self.pos += 1; Some(c) }
            None => None
        }
    }

    /// Resets back to the initial state.
    /// This should be the last expr in the rules.
    #[inline(always)]
    pub fn reset(&self) -> St {
        Default::default()
    }

    /// Writes one Unicode scalar value to the output.
    /// There is intentionally no check for `c`, so the caller should ensure that it's valid.
    /// If this is the last expr in the rules, also resets back to the initial state.
    #[inline(always)]
    pub fn emit(&mut self, c: u32) -> St {
        self.output.write_char(unsafe {mem::transmute(c)});
        Default::default()
    }

    /// Writes a Unicode string to the output.
    /// If this is the last expr in the rules, also resets back to the initial state.
    #[inline(always)]
    pub fn emit_str(&mut self, s: &str) -> St {
        self.output.write_str(s);
        Default::default()
    }

    /// Issues a codec error with given message at the current position.
    /// If this is the last expr in the rules, also resets back to the initial state.
    #[inline(always)]
    pub fn err(&mut self, msg: &'static str) -> St {
        self.err = Some(types::CodecError { upto: self.pos as isize, cause: msg.into() });
        Default::default()
    }

    /// Issues a codec error with given message at the current position minus `backup` bytes.
    /// If this is the last expr in the rules, also resets back to the initial state.
    ///
    /// This should be used to implement "prepending byte to the stream" in the Encoding spec,
    /// which corresponds to `ctx.backup_and_err(1, ...)`.
    #[inline(always)]
    pub fn backup_and_err(&mut self, backup: usize, msg: &'static str) -> St {
        let upto = self.pos as isize - backup as isize;
        self.err = Some(types::CodecError { upto: upto, cause: msg.into() });
        Default::default()
    }
}

/// Defines a stateful decoder from given state machine.
macro_rules! stateful_decoder(
    (
        $(#[$decmeta:meta])*
        struct $dec:ident;
        module $stmod:ident; // should be unique from other existing identifiers
        ascii_compatible $asciicompat:expr;
        $(internal $item:item)* // will only be visible from state functions
    initial:
        state $inist:ident($inictx:ident: Context) {
            $(case $($inilhs:pat),+ => $($inirhs:expr),+;)+
            final => $($inifin:expr),+;
        }
    checkpoint:
        $(state $ckst:ident($ckctx:ident: Context $(, $ckarg:ident: $ckty:ty)*) {
            $(case $($cklhs:pat),+ => $($ckrhs:expr),+;)+
            final => $($ckfin:expr),+;
        })*
    transient:
        $(state $st:ident($ctx:ident: Context $(, $arg:ident: $ty:ty)*) {
            $(case $($lhs:pat),+ => $($rhs:expr),+;)+
            final => $($fin:expr),+;
        })*
    ) => (
        $(#[$decmeta])*
        pub struct $dec {
            st: $stmod::State
        }

        #[allow(non_snake_case)]
        mod $stmod {
            pub use self::State::*;
            #[derive(PartialEq,Clone,Copy)]
            pub enum State {
                $inist,
                $(
                    $ckst(() $(, $ckty)*),
                )*
                $(
                    $st(() $(, $ty)*),
                )*
            }

            impl ::std::default::Default for State {
                #[inline(always)] fn default() -> State { $inist }
            }

            pub mod internal {
                pub type Context<'a> = ::util::StatefulDecoderHelper<'a, super::State>;

                $($item)*
            }

            pub mod start {
                use super::internal::*;

                #[inline(always)]
                pub fn $inist($inictx: &mut Context) -> super::State {
                    // prohibits all kind of recursions, including self-recursions
                    #[allow(unused_imports)] use super::transient::*;
                    match $inictx.read() {
                        None => super::$inist,
                        Some(c) => match c { $($($inilhs)|+ => { $($inirhs);+ })+ },
                    }
                }

                $(
                    #[inline(always)]
                    pub fn $ckst($ckctx: &mut Context $(, $ckarg: $ckty)*) -> super::State {
                        // prohibits all kind of recursions, including self-recursions
                        #[allow(unused_imports)] use super::transient::*;
                        match $ckctx.read() {
                            None => super::$ckst(() $(, $ckarg)*),
                            Some(c) => match c { $($($cklhs)|+ => { $($ckrhs);+ })+ },
                        }
                    }
                )*
            }

            pub mod transient {
                use super::internal::*;

                #[inline(always)]
                #[allow(dead_code)]
                pub fn $inist(_: &mut Context) -> super::State {
                    super::$inist // do not recurse further
                }

                $(
                    #[inline(always)]
                    #[allow(dead_code)]
                    pub fn $ckst(_: &mut Context $(, $ckarg: $ckty)*) -> super::State {
                        super::$ckst(() $(, $ckarg)*) // do not recurse further
                    }
                )*

                $(
                    #[inline(always)]
                    pub fn $st($ctx: &mut Context $(, $arg: $ty)*) -> super::State {
                        match $inictx.read() {
                            None => super::$st(() $(, $arg)*),
                            Some(c) => match c { $($($lhs)|+ => { $($rhs);+ })+ },
                        }
                    }
                )*
            }
        }

        impl $dec {
            pub fn new() -> Box<RawDecoder> {
                Box::new($dec { st: $stmod::$inist })
            }
        }

        impl RawDecoder for $dec {
            fn from_self(&self) -> Box<RawDecoder> { $dec::new() }
            fn is_ascii_compatible(&self) -> bool { $asciicompat }

            fn raw_feed(&mut self, input: &[u8],
                        output: &mut StringWriter) -> (usize, Option<CodecError>) {
                use self::$stmod::{start, transient};

                output.writer_hint(input.len());

                let mut ctx = ::util::StatefulDecoderHelper::new(input, output);
                let mut processed = 0;
                let mut st = self.st;

                let st_ = match st {
                    $stmod::$inist => $stmod::$inist,
                    $(
                        $stmod::$ckst(() $(, $ckarg)*) => start::$ckst(&mut ctx $(, $ckarg)*),
                    )*
                    $(
                        $stmod::$st(() $(, $arg)*) => transient::$st(&mut ctx $(, $arg)*),
                    )*
                };
                match (ctx.err.take(), st_) {
                    (None, $stmod::$inist) $(| (None, $stmod::$ckst(..)))* =>
                        { st = st_; processed = ctx.pos; }
                    // XXX splitting the match case improves the performance somehow, but why?
                    (None, _) => { self.st = st_; return (processed, None); }
                    (Some(err), _) => { self.st = st_; return (processed, Some(err)); }
                }

                while ctx.pos < ctx.buf.len() {
                    let st_ = match st {
                        $stmod::$inist => start::$inist(&mut ctx),
                        $(
                            $stmod::$ckst(() $(, $ckarg)*) => start::$ckst(&mut ctx $(, $ckarg)*),
                        )*
                        _ => unreachable!(),
                    };
                    match (ctx.err.take(), st_) {
                        (None, $stmod::$inist) $(| (None, $stmod::$ckst(..)))* =>
                            { st = st_; processed = ctx.pos; }
                        // XXX splitting the match case improves the performance somehow, but why?
                        (None, _) => { self.st = st_; return (processed, None); }
                        (Some(err), _) => { self.st = st_; return (processed, Some(err)); }
                    }
                }

                self.st = st;
                (processed, None)
            }

            fn raw_finish(&mut self, output: &mut StringWriter) -> Option<CodecError> {
                #![allow(unused_mut, unused_variables)]
                let mut ctx = ::util::StatefulDecoderHelper::new(&[], output);
                self.st = match ::std::mem::replace(&mut self.st, $stmod::$inist) {
                    $stmod::$inist => { let $inictx = &mut ctx; $($inifin);+ },
                    $(
                        $stmod::$ckst(() $(, $ckarg)*) => { let $ckctx = &mut ctx; $($ckfin);+ },
                    )*
                    $(
                        $stmod::$st(() $(, $arg)*) => { let $ctx = &mut ctx; $($fin);+ },
                    )*
                };
                ctx.err.take()
            }
        }
    )
);

/// Defines an ASCII-compatible stateful decoder from given state machine.
macro_rules! ascii_compatible_stateful_decoder(
    (
        $(#[$decmeta:meta])*
        struct $dec:ident;
        module $stmod:ident; // should be unique from other existing identifiers
        $(internal $item:item)* // will only be visible from state functions
    initial:
        state $inist:ident($inictx:ident: Context) {
            $(case $($inilhs:pat),+ => $($inirhs:expr),+;)+
        }
    transient:
        $(state $st:ident($ctx:ident: Context $(, $arg:ident: $ty:ty)*) {
            $(case $($lhs:pat),+ => $($rhs:expr),+;)+
        })*
    ) => (
        stateful_decoder!(
            $(#[$decmeta])*
            struct $dec;
            module $stmod;
            ascii_compatible true;
            $(internal $item)*
        initial:
            state $inist($inictx: Context) {
                $(case $($inilhs),+ => $($inirhs),+;)+
                final => $inictx.reset();
            }
        checkpoint:
        transient:
            $(state $st($ctx: Context $(, $arg: $ty)*) {
                $(case $($lhs),+ => $($rhs),+;)+
                final => $ctx.err("incomplete sequence");
            })*
        );
    )
);

<commit_msg>refactored the generated decoder functions into the impl mod.<commit_after>// This is a part of rust-encoding.
// Copyright (c) 2013-2015, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

//! Internal utilities.

use std::{str, char, mem};
use std::marker::PhantomData;
use std::convert::Into;
use std::default::Default;
use types;

/// Unchecked conversion to `char`.
pub fn as_char(ch: u32) -> char {
    debug_assert!(char::from_u32(ch).is_some());
    unsafe { mem::transmute(ch) }
}

/// External iterator for a string's characters with its corresponding byte offset range.
pub struct StrCharIndexIterator<'r> {
    index: usize,
    chars: str::Chars<'r>,
}

impl<'r> Iterator for StrCharIndexIterator<'r> {
    type Item = ((usize,usize), char);

    #[inline]
    fn next(&mut self) -> Option<((usize,usize), char)> {
        if let Some(ch) = self.chars.next() {
            let prev = self.index;
            let next = prev + ch.len_utf8();
            self.index = next;
            Some(((prev, next), ch))
        } else {
            None
        }
    }
}

/// A trait providing an `index_iter` method.
pub trait StrCharIndex<'r> {
    fn index_iter(&self) -> StrCharIndexIterator<'r>;
}

impl<'r> StrCharIndex<'r> for &'r str {
    /// Iterates over each character with corresponding byte offset range.
    fn index_iter(&self) -> StrCharIndexIterator<'r> {
        StrCharIndexIterator { index: 0, chars: self.chars() }
    }
}

/// A helper struct for the stateful decoder DSL.
pub struct StatefulDecoderHelper<'a, St, Data: 'a> {
    /// The current buffer.
    pub buf: &'a [u8],
    /// The current index to the buffer.
    pub pos: usize,
    /// The output buffer.
    pub output: &'a mut (types::StringWriter + 'a),
    /// The last codec error. The caller will later collect this.
    pub err: Option<types::CodecError>,
    /// The additional data attached for the use from transition functions.
    pub data: &'a Data,
    /// A marker for the phantom type parameter `St`.
    _marker: PhantomData<St>,
}

impl<'a, St: Default, Data> StatefulDecoderHelper<'a, St, Data> {
    /// Makes a new decoder context out of given buffer and output callback.
    #[inline(always)]
    pub fn new(buf: &'a [u8], output: &'a mut (types::StringWriter + 'a),
               data: &'a Data) -> StatefulDecoderHelper<'a, St, Data> {
        StatefulDecoderHelper { buf: buf, pos: 0, output: output, err: None,
                                data: data, _marker: PhantomData }
    }

    /// Reads one byte from the buffer if any.
    #[inline(always)]
    pub fn read(&mut self) -> Option<u8> {
        match self.buf.get(self.pos) {
            Some(&c) => { self.pos += 1; Some(c) }
            None => None
        }
    }

    /// Resets back to the initial state.
    /// This should be the last expr in the rules.
    #[inline(always)]
    pub fn reset(&self) -> St {
        Default::default()
    }

    /// Writes one Unicode scalar value to the output.
    /// There is intentionally no check for `c`, so the caller should ensure that it's valid.
    /// If this is the last expr in the rules, also resets back to the initial state.
    #[inline(always)]
    pub fn emit(&mut self, c: u32) -> St {
        self.output.write_char(unsafe {mem::transmute(c)});
        Default::default()
    }

    /// Writes a Unicode string to the output.
    /// If this is the last expr in the rules, also resets back to the initial state.
    #[inline(always)]
    pub fn emit_str(&mut self, s: &str) -> St {
        self.output.write_str(s);
        Default::default()
    }

    /// Issues a codec error with given message at the current position.
    /// If this is the last expr in the rules, also resets back to the initial state.
    #[inline(always)]
    pub fn err(&mut self, msg: &'static str) -> St {
        self.err = Some(types::CodecError { upto: self.pos as isize, cause: msg.into() });
        Default::default()
    }

    /// Issues a codec error with given message at the current position minus `backup` bytes.
    /// If this is the last expr in the rules, also resets back to the initial state.
    ///
    /// This should be used to implement "prepending byte to the stream" in the Encoding spec,
    /// which corresponds to `ctx.backup_and_err(1, ...)`.
    #[inline(always)]
    pub fn backup_and_err(&mut self, backup: usize, msg: &'static str) -> St {
        let upto = self.pos as isize - backup as isize;
        self.err = Some(types::CodecError { upto: upto, cause: msg.into() });
        Default::default()
    }
}

/// Defines a stateful decoder from given state machine.
macro_rules! stateful_decoder(
    (
        $(#[$decmeta:meta])*
        struct $dec:ident;
        module $stmod:ident; // should be unique from other existing identifiers
        ascii_compatible $asciicompat:expr;
        $(internal $item:item)* // will only be visible from state functions
    initial:
        state $inist:ident($inictx:ident: Context) {
            $(case $($inilhs:pat),+ => $($inirhs:expr),+;)+
            final => $($inifin:expr),+;
        }
    checkpoint:
        $(state $ckst:ident($ckctx:ident: Context $(, $ckarg:ident: $ckty:ty)*) {
            $(case $($cklhs:pat),+ => $($ckrhs:expr),+;)+
            final => $($ckfin:expr),+;
        })*
    transient:
        $(state $st:ident($ctx:ident: Context $(, $arg:ident: $ty:ty)*) {
            $(case $($lhs:pat),+ => $($rhs:expr),+;)+
            final => $($fin:expr),+;
        })*
    ) => (
        $(#[$decmeta])*
        pub struct $dec {
            st: $stmod::State
        }

        #[allow(non_snake_case)]
        mod $stmod {
            pub use self::State::*;
            #[derive(PartialEq,Clone,Copy)]
            pub enum State {
                $inist,
                $(
                    $ckst(() $(, $ckty)*),
                )*
                $(
                    $st(() $(, $ty)*),
                )*
            }

            impl ::std::default::Default for State {
                #[inline(always)] fn default() -> State { $inist }
            }

            pub mod internal {
                pub type Context<'a, Data> = ::util::StatefulDecoderHelper<'a, super::State, Data>;

                $($item)*
            }

            pub mod start {
                use super::internal::*;

                #[inline(always)]
                pub fn $inist<T>($inictx: &mut Context<T>) -> super::State {
                    // prohibits all kind of recursions, including self-recursions
                    #[allow(unused_imports)] use super::transient::*;
                    match $inictx.read() {
                        None => super::$inist,
                        Some(c) => match c { $($($inilhs)|+ => { $($inirhs);+ })+ },
                    }
                }

                $(
                    #[inline(always)]
                    pub fn $ckst<T>($ckctx: &mut Context<T> $(, $ckarg: $ckty)*) -> super::State {
                        // prohibits all kind of recursions, including self-recursions
                        #[allow(unused_imports)] use super::transient::*;
                        match $ckctx.read() {
                            None => super::$ckst(() $(, $ckarg)*),
                            Some(c) => match c { $($($cklhs)|+ => { $($ckrhs);+ })+ },
                        }
                    }
                )*
            }

            pub mod transient {
                use super::internal::*;

                #[inline(always)]
                #[allow(dead_code)]
                pub fn $inist<T>(_: &mut Context<T>) -> super::State {
                    super::$inist // do not recurse further
                }

                $(
                    #[inline(always)]
                    #[allow(dead_code)]
                    pub fn $ckst<T>(_: &mut Context<T> $(, $ckarg: $ckty)*) -> super::State {
                        super::$ckst(() $(, $ckarg)*) // do not recurse further
                    }
                )*

                $(
                    #[inline(always)]
                    pub fn $st<T>($ctx: &mut Context<T> $(, $arg: $ty)*) -> super::State {
                        match $inictx.read() {
                            None => super::$st(() $(, $arg)*),
                            Some(c) => match c { $($($lhs)|+ => { $($rhs);+ })+ },
                        }
                    }
                )*
            }

            pub fn raw_feed<T>(mut st: State, input: &[u8], output: &mut ::types::StringWriter,
                               data: &T) -> (State, usize, Option<::types::CodecError>) {
                output.writer_hint(input.len());

                let mut ctx = ::util::StatefulDecoderHelper::new(input, output, data);
                let mut processed = 0;

                let st_ = match st {
                    $inist => $inist,
                    $(
                        $ckst(() $(, $ckarg)*) => start::$ckst(&mut ctx $(, $ckarg)*),
                    )*
                    $(
                        $st(() $(, $arg)*) => transient::$st(&mut ctx $(, $arg)*),
                    )*
                };
                match (ctx.err.take(), st_) {
                    (None, $inist) $(| (None, $ckst(..)))* => { st = st_; processed = ctx.pos; }
                    // XXX splitting the match case improves the performance somehow, but why?
                    (None, _) => { return (st_, processed, None); }
                    (Some(err), _) => { return (st_, processed, Some(err)); }
                }

                while ctx.pos < ctx.buf.len() {
                    let st_ = match st {
                        $inist => start::$inist(&mut ctx),
                        $(
                            $ckst(() $(, $ckarg)*) => start::$ckst(&mut ctx $(, $ckarg)*),
                        )*
                        _ => unreachable!(),
                    };
                    match (ctx.err.take(), st_) {
                        (None, $inist) $(| (None, $ckst(..)))* => { st = st_; processed = ctx.pos; }
                        // XXX splitting the match case improves the performance somehow, but why?
                        (None, _) => { return (st_, processed, None); }
                        (Some(err), _) => { return (st_, processed, Some(err)); }
                    }
                }

                (st, processed, None)
            }

            pub fn raw_finish<T>(mut st: State, output: &mut ::types::StringWriter,
                                 data: &T) -> (State, Option<::types::CodecError>) {
                #![allow(unused_mut, unused_variables)]
                let mut ctx = ::util::StatefulDecoderHelper::new(&[], output, data);
                let st = match ::std::mem::replace(&mut st, $inist) {
                    $inist => { let $inictx = &mut ctx; $($inifin);+ },
                    $(
                        $ckst(() $(, $ckarg)*) => { let $ckctx = &mut ctx; $($ckfin);+ },
                    )*
                    $(
                        $st(() $(, $arg)*) => { let $ctx = &mut ctx; $($fin);+ },
                    )*
                };
                (st, ctx.err.take())
            }
        }

        impl $dec {
            pub fn new() -> Box<RawDecoder> {
                Box::new($dec { st: $stmod::$inist })
            }
        }

        impl RawDecoder for $dec {
            fn from_self(&self) -> Box<RawDecoder> { $dec::new() }
            fn is_ascii_compatible(&self) -> bool { $asciicompat }

            fn raw_feed(&mut self, input: &[u8],
                        output: &mut StringWriter) -> (usize, Option<CodecError>) {
                let (st, processed, err) = $stmod::raw_feed(self.st, input, output, &());
                self.st = st;
                (processed, err)
            }

            fn raw_finish(&mut self, output: &mut StringWriter) -> Option<CodecError> {
                let (st, err) = $stmod::raw_finish(self.st, output, &());
                self.st = st;
                err
            }
        }
    )
);

/// Defines an ASCII-compatible stateful decoder from given state machine.
macro_rules! ascii_compatible_stateful_decoder(
    (
        $(#[$decmeta:meta])*
        struct $dec:ident;
        module $stmod:ident; // should be unique from other existing identifiers
        $(internal $item:item)* // will only be visible from state functions
    initial:
        state $inist:ident($inictx:ident: Context) {
            $(case $($inilhs:pat),+ => $($inirhs:expr),+;)+
        }
    transient:
        $(state $st:ident($ctx:ident: Context $(, $arg:ident: $ty:ty)*) {
            $(case $($lhs:pat),+ => $($rhs:expr),+;)+
        })*
    ) => (
        stateful_decoder!(
            $(#[$decmeta])*
            struct $dec;
            module $stmod;
            ascii_compatible true;
            $(internal $item)*
        initial:
            state $inist($inictx: Context) {
                $(case $($inilhs),+ => $($inirhs),+;)+
                final => $inictx.reset();
            }
        checkpoint:
        transient:
            $(state $st($ctx: Context $(, $arg: $ty)*) {
                $(case $($lhs),+ => $($rhs),+;)+
                final => $ctx.err("incomplete sequence");
            })*
        );
    )
);

<|endoftext|>


<commit_before>use std::mem;
use slsr_core::geom::{Geom, Move};
use slsr_core::puzzle::Puzzle;

use ::SolverResult;
use ::model::side_map::SideMap;
use ::model::theorem::{Pattern, Theorem, TheoremMatcher};

#[derive(Clone, Debug)]
pub struct TheoremPool {
    data: Vec<TheoremMatcher>
}

impl TheoremPool {
    pub fn new<'a, T>(theo_defs: T,
                      puzzle: &Puzzle,
                      sum_of_hint: u32,
                      side_map: &mut SideMap)
                      -> SolverResult<TheoremPool>
        where T: IntoIterator<Item=Theorem>
    {
        let it = theo_defs
            .into_iter()
            .flat_map(|theo| theo.all_rotations());

        let mut hint_theorem = [vec![], vec![], vec![], vec![], vec![]];
        let mut nonhint_theorem = vec![];

        for theo in it {
            match theo.head() {
                Pattern::Hint(h) => hint_theorem[h.hint() as usize].push(theo),
                _ => nonhint_theorem.push(theo)
            }
        }

        let mut data = vec![];

        for p in puzzle.points() {
            if let Some(x) = puzzle.hint(p) {
                for theo in &hint_theorem[x as usize] {
                    let o = match theo.head() {
                        Pattern::Hint(hint) => hint.point(),
                        _ => panic!()
                    };
                    let matcher = theo.clone().shift(p - o);
                    try!(matcher.matches(puzzle, sum_of_hint, side_map))
                        .update(side_map, &mut data);
                }
            }
        }

        for theo in nonhint_theorem {
            let sz = theo.size();
            for r in (1 - sz.0)..(puzzle.row() + sz.0 - 1) {
                for c in (1 - sz.1)..(puzzle.column() + sz.1 - 1) {
                    let matcher = theo.clone().shift(Move(r, c));
                    try!(matcher.matches(puzzle, sum_of_hint, side_map))
                        .update(side_map, &mut data);
                }
            }
        }

        let mut pool = TheoremPool { data: data };
        pool.merge_dup();

        Ok(pool)
    }

    pub fn apply_all(&mut self, side_map: &mut SideMap) -> SolverResult<()> {
        let cap = self.data.len();

        for matcher in mem::replace(&mut self.data, Vec::with_capacity(cap)) {
            try!(matcher.matches(side_map))
                .update(side_map, &mut self.data);
        }

        Ok(())
    }

    fn merge_dup(&mut self) {
        self.data.sort();
        // Merge elements that have same matchers.
        unsafe {
            let len = self.data.len();
            let p = self.data.as_mut_ptr();

            let mut w = 1;
            for r in 1..len {
                let read = p.offset(r as isize);
                let cmp = p.offset((w - 1) as isize);

                match (*cmp).merge(&*read) {
                    Ok(()) => {}
                    Err(()) => {
                        let write = cmp.offset(1);
                        mem::swap(&mut *write, &mut *read);
                        w += 1;
                    }
                }
            }

            self.data.truncate(w);
        }
    }
}
<commit_msg>solver: Reduce theorem numbers in pool<commit_after>use std::mem;
use slsr_core::geom::{Geom, Move};
use slsr_core::puzzle::Puzzle;

use ::SolverResult;
use ::model::side_map::SideMap;
use ::model::theorem::{Pattern, Theorem, TheoremMatcher};

#[derive(Clone, Debug)]
pub struct TheoremPool {
    data: Vec<TheoremMatcher>
}

impl TheoremPool {
    pub fn new<'a, T>(theo_defs: T,
                      puzzle: &Puzzle,
                      sum_of_hint: u32,
                      side_map: &mut SideMap)
                      -> SolverResult<TheoremPool>
        where T: IntoIterator<Item=Theorem>
    {
        let it = theo_defs
            .into_iter()
            .flat_map(|theo| theo.all_rotations());

        let mut hint_theorem = [vec![], vec![], vec![], vec![], vec![]];
        let mut nonhint_theorem = vec![];

        for theo in it {
            match theo.head() {
                Pattern::Hint(h) => hint_theorem[h.hint() as usize].push(theo),
                _ => nonhint_theorem.push(theo)
            }
        }

        let mut data = vec![];

        for p in puzzle.points() {
            if let Some(x) = puzzle.hint(p) {
                for theo in &hint_theorem[x as usize] {
                    let o = match theo.head() {
                        Pattern::Hint(hint) => hint.point(),
                        _ => panic!()
                    };
                    let matcher = theo.clone().shift(p - o);
                    try!(matcher.matches(puzzle, sum_of_hint, side_map))
                        .update(side_map, &mut data);
                }
            }
        }

        for theo in nonhint_theorem {
            let sz = theo.size();
            for r in (1 - sz.0)..(puzzle.row() + sz.0 - 1) {
                for c in (1 - sz.1)..(puzzle.column() + sz.1 - 1) {
                    let matcher = theo.clone().shift(Move(r, c));
                    try!(matcher.matches(puzzle, sum_of_hint, side_map))
                        .update(side_map, &mut data);
                }
            }
        }

        let mut pool = TheoremPool { data: data };
        let mut rev = side_map.revision();
        loop {
            try!(pool.apply_all(side_map));
            if side_map.revision() == rev {
                break
            }
            rev = side_map.revision();
        }

        pool.merge_dup();

        Ok(pool)
    }

    pub fn apply_all(&mut self, side_map: &mut SideMap) -> SolverResult<()> {
        let cap = self.data.len();

        for matcher in mem::replace(&mut self.data, Vec::with_capacity(cap)) {
            try!(matcher.matches(side_map))
                .update(side_map, &mut self.data);
        }

        Ok(())
    }

    fn merge_dup(&mut self) {
        self.data.sort();
        // Merge elements that have same matchers.
        unsafe {
            let len = self.data.len();
            let p = self.data.as_mut_ptr();

            let mut w = 1;
            for r in 1..len {
                let read = p.offset(r as isize);
                let cmp = p.offset((w - 1) as isize);

                match (*cmp).merge(&*read) {
                    Ok(()) => {}
                    Err(()) => {
                        let write = cmp.offset(1);
                        mem::swap(&mut *write, &mut *read);
                        w += 1;
                    }
                }
            }

            self.data.truncate(w);
        }
    }
}
<|endoftext|>


<commit_before>//! Collection module for managing Algorithmia Data Collections
//!
//! # Examples
//!
//! ```no_run
//! use algorithmia::Service;
//! use std::fs::File;
//!
//! let service = Service::new("111112222233333444445555566");
//! let my_dir = service.collection("my_user/my_dir");
//!
//! my_dir.create();
//! let mut my_file = File::open("/path/to/file").unwrap();
//! my_dir.upload_file(&mut my_file);
//!
//! my_dir.write_file("some_filename", "file_contents".as_bytes());
//! ```

extern crate hyper;

use ::{Service, AlgorithmiaError, ApiErrorResponse, API_BASE_URL};
use hyper::Url;
use rustc_serialize::{json, Decoder};
use std::io::Read;
use std::fs::File;

static COLLECTION_BASE_PATH: &'static str = "data";

/// Algorithmia data collection
pub struct Collection<'a> {
    pub service: Service,
    pub path: &'a str,
}

pub type CollectionShowResult = Result<CollectionShow, AlgorithmiaError>;
pub type CollectionCreatedResult = Result<CollectionCreated, AlgorithmiaError>;
pub type CollectionDeletedResult = Result<CollectionDeleted, AlgorithmiaError>;
pub type CollectionFileAddedResult = Result<CollectionFileAdded, AlgorithmiaError>;
pub type CollectionFileDeletedResult = Result<CollectionFileDeleted, AlgorithmiaError>;

/// Permissions for a data collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionAcl {
    /// Readable by world
    pub read_w: bool,
    /// Readable by group
    pub read_g: bool,
    /// Readable by user
    pub read_u: bool,
    /// Readable by user's algorithms regardless who runs them
    pub read_a: bool,
}

/// Response when creating a new collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionCreated {
    pub collection_id: u32,
    pub object_id: String,
    pub collection_name: String,
    pub username: String,
    pub acl: CollectionAcl,
}

/// Response when deleting a new collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionDeleted {
    pub unknown: String,
}

/// Response when querying an existing collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionShow {
    pub username: String,
    pub collection_name: String,
    pub files: Vec<String>,
}

/// Response when adding a file to a collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionFileAdded {
    pub result: String
}

/// Response when deleting a file to a collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionFileDeleted {
    pub result: String
}

impl<'a> Collection<'a> {

    /// Get the parent path of a collection (i.e. unix `dirname`)
    ///
    /// ```
    /// # use algorithmia::Service;
    /// # let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// assert_eq!(my_dir.parent(), "my_user");
    /// ```
    pub fn parent(&self) -> &'a str {
        match &*self.path.rsplitn(1, "/").collect::<Vec<_>>() {
            [_, path] => path,
            _ => "/"
        }
    }

    /// Get the basename of the collection (i.e. unix `basename`)
    ///
    /// ```
    /// # use algorithmia::Service;
    /// # let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// assert_eq!(my_dir.basename(), "my_dir");
    /// ```
    pub fn basename(&self) -> &'a str {
        match &*self.path.rsplitn(1, "/").collect::<Vec<_>>() {
            [name, _] => name,
            _ => self.path
        }
    }

    /// Get the API Endpoint URL for a particular collection
    pub fn to_url(&self) -> Url {
        let url_string = format!("{}/{}/{}", API_BASE_URL, COLLECTION_BASE_PATH, self.path);
        Url::parse(&*url_string).unwrap()
    }

    /// Display collection details if it exists
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// match my_dir.show() {
    ///   Ok(dir) => println!("Files: {}", dir.files.connect(", ")),
    ///   Err(e) => println!("ERROR: {:?}", e),
    /// };
    /// ```
    pub fn show(&'a self) -> CollectionShowResult {
        let ref mut api_client = self.service.api_client();
        let req = api_client.get(self.to_url());

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        match json::decode::<CollectionShow>(&*res_json) {
            Ok(result) => Ok(result),
            Err(why) => match json::decode::<ApiErrorResponse>(&*res_json) {
                Ok(api_error) => Err(AlgorithmiaError::ApiError(api_error.error)),
                Err(_) => Err(AlgorithmiaError::DecoderErrorWithContext(why, res_json)),
            }
        }
    }

    /// Create a collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// match my_dir.create() {
    ///   Ok(_) => println!("Successfully created collection"),
    ///   Err(e) => println!("ERROR creating collection: {:?}", e),
    /// };
    /// ```
    pub fn create(&'a self) -> CollectionCreatedResult {
        // Construct URL
        let url_string = format!("{}/{}/{}", API_BASE_URL, COLLECTION_BASE_PATH, self.parent());
        let url = Url::parse(&*url_string).unwrap();

        // POST request
        let ref mut api_client = self.service.api_client();
        let req = api_client.post(url).body(self.basename());

        // Parse response
        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionCreated>(res_json)
    }

    /// Delete a collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// match my_dir.delete() {
    ///   Ok(_) => println!("Successfully deleted collection"),
    ///   Err(e) => println!("ERROR deleting collection: {:?}", e),
    /// };
    /// ```
    pub fn delete(&'a self) -> CollectionDeletedResult {
        // DELETE request
        let ref mut api_client = self.service.api_client();
        let req = api_client.delete(self.to_url());

        // Parse response
        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionDeleted>(res_json)
    }

    /// Upload a file to an existing collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// # use std::fs::File;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    ///
    /// let mut my_file = File::open("/path/to/file").unwrap();
    /// match my_dir.upload_file(&mut my_file) {
    ///   Ok(response) => println!("Successfully uploaded to: {}", response.result),
    ///   Err(e) => println!("ERROR uploading file: {:?}", e),
    /// };
    /// ```
    pub fn upload_file(&'a self, file: &mut File) -> CollectionFileAddedResult {
        let url_string = format!("{}/{}",
            self.to_url(),
            file.path().unwrap().file_name().unwrap().to_str().unwrap()
        );
        let url = Url::parse(&*url_string).unwrap();

        let ref mut api_client = self.service.api_client();
        let req = api_client.post(url).body(file);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionFileAdded>(res_json)
    }

    /// Write a file (raw bytes) directly to a data collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    ///
    /// match my_dir.write_file("some_filename", "file_contents".as_bytes()) {
    ///   Ok(response) => println!("Successfully uploaded to: {}", response.result),
    ///   Err(e) => println!("ERROR uploading file: {:?}", e),
    /// };
    /// ```
    pub fn write_file(&'a self, filename: &str, input_data: &[u8]) -> CollectionFileAddedResult {
        let url_string = format!("{}/{}", self.to_url(), filename);
        let url = Url::parse(&*url_string).unwrap();

        let ref mut api_client = self.service.api_client();
        let req = api_client.post(url).body(&*input_data);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionFileAdded>(res_json)
    }

    /// Delete a file from a data collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    ///
    /// match my_dir.delete_file("some_filename") {
    ///   Ok(_) => println!("Successfully deleted file"),
    ///   Err(e) => println!("ERROR deleting file: {:?}", e),
    /// };
    /// ```
    pub fn delete_file(&'a self, filename: &str) -> CollectionFileDeletedResult {
        let url_string = format!("{}/{}", self.to_url(), filename);
        let url = Url::parse(&*url_string).unwrap();

        let ref mut api_client = self.service.api_client();
        let req = api_client.delete(url);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionFileDeleted>(res_json)
    }

}

#[test]
fn test_to_url() {
    let collection = Collection { path: "anowell/foo", service: Service::new("")};
    assert_eq!(collection.to_url().serialize(), format!("{}/data/anowell/foo", API_BASE_URL));
}

#[test]
fn test_parent() {
    let collection = Collection { path: "anowell/foo", service: Service::new("")};
    assert_eq!(collection.parent(), "anowell");
}<commit_msg>Fix parent & basename to actually work<commit_after>//! Collection module for managing Algorithmia Data Collections
//!
//! # Examples
//!
//! ```no_run
//! use algorithmia::Service;
//! use std::fs::File;
//!
//! let service = Service::new("111112222233333444445555566");
//! let my_dir = service.collection("my_user/my_dir");
//!
//! my_dir.create();
//! let mut my_file = File::open("/path/to/file").unwrap();
//! my_dir.upload_file(&mut my_file);
//!
//! my_dir.write_file("some_filename", "file_contents".as_bytes());
//! ```

extern crate hyper;

use ::{Service, AlgorithmiaError, ApiErrorResponse, API_BASE_URL};
use hyper::Url;
use rustc_serialize::{json, Decoder};
use std::io::Read;
use std::fs::File;

static COLLECTION_BASE_PATH: &'static str = "data";

/// Algorithmia data collection
pub struct Collection<'a> {
    pub service: Service,
    pub path: &'a str,
}

pub type CollectionShowResult = Result<CollectionShow, AlgorithmiaError>;
pub type CollectionCreatedResult = Result<CollectionCreated, AlgorithmiaError>;
pub type CollectionDeletedResult = Result<CollectionDeleted, AlgorithmiaError>;
pub type CollectionFileAddedResult = Result<CollectionFileAdded, AlgorithmiaError>;
pub type CollectionFileDeletedResult = Result<CollectionFileDeleted, AlgorithmiaError>;

/// Permissions for a data collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionAcl {
    /// Readable by world
    pub read_w: bool,
    /// Readable by group
    pub read_g: bool,
    /// Readable by user
    pub read_u: bool,
    /// Readable by user's algorithms regardless who runs them
    pub read_a: bool,
}

/// Response when creating a new collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionCreated {
    pub collection_id: u32,
    pub object_id: String,
    pub collection_name: String,
    pub username: String,
    pub acl: CollectionAcl,
}

/// Response when deleting a new collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionDeleted {
    pub unknown: String,
}

/// Response when querying an existing collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionShow {
    pub username: String,
    pub collection_name: String,
    pub files: Vec<String>,
}

/// Response when adding a file to a collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionFileAdded {
    pub result: String
}

/// Response when deleting a file to a collection
#[derive(RustcDecodable, Debug)]
pub struct CollectionFileDeleted {
    pub result: String
}

impl<'a> Collection<'a> {

    /// Get the parent path of a collection (i.e. unix `dirname`)
    ///
    /// ```
    /// # use algorithmia::Service;
    /// # let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// assert_eq!(my_dir.parent(), "my_user");
    /// ```
    pub fn parent(&self) -> &'a str {
        match &*self.path.rsplitn(2, "/").collect::<Vec<_>>() {
            [_, path] => path,
            _ => "/"
        }
    }

    /// Get the basename of the collection (i.e. unix `basename`)
    ///
    /// ```
    /// # use algorithmia::Service;
    /// # let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// assert_eq!(my_dir.basename(), "my_dir");
    /// ```
    pub fn basename(&self) -> &'a str {
        match &*self.path.rsplitn(2, "/").collect::<Vec<_>>() {
            [name, _] => name,
            _ => self.path
        }
    }

    /// Get the API Endpoint URL for a particular collection
    pub fn to_url(&self) -> Url {
        let url_string = format!("{}/{}/{}", API_BASE_URL, COLLECTION_BASE_PATH, self.path);
        Url::parse(&*url_string).unwrap()
    }

    /// Display collection details if it exists
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// match my_dir.show() {
    ///   Ok(dir) => println!("Files: {}", dir.files.connect(", ")),
    ///   Err(e) => println!("ERROR: {:?}", e),
    /// };
    /// ```
    pub fn show(&'a self) -> CollectionShowResult {
        let ref mut api_client = self.service.api_client();
        let req = api_client.get(self.to_url());

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        match json::decode::<CollectionShow>(&*res_json) {
            Ok(result) => Ok(result),
            Err(why) => match json::decode::<ApiErrorResponse>(&*res_json) {
                Ok(api_error) => Err(AlgorithmiaError::ApiError(api_error.error)),
                Err(_) => Err(AlgorithmiaError::DecoderErrorWithContext(why, res_json)),
            }
        }
    }

    /// Create a collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// match my_dir.create() {
    ///   Ok(_) => println!("Successfully created collection"),
    ///   Err(e) => println!("ERROR creating collection: {:?}", e),
    /// };
    /// ```
    pub fn create(&'a self) -> CollectionCreatedResult {
        // Construct URL
        let url_string = format!("{}/{}/{}", API_BASE_URL, COLLECTION_BASE_PATH, self.parent());
        let url = Url::parse(&*url_string).unwrap();

        // POST request
        let ref mut api_client = self.service.api_client();
        let req = api_client.post(url).body(self.basename());

        // Parse response
        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionCreated>(res_json)
    }

    /// Delete a collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    /// match my_dir.delete() {
    ///   Ok(_) => println!("Successfully deleted collection"),
    ///   Err(e) => println!("ERROR deleting collection: {:?}", e),
    /// };
    /// ```
    pub fn delete(&'a self) -> CollectionDeletedResult {
        // DELETE request
        let ref mut api_client = self.service.api_client();
        let req = api_client.delete(self.to_url());

        // Parse response
        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionDeleted>(res_json)
    }

    /// Upload a file to an existing collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// # use std::fs::File;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    ///
    /// let mut my_file = File::open("/path/to/file").unwrap();
    /// match my_dir.upload_file(&mut my_file) {
    ///   Ok(response) => println!("Successfully uploaded to: {}", response.result),
    ///   Err(e) => println!("ERROR uploading file: {:?}", e),
    /// };
    /// ```
    pub fn upload_file(&'a self, file: &mut File) -> CollectionFileAddedResult {
        let url_string = format!("{}/{}",
            self.to_url(),
            file.path().unwrap().file_name().unwrap().to_str().unwrap()
        );
        let url = Url::parse(&*url_string).unwrap();

        let ref mut api_client = self.service.api_client();
        let req = api_client.post(url).body(file);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionFileAdded>(res_json)
    }

    /// Write a file (raw bytes) directly to a data collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    ///
    /// match my_dir.write_file("some_filename", "file_contents".as_bytes()) {
    ///   Ok(response) => println!("Successfully uploaded to: {}", response.result),
    ///   Err(e) => println!("ERROR uploading file: {:?}", e),
    /// };
    /// ```
    pub fn write_file(&'a self, filename: &str, input_data: &[u8]) -> CollectionFileAddedResult {
        let url_string = format!("{}/{}", self.to_url(), filename);
        let url = Url::parse(&*url_string).unwrap();

        let ref mut api_client = self.service.api_client();
        let req = api_client.post(url).body(&*input_data);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionFileAdded>(res_json)
    }

    /// Delete a file from a data collection
    ///
    /// # Examples
    /// ```no_run
    /// # use algorithmia::Service;
    /// # use algorithmia::collection::Collection;
    /// let service = Service::new("111112222233333444445555566");
    /// let my_dir = service.collection("my_user/my_dir");
    ///
    /// match my_dir.delete_file("some_filename") {
    ///   Ok(_) => println!("Successfully deleted file"),
    ///   Err(e) => println!("ERROR deleting file: {:?}", e),
    /// };
    /// ```
    pub fn delete_file(&'a self, filename: &str) -> CollectionFileDeletedResult {
        let url_string = format!("{}/{}", self.to_url(), filename);
        let url = Url::parse(&*url_string).unwrap();

        let ref mut api_client = self.service.api_client();
        let req = api_client.delete(url);

        let mut res = try!(req.send());
        let mut res_json = String::new();
        try!(res.read_to_string(&mut res_json));

        Service::decode_to_result::<CollectionFileDeleted>(res_json)
    }

}

#[test]
fn test_to_url() {
    let collection = Collection { path: "anowell/foo", service: Service::new("")};
    assert_eq!(collection.to_url().serialize(), format!("{}/data/anowell/foo", API_BASE_URL));
}

#[test]
fn test_parent() {
    let collection = Collection { path: "anowell/foo", service: Service::new("")};
    assert_eq!(collection.parent(), "anowell");
}<|endoftext|>


<commit_before>use std::net::{SocketAddr};
use std::time::{Duration, Instant};

use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
use tokio_core::io::{Io, Framed};
use tokio_timer::{Timer};
use futures::Future;
use futures::Sink;
use futures::Stream;
use futures::sync::mpsc;

use mqtt3::{Message, QoS, TopicPath};

use error::*;
use packet::*;
use codec::MqttCodec;
use clientoptions::MqttOptions;

pub struct Connection {
    pub addr: SocketAddr,
    pub state: MqttState,
    pub opts: MqttOptions,
    pub initial_connect: bool,
    pub await_pingresp: bool,
    pub last_flush: Instant,

    pub reactor: Core,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MqttState {
    Handshake,
    Connected,
    Disconnected,
}

#[derive(Debug)]
pub enum NetworkRequest {
    Subscribe(Vec<(TopicPath, QoS)>),
    Publish(Message),
    Retransmit,
    Shutdown,
    Disconnect,
    Ping,
}

#[derive(Debug)]
pub enum NetworkNotification {
    Disconnected,
    Connected,
}

// DESIGN: Initial connect status should be immediately known.
//        Intermediate disconnections should be automatically reconnected
fn _try_reconnect(addr: SocketAddr, reactor: &mut Core) -> Result<Framed<TcpStream, MqttCodec>, Error> {

    let connect = generate_connect_packet("".to_string(), true, None, None);

    let f_response = TcpStream::connect(&addr, &reactor.handle()).and_then(|connection| {
        let framed = connection.framed(MqttCodec);
        let f1 = framed.send(connect);

        f1.and_then(|framed| {
                framed.into_future()
                    .and_then(|(res, stream)| Ok((res, stream)))
                    .map_err(|(err, _stream)| err)
            })
            .boxed()
    });

    let response = reactor.run(f_response);
    let (packet, frame) = response?;
    println!("{:?}", packet);
    Ok(frame)
}

impl Connection {
    pub fn start(addr: SocketAddr, opts: MqttOptions) -> Result<(Self, Framed<TcpStream, MqttCodec>), Error> {
        let mut reactor = Core::new().unwrap();

        let framed = _try_reconnect(addr, &mut reactor)?;

        let connection = Connection {
            addr: addr,
            state: MqttState::Disconnected,
            opts: opts,
            initial_connect: true,
            await_pingresp: false,
            last_flush: Instant::now(),

            reactor: reactor,
        };

        Ok((connection, framed))
    }

    pub fn run(&mut self, framed: Framed<TcpStream, MqttCodec>) -> Result<(), Error> {
        let (mut sender, receiver) = framed.split();
        let rx_future = receiver.for_each(|msg| {
            print!("{:?}", msg);
            Ok(())
        }).map_err(|e| Error::Io(e));

        let (mut sender_tx, sender_rx) = mpsc::channel::<NetworkRequest>(1);

        // Ping timer
        let timer = Timer::default();

        let keep_alive = if self.opts.keep_alive.is_some() {
            self.opts.keep_alive.unwrap() as u64
        } else {
            1000
        };

        let interval = timer.interval(Duration::new(keep_alive, 0));
        let timer_future = interval.for_each(|_| {
                let ref mut sender_tx = sender_tx;
                sender_tx.send(NetworkRequest::Ping).wait().unwrap();
                Ok(())
            }).map_err(|e| Error::Timer(e));

        // Sender which does network writes
        let sender_future = sender_rx.for_each(move |r| {
            let packet = match r {
                NetworkRequest::Ping => {
                    println!("{:?}", r);
                    generate_pingreq_packet()
                }
                _ => panic!("Misc")
            };

            let _ = (&mut sender).send(packet).wait();
            Ok(())
        }).map_err(|_|Error::Sender);

        let mqtt_future =  timer_future.join3(rx_future, sender_future);

        let _ = self.reactor.run(mqtt_future)?;
        Ok(())
    }
}
<commit_msg>adding necessary state variable to connection struct<commit_after>use std::net::{SocketAddr};
use std::time::{Duration, Instant};
use std::collections::VecDeque;
use std::sync::Arc;

use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
use tokio_core::io::{Io, Framed};
use tokio_timer::{Timer};
use futures::Future;
use futures::Sink;
use futures::Stream;
use futures::sync::mpsc;

use mqtt3::{Message, QoS, TopicPath, PacketIdentifier, SubscribeTopic};

use error::*;
use packet::*;
use codec::MqttCodec;
use clientoptions::MqttOptions;

pub type MessageSendableFn = Box<Fn(Message) + Send + Sync>;
pub type PublishSendableFn = Box<Fn(Message) + Send + Sync>;

pub struct Connection {
    pub addr: SocketAddr,
    pub state: MqttState,
    pub opts: MqttOptions,
    pub initial_connect: bool,
    pub await_pingresp: bool,
    pub last_flush: Instant,

    pub no_of_reconnections: u32,

    /// On message callback
    pub message_callback: Option<Arc<MessageSendableFn>>,
    /// On publish callback
    pub publish_callback: Option<Arc<PublishSendableFn>>,

    // Queues. Note: 'record' is qos2 term for 'publish'
    /// For QoS 1. Stores outgoing publishes
    pub outgoing_pub: VecDeque<Box<Message>>,
    /// For QoS 2. Store for incoming publishes to record.
    pub incoming_rec: VecDeque<Box<Message>>, //
    /// For QoS 2. Store for outgoing publishes.
    pub outgoing_rec: VecDeque<PacketIdentifier>,
    /// For Qos2. Store for outgoing `pubrel` packets.
    pub outgoing_rel: VecDeque<PacketIdentifier>,
    /// For Qos2. Store for outgoing `pubcomp` packets.
    pub outgoing_comp: VecDeque<PacketIdentifier>,

    // clean_session=false will remember subscriptions only till lives.
    // If broker crashes, all its state will be lost (most brokers).
    // client wouldn't want to loose messages after it comes back up again
    pub subscriptions: VecDeque<Vec<SubscribeTopic>>,

    pub reactor: Core,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MqttState {
    Handshake,
    Connected,
    Disconnected,
}

#[derive(Debug)]
pub enum NetworkRequest {
    Subscribe(Vec<(TopicPath, QoS)>),
    Publish(Message),
    Retransmit,
    Shutdown,
    Disconnect,
    Ping,
}

#[derive(Debug)]
pub enum NetworkNotification {
    Disconnected,
    Connected,
}

// DESIGN: Initial connect status should be immediately known.
//        Intermediate disconnections should be automatically reconnected
fn _try_reconnect(addr: SocketAddr, reactor: &mut Core) -> Result<Framed<TcpStream, MqttCodec>, Error> {

    let connect = generate_connect_packet("".to_string(), true, None, None);

    let f_response = TcpStream::connect(&addr, &reactor.handle()).and_then(|connection| {
        let framed = connection.framed(MqttCodec);
        let f1 = framed.send(connect);

        f1.and_then(|framed| {
                framed.into_future()
                    .and_then(|(res, stream)| Ok((res, stream)))
                    .map_err(|(err, _stream)| err)
            })
            .boxed()
    });

    let response = reactor.run(f_response);
    let (packet, frame) = response?;
    println!("{:?}", packet);
    Ok(frame)
}

impl Connection {
    pub fn start(addr: SocketAddr,
                 opts: MqttOptions,
                 publish_callback: Option<Arc<PublishSendableFn>>,
                 message_callback: Option<Arc<MessageSendableFn>>) -> Result<(Self, Framed<TcpStream, MqttCodec>), Error> {
        let mut reactor = Core::new().unwrap();

        let framed = _try_reconnect(addr, &mut reactor)?;

        let connection = Connection {
            addr: addr,
            state: MqttState::Disconnected,
            opts: opts,
            initial_connect: true,
            await_pingresp: false,
            last_flush: Instant::now(),

            no_of_reconnections: 0,

            publish_callback: publish_callback,
            message_callback: message_callback,

            // Queues
            incoming_rec: VecDeque::new(),
            outgoing_pub: VecDeque::new(),
            outgoing_rec: VecDeque::new(),
            outgoing_rel: VecDeque::new(),
            outgoing_comp: VecDeque::new(),

            // Subscriptions
            subscriptions: VecDeque::new(),

            reactor: reactor,
        };

        Ok((connection, framed))
    }

    pub fn run(&mut self, framed: Framed<TcpStream, MqttCodec>) -> Result<(), Error> {
        let (mut sender, receiver) = framed.split();
        let rx_future = receiver.for_each(|msg| {
            print!("{:?}", msg);
            Ok(())
        }).map_err(|e| Error::Io(e));

        let (mut sender_tx, sender_rx) = mpsc::channel::<NetworkRequest>(1);

        // Ping timer
        let timer = Timer::default();

        let keep_alive = if self.opts.keep_alive.is_some() {
            self.opts.keep_alive.unwrap() as u64
        } else {
            1000
        };

        let interval = timer.interval(Duration::new(keep_alive, 0));
        let timer_future = interval.for_each(|_| {
                let ref mut sender_tx = sender_tx;
                sender_tx.send(NetworkRequest::Ping).wait().unwrap();
                Ok(())
            }).map_err(|e| Error::Timer(e));

        // Sender which does network writes
        let sender_future = sender_rx.for_each(move |r| {
            let packet = match r {
                NetworkRequest::Ping => {
                    println!("{:?}", r);
                    generate_pingreq_packet()
                }
                _ => panic!("Misc")
            };

            let _ = (&mut sender).send(packet).wait();
            Ok(())
        }).map_err(|_|Error::Sender);

        let mqtt_future =  timer_future.join3(rx_future, sender_future);

        let _ = self.reactor.run(mqtt_future)?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::collections::{VecDeque, HashMap, HashSet};

use rand::{self, Rng, ChaChaRng};

use ogg::{OggTrack, OggTrackBuf};
use ogg::vorbis::{Comments, VorbisHeader};

#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
pub struct Handle(pub u64);

struct HandleAllocator<R> {
    rng: R,
    limit: usize,
    allocated: HashSet<u64>,
}

impl<R> HandleAllocator<R> where R: Rng {
    pub fn new(rng: R, limit: usize) -> HandleAllocator<R> {
        HandleAllocator {
            rng: rng,
            limit: limit,
            allocated: HashSet::new(),
        }
    }

    pub fn generate(&mut self) -> Result<Handle, ()> {
        if self.limit <= self.allocated.len() {
            return Err(());
        }

        let new_handle;
        loop {
            let foo = self.rng.next_u64();
            if !self.allocated.contains(&foo) {
                new_handle = foo;
                break;
            }
        }

        println!("EMITTING HANDLE {:#x}", new_handle);
        self.allocated.insert(new_handle);
        Ok(Handle(new_handle))
    }

    pub fn dispose(&mut self, handle: Handle) -> Result<(), Handle> {
        match self.allocated.remove(&handle.0) {
            true => Ok(()),
            false => Err(handle),
        }
    }
}

struct Track {
    handle: Handle,
    data: OggTrackBuf,
    comments: Option<Comments>,
}

pub struct PlayQueue {
    halloc: HandleAllocator<ChaChaRng>,
    items: VecDeque<Track>,
}

impl PlayQueue {
    pub fn new(limit: usize) -> PlayQueue {
        let rng: ChaChaRng = rand::thread_rng().gen();
        PlayQueue {
            halloc: HandleAllocator::new(rng, limit),
            items: VecDeque::new(),
        }
    }

    pub fn reorder(&mut self, handle_ord: &[Handle]) {
        let old_items: VecDeque<Track> = mem::replace(&mut self.items, VecDeque::new());

        let mut map: HashMap<Handle, Track> = old_items.into_iter().map(|pq| (pq.handle, pq)).collect();

        for handle in handle_ord.iter() {
            match map.remove(handle) {
                Some(item) => {
                    self.items.push_back(item);
                },
                None => (),
            }
        }
    }

    pub fn remove_by_handle(&mut self, handle: Handle) {
        let old_items: VecDeque<Track> = mem::replace(&mut self.items, VecDeque::new());
        for item in old_items.into_iter() {
            if item.handle != handle {
                self.items.push_back(item);
            }
        }
    }

    pub fn add_track(&mut self, track: &OggTrack) -> Result<Handle, PlayQueueError> {
        let handle = try!(self.halloc.generate()
                .map_err(|()| PlayQueueError::Full));

        let comments = match VorbisHeader::find_comments(track.pages()) {
            Ok(header) => header.comments(),
            Err(_) => None
        };

        self.items.push_back(Track {
            handle: handle,
            data: track.to_owned(),
            comments: comments
        });
        Ok(handle)
    }

    pub fn pop_track(&mut self) -> Option<OggTrackBuf> {
        match self.items.pop_front() {
            Some(Track { handle, data, comments }) => {
                self.halloc.dispose(handle).unwrap();
                Some(data)
            },
            None => None,
        }
    }

    pub fn get_queue_comments_by_fields(&mut self, fields: &[&str]) -> Vec<Vec<(String, String)>> {
        self.items.iter().map(|track| {
            track.comments.as_ref().unwrap().comments.iter().filter_map(|comment|
                match fields.iter().any(|&field| *field == comment.0) {
                    true => Some(comment.clone()),
                    false => None
                }
            ).collect()
        }).collect()
    }
}

pub enum PlayQueueError {
    Full,
}

#[cfg(test)]
mod test {
    use ogg::OggTrack;
    use super::PlayQueue;

    static SAMPLE_OGG: &'static [u8] = include_bytes!("../../ogg/testdata/Hydrate-Kenny_Beltrey.ogg");

    #[test]
    fn test_get_queue_comments_by_fields() {
        let mut queue = PlayQueue::new(2);
        let track1 = OggTrack::new(SAMPLE_OGG).unwrap();
        let track2 = OggTrack::new(SAMPLE_OGG).unwrap();

        queue.add_track(&track1).ok();
        queue.add_track(&track2).ok();

        let expected = vec!(
            vec!(
                ("TITLE".to_string(), "Hydrate - Kenny Beltrey".to_string()),
                ("ARTIST".to_string(), "Kenny Beltrey".to_string())
            ),
            vec!(
                ("TITLE".to_string(), "Hydrate - Kenny Beltrey".to_string()),
                ("ARTIST".to_string(), "Kenny Beltrey".to_string())
            )
        );

        let got = queue.get_queue_comments_by_fields(&["ARTIST", "TITLE", "NOTAFIELD"]);
        assert_eq!(expected, got);
    }
}
<commit_msg>Fix potential case where track comments are None<commit_after>use std::mem;
use std::collections::{VecDeque, HashMap, HashSet};

use rand::{self, Rng, ChaChaRng};

use ogg::{OggTrack, OggTrackBuf};
use ogg::vorbis::{Comments, VorbisHeader};

#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
pub struct Handle(pub u64);

struct HandleAllocator<R> {
    rng: R,
    limit: usize,
    allocated: HashSet<u64>,
}

impl<R> HandleAllocator<R> where R: Rng {
    pub fn new(rng: R, limit: usize) -> HandleAllocator<R> {
        HandleAllocator {
            rng: rng,
            limit: limit,
            allocated: HashSet::new(),
        }
    }

    pub fn generate(&mut self) -> Result<Handle, ()> {
        if self.limit <= self.allocated.len() {
            return Err(());
        }

        let new_handle;
        loop {
            let foo = self.rng.next_u64();
            if !self.allocated.contains(&foo) {
                new_handle = foo;
                break;
            }
        }

        println!("EMITTING HANDLE {:#x}", new_handle);
        self.allocated.insert(new_handle);
        Ok(Handle(new_handle))
    }

    pub fn dispose(&mut self, handle: Handle) -> Result<(), Handle> {
        match self.allocated.remove(&handle.0) {
            true => Ok(()),
            false => Err(handle),
        }
    }
}

struct Track {
    handle: Handle,
    data: OggTrackBuf,
    comments: Option<Comments>,
}

pub struct PlayQueue {
    halloc: HandleAllocator<ChaChaRng>,
    items: VecDeque<Track>,
}

impl PlayQueue {
    pub fn new(limit: usize) -> PlayQueue {
        let rng: ChaChaRng = rand::thread_rng().gen();
        PlayQueue {
            halloc: HandleAllocator::new(rng, limit),
            items: VecDeque::new(),
        }
    }

    pub fn reorder(&mut self, handle_ord: &[Handle]) {
        let old_items: VecDeque<Track> = mem::replace(&mut self.items, VecDeque::new());

        let mut map: HashMap<Handle, Track> = old_items.into_iter().map(|pq| (pq.handle, pq)).collect();

        for handle in handle_ord.iter() {
            match map.remove(handle) {
                Some(item) => {
                    self.items.push_back(item);
                },
                None => (),
            }
        }
    }

    pub fn remove_by_handle(&mut self, handle: Handle) {
        let old_items: VecDeque<Track> = mem::replace(&mut self.items, VecDeque::new());
        for item in old_items.into_iter() {
            if item.handle != handle {
                self.items.push_back(item);
            }
        }
    }

    pub fn add_track(&mut self, track: &OggTrack) -> Result<Handle, PlayQueueError> {
        let handle = try!(self.halloc.generate()
                .map_err(|()| PlayQueueError::Full));

        let comments = match VorbisHeader::find_comments(track.pages()) {
            Ok(header) => header.comments(),
            Err(_) => None
        };

        self.items.push_back(Track {
            handle: handle,
            data: track.to_owned(),
            comments: comments
        });
        Ok(handle)
    }

    pub fn pop_track(&mut self) -> Option<OggTrackBuf> {
        match self.items.pop_front() {
            Some(Track { handle, data, comments }) => {
                self.halloc.dispose(handle).unwrap();
                Some(data)
            },
            None => None,
        }
    }

    pub fn get_queue_comments_by_fields(&mut self, fields: &[&str]) -> Vec<Vec<(String, String)>> {
        self.items.iter().map(|track| {
            track.comments.as_ref().map_or(Vec::new(), |comments| {
                comments.comments.iter().filter_map(|comment|
                    match fields.iter().any(|&field| *field == comment.0) {
                        true => Some(comment.clone()),
                        false => None
                    }
                ).collect()
            })
        }).collect()
    }
}

pub enum PlayQueueError {
    Full,
}

#[cfg(test)]
mod test {
    use ogg::OggTrack;
    use super::PlayQueue;

    static SAMPLE_OGG: &'static [u8] = include_bytes!("../../ogg/testdata/Hydrate-Kenny_Beltrey.ogg");

    #[test]
    fn test_get_queue_comments_by_fields() {
        let mut queue = PlayQueue::new(2);
        let track1 = OggTrack::new(SAMPLE_OGG).unwrap();
        let track2 = OggTrack::new(SAMPLE_OGG).unwrap();

        queue.add_track(&track1).ok();
        queue.add_track(&track2).ok();

        let expected = vec!(
            vec!(
                ("TITLE".to_string(), "Hydrate - Kenny Beltrey".to_string()),
                ("ARTIST".to_string(), "Kenny Beltrey".to_string())
            ),
            vec!(
                ("TITLE".to_string(), "Hydrate - Kenny Beltrey".to_string()),
                ("ARTIST".to_string(), "Kenny Beltrey".to_string())
            )
        );

        let got = queue.get_queue_comments_by_fields(&["ARTIST", "TITLE", "NOTAFIELD"]);
        assert_eq!(expected, got);
    }
}
<|endoftext|>


<commit_before>#![feature(collections)]
#![feature(binary_heap_extras)]
// Demo program for cooperative interval branch and bound algorithm.

use std::collections::BinaryHeap;
use std::io::Write;

extern crate rand;

#[macro_use(max)]
extern crate gu;
extern crate ga;
extern crate gr;

use ga::{ea, Individual};

use gu::{Quple, INF, NINF, Flt, Parameters};

use gr::{GI, width_box, split_box, midpoint_box, eps_tol};

use std::sync::{Barrier, RwLock, Arc};

use std::sync::atomic::{AtomicBool, Ordering};

use std::thread;

use std::thread::{sleep_ms};
extern crate function;
use function::FuncObj;

extern crate args;
use args::{process_args};

extern crate time;

// Returns the upper bound, the domain where this bound occurs and a status
// flag indicating whether the answer is complete for the problem.
fn ibba(x_0: Vec<GI>, e_x: Flt, e_f: Flt,
        f_bestag: Arc<RwLock<Flt>>,
        f_best_shared: Arc<RwLock<Flt>>,
        x_bestbb: Arc<RwLock<Vec<GI>>>,
        b1: Arc<Barrier>, b2: Arc<Barrier>,
        q: Arc<RwLock<BinaryHeap<Quple>>>,
        sync: Arc<AtomicBool>, stop: Arc<AtomicBool>,
        f: FuncObj)
        -> (Flt, Vec<GI>, bool) {
    let mut f_best_high = NINF;
    let mut f_best_low  = NINF;
    let mut best_x = x_0.clone();

    let mut i: u32 = 0;
    q.write().unwrap().push(Quple{p: INF, pf: i, data: x_0.clone()});
    while q.read().unwrap().len() != 0 && !stop.load(Ordering::Acquire) {
        if sync.load(Ordering::Acquire) {
            // Ugly: Update the update thread's view of the best branch bound.
            *f_best_shared.write().unwrap() = f_best_low;
            b1.wait();
            b2.wait();
        }
        // Take q as writable during an iteration
        let mut q = q.write().unwrap();

        f_best_low = max!(f_best_low, *f_bestag.read().unwrap());
        let v = q.pop();
        let (ref x, e_fx) =
            match v {
                Some(y) => (y.data, y.p),
                None    => panic!("wtf")
            };
//        let xw = width_box(x);
        let fx = f.call(x);
//        let fw = fx.width();

        if fx.upper() < f_best_low ||
            width_box(x, e_x) ||
            eps_tol(fx, e_f) {
                if f_best_high < fx.upper() {
                    f_best_high = fx.upper();
                    best_x = x.clone();
                }
                continue;
            }
        else {
            let x_s = split_box(&x);
            for sx in x_s {
                let mid = midpoint_box(&sx);
                let est_m = f.call(&mid);
                let est_i = f.call(&sx);
                let est_max = max!(est_m.lower(), est_i.lower());
                if f_best_low < est_max  {
                    f_best_low = est_max;
                    *x_bestbb.write().unwrap() = sx.clone();
                }
                i += 1;
                q.push(Quple{p: est_i.lower(),
                             pf: i,
                             data: sx});
            }
        }
    }
    if !stop.load(Ordering::Acquire) {
        // Exiting normally
        // Tell GA thread to stop
        stop.store(true, Ordering::Release);
        (f_best_high, best_x, true)
    }
    else {
        // Exiting by some other condition
        (f_best_high, best_x, false)
    }
}

fn distance(p: &Vec<GI>, x: &Vec<GI>) -> Flt {
    let mut result = 0.0;
    for i in 0..x.len() {
        let dx = max!(x[i].lower() - p[i].lower(),
                       0.0, &p[i].lower() - x[i].upper());
        result += dx*dx;
    }
    result.sqrt()
}

fn update(q: Arc<RwLock<BinaryHeap<Quple>>>, population: Arc<RwLock<Vec<Individual>>>,
          f_best_shared: Arc<RwLock<Flt>>,
          stop: Arc<AtomicBool>, sync: Arc<AtomicBool>,
          b1: Arc<Barrier>, b2: Arc<Barrier>,
          duration: u32, f: FuncObj) {
    while !stop.load(Ordering::Acquire) {
        // Timer code...
        thread::sleep_ms(duration);
        // Signal EA and IBBA threads.
        sync.store(true, Ordering::Release);

        // Wait for EA and IBBA threads to stop.
        b1.wait();
        // Do update bizness.
        let mut q_u = q.write().unwrap();
        let mut q = Vec::new();
        for qi in q_u.iter() {
            q.push(qi.clone());
        }
        let mut pop = population.write().unwrap();
        let fbest = f_best_shared.read().unwrap();

        for i in 0..pop.len() {
            let mut d_min = INF;
            let mut j = 0;
            let mut x: Vec<GI>;
            let px: Flt = NINF;
            let mut x_c: Vec<GI> = q[0].data.clone();
            while j < q.len() && d_min != 0.0 {
                x = q[j].data.clone();
                if f.call(&x).upper() < *fbest {
                    q.remove(j);
                    continue;
                }
                let d = distance(&pop[i].solution, &x);

                if d == 0.0 {d_min = 0.0; continue;}
                else {
                    if d < d_min {d_min = d; x_c = x.clone();}
                }
                j += 1;
            }
            if d_min == 0.0 {
                let fp = f.call(&pop[i].solution).lower();
                if px < fp {
                    q[j] = Quple{p: fp, pf: q[j].pf,
                                 data: q[j].data.clone()}.clone();
                }
            }
            else {
                // Individual is outside the search region.
                // Project it back into the nearest current search space.
                project(&mut pop[i], &x_c, f.clone());
            }
        }
        // Restore the q for the ibba thread.
        (*q_u) = BinaryHeap::from_vec(q);
        // Clear sync flag.
        sync.store(false, Ordering::SeqCst);

        // Resume EA and IBBA threads.
        b2.wait();
    }
}

/* Projects the box x into the box x_c */
fn project(p: &mut Individual, x_c: &Vec<GI>, f: FuncObj) {
    for i in 0..x_c.len() {
        if p.solution[i].lower() < x_c[i].lower()
            || p.solution[i].lower() > x_c[i].upper() {
            if x_c[i].upper() < p.solution[i].lower()
                {p.solution[i] = GI::new_d(x_c[i].upper(),
                                           x_c[i].upper());}
            else {p.solution[i] = GI::new_d(x_c[i].lower(),
                                            x_c[i].lower());}
        }
    }
    p.fitness = f.call(&p.solution).lower();
}

// stop is used to signal the other threads to stop
// timeout is the timeout time in seconds. 0 means no timeout
fn timeout(stop: Arc<AtomicBool>, timeout: u32) {
    let start = time::get_time();

    if timeout > 0 {
        while time::get_time().sec - start.sec < timeout as i64 {
            std::thread::sleep_ms(timeout*1000);
        } // guard agains spurious wakes.
        if !stop.load(Ordering::Acquire) { // Check if we've already stopped
            writeln!(&mut std::io::stderr(), "Stopping early...");
            stop.store(true, Ordering::Release);
        }
    }
}

fn main() {
    let args = process_args();

    let ref x_0 = args.domain;
    let ref fo = args.function;
    let x_err = args.x_error;
    let y_err = args.y_error;

    // Early out if there are no input variables...
    if x_0.len() == 0 {
        let result = fo.call(&x_0);
        println!("[{}, {{}}]", result.upper());
        return
    }

    let q_inner: BinaryHeap<Quple> = BinaryHeap::new();
    let q = Arc::new(RwLock::new(q_inner));

    let population_inner: Vec<Individual> = Vec::new();
    let population = Arc::new(RwLock::new(population_inner));

    let b1 = Arc::new(Barrier::new(3));
    let b2 = Arc::new(Barrier::new(3));

    let sync = Arc::new(AtomicBool::new(false));
    let stop = Arc::new(AtomicBool::new(false));

    let f_bestag: Arc<RwLock<Flt>> = Arc::new(RwLock::new(NINF));
    let f_best_shared: Arc<RwLock<Flt>> = Arc::new(RwLock::new(NINF));

    let x_e = x_0.clone();
    let x_i = x_0.clone();

    let x_bestbb = Arc::new(RwLock::new(x_0.clone()));

    let ibba_thread =
    {
        let q = q.clone();
        let b1 = b1.clone();
        let b2 = b2.clone();
        let f_bestag = f_bestag.clone();
        let f_best_shared = f_best_shared.clone();
        let x_bestbb = x_bestbb.clone();
        let sync = sync.clone();
        let stop = stop.clone();
        let fo_c = fo.clone();
        thread::Builder::new().name("IBBA".to_string()).spawn(move || {
            ibba(x_i, x_err, y_err,
                 f_bestag, f_best_shared,
                 x_bestbb,
                 b1, b2, q, sync, stop, fo_c)
        })};

    let ea_thread =
    {
        let population = population.clone();
        let f_bestag = f_bestag.clone();
        let x_bestbb = x_bestbb.clone();
        let sync = sync.clone();
        let stop = stop.clone();
        let b1 = b1.clone();
        let b2 = b2.clone();
        let fo_c = fo.clone();
        thread::Builder::new().name("EA".to_string()).spawn(move || {
            ea(x_e, Parameters{population: 2000, //1000,
                               selection: 8, //4,
                               elitism: 5, //2,
                               mutation: 0.4_f64,//0.3_f64,
                               crossover: 0.3_f64 // 0.5_f64},
                               },
               population,
               f_bestag,
               x_bestbb,
               b1, b2,
               stop, sync, fo_c)
        })};

    let update_thread =
    {
        let q = q.clone();
        let population = population.clone();
        let f_best_shared = f_best_shared.clone();
        let sync = sync.clone();
        let stop = stop.clone();
        let b1 = b1.clone();
        let b2 = b2.clone();
        let fo_c = fo.clone();
        thread::Builder::new().name("Update".to_string()).spawn(move || {
            update(q, population, f_best_shared,
                   stop, sync, b1, b2, 10000, fo_c)
        })};

    let timeout_thread =
    {
        let stop = stop.clone();
        let to = args.timeout.clone();
        thread::Builder::new().name("Timeout".to_string()).spawn(move || {
            timeout(stop, to);
        })
    };

    let result = ibba_thread.unwrap().join();
    ea_thread.unwrap().join();

    // Join EA and Update here pending stop signaling.
    if result.is_ok() {
        let (mut max, mut interval, completed) = result.unwrap();
        if !completed {
            // Go through all remaining intervals from IBBA to find the true
            // max
            let mut lq = q.write().unwrap();
            while lq.len() != 0 {
                let v = lq.pop().unwrap();
                let ref l_data = &v.data;
                let ub = fo.call(l_data).upper();
                if ub > max {
                    max = ub;
                    interval =v.data.clone();
                }
            }
        }
        println!("[{}, {{", max);
        for i in 0..args.names.len() {
            println!("'{}' : {},", args.names[i], interval[i].to_string());
        }
        println!("}}]");

    }
    else {println!("error")}
}
<commit_msg>"Fixed" deadlock<commit_after>#![feature(collections)]
#![feature(binary_heap_extras)]
// Demo program for cooperative interval branch and bound algorithm.

use std::collections::BinaryHeap;
use std::io::Write;

extern crate rand;

#[macro_use(max)]
extern crate gu;
extern crate ga;
extern crate gr;

use ga::{ea, Individual};

use gu::{Quple, INF, NINF, Flt, Parameters};

use gr::{GI, width_box, split_box, midpoint_box, eps_tol};

use std::sync::{Barrier, RwLock, Arc};

use std::sync::atomic::{AtomicBool, Ordering};

use std::thread;

use std::thread::{sleep_ms};
extern crate function;
use function::FuncObj;

extern crate args;
use args::{process_args};

extern crate time;

// Returns the upper bound, the domain where this bound occurs and a status
// flag indicating whether the answer is complete for the problem.
fn ibba(x_0: Vec<GI>, e_x: Flt, e_f: Flt,
        f_bestag: Arc<RwLock<Flt>>,
        f_best_shared: Arc<RwLock<Flt>>,
        x_bestbb: Arc<RwLock<Vec<GI>>>,
        b1: Arc<Barrier>, b2: Arc<Barrier>,
        q: Arc<RwLock<BinaryHeap<Quple>>>,
        sync: Arc<AtomicBool>, stop: Arc<AtomicBool>,
        f: FuncObj)
        -> (Flt, Vec<GI>, bool) {
    let mut f_best_high = NINF;
    let mut f_best_low  = NINF;
    let mut best_x = x_0.clone();

    let mut i: u32 = 0;
    q.write().unwrap().push(Quple{p: INF, pf: i, data: x_0.clone()});
    while q.read().unwrap().len() != 0 && !stop.load(Ordering::Acquire) {
        if sync.load(Ordering::Acquire) {
            // Ugly: Update the update thread's view of the best branch bound.
            *f_best_shared.write().unwrap() = f_best_low;
            b1.wait();                                                           // Dead lock here
            b2.wait();                                                           // Dead lock here?
        }
        // Take q as writable during an iteration
        let mut q = q.write().unwrap();

        f_best_low = max!(f_best_low, *f_bestag.read().unwrap());
        let v = q.pop();
        let (ref x, e_fx) =
            match v {
                Some(y) => (y.data, y.p),
                None    => panic!("wtf")
            };
//        let xw = width_box(x);
        let fx = f.call(x);
//        let fw = fx.width();

        if fx.upper() < f_best_low ||
            width_box(x, e_x) ||
            eps_tol(fx, e_f) {
                if f_best_high < fx.upper() {
                    f_best_high = fx.upper();
                    best_x = x.clone();
                }
                continue;
            }
        else {
            let x_s = split_box(&x);
            for sx in x_s {
                let mid = midpoint_box(&sx);
                let est_m = f.call(&mid);
                let est_i = f.call(&sx);
                let est_max = max!(est_m.lower(), est_i.lower());
                if f_best_low < est_max  {
                    f_best_low = est_max;
                    *x_bestbb.write().unwrap() = sx.clone();
                }
                i += 1;
                q.push(Quple{p: est_i.lower(),
                             pf: i,
                             data: sx});
            }
        }
    }
    if !stop.load(Ordering::Acquire) {
        // Exiting normally
        // Tell GA thread to stop
        stop.store(true, Ordering::Release);
        (f_best_high, best_x, true)
    }
    else {
        // Exiting by some other condition
        (f_best_high, best_x, false)
    }
}

fn distance(p: &Vec<GI>, x: &Vec<GI>) -> Flt {
    let mut result = 0.0;
    for i in 0..x.len() {
        let dx = max!(x[i].lower() - p[i].lower(),
                       0.0, &p[i].lower() - x[i].upper());
        result += dx*dx;
    }
    result.sqrt()
}

fn update(q: Arc<RwLock<BinaryHeap<Quple>>>, population: Arc<RwLock<Vec<Individual>>>,
          f_best_shared: Arc<RwLock<Flt>>,
          stop: Arc<AtomicBool>, sync: Arc<AtomicBool>,
          b1: Arc<Barrier>, b2: Arc<Barrier>,
          duration: u32, f: FuncObj,
          timeout: u32) {
    let start = time::get_time();

    while !stop.load(Ordering::Acquire) {
        // Rewrite this so that the timing code is finer by checking for
        // whether the next scheduled event should be executed, e.g., the time
        // or update operation.

        // Timer code...
        thread::sleep_ms(duration);
        if timeout > 0 && time::get_time().sec - start.sec >= timeout as i64
            && !stop.load(Ordering::Acquire) { // Check if we've already stopped
                writeln!(&mut std::io::stderr(), "Stopping early...");
                stop.store(true, Ordering::Release);
            }

        // Signal EA and IBBA threads.
        sync.store(true, Ordering::Release);

        // Wait for EA and IBBA threads to stop.
        b1.wait();                                                               // Dead lock here?
        // Do update bizness.
        let mut q_u = q.write().unwrap();
        let mut q = Vec::new();
        for qi in q_u.iter() {
            q.push(qi.clone());
        }
        let mut pop = population.write().unwrap();
        let fbest = f_best_shared.read().unwrap();

        for i in 0..pop.len() {
            let mut d_min = INF;
            let mut j = 0;
            let mut x: Vec<GI>;
            let px: Flt = NINF;
            let mut x_c: Vec<GI> = q[0].data.clone();
            while j < q.len() && d_min != 0.0 {
                x = q[j].data.clone();
                if f.call(&x).upper() < *fbest {
                    q.remove(j);
                    continue;
                }
                let d = distance(&pop[i].solution, &x);

                if d == 0.0 {d_min = 0.0; continue;}
                else {
                    if d < d_min {d_min = d; x_c = x.clone();}
                }
                j += 1;
            }
            if d_min == 0.0 {
                let fp = f.call(&pop[i].solution).lower();
                if px < fp {
                    q[j] = Quple{p: fp, pf: q[j].pf,
                                 data: q[j].data.clone()}.clone();
                }
            }
            else {
                // Individual is outside the search region.
                // Project it back into the nearest current search space.
                project(&mut pop[i], &x_c, f.clone());
            }
        }
        // Restore the q for the ibba thread.
        (*q_u) = BinaryHeap::from_vec(q);
        // Clear sync flag.
        sync.store(false, Ordering::SeqCst);

        // Resume EA and IBBA threads.
        b2.wait();                                                               // Dead lock here?
    }
}

/* Projects the box x into the box x_c */
fn project(p: &mut Individual, x_c: &Vec<GI>, f: FuncObj) {
    for i in 0..x_c.len() {
        if p.solution[i].lower() < x_c[i].lower()
            || p.solution[i].lower() > x_c[i].upper() {
            if x_c[i].upper() < p.solution[i].lower()
                {p.solution[i] = GI::new_d(x_c[i].upper(),
                                           x_c[i].upper());}
            else {p.solution[i] = GI::new_d(x_c[i].lower(),
                                            x_c[i].lower());}
        }
    }
    p.fitness = f.call(&p.solution).lower();
}

// stop is used to signal the other threads to stop
// timeout is the timeout time in seconds. 0 means no timeout
fn timeout(stop: Arc<AtomicBool>, timeout: u32) {
    let start = time::get_time();

    if timeout > 0 {
        while time::get_time().sec - start.sec < timeout as i64 {
            std::thread::sleep_ms(timeout*1000);
        } // guard agains spurious wakes.
        if !stop.load(Ordering::Acquire) { // Check if we've already stopped
            writeln!(&mut std::io::stderr(), "Stopping early...");
            stop.store(true, Ordering::Release);
        }
    }
}

fn main() {
    let args = process_args();

    let ref x_0 = args.domain;
    let ref fo = args.function;
    let x_err = args.x_error;
    let y_err = args.y_error;

    // Early out if there are no input variables...
    if x_0.len() == 0 {
        let result = fo.call(&x_0);
        println!("[{}, {{}}]", result.upper());
        return
    }

    let q_inner: BinaryHeap<Quple> = BinaryHeap::new();
    let q = Arc::new(RwLock::new(q_inner));

    let population_inner: Vec<Individual> = Vec::new();
    let population = Arc::new(RwLock::new(population_inner));

    let b1 = Arc::new(Barrier::new(3));
    let b2 = Arc::new(Barrier::new(3));

    let sync = Arc::new(AtomicBool::new(false));
    let stop = Arc::new(AtomicBool::new(false));

    let f_bestag: Arc<RwLock<Flt>> = Arc::new(RwLock::new(NINF));
    let f_best_shared: Arc<RwLock<Flt>> = Arc::new(RwLock::new(NINF));

    let x_e = x_0.clone();
    let x_i = x_0.clone();

    let x_bestbb = Arc::new(RwLock::new(x_0.clone()));

    let ibba_thread =
    {
        let q = q.clone();
        let b1 = b1.clone();
        let b2 = b2.clone();
        let f_bestag = f_bestag.clone();
        let f_best_shared = f_best_shared.clone();
        let x_bestbb = x_bestbb.clone();
        let sync = sync.clone();
        let stop = stop.clone();
        let fo_c = fo.clone();
        thread::Builder::new().name("IBBA".to_string()).spawn(move || {
            ibba(x_i, x_err, y_err,
                 f_bestag, f_best_shared,
                 x_bestbb,
                 b1, b2, q, sync, stop, fo_c)
        })};

    let ea_thread =
    {
        let population = population.clone();
        let f_bestag = f_bestag.clone();
        let x_bestbb = x_bestbb.clone();
        let sync = sync.clone();
        let stop = stop.clone();
        let b1 = b1.clone();
        let b2 = b2.clone();
        let fo_c = fo.clone();
        thread::Builder::new().name("EA".to_string()).spawn(move || {
            ea(x_e, Parameters{population: 2000, //1000,
                               selection: 8, //4,
                               elitism: 5, //2,
                               mutation: 0.4_f64,//0.3_f64,
                               crossover: 0.3_f64 // 0.5_f64},
                               },
               population,
               f_bestag,
               x_bestbb,
               b1, b2,
               stop, sync, fo_c)
        })};

    let update_thread =
    {
        let q = q.clone();
        let population = population.clone();
        let f_best_shared = f_best_shared.clone();
        let sync = sync.clone();
        let stop = stop.clone();
        let b1 = b1.clone();
        let b2 = b2.clone();
        let fo_c = fo.clone();
        let to = args.timeout.clone();
        thread::Builder::new().name("Update".to_string()).spawn(move || {
            update(q, population, f_best_shared,
                   stop, sync, b1, b2, 10000, fo_c, to)
        })};

    let result = ibba_thread.unwrap().join();
    ea_thread.unwrap().join();

    // Join EA and Update here pending stop signaling.
    if result.is_ok() {
        let (mut max, mut interval, completed) = result.unwrap();
        if !completed {
            // Go through all remaining intervals from IBBA to find the true
            // max
            let mut lq = q.write().unwrap();
            while lq.len() != 0 {
                let v = lq.pop().unwrap();
                let ref l_data = &v.data;
                let ub = fo.call(l_data).upper();
                if ub > max {
                    max = ub;
                    interval =v.data.clone();
                }
            }
        }
        println!("[{}, {{", max);
        for i in 0..args.names.len() {
            println!("'{}' : {},", args.names[i], interval[i].to_string());
        }
        println!("}}]");

    }
    else {println!("error")}
}
<|endoftext|>