<commit_before>//! Locks that have the same behaviour as a mutex.
//!
//! The [`Mutex`] in the root of the crate, can be configured using the `ticket_mutex` feature.
//! If it's enabled, [`TicketMutex`] and [`TicketMutexGuard`] will be re-exported as [`Mutex`]
//! and [`MutexGuard`], otherwise the [`SpinMutex`] and guard will be re-exported.
//!
//! `ticket_mutex` is disabled by default.
//!
//! [`Mutex`]: ../struct.Mutex.html
//! [`MutexGuard`]: ../struct.MutexGuard.html
//! [`TicketMutex`]: ./struct.TicketMutex.html
//! [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html
//! [`SpinMutex`]: ./struct.SpinMutex.html
//! [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html

#[cfg(feature = "spin_mutex")]
#[cfg_attr(docsrs, doc(cfg(feature = "spin_mutex")))]
pub mod spin;

#[cfg(feature = "ticket_mutex")]
#[cfg_attr(docsrs, doc(cfg(feature = "ticket_mutex")))]
pub mod ticket;

use core::{
    fmt,
    ops::{Deref, DerefMut},
};
use crate::{RelaxStrategy, Spin};

#[cfg(all(not(feature = "spin_mutex"), not(feature = "use_ticket_mutex")))]
compile_error!("The `mutex` feature flag was used (perhaps through another feature?) without either `spin_mutex` or `use_ticket_mutex`. One of these is required.");

#[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))]
type InnerMutex<T, R> = self::spin::SpinMutex<T, R>;
#[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))]
type InnerMutexGuard<'a, T> = self::spin::SpinMutexGuard<'a, T>;

#[cfg(feature = "use_ticket_mutex")]
type InnerMutex<T, R> = self::ticket::TicketMutex<T, R>;
#[cfg(feature = "use_ticket_mutex")]
type InnerMutexGuard<'a, T> = self::ticket::TicketMutexGuard<'a, T>;

/// A spin-based lock providing mutually exclusive access to data.
///
/// The implementation uses either a ticket mutex or a regular spin mutex depending on whether the `spin_mutex` or
/// `ticket_mutex` feature flag is enabled.
///
/// # Example
///
/// ```
/// use spin;
///
/// let lock = spin::Mutex::new(0);
///
/// // Modify the data
/// *lock.lock() = 2;
///
/// // Read the data
/// let answer = *lock.lock();
/// assert_eq!(answer, 2);
/// ```
///
/// # Thread safety example
///
/// ```
/// use spin;
/// use std::sync::{Arc, Barrier};
///
/// let thread_count = 1000;
/// let spin_mutex = Arc::new(spin::Mutex::new(0));
///
/// // We use a barrier to ensure the readout happens after all writing
/// let barrier = Arc::new(Barrier::new(thread_count + 1));
///
/// for _ in (0..thread_count) {
///     let my_barrier = barrier.clone();
///     let my_lock = spin_mutex.clone();
///     std::thread::spawn(move || {
///         let mut guard = my_lock.lock();
///         *guard += 1;
///
///         // Release the lock to prevent a deadlock
///         drop(guard);
///         my_barrier.wait();
///     });
/// }
///
/// barrier.wait();
///
/// let answer = { *spin_mutex.lock() };
/// assert_eq!(answer, thread_count);
/// ```
pub struct Mutex<T: ?Sized, R = Spin> {
    inner: InnerMutex<T, R>,
}

unsafe impl<T: ?Sized + Send, R> Sync for Mutex<T, R> {}
unsafe impl<T: ?Sized + Send, R> Send for Mutex<T, R> {}

/// A generic guard that will protect some data access and
/// uses either a ticket lock or a normal spin mutex.
///
/// For more info see [`TicketMutexGuard`] or [`SpinMutexGuard`].
///
/// [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html
/// [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html
pub struct MutexGuard<'a, T: 'a + ?Sized> {
    inner: InnerMutexGuard<'a, T>,
}

impl<T, R> Mutex<T, R> {
    /// Creates a new [`Mutex`] wrapping the supplied data.
    ///
    /// # Example
    ///
    /// ```
    /// use spin::Mutex;
    ///
    /// static MUTEX: Mutex<()> = Mutex::new(());
    ///
    /// fn demo() {
    ///     let lock = MUTEX.lock();
    ///     // do something with lock
    ///     drop(lock);
    /// }
    /// ```
    #[inline(always)]
    pub const fn new(value: T) -> Self {
        Self { inner: InnerMutex::new(value) }
    }

    /// Consumes this [`Mutex`] and unwraps the underlying data.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::Mutex::new(42);
    /// assert_eq!(42, lock.into_inner());
    /// ```
    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.inner.into_inner()
    }
}

impl<T: ?Sized, R: RelaxStrategy> Mutex<T, R> {
    /// Locks the [`Mutex`] and returns a guard that permits access to the inner data.
    ///
    /// The returned value may be dereferenced for data access
    /// and the lock will be dropped when the guard falls out of scope.
    ///
    /// ```
    /// let lock = spin::Mutex::new(0);
    /// {
    ///     let mut data = lock.lock();
    ///     // The lock is now locked and the data can be accessed
    ///     *data += 1;
    ///     // The lock is implicitly dropped at the end of the scope
    /// }
    /// ```
    #[inline(always)]
    pub fn lock(&self) -> MutexGuard<T> {
        MutexGuard {
            inner: self.inner.lock(),
        }
    }
}

impl<T: ?Sized, R> Mutex<T, R> {
    /// Returns `true` if the lock is currently held.
    ///
    /// # Safety
    ///
    /// This function provides no synchronization guarantees and so its result should be considered 'out of date'
    /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic.
    #[inline(always)]
    pub fn is_locked(&self) -> bool {
        self.inner.is_locked()
    }

    /// Force unlock this [`Mutex`].
    ///
    /// # Safety
    ///
    /// This is *extremely* unsafe if the lock is not held by the current
    /// thread. However, this can be useful in some instances for exposing the
    /// lock to FFI that doesn't know how to deal with RAII.
    #[inline(always)]
    pub unsafe fn force_unlock(&self) {
        self.inner.force_unlock()
    }

    /// Try to lock this [`Mutex`], returning a lock guard if successful.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::Mutex::new(42);
    ///
    /// let maybe_guard = lock.try_lock();
    /// assert!(maybe_guard.is_some());
    ///
    /// // `maybe_guard` is still held, so the second call fails
    /// let maybe_guard2 = lock.try_lock();
    /// assert!(maybe_guard2.is_none());
    /// ```
    #[inline(always)]
    pub fn try_lock(&self) -> Option<MutexGuard<T>> {
        self.inner
            .try_lock()
            .map(|guard| MutexGuard { inner: guard })
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the [`Mutex`] mutably, and a mutable reference is guaranteed to be exclusive in Rust,
    /// no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As such,
    /// this is a 'zero-cost' operation.
    ///
    /// # Example
    ///
    /// ```
    /// let mut lock = spin::Mutex::new(0);
    /// *lock.get_mut() = 10;
    /// assert_eq!(*lock.lock(), 10);
    /// ```
    #[inline(always)]
    pub fn get_mut(&mut self) -> &mut T {
        self.inner.get_mut()
    }
}

impl<T: ?Sized + fmt::Debug, R> fmt::Debug for Mutex<T, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.inner, f)
    }
}

impl<T: ?Sized + Default, R> Default for Mutex<T, R> {
    fn default() -> Self {
        Self::new(Default::default())
    }
}

impl<T, R> From<T> for Mutex<T, R> {
    fn from(data: T) -> Self {
        Self::new(data)
    }
}

impl<'a, T: ?Sized> MutexGuard<'a, T> {
    /// Leak the lock guard, yielding a mutable reference to the underlying data.
    ///
    /// Note that this function will permanently lock the original [`Mutex`].
    ///
    /// ```
    /// let mylock = spin::Mutex::new(0);
    ///
    /// let data: &mut i32 = spin::MutexGuard::leak(mylock.lock());
    ///
    /// *data = 1;
    /// assert_eq!(*data, 1);
    /// ```
    #[inline(always)]
    pub fn leak(this: Self) -> &'a mut T {
        InnerMutexGuard::leak(this.inner)
    }
}

impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&**self, f)
    }
}

impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        &*self.inner
    }
}

impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut *self.inner
    }
}

#[cfg(feature = "lock_api")]
unsafe impl<R: RelaxStrategy> lock_api_crate::RawMutex for Mutex<(), R> {
    type GuardMarker = lock_api_crate::GuardSend;

    const INIT: Self = Self::new(());

    fn lock(&self) {
        // Prevent guard destructor running
        core::mem::forget(Self::lock(self));
    }

    fn try_lock(&self) -> bool {
        // Prevent guard destructor running
        Self::try_lock(self).map(core::mem::forget).is_some()
    }

    unsafe fn unlock(&self) {
        self.force_unlock();
    }

    fn is_locked(&self) -> bool {
        self.inner.is_locked()
    }
}
<commit_msg>Fixed failing tests<commit_after>//! Locks that have the same behaviour as a mutex.
//!
//! The [`Mutex`] in the root of the crate, can be configured using the `ticket_mutex` feature.
//! If it's enabled, [`TicketMutex`] and [`TicketMutexGuard`] will be re-exported as [`Mutex`]
//! and [`MutexGuard`], otherwise the [`SpinMutex`] and guard will be re-exported.
//!
//! `ticket_mutex` is disabled by default.
//!
//! [`Mutex`]: ../struct.Mutex.html
//! [`MutexGuard`]: ../struct.MutexGuard.html
//! [`TicketMutex`]: ./struct.TicketMutex.html
//! [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html
//! [`SpinMutex`]: ./struct.SpinMutex.html
//! [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html

#[cfg(feature = "spin_mutex")]
#[cfg_attr(docsrs, doc(cfg(feature = "spin_mutex")))]
pub mod spin;
#[cfg(feature = "spin_mutex")]
#[cfg_attr(docsrs, doc(cfg(feature = "spin_mutex")))]
pub use self::spin::{SpinMutex, SpinMutexGuard};

#[cfg(feature = "ticket_mutex")]
#[cfg_attr(docsrs, doc(cfg(feature = "ticket_mutex")))]
pub mod ticket;
#[cfg(feature = "ticket_mutex")]
#[cfg_attr(docsrs, doc(cfg(feature = "ticket_mutex")))]
pub use self::ticket::{TicketMutex, TicketMutexGuard};

use core::{
    fmt,
    ops::{Deref, DerefMut},
};
use crate::{RelaxStrategy, Spin};

#[cfg(all(not(feature = "spin_mutex"), not(feature = "use_ticket_mutex")))]
compile_error!("The `mutex` feature flag was used (perhaps through another feature?) without either `spin_mutex` or `use_ticket_mutex`. One of these is required.");

#[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))]
type InnerMutex<T, R> = self::spin::SpinMutex<T, R>;
#[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))]
type InnerMutexGuard<'a, T> = self::spin::SpinMutexGuard<'a, T>;

#[cfg(feature = "use_ticket_mutex")]
type InnerMutex<T, R> = self::ticket::TicketMutex<T, R>;
#[cfg(feature = "use_ticket_mutex")]
type InnerMutexGuard<'a, T> = self::ticket::TicketMutexGuard<'a, T>;

/// A spin-based lock providing mutually exclusive access to data.
///
/// The implementation uses either a ticket mutex or a regular spin mutex depending on whether the `spin_mutex` or
/// `ticket_mutex` feature flag is enabled.
///
/// # Example
///
/// ```
/// use spin;
///
/// let lock = spin::Mutex::new(0);
///
/// // Modify the data
/// *lock.lock() = 2;
///
/// // Read the data
/// let answer = *lock.lock();
/// assert_eq!(answer, 2);
/// ```
///
/// # Thread safety example
///
/// ```
/// use spin;
/// use std::sync::{Arc, Barrier};
///
/// let thread_count = 1000;
/// let spin_mutex = Arc::new(spin::Mutex::new(0));
///
/// // We use a barrier to ensure the readout happens after all writing
/// let barrier = Arc::new(Barrier::new(thread_count + 1));
///
/// for _ in (0..thread_count) {
///     let my_barrier = barrier.clone();
///     let my_lock = spin_mutex.clone();
///     std::thread::spawn(move || {
///         let mut guard = my_lock.lock();
///         *guard += 1;
///
///         // Release the lock to prevent a deadlock
///         drop(guard);
///         my_barrier.wait();
///     });
/// }
///
/// barrier.wait();
///
/// let answer = { *spin_mutex.lock() };
/// assert_eq!(answer, thread_count);
/// ```
pub struct Mutex<T: ?Sized, R = Spin> {
    inner: InnerMutex<T, R>,
}

unsafe impl<T: ?Sized + Send, R> Sync for Mutex<T, R> {}
unsafe impl<T: ?Sized + Send, R> Send for Mutex<T, R> {}

/// A generic guard that will protect some data access and
/// uses either a ticket lock or a normal spin mutex.
///
/// For more info see [`TicketMutexGuard`] or [`SpinMutexGuard`].
///
/// [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html
/// [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html
pub struct MutexGuard<'a, T: 'a + ?Sized> {
    inner: InnerMutexGuard<'a, T>,
}

impl<T, R> Mutex<T, R> {
    /// Creates a new [`Mutex`] wrapping the supplied data.
    ///
    /// # Example
    ///
    /// ```
    /// use spin::Mutex;
    ///
    /// static MUTEX: Mutex<()> = Mutex::new(());
    ///
    /// fn demo() {
    ///     let lock = MUTEX.lock();
    ///     // do something with lock
    ///     drop(lock);
    /// }
    /// ```
    #[inline(always)]
    pub const fn new(value: T) -> Self {
        Self { inner: InnerMutex::new(value) }
    }

    /// Consumes this [`Mutex`] and unwraps the underlying data.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::Mutex::new(42);
    /// assert_eq!(42, lock.into_inner());
    /// ```
    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.inner.into_inner()
    }
}

impl<T: ?Sized, R: RelaxStrategy> Mutex<T, R> {
    /// Locks the [`Mutex`] and returns a guard that permits access to the inner data.
    ///
    /// The returned value may be dereferenced for data access
    /// and the lock will be dropped when the guard falls out of scope.
    ///
    /// ```
    /// let lock = spin::Mutex::new(0);
    /// {
    ///     let mut data = lock.lock();
    ///     // The lock is now locked and the data can be accessed
    ///     *data += 1;
    ///     // The lock is implicitly dropped at the end of the scope
    /// }
    /// ```
    #[inline(always)]
    pub fn lock(&self) -> MutexGuard<T> {
        MutexGuard {
            inner: self.inner.lock(),
        }
    }
}

impl<T: ?Sized, R> Mutex<T, R> {
    /// Returns `true` if the lock is currently held.
    ///
    /// # Safety
    ///
    /// This function provides no synchronization guarantees and so its result should be considered 'out of date'
    /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic.
    #[inline(always)]
    pub fn is_locked(&self) -> bool {
        self.inner.is_locked()
    }

    /// Force unlock this [`Mutex`].
    ///
    /// # Safety
    ///
    /// This is *extremely* unsafe if the lock is not held by the current
    /// thread. However, this can be useful in some instances for exposing the
    /// lock to FFI that doesn't know how to deal with RAII.
    #[inline(always)]
    pub unsafe fn force_unlock(&self) {
        self.inner.force_unlock()
    }

    /// Try to lock this [`Mutex`], returning a lock guard if successful.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::Mutex::new(42);
    ///
    /// let maybe_guard = lock.try_lock();
    /// assert!(maybe_guard.is_some());
    ///
    /// // `maybe_guard` is still held, so the second call fails
    /// let maybe_guard2 = lock.try_lock();
    /// assert!(maybe_guard2.is_none());
    /// ```
    #[inline(always)]
    pub fn try_lock(&self) -> Option<MutexGuard<T>> {
        self.inner
            .try_lock()
            .map(|guard| MutexGuard { inner: guard })
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the [`Mutex`] mutably, and a mutable reference is guaranteed to be exclusive in Rust,
    /// no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As such,
    /// this is a 'zero-cost' operation.
    ///
    /// # Example
    ///
    /// ```
    /// let mut lock = spin::Mutex::new(0);
    /// *lock.get_mut() = 10;
    /// assert_eq!(*lock.lock(), 10);
    /// ```
    #[inline(always)]
    pub fn get_mut(&mut self) -> &mut T {
        self.inner.get_mut()
    }
}

impl<T: ?Sized + fmt::Debug, R> fmt::Debug for Mutex<T, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.inner, f)
    }
}

impl<T: ?Sized + Default, R> Default for Mutex<T, R> {
    fn default() -> Self {
        Self::new(Default::default())
    }
}

impl<T, R> From<T> for Mutex<T, R> {
    fn from(data: T) -> Self {
        Self::new(data)
    }
}

impl<'a, T: ?Sized> MutexGuard<'a, T> {
    /// Leak the lock guard, yielding a mutable reference to the underlying data.
    ///
    /// Note that this function will permanently lock the original [`Mutex`].
    ///
    /// ```
    /// let mylock = spin::Mutex::new(0);
    ///
    /// let data: &mut i32 = spin::MutexGuard::leak(mylock.lock());
    ///
    /// *data = 1;
    /// assert_eq!(*data, 1);
    /// ```
    #[inline(always)]
    pub fn leak(this: Self) -> &'a mut T {
        InnerMutexGuard::leak(this.inner)
    }
}

impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&**self, f)
    }
}

impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        &*self.inner
    }
}

impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut *self.inner
    }
}

#[cfg(feature = "lock_api")]
unsafe impl<R: RelaxStrategy> lock_api_crate::RawMutex for Mutex<(), R> {
    type GuardMarker = lock_api_crate::GuardSend;

    const INIT: Self = Self::new(());

    fn lock(&self) {
        // Prevent guard destructor running
        core::mem::forget(Self::lock(self));
    }

    fn try_lock(&self) -> bool {
        // Prevent guard destructor running
        Self::try_lock(self).map(core::mem::forget).is_some()
    }

    unsafe fn unlock(&self) {
        self.force_unlock();
    }

    fn is_locked(&self) -> bool {
        self.inner.is_locked()
    }
}
<|endoftext|>


<commit_before>use math::Vec3;
use num::FromPrimitive;
use std::collections::HashMap;
use std::default::Default;

/// The maximum number of entities per packet, excluding nails.
pub const MAX_PACKET_ENTITIES: usize = 64;

/// The maximum allowed size of a UDP packet.
pub const PACKET_MAX: usize = 8192;
pub const VERSION: u32 = 28;

pub const PORT_MASTER: u16 = 27000;
pub const PORT_CLIENT: u16 = 27001;
pub const PORT_SERVER: u16 = 27500;

#[derive(Debug, FromPrimitive)]
pub enum SvCmd {
    Bad = 0,
    Nop = 1,
    Disconnect = 2,
    UpdateStat = 3,
    // Version = 4,
    SetView = 5,
    Sound = 6,
    // Time = 7,
    Print = 8,
    StuffText = 9,
    SetAngle = 10,
    ServerData = 11,
    LightStyle = 12,
    // UpdateName = 13,
    UpdateFrags = 14,
    // ClientData = 15,
    StopSound = 16,
    // UpdateColors = 17,
    // Particle = 18,
    Damage = 19,
    SpawnStatic = 20,
    // SpawnBinary = 21,
    SpawnBaseline = 22,
    TempEntity = 23,
    SetPause = 24,
    // SigNonNum = 25,
    CenterPrint = 26,
    KilledMonster = 27,
    FoundSecret = 28,
    SpawnStaticSound = 29,
    Intermission = 30,
    Finale = 31,
    CdTrack = 32,
    SellScreen = 33,

    /// set client punchangle to 2
    SmallKick = 34,

    /// set client punchangle to 4
    BigKick = 35,

    UpdatePing = 36,
    UpdateEnterTime = 37,
    UpdateStatLong = 38,
    MuzzleFlash = 39,
    UpdateUserInfo = 40,
    Download = 41,
    PlayerInfo = 42,
    Nails = 43,
    ChokeCount = 44,
    ModelList = 45,
    SoundList = 46,
    PacketEntities = 47,
    DeltaPacketEntities = 48,
    MaxSpeed = 49,
    EntGravity = 50,
    SetInfo = 51,
    ServerInfo = 52,
    UpdatePl = 53,
}

#[derive(Debug, FromPrimitive)]
pub enum ClCmd {
    Bad = 0,
    Nop = 1,
    // DoubleMove = 2,
    Move = 3,
    StringCmd = 4,
    Delta = 5,
    TMove = 6,
    Upload = 7,
}

pub struct UserInfo(HashMap<String, String>);

impl UserInfo {
    pub fn new() -> UserInfo {
        UserInfo(HashMap::new())
    }

    pub fn serialize(&self) -> String {
        let mut result = String::new();

        for (k, v) in self.0.iter() {
            result.push('\\');
            result.push_str(&k);
            result.push('\\');
            result.push_str(&v);
        }

        result
    }
}

impl Default for UserInfo {
    fn default() -> UserInfo {
        let mut map = HashMap::new();
        map.insert("name".to_owned(), "unnamed".to_owned());
        map.insert("topcolor".to_owned(), "0".to_owned());
        map.insert("bottomcolor".to_owned(), "0".to_owned());
        map.insert("rate".to_owned(), "2500".to_owned());
        map.insert("msg".to_owned(), "1".to_owned());
        UserInfo(map)
    }
}

// TODO: this is a straight translation of the original struct,
// make it nicer. Also see if we can avoid making it Copy/Clone
#[derive(Copy, Clone)]
#[repr(C)]
pub struct UserCmd {
    msec: u8,
    angles: Vec3,
    fwd: i16,
    side: i16,
    back: i16,
    buttons: u8,
    impulse: u8,
}

impl Default for UserCmd {
    fn default() -> UserCmd {
        UserCmd {
            msec: 0,
            angles: Vec3::new(0.0, 0.0, 0.0),
            fwd: 0,
            side: 0,
            back: 0,
            buttons: 0,
            impulse: 0,
        }
    }
}

pub struct EntityState {
    edict_id: usize,
    flags: u32,
    origin: Vec3,
    angles: Vec3,
    model_id: usize,
    frame: usize,
    colormap: u32,
    skin_count: usize,
    effects: u32,
}

pub type PacketEntities = Box<[EntityState]>;
<commit_msg>Add FTE extension defs and parsing<commit_after>use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use math::Vec3;
use num::FromPrimitive;
use std::collections::HashMap;
use std::default::Default;
use std::io::{Cursor, Read, Write};
use std::str::FromStr;

/// The maximum number of entities per packet, excluding nails.
pub const MAX_PACKET_ENTITIES: usize = 64;

/// The maximum allowed size of a UDP packet.
pub const PACKET_MAX: usize = 8192;
pub const VERSION: u32 = 28;

pub const PORT_MASTER: u16 = 27000;
pub const PORT_CLIENT: u16 = 27001;
pub const PORT_SERVER: u16 = 27500;

#[derive(Debug, FromPrimitive)]
pub enum SvCmd {
    Bad = 0,
    Nop = 1,
    Disconnect = 2,
    UpdateStat = 3,
    // Version = 4,
    SetView = 5,
    Sound = 6,
    // Time = 7,
    Print = 8,
    StuffText = 9,
    SetAngle = 10,
    ServerData = 11,
    LightStyle = 12,
    // UpdateName = 13,
    UpdateFrags = 14,
    // ClientData = 15,
    StopSound = 16,
    // UpdateColors = 17,
    // Particle = 18,
    Damage = 19,
    SpawnStatic = 20,
    // SpawnBinary = 21,
    SpawnBaseline = 22,
    TempEntity = 23,
    SetPause = 24,
    // SigNonNum = 25,
    CenterPrint = 26,
    KilledMonster = 27,
    FoundSecret = 28,
    SpawnStaticSound = 29,
    Intermission = 30,
    Finale = 31,
    CdTrack = 32,
    SellScreen = 33,

    /// set client punchangle to 2
    SmallKick = 34,

    /// set client punchangle to 4
    BigKick = 35,

    UpdatePing = 36,
    UpdateEnterTime = 37,
    UpdateStatLong = 38,
    MuzzleFlash = 39,
    UpdateUserInfo = 40,
    Download = 41,
    PlayerInfo = 42,
    Nails = 43,
    ChokeCount = 44,
    ModelList = 45,
    SoundList = 46,
    PacketEntities = 47,
    DeltaPacketEntities = 48,
    MaxSpeed = 49,
    EntGravity = 50,
    SetInfo = 51,
    ServerInfo = 52,
    UpdatePl = 53,
}

#[derive(Debug, FromPrimitive)]
pub enum ClCmd {
    Bad = 0,
    Nop = 1,
    // DoubleMove = 2,
    Move = 3,
    StringCmd = 4,
    Delta = 5,
    TMove = 6,
    Upload = 7,
}

const PROTOCOL_FTE: u32 = ('F' as u32) << 0 | ('T' as u32) << 8 | ('E' as u32) << 16 |
                          ('X' as u32) << 24;

// FTE extensions, https://github.com/mdeguzis/ftequake/blob/master/engine/common/protocol.h#L21
bitflags! {
    pub flags FteExtensions: u32 {
        const FTE_SETVIEW           = 0x00000001,
        const FTE_SCALE             = 0x00000002,
        const FTE_LIGHTSTYLECOL     = 0x00000004,
        const FTE_TRANS             = 0x00000008,
        const FTE_VIEW2             = 0x00000010,
        // const FTE_BULLETENS      = 0x00000020,
        const FTE_ACCURATETIMINGS   = 0x00000040,
        const FTE_SOUNDDBL          = 0x00000080,
        const FTE_FATNESS           = 0x00000100,
        const FTE_HLBSP             = 0x00000200,
        const FTE_TE_BULLET         = 0x00000400,
        const FTE_HULLSIZE          = 0x00000800,
        const FTE_MODELDBL          = 0x00001000,
        const FTE_ENTITYDBL         = 0x00002000,
        const FTE_ENTITYDBL2        = 0x00004000,
        const FTE_FLOATCOORDS       = 0x00008000,
        // const FTE_VWEAP          = 0x00010000,
        const FTE_Q2BSP             = 0x00020000,
        const FTE_Q3BSP             = 0x00040000,
        const FTE_COLOURMOD         = 0x00080000,
        const FTE_SPLITSCREEN       = 0x00100000,
        const FTE_HEXEN2            = 0x00200000,
        const FTE_SPAWNSTATIC2      = 0x00400000,
        const FTE_CUSTOMTEMPEFFECTS = 0x00800000,
        const FTE_256PACKETENTITIES = 0x01000000,
        // const FTE_NEVERUSED      = 0x02000000,
        const FTE_SHOWPIC           = 0x04000000,
        const FTE_SETATTACHMENT     = 0x08000000,
        // const FTE_NEVERUSED      = 0x10000000,
        const FTE_CHUNKEDDOWNLOADS  = 0x20000000,
        const FTE_CSQC              = 0x40000000,
        const FTE_DPFLAGS           = 0x80000000,
        const FTE_BIGUSERINFOS      = 0xffffffff,
    }
}

const PROTOCOL_FTE2: u32 = ('F' as u32) << 0 | ('T' as u32) << 8 | ('E' as u32) << 16 |
                           ('2' as u32) << 24;

// FTE2 extensions, https://github.com/mdeguzis/ftequake/blob/master/engine/common/protocol.h#L73
bitflags! {
    pub flags Fte2Extensions: u32 {
        const FTE2_PRYDONCURSOR      = 0x00000001,
        const FTE2_VOICECHAT         = 0x00000002,
        const FTE2_SETANGLEDELTA     = 0x00000004,
        const FTE2_REPLACEMENTDELTAS = 0x00000008,
        const FTE2_MAXPLAYERS        = 0x00000010,
        const FTE2_PREDINFO          = 0x00000020,
        const FTE2_NEWSIZEENCODING   = 0x00000040,
    }
}

pub struct Challenge {
    pub challenge: i32,
    pub fte_extensions: Option<FteExtensions>,
    pub fte2_extensions: Option<Fte2Extensions>,
}

impl Challenge {
    pub fn serialize(&self) -> Vec<u8> {
        let mut result = Cursor::new(Vec::new());
        result.write(&self.challenge.to_string().into_bytes()).unwrap();

        if let Some(fte) = self.fte_extensions {
            result.write_u32::<LittleEndian>(fte.bits()).unwrap();
        }

        if let Some(fte2) = self.fte2_extensions {
            result.write_u32::<LittleEndian>(fte2.bits()).unwrap();
        }

        result.into_inner()
    }

    pub fn deserialize<A>(data: A) -> Challenge
        where A: AsRef<[u8]>
    {
        let mut result = Challenge {
            challenge: 0,
            fte_extensions: None,
            fte2_extensions: None,
        };

        let data = data.as_ref();
        let mut i: usize = 0;

        if data[i] == '-' as u8 {
            i += 1;
        }

        while i < data.len() && data[i] >= '0' as u8 && data[i] <= '9' as u8 {
            i += 1;
        }

        result.challenge = i32::from_str(::std::str::from_utf8(&data[..i]).unwrap()).unwrap();

        assert!(data[i..].len() <= 16);
        assert!(data[i..].len() % 8 == 0);
        let mut curs = Cursor::new(&data[i..]);

        while let Ok(n) = curs.read_u32::<LittleEndian>() {
            match n {
                PROTOCOL_FTE => {
                    result.fte_extensions =
                        Some(FteExtensions::from_bits(curs.read_u32::<LittleEndian>().unwrap())
                                 .unwrap())
                }
                PROTOCOL_FTE2 => {
                    result.fte2_extensions =
                        Some(Fte2Extensions::from_bits(curs.read_u32::<LittleEndian>().unwrap())
                                 .unwrap())
                }
                _ => panic!("Unrecognized sequence in challenge packet"),
            }
        }

        result
    }
}

pub struct UserInfo(HashMap<String, String>);

impl UserInfo {
    pub fn new() -> UserInfo {
        UserInfo(HashMap::new())
    }

    pub fn serialize(&self) -> String {
        let mut result = String::new();

        for (k, v) in self.0.iter() {
            result.push('\\');
            result.push_str(&k);
            result.push('\\');
            result.push_str(&v);
        }

        result
    }
}

impl Default for UserInfo {
    fn default() -> UserInfo {
        let mut map = HashMap::new();
        map.insert("name".to_owned(), "unnamed".to_owned());
        map.insert("topcolor".to_owned(), "0".to_owned());
        map.insert("bottomcolor".to_owned(), "0".to_owned());
        map.insert("rate".to_owned(), "2500".to_owned());
        map.insert("msg".to_owned(), "1".to_owned());
        UserInfo(map)
    }
}

// TODO: this is a straight translation of the original struct,
// make it nicer. Also see if we can avoid making it Copy/Clone
#[derive(Copy, Clone)]
#[repr(C)]
pub struct UserCmd {
    msec: u8,
    angles: Vec3,
    fwd: i16,
    side: i16,
    back: i16,
    buttons: u8,
    impulse: u8,
}

impl Default for UserCmd {
    fn default() -> UserCmd {
        UserCmd {
            msec: 0,
            angles: Vec3::new(0.0, 0.0, 0.0),
            fwd: 0,
            side: 0,
            back: 0,
            buttons: 0,
            impulse: 0,
        }
    }
}

pub struct EntityState {
    edict_id: usize,
    flags: u32,
    origin: Vec3,
    angles: Vec3,
    model_id: usize,
    frame: usize,
    colormap: u32,
    skin_count: usize,
    effects: u32,
}

pub type PacketEntities = Box<[EntityState]>;
<|endoftext|>


<commit_before>// Copyright 2015 Nicholas Bishop
//
// 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.

/// Inclusive range from min to max
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct InclusiveRange<T: Copy + PartialOrd> {
    pub min: T,
    pub max: T
}

pub const RANGE_0_1_F32: InclusiveRange<f32> = InclusiveRange { min: 0.0, max: 0.0 };

impl<T: Copy + PartialOrd> InclusiveRange<T> {
    /// Create an InclusiveRange range from min to max
    pub fn new(min: T, max: T) -> InclusiveRange<T> {
        assert!(min <= max);
        InclusiveRange { min: min, max: max }
    }
}

/// Create range covering the overlap between two ranges, or None if
/// there is no overlap.
pub fn range_clamp<T: Copy + PartialOrd>(a: &InclusiveRange<T>,
                                         b: &InclusiveRange<T>)
                                         -> Option<InclusiveRange<T>> {
    let min = if a.min > b.min { a.min } else { b.min };
    let max = if a.max < b.max { a.max } else { b.max };

    if min <= max {
        Some(InclusiveRange::new(min, max))
    }
    else {
        None
    }
}

#[test]
fn test_range_clamp() {
    assert!(range_clamp(&InclusiveRange::new(0, 2),
                        &InclusiveRange::new(0, 2)) ==
            Some(InclusiveRange::new(0, 2)));

    assert!(range_clamp(&InclusiveRange::new(0, 1),
                        &InclusiveRange::new(2, 3)) ==
            None);

    assert!(range_clamp(&InclusiveRange::new(2, 3),
                        &InclusiveRange::new(0, 1)) ==
            None);

    assert!(range_clamp(&InclusiveRange::new(0, 2),
                        &InclusiveRange::new(1, 3)) ==
            Some(InclusiveRange::new(1, 2)));

    assert!(range_clamp(&InclusiveRange::new(1, 3),
                        &InclusiveRange::new(0, 2)) ==
            Some(InclusiveRange::new(1, 2)));

    assert!(range_clamp(&InclusiveRange::new(1.0, 3.0),
                        &InclusiveRange::new(0.0, 2.0)) ==
            Some(InclusiveRange::new(1.0, 2.0)));
}
<commit_msg>Range expand and tests<commit_after>// Copyright 2015 Nicholas Bishop
//
// 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.

/// Inclusive range from min to max
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct InclusiveRange<T: Copy + PartialOrd> {
    pub min: T,
    pub max: T
}

pub const RANGE_0_1_F32: InclusiveRange<f32> = InclusiveRange { min: 0.0, max: 0.0 };

fn pomax<T: PartialOrd>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

fn pomin<T: PartialOrd>(a: T, b: T) -> T {
    if a < b { a } else { b }
}

impl<T: Copy + PartialOrd> InclusiveRange<T> {
    /// Create an InclusiveRange range from min to max
    pub fn new(min: T, max: T) -> InclusiveRange<T> {
        assert!(min <= max);
        InclusiveRange { min: min, max: max }
    }

    pub fn expand(&mut self, other: &InclusiveRange<T>) {
        self.min = pomin(self.min, other.min);
        self.max = pomax(self.max, other.max);
    }
}

/// Create range covering the overlap between two ranges, or None if
/// there is no overlap.
pub fn range_clamp<T: Copy + PartialOrd>(a: &InclusiveRange<T>,
                                         b: &InclusiveRange<T>)
                                         -> Option<InclusiveRange<T>> {
    let min = pomax(a.min, b.min);
    let max = pomin(a.max, b.max);

    if min <= max {
        Some(InclusiveRange::new(min, max))
    }
    else {
        None
    }
}

#[test]
fn test_range_clamp() {
    assert!(range_clamp(&InclusiveRange::new(0, 2),
                        &InclusiveRange::new(0, 2)) ==
            Some(InclusiveRange::new(0, 2)));

    assert!(range_clamp(&InclusiveRange::new(0, 1),
                        &InclusiveRange::new(2, 3)) ==
            None);

    assert!(range_clamp(&InclusiveRange::new(2, 3),
                        &InclusiveRange::new(0, 1)) ==
            None);

    assert!(range_clamp(&InclusiveRange::new(0, 2),
                        &InclusiveRange::new(1, 3)) ==
            Some(InclusiveRange::new(1, 2)));

    assert!(range_clamp(&InclusiveRange::new(1, 3),
                        &InclusiveRange::new(0, 2)) ==
            Some(InclusiveRange::new(1, 2)));

    assert!(range_clamp(&InclusiveRange::new(1.0, 3.0),
                        &InclusiveRange::new(0.0, 2.0)) ==
            Some(InclusiveRange::new(1.0, 2.0)));
}

#[test]
fn test_range_expand() {
    let mut r = InclusiveRange::new(0, 1);
    r.expand(&InclusiveRange::new(-1, 2));
    assert!(r == InclusiveRange::new(-1, 2));
}
<|endoftext|>


<commit_before>use std::io::stdin;
use std::io::stdout;
use std::io::Write;
use std::str;
use std::time::Duration;

use zookeeper::{Watcher, WatchedEvent, ZooKeeper};

struct MyWatcher;

impl Watcher for MyWatcher {
    fn handle(&self, _e: &WatchedEvent) {
        // println!("{:?}", e)
    }
}

pub struct Shell {
    hosts: String,
    zk: Option<ZooKeeper>,
    session_timeout: u64,
}

// are we connected?
macro_rules! fetch_zk {
    ($e:expr) => (
        match $e {
            Some(ref __zk) => __zk,
            _ => {
                println!("Not connected.");
                return;
            }
        })
}

macro_rules! check_args {
    ($args:ident, $count:expr, $params:expr) => (
        if $args.len() != $count {
            println!("Wrong number of arguments, expected parameters: {}", $params);
            return;
        })
}

impl Shell {
    pub fn new(hosts: &str) -> Shell {
        Shell {
            hosts: hosts.to_string(),
            zk: None,
            session_timeout: 5
        }
    }

    pub fn run(&mut self) {
        if !self.hosts.is_empty() {
            println!("Connecting...");
            let zk = ZooKeeper::connect(
                &self.hosts,
                Duration::from_secs(self.session_timeout),
                MyWatcher).unwrap();
            self.zk = Some(zk);
        }

        loop {
            let mut line = String::new();

            print!("> ");
            let _ = stdout().flush();

            stdin()
                .read_line(&mut line)
                .ok()
                .expect("Failed to read line");

            let pieces: Vec<&str>  = line.trim().split_whitespace().collect();

            if pieces.len() == 0 {
                continue;
            }

            // dispatch the command
            let args = pieces[1..].to_vec();
            match pieces[0] {
                "get" => self.get(args),
                "set" => self.set(args),
                unknown => println!("Unknown command: {}", unknown)
            }
        }

    }

    fn get(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);

        let data = zk.get_data(args[0], false);
        if data.is_ok() {
            let (bytes, _) = data.unwrap();
            println!("{}", str::from_utf8(&bytes[..]).unwrap().to_string());
        }
    }

    fn set(&mut self, args: Vec<&str>) {
        check_args!(args, 2, "<path> <data>");
        let zk = fetch_zk!(self.zk);

        let path = args[0];
        let data = args[1].as_bytes().to_vec();
        let ret = zk.set_data(path, data, -1);
        match ret {
            Ok(_) => (),
            Err(e) => println!("set failed: {}", e)
        }
    }
}
<commit_msg>feature(shell): implement `ls`<commit_after>use std::io::stdin;
use std::io::stdout;
use std::io::Write;
use std::str;
use std::time::Duration;

use zookeeper::{Watcher, WatchedEvent, ZooKeeper};

struct MyWatcher;

impl Watcher for MyWatcher {
    fn handle(&self, _e: &WatchedEvent) {
        // println!("{:?}", e)
    }
}

pub struct Shell {
    hosts: String,
    zk: Option<ZooKeeper>,
    session_timeout: u64,
}

// are we connected?
macro_rules! fetch_zk {
    ($e:expr) => (
        match $e {
            Some(ref __zk) => __zk,
            _ => {
                println!("Not connected.");
                return;
            }
        })
}

macro_rules! check_args {
    ($args:ident, $count:expr, $params:expr) => (
        if $args.len() != $count {
            println!("Wrong number of arguments, expected parameters: {}", $params);
            return;
        })
}

impl Shell {
    pub fn new(hosts: &str) -> Shell {
        Shell {
            hosts: hosts.to_string(),
            zk: None,
            session_timeout: 5
        }
    }

    pub fn run(&mut self) {
        if !self.hosts.is_empty() {
            println!("Connecting...");
            let zk = ZooKeeper::connect(
                &self.hosts,
                Duration::from_secs(self.session_timeout),
                MyWatcher).unwrap();
            self.zk = Some(zk);
        }

        loop {
            let mut line = String::new();

            print!("> ");
            let _ = stdout().flush();

            stdin()
                .read_line(&mut line)
                .ok()
                .expect("Failed to read line");

            let pieces: Vec<&str>  = line.trim().split_whitespace().collect();

            if pieces.len() == 0 {
                continue;
            }

            // dispatch the command
            let args = pieces[1..].to_vec();
            match pieces[0] {
                "get" => self.get(args),
                "set" => self.set(args),
                "ls" => self.ls(args),
                unknown => println!("Unknown command: {}", unknown)
            }
        }

    }

    fn get(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);

        let data = zk.get_data(args[0], false);
        if data.is_ok() {
            let (bytes, _) = data.unwrap();
            println!("{}", str::from_utf8(&bytes[..]).unwrap().to_string());
        }
    }

    fn set(&mut self, args: Vec<&str>) {
        check_args!(args, 2, "<path> <data>");
        let zk = fetch_zk!(self.zk);

        let path = args[0];
        let data = args[1].as_bytes().to_vec();
        let ret = zk.set_data(path, data, -1);
        match ret {
            Ok(_) => (),
            Err(e) => println!("set failed: {}", e)
        }
    }

    fn ls(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_children(path, false);
        if ret.is_ok() {
            let children = ret.unwrap();
            println!("{}", children.join(" "));
        }
    }
}
<|endoftext|>


<commit_before>
use ndarray::*;
use super::layout::*;
use super::error::*;
use super::impl2::*;

pub use impl2::{Pivot, Transpose};

pub struct Factorized<S: Data> {
    pub a: ArrayBase<S, Ix2>,
    pub ipiv: Pivot,
}

impl<A, S> Factorized<S>
    where A: LapackScalar,
          S: Data<Elem = A>
{
    pub fn solve<Sb>(&self, t: Transpose, mut rhs: ArrayBase<Sb, Ix1>) -> Result<ArrayBase<Sb, Ix1>>
        where Sb: DataMut<Elem = A>
    {
        A::solve(self.a.layout()?,
                 t,
                 self.a.as_allocated()?,
                 &self.ipiv,
                 rhs.as_slice_mut().unwrap())?;
        Ok(rhs)
    }
}

impl<A, S> Factorized<S>
    where A: LapackScalar,
          S: DataMut<Elem = A>
{
    pub fn into_inverse(mut self) -> Result<ArrayBase<S, Ix2>> {
        A::inv(self.a.layout()?, self.a.as_allocated_mut()?, &self.ipiv)?;
        Ok(self.a)
    }
}

pub trait Factorize<S: Data> {
    fn factorize(self) -> Result<Factorized<S>>;
}

impl<A, S> Factorize<S> for ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>
{
    fn factorize(mut self) -> Result<Factorized<S>> {
        let ipiv = A::lu(self.layout()?, self.as_allocated_mut()?)?;
        Ok(Factorized {
            a: self,
            ipiv: ipiv,
        })
    }
}

impl<'a, A, S> Factorize<OwnedRepr<A>> for &'a ArrayBase<S, Ix2>
    where A: LapackScalar + Clone,
          S: Data<Elem = A>
{
    fn factorize(self) -> Result<Factorized<OwnedRepr<A>>> {
        let mut a = self.to_owned();
        let ipiv = A::lu(a.layout()?, a.as_allocated_mut()?)?;
        Ok(Factorized { a: a, ipiv: ipiv })
    }
}
<commit_msg>impl inv()<commit_after>
use ndarray::*;
use super::layout::*;
use super::error::*;
use super::impl2::*;

pub use impl2::{Pivot, Transpose};

pub struct Factorized<S: Data> {
    pub a: ArrayBase<S, Ix2>,
    pub ipiv: Pivot,
}

impl<A, S> Factorized<S>
    where A: LapackScalar,
          S: Data<Elem = A>
{
    pub fn solve<Sb>(&self, t: Transpose, mut rhs: ArrayBase<Sb, Ix1>) -> Result<ArrayBase<Sb, Ix1>>
        where Sb: DataMut<Elem = A>
    {
        A::solve(self.a.layout()?,
                 t,
                 self.a.as_allocated()?,
                 &self.ipiv,
                 rhs.as_slice_mut().unwrap())?;
        Ok(rhs)
    }
}

impl<A, S> Factorized<S>
    where A: LapackScalar,
          S: DataMut<Elem = A>
{
    pub fn into_inverse(mut self) -> Result<ArrayBase<S, Ix2>> {
        A::inv(self.a.layout()?, self.a.as_allocated_mut()?, &self.ipiv)?;
        Ok(self.a)
    }
}

pub trait Factorize<S: Data> {
    fn factorize(self) -> Result<Factorized<S>>;
}

impl<A, S> Factorize<S> for ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>
{
    fn factorize(mut self) -> Result<Factorized<S>> {
        let ipiv = A::lu(self.layout()?, self.as_allocated_mut()?)?;
        Ok(Factorized {
            a: self,
            ipiv: ipiv,
        })
    }
}

impl<'a, A, S> Factorize<OwnedRepr<A>> for &'a ArrayBase<S, Ix2>
    where A: LapackScalar + Clone,
          S: Data<Elem = A>
{
    fn factorize(self) -> Result<Factorized<OwnedRepr<A>>> {
        let mut a = self.to_owned();
        let ipiv = A::lu(a.layout()?, a.as_allocated_mut()?)?;
        Ok(Factorized { a: a, ipiv: ipiv })
    }
}

pub trait Inverse<Inv> {
    fn inv(self) -> Result<Inv>;
}

impl<A, S> Inverse<ArrayBase<S, Ix2>> for ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>
{
    fn inv(self) -> Result<ArrayBase<S, Ix2>> {
        let f = self.factorize()?;
        f.into_inverse()
    }
}

impl<'a, A, S> Inverse<Array2<A>> for &'a ArrayBase<S, Ix2>
    where A: LapackScalar + Clone,
          S: Data<Elem = A>
{
    fn inv(self) -> Result<Array2<A>> {
        let f = self.factorize()?;
        f.into_inverse()
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::mem;
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};

use tokio_core::io::Io;

use futures::{Async, Future, Poll};
use futures::sync::{BiLock, BiLockAcquired, BiLockAcquire};
use {Buf};

struct Shared<S> {
    socket: S,
    done: bool,
}

/// An input counterpart of IoBuf when the latter is split
pub struct ReadBuf<S> {
    pub in_buf: Buf,
    shared: BiLock<Shared<S>>,
}

/// An output counterpart of IoBuf when the latter is split
pub struct WriteBuf<S> {
    pub out_buf: Buf,
    shared: BiLock<Shared<S>>,
}

/// A structure that locks IoBuf and allows you to write to the socket directly
///
/// Where "directly" means without buffering and presumably with some zero-copy
/// method like `sendfile()` or `splice()`
///
/// Note: when `WriteRaw` is alive `ReadBuf` is alive, but locked and will
/// wake up as quick as `WriteRaw` is converted back to `WriteBuf`.
pub struct WriteRaw<S> {
    io: BiLockAcquired<Shared<S>>,
}

/// A future which converts `WriteBuf` into `WriteRaw`
pub struct FutureWriteRaw<S>(WriteRawFutState<S>);

enum WriteRawFutState<S> {
    Flushing(WriteBuf<S>),
    Locking(BiLockAcquire<Shared<S>>),
    Done,
}

pub fn create<S>(in_buf: Buf, out_buf: Buf, socket: S, done: bool)
    -> (WriteBuf<S>, ReadBuf<S>)
{
    let (a, b) = BiLock::new(Shared {
        socket: socket,
        done: done,
    });
    return (
        WriteBuf {
            out_buf: in_buf,
            shared: b,
        },
        ReadBuf {
            in_buf: out_buf,
            shared: a,
        });
}

impl<S: Io> ReadBuf<S> {
    /// Read a chunk of data into a buffer
    ///
    /// The data just read can then be found in `self.in_buf`.
    ///
    /// This method does just one read. Because you are ought to try parse
    /// request after every read rather than reading a lot of the data in
    /// memory.
    ///
    /// This method returns `0` when no bytes are read, both when WouldBlock
    /// occurred and when connection has been closed. You may then use
    /// `self.done()` to distinguish from these conditions.
    ///
    /// Note: this method silently assumes that you will call it on poll
    /// every time until self.done() returns false. I.e. it behaves as Async
    /// method but does't return Async value to allow simpler handling
    pub fn read(&mut self) -> Result<usize, io::Error> {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            match self.in_buf.read_from(&mut s.socket) {
                Ok(0) => {
                    s.done = true;
                    Ok(0)
                }
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(0),
                Err(ref e)
                    if e.kind() == io::ErrorKind::BrokenPipe ||
                       e.kind() == io::ErrorKind::ConnectionReset
                => {
                    s.done = true;
                    Ok(0)
                }
                result => result,
            }
        } else {
            Ok(0)
        }
    }

    /// Returns true when connection is closed by peer
    ///
    /// Note: this method returns false and schedules a wakeup if connecion
    /// is currently locked
    pub fn done(&self) -> bool {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            return s.done;
        } else {
            return false;
        }
    }
}

impl<S: Io> WriteBuf<S> {
    /// Write data in the output buffer to actual stream
    ///
    /// You should put the data to be sent into `self.out_buf` before flush
    ///
    /// Note: this method silently assumes that you will call it on poll
    /// every time until self.done() returns false. I.e. it behaves as Async
    /// method but does't return Async value to allow simpler handling
    pub fn flush(&mut self) -> Result<(), io::Error> {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            loop {
                if self.out_buf.len() == 0 {
                    break;
                }
                match self.out_buf.write_to(&mut s.socket) {
                    Ok(0) => break,
                    Ok(_) => continue,
                    Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                        break;
                    }
                    Err(ref e)
                        if e.kind() == io::ErrorKind::BrokenPipe ||
                           e.kind() == io::ErrorKind::ConnectionReset
                    => {
                        s.done = true;
                        break;
                    }
                    Err(e) => {
                        return Err(e);
                    },
                }
            }
            // This probably always does nothing, but we have to support the
            // full Io protocol
            match s.socket.flush() {
                Ok(()) => Ok(()),
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(()),
                Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe ||
                              e.kind() == io::ErrorKind::ConnectionReset
                => {
                    s.done = true;
                    Ok(())
                }
                Err(e) => Err(e),
            }
        } else {
            Ok(())
        }
    }

    /// Returns true when connection is closed by peer
    ///
    /// Note: this method returns false and schedules a wakeup if connecion
    /// is currently locked
    pub fn done(&self) -> bool {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            return s.done;
        } else {
            return false;
        }
    }

    /// Returns a future which will resolve into WriteRaw
    ///
    /// This future resolves when after two conditions:
    ///
    /// 1. Output buffer is fully flushed to the network (i.e. OS buffers)
    /// 2. Internal BiLock is locked
    ///
    /// Note: `WriteRaw` will lock the underlying stream for the whole
    /// lifetime of the `WriteRaw`.
    pub fn borrow_raw(self) -> FutureWriteRaw<S> {
        if self.out_buf.len() == 0 {
            FutureWriteRaw(WriteRawFutState::Locking(self.shared.lock()))
        } else {
            FutureWriteRaw(WriteRawFutState::Flushing(self))
        }
    }
}

impl<S: Io> Future for FutureWriteRaw<S> {
    type Item = WriteRaw<S>;
    type Error = io::Error;
    fn poll(&mut self) -> Poll<WriteRaw<S>, io::Error> {
        use self::WriteRawFutState::*;
        self.0 = match mem::replace(&mut self.0, Done) {
            Flushing(mut buf) => {
                buf.flush()?;
                if buf.out_buf.len() == 0 {
                    let mut lock = buf.shared.lock();
                    match lock.poll().expect("lock never fails") {
                        Async::Ready(s) => {
                            return Ok(Async::Ready(WriteRaw { io: s }));
                        }
                        Async::NotReady => {}
                    }
                    Locking(lock)
                } else {
                    Flushing(buf)
                }
            }
            Locking(mut f) => {
                match f.poll().expect("lock never fails") {
                    Async::Ready(s) => {
                        return Ok(Async::Ready(WriteRaw { io: s }));
                    }
                    Async::NotReady => {}
                }
                Locking(f)
            }
            Done => panic!("future polled after completion"),
        };
        return Ok(Async::NotReady);
    }
}

impl<S: Io> io::Write for WriteRaw<S> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.socket.write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.io.socket.flush()
    }
}

#[cfg(unix)]
impl<S: AsRawFd + Io> AsRawFd for WriteRaw<S> {
    fn as_raw_fd(&self) -> RawFd {
        self.io.socket.as_raw_fd()
    }
}
<commit_msg>Implements `WriteRaw::into_buf`<commit_after>use std::io;
use std::mem;
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};

use tokio_core::io::Io;

use futures::{Async, Future, Poll};
use futures::sync::{BiLock, BiLockAcquired, BiLockAcquire};
use {Buf};

struct Shared<S> {
    socket: S,
    done: bool,
}

/// An input counterpart of IoBuf when the latter is split
pub struct ReadBuf<S> {
    pub in_buf: Buf,
    shared: BiLock<Shared<S>>,
}

/// An output counterpart of IoBuf when the latter is split
pub struct WriteBuf<S> {
    pub out_buf: Buf,
    shared: BiLock<Shared<S>>,
}

/// A structure that locks IoBuf and allows you to write to the socket directly
///
/// Where "directly" means without buffering and presumably with some zero-copy
/// method like `sendfile()` or `splice()`
///
/// Note: when `WriteRaw` is alive `ReadBuf` is alive, but locked and will
/// wake up as quick as `WriteRaw` is converted back to `WriteBuf`.
pub struct WriteRaw<S> {
    io: BiLockAcquired<Shared<S>>,
}

/// A future which converts `WriteBuf` into `WriteRaw`
pub struct FutureWriteRaw<S>(WriteRawFutState<S>);

enum WriteRawFutState<S> {
    Flushing(WriteBuf<S>),
    Locking(BiLockAcquire<Shared<S>>),
    Done,
}

pub fn create<S>(in_buf: Buf, out_buf: Buf, socket: S, done: bool)
    -> (WriteBuf<S>, ReadBuf<S>)
{
    let (a, b) = BiLock::new(Shared {
        socket: socket,
        done: done,
    });
    return (
        WriteBuf {
            out_buf: in_buf,
            shared: b,
        },
        ReadBuf {
            in_buf: out_buf,
            shared: a,
        });
}

impl<S: Io> ReadBuf<S> {
    /// Read a chunk of data into a buffer
    ///
    /// The data just read can then be found in `self.in_buf`.
    ///
    /// This method does just one read. Because you are ought to try parse
    /// request after every read rather than reading a lot of the data in
    /// memory.
    ///
    /// This method returns `0` when no bytes are read, both when WouldBlock
    /// occurred and when connection has been closed. You may then use
    /// `self.done()` to distinguish from these conditions.
    ///
    /// Note: this method silently assumes that you will call it on poll
    /// every time until self.done() returns false. I.e. it behaves as Async
    /// method but does't return Async value to allow simpler handling
    pub fn read(&mut self) -> Result<usize, io::Error> {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            match self.in_buf.read_from(&mut s.socket) {
                Ok(0) => {
                    s.done = true;
                    Ok(0)
                }
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(0),
                Err(ref e)
                    if e.kind() == io::ErrorKind::BrokenPipe ||
                       e.kind() == io::ErrorKind::ConnectionReset
                => {
                    s.done = true;
                    Ok(0)
                }
                result => result,
            }
        } else {
            Ok(0)
        }
    }

    /// Returns true when connection is closed by peer
    ///
    /// Note: this method returns false and schedules a wakeup if connecion
    /// is currently locked
    pub fn done(&self) -> bool {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            return s.done;
        } else {
            return false;
        }
    }
}

impl<S: Io> WriteBuf<S> {
    /// Write data in the output buffer to actual stream
    ///
    /// You should put the data to be sent into `self.out_buf` before flush
    ///
    /// Note: this method silently assumes that you will call it on poll
    /// every time until self.done() returns false. I.e. it behaves as Async
    /// method but does't return Async value to allow simpler handling
    pub fn flush(&mut self) -> Result<(), io::Error> {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            loop {
                if self.out_buf.len() == 0 {
                    break;
                }
                match self.out_buf.write_to(&mut s.socket) {
                    Ok(0) => break,
                    Ok(_) => continue,
                    Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                        break;
                    }
                    Err(ref e)
                        if e.kind() == io::ErrorKind::BrokenPipe ||
                           e.kind() == io::ErrorKind::ConnectionReset
                    => {
                        s.done = true;
                        break;
                    }
                    Err(e) => {
                        return Err(e);
                    },
                }
            }
            // This probably always does nothing, but we have to support the
            // full Io protocol
            match s.socket.flush() {
                Ok(()) => Ok(()),
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(()),
                Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe ||
                              e.kind() == io::ErrorKind::ConnectionReset
                => {
                    s.done = true;
                    Ok(())
                }
                Err(e) => Err(e),
            }
        } else {
            Ok(())
        }
    }

    /// Returns true when connection is closed by peer
    ///
    /// Note: this method returns false and schedules a wakeup if connecion
    /// is currently locked
    pub fn done(&self) -> bool {
        if let Async::Ready(ref mut s) = self.shared.poll_lock() {
            return s.done;
        } else {
            return false;
        }
    }

    /// Returns a future which will resolve into WriteRaw
    ///
    /// This future resolves when after two conditions:
    ///
    /// 1. Output buffer is fully flushed to the network (i.e. OS buffers)
    /// 2. Internal BiLock is locked
    ///
    /// Note: `WriteRaw` will lock the underlying stream for the whole
    /// lifetime of the `WriteRaw`.
    pub fn borrow_raw(self) -> FutureWriteRaw<S> {
        if self.out_buf.len() == 0 {
            FutureWriteRaw(WriteRawFutState::Locking(self.shared.lock()))
        } else {
            FutureWriteRaw(WriteRawFutState::Flushing(self))
        }
    }
}

impl<S: Io> WriteRaw<S> {
    /// Turn raw writer back into buffered and release internal BiLock
    pub fn into_buf(self) -> WriteBuf<S> {
        WriteBuf {
            out_buf: Buf::new(),
            shared: self.io.unlock(),
        }
    }
}

impl<S: Io> Future for FutureWriteRaw<S> {
    type Item = WriteRaw<S>;
    type Error = io::Error;
    fn poll(&mut self) -> Poll<WriteRaw<S>, io::Error> {
        use self::WriteRawFutState::*;
        self.0 = match mem::replace(&mut self.0, Done) {
            Flushing(mut buf) => {
                buf.flush()?;
                if buf.out_buf.len() == 0 {
                    let mut lock = buf.shared.lock();
                    match lock.poll().expect("lock never fails") {
                        Async::Ready(s) => {
                            return Ok(Async::Ready(WriteRaw { io: s }));
                        }
                        Async::NotReady => {}
                    }
                    Locking(lock)
                } else {
                    Flushing(buf)
                }
            }
            Locking(mut f) => {
                match f.poll().expect("lock never fails") {
                    Async::Ready(s) => {
                        return Ok(Async::Ready(WriteRaw { io: s }));
                    }
                    Async::NotReady => {}
                }
                Locking(f)
            }
            Done => panic!("future polled after completion"),
        };
        return Ok(Async::NotReady);
    }
}

impl<S: Io> io::Write for WriteRaw<S> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.socket.write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.io.socket.flush()
    }
}

#[cfg(unix)]
impl<S: AsRawFd + Io> AsRawFd for WriteRaw<S> {
    fn as_raw_fd(&self) -> RawFd {
        self.io.socket.as_raw_fd()
    }
}
<|endoftext|>


<commit_before>//! # `split` - split extremely large files into consistently-sized deterministic chunks.
//!
//! Key functionality of this module includes:
//!
//! * Splitting large files into chunks, via memory-mapped files.
//! * Splitting slices of bytes into chunks, for use with lazily-downloaded files.
//!
//! The main functions of this module are `arc_slice::chunk` and `arc_slice::chunk_with_trace`.

use std::cmp;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;

use generic_array::ArrayLength;
use seahash::SeaHasher;
use typenum::Unsigned;

use arc_slice::{self, ArcSlice};

pub struct GenericSplitter<Win, Min, Mod, Cst, T, F, H, I, S>
where
    Win: ArrayLength<u8>,
    Min: Unsigned,
    Mod: Unsigned,
    Cst: Unsigned,
    F: Fn(T) -> (H, I),
    H: Deref<Target = [u8]>,
    S: Iterator<Item = T>,
{
    acc: u64,
    buf: Vec<u8>,
    group: Vec<I>,
    hash: F,
    iterator: Option<S>,
    _consts: PhantomData<(Win, Min, Mod, Cst)>,
}

impl<Win, Min, Mod, Cst, T, F, H, I, S> GenericSplitter<Win, Min, Mod, Cst, T, F, H, I, S>
where
    Win: ArrayLength<u8>,
    Min: Unsigned,
    Mod: Unsigned,
    Cst: Unsigned,
    F: Fn(T) -> (H, I),
    H: Deref<Target = [u8]>,
    S: Iterator<Item = T>,
{
    pub fn new(stream: S, hash: F) -> Self {
        GenericSplitter {
            acc: 0,
            buf: Vec::new(),
            group: Vec::new(),
            hash,
            iterator: Some(stream),
            _consts: PhantomData,
        }
    }
}

impl<Win, Min, Mod, Cst, T, F, H, I, S> Iterator
    for GenericSplitter<Win, Min, Mod, Cst, T, F, H, I, S>
where
    Win: ArrayLength<u8>,
    Min: Unsigned,
    Mod: Unsigned,
    Cst: Unsigned,
    F: Fn(T) -> (H, I),
    H: Deref<Target = [u8]>,
    S: Iterator<Item = T>,
{
    type Item = (Vec<u8>, Vec<I>);

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            match self.iterator.as_mut().map(Iterator::next) {
                Some(Some(input)) => {
                    let (hashed, item) = (self.hash)(input);
                    let buf_len = self.buf.len();
                    self.buf.extend_from_slice(&*hashed);
                    self.group.push(item);

                    for (i, &b) in (buf_len..).zip(&self.buf[buf_len..]) {
                        self.acc = self.acc.wrapping_add(b as u64);

                        if i >= Win::to_usize() {
                            self.acc = self.acc.wrapping_sub(self.buf[i - Win::to_usize()] as u64);
                        }
                    }

                    self.acc &= (1 << Mod::to_u32()) - 1;

                    if self.buf.len() >= Win::to_usize() {
                        let new_buf_len = self.buf.len();
                        self.buf.drain(..new_buf_len - Win::to_usize());
                    }

                    if self.group.len() >= Min::to_usize() && self.acc == Cst::to_u64() {
                        let split_zone = mem::replace(&mut self.buf, Vec::new());
                        let group = mem::replace(&mut self.group, Vec::new());

                        self.acc = 0;

                        return Some((split_zone, group));
                    }
                }

                Some(None) => {
                    let split_zone = mem::replace(&mut self.buf, Vec::new());
                    let group = mem::replace(&mut self.group, Vec::new());

                    mem::drop(self.iterator.take());

                    return Some((split_zone, group));
                }

                None => return None,
            }
        }
    }
}

/// A "splitter" over a slice, which functions as an iterator producing ~10 kb [citation needed]
/// chunks.
pub struct SliceSplitter {
    slice: ArcSlice,
}

impl SliceSplitter {
    pub fn new(slice: ArcSlice) -> SliceSplitter {
        SliceSplitter { slice }
    }
}

/// The minimum chunk size. Chosen to reduce the number of extremely small (1-4 byte) chunks by
/// reducing the likelihood of finding chunks which instantly satisfy the chunking criteria (within
/// only a few bytes - e.g. a `0x01` byte followed by a whole bunch of zeroes, or a whole bunch of
/// zeroes with a `0x01` byte embedded inside.)
const SPLIT_MINIMUM: usize = SPLIT_WINDOW;

// 1 << 12 = 4096
// 1 << 13 = 8192
// 1 << 14 = 16384
/// The bitmask of the power-of-two modulus we use to cap the rolling sum.
const SPLIT_MODULUS_MASK: u16 = (1 << 14) - 1;

/// We sum all the bytes in a window, mask them off, and then check whether or not the result is
/// equal to the `SPLIT` constant. If it is, this is a chunk split.
const SPLIT_CONSTANT: u16 = 1;

// 1 << 13 = 8192
/// The size of the window of bytes to "hash".
const SPLIT_WINDOW: usize = 1 << 13;

impl Iterator for SliceSplitter {
    type Item = ArcSlice;

    fn next(&mut self) -> Option<ArcSlice> {
        if self.slice.len() == 0 {
            return None;
        }

        let mut acc = 0;

        for i in 0..self.slice.len() {
            if i >= SPLIT_WINDOW {
                acc -= self.slice[i - SPLIT_WINDOW] as u16;
            }

            acc += self.slice[i] as u16;
            acc &= SPLIT_MODULUS_MASK;

            if acc == SPLIT_CONSTANT && i >= SPLIT_MINIMUM {
                let split = self.slice.clone().map(|slice| slice.split_at(i).0);
                let rest = self.slice.clone().map(|slice| slice.split_at(i).1);

                self.slice = rest;

                return Some(split);
            }
        }

        return Some(mem::replace(&mut self.slice, arc_slice::empty()));
    }
}

/// A ring buffer used to implement the rolling rsync-style checksum.
pub struct Ring {
    buf: [u8; CHUNK_WINDOW],
    loc: usize,
}

impl Ring {
    fn new() -> Ring {
        Ring {
            buf: [0u8; CHUNK_WINDOW],
            loc: 0,
        }
    }

    /// Push a new byte into the ring buffer, ignoring the last byte.
    fn push(&mut self, byte: u8) {
        self.push_pop(byte);
    }

    /// Remove the last byte from the ring buffer, replacing it.
    fn push_pop(&mut self, byte: u8) -> u8 {
        let popped = mem::replace(&mut self.buf[self.loc], byte);
        self.loc = (self.loc + 1) % CHUNK_WINDOW;

        popped
    }
}

/// "Chunk" a slice, producing ~3 MB chunks.
pub struct SliceChunker {
    rest: ArcSlice,
    splitter: SliceSplitter,
}

impl SliceChunker {
    pub fn new(slice: ArcSlice) -> SliceChunker {
        SliceChunker {
            rest: slice.clone(),
            splitter: SliceSplitter::new(slice),
        }
    }
}

const CHUNK_MINIMUM: usize = 32;
const CHUNK_MODULUS_MASK: u16 = (1 << 7) - 1;
const CHUNK_CONSTANT: u16 = 1;
const CHUNK_WINDOW: usize = 4;

fn seahash(slice: &[u8]) -> u8 {
    let mut hasher = SeaHasher::default();
    slice.hash(&mut hasher);
    hasher.finish() as u8
}

impl Iterator for SliceChunker {
    type Item = ArcSlice;

    fn next(&mut self) -> Option<ArcSlice> {
        if self.rest.len() == 0 {
            return None;
        }

        let mut ring = Ring::new();

        let mut offset = 0;
        let mut acc = 0;

        for (i, slice) in self.splitter.by_ref().enumerate() {
            let sig = seahash(&slice[slice.len() - cmp::min(SPLIT_WINDOW, slice.len())..]);

            if i >= CHUNK_WINDOW {
                acc -= ring.push_pop(sig) as u16;
            } else {
                ring.push(sig);
            }

            acc += sig as u16;
            acc &= CHUNK_MODULUS_MASK;

            offset += slice.len();

            if acc == CHUNK_CONSTANT && i >= CHUNK_MINIMUM {
                let split = self.rest.clone().map(|slice| slice.split_at(offset).0);
                let rest = self.rest.clone().map(|slice| slice.split_at(offset).1);

                self.rest = rest;

                return Some(split);
            }
        }

        return Some(mem::replace(&mut self.rest, arc_slice::empty()));
    }
}
<commit_msg>Fix: non-wrapping add/sub in splitter<commit_after>//! # `split` - split extremely large files into consistently-sized deterministic chunks.
//!
//! Key functionality of this module includes:
//!
//! * Splitting large files into chunks, via memory-mapped files.
//! * Splitting slices of bytes into chunks, for use with lazily-downloaded files.
//!
//! The main functions of this module are `arc_slice::chunk` and `arc_slice::chunk_with_trace`.

use std::cmp;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;

use generic_array::ArrayLength;
use seahash::SeaHasher;
use typenum::Unsigned;

use arc_slice::{self, ArcSlice};

pub struct GenericSplitter<Win, Min, Mod, Cst, T, F, H, I, S>
where
    Win: ArrayLength<u8>,
    Min: Unsigned,
    Mod: Unsigned,
    Cst: Unsigned,
    F: Fn(T) -> (H, I),
    H: Deref<Target = [u8]>,
    S: Iterator<Item = T>,
{
    acc: u64,
    buf: Vec<u8>,
    group: Vec<I>,
    hash: F,
    iterator: Option<S>,
    _consts: PhantomData<(Win, Min, Mod, Cst)>,
}

impl<Win, Min, Mod, Cst, T, F, H, I, S> GenericSplitter<Win, Min, Mod, Cst, T, F, H, I, S>
where
    Win: ArrayLength<u8>,
    Min: Unsigned,
    Mod: Unsigned,
    Cst: Unsigned,
    F: Fn(T) -> (H, I),
    H: Deref<Target = [u8]>,
    S: Iterator<Item = T>,
{
    pub fn new(stream: S, hash: F) -> Self {
        GenericSplitter {
            acc: 0,
            buf: Vec::new(),
            group: Vec::new(),
            hash,
            iterator: Some(stream),
            _consts: PhantomData,
        }
    }
}

impl<Win, Min, Mod, Cst, T, F, H, I, S> Iterator
    for GenericSplitter<Win, Min, Mod, Cst, T, F, H, I, S>
where
    Win: ArrayLength<u8>,
    Min: Unsigned,
    Mod: Unsigned,
    Cst: Unsigned,
    F: Fn(T) -> (H, I),
    H: Deref<Target = [u8]>,
    S: Iterator<Item = T>,
{
    type Item = (Vec<u8>, Vec<I>);

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            match self.iterator.as_mut().map(Iterator::next) {
                Some(Some(input)) => {
                    let (hashed, item) = (self.hash)(input);
                    let buf_len = self.buf.len();
                    self.buf.extend_from_slice(&*hashed);
                    self.group.push(item);

                    for (i, &b) in (buf_len..).zip(&self.buf[buf_len..]) {
                        self.acc = self.acc.wrapping_add(b as u64);

                        if i >= Win::to_usize() {
                            self.acc = self.acc.wrapping_sub(self.buf[i - Win::to_usize()] as u64);
                        }
                    }

                    self.acc &= (1 << Mod::to_u32()) - 1;

                    if self.buf.len() >= Win::to_usize() {
                        let new_buf_len = self.buf.len();
                        self.buf.drain(..new_buf_len - Win::to_usize());
                    }

                    if self.group.len() >= Min::to_usize() && self.acc == Cst::to_u64() {
                        let split_zone = mem::replace(&mut self.buf, Vec::new());
                        let group = mem::replace(&mut self.group, Vec::new());

                        self.acc = 0;

                        return Some((split_zone, group));
                    }
                }

                Some(None) => {
                    let split_zone = mem::replace(&mut self.buf, Vec::new());
                    let group = mem::replace(&mut self.group, Vec::new());

                    mem::drop(self.iterator.take());

                    return Some((split_zone, group));
                }

                None => return None,
            }
        }
    }
}

/// A "splitter" over a slice, which functions as an iterator producing ~10 kb [citation needed]
/// chunks.
pub struct SliceSplitter {
    slice: ArcSlice,
}

impl SliceSplitter {
    pub fn new(slice: ArcSlice) -> SliceSplitter {
        SliceSplitter { slice }
    }
}

/// The minimum chunk size. Chosen to reduce the number of extremely small (1-4 byte) chunks by
/// reducing the likelihood of finding chunks which instantly satisfy the chunking criteria (within
/// only a few bytes - e.g. a `0x01` byte followed by a whole bunch of zeroes, or a whole bunch of
/// zeroes with a `0x01` byte embedded inside.)
const SPLIT_MINIMUM: usize = SPLIT_WINDOW;

// 1 << 12 = 4096
// 1 << 13 = 8192
// 1 << 14 = 16384
/// The bitmask of the power-of-two modulus we use to cap the rolling sum.
const SPLIT_MODULUS_MASK: u16 = (1 << 14) - 1;

/// We sum all the bytes in a window, mask them off, and then check whether or not the result is
/// equal to the `SPLIT` constant. If it is, this is a chunk split.
const SPLIT_CONSTANT: u16 = 1;

// 1 << 13 = 8192
/// The size of the window of bytes to "hash".
const SPLIT_WINDOW: usize = 1 << 13;

impl Iterator for SliceSplitter {
    type Item = ArcSlice;

    fn next(&mut self) -> Option<ArcSlice> {
        if self.slice.len() == 0 {
            return None;
        }

        let mut acc = 0u16;

        for i in 0..self.slice.len() {
            if i >= SPLIT_WINDOW {
                acc = acc.wrapping_sub(self.slice[i - SPLIT_WINDOW] as u16);
            }

            acc = acc.wrapping_add(self.slice[i] as u16);
            acc &= SPLIT_MODULUS_MASK;

            if acc == SPLIT_CONSTANT && i >= SPLIT_MINIMUM {
                let split = self.slice.clone().map(|slice| slice.split_at(i).0);
                let rest = self.slice.clone().map(|slice| slice.split_at(i).1);

                self.slice = rest;

                return Some(split);
            }
        }

        return Some(mem::replace(&mut self.slice, arc_slice::empty()));
    }
}

/// A ring buffer used to implement the rolling rsync-style checksum.
pub struct Ring {
    buf: [u8; CHUNK_WINDOW],
    loc: usize,
}

impl Ring {
    fn new() -> Ring {
        Ring {
            buf: [0u8; CHUNK_WINDOW],
            loc: 0,
        }
    }

    /// Push a new byte into the ring buffer, ignoring the last byte.
    fn push(&mut self, byte: u8) {
        self.push_pop(byte);
    }

    /// Remove the last byte from the ring buffer, replacing it.
    fn push_pop(&mut self, byte: u8) -> u8 {
        let popped = mem::replace(&mut self.buf[self.loc], byte);
        self.loc = (self.loc + 1) % CHUNK_WINDOW;

        popped
    }
}

/// "Chunk" a slice, producing ~3 MB chunks.
pub struct SliceChunker {
    rest: ArcSlice,
    splitter: SliceSplitter,
}

impl SliceChunker {
    pub fn new(slice: ArcSlice) -> SliceChunker {
        SliceChunker {
            rest: slice.clone(),
            splitter: SliceSplitter::new(slice),
        }
    }
}

const CHUNK_MINIMUM: usize = 32;
const CHUNK_MODULUS_MASK: u16 = (1 << 7) - 1;
const CHUNK_CONSTANT: u16 = 1;
const CHUNK_WINDOW: usize = 4;

fn seahash(slice: &[u8]) -> u8 {
    let mut hasher = SeaHasher::default();
    slice.hash(&mut hasher);
    hasher.finish() as u8
}

impl Iterator for SliceChunker {
    type Item = ArcSlice;

    fn next(&mut self) -> Option<ArcSlice> {
        if self.rest.len() == 0 {
            return None;
        }

        let mut ring = Ring::new();

        let mut offset = 0;
        let mut acc = 0u16;

        for (i, slice) in self.splitter.by_ref().enumerate() {
            let sig = seahash(&slice[slice.len() - cmp::min(SPLIT_WINDOW, slice.len())..]);

            if i >= CHUNK_WINDOW {
                acc = acc.wrapping_sub(ring.push_pop(sig) as u16);
            } else {
                ring.push(sig);
            }

            acc = acc.wrapping_add(sig as u16);
            acc &= CHUNK_MODULUS_MASK;

            offset += slice.len();

            if acc == CHUNK_CONSTANT && i >= CHUNK_MINIMUM {
                let split = self.rest.clone().map(|slice| slice.split_at(offset).0);
                let rest = self.rest.clone().map(|slice| slice.split_at(offset).1);

                self.rest = rest;

                return Some(split);
            }
        }

        return Some(mem::replace(&mut self.rest, arc_slice::empty()));
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017-2018 Ryan Huang
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#![cfg(test)]

use model::Board;

fn perft(board: &Board, depth: u8) -> u64 {
    if depth == 0 {
        1
    } else {
        let mut sum = 0;
        for mv in board.generate_moves() {
            let mut new_board = *board;
            new_board.apply_move(&mv);
            sum += perft(&new_board, depth - 1);
        }
        sum
    }
}

#[test]
fn perft_depth_4() {
    // These counts have not been verified by an external source. They only test for consistency
    // with earlier versions of the program.
    let counts = [48, 2304, 110304, 5280654];
    let board = Board::new();

    for (i, &count) in counts.iter().enumerate() {
        assert_eq!(count, perft(&board, i as u8 + 1));
    }
}

#[test]
#[ignore]
fn perft_depth_5() {
    // These counts have not been verified by an external source. They only test for consistency
    // with earlier versions of the program.
    let counts = [48, 2304, 110304, 5280654, 254945184];
    let board = Board::new();

    for (i, &count) in counts.iter().enumerate() {
        assert_eq!(count, perft(&board, i as u8 + 1));
    }
}

#[test]
#[ignore]
fn perft_depth_6() {
    // These counts have not been verified by an external source. They only test for consistency
    // with earlier versions of the program.
    let counts = [48, 2304, 110304, 5280654, 254945184, 12307984056];
    let board = Board::new();

    for (i, &count) in counts.iter().enumerate() {
        assert_eq!(count, perft(&board, i as u8 + 1));
    }
}
<commit_msg>Fix perft tests<commit_after>/*
 * Copyright (C) 2017-2018 Ryan Huang
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#![cfg(test)]

use model::{Board, GameType};

fn perft(board: &Board, depth: u8) -> u64 {
    if depth == 0 {
        1
    } else {
        let mut sum = 0;
        for mv in board.generate_moves() {
            let mut new_board = *board;
            new_board.apply_move(&mv);
            sum += perft(&new_board, depth - 1);
        }
        sum
    }
}

#[test]
fn laurentius_perft_4() {
    // These counts have not been verified by an external source. They only test for consistency
    // with earlier versions of the program.
    let counts = [48, 2304, 110304, 5280654];
    let board = Board::new(GameType::Laurentius);

    for (i, &count) in counts.iter().enumerate() {
        assert_eq!(count, perft(&board, i as u8 + 1));
    }
}

#[test]
#[ignore]
fn laurentius_perft_5() {
    // These counts have not been verified by an external source. They only test for consistency
    // with earlier versions of the program.
    let counts = [48, 2304, 110304, 5280654, 254945184];
    let board = Board::new(GameType::Laurentius);

    for (i, &count) in counts.iter().enumerate() {
        assert_eq!(count, perft(&board, i as u8 + 1));
    }
}

#[test]
#[ignore]
fn laurentius_perft_6() {
    // These counts have not been verified by an external source. They only test for consistency
    // with earlier versions of the program.
    let counts = [48, 2304, 110304, 5280654, 254945184, 12307984056];
    let board = Board::new(GameType::Laurentius);

    for (i, &count) in counts.iter().enumerate() {
        assert_eq!(count, perft(&board, i as u8 + 1));
    }
}
<|endoftext|>