<commit_before>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign, Div, Rem};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};
use crate::intrinsics;

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            /// An integer that is known not to equal zero.
            ///
            /// This enables some memory layout optimization.
            #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
            ///
            /// ```rust
            /// use std::mem::size_of;
            #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
            /// ```
            #[$stability]
            #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
            #[repr(transparent)]
            #[rustc_layout_scalar_valid_range_start(1)]
            #[rustc_nonnull_optimization_guaranteed]
            pub struct $Ty($Int);

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
                #[inline]
                fn from(nonzero: $Ty) -> Self {
                    nonzero.0
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }

macro_rules! nonzero_leading_trailing_zeros {
    ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
        $(
            impl $Ty {
                doc_comment! {
                    concat!("Returns the number of leading zeros in the binary representation of `self`.

On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.

# Examples

Basic usage:

```
#![feature(nonzero_leading_trailing_zeros)]
let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();

assert_eq!(n.leading_zeros(), 0);
```"),
                    #[unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                    #[rustc_const_unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                    #[inline]
                    pub const fn leading_zeros(self) -> u32 {
                        // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
                        unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
                    }
                }

                doc_comment! {
                    concat!("Returns the number of trailing zeros in the binary representation
of `self`.

On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.

# Examples

Basic usage:

```
#![feature(nonzero_leading_trailing_zeros)]
let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();

assert_eq!(n.trailing_zeros(), 3);
```"),
                    #[unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                    #[rustc_const_unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                    #[inline]
                    pub const fn trailing_zeros(self) -> u32 {
                        // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
                        unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
                    }
                }

            }
        )+
    }
}

nonzero_leading_trailing_zeros! {
    NonZeroU8(u8), u8::MAX;
    NonZeroU16(u16), u16::MAX;
    NonZeroU32(u32), u32::MAX;
    NonZeroU64(u64), u64::MAX;
    NonZeroU128(u128), u128::MAX;
    NonZeroUsize(usize), usize::MAX;
    NonZeroI8(u8), -1i8;
    NonZeroI16(u16), -1i16;
    NonZeroI32(u32), -1i32;
    NonZeroI64(u64), -1i64;
    NonZeroI128(u128), -1i128;
    NonZeroIsize(usize), -1isize;
}

macro_rules! nonzero_integers_div {
    ( $( $Ty: ident($Int: ty); )+ ) => {
        $(
            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Div<$Ty> for $Int {
                type Output = $Int;
                /// This operation rounds towards zero,
                /// truncating any fractional part of the exact result, and cannot panic.
                #[inline]
                fn div(self, other: $Ty) -> $Int {
                    // SAFETY: div by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
                }
            }

            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Rem<$Ty> for $Int {
                type Output = $Int;
                /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
                #[inline]
                fn rem(self, other: $Ty) -> $Int {
                    // SAFETY: rem by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
                }
            }
        )+
    }
}

nonzero_integers_div! {
    NonZeroU8(u8);
    NonZeroU16(u16);
    NonZeroU32(u32);
    NonZeroU64(u64);
    NonZeroU128(u128);
    NonZeroUsize(usize);
}
<commit_msg>Don't use doc_comment!{} hack in nonzero_leading_trailing_zeros!{}.<commit_after>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign, Div, Rem};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};
use crate::intrinsics;

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            /// An integer that is known not to equal zero.
            ///
            /// This enables some memory layout optimization.
            #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
            ///
            /// ```rust
            /// use std::mem::size_of;
            #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
            /// ```
            #[$stability]
            #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
            #[repr(transparent)]
            #[rustc_layout_scalar_valid_range_start(1)]
            #[rustc_nonnull_optimization_guaranteed]
            pub struct $Ty($Int);

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
                #[inline]
                fn from(nonzero: $Ty) -> Self {
                    nonzero.0
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }

macro_rules! nonzero_leading_trailing_zeros {
    ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
        $(
            impl $Ty {
                /// Returns the number of leading zeros in the binary representation of `self`.
                ///
                /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                /// #![feature(nonzero_leading_trailing_zeros)]
                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();")]
                ///
                /// assert_eq!(n.leading_zeros(), 0);
                /// ```
                #[unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                #[rustc_const_unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                #[inline]
                pub const fn leading_zeros(self) -> u32 {
                    // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
                    unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
                }

                /// Returns the number of trailing zeros in the binary representation
                /// of `self`.
                ///
                /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                /// #![feature(nonzero_leading_trailing_zeros)]
                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
                ///
                /// assert_eq!(n.trailing_zeros(), 3);
                /// ```
                #[unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                #[rustc_const_unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
                #[inline]
                pub const fn trailing_zeros(self) -> u32 {
                    // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
                    unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
                }

            }
        )+
    }
}

nonzero_leading_trailing_zeros! {
    NonZeroU8(u8), u8::MAX;
    NonZeroU16(u16), u16::MAX;
    NonZeroU32(u32), u32::MAX;
    NonZeroU64(u64), u64::MAX;
    NonZeroU128(u128), u128::MAX;
    NonZeroUsize(usize), usize::MAX;
    NonZeroI8(u8), -1i8;
    NonZeroI16(u16), -1i16;
    NonZeroI32(u32), -1i32;
    NonZeroI64(u64), -1i64;
    NonZeroI128(u128), -1i128;
    NonZeroIsize(usize), -1isize;
}

macro_rules! nonzero_integers_div {
    ( $( $Ty: ident($Int: ty); )+ ) => {
        $(
            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Div<$Ty> for $Int {
                type Output = $Int;
                /// This operation rounds towards zero,
                /// truncating any fractional part of the exact result, and cannot panic.
                #[inline]
                fn div(self, other: $Ty) -> $Int {
                    // SAFETY: div by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
                }
            }

            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Rem<$Ty> for $Int {
                type Output = $Int;
                /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
                #[inline]
                fn rem(self, other: $Ty) -> $Int {
                    // SAFETY: rem by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
                }
            }
        )+
    }
}

nonzero_integers_div! {
    NonZeroU8(u8);
    NonZeroU16(u16);
    NonZeroU32(u32);
    NonZeroU64(u64);
    NonZeroU128(u128);
    NonZeroUsize(usize);
}
<|endoftext|>


<commit_before>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};

macro_rules! doc_comment {
    ($x:expr, $($tt:tt)*) => {
        #[doc = $x]
        $($tt)*
    };
}

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            doc_comment! {
                concat!("An integer that is known not to equal zero.

This enables some memory layout optimization.
For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:

```rust
use std::mem::size_of;
assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
">());
```"),
                #[$stability]
                #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                #[repr(transparent)]
                #[rustc_layout_scalar_valid_range_start(1)]
                #[rustc_nonnull_optimization_guaranteed]
                pub struct $Ty($Int);
            }

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                doc_comment! {
                    concat!(
"Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`"),
                    fn from(nonzero: $Ty) -> Self {
                        nonzero.0
                    }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
<commit_msg>Rollup merge of #78491 - petertodd:2020-inline-from-nonzero, r=sfackler<commit_after>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};

macro_rules! doc_comment {
    ($x:expr, $($tt:tt)*) => {
        #[doc = $x]
        $($tt)*
    };
}

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            doc_comment! {
                concat!("An integer that is known not to equal zero.

This enables some memory layout optimization.
For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:

```rust
use std::mem::size_of;
assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
">());
```"),
                #[$stability]
                #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                #[repr(transparent)]
                #[rustc_layout_scalar_valid_range_start(1)]
                #[rustc_nonnull_optimization_guaranteed]
                pub struct $Ty($Int);
            }

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                doc_comment! {
                    concat!(
"Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`"),
                    #[inline]
                    fn from(nonzero: $Ty) -> Self {
                        nonzero.0
                    }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
<|endoftext|>


<commit_before>//  rpc-perf - RPC Performance Testing
//  Copyright 2015 Twitter, Inc
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#![crate_type = "lib"]

extern crate mpmc;
extern crate pad;
extern crate rand;
extern crate ratelimit;
extern crate rpcperf_request as request;
extern crate shuteye;
extern crate time;

const ONE_SECOND: u64 = 1_000_000_000;
pub const BUCKET_SIZE: usize = 10_000;

use mpmc::Queue as BoundedQueue;
use pad::{PadStr, Alignment};
use rand::{thread_rng, Rng};
use ratelimit::Ratelimit;
use request::{echo, memcache, ping, redis, thrift};
use std::str;
use request::thrift::*;

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Protocol {
    Echo,
    Memcache,
    Ping,
    Redis,
    Thrift,
    Unknown,
}

impl Protocol {
    pub fn new(protocol: &str) -> Result<Protocol, &'static str> {
        match &*protocol {
            "echo" => Ok(Protocol::Echo),
            "memcache" => Ok(Protocol::Memcache),
            "ping" => Ok(Protocol::Ping),
            "redis" => Ok(Protocol::Redis),
            "thrift" => Ok(Protocol::Thrift),
            _ => Err("unknown protocol"),
        }
    }
}

pub fn rate_to_interval(rate: u64) -> u64 {
    if rate == 0 {
        return 0;
    }
    let interval = ONE_SECOND / rate;
    if interval < 1 {
        return 0;
    }
    interval
}

fn random_string(size: usize) -> String {
    thread_rng().gen_ascii_chars().take(size).collect()
}

fn seeded_string(size: usize, seed: usize) -> String {
    let s = format!("{}", seed);
    s.pad(size, '0', Alignment::Right, true)
}

#[derive(Clone, Debug)]
pub enum Type {
    Stop,
    Void,
    Bool,
    Byte,
    Double,
    Int16,
    Int32,
    Int64,
    String,
    Struct,
    Map,
    Set,
    List(String),
    None,
}

#[derive(Clone, Debug)]
pub enum Style {
    Random,
    Static,
}

#[derive(Clone, Debug)]
pub struct Parameter {
    pub id: Option<i16>,
    pub ptype: Type,
    pub seed: usize,
    pub size: usize,
    pub style: Style,
    pub regenerate: bool,
    pub value: Value,
}

#[derive(Clone, Debug)]
pub enum Value {
    Stop,
    Void,
    Bool(bool),
    Byte(u8),
    Double(f64),
    Int16(i16),
    Int32(i32),
    Int64(i64),
    String(String),
    Struct,
    Map,
    Set,
    List(String, i32),
    None,
}

impl Default for Value {
    fn default() -> Value {
        Value::None
    }
}

impl Default for Parameter {
    fn default() -> Parameter {
        Parameter {
            id: None,
            ptype: Type::None,
            seed: 0,
            size: 1,
            style: Style::Static,
            regenerate: false,
            value: Default::default(),
        }
    }
}

pub enum Preparation {
    Flush,
    Hit,
}

pub struct Workload {
    protocol: Protocol,
    command: String,
    rate: u64,
    ratelimit: Ratelimit,
    queue: BoundedQueue<Vec<u8>>,
    parameters: Vec<Parameter>,
    values: Vec<Vec<u8>>,
}

impl Workload {
    pub fn new(protocol: Protocol,
               command: String,
               rate: Option<u64>,
               queue: BoundedQueue<Vec<u8>>)
               -> Result<Workload, &'static str> {
        let r = rate.unwrap_or(0);
        let i = rate_to_interval(r);
        let ratelimit = match Ratelimit::new(BUCKET_SIZE, time::precise_time_ns(), i, 1) {
            Some(r) => r,
            None => {
                return Err("Ratelimit initialization failed!");
            }
        };
        Ok(Workload {
            protocol: protocol,
            command: command,
            rate: rate.unwrap_or(0),
            ratelimit: ratelimit,
            queue: queue,
            parameters: Vec::<Parameter>::new(),
            values: Vec::<Vec<u8>>::new(),
        })
    }

    fn generate_values(&mut self, force: bool) {
        for i in 0..self.parameters.len() {
            match self.parameters[i].style {
                Style::Random => {
                    if self.parameters[i].regenerate || force {
                        self.parameters[i].value = match self.parameters[i].ptype {
                            Type::Stop => Value::Stop,
                            Type::Void => Value::Void,
                            Type::Bool => Value::Bool(rand::random::<bool>()),
                            Type::Int16 => Value::Int16(rand::random::<i16>()),
                            Type::Int32 => Value::Int32(rand::random::<i32>()),
                            Type::Int64 => Value::Int64(rand::random::<i64>()),
                            Type::Struct => Value::Struct,
                            Type::String => Value::String(random_string(self.parameters[i].size)),
                            _ => {
                                self.values[i] = random_string(self.parameters[i].size)
                                                     .into_bytes();
                                Value::None
                            }
                        }
                    }
                }
                Style::Static => {
                    self.parameters[i].value = match self.parameters[i].ptype.clone() {
                        Type::Int16 => Value::Int16(self.parameters[i].seed as i16),
                        Type::Int32 => Value::Int32(self.parameters[i].seed as i32),
                        Type::Int64 => Value::Int64(self.parameters[i].seed as i64),
                        Type::List(ttype) => Value::List(ttype.clone(), self.parameters[i].seed as i32),
                        Type::Stop => Value::Stop,
                        Type::Struct => Value::Struct,
                        _ => {
                            self.values[i] = seeded_string(self.parameters[i].size,
                                                           self.parameters[i].seed)
                                                 .into_bytes();
                            Value::None
                        }
                    }
                }
            }
        }
    }

    pub fn add_param(&mut self, parameter: Parameter) {
        self.parameters.push(parameter);
        self.values.push(Vec::<u8>::new());
    }

    pub fn prepare(&mut self, preparation: Preparation) {
        match preparation {
            Preparation::Flush => {
                match self.protocol {
                    Protocol::Memcache => {
                        let _ = self.queue.push(memcache::flush_all().into_bytes());
                    }
                    Protocol::Redis => {
                        let _ = self.queue.push(redis::flushall().into_bytes());
                    }
                    _ => {}
                }
            }
            Preparation::Hit => {
                match &*self.command {
                    "get" => {
                        match self.protocol {
                            Protocol::Memcache => {
                                if self.values.len() < 2 {
                                    self.values.push(Default::default());
                                }
                                let _ = self.queue
                                            .push(memcache::set(str::from_utf8(&*self.values[0])
                                                                    .unwrap(),
                                                                str::from_utf8(&*self.values[1])
                                                                    .unwrap(),
                                                                None,
                                                                None)
                                                      .into_bytes());
                            }
                            Protocol::Redis => {
                                let _ = self.queue.push(redis::flushall().into_bytes());
                            }
                            _ => {}
                        }
                    }
                    _ => {}
                }
            }
        }
    }

    pub fn run(&mut self) {
        self.generate_values(true);
        loop {
            if self.rate != 0 {
                self.ratelimit.block(1);
            }
            self.generate_values(false);

            let query = match self.protocol {
                Protocol::Echo => {
                    match &*self.command {
                        "echo" => echo::echo(&*self.values[0]),
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Memcache => {
                    match &*self.command {
                        "set" => {
                            memcache::set(str::from_utf8(&*self.values[0]).unwrap(),
                                          str::from_utf8(&*self.values[1]).unwrap(),
                                          None,
                                          None)
                                .into_bytes()
                        }
                        "get" => {
                            memcache::get(str::from_utf8(&*self.values[0]).unwrap()).into_bytes()
                        }
                        "gets" => {
                            memcache::gets(str::from_utf8(&*self.values[0]).unwrap()).into_bytes()
                        }
                        "add" => {
                            memcache::add(str::from_utf8(&*self.values[0]).unwrap(),
                                          str::from_utf8(&*self.values[1]).unwrap(),
                                          None,
                                          None)
                                .into_bytes()
                        }
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Ping => {
                    match &*self.command {
                        "ping" => ping::ping().into_bytes(),
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Redis => {
                    match &*self.command {
                        "set" => {
                            redis::set(str::from_utf8(&*self.values[0]).unwrap(),
                                       str::from_utf8(&*self.values[1]).unwrap())
                                .into_bytes()
                        }
                        "get" => redis::get(str::from_utf8(&*self.values[0]).unwrap()).into_bytes(),
                        "hset" => {
                            redis::hset(str::from_utf8(&*self.values[0]).unwrap(),
                                        str::from_utf8(&*self.values[1]).unwrap(),
                                        str::from_utf8(&*self.values[2]).unwrap())
                                .into_bytes()
                        }
                        "hget" => {
                            redis::hget(str::from_utf8(&*self.values[0]).unwrap(),
                                        str::from_utf8(&*self.values[1]).unwrap())
                                .into_bytes()
                        }
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Thrift => {
                    match &*self.command {
                        "ping" => thrift::ping(),
                        _ => {
                            let mut thrift = thrift::ThriftRequest::default();
                            thrift.method = &self.command;
                            for p in &self.parameters {
                                match p.value {
                                    Value::Stop => {
                                        thrift.payload.push(ThriftType::Stop)
                                    }
                                    Value::Void => {
                                        thrift.payload.push(ThriftType::Void)
                                    }
                                    Value::Bool(v) => {
                                        thrift.payload.push(ThriftType::Bool(p.id, v))
                                    }
                                    Value::Byte(v) => {
                                        thrift.payload.push(ThriftType::Byte(p.id, v))
                                    }
                                    Value::Int16(v) => {
                                        thrift.payload.push(ThriftType::Int16(p.id, v))
                                    }
                                    Value::Int32(v) => {
                                        thrift.payload.push(ThriftType::Int32(p.id, v))
                                    }
                                    Value::Int64(v) => {
                                        thrift.payload.push(ThriftType::Int64(p.id, v))
                                    }
                                    Value::String(ref v) => {
                                        thrift.payload.push(ThriftType::String(p.id, v))
                                    }
                                    Value::Struct => {
                                        thrift.payload.push(ThriftType::Struct(p.id.unwrap()))
                                    }
                                    Value::List(ref ttype, length) => {
                                        thrift.payload.push(ThriftType::List(p.id.unwrap(), ttype, length))
                                    }
                                    _ => {}
                                }
                            }
                            thrift::generic(thrift)
                        }
                    }
                }
                _ => {
                    panic!("unsupported protocol");
                }
            };
            let _ = self.queue.push(query.clone());
        }
    }
}
<commit_msg>workload: unnecessary clone()<commit_after>//  rpc-perf - RPC Performance Testing
//  Copyright 2015 Twitter, Inc
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#![crate_type = "lib"]

extern crate mpmc;
extern crate pad;
extern crate rand;
extern crate ratelimit;
extern crate rpcperf_request as request;
extern crate shuteye;
extern crate time;

const ONE_SECOND: u64 = 1_000_000_000;
pub const BUCKET_SIZE: usize = 10_000;

use mpmc::Queue as BoundedQueue;
use pad::{PadStr, Alignment};
use rand::{thread_rng, Rng};
use ratelimit::Ratelimit;
use request::{echo, memcache, ping, redis, thrift};
use std::str;
use request::thrift::*;

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Protocol {
    Echo,
    Memcache,
    Ping,
    Redis,
    Thrift,
    Unknown,
}

impl Protocol {
    pub fn new(protocol: &str) -> Result<Protocol, &'static str> {
        match &*protocol {
            "echo" => Ok(Protocol::Echo),
            "memcache" => Ok(Protocol::Memcache),
            "ping" => Ok(Protocol::Ping),
            "redis" => Ok(Protocol::Redis),
            "thrift" => Ok(Protocol::Thrift),
            _ => Err("unknown protocol"),
        }
    }
}

pub fn rate_to_interval(rate: u64) -> u64 {
    if rate == 0 {
        return 0;
    }
    let interval = ONE_SECOND / rate;
    if interval < 1 {
        return 0;
    }
    interval
}

fn random_string(size: usize) -> String {
    thread_rng().gen_ascii_chars().take(size).collect()
}

fn seeded_string(size: usize, seed: usize) -> String {
    let s = format!("{}", seed);
    s.pad(size, '0', Alignment::Right, true)
}

#[derive(Clone, Debug)]
pub enum Type {
    Stop,
    Void,
    Bool,
    Byte,
    Double,
    Int16,
    Int32,
    Int64,
    String,
    Struct,
    Map,
    Set,
    List(String),
    None,
}

#[derive(Clone, Debug)]
pub enum Style {
    Random,
    Static,
}

#[derive(Clone, Debug)]
pub struct Parameter {
    pub id: Option<i16>,
    pub ptype: Type,
    pub seed: usize,
    pub size: usize,
    pub style: Style,
    pub regenerate: bool,
    pub value: Value,
}

#[derive(Clone, Debug)]
pub enum Value {
    Stop,
    Void,
    Bool(bool),
    Byte(u8),
    Double(f64),
    Int16(i16),
    Int32(i32),
    Int64(i64),
    String(String),
    Struct,
    Map,
    Set,
    List(String, i32),
    None,
}

impl Default for Value {
    fn default() -> Value {
        Value::None
    }
}

impl Default for Parameter {
    fn default() -> Parameter {
        Parameter {
            id: None,
            ptype: Type::None,
            seed: 0,
            size: 1,
            style: Style::Static,
            regenerate: false,
            value: Default::default(),
        }
    }
}

pub enum Preparation {
    Flush,
    Hit,
}

pub struct Workload {
    protocol: Protocol,
    command: String,
    rate: u64,
    ratelimit: Ratelimit,
    queue: BoundedQueue<Vec<u8>>,
    parameters: Vec<Parameter>,
    values: Vec<Vec<u8>>,
}

impl Workload {
    pub fn new(protocol: Protocol,
               command: String,
               rate: Option<u64>,
               queue: BoundedQueue<Vec<u8>>)
               -> Result<Workload, &'static str> {
        let r = rate.unwrap_or(0);
        let i = rate_to_interval(r);
        let ratelimit = match Ratelimit::new(BUCKET_SIZE, time::precise_time_ns(), i, 1) {
            Some(r) => r,
            None => {
                return Err("Ratelimit initialization failed!");
            }
        };
        Ok(Workload {
            protocol: protocol,
            command: command,
            rate: rate.unwrap_or(0),
            ratelimit: ratelimit,
            queue: queue,
            parameters: Vec::<Parameter>::new(),
            values: Vec::<Vec<u8>>::new(),
        })
    }

    fn generate_values(&mut self, force: bool) {
        for i in 0..self.parameters.len() {
            match self.parameters[i].style {
                Style::Random => {
                    if self.parameters[i].regenerate || force {
                        self.parameters[i].value = match self.parameters[i].ptype {
                            Type::Stop => Value::Stop,
                            Type::Void => Value::Void,
                            Type::Bool => Value::Bool(rand::random::<bool>()),
                            Type::Int16 => Value::Int16(rand::random::<i16>()),
                            Type::Int32 => Value::Int32(rand::random::<i32>()),
                            Type::Int64 => Value::Int64(rand::random::<i64>()),
                            Type::Struct => Value::Struct,
                            Type::String => Value::String(random_string(self.parameters[i].size)),
                            _ => {
                                self.values[i] = random_string(self.parameters[i].size)
                                                     .into_bytes();
                                Value::None
                            }
                        }
                    }
                }
                Style::Static => {
                    self.parameters[i].value = match self.parameters[i].ptype.clone() {
                        Type::Int16 => Value::Int16(self.parameters[i].seed as i16),
                        Type::Int32 => Value::Int32(self.parameters[i].seed as i32),
                        Type::Int64 => Value::Int64(self.parameters[i].seed as i64),
                        Type::List(ttype) => Value::List(ttype.clone(), self.parameters[i].seed as i32),
                        Type::Stop => Value::Stop,
                        Type::Struct => Value::Struct,
                        _ => {
                            self.values[i] = seeded_string(self.parameters[i].size,
                                                           self.parameters[i].seed)
                                                 .into_bytes();
                            Value::None
                        }
                    }
                }
            }
        }
    }

    pub fn add_param(&mut self, parameter: Parameter) {
        self.parameters.push(parameter);
        self.values.push(Vec::<u8>::new());
    }

    pub fn prepare(&mut self, preparation: Preparation) {
        match preparation {
            Preparation::Flush => {
                match self.protocol {
                    Protocol::Memcache => {
                        let _ = self.queue.push(memcache::flush_all().into_bytes());
                    }
                    Protocol::Redis => {
                        let _ = self.queue.push(redis::flushall().into_bytes());
                    }
                    _ => {}
                }
            }
            Preparation::Hit => {
                match &*self.command {
                    "get" => {
                        match self.protocol {
                            Protocol::Memcache => {
                                if self.values.len() < 2 {
                                    self.values.push(Default::default());
                                }
                                let _ = self.queue
                                            .push(memcache::set(str::from_utf8(&*self.values[0])
                                                                    .unwrap(),
                                                                str::from_utf8(&*self.values[1])
                                                                    .unwrap(),
                                                                None,
                                                                None)
                                                      .into_bytes());
                            }
                            Protocol::Redis => {
                                let _ = self.queue.push(redis::flushall().into_bytes());
                            }
                            _ => {}
                        }
                    }
                    _ => {}
                }
            }
        }
    }

    pub fn run(&mut self) {
        self.generate_values(true);
        loop {
            if self.rate != 0 {
                self.ratelimit.block(1);
            }
            self.generate_values(false);

            let query = match self.protocol {
                Protocol::Echo => {
                    match &*self.command {
                        "echo" => echo::echo(&*self.values[0]),
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Memcache => {
                    match &*self.command {
                        "set" => {
                            memcache::set(str::from_utf8(&*self.values[0]).unwrap(),
                                          str::from_utf8(&*self.values[1]).unwrap(),
                                          None,
                                          None)
                                .into_bytes()
                        }
                        "get" => {
                            memcache::get(str::from_utf8(&*self.values[0]).unwrap()).into_bytes()
                        }
                        "gets" => {
                            memcache::gets(str::from_utf8(&*self.values[0]).unwrap()).into_bytes()
                        }
                        "add" => {
                            memcache::add(str::from_utf8(&*self.values[0]).unwrap(),
                                          str::from_utf8(&*self.values[1]).unwrap(),
                                          None,
                                          None)
                                .into_bytes()
                        }
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Ping => {
                    match &*self.command {
                        "ping" => ping::ping().into_bytes(),
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Redis => {
                    match &*self.command {
                        "set" => {
                            redis::set(str::from_utf8(&*self.values[0]).unwrap(),
                                       str::from_utf8(&*self.values[1]).unwrap())
                                .into_bytes()
                        }
                        "get" => redis::get(str::from_utf8(&*self.values[0]).unwrap()).into_bytes(),
                        "hset" => {
                            redis::hset(str::from_utf8(&*self.values[0]).unwrap(),
                                        str::from_utf8(&*self.values[1]).unwrap(),
                                        str::from_utf8(&*self.values[2]).unwrap())
                                .into_bytes()
                        }
                        "hget" => {
                            redis::hget(str::from_utf8(&*self.values[0]).unwrap(),
                                        str::from_utf8(&*self.values[1]).unwrap())
                                .into_bytes()
                        }
                        _ => {
                            panic!("unknown command: {} for protocol: {:?}",
                                   self.command,
                                   self.protocol);
                        }
                    }
                }
                Protocol::Thrift => {
                    match &*self.command {
                        "ping" => thrift::ping(),
                        _ => {
                            let mut thrift = thrift::ThriftRequest::default();
                            thrift.method = &self.command;
                            for p in &self.parameters {
                                match p.value {
                                    Value::Stop => {
                                        thrift.payload.push(ThriftType::Stop)
                                    }
                                    Value::Void => {
                                        thrift.payload.push(ThriftType::Void)
                                    }
                                    Value::Bool(v) => {
                                        thrift.payload.push(ThriftType::Bool(p.id, v))
                                    }
                                    Value::Byte(v) => {
                                        thrift.payload.push(ThriftType::Byte(p.id, v))
                                    }
                                    Value::Int16(v) => {
                                        thrift.payload.push(ThriftType::Int16(p.id, v))
                                    }
                                    Value::Int32(v) => {
                                        thrift.payload.push(ThriftType::Int32(p.id, v))
                                    }
                                    Value::Int64(v) => {
                                        thrift.payload.push(ThriftType::Int64(p.id, v))
                                    }
                                    Value::String(ref v) => {
                                        thrift.payload.push(ThriftType::String(p.id, v))
                                    }
                                    Value::Struct => {
                                        thrift.payload.push(ThriftType::Struct(p.id.unwrap()))
                                    }
                                    Value::List(ref ttype, length) => {
                                        thrift.payload.push(ThriftType::List(p.id.unwrap(), ttype, length))
                                    }
                                    _ => {}
                                }
                            }
                            thrift::generic(thrift)
                        }
                    }
                }
                _ => {
                    panic!("unsupported protocol");
                }
            };
            let _ = self.queue.push(query);
        }
    }
}
<|endoftext|>


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

use std::collections::BinaryHeap;

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};

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};

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>) {
    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 {
        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 ||
            xw < e_x ||
            fw < 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});
            }
        }
    }
    // Tell GA thread to stop
    stop.store(true, Ordering::Release);
    (f_best_high, best_x)
}

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();
}

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.x_error;

    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 result = ibba_thread.unwrap().join();
    ea_thread.unwrap().join();
    // Join EA and Update here pending stop signaling.
    if result.is_ok() {
        let (max, interval) = result.unwrap();
        println!("[{}, {{", max);
        for i in 0..args.names.len() {
            println!("'{}' : {},", args.names[i], interval[i].to_string());
        }
        println!("}}]");

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

use std::collections::BinaryHeap;

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};

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};

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>) {
    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 {
        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 ||
            xw < e_x ||
            fw < 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});
            }
        }
    }
    // Tell GA thread to stop
    stop.store(true, Ordering::Release);
    (f_best_high, best_x)
}

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();
}

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.x_error;
    if x_err <= 0.0 || y_err <= 0.0 {
        panic!("Tolerance is 0");
    }
    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 result = ibba_thread.unwrap().join();
    ea_thread.unwrap().join();
    // Join EA and Update here pending stop signaling.
    if result.is_ok() {
        let (max, interval) = result.unwrap();
        println!("[{}, {{", max);
        for i in 0..args.names.len() {
            println!("'{}' : {},", args.names[i], interval[i].to_string());
        }
        println!("}}]");

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


<commit_before>use std::ops::DerefMut;

use libimagerror::into::IntoError;
use libimagrt::runtime::Runtime;
use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;

use result::Result;
use error::EditErrorKind;
use error::MapErrInto;

pub trait Edit {
    fn edit_content(&mut self, rt: &Runtime) -> Result<()>;
}

impl Edit for String {

    fn edit_content(&mut self, rt: &Runtime) -> Result<()> {
        edit_in_tmpfile(rt, self).map(|_| ())
    }

}

impl Edit for Entry {

    fn edit_content(&mut self, rt: &Runtime) -> Result<()> {
        edit_in_tmpfile(rt, self.get_content_mut())
            .map(|_| ())
    }

}

impl<'a> Edit for FileLockEntry<'a> {

    fn edit_content(&mut self, rt: &Runtime) -> Result<()> {
        self.deref_mut().edit_content(rt)
    }

}

pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> {
    use tempfile::NamedTempFile;
    use std::io::Seek;
    use std::io::Read;
    use std::io::SeekFrom;
    use std::io::Write;

    let file      = try!(NamedTempFile::new().map_err_into(EditErrorKind::IOError));
    let file_path = file.path();
    let mut file  = try!(file.reopen().map_err_into(EditErrorKind::IOError));

    try!(file.write_all(&s.clone().into_bytes()[..]).map_err_into(EditErrorKind::IOError));
    try!(file.sync_data().map_err_into(EditErrorKind::IOError));

    if let Some(mut editor) = rt.editor() {
        let exit_status = editor.arg(file_path).status();

        match exit_status.map(|s| s.success()).map_err(Box::new) {
            Ok(true)  => {
                file.sync_data()
                    .and_then(|_| file.seek(SeekFrom::Start(0)))
                    .and_then(|_| {
                        let mut new_s = String::new();
                        let res = file.read_to_string(&mut new_s);
                        *s = new_s;
                        res
                    })
                    .map(|_| ())
                    .map_err_into(EditErrorKind::IOError)
            },
            Ok(false) => Err(EditErrorKind::ProcessExitFailure.into()),
            Err(e)    => Err(EditErrorKind::IOError.into_error_with_cause(e)),
        }
    } else {
        Err(EditErrorKind::InstantiateError.into())
    }
}
<commit_msg>Refactor edit_in_tmpfile()<commit_after>use std::ops::DerefMut;

use libimagerror::into::IntoError;
use libimagrt::runtime::Runtime;
use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;

use result::Result;
use error::EditErrorKind;
use error::MapErrInto;

pub trait Edit {
    fn edit_content(&mut self, rt: &Runtime) -> Result<()>;
}

impl Edit for String {

    fn edit_content(&mut self, rt: &Runtime) -> Result<()> {
        edit_in_tmpfile(rt, self).map(|_| ())
    }

}

impl Edit for Entry {

    fn edit_content(&mut self, rt: &Runtime) -> Result<()> {
        edit_in_tmpfile(rt, self.get_content_mut())
            .map(|_| ())
    }

}

impl<'a> Edit for FileLockEntry<'a> {

    fn edit_content(&mut self, rt: &Runtime) -> Result<()> {
        self.deref_mut().edit_content(rt)
    }

}

pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> {
    edit_in_tmpfile_with_command(rt.editor(), s)
}

pub fn edit_in_tmpfile_with_command(cmd: Command, s: &mut String) -> Result<()> {
    use tempfile::NamedTempFile;
    use std::io::Seek;
    use std::io::Read;
    use std::io::SeekFrom;
    use std::io::Write;

    let file      = try!(NamedTempFile::new().map_err_into(EditErrorKind::IOError));
    let file_path = file.path();
    let mut file  = try!(file.reopen().map_err_into(EditErrorKind::IOError));

    try!(file.write_all(&s.clone().into_bytes()[..]).map_err_into(EditErrorKind::IOError));
    try!(file.sync_data().map_err_into(EditErrorKind::IOError));

    if let Some(mut editor) = rt.editor() {
        let exit_status = editor.arg(file_path).status();

        match exit_status.map(|s| s.success()).map_err(Box::new) {
            Ok(true)  => {
                file.sync_data()
                    .and_then(|_| file.seek(SeekFrom::Start(0)))
                    .and_then(|_| {
                        let mut new_s = String::new();
                        let res = file.read_to_string(&mut new_s);
                        *s = new_s;
                        res
                    })
                    .map(|_| ())
                    .map_err_into(EditErrorKind::IOError)
            },
            Ok(false) => Err(EditErrorKind::ProcessExitFailure.into()),
            Err(e)    => Err(EditErrorKind::IOError.into_error_with_cause(e)),
        }
    } else {
        Err(EditErrorKind::InstantiateError.into())
    }
}

<|endoftext|>


<commit_before>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#![allow(dead_code)]

use std::collections::HashSet;
use std::hash::Hash;
use std::rc::Rc;

/// An `InternSet` allows to "intern" some potentially large values, maintaining a single value
/// instance owned by the `InternSet` and leaving consumers with lightweight ref-counted handles to
/// the large owned value.  This can avoid expensive clone() operations.
///
/// In Mentat, such large values might be strings or arbitrary [a v] pairs.
///
/// See https://en.wikipedia.org/wiki/String_interning for discussion.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct InternSet<T> where T: Eq + Hash {
    pub inner: HashSet<Rc<T>>,
}

impl<T> InternSet<T> where T: Eq + Hash {
    pub fn new() -> InternSet<T> {
        InternSet {
            inner: HashSet::new(),
        }
    }

    /// Intern a value, providing a ref-counted handle to the interned value.
    pub fn intern(&mut self, value: T) -> Rc<T> {
        let key = Rc::new(value);
        if self.inner.insert(key.clone()) {
            key
        } else {
            self.inner.get(&key).unwrap().clone()
        }
    }
}
<commit_msg>Make InternSet::intern accept Into<Rc<T>>. Add a test. r=nalexander<commit_after>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#![allow(dead_code)]

use std::collections::HashSet;
use std::hash::Hash;
use std::rc::Rc;

/// An `InternSet` allows to "intern" some potentially large values, maintaining a single value
/// instance owned by the `InternSet` and leaving consumers with lightweight ref-counted handles to
/// the large owned value.  This can avoid expensive clone() operations.
///
/// In Mentat, such large values might be strings or arbitrary [a v] pairs.
///
/// See https://en.wikipedia.org/wiki/String_interning for discussion.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct InternSet<T> where T: Eq + Hash {
    pub inner: HashSet<Rc<T>>,
}

impl<T> InternSet<T> where T: Eq + Hash {
    pub fn new() -> InternSet<T> {
        InternSet {
            inner: HashSet::new(),
        }
    }

    /// Intern a value, providing a ref-counted handle to the interned value.
    ///
    /// ```
    /// use std::rc::Rc;
    /// use mentat_core::intern_set::InternSet;
    ///
    /// let mut s = InternSet::new();
    ///
    /// let one = "foo".to_string();
    /// let two = Rc::new("foo".to_string());
    ///
    /// let out_one = s.intern(one);
    /// assert_eq!(out_one, two);
    /// // assert!(!&out_one.ptr_eq(&two));      // Nightly-only.
    ///
    /// let out_two = s.intern(two);
    /// assert_eq!(out_one, out_two);
    /// assert_eq!(1, s.inner.len());
    /// // assert!(&out_one.ptr_eq(&out_two));   // Nightly-only.
    /// ```
    pub fn intern<R: Into<Rc<T>>>(&mut self, value: R) -> Rc<T> {
        let key: Rc<T> = value.into();
        if self.inner.insert(key.clone()) {
            key
        } else {
            self.inner.get(&key).unwrap().clone()
        }
    }
}<|endoftext|>