<commit_before>use std::collections::btree_map::{BTreeMap, Range};
use std::collections::Bound::*;
use std::cmp::Ordering::*;
use std::iter::Peekable;

use super::Result;

use self::NextIterValue::*;

/// A set of serial changes that should be applied to a storage atomically.
pub type Patch = BTreeMap<Vec<u8>, Change>;

/// A generalized iterator over a storage views.
pub type Iter<'a> = Box<Iterator + 'a>;

/// An enum that represents a kind of change of some key in storage.
#[derive(Debug, Clone)]
pub enum Change {
    /// Put the specified value into storage for a corresponding key.
    Put(Vec<u8>),
    /// Delete a value from storage for a corresponding key.
    Delete,
}

// FIXME: make &mut Fork "unwind safe"
pub struct Fork {
    snapshot: Box<Snapshot>,
    changes: Patch,
    changelog: Vec<(Vec<u8>, Option<Change>)>,
    logged: bool,
}

struct ForkIter<'a> {
    snapshot: Iter<'a>,
    changes: Peekable<Range<'a, Vec<u8>, Change>>,
}

#[derive(Debug, PartialEq, Eq)]
enum NextIterValue {
    Stored,
    Replaced,
    Inserted,
    Deleted,
    MissDeleted,
    Finished,
}

/// A trait that define a low-level storage backend.
///
/// The trait `Database` requires to implement traits `Send` and `Sync` and should not be borrowed
/// data, so you can use method [`clone`] to get the references to the database for concurrent
/// usage.
///
/// There is no way to directly interact with data in the database.
///
/// If you only need to read the data, you can create a [`Snapshot`] using method [`snapshot`].
/// Snapshots provide a read isolation, so you are guaranteed to work with consistent values even
/// if the data in the database changes between reads.
///
/// If you need to make any changes to the data, you need to create a [`Fork`] using method
/// [`fork`]. As well as `Snapshot`, `Fork` provides a read isolation and also allows you to create
/// a sequence of changes to the database that are specified as [`Patch`]. Later you can atomically
/// merge a patch into the database using method [`merge`].
///
/// [`clone`]: #tymethod.fork
/// [`Snapshot`]: trait.Snapshot.html
/// [`snapshot`]: #tymethod.snapshot
/// [`Fork`]: struct.Fork.html
/// [`fork`]: #method.fork
/// [`Patch`]: type.Patch.html
/// [`merge`]: #tymethod.merge
pub trait Database: Send + Sync + 'static {
    /// Creates a new reference to the database as `Box<Database>`.
    fn clone(&self) -> Box<Database>;

    /// Creates a new snapshot of the database from its current state.
    ///
    /// See [`Snapshot`] documentation for more.
    /// [`Snapshot`]: trait.Snapshot.html
    fn snapshot(&self) -> Box<Snapshot>;

    /// Creates a new fork of the database from its current state.
    ///
    /// See [`Fork`] documentation for more.
    /// [`Fork`]: struct.Fork.html
    fn fork(&self) -> Fork {
        Fork {
            snapshot: self.snapshot(),
            changes: Patch::new(),
            changelog: Vec::new(),
            logged: false,
        }
    }

    /// Atomically applies a sequence of patch changes to the database.
    ///
    /// # Errors
    /// If this method encounters any form of I/O or other error during merging, an error variant
    /// will be returned. If an error is returned then it must be guaranteed that no changes were
    /// applied.
    fn merge(&mut self, patch: Patch) -> Result<()>;
}

/// A trait that define a snapshot of storage backend.
///
/// `Snapshot` instance is immutable representation of storage state. It provides a read isolation,
/// so using snapshot you are guaranteed to work with consistent values even if the data in
/// the database changes between reads.
///
/// `Snapshot` provides all the necessary methods for reading data from the database, so `&Storage`
/// is used as a storage view for creating read-only indexes representation.
// TODO: should Snapshot be Send or Sync?
pub trait Snapshot: 'static {
    /// Returns a value as raw vector of bytes corresponding to the specified key
    /// or `None` if not exists.
    fn get(&self, key: &[u8]) -> Option<Vec<u8>>;

    /// Returns `true` if the snapshot contains a value for the specified key.
    ///
    /// Default implementation tries to read the value using method [`get`].
    /// [`get`]: #tymethod.get
    fn contains(&self, key: &[u8]) -> bool {
        self.get(key).is_some()
    }

    /// Returns an iterator over the entries of the snapshot in ascending order starting from
    /// the specified key. The iterator element type is `(&[u8], &[u8])`.
    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a>;
}

/// A trait that define streaming iterator over storage view entries.
pub trait Iterator {
    /// Advances the iterator and returns the next key and value.
    fn next(&mut self) -> Option<(&[u8], &[u8])>;

    /// Returns references to the current key and value of the iterator.
    fn peek(&mut self) -> Option<(&[u8], &[u8])>;
}

impl Snapshot for Fork {
    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        match self.changes.get(key) {
            Some(change) => {
                match *change {
                    Change::Put(ref v) => Some(v.clone()),
                    Change::Delete => None,
                }
            }
            None => self.snapshot.get(key),
        }
    }

    fn contains(&self, key: &[u8]) -> bool {
        match self.changes.get(key) {
            Some(change) => {
                match *change {
                    Change::Put(..) => true,
                    Change::Delete => false,
                }
            }
            None => self.snapshot.get(key).is_some(),
        }
    }

    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a> {
        let range = (Included(from), Unbounded);
        Box::new(ForkIter {
                     snapshot: self.snapshot.iter(from),
                     changes: self.changes.range::<[u8], _>(range).peekable(),
                 })
    }
}

impl Fork {
    pub fn checkpoint(&mut self) {
        if self.logged {
            panic!("call checkpoint before rollback or commit");
        }
        self.logged = true;
    }

    pub fn commit(&mut self) {
        if !self.logged {
            panic!("call commit before checkpoint");
        }
        self.changelog.clear();
        self.logged = false;
    }

    pub fn rollback(&mut self) {
        if !self.logged {
            panic!("call rollback before checkpoint");
        }
        for (k, c) in self.changelog.drain(..).rev() {
            match c {
                Some(change) => self.changes.insert(k, change),
                None => self.changes.remove(&k),
            };
        }
        self.logged = false;
    }

    pub fn put(&mut self, key: Vec<u8>, value: Vec<u8>) {
        if self.logged {
            self.changelog
                .push((key.clone(), self.changes.insert(key, Change::Put(value))));
        } else {
            self.changes.insert(key, Change::Put(value));
        }
    }

    pub fn remove(&mut self, key: Vec<u8>) {
        if self.logged {
            self.changelog
                .push((key.clone(), self.changes.insert(key, Change::Delete)));
        } else {
            self.changes.insert(key, Change::Delete);
        }
    }

    pub fn remove_by_prefix(&mut self, prefix: &[u8]) {
        // Remove changes
        let keys = self.changes
                       .range::<[u8], _>((Included(prefix), Unbounded))
                       .map(|(k, ..)| k.to_vec())
                       .take_while(|k| k.starts_with(prefix))
                       .collect::<Vec<_>>();
        for k in keys {
            self.changes.remove(&k);
        }
        // Remove from storage
        let mut iter = self.snapshot.iter(prefix);
        while let Some((k, ..)) = iter.next() {
            if !k.starts_with(prefix) {
                return;
            }
            let change = self.changes.insert(k.to_vec(), Change::Delete);
            if self.logged {
                self.changelog.push((k.to_vec(), change));
            }
        }
    }

    pub fn into_patch(self) -> Patch {
        self.changes
    }

    pub fn merge(&mut self, patch: Patch) {
        if self.logged {
            panic!("call merge before commit or rollback");
        }
        self.changes.extend(patch)
    }
}

impl AsRef<Snapshot> for Snapshot + 'static {
    fn as_ref(&self) -> &Snapshot {
        self
    }
}

impl AsRef<Snapshot> for Fork {
    fn as_ref(&self) -> &Snapshot {
        self
    }
}

impl ::std::fmt::Debug for Fork {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "Fork(..)")
    }
}

impl<'a> ForkIter<'a> {
    fn step(&mut self) -> NextIterValue {
        match self.changes.peek() {
            Some(&(k, change)) => {
                match self.snapshot.peek() {
                    Some((key, ..)) => {
                        match *change {
                            Change::Put(..) => {
                                match k[..].cmp(key) {
                                    Equal => Replaced,
                                    Less => Inserted,
                                    Greater => Stored,
                                }
                            }
                            Change::Delete => {
                                match k[..].cmp(key) {
                                    Equal => Deleted,
                                    Less => MissDeleted,
                                    Greater => Stored,
                                }
                            }
                        }
                    }
                    None => {
                        match *change {
                            Change::Put(..) => Inserted,
                            Change::Delete => MissDeleted,
                        }
                    }
                }
            }
            None => {
                match self.snapshot.peek() {
                    Some(..) => Stored,
                    None => Finished,
                }
            }
        }
    }
}

impl<'a> Iterator for ForkIter<'a> {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        loop {
            match self.step() {
                Stored => return self.snapshot.next(),
                Replaced => {
                    self.snapshot.next();
                    return self.changes
                               .next()
                               .map(|(key, change)| {
                                        (key.as_slice(),
                                         match *change {
                                             Change::Put(ref value) => value.as_slice(),
                                             Change::Delete => unreachable!(),
                                         })
                                    });
                }
                Inserted => {
                    return self.changes
                               .next()
                               .map(|(key, change)| {
                                        (key.as_slice(),
                                         match *change {
                                             Change::Put(ref value) => value.as_slice(),
                                             Change::Delete => unreachable!(),
                                         })
                                    })
                }
                Deleted => {
                    self.changes.next();
                    self.snapshot.next();
                }
                MissDeleted => {
                    self.changes.next();
                }
                Finished => return None,
            }
        }
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        loop {
            match self.step() {
                Stored => return self.snapshot.peek(),
                Replaced | Inserted => {
                    return self.changes
                               .peek()
                               .map(|&(key, change)| {
                                        (key.as_slice(),
                                         match *change {
                                             Change::Put(ref value) => value.as_slice(),
                                             Change::Delete => unreachable!(),
                                         })
                                    })
                }
                Deleted => {
                    self.changes.next();
                    self.snapshot.next();
                }
                MissDeleted => {
                    self.changes.next();
                }
                Finished => return None,
            }
        }
    }
}
<commit_msg>Docs for Fork<commit_after>use std::collections::btree_map::{BTreeMap, Range};
use std::collections::Bound::*;
use std::cmp::Ordering::*;
use std::iter::Peekable;

use super::Result;

use self::NextIterValue::*;

/// A set of serial changes that should be applied to a storage atomically.
pub type Patch = BTreeMap<Vec<u8>, Change>;

/// A generalized iterator over a storage views.
pub type Iter<'a> = Box<Iterator + 'a>;

/// An enum that represents a kind of change of some key in storage.
#[derive(Debug, Clone)]
pub enum Change {
    /// Put the specified value into storage for a corresponding key.
    Put(Vec<u8>),
    /// Delete a value from storage for a corresponding key.
    Delete,
}

/// A combination of a database snapshot and a sequence of changes on top of it.
///
/// A `Fork` provides both immutable and mutable operations over database. As well as [`Snapshot`],
/// it provides a read isolation. When mutable operations ([`put`], [`remove`] and
/// [`remove_by_prefix`] methods) are performed for fork, the data is presented as if these changes
/// are applied to the database. However, instead of applying changes directly to the database,
/// fork only accumulates these changes in memory.
///
/// To apply changes to the database, you need to convert a `Fork` into a [`Patch`] using method
/// [`into_patch`] and then atomically merge it into the database using method [`merge`]. If two
/// conflicting forks are merged into a database, this can lead to a non-consistent state. If you
/// need to consistently apply several sets of changes for the same data, the next fork should be
/// created after the previous fork has been merged.
///
/// `Fork` also supports a checkpoint mechanism (methods [`checkpoint`], [`commit`] and [`rollback`])
/// that allows you to rollback some of the latest changes if for some reason you can not provide
/// a consistent state after the changes due to a runtime error.
///
/// `Fork` implement [`Snapshot`] trait and provides all the necessary methods for both reading and
/// writing data from the database, so `&mut Fork` is used as a storage view for creating
/// read-write indices representation.
///
/// [`Snapshot`]: trait.Snapshot.html
/// [`put`]: #method.put
/// [`remove`]: #method.remove
/// [`remove_by_prefix`]: #method.remove_by_prefix
/// [`Patch`]: type.Patch.html
/// [`into_patch`]: #method.into_patch
/// [`merge`]: trait.Database.html#tymethod.merge
/// [`checkpoint`]: #method.checkpoint
/// [`commit`]: #method.commit
/// [`rollback`]: #method.rollback
// FIXME: make &mut Fork "unwind safe"
pub struct Fork {
    snapshot: Box<Snapshot>,
    changes: Patch,
    changelog: Vec<(Vec<u8>, Option<Change>)>,
    logged: bool,
}

struct ForkIter<'a> {
    snapshot: Iter<'a>,
    changes: Peekable<Range<'a, Vec<u8>, Change>>,
}

#[derive(Debug, PartialEq, Eq)]
enum NextIterValue {
    Stored,
    Replaced,
    Inserted,
    Deleted,
    MissDeleted,
    Finished,
}

/// A trait that define a low-level storage backend.
///
/// The trait `Database` requires to implement traits `Send` and `Sync` and should not be borrowed
/// data, so you can use method [`clone`] to get the references to the database for concurrent
/// usage.
///
/// There is no way to directly interact with data in the database.
///
/// If you only need to read the data, you can create a [`Snapshot`] using method [`snapshot`][1].
/// Snapshots provide a read isolation, so you are guaranteed to work with consistent values even
/// if the data in the database changes between reads.
///
/// If you need to make any changes to the data, you need to create a [`Fork`] using method
/// [`fork`][2]. As well as `Snapshot`, `Fork` provides a read isolation and also allows you to create
/// a sequence of changes to the database that are specified as [`Patch`]. Later you can atomically
/// merge a patch into the database using method [`merge`].
///
/// [`clone`]: #tymethod.fork
/// [`Snapshot`]: trait.Snapshot.html
/// [1]: #tymethod.snapshot
/// [`Fork`]: struct.Fork.html
/// [2]: #method.fork
/// [`Patch`]: type.Patch.html
/// [`merge`]: #tymethod.merge
pub trait Database: Send + Sync + 'static {
    /// Creates a new reference to the database as `Box<Database>`.
    fn clone(&self) -> Box<Database>;

    /// Creates a new snapshot of the database from its current state.
    ///
    /// See [`Snapshot`] documentation for more.
    /// [`Snapshot`]: trait.Snapshot.html
    fn snapshot(&self) -> Box<Snapshot>;

    /// Creates a new fork of the database from its current state.
    ///
    /// See [`Fork`] documentation for more.
    /// [`Fork`]: struct.Fork.html
    fn fork(&self) -> Fork {
        Fork {
            snapshot: self.snapshot(),
            changes: Patch::new(),
            changelog: Vec::new(),
            logged: false,
        }
    }

    /// Atomically applies a sequence of patch changes to the database.
    ///
    /// # Errors
    /// If this method encounters any form of I/O or other error during merging, an error variant
    /// will be returned. If an error is returned then it must be guaranteed that no changes were
    /// applied.
    fn merge(&mut self, patch: Patch) -> Result<()>;
}

/// A trait that define a snapshot of storage backend.
///
/// `Snapshot` instance is immutable representation of storage state. It provides a read isolation,
/// so using snapshot you are guaranteed to work with consistent values even if the data in
/// the database changes between reads.
///
/// `Snapshot` provides all the necessary methods for reading data from the database, so `&Storage`
/// is used as a storage view for creating read-only indices representation.
// TODO: should Snapshot be Send or Sync?
pub trait Snapshot: 'static {
    /// Returns a value as raw vector of bytes corresponding to the specified key
    /// or `None` if not exists.
    fn get(&self, key: &[u8]) -> Option<Vec<u8>>;

    /// Returns `true` if the snapshot contains a value for the specified key.
    ///
    /// Default implementation tries to read the value using method [`get`].
    /// [`get`]: #tymethod.get
    fn contains(&self, key: &[u8]) -> bool {
        self.get(key).is_some()
    }

    /// Returns an iterator over the entries of the snapshot in ascending order starting from
    /// the specified key. The iterator element type is `(&[u8], &[u8])`.
    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a>;
}

/// A trait that define streaming iterator over storage view entries.
pub trait Iterator {
    /// Advances the iterator and returns the next key and value.
    fn next(&mut self) -> Option<(&[u8], &[u8])>;

    /// Returns references to the current key and value of the iterator.
    fn peek(&mut self) -> Option<(&[u8], &[u8])>;
}

impl Snapshot for Fork {
    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        match self.changes.get(key) {
            Some(change) => {
                match *change {
                    Change::Put(ref v) => Some(v.clone()),
                    Change::Delete => None,
                }
            }
            None => self.snapshot.get(key),
        }
    }

    fn contains(&self, key: &[u8]) -> bool {
        match self.changes.get(key) {
            Some(change) => {
                match *change {
                    Change::Put(..) => true,
                    Change::Delete => false,
                }
            }
            None => self.snapshot.contains(key),
        }
    }

    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a> {
        let range = (Included(from), Unbounded);
        Box::new(ForkIter {
                     snapshot: self.snapshot.iter(from),
                     changes: self.changes.range::<[u8], _>(range).peekable(),
                 })
    }
}

impl Fork {
    /// Creates a new checkpoint.
    ///
    /// # Panics
    /// Panics if another checkpoint was created before and it was not commited or rollbacked yet.
    pub fn checkpoint(&mut self) {
        if self.logged {
            panic!("call checkpoint before rollback or commit");
        }
        self.logged = true;
    }

    /// Finalizes all changes after the last checkpoint.
    ///
    /// # Panics
    /// Panics if checkpoint was not created before or last checkpoint is already commited or
    /// rollbacked.
    pub fn commit(&mut self) {
        if !self.logged {
            panic!("call commit before checkpoint");
        }
        self.changelog.clear();
        self.logged = false;
    }

    /// Rollbakcs all changes after the last checkpoint.
    ///
    /// # Panics
    /// Panics if checkpoint was not created before or last checkpoint is already commited or
    /// rollbacked.
    pub fn rollback(&mut self) {
        if !self.logged {
            panic!("call rollback before checkpoint");
        }
        for (k, c) in self.changelog.drain(..).rev() {
            match c {
                Some(change) => self.changes.insert(k, change),
                None => self.changes.remove(&k),
            };
        }
        self.logged = false;
    }

    /// Inserts the key-value pair into the fork.
    pub fn put(&mut self, key: Vec<u8>, value: Vec<u8>) {
        if self.logged {
            self.changelog
                .push((key.clone(), self.changes.insert(key, Change::Put(value))));
        } else {
            self.changes.insert(key, Change::Put(value));
        }
    }

    /// Removes the key from the fork.
    pub fn remove(&mut self, key: Vec<u8>) {
        if self.logged {
            self.changelog
                .push((key.clone(), self.changes.insert(key, Change::Delete)));
        } else {
            self.changes.insert(key, Change::Delete);
        }
    }

    /// Removes all keys started with specified prefix from the fork.
    pub fn remove_by_prefix(&mut self, prefix: &[u8]) {
        // Remove changes
        let keys = self.changes
                       .range::<[u8], _>((Included(prefix), Unbounded))
                       .map(|(k, ..)| k.to_vec())
                       .take_while(|k| k.starts_with(prefix))
                       .collect::<Vec<_>>();
        for k in keys {
            self.changes.remove(&k);
        }
        // Remove from storage
        let mut iter = self.snapshot.iter(prefix);
        while let Some((k, ..)) = iter.next() {
            if !k.starts_with(prefix) {
                return;
            }
            let change = self.changes.insert(k.to_vec(), Change::Delete);
            if self.logged {
                self.changelog.push((k.to_vec(), change));
            }
        }
    }

    /// Converts the fork into `Patch`.
    pub fn into_patch(self) -> Patch {
        self.changes
    }

    /// Merges patch from another fork to this fork.
    ///
    /// If both forks have changed the same data, this can lead to a non-consistent state. So this
    /// method is useful only if you are sure that forks interacted with different indices.
    ///
    /// # Panics
    /// Panics if checkpoint was created before and it was not commited or rollbacked yet.
    pub fn merge(&mut self, patch: Patch) {
        if self.logged {
            panic!("call merge before commit or rollback");
        }
        self.changes.extend(patch)
    }
}

impl AsRef<Snapshot> for Snapshot + 'static {
    fn as_ref(&self) -> &Snapshot {
        self
    }
}

impl AsRef<Snapshot> for Fork {
    fn as_ref(&self) -> &Snapshot {
        self
    }
}

impl ::std::fmt::Debug for Fork {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "Fork(..)")
    }
}

impl<'a> ForkIter<'a> {
    fn step(&mut self) -> NextIterValue {
        match self.changes.peek() {
            Some(&(k, change)) => {
                match self.snapshot.peek() {
                    Some((key, ..)) => {
                        match *change {
                            Change::Put(..) => {
                                match k[..].cmp(key) {
                                    Equal => Replaced,
                                    Less => Inserted,
                                    Greater => Stored,
                                }
                            }
                            Change::Delete => {
                                match k[..].cmp(key) {
                                    Equal => Deleted,
                                    Less => MissDeleted,
                                    Greater => Stored,
                                }
                            }
                        }
                    }
                    None => {
                        match *change {
                            Change::Put(..) => Inserted,
                            Change::Delete => MissDeleted,
                        }
                    }
                }
            }
            None => {
                match self.snapshot.peek() {
                    Some(..) => Stored,
                    None => Finished,
                }
            }
        }
    }
}

impl<'a> Iterator for ForkIter<'a> {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        loop {
            match self.step() {
                Stored => return self.snapshot.next(),
                Replaced => {
                    self.snapshot.next();
                    return self.changes
                               .next()
                               .map(|(key, change)| {
                                        (key.as_slice(),
                                         match *change {
                                             Change::Put(ref value) => value.as_slice(),
                                             Change::Delete => unreachable!(),
                                         })
                                    });
                }
                Inserted => {
                    return self.changes
                               .next()
                               .map(|(key, change)| {
                                        (key.as_slice(),
                                         match *change {
                                             Change::Put(ref value) => value.as_slice(),
                                             Change::Delete => unreachable!(),
                                         })
                                    })
                }
                Deleted => {
                    self.changes.next();
                    self.snapshot.next();
                }
                MissDeleted => {
                    self.changes.next();
                }
                Finished => return None,
            }
        }
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        loop {
            match self.step() {
                Stored => return self.snapshot.peek(),
                Replaced | Inserted => {
                    return self.changes
                               .peek()
                               .map(|&(key, change)| {
                                        (key.as_slice(),
                                         match *change {
                                             Change::Put(ref value) => value.as_slice(),
                                             Change::Delete => unreachable!(),
                                         })
                                    })
                }
                Deleted => {
                    self.changes.next();
                    self.snapshot.next();
                }
                MissDeleted => {
                    self.changes.next();
                }
                Finished => return None,
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::mem;
use libc::size_t;
use num_complex::Complex;
use fnv::FnvHashMap;

use super::PI;
use sitevector::SiteVector;
use blochfunc::{BlochFunc, BlochFuncSet};

// c compatible complex type for export to numpy at the end
#[repr(C)]
pub struct CComplex<T> {
    pub re: T,
    pub im: T
}

impl<T> CComplex<T> {
    pub fn from_num_complex(c: Complex<T>) -> CComplex<T> {
        let re = c.re;
        let im = c.im;
        CComplex { re, im }
    }
}

#[repr(C)]
pub struct Vector<T> {
    ptr: *const T,
    len: size_t
}

impl<T> Vector<T> {
    fn new(ptr: *const T, len: size_t) -> Vector<T> {
        Vector { ptr, len }
    }
}

#[repr(C)]
pub struct CoordMatrix<T> {
    data: Vector<T>,
    col: Vector<u32>,
    row: Vector<u32>
}

impl<T> CoordMatrix<T> {
    pub fn new(mut data: Vec<T>, mut col: Vec<u32>, mut row: Vec<u32>) -> CoordMatrix<T> {
        let data_ptr = data.as_mut_ptr();
        let data_len = data.len() as size_t;

        let col_ptr = col.as_mut_ptr();
        let col_len = col.len() as size_t;

        let row_ptr = row.as_mut_ptr();
        let row_len = row.len() as size_t;

        mem::forget(data);
        mem::forget(col);
        mem::forget(row);
        let data = Vector::new(data_ptr, data_len);
        let col = Vector::new(col_ptr, col_len);
        let row = Vector::new(row_ptr, row_len);
        CoordMatrix { data, col, row }
    }
}

pub struct InteractingSites {
    pub first: (Vec<u32>, Vec<u32>),
    pub second: (Vec<u32>, Vec<u32>),
    pub third: (Vec<u32>, Vec<u32>)
}

pub fn translate_x(dec: u32, nx: u32, ny: u32) -> u32 {
    let n = (0..ny).map(|x| x * nx).collect::<Vec<u32>>();
    let s = n.iter()
        .map(|&x| dec % 2_u32.pow(x + nx) / 2_u32.pow(x))
        .map(|x| (x * 2_u32) % 2_u32.pow(nx) + x / 2_u32.pow(nx - 1));

    n.iter().map(|&x| 2_u32.pow(x))
        .zip(s)
        .map(|(a, b)| a * b)  // basically a dot product here
        .sum()
}

pub fn translate_y(dec: u32, nx: u32, ny: u32) -> u32 {
    let xdim = 2_u32.pow(nx);
    let pred_totdim = 2_u32.pow(nx * (ny - 1));
    let tail = dec % xdim;
    dec / xdim + tail * pred_totdim
}

pub fn exchange_spin_flips(dec: u32, s1: u32, s2: u32) -> (bool, bool) {
    let updown = (dec | s1 == dec) && (dec | s2 != dec);
    let downup = (dec | s1 != dec) && (dec | s2 == dec);
    (updown, downup)
}

pub fn repeated_spins(dec: u32, s1: u32, s2: u32) -> (bool, bool) {
    let upup = (dec | s1 == dec) && (dec | s2 == dec);
    let downdown = (dec | s1 != dec) && (dec | s2 != dec);
    (upup, downdown)
}

pub fn generate_bonds(nx: u32, ny: u32) -> Vec<Vec<Vec<SiteVector>>> {
    let n = nx * ny;
    let mut vec = SiteVector::new((0, 0), nx, ny);
    let mut bonds_by_range = vec![Vec::new(); 3];
    for _ in 0..n {
        let nearest_neighbor = vec.nearest_neighboring_sites(false);
        let second_neighbor = vec.second_neighboring_sites(false);
        let third_neighbor = vec.third_neighboring_sites(false);
        let neighbors = vec![nearest_neighbor, second_neighbor, third_neighbor];
        for (leap, bonds) in bonds_by_range.iter_mut().enumerate() {
            for n in neighbors[leap].iter() {
                let mut bond = vec![vec.clone(), n.clone()];
                bond.sort();
                bonds.push(bond);
            }
        }
        vec = vec.next_site();
    }
    bonds_by_range
}

pub fn gamma(nx: u32, ny: u32, s1: u32, s2: u32) -> Complex<f64> {
    let m = (s1 as f64).log2().round() as u32;
    let n = (s2 as f64).log2().round() as u32;
    let vec1 = SiteVector::from_index(m, nx, ny);
    let vec2 = SiteVector::from_index(n, nx, ny );
    let ang = vec1.angle_with(&vec2);

    Complex::from_polar(&1.0, &ang)
}

pub fn interacting_sites(nx: u32, ny: u32, l: u32) -> (Vec<u32>, Vec<u32>) {
    let mut site1 = Vec::new();
    let mut site2 = Vec::new();
    let bonds_by_range = generate_bonds(nx, ny);
    let bonds = &bonds_by_range[l as usize - 1];
    for bond in bonds.iter() {
        site1.push(bond[0].lattice_index());
        site2.push(bond[1].lattice_index());
    }

    (
    site1.into_iter().map(|x| 2_u32.pow(x)).collect::<Vec<_>>(),
    site2.into_iter().map(|x| 2_u32.pow(x)).collect::<Vec<_>>(),
    )
}

pub fn bloch_states<'a>(nx: u32, ny: u32, kx: u32, ky: u32) -> BlochFuncSet {
    let n = nx * ny;
    let mut sieve = vec![true; 2_usize.pow(n)];
    let mut bfuncs: Vec<BlochFunc> = Vec::new();
    let phase = |i, j| {
        let r = 1.;
        let ang1 = 2. * PI * (i * kx) as f64 / nx as f64;
        let ang2 = 2. * PI * (j * ky) as f64 / ny as f64;
        Complex::from_polar(&r, &(ang1 + ang2))
    };

    for dec in 0..2_usize.pow(n) {
        if sieve[dec]
        {   // if the corresponding entry of dec in "sieve" is not false,
            // we find all translations of dec and put them in a BlochFunc
            // then mark all corresponding entries in "sieve" as false.

            // "decs" is a hashtable that holds vectors whose entries
            // correspond to Bloch function constituent configurations which
            // are mapped to single decimals that represent the leading states.
            let mut decs: FnvHashMap<u32, Complex<f64>> = FnvHashMap::default();
            // "new_dec" represents the configuration we are currently iterating
            // over.
            let mut new_dec = dec as u32;
            for j in 0..ny {
                for i in 0..nx {
                    sieve[new_dec as usize] = false;
                    let new_p = match decs.get(&new_dec) {
                        Some(&p) => p + phase(i, j),
                        None     => phase(i, j)
                    };
                    decs.insert(new_dec, new_p);
                    new_dec = translate_x(new_dec, nx, ny);
                }
                new_dec = translate_y(new_dec, nx, ny);
            }

            let lead = dec as u32;
            let norm = decs.values()
                .into_iter()
                .map(|&x| x.norm_sqr())
                .sum::<f64>()
                .sqrt();

            if norm > 1e-8 {
                let mut bfunc = BlochFunc { lead, decs, norm };
                bfuncs.push(bfunc);
            }
        }
    }

    let mut table = BlochFuncSet::create(bfuncs);
    table.sort();
    table
}

pub fn find_leading_state<'a>(dec: u32,
                           hashtable: &'a FnvHashMap<&u32, &BlochFunc>
                           ) -> Option<(&'a BlochFunc, Complex<f64>)> {

    match hashtable.get(&dec) {
        None => None,
        Some(&cntd_state) =>
            match cntd_state.decs.get(&dec) {
                None     => None,
                Some(&p) => {
                    let mut phase = p.conj();
                    phase /= phase.norm();
                    Some((cntd_state, phase))
                },
            }
    }
}

pub fn gen_ind_dec_conv_dicts<'a>(bfuncs: &'a BlochFuncSet)
    -> (FnvHashMap<u32, &'a BlochFunc>, FnvHashMap<u32, u32>) {
    let nonzero_states = bfuncs.iter()
        .filter(|s| s.norm > 1e-8)
        .collect::<Vec<_>>();
    let dec = nonzero_states.iter()
        .map(|x| x.lead)
        .collect::<Vec<_>>();
    let nstates = dec.len();
    let inds = (0..nstates as u32).collect::<Vec<u32>>();

    // build the hashtables
    let dec_to_ind = dec.into_iter()
        .zip(inds.clone())
        .collect::<FnvHashMap<u32, u32>>();
    let ind_to_dec = inds.into_iter()
        .zip(nonzero_states)
        .collect::<FnvHashMap<u32, &BlochFunc>>();

    (ind_to_dec, dec_to_ind)
}

pub fn coeff(orig_state: &BlochFunc, cntd_state: &BlochFunc) -> f64 {
    cntd_state.norm / orig_state.norm
}
<commit_msg>Removed useless code<commit_after>use std::mem;
use libc::size_t;
use num_complex::Complex;
use fnv::FnvHashMap;

use super::PI;
use sitevector::SiteVector;
use blochfunc::{BlochFunc, BlochFuncSet};

// c compatible complex type for export to numpy at the end
#[repr(C)]
pub struct CComplex<T> {
    pub re: T,
    pub im: T
}

impl<T> CComplex<T> {
    pub fn from_num_complex(c: Complex<T>) -> CComplex<T> {
        let re = c.re;
        let im = c.im;
        CComplex { re, im }
    }
}

#[repr(C)]
pub struct Vector<T> {
    ptr: *const T,
    len: size_t
}

impl<T> Vector<T> {
    fn new(ptr: *const T, len: size_t) -> Vector<T> {
        Vector { ptr, len }
    }
}

#[repr(C)]
pub struct CoordMatrix<T> {
    data: Vector<T>,
    col: Vector<u32>,
    row: Vector<u32>
}

impl<T> CoordMatrix<T> {
    pub fn new(mut data: Vec<T>, mut col: Vec<u32>, mut row: Vec<u32>) -> CoordMatrix<T> {
        let data_ptr = data.as_mut_ptr();
        let data_len = data.len() as size_t;

        let col_ptr = col.as_mut_ptr();
        let col_len = col.len() as size_t;

        let row_ptr = row.as_mut_ptr();
        let row_len = row.len() as size_t;

        mem::forget(data);
        mem::forget(col);
        mem::forget(row);
        let data = Vector::new(data_ptr, data_len);
        let col = Vector::new(col_ptr, col_len);
        let row = Vector::new(row_ptr, row_len);
        CoordMatrix { data, col, row }
    }
}

pub struct InteractingSites {
    pub first: (Vec<u32>, Vec<u32>),
    pub second: (Vec<u32>, Vec<u32>),
    pub third: (Vec<u32>, Vec<u32>)
}

pub fn translate_x(dec: u32, nx: u32, ny: u32) -> u32 {
    let n = (0..ny).map(|x| x * nx).collect::<Vec<u32>>();
    let s = n.iter()
        .map(|&x| dec % 2_u32.pow(x + nx) / 2_u32.pow(x))
        .map(|x| (x * 2_u32) % 2_u32.pow(nx) + x / 2_u32.pow(nx - 1));

    n.iter().map(|&x| 2_u32.pow(x))
        .zip(s)
        .map(|(a, b)| a * b)  // basically a dot product here
        .sum()
}

pub fn translate_y(dec: u32, nx: u32, ny: u32) -> u32 {
    let xdim = 2_u32.pow(nx);
    let pred_totdim = 2_u32.pow(nx * (ny - 1));
    let tail = dec % xdim;
    dec / xdim + tail * pred_totdim
}

pub fn exchange_spin_flips(dec: u32, s1: u32, s2: u32) -> (bool, bool) {
    let updown = (dec | s1 == dec) && (dec | s2 != dec);
    let downup = (dec | s1 != dec) && (dec | s2 == dec);
    (updown, downup)
}

pub fn repeated_spins(dec: u32, s1: u32, s2: u32) -> (bool, bool) {
    let upup = (dec | s1 == dec) && (dec | s2 == dec);
    let downdown = (dec | s1 != dec) && (dec | s2 != dec);
    (upup, downdown)
}

pub fn generate_bonds(nx: u32, ny: u32) -> Vec<Vec<Vec<SiteVector>>> {
    let n = nx * ny;
    let mut vec = SiteVector::new((0, 0), nx, ny);
    let mut bonds_by_range = vec![Vec::new(); 3];
    for _ in 0..n {
        let nearest_neighbor = vec.nearest_neighboring_sites(false);
        let second_neighbor = vec.second_neighboring_sites(false);
        let third_neighbor = vec.third_neighboring_sites(false);
        let neighbors = vec![nearest_neighbor, second_neighbor, third_neighbor];
        for (leap, bonds) in bonds_by_range.iter_mut().enumerate() {
            for n in neighbors[leap].iter() {
                let mut bond = vec![vec.clone(), n.clone()];
                bond.sort();
                bonds.push(bond);
            }
        }
        vec = vec.next_site();
    }
    bonds_by_range
}

pub fn gamma(nx: u32, ny: u32, s1: u32, s2: u32) -> Complex<f64> {
    let m = (s1 as f64).log2().round() as u32;
    let n = (s2 as f64).log2().round() as u32;
    let vec1 = SiteVector::from_index(m, nx, ny);
    let vec2 = SiteVector::from_index(n, nx, ny );
    let ang = vec1.angle_with(&vec2);

    Complex::from_polar(&1.0, &ang)
}

pub fn interacting_sites(nx: u32, ny: u32, l: u32) -> (Vec<u32>, Vec<u32>) {
    let mut site1 = Vec::new();
    let mut site2 = Vec::new();
    let bonds_by_range = generate_bonds(nx, ny);
    let bonds = &bonds_by_range[l as usize - 1];
    for bond in bonds.iter() {
        site1.push(bond[0].lattice_index());
        site2.push(bond[1].lattice_index());
    }

    (
    site1.into_iter().map(|x| 2_u32.pow(x)).collect::<Vec<_>>(),
    site2.into_iter().map(|x| 2_u32.pow(x)).collect::<Vec<_>>(),
    )
}

pub fn bloch_states<'a>(nx: u32, ny: u32, kx: u32, ky: u32) -> BlochFuncSet {
    let n = nx * ny;
    let mut sieve = vec![true; 2_usize.pow(n)];
    let mut bfuncs: Vec<BlochFunc> = Vec::new();
    let phase = |i, j| {
        let r = 1.;
        let ang1 = 2. * PI * (i * kx) as f64 / nx as f64;
        let ang2 = 2. * PI * (j * ky) as f64 / ny as f64;
        Complex::from_polar(&r, &(ang1 + ang2))
    };

    for dec in 0..2_usize.pow(n) {
        if sieve[dec]
        {   // if the corresponding entry of dec in "sieve" is not false,
            // we find all translations of dec and put them in a BlochFunc
            // then mark all corresponding entries in "sieve" as false.

            // "decs" is a hashtable that holds vectors whose entries
            // correspond to Bloch function constituent configurations which
            // are mapped to single decimals that represent the leading states.
            let mut decs: FnvHashMap<u32, Complex<f64>> = FnvHashMap::default();
            // "new_dec" represents the configuration we are currently iterating
            // over.
            let mut new_dec = dec as u32;
            for j in 0..ny {
                for i in 0..nx {
                    sieve[new_dec as usize] = false;
                    let new_p = match decs.get(&new_dec) {
                        Some(&p) => p + phase(i, j),
                        None     => phase(i, j)
                    };
                    decs.insert(new_dec, new_p);
                    new_dec = translate_x(new_dec, nx, ny);
                }
                new_dec = translate_y(new_dec, nx, ny);
            }

            let lead = dec as u32;
            let norm = decs.values()
                .into_iter()
                .map(|&x| x.norm_sqr())
                .sum::<f64>()
                .sqrt();

            if norm > 1e-8 {
                let mut bfunc = BlochFunc { lead, decs, norm };
                bfuncs.push(bfunc);
            }
        }
    }

    let mut table = BlochFuncSet::create(bfuncs);
    table.sort();
    table
}

pub fn find_leading_state<'a>(dec: u32,
                           hashtable: &'a FnvHashMap<&u32, &BlochFunc>
                           ) -> Option<(&'a BlochFunc, Complex<f64>)> {

    match hashtable.get(&dec) {
        None => None,
        Some(&cntd_state) =>
            match cntd_state.decs.get(&dec) {
                None     => None,
                Some(&p) => {
                    let mut phase = p.conj();
                    phase /= phase.norm();
                    Some((cntd_state, phase))
                },
            }
    }
}

pub fn gen_ind_dec_conv_dicts<'a>(bfuncs: &'a BlochFuncSet)
    -> (FnvHashMap<u32, &'a BlochFunc>, FnvHashMap<u32, u32>) {
    let dec = bfuncs.iter()
        .map(|x| x.lead)
        .collect::<Vec<_>>();
    let nstates = dec.len();
    let inds = (0..nstates as u32).collect::<Vec<u32>>();

    // build the hashtables
    let dec_to_ind = dec.into_iter()
        .zip(inds.clone())
        .collect::<FnvHashMap<u32, u32>>();
    let ind_to_dec = inds.into_iter()
        .zip(bfuncs.iter())
        .collect::<FnvHashMap<u32, &BlochFunc>>();

    (ind_to_dec, dec_to_ind)
}

pub fn coeff(orig_state: &BlochFunc, cntd_state: &BlochFunc) -> f64 {
    cntd_state.norm / orig_state.norm
}
<|endoftext|>


<commit_before>use rustc::traits::query::CanonicalPredicateGoal;
use rustc::traits::{
    EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode,
};
use rustc::ty::query::Providers;
use rustc::ty::{ParamEnvAnd, TyCtxt};
use syntax::source_map::DUMMY_SP;

crate fn provide(p: &mut Providers<'_>) {
    *p = Providers {
        evaluate_obligation,
        ..*p
    };
}

fn evaluate_obligation<'tcx>(
    tcx: TyCtxt<'tcx>,
    canonical_goal: CanonicalPredicateGoal<'tcx>,
) -> Result<EvaluationResult, OverflowError> {
    tcx.infer_ctxt().enter_with_canonical(
        DUMMY_SP,
        &canonical_goal,
        |ref infcx, goal, _canonical_inference_vars| {
            let ParamEnvAnd {
                param_env,
                value: predicate,
            } = goal;

            let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
            let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);

            selcx.evaluate_root_obligation(&obligation)
        },
    )
}
<commit_msg>add `debug!` to evaluate_obligation<commit_after>use rustc::traits::query::CanonicalPredicateGoal;
use rustc::traits::{
    EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode,
};
use rustc::ty::query::Providers;
use rustc::ty::{ParamEnvAnd, TyCtxt};
use syntax::source_map::DUMMY_SP;

crate fn provide(p: &mut Providers<'_>) {
    *p = Providers {
        evaluate_obligation,
        ..*p
    };
}

fn evaluate_obligation<'tcx>(
    tcx: TyCtxt<'tcx>,
    canonical_goal: CanonicalPredicateGoal<'tcx>,
) -> Result<EvaluationResult, OverflowError> {
    debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal);
    tcx.infer_ctxt().enter_with_canonical(
        DUMMY_SP,
        &canonical_goal,
        |ref infcx, goal, _canonical_inference_vars| {
            debug!("evaluate_obligation: goal={:#?}", goal);
            let ParamEnvAnd {
                param_env,
                value: predicate,
            } = goal;

            let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
            let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);

            selcx.evaluate_root_obligation(&obligation)
        },
    )
}
<|endoftext|>


<commit_before>//! Running of programs.

use parser::Instruction;
use parser::Instructions;
use std;

///
/// A runner of programs.
///
#[derive(Default)]
pub struct Runner {
    /// Program to be run.
    prog: Instructions,
    /// A potentially infinite number of data cells.
    data: Vec<u8>,
    /// Instruction pointer (index).
    ip: usize,
    /// Data-cell pointer (index).
    dp: usize,
}

impl Runner {
    ///
    /// Constructs a new runner.
    ///
    pub fn new() -> Self {
        Runner::default()
    }

    ///
    /// Runs the given program.
    ///
    /// # Arguments
    ///
    /// * `prog` - Program to be run.
    /// * `input` - Input for the program.
    /// * `output` - Output for the program.
    ///
    pub fn run(&mut self,
               prog: Instructions,
               mut input: &mut std::io::Read,
               mut output: &mut std::io::Write)
               -> Result<(), String> {
        self.prog = prog;
        self.data.clear();
        self.ip = 0;
        self.dp = 0;

        while !self.is_prog_end() {
            try!(self.run_instruction(&mut input, &mut output));
        }

        Ok(())
    }

    fn is_prog_end(&self) -> bool {
        self.ip >= self.prog.len()
    }

    fn run_instruction(&mut self,
                       mut input: &mut std::io::Read,
                       mut output: &mut std::io::Write)
                       -> Result<(), String> {
        match self.prog[self.ip] {
            Instruction::Next => {
                try!(self.ensure_can_increment_dp_by_one());
                self.dp += 1;
            }
            Instruction::Prev => {
                try!(self.ensure_can_decrement_dp_by_one());
                self.dp -= 1;
            }
            Instruction::Inc => {
                let value = self.load_value();
                self.store_value(value.wrapping_add(1));
            }
            Instruction::Dec => {
                let value = self.load_value();
                self.store_value(value.wrapping_sub(1));
            }
            Instruction::Read => {
                let value = try!(self.read_value(&mut input));
                self.store_value(value);
            }
            Instruction::Write => {
                let value = self.load_value();
                try!(self.write_value(&mut output, value));
            }
            Instruction::LoopStart(loop_end_ip) => {
                if self.is_current_cell_zero() {
                    self.ip = loop_end_ip;
                }
            }
            Instruction::LoopEnd(loop_start_ip) => {
                if !self.is_current_cell_zero() {
                    self.ip = loop_start_ip;
                }
            }
        }
        self.ip += 1;
        Ok(())
    }

    fn load_value(&mut self) -> u8 {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp]
    }

    fn store_value(&mut self, value: u8) {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp] = value;
    }

    fn read_value(&mut self, mut input: &mut std::io::Read) -> Result<u8, String> {
        let mut buf = [0u8];
        match input.read_exact(&mut buf) {
            Err(err) => match err.kind() {
                std::io::ErrorKind::UnexpectedEof => {
                    // There are multiple ways of dealing with EOF (see
                    // https://en.wikipedia.org/wiki/Brainfuck#End-of-file_behavior).
                    // We have chosen to return the value of the current cell,
                    // i.e. Instruction::Read will not change the value of the
                    // current cell.
                    Ok(self.load_value())
                }
                _ => Err(format!("reading of a value failed (reason: {:?})", err.kind())),
            },
            Ok(_) => Ok(buf[0]),
        }
    }

    fn write_value(&self, mut output: &mut std::io::Write, value: u8) -> Result<(), String> {
        match output.write(&[value]) {
            Err(err) => Err(
                format!("writing of a value failed (reason: {})", err)
            ),
            Ok(_) => Ok(()),
        }
    }

    fn is_current_cell_zero(&mut self) -> bool {
        self.load_value() == 0
    }

    fn ensure_current_cell_is_accessible(&mut self) {
        let cell_count = self.data.len();
        if self.dp >= cell_count {
            for _ in 0..(self.dp - cell_count + 1) {
                self.data.push(0);
            }
        }
    }

    fn ensure_can_increment_dp_by_one(&self) -> Result<(), String> {
        match self.dp {
            std::usize::MAX => Err(
                "cannot increment the data pointer because it is MAX".to_string()
            ),
            _ => Ok(()),
        }
    }

    fn ensure_can_decrement_dp_by_one(&self) -> Result<(), String> {
        match self.dp {
            0 => Err("cannot decrement the data pointer because it is 0".to_string()),
            _ => Ok(()),
        }
    }
}

///
/// Runs the given program.
///
/// # Arguments
///
/// * `prog` - Program to be run.
/// * `input` - Input for the program.
/// * `output` - Output for the program.
///
pub fn run(prog: Instructions,
           mut input: &mut std::io::Read,
           mut output: &mut std::io::Write)
           -> Result<(), String> {
    let mut runner = Runner::new();
    runner.run(prog, &mut input, &mut output)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std;
    use parser::Instruction;
    use parser::Instructions;

    fn run_and_get_output(prog: Instructions,
                          input: &[u8])
                          -> Result<Vec<u8>, String> {
        let mut output = Vec::new();
        match {
            let mut input_reader = std::io::BufReader::new(input.as_ref());
            let mut output_writer = std::io::BufWriter::new(&mut output);
            run(prog, &mut input_reader, &mut output_writer)
        } {
            Ok(_) => Ok(output),
            Err(err) => Err(err),
        }
    }

    fn assert_run_writes_correct_output(prog: Instructions,
                                        input: &[u8],
                                        expected_output: &[u8]) {
        let output = run_and_get_output(prog, input).unwrap();
        assert_eq!(output, expected_output);
    }

    fn assert_run_returns_error(prog: Instructions,
                         input: &[u8]) {
        let result = run_and_get_output(prog, input);
        assert!(result.is_err());
    }

    #[test]
    fn test_run_does_nothing_when_program_has_no_instructions() {
        assert_run_writes_correct_output(
            vec![],
            &[],
            &[]
        );
    }

    #[test]
    fn test_run_can_read_from_input_and_write_to_output() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Write
            ],
            &[1],
            &[1]
        );
    }

    #[test]
    fn test_read_does_not_alter_cell_value_when_at_end_of_file() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Inc,
                Instruction::Read,
                Instruction::Write
            ],
            &[],
            &[1]
        );
    }

    #[test]
    fn test_run_can_increment_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Inc,
                Instruction::Write,
            ],
            &[1],
            &[2]
        );
    }

    #[test]
    fn test_run_can_decrement_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Dec,
                Instruction::Write,
            ],
            &[1],
            &[0]
        );
    }

    #[test]
    fn test_run_can_move_between_cells() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Next,
                Instruction::Read,
                Instruction::Next,
                Instruction::Prev,
                Instruction::Write,
                Instruction::Prev,
                Instruction::Write,
            ],
            &[1, 2],
            &[2, 1]
        );
    }

    #[test]
    fn test_run_can_loop() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::LoopStart(6),
                Instruction::Dec,
                Instruction::Next,
                Instruction::Inc,
                Instruction::Prev,
                Instruction::LoopEnd(1),
                Instruction::Write,
                Instruction::Next,
                Instruction::Write
            ],
            &[2],
            &[0, 2]
        );
    }

    #[test]
    fn test_copies_input_to_output() {
        assert_run_writes_correct_output(
            vec![
                // Read the whole input:
                Instruction::Next,
                Instruction::Inc,
                Instruction::LoopStart(5),
                Instruction::Next,
                Instruction::Read,
                Instruction::LoopEnd(2),
                // Rewind to the beginning:
                Instruction::Prev,
                Instruction::LoopStart(9),
                Instruction::Prev,
                Instruction::LoopEnd(7),
                // Write the whole input:
                Instruction::Next,
                Instruction::Next,
                Instruction::LoopStart(15),
                Instruction::Write,
                Instruction::Next,
                Instruction::LoopEnd(12)
            ],
            &[4, 3, 1, 5],
            &[4, 3, 1, 5]
        );
    }

    #[test]
    fn test_returns_error_when_underflowing_data_pointer() {
        assert_run_returns_error(vec![Instruction::Prev], &[]);
    }
}
<commit_msg>Refactor the reading and writing of values.<commit_after>//! Running of programs.

use parser::Instruction;
use parser::Instructions;
use std;

///
/// A runner of programs.
///
#[derive(Default)]
pub struct Runner {
    /// Program to be run.
    prog: Instructions,
    /// A potentially infinite number of data cells.
    data: Vec<u8>,
    /// Instruction pointer (index).
    ip: usize,
    /// Data-cell pointer (index).
    dp: usize,
}

impl Runner {
    ///
    /// Constructs a new runner.
    ///
    pub fn new() -> Self {
        Runner::default()
    }

    ///
    /// Runs the given program.
    ///
    /// # Arguments
    ///
    /// * `prog` - Program to be run.
    /// * `input` - Input for the program.
    /// * `output` - Output for the program.
    ///
    pub fn run(&mut self,
               prog: Instructions,
               mut input: &mut std::io::Read,
               mut output: &mut std::io::Write)
               -> Result<(), String> {
        self.prog = prog;
        self.data.clear();
        self.ip = 0;
        self.dp = 0;

        while !self.is_prog_end() {
            try!(self.run_instruction(&mut input, &mut output));
        }

        Ok(())
    }

    fn is_prog_end(&self) -> bool {
        self.ip >= self.prog.len()
    }

    fn run_instruction(&mut self,
                       mut input: &mut std::io::Read,
                       mut output: &mut std::io::Write)
                       -> Result<(), String> {
        match self.prog[self.ip] {
            Instruction::Next => {
                try!(self.ensure_can_increment_dp_by_one());
                self.dp += 1;
            }
            Instruction::Prev => {
                try!(self.ensure_can_decrement_dp_by_one());
                self.dp -= 1;
            }
            Instruction::Inc => {
                let value = self.load_value();
                self.store_value(value.wrapping_add(1));
            }
            Instruction::Dec => {
                let value = self.load_value();
                self.store_value(value.wrapping_sub(1));
            }
            Instruction::Read => {
                try!(self.read_value(&mut input));
            }
            Instruction::Write => {
                try!(self.write_value(&mut output));
            }
            Instruction::LoopStart(loop_end_ip) => {
                if self.is_current_cell_zero() {
                    self.ip = loop_end_ip;
                }
            }
            Instruction::LoopEnd(loop_start_ip) => {
                if !self.is_current_cell_zero() {
                    self.ip = loop_start_ip;
                }
            }
        }
        self.ip += 1;
        Ok(())
    }

    fn load_value(&mut self) -> u8 {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp]
    }

    fn store_value(&mut self, value: u8) {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp] = value;
    }

    fn read_value(&mut self, mut input: &mut std::io::Read) -> Result<(), String> {
        let mut buf = [0u8];
        match input.read_exact(&mut buf) {
            Err(err) => match err.kind() {
                std::io::ErrorKind::UnexpectedEof => {
                    // There are multiple ways of dealing with EOF (see
                    // https://en.wikipedia.org/wiki/Brainfuck#End-of-file_behavior).
                    // We have chosen to leave the current cell unchanged.
                    Ok(())
                },
                _ => Err(format!("reading of a value failed (reason: {:?})", err.kind())),
            },
            Ok(_) => {
                self.store_value(buf[0]);
                Ok(())
            }
        }
    }

    fn write_value(&mut self, mut output: &mut std::io::Write) -> Result<(), String> {
        let value = self.load_value();
        match output.write(&[value]) {
            Err(err) => Err(
                format!("writing of a value failed (reason: {})", err)
            ),
            Ok(_) => Ok(()),
        }
    }

    fn is_current_cell_zero(&mut self) -> bool {
        self.load_value() == 0
    }

    fn ensure_current_cell_is_accessible(&mut self) {
        let cell_count = self.data.len();
        if self.dp >= cell_count {
            for _ in 0..(self.dp - cell_count + 1) {
                self.data.push(0);
            }
        }
    }

    fn ensure_can_increment_dp_by_one(&self) -> Result<(), String> {
        match self.dp {
            std::usize::MAX => Err(
                "cannot increment the data pointer because it is MAX".to_string()
            ),
            _ => Ok(()),
        }
    }

    fn ensure_can_decrement_dp_by_one(&self) -> Result<(), String> {
        match self.dp {
            0 => Err("cannot decrement the data pointer because it is 0".to_string()),
            _ => Ok(()),
        }
    }
}

///
/// Runs the given program.
///
/// # Arguments
///
/// * `prog` - Program to be run.
/// * `input` - Input for the program.
/// * `output` - Output for the program.
///
pub fn run(prog: Instructions,
           mut input: &mut std::io::Read,
           mut output: &mut std::io::Write)
           -> Result<(), String> {
    let mut runner = Runner::new();
    runner.run(prog, &mut input, &mut output)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std;
    use parser::Instruction;
    use parser::Instructions;

    fn run_and_get_output(prog: Instructions,
                          input: &[u8])
                          -> Result<Vec<u8>, String> {
        let mut output = Vec::new();
        match {
            let mut input_reader = std::io::BufReader::new(input.as_ref());
            let mut output_writer = std::io::BufWriter::new(&mut output);
            run(prog, &mut input_reader, &mut output_writer)
        } {
            Ok(_) => Ok(output),
            Err(err) => Err(err),
        }
    }

    fn assert_run_writes_correct_output(prog: Instructions,
                                        input: &[u8],
                                        expected_output: &[u8]) {
        let output = run_and_get_output(prog, input).unwrap();
        assert_eq!(output, expected_output);
    }

    fn assert_run_returns_error(prog: Instructions,
                         input: &[u8]) {
        let result = run_and_get_output(prog, input);
        assert!(result.is_err());
    }

    #[test]
    fn test_run_does_nothing_when_program_has_no_instructions() {
        assert_run_writes_correct_output(
            vec![],
            &[],
            &[]
        );
    }

    #[test]
    fn test_run_can_read_from_input_and_write_to_output() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Write
            ],
            &[1],
            &[1]
        );
    }

    #[test]
    fn test_read_does_not_alter_cell_value_when_at_end_of_file() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Inc,
                Instruction::Read,
                Instruction::Write
            ],
            &[],
            &[1]
        );
    }

    #[test]
    fn test_run_can_increment_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Inc,
                Instruction::Write,
            ],
            &[1],
            &[2]
        );
    }

    #[test]
    fn test_run_can_decrement_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Dec,
                Instruction::Write,
            ],
            &[1],
            &[0]
        );
    }

    #[test]
    fn test_run_can_move_between_cells() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Next,
                Instruction::Read,
                Instruction::Next,
                Instruction::Prev,
                Instruction::Write,
                Instruction::Prev,
                Instruction::Write,
            ],
            &[1, 2],
            &[2, 1]
        );
    }

    #[test]
    fn test_run_can_loop() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::LoopStart(6),
                Instruction::Dec,
                Instruction::Next,
                Instruction::Inc,
                Instruction::Prev,
                Instruction::LoopEnd(1),
                Instruction::Write,
                Instruction::Next,
                Instruction::Write
            ],
            &[2],
            &[0, 2]
        );
    }

    #[test]
    fn test_copies_input_to_output() {
        assert_run_writes_correct_output(
            vec![
                // Read the whole input:
                Instruction::Next,
                Instruction::Inc,
                Instruction::LoopStart(5),
                Instruction::Next,
                Instruction::Read,
                Instruction::LoopEnd(2),
                // Rewind to the beginning:
                Instruction::Prev,
                Instruction::LoopStart(9),
                Instruction::Prev,
                Instruction::LoopEnd(7),
                // Write the whole input:
                Instruction::Next,
                Instruction::Next,
                Instruction::LoopStart(15),
                Instruction::Write,
                Instruction::Next,
                Instruction::LoopEnd(12)
            ],
            &[4, 3, 1, 5],
            &[4, 3, 1, 5]
        );
    }

    #[test]
    fn test_returns_error_when_underflowing_data_pointer() {
        assert_run_returns_error(vec![Instruction::Prev], &[]);
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate rustc_serialize;
extern crate rusqlite;
extern crate jmap;
extern crate time;

#[macro_use]
extern crate log;

mod logger;
mod db;
mod util;
mod record;

use std::default::Default;
use std::io::{Read, Write, ErrorKind};

use std::fs::File;

use hyper::server::{Request, Response};
use hyper::method::Method;
use hyper::method::Method::{Post, Get, Head};
use hyper::status::StatusCode;
use hyper::uri::RequestUri::AbsolutePath;
use hyper::header;

use rustc_serialize::json::{Json,ToJson};

use jmap::parse::FromJson;
use jmap::method::{RequestBatch, ResponseBatch, ResponseMethod};
use jmap::method::RequestMethod::*;
use jmap::method::ResponseMethod::*;

use util::RequestContext;
use record::RecordHandler;
use db::Db;

struct StatusBody {
    code: StatusCode,
    body: Option<Vec<u8>>
}
impl StatusBody {
    fn new(code: StatusCode, body: Option<Vec<u8>>) -> StatusBody {
        StatusBody { code: code, body: body }
    }
}

macro_rules! make_crud_method_dispatcher {
    ($method: expr, $rmethods: expr, $r: expr,
     $($ty: ty { $get: ident => $rget: ident, $set: ident => $rset: ident, $getup: ident => $rgetup: ident }),*) => {
        $rmethods = match $method {
            $(
                $get(args, id)
                    => vec!($r.get_records(&args).map(|a| $rget(a, id.clone())).unwrap_or_else(|e| ResponseError(e, id.clone()))),
                $set(args, id)
                    => vec!($r.set_records(&args).map(|a| $rset(a, id.clone())).unwrap_or_else(|e| ResponseError(e, id.clone()))),
                $getup(args, id) => $r.get_record_updates(&args).map(|a| {
                    match a {
                        (a, Some(b)) => vec!($rgetup(a, id.clone()), $rget(b, id.clone())),
                        (a, _)       => vec!($rgetup(a, id.clone())),
                    }
                }).unwrap_or_else(|e| vec!(ResponseError(e, id.clone()))),
            )*
            RequestError(args, id) => vec!(ResponseError(args, id)),
        };
    }
}

fn jmap_handler(mut req: Request) -> StatusBody {

    match Json::from_reader(&mut req) {
        Ok(j) => match RequestBatch::from_json(&j) {
            Ok(b) => {
                let mut rbatch: ResponseBatch = ResponseBatch::default();

                let r = RequestContext {
                    userid: 1, // XXX get userid from auth
                    db: Db::open().unwrap(),
                };

                for method in b.0.into_iter() {
                    let rmethods: Vec<ResponseMethod>;
                    make_crud_method_dispatcher!(method, rmethods, r,
                        Calendar {
                            GetCalendars       => Calendars,
                            SetCalendars       => CalendarsSet,
                            GetCalendarUpdates => CalendarUpdates
                        },
                        CalendarEvent {
                            GetCalendarEvents       => CalendarEvents,
                            SetCalendarEvents       => CalendarEventsSet,
                            GetCalendarEventUpdates => CalendarEventUpdates
                        },
                        Contact {
                            GetContacts       => Contacts,
                            SetContacts       => ContactsSet,
                            GetContactUpdates => ContactUpdates
                        },
                        ContactGroup {
                            GetContactGroups       => ContactGroups,
                            SetContactGroups       => ContactGroupsSet,
                            GetContactGroupUpdates => ContactGroupUpdates
                        },
                        Mailbox {
                            GetMailboxes      => Mailboxes,
                            SetMailboxes      => MailboxesSet,
                            GetMailboxUpdates => MailboxUpdates
                        }
                    );

                    rbatch.0.extend(rmethods.into_iter());
                }

                StatusBody::new(StatusCode::Ok, Some(rbatch.to_json().to_string().into_bytes()))
            },
            Err(e) =>
                StatusBody::new(StatusCode::BadRequest, Some(e.to_string().into_bytes())),
        },
        Err(e) => StatusBody::new(StatusCode::BadRequest, Some(e.to_string().into_bytes())),
    }
}

fn file_handler(path: &String, include_body: bool) -> StatusBody {
    match File::open(String::from("client") + if path == "/" { "/index.html" } else { path }) {
        Err(ref e) => match e.kind() {
            ErrorKind::NotFound => StatusBody::new(StatusCode::NotFound, None),
            // XXX others
            _ => StatusBody::new(StatusCode::InternalServerError, Some(format!("{}", e).into_bytes())),
        },
        Ok(ref mut f) => {
            match include_body {
                false => StatusBody::new(StatusCode::Ok, None),
                true  => {
                    let mut s = String::new();
                    match f.read_to_string(&mut s) {
                        Err(ref e) =>
                            StatusBody::new(StatusCode::InternalServerError, Some(format!("{}", e).into_bytes())),
                        _ =>
                            StatusBody::new(StatusCode::Ok, Some(s.into_bytes())),
                    }
                },
            }
        },
    }
}

fn finish_response(method: Method, path: &String, mut res: Response, out: StatusBody) {
    *res.status_mut() = out.code;

    info!("HTTP: {} {} => {}", method, path, out.code);

    match res.start()
        .and_then(|mut res|
                  match out.body {
                      Some(ref b) => {
                          try!(res.write_all(b));
                          Ok(res)
                      }
                      None => {
                          Ok(res)
                      }
                  })
        .and_then(|res| res.end()) {
            Err(e) => error!("response error: {}", e),
            _      => (),
        };
}

fn http_handler(mut req: Request, mut res: Response) {
    res.headers_mut().set(header::Server("salada/0.0.5".to_string()));

    let method = req.method.clone();
    let uri = req.uri.clone();

    match (method, uri) {
        (Post, AbsolutePath(ref path)) if path == "/jmap" =>
            finish_response(Post, path, res, jmap_handler(req)),

        (Get, AbsolutePath(ref path)) =>
            finish_response(Get, path, res, file_handler(path, true)),

        (Head, AbsolutePath(ref path)) =>
            finish_response(Head, path, res, file_handler(path, false)),

        (_, ref ap) => {
            let s = match ap {
                &AbsolutePath(ref u) => u,
                _ => panic!("RequestUri not AbsolutePath?"),
            };
            let mut drain: Vec<u8> = vec!();
            req.read_to_end(&mut drain).ok();
            finish_response(req.method, &s, res, StatusBody::new(StatusCode::MethodNotAllowed, None))
        },
    };
}

fn main() {
    logger::init().unwrap();

    info!("Listening on http://127.0.0.1:3000/jmap");
    hyper::Server::http("127.0.0.1:3000").unwrap().handle(http_handler).unwrap();
}
<commit_msg>Endpoint at /jmap/<commit_after>extern crate hyper;
extern crate rustc_serialize;
extern crate rusqlite;
extern crate jmap;
extern crate time;

#[macro_use]
extern crate log;

mod logger;
mod db;
mod util;
mod record;

use std::default::Default;
use std::io::{Read, Write, ErrorKind};

use std::fs::File;

use hyper::server::{Request, Response};
use hyper::method::Method;
use hyper::method::Method::{Post, Get, Head};
use hyper::status::StatusCode;
use hyper::uri::RequestUri::AbsolutePath;
use hyper::header;

use rustc_serialize::json::{Json,ToJson};

use jmap::parse::FromJson;
use jmap::method::{RequestBatch, ResponseBatch, ResponseMethod};
use jmap::method::RequestMethod::*;
use jmap::method::ResponseMethod::*;

use util::RequestContext;
use record::RecordHandler;
use db::Db;

struct StatusBody {
    code: StatusCode,
    body: Option<Vec<u8>>
}
impl StatusBody {
    fn new(code: StatusCode, body: Option<Vec<u8>>) -> StatusBody {
        StatusBody { code: code, body: body }
    }
}

macro_rules! make_crud_method_dispatcher {
    ($method: expr, $rmethods: expr, $r: expr,
     $($ty: ty { $get: ident => $rget: ident, $set: ident => $rset: ident, $getup: ident => $rgetup: ident }),*) => {
        $rmethods = match $method {
            $(
                $get(args, id)
                    => vec!($r.get_records(&args).map(|a| $rget(a, id.clone())).unwrap_or_else(|e| ResponseError(e, id.clone()))),
                $set(args, id)
                    => vec!($r.set_records(&args).map(|a| $rset(a, id.clone())).unwrap_or_else(|e| ResponseError(e, id.clone()))),
                $getup(args, id) => $r.get_record_updates(&args).map(|a| {
                    match a {
                        (a, Some(b)) => vec!($rgetup(a, id.clone()), $rget(b, id.clone())),
                        (a, _)       => vec!($rgetup(a, id.clone())),
                    }
                }).unwrap_or_else(|e| vec!(ResponseError(e, id.clone()))),
            )*
            RequestError(args, id) => vec!(ResponseError(args, id)),
        };
    }
}

fn jmap_handler(mut req: Request) -> StatusBody {

    match Json::from_reader(&mut req) {
        Ok(j) => match RequestBatch::from_json(&j) {
            Ok(b) => {
                let mut rbatch: ResponseBatch = ResponseBatch::default();

                let r = RequestContext {
                    userid: 1, // XXX get userid from auth
                    db: Db::open().unwrap(),
                };

                for method in b.0.into_iter() {
                    let rmethods: Vec<ResponseMethod>;
                    make_crud_method_dispatcher!(method, rmethods, r,
                        Calendar {
                            GetCalendars       => Calendars,
                            SetCalendars       => CalendarsSet,
                            GetCalendarUpdates => CalendarUpdates
                        },
                        CalendarEvent {
                            GetCalendarEvents       => CalendarEvents,
                            SetCalendarEvents       => CalendarEventsSet,
                            GetCalendarEventUpdates => CalendarEventUpdates
                        },
                        Contact {
                            GetContacts       => Contacts,
                            SetContacts       => ContactsSet,
                            GetContactUpdates => ContactUpdates
                        },
                        ContactGroup {
                            GetContactGroups       => ContactGroups,
                            SetContactGroups       => ContactGroupsSet,
                            GetContactGroupUpdates => ContactGroupUpdates
                        },
                        Mailbox {
                            GetMailboxes      => Mailboxes,
                            SetMailboxes      => MailboxesSet,
                            GetMailboxUpdates => MailboxUpdates
                        }
                    );

                    rbatch.0.extend(rmethods.into_iter());
                }

                StatusBody::new(StatusCode::Ok, Some(rbatch.to_json().to_string().into_bytes()))
            },
            Err(e) =>
                StatusBody::new(StatusCode::BadRequest, Some(e.to_string().into_bytes())),
        },
        Err(e) => StatusBody::new(StatusCode::BadRequest, Some(e.to_string().into_bytes())),
    }
}

fn file_handler(path: &String, include_body: bool) -> StatusBody {
    match File::open(String::from("client") + if path == "/" { "/index.html" } else { path }) {
        Err(ref e) => match e.kind() {
            ErrorKind::NotFound => StatusBody::new(StatusCode::NotFound, None),
            // XXX others
            _ => StatusBody::new(StatusCode::InternalServerError, Some(format!("{}", e).into_bytes())),
        },
        Ok(ref mut f) => {
            match include_body {
                false => StatusBody::new(StatusCode::Ok, None),
                true  => {
                    let mut s = String::new();
                    match f.read_to_string(&mut s) {
                        Err(ref e) =>
                            StatusBody::new(StatusCode::InternalServerError, Some(format!("{}", e).into_bytes())),
                        _ =>
                            StatusBody::new(StatusCode::Ok, Some(s.into_bytes())),
                    }
                },
            }
        },
    }
}

fn finish_response(method: Method, path: &String, mut res: Response, out: StatusBody) {
    *res.status_mut() = out.code;

    info!("HTTP: {} {} => {}", method, path, out.code);

    match res.start()
        .and_then(|mut res|
                  match out.body {
                      Some(ref b) => {
                          try!(res.write_all(b));
                          Ok(res)
                      }
                      None => {
                          Ok(res)
                      }
                  })
        .and_then(|res| res.end()) {
            Err(e) => error!("response error: {}", e),
            _      => (),
        };
}

fn http_handler(mut req: Request, mut res: Response) {
    res.headers_mut().set(header::Server("salada/0.0.5".to_string()));

    let method = req.method.clone();
    let uri = req.uri.clone();

    match (method, uri) {
        (Post, AbsolutePath(ref path)) if path == "/jmap/" =>
            finish_response(Post, path, res, jmap_handler(req)),

        (Get, AbsolutePath(ref path)) =>
            finish_response(Get, path, res, file_handler(path, true)),

        (Head, AbsolutePath(ref path)) =>
            finish_response(Head, path, res, file_handler(path, false)),

        (_, ref ap) => {
            let s = match ap {
                &AbsolutePath(ref u) => u,
                _ => panic!("RequestUri not AbsolutePath?"),
            };
            let mut drain: Vec<u8> = vec!();
            req.read_to_end(&mut drain).ok();
            finish_response(req.method, &s, res, StatusBody::new(StatusCode::MethodNotAllowed, None))
        },
    };
}

fn main() {
    logger::init().unwrap();

    info!("Listening on http://127.0.0.1:3000/jmap");
    hyper::Server::http("127.0.0.1:3000").unwrap().handle(http_handler).unwrap();
}
<|endoftext|>