<commit_before>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [Postcard]: https://github.com/jamesmunns/postcard
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.104")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy and clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // not available in our oldest supported compiler
        checked_conversions,
        empty_enum,
        redundant_field_names,
        redundant_static_lifetimes,
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_sign_loss,
        // things are often more readable this way
        cast_lossless,
        module_name_repetitions,
        single_match_else,
        type_complexity,
        use_self,
        zero_prefixed_literal,
        // not practical
        needless_pass_by_value,
        similar_names,
        too_many_lines,
        // preference
        doc_markdown,
        // false positive
        needless_doctest_main,
        // noisy
        must_use_candidate,
    )
)]
// Rustc lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::{String, ToString};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(all(feature = "std", collections_bound))]
    pub use std::collections::Bound;

    #[cfg(core_reverse)]
    pub use self::core::cmp::Reverse;

    #[cfg(ops_bound)]
    pub use self::core::ops::Bound;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;

    #[cfg(all(feature = "std", std_atomic))]
    pub use std::sync::atomic::{
        AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
        AtomicUsize, Ordering,
    };
    #[cfg(all(feature = "std", std_atomic64))]
    pub use std::sync::atomic::{AtomicI64, AtomicU64};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

#[cfg(not(feature = "std"))]
mod std_error;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<commit_msg>Ignore missing_errors_doc pedantic lint<commit_after>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [Postcard]: https://github.com/jamesmunns/postcard
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.104")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy and clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // not available in our oldest supported compiler
        checked_conversions,
        empty_enum,
        redundant_field_names,
        redundant_static_lifetimes,
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_sign_loss,
        // things are often more readable this way
        cast_lossless,
        module_name_repetitions,
        single_match_else,
        type_complexity,
        use_self,
        zero_prefixed_literal,
        // not practical
        needless_pass_by_value,
        similar_names,
        too_many_lines,
        // preference
        doc_markdown,
        // false positive
        needless_doctest_main,
        // noisy
        missing_errors_doc,
        must_use_candidate,
    )
)]
// Rustc lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::{String, ToString};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(all(feature = "std", collections_bound))]
    pub use std::collections::Bound;

    #[cfg(core_reverse)]
    pub use self::core::cmp::Reverse;

    #[cfg(ops_bound)]
    pub use self::core::ops::Bound;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;

    #[cfg(all(feature = "std", std_atomic))]
    pub use std::sync::atomic::{
        AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
        AtomicUsize, Ordering,
    };
    #[cfg(all(feature = "std", std_atomic64))]
    pub use std::sync::atomic::{AtomicI64, AtomicU64};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

#[cfg(not(feature = "std"))]
mod std_error;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<|endoftext|>


<commit_before>use std::sync::RwLock;
use std::time::SystemTime;
use board::*;
use depth::*;
use search_executor::*;
use hash_table::Variation;
use search_node::SearchNode;
use time_manager::{TimeManager, RemainingTime};
use uci::{SetOption, OptionDescription};

/// Decides when the search must be terminated.
pub struct StdTimeManager {
    started_at: SystemTime,
    depth: Depth,
    extrapolation_points: Vec<(f64, f64)>,
    hard_limit: f64,
    allotted_time: f64,
    must_play: bool,
}

impl<S> TimeManager<S> for StdTimeManager
    where S: SearchExecutor<ReportData = Vec<Variation>>
{
    #[allow(unused_variables)]
    fn new(position: &S::SearchNode, time: RemainingTime) -> StdTimeManager {
        let (t, inc) = if position.board().to_move == WHITE {
            (time.white_millis as f64, time.winc_millis as f64)
        } else {
            (time.black_millis as f64, time.binc_millis as f64)
        };
        let n = time.movestogo.unwrap_or(40) as f64; // TODO: assert that n >= 1.0

        // Calculate an approximation for the total time we have till
        // the next time control or the end of the game.
        let time_heap = t + inc * (n - 1.0);

        // Set a hard limit for the time we will spend on this
        // move. Thinking longer that that would be reckless.
        let hard_limit = (t / n.sqrt() + inc).min(t - 1000.0);

        StdTimeManager {
            started_at: SystemTime::now(),
            depth: DEPTH_MIN - 1,
            extrapolation_points: Vec::with_capacity(32),
            hard_limit: if position.legal_moves().len() > 1 {
                hard_limit
            } else {
                // When there is only one legal move, the engine is
                // allowed to think a fraction of a second in order to
                // find a good ponder move.
                hard_limit.min(500.0)
            },
            allotted_time: if *PONDER.read().unwrap() {
                // Statistically, the move we ponder will be played in
                // 50% of the cases. Therefore, in principal we can
                // add half of opponent's thinking time to our time
                // heap. But because we can not know how opponent's
                // time will be spend, we simply increase our time
                // heap by 50%.
                1.5 * time_heap / n
            } else {
                time_heap / n
            },
            must_play: false,
        }
    }

    #[allow(unused_variables)]
    fn update(&mut self, report: &SearchReport<Vec<Variation>>) {
        const M: usize = 5;

        let &SearchReport { ref depth, ref searched_nodes, .. } = report;
        if *depth > self.depth {
            self.depth = *depth;
            if *searched_nodes > 100 {
                let t = elapsed_millis(&self.started_at);
                let depth = *depth as f64;
                let searched_nodes = *searched_nodes as f64;
                self.extrapolation_points.push((depth, searched_nodes.ln()));
                let expected_duration = match self.extrapolation_points.len() {
                    n if n >= M => {
                        let last_m = &self.extrapolation_points[n - M..];
                        let factor = extrapolate(last_m, depth + 1.0).exp() / searched_nodes;
                        if n == M {
                            // Update `BRANCHING_FACTOR`. This is the
                            // average factor calculated for the last
                            // few moves.
                            let mut bf = BRANCHING_FACTOR.write().unwrap();
                            *bf = (*bf * 2.0 + factor) / 3.0;
                        }
                        factor * t
                    }
                    _ => *BRANCHING_FACTOR.read().unwrap() * t,
                };
                self.must_play = expected_duration > self.hard_limit ||
                                 expected_duration > self.allotted_time &&
                                 expected_duration - self.allotted_time > self.allotted_time - t;
            }
        }
    }

    #[allow(unused_variables)]
    fn must_play(&self, search: &S) -> bool {
        self.must_play || elapsed_millis(&self.started_at) > self.hard_limit
    }
}

impl SetOption for StdTimeManager {
    fn options() -> Vec<(String, OptionDescription)> {
        vec![("Ponder".to_string(), OptionDescription::Check { default: false })]
    }

    fn set_option(name: &str, value: &str) {
        if name == "Ponder" {
            match value {
                "true" => *PONDER.write().unwrap() = true,
                "false" => *PONDER.write().unwrap() = false,
                _ => (),
            }
        }
    }
}

lazy_static! {
    static ref PONDER: RwLock<bool> = RwLock::new(false);
    static ref BRANCHING_FACTOR: RwLock<f64> = RwLock::new(2.0);
}

/// A helper function. It calculates the elapsed milliseconds since a
/// given time.
fn elapsed_millis(since: &SystemTime) -> f64 {
    let d = since.elapsed().unwrap();
    (1000 * d.as_secs()) as f64 + (d.subsec_nanos() / 1_000_000) as f64
}

/// A helper function. It linearly extrapolates the value y(x) using
/// the (x, y) values in `points` as reference.
fn extrapolate(points: &[(f64, f64)], x: f64) -> f64 {
    debug_assert!(points.len() > 1);
    let sum_x = points.iter().fold(0.0, |acc, &p| acc + p.0);
    let sum_y = points.iter().fold(0.0, |acc, &p| acc + p.1);
    let sum_xx = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.0);
    let sum_xy = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.1);
    let n = points.len() as f64;
    let slope = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
    let intercept = (sum_y - slope * sum_x) / n;
    slope * x + intercept
}

#[cfg(test)]
mod tests {
    #[test]
    fn linear_regression() {
        use super::extrapolate;
        let points = vec![(21.0, 1.0), (22.0, 2.0), (23.0, 3.0), (24.0, 4.0)];
        let x = 25.0;
        let y = extrapolate(&points, x);
        assert!(4.99 < y && y < 5.01);
    }
}
<commit_msg>add comments<commit_after>use std::cmp::max;
use std::sync::RwLock;
use std::time::SystemTime;
use board::*;
use depth::*;
use search_executor::*;
use hash_table::Variation;
use search_node::SearchNode;
use time_manager::{TimeManager, RemainingTime};
use uci::{SetOption, OptionDescription};

/// Decides when the search must be terminated.
pub struct StdTimeManager {
    started_at: SystemTime,
    depth: Depth,
    extrapolation_points: Vec<(f64, f64)>,
    hard_limit: f64,
    allotted_time: f64,
    must_play: bool,
}

impl<S> TimeManager<S> for StdTimeManager
    where S: SearchExecutor<ReportData = Vec<Variation>>
{
    #[allow(unused_variables)]
    fn new(position: &S::SearchNode, time: RemainingTime) -> StdTimeManager {
        // Get our remaining time and increment (in milliseconds).
        let (t, inc) = if position.board().to_move == WHITE {
            (time.white_millis as f64, time.winc_millis as f64)
        } else {
            (time.black_millis as f64, time.binc_millis as f64)
        };

        // Get the number of moves till the next time control, or
        // guess the number of moves till the end of the game.
        let n = max(1, time.movestogo.unwrap_or(40)) as f64;

        // Calculate an approximation for the total time we have till
        // the next time control or the end of the game.
        let time_heap = t + inc * (n - 1.0);

        // Set a hard limit for the time we will spend on this
        // move. Thinking longer that that would be reckless.
        let hard_limit = (t / n.sqrt() + inc).min(t - 1000.0);

        StdTimeManager {
            started_at: SystemTime::now(),
            depth: DEPTH_MIN - 1,
            extrapolation_points: Vec::with_capacity(32),
            hard_limit: if position.legal_moves().len() > 1 {
                hard_limit
            } else {
                // When there is only one legal move, the engine is
                // allowed to think a fraction of a second in order to
                // find a good ponder move.
                hard_limit.min(500.0)
            },
            allotted_time: if *PONDER.read().unwrap() {
                // Statistically, the move we ponder will be played in
                // 50% of the cases. Therefore, in principal we can
                // add half of opponent's thinking time to our time
                // heap. But because we can not know how opponent's
                // time will be spend, we simply increase our time
                // heap by 50%.
                1.5 * time_heap / n
            } else {
                time_heap / n
            },
            must_play: false,
        }
    }

    #[allow(unused_variables)]
    fn update(&mut self, report: &SearchReport<Vec<Variation>>) {
        const M: usize = 5;

        let &SearchReport { ref depth, ref searched_nodes, .. } = report;
        if *depth > self.depth {
            self.depth = *depth;
            if *searched_nodes > 100 {
                let t = elapsed_millis(&self.started_at);
                let depth = *depth as f64;
                let searched_nodes = *searched_nodes as f64;
                self.extrapolation_points.push((depth, searched_nodes.ln()));
                let expected_duration = match self.extrapolation_points.len() {
                    n if n >= M => {
                        let last_m = &self.extrapolation_points[n - M..];
                        let factor = extrapolate(last_m, depth + 1.0).exp() / searched_nodes;
                        if n == M {
                            // Update `BRANCHING_FACTOR`. This is the
                            // average factor calculated for the last
                            // few moves.
                            let mut bf = BRANCHING_FACTOR.write().unwrap();
                            *bf = (*bf * 2.0 + factor) / 3.0;
                        }
                        factor * t
                    }
                    _ => *BRANCHING_FACTOR.read().unwrap() * t,
                };
                self.must_play = expected_duration > self.hard_limit ||
                                 expected_duration > self.allotted_time &&
                                 expected_duration - self.allotted_time > self.allotted_time - t;
            }
        }
    }

    #[allow(unused_variables)]
    fn must_play(&self, search: &S) -> bool {
        self.must_play || elapsed_millis(&self.started_at) > self.hard_limit
    }
}

impl SetOption for StdTimeManager {
    fn options() -> Vec<(String, OptionDescription)> {
        vec![("Ponder".to_string(), OptionDescription::Check { default: false })]
    }

    fn set_option(name: &str, value: &str) {
        if name == "Ponder" {
            match value {
                "true" => *PONDER.write().unwrap() = true,
                "false" => *PONDER.write().unwrap() = false,
                _ => (),
            }
        }
    }
}

lazy_static! {
    static ref PONDER: RwLock<bool> = RwLock::new(false);
    static ref BRANCHING_FACTOR: RwLock<f64> = RwLock::new(2.0);
}

/// A helper function. It calculates the elapsed milliseconds since a
/// given time.
fn elapsed_millis(since: &SystemTime) -> f64 {
    let d = since.elapsed().unwrap();
    (1000 * d.as_secs()) as f64 + (d.subsec_nanos() / 1_000_000) as f64
}

/// A helper function. It linearly extrapolates the value y(x) using
/// the (x, y) values in `points` as reference.
fn extrapolate(points: &[(f64, f64)], x: f64) -> f64 {
    debug_assert!(points.len() > 1);
    let sum_x = points.iter().fold(0.0, |acc, &p| acc + p.0);
    let sum_y = points.iter().fold(0.0, |acc, &p| acc + p.1);
    let sum_xx = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.0);
    let sum_xy = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.1);
    let n = points.len() as f64;
    let slope = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
    let intercept = (sum_y - slope * sum_x) / n;
    slope * x + intercept
}

#[cfg(test)]
mod tests {
    #[test]
    fn linear_regression() {
        use super::extrapolate;
        let points = vec![(21.0, 1.0), (22.0, 2.0), (23.0, 3.0), (24.0, 4.0)];
        let x = 25.0;
        let y = extrapolate(&points, x);
        assert!(4.99 < y && y < 5.01);
    }
}
<|endoftext|>


<commit_before>//! This crate defines a
//! [Wadler-style](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)
//! pretty-printing API.
//!
//! See `Doc` and
extern crate typed_arena;

use doc::Doc::{
    Append,
    Group,
    Nest,
    Newline,
    Nil,
    Text,
};
use std::borrow::Cow;
use std::fmt;
use std::ops::Deref;

mod doc;

#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct BoxDoc<'a>(Box<doc::Doc<'a, BoxDoc<'a>>>);

impl<'a> fmt::Debug for BoxDoc<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<'a> BoxDoc<'a> {
    fn new(doc: doc::Doc<'a, BoxDoc<'a>>) -> BoxDoc<'a> {
        BoxDoc(Box::new(doc))
    }
}

impl<'a> Deref for BoxDoc<'a> {
    type Target = doc::Doc<'a, BoxDoc<'a>>;

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

/// The `DocBuilder` type allows for convenient appending of documents even for arena allocated
/// documents by storing the arena inline.
pub struct DocBuilder<'a, A: ?Sized>(pub &'a A, pub doc::Doc<'a, A::Doc>)
    where A: DocAllocator<'a> + 'a;

impl <'a, A: ?Sized> Into<doc::Doc<'a, A::Doc>> for DocBuilder<'a, A>
    where A: DocAllocator<'a>
{
    fn into(self) -> doc::Doc<'a, A::Doc> {
        self.1
    }
}

/// The `DocAllocator` trait abstracts over a type which can allocate (pointers to) `Doc`.
pub trait DocAllocator<'a> {
    type Doc: Deref<Target = doc::Doc<'a, Self::Doc>> + Clone;
    fn alloc(&'a self, doc::Doc<'a, Self::Doc>) -> Self::Doc;

    #[inline]
    fn nil(&'a self) -> DocBuilder<'a, Self> {
        DocBuilder(self, Nil)
    }

    #[inline]
    fn newline(&'a self) -> DocBuilder<'a, Self> {
        DocBuilder(self, Newline)
    }

    #[inline]
    fn as_string<T: ToString>(&'a self, t: T) -> DocBuilder<'a, Self> {
        self.text(t.to_string())
    }

    #[inline]
    fn text<T: Into<Cow<'a, str>>>(&'a self, data: T) -> DocBuilder<'a, Self> {
        DocBuilder(self, Text(data.into()))
    }

    #[inline]
    fn concat<I>(&'a self, docs: I) -> DocBuilder<'a, Self>
    where I: IntoIterator<Item = doc::Doc<'a, Self::Doc>>
    {
        docs.into_iter().fold(self.nil(), |a, b| a.append(b))
    }
}

impl<'a, 's, A: ?Sized> DocBuilder<'a, A> where A: DocAllocator<'a> {
    #[inline]
    pub fn append<B>(self, that: B) -> DocBuilder<'a, A>
    where B: Into<doc::Doc<'a, A::Doc>>,
    {
        let DocBuilder(allocator, this) = self;
        let that = that.into();
        let doc = match this {
            Nil  => that,
            _ => match that {
                Nil  => this,
                _ => Append(allocator.alloc(this), allocator.alloc(that)),
            }
        };
        DocBuilder(allocator, doc)
    }

    #[inline]
    pub fn group(self) -> DocBuilder<'a, A>
    {
        let DocBuilder(allocator, this) = self;
        DocBuilder(allocator, Group(allocator.alloc(this)))
    }

    #[inline]
    pub fn nest(self, offset: usize) -> DocBuilder<'a, A>
    {
        let DocBuilder(allocator, this) = self;
        DocBuilder(allocator, Nest(offset, allocator.alloc(this)))
    }
}

/// Newtype wrapper for `&doc::Doc`
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct RefDoc<'a>(&'a doc::Doc<'a, RefDoc<'a>>);

impl<'a> fmt::Debug for RefDoc<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<'a> Deref for RefDoc<'a> {
    type Target = doc::Doc<'a, RefDoc<'a>>;

    fn deref(&self) -> &doc::Doc<'a, RefDoc<'a>> {
        &self.0
    }
}

/// An arena which can be used to allocate `Doc` values.
pub type Arena<'a> = typed_arena::Arena<doc::Doc<'a, RefDoc<'a>>>;

impl<'a> DocAllocator<'a> for Arena<'a> {
    type Doc = RefDoc<'a>;

    fn alloc(&'a self, doc: doc::Doc<'a, Self::Doc>) -> Self::Doc {
        RefDoc(Arena::alloc(self, doc))
    }
}

pub struct BoxAllocator;

static BOX_ALLOCATOR: BoxAllocator = BoxAllocator;

impl<'a> DocAllocator<'a> for BoxAllocator {
    type Doc = BoxDoc<'a>;

    fn alloc(&'a self, doc: doc::Doc<'a, Self::Doc>) -> Self::Doc {
        BoxDoc::new(doc)
    }
}

pub use doc::Doc;

impl<'a> Doc<'a, BoxDoc<'a>> {
    #[inline]
    pub fn nil() -> Doc<'a, BoxDoc<'a>> {
        Nil
    }

    #[inline]
    pub fn append(self, that: Doc<'a, BoxDoc<'a>>) -> Doc<'a, BoxDoc<'a>> {
        DocBuilder(&BOX_ALLOCATOR, self).append(that).into()
    }

    #[inline]
    pub fn as_string<T: ToString>(t: T) -> Doc<'a, BoxDoc<'a>> {
        Doc::text(t.to_string())
    }

    #[inline]
    pub fn concat<I>(&'a self, docs: I) -> Doc<'a, BoxDoc<'a>>
    where I: IntoIterator<Item = Doc<'a, BoxDoc<'a>>>
    {
        docs.into_iter().fold(Doc::nil(), |a, b| a.append(b))
    }

    #[inline]
    pub fn group(self) -> Doc<'a, BoxDoc<'a>> {
        DocBuilder(&BOX_ALLOCATOR, self).group().into()
    }

    #[inline]
    pub fn nest(self, offset: usize) -> Doc<'a, BoxDoc<'a>> {
        DocBuilder(&BOX_ALLOCATOR, self).nest(offset).into()
    }

    #[inline]
    pub fn newline() -> Doc<'a, BoxDoc<'a>> {
        Newline
    }

    #[inline]
    pub fn text<T: Into<Cow<'a, str>>>(data: T) -> Doc<'a, BoxDoc<'a>> {
        Text(data.into())
    }
}
<commit_msg>Allow the static functions on `Doc` to be used with B = RefDoc as well<commit_after>//! This crate defines a
//! [Wadler-style](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)
//! pretty-printing API.
//!
//! See `Doc` and
extern crate typed_arena;

use doc::Doc::{
    Append,
    Group,
    Nest,
    Newline,
    Nil,
    Text,
};
use std::borrow::Cow;
use std::fmt;
use std::ops::Deref;

mod doc;

#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct BoxDoc<'a>(Box<doc::Doc<'a, BoxDoc<'a>>>);

impl<'a> fmt::Debug for BoxDoc<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<'a> BoxDoc<'a> {
    fn new(doc: doc::Doc<'a, BoxDoc<'a>>) -> BoxDoc<'a> {
        BoxDoc(Box::new(doc))
    }
}

impl<'a> Deref for BoxDoc<'a> {
    type Target = doc::Doc<'a, BoxDoc<'a>>;

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

/// The `DocBuilder` type allows for convenient appending of documents even for arena allocated
/// documents by storing the arena inline.
pub struct DocBuilder<'a, A: ?Sized>(pub &'a A, pub doc::Doc<'a, A::Doc>)
    where A: DocAllocator<'a> + 'a;

impl <'a, A: ?Sized> Into<doc::Doc<'a, A::Doc>> for DocBuilder<'a, A>
    where A: DocAllocator<'a>
{
    fn into(self) -> doc::Doc<'a, A::Doc> {
        self.1
    }
}

/// The `DocAllocator` trait abstracts over a type which can allocate (pointers to) `Doc`.
pub trait DocAllocator<'a> {
    type Doc: Deref<Target = doc::Doc<'a, Self::Doc>> + Clone;
    fn alloc(&'a self, doc::Doc<'a, Self::Doc>) -> Self::Doc;

    #[inline]
    fn nil(&'a self) -> DocBuilder<'a, Self> {
        DocBuilder(self, Nil)
    }

    #[inline]
    fn newline(&'a self) -> DocBuilder<'a, Self> {
        DocBuilder(self, Newline)
    }

    #[inline]
    fn as_string<T: ToString>(&'a self, t: T) -> DocBuilder<'a, Self> {
        self.text(t.to_string())
    }

    #[inline]
    fn text<T: Into<Cow<'a, str>>>(&'a self, data: T) -> DocBuilder<'a, Self> {
        DocBuilder(self, Text(data.into()))
    }

    #[inline]
    fn concat<I>(&'a self, docs: I) -> DocBuilder<'a, Self>
    where I: IntoIterator<Item = doc::Doc<'a, Self::Doc>>
    {
        docs.into_iter().fold(self.nil(), |a, b| a.append(b))
    }
}

impl<'a, 's, A: ?Sized> DocBuilder<'a, A> where A: DocAllocator<'a> {
    #[inline]
    pub fn append<B>(self, that: B) -> DocBuilder<'a, A>
    where B: Into<doc::Doc<'a, A::Doc>>,
    {
        let DocBuilder(allocator, this) = self;
        let that = that.into();
        let doc = match this {
            Nil  => that,
            _ => match that {
                Nil  => this,
                _ => Append(allocator.alloc(this), allocator.alloc(that)),
            }
        };
        DocBuilder(allocator, doc)
    }

    #[inline]
    pub fn group(self) -> DocBuilder<'a, A>
    {
        let DocBuilder(allocator, this) = self;
        DocBuilder(allocator, Group(allocator.alloc(this)))
    }

    #[inline]
    pub fn nest(self, offset: usize) -> DocBuilder<'a, A>
    {
        let DocBuilder(allocator, this) = self;
        DocBuilder(allocator, Nest(offset, allocator.alloc(this)))
    }
}

/// Newtype wrapper for `&doc::Doc`
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct RefDoc<'a>(&'a doc::Doc<'a, RefDoc<'a>>);

impl<'a> fmt::Debug for RefDoc<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<'a> Deref for RefDoc<'a> {
    type Target = doc::Doc<'a, RefDoc<'a>>;

    fn deref(&self) -> &doc::Doc<'a, RefDoc<'a>> {
        &self.0
    }
}

/// An arena which can be used to allocate `Doc` values.
pub type Arena<'a> = typed_arena::Arena<doc::Doc<'a, RefDoc<'a>>>;

impl<'a> DocAllocator<'a> for Arena<'a> {
    type Doc = RefDoc<'a>;

    fn alloc(&'a self, doc: doc::Doc<'a, Self::Doc>) -> Self::Doc {
        RefDoc(Arena::alloc(self, doc))
    }
}

pub struct BoxAllocator;

static BOX_ALLOCATOR: BoxAllocator = BoxAllocator;

impl<'a> DocAllocator<'a> for BoxAllocator {
    type Doc = BoxDoc<'a>;

    fn alloc(&'a self, doc: doc::Doc<'a, Self::Doc>) -> Self::Doc {
        BoxDoc::new(doc)
    }
}

pub use doc::Doc;

impl<'a, B> Doc<'a, B> {
    #[inline]
    pub fn nil() -> Doc<'a, B> {
        Nil
    }

    #[inline]
    pub fn as_string<T: ToString>(t: T) -> Doc<'a, B> {
        Doc::text(t.to_string())
    }

    #[inline]
    pub fn newline() -> Doc<'a, B> {
        Newline
    }

    #[inline]
    pub fn text<T: Into<Cow<'a, str>>>(data: T) -> Doc<'a, B> {
        Text(data.into())
    }
}

impl<'a> Doc<'a, BoxDoc<'a>> {
    #[inline]
    pub fn append(self, that: Doc<'a, BoxDoc<'a>>) -> Doc<'a, BoxDoc<'a>> {
        DocBuilder(&BOX_ALLOCATOR, self).append(that).into()
    }

    #[inline]
    pub fn concat<I>(&'a self, docs: I) -> Doc<'a, BoxDoc<'a>>
    where I: IntoIterator<Item = Doc<'a, BoxDoc<'a>>>
    {
        docs.into_iter().fold(Doc::nil(), |a, b| a.append(b))
    }

    #[inline]
    pub fn group(self) -> Doc<'a, BoxDoc<'a>> {
        DocBuilder(&BOX_ALLOCATOR, self).group().into()
    }

    #[inline]
    pub fn nest(self, offset: usize) -> Doc<'a, BoxDoc<'a>> {
        DocBuilder(&BOX_ALLOCATOR, self).nest(offset).into()
    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
use fnv::FnvHashMap;

#[cfg(test)]
use juniper::{self, FromInputValue, GraphQLType, InputValue, ToInputValue};

#[derive(GraphQLEnum, Debug, PartialEq)]
#[graphql(name = "Some", description = "enum descr")]
enum SomeEnum {
    Regular,

    #[graphql(name = "FULL", description = "field descr", deprecated = "depr")]
    Full,
}

#[test]
fn test_derived_enum() {
    // Ensure that rename works.
    assert_eq!(SomeEnum::name(&()), Some("Some"));

    // Ensure validity of meta info.
    let mut registry = juniper::Registry::new(FnvHashMap::default());
    let meta = SomeEnum::meta(&(), &mut registry);

    assert_eq!(meta.name(), Some("Some"));
    assert_eq!(meta.description(), Some(&"enum descr".to_string()));

    // Test Regular variant.
    assert_eq!(SomeEnum::Regular.to_input_value(), InputValue::String("REGULAR".into()));
    assert_eq!(
        FromInputValue::from_input_value(&InputValue::String("REGULAR".into())),
        Some(SomeEnum::Regular)
    );

    // Test FULL variant.
    assert_eq!(SomeEnum::Full.to_input_value(), InputValue::String("FULL".into()));
    assert_eq!(
        FromInputValue::from_input_value(&InputValue::String("FULL".into())),
        Some(SomeEnum::Full)
    );
}
<commit_msg>(tests) Fix derive_enum test to actually test custom names<commit_after>#[cfg(test)]
use fnv::FnvHashMap;

#[cfg(test)]
use juniper::{self, FromInputValue, GraphQLType, InputValue, ToInputValue};

#[derive(GraphQLEnum, Debug, PartialEq)]
#[graphql(name = "Some", description = "enum descr")]
enum SomeEnum {
    Regular,

    #[graphql(name = "full", description = "field descr", deprecated = "depr")]
    Full,
}

#[test]
fn test_derived_enum() {
    // Ensure that rename works.
    assert_eq!(SomeEnum::name(&()), Some("Some"));

    // Ensure validity of meta info.
    let mut registry = juniper::Registry::new(FnvHashMap::default());
    let meta = SomeEnum::meta(&(), &mut registry);

    assert_eq!(meta.name(), Some("Some"));
    assert_eq!(meta.description(), Some(&"enum descr".to_string()));

    // Test Regular variant.
    assert_eq!(SomeEnum::Regular.to_input_value(), InputValue::String("REGULAR".into()));
    assert_eq!(
        FromInputValue::from_input_value(&InputValue::String("REGULAR".into())),
        Some(SomeEnum::Regular)
    );

    // Test FULL variant.
    assert_eq!(SomeEnum::Full.to_input_value(), InputValue::String("full".into()));
    assert_eq!(
        FromInputValue::from_input_value(&InputValue::String("full".into())),
        Some(SomeEnum::Full)
    );
}
<|endoftext|>


<commit_before>use std::collections::{HashMap};
use std::hash::{Hash, Hasher};
use std::sync::{Mutex, Condvar};
use std::cmp::{self, Ordering};
use std::time::{Duration};
use std::{mem};

use arc::{Arc, Weak, WeakTrait};
use sortedvec::{SortedVec};
use super::{Selectable, _Selectable};

/// Container for all targets being selected on.
pub struct Select {
    condvar: Arc<Condvar>,
    inner: Arc<Mutex<Inner>>,
}

impl Select {
    /// Creates a new `Select` object.
    pub fn new() -> Select {
        let condvar = Arc::new(Condvar::new());
        Select {
            condvar: condvar.clone(),
            inner: Arc::new(Mutex::new(Inner::new(condvar)))
        }
    }

    fn as_payload(&self) -> Payload {
        Payload { data: self.inner.downgrade() }
    }

    /// Adds a target to the select object.
    pub fn add<T: Selectable>(&self, sel: &T) {
        let sel = sel.as_selectable();

        // Careful not to deadlock in `register`.
        sel.register(self.as_payload());

        let mut inner = self.inner.lock().unwrap();

        let id = sel.unique_id();

        if sel.ready() {
            inner.ready_list.insert(id);
        }

        inner.wait_list.insert(id, Entry { data: sel.downgrade() });
    }

    /// Removes a target from the `Select` object. Returns `true` if the target was
    /// previously registered in the `Select` object, `false` otherwise.
    pub fn remove<T: Selectable>(&self, sel: &T) -> bool {
        let sel = sel.as_selectable();

        let mut inner = self.inner.lock().unwrap();

        if inner.wait_list.remove(&sel.unique_id()).is_none() {
            return false;
        }
        inner.ready_list.remove(&sel.unique_id());

        // Careful not to deadlock in `unregister`.
        drop(inner);

        sel.unregister(self.inner.unique_id());

        true
    }

    /// Waits for any of the targets in the `Select` object to become ready. The ids of
    /// the ready targets will be stored in `ready`. Returns the prefix containing the set
    /// of stored `ids`.
    ///
    /// If the select object is empty, an empty slice is returned immediately.
    pub fn wait<'a>(&self, ready: &'a mut [usize]) -> &'a mut [usize] {
        let mut inner = self.inner.lock().unwrap();

        if inner.wait_list.is_empty() {
            return &mut [];
        }

        if let Some(n) = inner.check_ready_list(ready) {
            return &mut ready[..n];
        }

        while inner.ready_list.len() == 0 {
            inner = self.condvar.wait(inner).unwrap();
        }

        let min = cmp::min(ready.len(), inner.ready_list.len());
        for i in 0..min {
            ready[i] = inner.ready_list[i];
        }
        &mut ready[..min]
    }

    /// Waits for any of the targets in the `Select` object to become ready. The semantics
    /// are as for the `wait` function except that
    ///
    /// - if `duration` is some duration, then it will sleep for at most `duration`, and
    /// - if `duration` is none, then it will only check if at the time of the call any
    ///   targets are ready and return immediately.
    ///
    /// # Return value
    ///
    /// Returns `None` if the timeout expired.
    pub fn wait_timeout<'a>(&self, ready: &'a mut [usize],
                            duration: Option<Duration>) -> Option<&'a mut [usize]> {
        let mut inner = self.inner.lock().unwrap();

        if inner.wait_list.is_empty() {
            return Some(&mut []);
        }

        if let Some(n) = inner.check_ready_list(ready) {
            return Some(&mut ready[..n]);
        }

        let duration = match duration {
            Some(d) => d,
            _ => return Some(&mut []),
        };

        let (inner, notified) = self.condvar.wait_timeout_with(inner, duration, |inner| {
            inner.unwrap().ready_list.len() > 0
        }).unwrap();

        if !notified {
            return None;
        }

        let min = cmp::min(ready.len(), inner.ready_list.len());
        for i in 0..min {
            ready[i] = inner.ready_list[i];
        }
        Some(&mut ready[..min])
    }
}

unsafe impl Sync for Select { }
unsafe impl Send for Select { }

struct Inner {
    wait_list: HashMap<usize, Entry>,

    ready_list: SortedVec<usize>,
    ready_list2: SortedVec<usize>,

    condvar: Arc<Condvar>,
}

impl Inner {
    fn new(condvar: Arc<Condvar>) -> Inner {
        Inner {
            wait_list: HashMap::new(),
            ready_list: SortedVec::new(),
            ready_list2: SortedVec::new(),
            condvar: condvar
        }
    }

    fn add_ready(&mut self, id: usize) -> bool {
        if !self.wait_list.contains_key(&id) {
            return false;
        }

        self.ready_list.insert(id);
        self.condvar.notify_one();

        true
    }

    fn going_away(&mut self, id: usize) -> bool {
        if self.wait_list.remove(&id).is_none() {
            return false;
        }

        self.ready_list.insert(id);
        self.condvar.notify_one();

        true
    }

    fn check_ready_list(&mut self, ready: &mut [usize]) -> Option<usize> {
        for id in self.ready_list.drain() {
            if self.wait_list[id].data.upgrade().map(|e| e.ready()).unwrap_or(false) {
                self.ready_list2.push(id);
            }
        }
        mem::swap(&mut self.ready_list, &mut self.ready_list2);

        match cmp::min(ready.len(), self.ready_list.len()) {
            0 => None,
            n => {
                for i in 0..n {
                    ready[i] = self.ready_list[i];
                }
                Some(n)
            }
        }
    }
}

unsafe impl Send for Inner { }

#[derive(Clone)]
struct Entry {
    data: WeakTrait<_Selectable+'static>,
}

impl PartialEq for Entry {
    fn eq(&self, other: &Entry) -> bool {
        self.data.unique_id() == other.data.unique_id()
    }
}

impl Eq for Entry { }

impl PartialOrd for Entry {
    fn partial_cmp(&self, other: &Entry) -> Option<Ordering> {
        self.data.unique_id().partial_cmp(&other.data.unique_id())
    }
}

impl Ord for Entry {
    fn cmp(&self, other: &Entry) -> Ordering {
        self.data.unique_id().cmp(&other.data.unique_id())
    }
}

impl Hash for Entry {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.data.unique_id().hash(state);
    }
}

/// A structure stored by `Selectable` objects to interact with `Select` objects that want
/// to be notified when the `Selectable` object becomes ready.
pub struct WaitQueue {
    queue: Vec<Weak<Mutex<Inner>>>,
    id: usize,
}

impl WaitQueue {
    /// Creates a new `WaitQueue`. This function does not allocate.
    pub fn new() -> WaitQueue {
        WaitQueue {
            queue: vec!(),
            id: 0,
        }
    }

    /// Sets the `id` of the `Selectable` object containing the `WaitQueue`. This id must
    /// be the id returned by `Selectable::as_selectable().unique_id()`. This function
    /// must be called with the correct id before any other functions are called.
    pub fn set_id(&mut self, id: usize) {
        self.id = id;
    }

    /// Add a `Select` object to the `WaitQueue`. Returns the number of `Select` objects
    /// contained in the `WaitQueue` after this call.
    pub fn add(&mut self, load: Payload) -> usize {
        self.queue.push(load.data);
        self.queue.len()
    }

    /// Removes a `Select` object from the `WaitQueue`. Returns the number of `Select`
    /// objects contained in the `WaitQueue` after this call.
    pub fn remove(&mut self, id: usize) -> usize {
        if let Some(p) = self.queue.iter().position(|el| el.unique_id() == id) {
            self.queue.remove(p);
        }
        self.queue.len()
    }

    /// Notifies all `Select` objects contained in this `WaitQueue` that the `Selectable`
    /// object has become ready. Returns the number of `Select` objects contained in the
    /// `WaitQueue` after this call. This function might remove `Select` objects from the
    /// `WaitQueue`.
    pub fn notify(&mut self) -> usize {
        let mut i = 0;
        while i < self.queue.len() {
            let strong = match self.queue[i].upgrade() {
                Some(s) => s,
                _ => {
                    self.queue.swap_remove(i);
                    continue;
                },
            };
            let mut select = strong.lock().unwrap();
            select.add_ready(self.id);
            i += 1;
        }
        self.queue.len()
    }

    /// Removes all `Select` objects from this wait queue and signals them that the
    /// `Selectable` object will no longer be available. This happens automatically when
    /// the `WaitQueue` is dropped.
    pub fn clear(&mut self) {
        for el in self.queue.drain() {
            if let Some(strong) = el.upgrade() {
                let mut select = strong.lock().unwrap();
                select.going_away(self.id);
            }
        }
    }
}

impl Drop for WaitQueue {
    fn drop(&mut self) {
        self.clear();
    }
}

/// Container passed from the `Select` object to a `WaitQueue`.
pub struct Payload {
    data: Weak<Mutex<Inner>>,
}
<commit_msg>fix bug in ready list checking<commit_after>use std::collections::{HashMap};
use std::hash::{Hash, Hasher};
use std::sync::{Mutex, Condvar};
use std::cmp::{self, Ordering};
use std::time::{Duration};
use std::{mem};

use arc::{Arc, Weak, WeakTrait};
use sortedvec::{SortedVec};
use super::{Selectable, _Selectable};

/// Container for all targets being selected on.
pub struct Select {
    condvar: Arc<Condvar>,
    inner: Arc<Mutex<Inner>>,
}

impl Select {
    /// Creates a new `Select` object.
    pub fn new() -> Select {
        let condvar = Arc::new(Condvar::new());
        Select {
            condvar: condvar.clone(),
            inner: Arc::new(Mutex::new(Inner::new(condvar)))
        }
    }

    fn as_payload(&self) -> Payload {
        Payload { data: self.inner.downgrade() }
    }

    /// Adds a target to the select object.
    pub fn add<T: Selectable>(&self, sel: &T) {
        let sel = sel.as_selectable();

        // Careful not to deadlock in `register`.
        sel.register(self.as_payload());

        let mut inner = self.inner.lock().unwrap();

        let id = sel.unique_id();

        if sel.ready() {
            inner.ready_list.insert(id);
        }

        inner.wait_list.insert(id, Entry { data: sel.downgrade() });
    }

    /// Removes a target from the `Select` object. Returns `true` if the target was
    /// previously registered in the `Select` object, `false` otherwise.
    pub fn remove<T: Selectable>(&self, sel: &T) -> bool {
        let sel = sel.as_selectable();

        let mut inner = self.inner.lock().unwrap();

        if inner.wait_list.remove(&sel.unique_id()).is_none() {
            return false;
        }
        inner.ready_list.remove(&sel.unique_id());

        // Careful not to deadlock in `unregister`.
        drop(inner);

        sel.unregister(self.inner.unique_id());

        true
    }

    /// Waits for any of the targets in the `Select` object to become ready. The ids of
    /// the ready targets will be stored in `ready`. Returns the prefix containing the set
    /// of stored `ids`.
    ///
    /// If the select object is empty, an empty slice is returned immediately.
    pub fn wait<'a>(&self, ready: &'a mut [usize]) -> &'a mut [usize] {
        let mut inner = self.inner.lock().unwrap();

        if inner.wait_list.is_empty() {
            return &mut [];
        }

        if let Some(n) = inner.check_ready_list(ready) {
            return &mut ready[..n];
        }

        while inner.ready_list.len() == 0 {
            inner = self.condvar.wait(inner).unwrap();
        }

        let min = cmp::min(ready.len(), inner.ready_list.len());
        for i in 0..min {
            ready[i] = inner.ready_list[i];
        }
        &mut ready[..min]
    }

    /// Waits for any of the targets in the `Select` object to become ready. The semantics
    /// are as for the `wait` function except that
    ///
    /// - if `duration` is some duration, then it will sleep for at most `duration`, and
    /// - if `duration` is none, then it will only check if at the time of the call any
    ///   targets are ready and return immediately.
    ///
    /// # Return value
    ///
    /// Returns `None` if the timeout expired.
    pub fn wait_timeout<'a>(&self, ready: &'a mut [usize],
                            duration: Option<Duration>) -> Option<&'a mut [usize]> {
        let mut inner = self.inner.lock().unwrap();

        if inner.wait_list.is_empty() {
            return Some(&mut []);
        }

        if let Some(n) = inner.check_ready_list(ready) {
            return Some(&mut ready[..n]);
        }

        let duration = match duration {
            Some(d) => d,
            _ => return Some(&mut []),
        };

        let (inner, notified) = self.condvar.wait_timeout_with(inner, duration, |inner| {
            inner.unwrap().ready_list.len() > 0
        }).unwrap();

        if !notified {
            return None;
        }

        let min = cmp::min(ready.len(), inner.ready_list.len());
        for i in 0..min {
            ready[i] = inner.ready_list[i];
        }
        Some(&mut ready[..min])
    }
}

unsafe impl Sync for Select { }
unsafe impl Send for Select { }

struct Inner {
    wait_list: HashMap<usize, Entry>,

    ready_list: SortedVec<usize>,
    ready_list2: SortedVec<usize>,

    condvar: Arc<Condvar>,
}

impl Inner {
    fn new(condvar: Arc<Condvar>) -> Inner {
        Inner {
            wait_list: HashMap::new(),
            ready_list: SortedVec::new(),
            ready_list2: SortedVec::new(),
            condvar: condvar
        }
    }

    fn add_ready(&mut self, id: usize) -> bool {
        if !self.wait_list.contains_key(&id) {
            return false;
        }

        self.ready_list.insert(id);
        self.condvar.notify_one();

        true
    }

    fn going_away(&mut self, id: usize) -> bool {
        if self.wait_list.remove(&id).is_none() {
            return false;
        }

        self.ready_list.insert(id);
        self.condvar.notify_one();

        true
    }

    fn check_ready_list(&mut self, ready: &mut [usize]) -> Option<usize> {
        for id in self.ready_list.drain() {
            if let Some(target) = self.wait_list.get(&id) {
                if target.data.upgrade().map(|e| e.ready()).unwrap_or(false) {
                    self.ready_list2.push(id);
                }
            }
        }
        mem::swap(&mut self.ready_list, &mut self.ready_list2);

        match cmp::min(ready.len(), self.ready_list.len()) {
            0 => None,
            n => {
                for i in 0..n {
                    ready[i] = self.ready_list[i];
                }
                Some(n)
            }
        }
    }
}

unsafe impl Send for Inner { }

#[derive(Clone)]
struct Entry {
    data: WeakTrait<_Selectable+'static>,
}

impl PartialEq for Entry {
    fn eq(&self, other: &Entry) -> bool {
        self.data.unique_id() == other.data.unique_id()
    }
}

impl Eq for Entry { }

impl PartialOrd for Entry {
    fn partial_cmp(&self, other: &Entry) -> Option<Ordering> {
        self.data.unique_id().partial_cmp(&other.data.unique_id())
    }
}

impl Ord for Entry {
    fn cmp(&self, other: &Entry) -> Ordering {
        self.data.unique_id().cmp(&other.data.unique_id())
    }
}

impl Hash for Entry {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.data.unique_id().hash(state);
    }
}

/// A structure stored by `Selectable` objects to interact with `Select` objects that want
/// to be notified when the `Selectable` object becomes ready.
pub struct WaitQueue {
    queue: Vec<Weak<Mutex<Inner>>>,
    id: usize,
}

impl WaitQueue {
    /// Creates a new `WaitQueue`. This function does not allocate.
    pub fn new() -> WaitQueue {
        WaitQueue {
            queue: vec!(),
            id: 0,
        }
    }

    /// Sets the `id` of the `Selectable` object containing the `WaitQueue`. This id must
    /// be the id returned by `Selectable::as_selectable().unique_id()`. This function
    /// must be called with the correct id before any other functions are called.
    pub fn set_id(&mut self, id: usize) {
        self.id = id;
    }

    /// Add a `Select` object to the `WaitQueue`. Returns the number of `Select` objects
    /// contained in the `WaitQueue` after this call.
    pub fn add(&mut self, load: Payload) -> usize {
        self.queue.push(load.data);
        self.queue.len()
    }

    /// Removes a `Select` object from the `WaitQueue`. Returns the number of `Select`
    /// objects contained in the `WaitQueue` after this call.
    pub fn remove(&mut self, id: usize) -> usize {
        if let Some(p) = self.queue.iter().position(|el| el.unique_id() == id) {
            self.queue.remove(p);
        }
        self.queue.len()
    }

    /// Notifies all `Select` objects contained in this `WaitQueue` that the `Selectable`
    /// object has become ready. Returns the number of `Select` objects contained in the
    /// `WaitQueue` after this call. This function might remove `Select` objects from the
    /// `WaitQueue`.
    pub fn notify(&mut self) -> usize {
        let mut i = 0;
        while i < self.queue.len() {
            let strong = match self.queue[i].upgrade() {
                Some(s) => s,
                _ => {
                    self.queue.swap_remove(i);
                    continue;
                },
            };
            let mut select = strong.lock().unwrap();
            select.add_ready(self.id);
            i += 1;
        }
        self.queue.len()
    }

    /// Removes all `Select` objects from this wait queue and signals them that the
    /// `Selectable` object will no longer be available. This happens automatically when
    /// the `WaitQueue` is dropped.
    pub fn clear(&mut self) {
        for el in self.queue.drain() {
            if let Some(strong) = el.upgrade() {
                let mut select = strong.lock().unwrap();
                select.going_away(self.id);
            }
        }
    }
}

impl Drop for WaitQueue {
    fn drop(&mut self) {
        self.clear();
    }
}

/// Container passed from the `Select` object to a `WaitQueue`.
pub struct Payload {
    data: Weak<Mutex<Inner>>,
}
<|endoftext|>


<commit_before>use std::fmt;
use std::io;
use std::net::{SocketAddr, TcpListener as StdTcpListener};
use std::time::{Duration, Instant};

use futures::{Async, Future, Poll, Stream};
use tokio_reactor::Handle;
use tokio_tcp::TcpListener;
use tokio_timer::Delay;

use self::addr_stream::AddrStream;

/// A stream of connections from binding to an address.
#[must_use = "streams do nothing unless polled"]
pub struct AddrIncoming {
    addr: SocketAddr,
    listener: TcpListener,
    sleep_on_errors: bool,
    tcp_keepalive_timeout: Option<Duration>,
    tcp_nodelay: bool,
    timeout: Option<Delay>,
}

impl AddrIncoming {
    pub(super) fn new(addr: &SocketAddr, handle: Option<&Handle>) -> ::Result<AddrIncoming> {
        let listener = if let Some(handle) = handle {
            let std_listener = StdTcpListener::bind(addr)
                .map_err(::Error::new_listen)?;
            TcpListener::from_std(std_listener, handle)
                .map_err(::Error::new_listen)?
        } else {
            TcpListener::bind(addr).map_err(::Error::new_listen)?
        };

        let addr = listener.local_addr().map_err(::Error::new_listen)?;

        Ok(AddrIncoming {
            addr: addr,
            listener: listener,
            sleep_on_errors: true,
            tcp_keepalive_timeout: None,
            tcp_nodelay: false,
            timeout: None,
        })
    }

    /// Get the local address bound to this listener.
    pub fn local_addr(&self) -> SocketAddr {
        self.addr
    }

    /// Set whether TCP keepalive messages are enabled on accepted connections.
    ///
    /// If `None` is specified, keepalive is disabled, otherwise the duration
    /// specified will be the time to remain idle before sending TCP keepalive
    /// probes.
    pub fn set_keepalive(&mut self, keepalive: Option<Duration>) -> &mut Self {
        self.tcp_keepalive_timeout = keepalive;
        self
    }

    /// Set the value of `TCP_NODELAY` option for accepted connections.
    pub fn set_nodelay(&mut self, enabled: bool) -> &mut Self {
        self.tcp_nodelay = enabled;
        self
    }

    /// Set whether to sleep on accept errors.
    ///
    /// A possible scenario is that the process has hit the max open files
    /// allowed, and so trying to accept a new connection will fail with
    /// `EMFILE`. In some cases, it's preferable to just wait for some time, if
    /// the application will likely close some files (or connections), and try
    /// to accept the connection again. If this option is `true`, the error
    /// will be logged at the `error` level, since it is still a big deal,
    /// and then the listener will sleep for 1 second.
    ///
    /// In other cases, hitting the max open files should be treat similarly
    /// to being out-of-memory, and simply error (and shutdown). Setting
    /// this option to `false` will allow that.
    ///
    /// Default is `true`.
    pub fn set_sleep_on_errors(&mut self, val: bool) {
        self.sleep_on_errors = val;
    }
}

impl Stream for AddrIncoming {
    // currently unnameable...
    type Item = AddrStream;
    type Error = ::std::io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        // Check if a previous timeout is active that was set by IO errors.
        if let Some(ref mut to) = self.timeout {
            match to.poll() {
                Ok(Async::Ready(())) => {}
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Err(err) => {
                    error!("sleep timer error: {}", err);
                }
            }
        }
        self.timeout = None;
        loop {
            match self.listener.poll_accept() {
                Ok(Async::Ready((socket, addr))) => {
                    if let Some(dur) = self.tcp_keepalive_timeout {
                        if let Err(e) = socket.set_keepalive(Some(dur)) {
                            trace!("error trying to set TCP keepalive: {}", e);
                        }
                    }
                    if let Err(e) = socket.set_nodelay(self.tcp_nodelay) {
                        trace!("error trying to set TCP nodelay: {}", e);
                    }
                    return Ok(Async::Ready(Some(AddrStream::new(socket, addr))));
                },
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Err(e) => {
                    if self.sleep_on_errors {
                        // Connection errors can be ignored directly, continue by
                        // accepting the next request.
                        if is_connection_error(&e) {
                            debug!("accepted connection already errored: {}", e);
                            continue;
                        }
                        // Sleep 1s.
                        let delay = Instant::now() + Duration::from_secs(1);
                        let mut timeout = Delay::new(delay);

                        match timeout.poll() {
                            Ok(Async::Ready(())) => {
                                // Wow, it's been a second already? Ok then...
                                error!("accept error: {}", e);
                                continue
                            },
                            Ok(Async::NotReady) => {
                                error!("accept error: {}", e);
                                self.timeout = Some(timeout);
                                return Ok(Async::NotReady);
                            },
                            Err(timer_err) => {
                                error!("couldn't sleep on error, timer error: {}", timer_err);
                                return Err(e);
                            }
                        }
                    } else {
                        return Err(e);
                    }
                },
            }
        }
    }
}

/// This function defines errors that are per-connection. Which basically
/// means that if we get this error from `accept()` system call it means
/// next connection might be ready to be accepted.
///
/// All other errors will incur a timeout before next `accept()` is performed.
/// The timeout is useful to handle resource exhaustion errors like ENFILE
/// and EMFILE. Otherwise, could enter into tight loop.
fn is_connection_error(e: &io::Error) -> bool {
    e.kind() == io::ErrorKind::ConnectionRefused ||
    e.kind() == io::ErrorKind::ConnectionAborted ||
    e.kind() == io::ErrorKind::ConnectionReset
}

impl fmt::Debug for AddrIncoming {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("AddrIncoming")
            .field("addr", &self.addr)
            .field("sleep_on_errors", &self.sleep_on_errors)
            .field("tcp_keepalive_timeout", &self.tcp_keepalive_timeout)
            .field("tcp_nodelay", &self.tcp_nodelay)
            .finish()
    }
}

mod addr_stream {
    use std::io::{self, Read, Write};
    use std::net::SocketAddr;
    use bytes::{Buf, BufMut};
    use futures::Poll;
    use tokio_tcp::TcpStream;
    use tokio_io::{AsyncRead, AsyncWrite};

    #[derive(Debug)]
    pub struct AddrStream {
        inner: TcpStream,
        pub(super) remote_addr: SocketAddr,
    }

    impl AddrStream {
        pub(super) fn new(tcp: TcpStream, addr: SocketAddr) -> AddrStream {
            AddrStream {
                inner: tcp,
                remote_addr: addr,
            }
        }
    }

    impl Read for AddrStream {
        #[inline]
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            self.inner.read(buf)
        }
    }

    impl Write for AddrStream {
        #[inline]
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.inner.write(buf)
        }

        #[inline]
        fn flush(&mut self) -> io::Result<()> {
            // TcpStream::flush is a noop, so skip calling it...
            Ok(())
        }
    }

    impl AsyncRead for AddrStream {
        #[inline]
        unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
            self.inner.prepare_uninitialized_buffer(buf)
        }

        #[inline]
        fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
            self.inner.read_buf(buf)
        }
    }

    impl AsyncWrite for AddrStream {
        #[inline]
        fn shutdown(&mut self) -> Poll<(), io::Error> {
            AsyncWrite::shutdown(&mut self.inner)
        }

        #[inline]
        fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
            self.inner.write_buf(buf)
        }
    }
}
<commit_msg>feat(server): add remote_addr method to AddrStream<commit_after>use std::fmt;
use std::io;
use std::net::{SocketAddr, TcpListener as StdTcpListener};
use std::time::{Duration, Instant};

use futures::{Async, Future, Poll, Stream};
use tokio_reactor::Handle;
use tokio_tcp::TcpListener;
use tokio_timer::Delay;

use self::addr_stream::AddrStream;

/// A stream of connections from binding to an address.
#[must_use = "streams do nothing unless polled"]
pub struct AddrIncoming {
    addr: SocketAddr,
    listener: TcpListener,
    sleep_on_errors: bool,
    tcp_keepalive_timeout: Option<Duration>,
    tcp_nodelay: bool,
    timeout: Option<Delay>,
}

impl AddrIncoming {
    pub(super) fn new(addr: &SocketAddr, handle: Option<&Handle>) -> ::Result<AddrIncoming> {
        let listener = if let Some(handle) = handle {
            let std_listener = StdTcpListener::bind(addr)
                .map_err(::Error::new_listen)?;
            TcpListener::from_std(std_listener, handle)
                .map_err(::Error::new_listen)?
        } else {
            TcpListener::bind(addr).map_err(::Error::new_listen)?
        };

        let addr = listener.local_addr().map_err(::Error::new_listen)?;

        Ok(AddrIncoming {
            addr: addr,
            listener: listener,
            sleep_on_errors: true,
            tcp_keepalive_timeout: None,
            tcp_nodelay: false,
            timeout: None,
        })
    }

    /// Get the local address bound to this listener.
    pub fn local_addr(&self) -> SocketAddr {
        self.addr
    }

    /// Set whether TCP keepalive messages are enabled on accepted connections.
    ///
    /// If `None` is specified, keepalive is disabled, otherwise the duration
    /// specified will be the time to remain idle before sending TCP keepalive
    /// probes.
    pub fn set_keepalive(&mut self, keepalive: Option<Duration>) -> &mut Self {
        self.tcp_keepalive_timeout = keepalive;
        self
    }

    /// Set the value of `TCP_NODELAY` option for accepted connections.
    pub fn set_nodelay(&mut self, enabled: bool) -> &mut Self {
        self.tcp_nodelay = enabled;
        self
    }

    /// Set whether to sleep on accept errors.
    ///
    /// A possible scenario is that the process has hit the max open files
    /// allowed, and so trying to accept a new connection will fail with
    /// `EMFILE`. In some cases, it's preferable to just wait for some time, if
    /// the application will likely close some files (or connections), and try
    /// to accept the connection again. If this option is `true`, the error
    /// will be logged at the `error` level, since it is still a big deal,
    /// and then the listener will sleep for 1 second.
    ///
    /// In other cases, hitting the max open files should be treat similarly
    /// to being out-of-memory, and simply error (and shutdown). Setting
    /// this option to `false` will allow that.
    ///
    /// Default is `true`.
    pub fn set_sleep_on_errors(&mut self, val: bool) {
        self.sleep_on_errors = val;
    }
}

impl Stream for AddrIncoming {
    // currently unnameable...
    type Item = AddrStream;
    type Error = ::std::io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        // Check if a previous timeout is active that was set by IO errors.
        if let Some(ref mut to) = self.timeout {
            match to.poll() {
                Ok(Async::Ready(())) => {}
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Err(err) => {
                    error!("sleep timer error: {}", err);
                }
            }
        }
        self.timeout = None;
        loop {
            match self.listener.poll_accept() {
                Ok(Async::Ready((socket, addr))) => {
                    if let Some(dur) = self.tcp_keepalive_timeout {
                        if let Err(e) = socket.set_keepalive(Some(dur)) {
                            trace!("error trying to set TCP keepalive: {}", e);
                        }
                    }
                    if let Err(e) = socket.set_nodelay(self.tcp_nodelay) {
                        trace!("error trying to set TCP nodelay: {}", e);
                    }
                    return Ok(Async::Ready(Some(AddrStream::new(socket, addr))));
                },
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Err(e) => {
                    if self.sleep_on_errors {
                        // Connection errors can be ignored directly, continue by
                        // accepting the next request.
                        if is_connection_error(&e) {
                            debug!("accepted connection already errored: {}", e);
                            continue;
                        }
                        // Sleep 1s.
                        let delay = Instant::now() + Duration::from_secs(1);
                        let mut timeout = Delay::new(delay);

                        match timeout.poll() {
                            Ok(Async::Ready(())) => {
                                // Wow, it's been a second already? Ok then...
                                error!("accept error: {}", e);
                                continue
                            },
                            Ok(Async::NotReady) => {
                                error!("accept error: {}", e);
                                self.timeout = Some(timeout);
                                return Ok(Async::NotReady);
                            },
                            Err(timer_err) => {
                                error!("couldn't sleep on error, timer error: {}", timer_err);
                                return Err(e);
                            }
                        }
                    } else {
                        return Err(e);
                    }
                },
            }
        }
    }
}

/// This function defines errors that are per-connection. Which basically
/// means that if we get this error from `accept()` system call it means
/// next connection might be ready to be accepted.
///
/// All other errors will incur a timeout before next `accept()` is performed.
/// The timeout is useful to handle resource exhaustion errors like ENFILE
/// and EMFILE. Otherwise, could enter into tight loop.
fn is_connection_error(e: &io::Error) -> bool {
    e.kind() == io::ErrorKind::ConnectionRefused ||
    e.kind() == io::ErrorKind::ConnectionAborted ||
    e.kind() == io::ErrorKind::ConnectionReset
}

impl fmt::Debug for AddrIncoming {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("AddrIncoming")
            .field("addr", &self.addr)
            .field("sleep_on_errors", &self.sleep_on_errors)
            .field("tcp_keepalive_timeout", &self.tcp_keepalive_timeout)
            .field("tcp_nodelay", &self.tcp_nodelay)
            .finish()
    }
}

mod addr_stream {
    use std::io::{self, Read, Write};
    use std::net::SocketAddr;
    use bytes::{Buf, BufMut};
    use futures::Poll;
    use tokio_tcp::TcpStream;
    use tokio_io::{AsyncRead, AsyncWrite};

    #[derive(Debug)]
    pub struct AddrStream {
        inner: TcpStream,
        pub(super) remote_addr: SocketAddr,
    }

    impl AddrStream {
        pub(super) fn new(tcp: TcpStream, addr: SocketAddr) -> AddrStream {
            AddrStream {
                inner: tcp,
                remote_addr: addr,
            }
        }

        /// Returns the remote (peer) address of this connection.
        #[inline]
        pub fn remote_addr(&self) -> SocketAddr {
            self.remote_addr
        }
    }

    impl Read for AddrStream {
        #[inline]
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            self.inner.read(buf)
        }
    }

    impl Write for AddrStream {
        #[inline]
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.inner.write(buf)
        }

        #[inline]
        fn flush(&mut self) -> io::Result<()> {
            // TcpStream::flush is a noop, so skip calling it...
            Ok(())
        }
    }

    impl AsyncRead for AddrStream {
        #[inline]
        unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
            self.inner.prepare_uninitialized_buffer(buf)
        }

        #[inline]
        fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
            self.inner.read_buf(buf)
        }
    }

    impl AsyncWrite for AddrStream {
        #[inline]
        fn shutdown(&mut self) -> Poll<(), io::Error> {
            AsyncWrite::shutdown(&mut self.inner)
        }

        #[inline]
        fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
            self.inner.write_buf(buf)
        }
    }
}
<|endoftext|>


<commit_before>use crate::spec::EntitySpawn;
use crate::terrain::Terrain;
use calx::{CellVector, FromPrefab, IntoPrefab};
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::error::Error;
use std::fmt;

pub type Prefab = HashMap<CellVector, (Terrain, Vec<EntitySpawn>)>;

#[derive(Debug, Serialize, Deserialize)]
pub struct MapSave {
    pub map: String,
    pub legend: BTreeMap<char, (Terrain, Vec<EntitySpawn>)>,
}

/// Convert a standard map prefab into an ASCII map with a legend.
///
/// The legend characters are assigned procedurally. The function will fail if the prefab is too
/// complex and the legend generator runs out of separate characters to use.
pub fn build_textmap(
    prefab: &Prefab,
) -> Result<
    (
        HashMap<CellVector, char>,
        BTreeMap<char, (Terrain, Vec<EntitySpawn>)>,
    ),
    Box<dyn Error>,
> {
    const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                            abcdefghijklmnopqrstuvwxyz\
                            0123456789";

    let chars_f = move |x: &(Terrain, Vec<EntitySpawn>)| {
        let &(ref t, ref e) = x;
        if e.is_empty() {
            t.preferred_map_chars()
        } else {
            ""
        }
    };

    let mut legend_builder = calx::LegendBuilder::new(ALPHABET.to_string(), chars_f);

    let prefab: HashMap<CellVector, _> = prefab
        .clone()
        .into_iter()
        .map(|(p, e)| (p, legend_builder.add(&e)))
        .collect();
    // Values are still results, we need to check if legend building failed.
    if legend_builder.out_of_alphabet {
        return Err("Unable to build legend, scene too complex?".into());
    }

    // Mustn't have non-errs in the build prefab unless out_of_alphabet was flipped.
    let prefab: HashMap<CellVector, _> = prefab.into_iter().map(|(p, e)| (p, e.unwrap())).collect();

    Ok((prefab, legend_builder.legend))
}

impl MapSave {
    pub fn from_prefab(prefab: &Prefab) -> Result<MapSave, Box<dyn Error>> {
        let (prefab, legend) = build_textmap(prefab)?;
        Ok(MapSave::new(prefab, legend))
    }

    pub fn into_prefab(self) -> Result<Prefab, Box<dyn Error>> {
        let (map, legend) = (self.map, self.legend);
        for c in map.chars() {
            if c.is_whitespace() {
                continue;
            }
            if !legend.contains_key(&c) {
                return Err(format!("Unknown map character '{}'", c).into());
            }
        }

        let prefab: HashMap<CellVector, char> = IntoPrefab::into_prefab(map)?;
        let ret: Prefab = prefab
            .into_iter()
            .map(|(p, item)| (p, legend[&item].clone()))
            .collect();
        Ok(ret)
    }

    pub fn new(
        text_prefab: impl IntoIterator<Item = (CellVector, char)>,
        legend: impl IntoIterator<Item = (char, (Terrain, Vec<EntitySpawn>))>,
    ) -> MapSave {
        MapSave {
            map: String::from_prefab(&text_prefab.into_iter().collect()),
            legend: legend.into_iter().collect(),
        }
    }
}

impl fmt::Display for MapSave {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Custom RON prettyprint that prints prettier than ron::ser::pretty
        writeln!(f, "(\n    map: \"")?;
        for line in self.map.lines() {
            writeln!(f, "{}", line.trim_end())?;
        }
        writeln!(f, "\",\n")?;
        writeln!(f, "    legend: {{")?;
        for (k, v) in &self.legend {
            writeln!(f, "        {:?}: ({:?}, {:?}),", k, v.0, v.1)?;
        }
        writeln!(f, "    }}")?;
        writeln!(f, ")")
    }
}
<commit_msg>Lettery alphabet for map legend<commit_after>use crate::spec::EntitySpawn;
use crate::terrain::Terrain;
use calx::{CellVector, FromPrefab, IntoPrefab};
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::error::Error;
use std::fmt;

pub type Prefab = HashMap<CellVector, (Terrain, Vec<EntitySpawn>)>;

#[derive(Debug, Serialize, Deserialize)]
pub struct MapSave {
    pub map: String,
    pub legend: BTreeMap<char, (Terrain, Vec<EntitySpawn>)>,
}

/// Convert a standard map prefab into an ASCII map with a legend.
///
/// The legend characters are assigned procedurally. The function will fail if the prefab is too
/// complex and the legend generator runs out of separate characters to use.
pub fn build_textmap(
    prefab: &Prefab,
) -> Result<
    (
        HashMap<CellVector, char>,
        BTreeMap<char, (Terrain, Vec<EntitySpawn>)>,
    ),
    Box<dyn Error>,
> {
    const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                            abcdefghijklmnopqrstuvwxyz\
                            αβγδεζηθικλμξπρστφχψω\
                            ΓΔΛΞΠΣΦΨΩ\
                            БГҐДЂЃЄЖЗЙЛЉЊПЎФЦЧЏШЩЪЭЮЯ\
                            àèòùáêõýþâìúãíäîåæçéóëïðñôûöøüÿ\
                            ÀÈÒÙÁÊÕÝÞÂÌÚÃÉÓÄÍÅÆÇËÎÔÏÐÑÖØÛßÜ";

    let chars_f = move |x: &(Terrain, Vec<EntitySpawn>)| {
        let &(ref t, ref e) = x;
        if e.is_empty() {
            t.preferred_map_chars()
        } else {
            ""
        }
    };

    let mut legend_builder = calx::LegendBuilder::new(ALPHABET.to_string(), chars_f);

    let prefab: HashMap<CellVector, _> = prefab
        .clone()
        .into_iter()
        .map(|(p, e)| (p, legend_builder.add(&e)))
        .collect();
    // Values are still results, we need to check if legend building failed.
    if legend_builder.out_of_alphabet {
        return Err("Unable to build legend, scene too complex?".into());
    }

    // Mustn't have non-errs in the build prefab unless out_of_alphabet was flipped.
    let prefab: HashMap<CellVector, _> = prefab.into_iter().map(|(p, e)| (p, e.unwrap())).collect();

    Ok((prefab, legend_builder.legend))
}

impl MapSave {
    pub fn from_prefab(prefab: &Prefab) -> Result<MapSave, Box<dyn Error>> {
        let (prefab, legend) = build_textmap(prefab)?;
        Ok(MapSave::new(prefab, legend))
    }

    pub fn into_prefab(self) -> Result<Prefab, Box<dyn Error>> {
        let (map, legend) = (self.map, self.legend);
        for c in map.chars() {
            if c.is_whitespace() {
                continue;
            }
            if !legend.contains_key(&c) {
                return Err(format!("Unknown map character '{}'", c).into());
            }
        }

        let prefab: HashMap<CellVector, char> = IntoPrefab::into_prefab(map)?;
        let ret: Prefab = prefab
            .into_iter()
            .map(|(p, item)| (p, legend[&item].clone()))
            .collect();
        Ok(ret)
    }

    pub fn new(
        text_prefab: impl IntoIterator<Item = (CellVector, char)>,
        legend: impl IntoIterator<Item = (char, (Terrain, Vec<EntitySpawn>))>,
    ) -> MapSave {
        MapSave {
            map: String::from_prefab(&text_prefab.into_iter().collect()),
            legend: legend.into_iter().collect(),
        }
    }
}

impl fmt::Display for MapSave {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Custom RON prettyprint that prints prettier than ron::ser::pretty
        writeln!(f, "(\n    map: \"")?;
        for line in self.map.lines() {
            writeln!(f, "{}", line.trim_end())?;
        }
        writeln!(f, "\",\n")?;
        writeln!(f, "    legend: {{")?;
        for (k, v) in &self.legend {
            writeln!(f, "        {:?}: ({:?}, {:?}),", k, v.0, v.1)?;
        }
        writeln!(f, "    }}")?;
        writeln!(f, ")")
    }
}
<|endoftext|>