<commit_before>use crossbeam::sync::SegQueue;

// TODO: Merge `Transaction` and `Transacting`.

/// A transaction handler
///
/// This is used for representing a write transaction node. It has a reference to the cache and a
/// mutable reference to the block, allowing it to create child transactions of the write.
///
/// The transaction will be flushable when this handler is dropped.
#[derive(Copy, Clone)]
#[must_use]
struct Transaction<'a> {
    /// The sector of the transaction.
    sector: disk::Sector,
    /// The block in question.
    ///
    /// This is a lock guard, and thus as long it is held, the block cannot be flushed.
    block: chashmap::WriteGuard<'a, Block>,
}

impl<'a> Transaction<'a> {
    /// Wrap a value in the transaction.
    ///
    /// This makes a `Transacting` with the transaction and inner value `inner`.
    pub fn wrap<T>(self, inner: T) -> Transacting<T> {
        Transacting {
            inner: T,
            transaction: self,
        }
    }

    /// Execute a transaction depending on the current.
    ///
    /// This makes a new transaction which will execute `self` transaction then `other`.
    ///
    /// Beware that it will make `self` flushable, by executing the lock.
    pub fn then(self, other: Transaction) -> Transaction {
        // Make `other` depend on `self`.
        other.block.flush_dependencies.push(self.sector);

        // Since `other` depends on `self`, we can safely use `other`.
        Transaction {
            sector: other.sector,
            block: other.block,
        }

        // Now `self` will drop, releasing the lock, and making it flushable.
    }

    /// Execute the transaction.
    pub fn execute(self) {
        // Release the lock.
        drop(self.block);
        // To avoid the safety destructor from running, we leak `self`, knowing that everything is
        // deallocated.
        mem::forget(self);
    }
}

impl<'a> Drop for Transaction<'a> {
    fn drop(&mut self) {
        // In order to avoid accidentally dropping transactions, we force the programmer to
        // manually execute transactions.
        panic!("Dropping a `Transaction` automatically. Use `.execute()` instead.");
    }
}

/// A monad-like wrapper telling that some data depends on a transaction.
///
/// This wraps some inner data, adding a transaction, which it depends on.
///
/// It is usually used if some data requires a transaction to be valid. An example is if a file was
/// allocated on an address, then the address would only be valid if the associated transaction was
/// executed.
#[must_use]
struct Transacting<'a, T> {
    /// The inner data.
    inner: T,
    /// The accompanying transaction.
    transaction: Option<Transaction<'a>>,
}

impl<'a, T> Transacting<'a, T> {
    /// Create a new `Transacting`.
    ///
    /// This creates a new `Transacting<T>` from inner value `inner` and with transaction
    /// `Transaction`.
    fn new(inner: T, transaction: Option<Transaction>) -> Transacting<T> {
        Transacting {
            inner: inner,
            transaction: transaction,
        }
    }

    /// Create a new `Transacting` without a transaction.
    fn no_transaction(inner: T) -> Transacting<T> {
        Transacting {
            inner: T,
            transaction: None,
        }
    }

    /// Chain the transaction together with another transaction, so they're executed sequentially.
    ///
    /// This makes a new transaction which will execute `self`'s transaction then `other`.
    fn then(self, other: Transaction) -> Transaction {
        if let Some(transaction) = self.transaction {
            // Append it to the current transaction.
            transaction.then(other)
        } else {
            // `self` contained no transaction, so we'll simply execute `other`.
            other
        }
    }
}

/// A cache block.
///
/// This stores a single sector in memory, for more performant reads and writes.
///
/// The terminology "cache block" is similar to "cache lines" in CPUs. They represent a single
/// fixed-size block which is cached in memory.
struct Block {
    /// The data of the sector.
    ///
    /// This shall reflect what is on the disk, unless the block is marked "dirty".
    data: disk::SectorBuf,
    /// Is this block in sync with the disk?
    ///
    /// This is set if `self.data` matches what is written to the disk. Namely, if it has been
    /// flushed or not.
    dirty: bool,
    /// Disk sectors that shall be flushed _before_ this block.
    ///
    /// This defines the flush dependencies and is crucial to the consistency of the cache. In
    /// particular, ordering matters, since unexpected crashes should never leave the system in an
    /// inconsistent state.
    ///
    /// To consider flush ordering, we define a poset on the cache blocks. If `A < B`, `A` should
    /// be written prior to `B`. This is represented as an ADG. The algorithm for flushing is:
    /// write the orphan nodes to the disk, until no nodes are dirty.
    ///
    /// In other words, the sectors in this vector are _guaranteed_ to be written before the block
    /// itself.
    flush_dependencies: Vec<disk::Sector>,
}

impl Block {
    /// Create a new block with some data.
    fn new(data: disk::SectorBuf) -> Block {
        Block {
            data: data,
            dirty: false,
            flush_dependencies: Vec::new(),
        }
    }
}

/// A cache operation.
enum CacheOperation {
    /// Create a new cache block for some sector.
    Create(disk::Sector),
    /// Touch a cache block of some sector.
    Touch(disk::Sector),
}

/// A cached disk.
///
/// This wrapper manages caching and the consistency issues originating from it.
///
/// It organizes the cache into _cache blocks_ each representing some _disk sector_. The cache
/// blocks are put in a _dependency graph_ which enforces the ordering of flushes (writes to
/// disks).
///
/// It holds a vdev driver, which the flushes are written to.
struct Cache {
    /// The inner driver.
    driver: vdev::Driver,

    /// The cache tracker operation queue.
    ///
    /// In order to avoid excessively locking and unlocking the cache tracker, we buffer the
    /// operations, which will then be executed in one go, when needed.
    queue: SegQueue<CacheOperation>,
    /// The cache replacement tracker.
    ///
    /// This tracks the state of the replacement algorithm, which chooses which cache block shall
    /// be replaced in favor of a new cache. It serves to estimate/guess which block is likely not
    /// used in the near future.
    tracker: Mutex<mlcr::Cache>,

    /// The sector-to-cache block map.
    sector_map: CHashMap<disk::Sector, Block>,
}

impl Cache {
    /// Execute a write transaction.
    ///
    /// This creates a transaction writing `buf` into sector `sector`, when dropped.
    fn write<F>(&self, sector: disk::Sector, buf: disk::SectorBuf) -> Transaction {
        // Acquire the lock to the block, and initialize if it doesn't already exist.
        let lock = self.sector_map.get_mut_or(sector, Block::default());
        // Set the dirty flag.
        lock.dirty = true;
        // Update the data.
        lock.data = buf;

        Transaction {
            block: lock,
            cache: self,
        }
    }

    /// Read a sector.
    ///
    /// This reads sector `sector`, and applies the closure `map`. If `sector` needs to be fetched
    /// from the disk, and `map` fails, data recovery is attempted.
    ///
    /// If an I/O operation fails, the error is returned. Otherwise, the return value of `map` is
    /// returned.
    fn read_then<F, T, E>(&self, sector: disk::Sector, map: F) -> Result<T, E>
        where F: Fn(&disk::SectorBuf) -> Result<T, E>,
              E: From<disk::Error> {
        debug!(self, "reading sector"; "sector" => sector);

        // Check if the sector is already available in the cache.
        if let Some(accessor) = self.sector_map.find(sector) {
            // Yup, we found the sector in the cache.
            trace!(self, "cache hit; reading from cache"; "sector" => sector);

            // Touch the sector.
            self.queue.push(CacheOperation::Touch(sector));

            handler(accessor)
        } else {
            trace!(self, "cache miss; reading from disk"; "sector" => sector);

            // Occupy the block in the map, so that we can later on insert it.
            let block = self.sector_map.get_mut_or(sector, Block::default());
            // Insert the sector into the cache tracker.
            self.queue.push(CacheOperation::Create(sector));

            // Fetch the data from the disk.
            self.disk.read(sector, &mut block.data)?;

            // Handle the block through the closure, and resolve respective verification issues.
            match map(&block.data) {
                Err(err) => {
                    // The verifier failed, so the data is likely corrupt. We'll try to recover the
                    // data through the vdev's redundancy, then we read it again and see if it passes
                    // verification this time. If not, healing failed, and we cannot do anything about
                    // it.
                    warn!(self, "data verification failed"; "sector" => sector, "error" => err);

                    // Attempt to heal the sector.
                    self.disk.heal(sector)?;
                    // Read it again.
                    self.disk.read(sector, &mut block.data)?;

                    // Try to verify it once again.
                    map(&block.data)
                },
                x => x,
            }
        }
    }

    /// Trim the cache.
    ///
    /// This reduces the cache to exactly `to` blocks. Note that this is quite expensive, and
    /// should thus only be called once in a whle.
    fn trim(&self, to: usize) -> Result<(), disk::Error> {
        info!(self, "trimming cache"; "to" => to);

        // Lock the cache tracker.
        let tracker = self.tracker.lock();
        // Commit the buffered operations to the tracker.
        while let Some(op) = self.queue.try_pop() {
            match op {
                // Create new cache block.
                CacheOperation::Create(sector) => tracker.create(sector),
                // Touch a cache block.
                CacheOperation::Touch(sector) => tracker.touch(sector),
            }
        }

        // The set of blocks to trim.
        let mut flush: HashSet<_> = tracker.trim(to).collect();
        // Exhaust the set until it is empty.
        while let Some(tl_sector) = flush.drain().first() {
            debug!(self, "flushing and removing block"; "sector" => tl_sector);

            // We grab the reference and lock in order to avoid the block changing while we
            // traverse.
            let tl_block = self.sector_map.find_mut(tl_sector);
            // Skip flushing, if the block is not dirty.
            if !tl_block.dirty {
                continue;
            }
            // Start with an empty stack to do our search. This stack will hold the state of the
            // traversal, following a variant of DFS, where we dive as deep as possible first, and
            // then backtrack when we can go deeper. Every element must be a dirty block.
            let mut stack = Vec::new();
            // Push the sector we will flush to the stack.
            stack.push((tl_sector, tl_block));

            // Traverse!
            loop {
                // Pop the top of the stack to deepen it.
                if let Some((sector, block)) = stack.pop() {
                    // See if the block has flush dependencies, which must be flushed before.
                    if let Some(dep) = block.flush_dependencies.pop() {
                        // It got at least one flush dependencies.
                        trace!(self, "traversing dependency";
                               "sector" => sector,
                               "depending sector" => dep);

                        // Since it could potentially have more than one dependencies, we push it
                        // back so that we can reinvestigate later.
                        stack.push((sector, block));

                        // Check if the block is dirty, or we can skip it. This holds up the
                        // invariant that every block in `stack` are dirty.
                        if block.dirty {
                            // Push the dependency to the stack. Again, we use `find_mut` to make sure
                            // other threads doesn't access it while we traverse.
                            stack.push((dep, self.sector_map.find_mut(sector)));
                        }
                    } else {
                        // The block is dirty and needs to be flushed. Note that we need not to
                        // check if it is dirty, as our invariant states that al blocks in `stack`
                        // are dirty.
                        debug!(self, "flushing block"; "sector" => sector);

                        // No more flush dependencies on the former top of the stack (`block`), so
                        // we can safely write the sector, knowing that all dependencies have been
                        // flushed.
                        self.driver.write(sector, block.data)?;
                        // Unset the dirty flag.
                        block.dirty = false;

                        // Clean up the block if it is a top-level block (a block which will be
                        // removed).
                        if flush.remove(sector) || sector == tl_sector {
                            // We've now removed the block from `flush`, so we won't flush it later
                            // on.

                            // Remove the sector from the cache tracker.
                            tracker.remove(sector);
                            // Finally, remove the block from the sector map.
                            self.sector_map.remove(sector);
                        }

                        // We don't need to pop from the stack, since we have already popped an
                        // element, which we won't push back. The lock originating from `find_mut`
                        // is dropped here, and the block can then freely be modified.
                    }
                } else {
                    // The stack is empty, and we've traversed everything.
                    break;
                }
            }
        }
    }
}

impl Drop for Cache {
    fn drop(&mut self) {
        info!(self, "closing cache");

        self.trim(0);
    }
}

delegate_log!(Cache.driver);

// TODO: Add tests.
<commit_msg>Define a type alias for write guards in caching.<commit_after>use crossbeam::sync::SegQueue;

/// A writable guard to a cache block.
type WriteGuard<'a> = chashmap::WriteGuard<'a, disk::Sector, Block>;

// TODO: Merge `Transaction` and `Transacting`.

/// A transaction handler
///
/// This is used for representing a write transaction node. It has a reference to the cache and a
/// mutable reference to the block, allowing it to create child transactions of the write.
///
/// The transaction will be flushable when this handler is dropped.
#[derive(Copy, Clone)]
#[must_use]
struct Transaction<'a> {
    /// The sector of the transaction.
    sector: disk::Sector,
    /// The block in question.
    ///
    /// This is a lock guard, and thus as long it is held, the block cannot be flushed.
    block: chashmap::WriteGuard<'a>,
}

impl<'a> Transaction<'a> {
    /// Wrap a value in the transaction.
    ///
    /// This makes a `Transacting` with the transaction and inner value `inner`.
    pub fn wrap<T>(self, inner: T) -> Transacting<T> {
        Transacting {
            inner: T,
            transaction: self,
        }
    }

    /// Execute a transaction depending on the current.
    ///
    /// This makes a new transaction which will execute `self` transaction then `other`.
    ///
    /// Beware that it will make `self` flushable, by executing the lock.
    pub fn then(self, other: Transaction) -> Transaction {
        // Make `other` depend on `self`.
        other.block.flush_dependencies.push(self.sector);

        // Since `other` depends on `self`, we can safely use `other`.
        Transaction {
            sector: other.sector,
            block: other.block,
        }

        // Now `self` will drop, releasing the lock, and making it flushable.
    }

    /// Execute the transaction.
    pub fn execute(self) {
        // Release the lock.
        drop(self.block);
        // To avoid the safety destructor from running, we leak `self`, knowing that everything is
        // deallocated.
        mem::forget(self);
    }
}

impl<'a> Drop for Transaction<'a> {
    fn drop(&mut self) {
        // In order to avoid accidentally dropping transactions, we force the programmer to
        // manually execute transactions.
        panic!("Dropping a `Transaction` automatically. Use `.execute()` instead.");
    }
}

/// A monad-like wrapper telling that some data depends on a transaction.
///
/// This wraps some inner data, adding a transaction, which it depends on.
///
/// It is usually used if some data requires a transaction to be valid. An example is if a file was
/// allocated on an address, then the address would only be valid if the associated transaction was
/// executed.
#[must_use]
struct Transacting<'a, T> {
    /// The inner data.
    inner: T,
    /// The accompanying transaction.
    transaction: Option<Transaction<'a>>,
}

impl<'a, T> Transacting<'a, T> {
    /// Create a new `Transacting`.
    ///
    /// This creates a new `Transacting<T>` from inner value `inner` and with transaction
    /// `Transaction`.
    fn new(inner: T, transaction: Option<Transaction>) -> Transacting<T> {
        Transacting {
            inner: inner,
            transaction: transaction,
        }
    }

    /// Create a new `Transacting` without a transaction.
    fn no_transaction(inner: T) -> Transacting<T> {
        Transacting {
            inner: T,
            transaction: None,
        }
    }

    /// Chain the transaction together with another transaction, so they're executed sequentially.
    ///
    /// This makes a new transaction which will execute `self`'s transaction then `other`.
    fn then(self, other: Transaction) -> Transaction {
        if let Some(transaction) = self.transaction {
            // Append it to the current transaction.
            transaction.then(other)
        } else {
            // `self` contained no transaction, so we'll simply execute `other`.
            other
        }
    }
}

/// A cache block.
///
/// This stores a single sector in memory, for more performant reads and writes.
///
/// The terminology "cache block" is similar to "cache lines" in CPUs. They represent a single
/// fixed-size block which is cached in memory.
struct Block {
    /// The data of the sector.
    ///
    /// This shall reflect what is on the disk, unless the block is marked "dirty".
    data: disk::SectorBuf,
    /// Is this block in sync with the disk?
    ///
    /// This is set if `self.data` matches what is written to the disk. Namely, if it has been
    /// flushed or not.
    dirty: bool,
    /// Disk sectors that shall be flushed _before_ this block.
    ///
    /// This defines the flush dependencies and is crucial to the consistency of the cache. In
    /// particular, ordering matters, since unexpected crashes should never leave the system in an
    /// inconsistent state.
    ///
    /// To consider flush ordering, we define a poset on the cache blocks. If `A < B`, `A` should
    /// be written prior to `B`. This is represented as an ADG. The algorithm for flushing is:
    /// write the orphan nodes to the disk, until no nodes are dirty.
    ///
    /// In other words, the sectors in this vector are _guaranteed_ to be written before the block
    /// itself.
    flush_dependencies: Vec<disk::Sector>,
}

impl Block {
    /// Create a new block with some data.
    fn new(data: disk::SectorBuf) -> Block {
        Block {
            data: data,
            dirty: false,
            flush_dependencies: Vec::new(),
        }
    }
}

/// A cache operation.
enum CacheOperation {
    /// Create a new cache block for some sector.
    Create(disk::Sector),
    /// Touch a cache block of some sector.
    Touch(disk::Sector),
}

/// A cached disk.
///
/// This wrapper manages caching and the consistency issues originating from it.
///
/// It organizes the cache into _cache blocks_ each representing some _disk sector_. The cache
/// blocks are put in a _dependency graph_ which enforces the ordering of flushes (writes to
/// disks).
///
/// It holds a vdev driver, which the flushes are written to.
struct Cache {
    /// The inner driver.
    driver: vdev::Driver,

    /// The cache tracker operation queue.
    ///
    /// In order to avoid excessively locking and unlocking the cache tracker, we buffer the
    /// operations, which will then be executed in one go, when needed.
    queue: SegQueue<CacheOperation>,
    /// The cache replacement tracker.
    ///
    /// This tracks the state of the replacement algorithm, which chooses which cache block shall
    /// be replaced in favor of a new cache. It serves to estimate/guess which block is likely not
    /// used in the near future.
    tracker: Mutex<mlcr::Cache>,

    /// The sector-to-cache block map.
    sector_map: CHashMap<disk::Sector, Block>,
}

impl Cache {
    /// Execute a write transaction.
    ///
    /// This creates a transaction writing `buf` into sector `sector`, when dropped.
    fn write<F>(&self, sector: disk::Sector, buf: disk::SectorBuf) -> Transaction {
        debug!(self, "writing sector"; "sector" => sector);

        // Acquire the lock to the block, and initialize if it doesn't already exist.
        let lock = self.sector_map.get_mut_or(sector, Block::default());
        // Set the dirty flag.
        lock.dirty = true;
        // Update the data.
        lock.data = buf;

        Transaction {
            block: lock,
            cache: self,
        }
    }

    /// Read a sector.
    ///
    /// This reads sector `sector`, and applies the closure `map`. If `sector` needs to be fetched
    /// from the disk, and `map` fails, data recovery is attempted.
    ///
    /// If an I/O operation fails, the error is returned. Otherwise, the return value of `map` is
    /// returned.
    fn read_then<F, T, E>(&self, sector: disk::Sector, map: F) -> Result<T, E>
        where F: Fn(&disk::SectorBuf) -> Result<T, E>,
              E: From<disk::Error> {
        debug!(self, "reading sector"; "sector" => sector);

        // Check if the sector is already available in the cache.
        if let Some(accessor) = self.sector_map.find(sector) {
            // Yup, we found the sector in the cache.
            trace!(self, "cache hit; reading from cache"; "sector" => sector);

            // Touch the sector.
            self.queue.push(CacheOperation::Touch(sector));

            handler(accessor)
        } else {
            trace!(self, "cache miss; reading from disk"; "sector" => sector);

            // Occupy the block in the map, so that we can later on insert it.
            let block = self.sector_map.get_mut_or(sector, Block::default());
            // Insert the sector into the cache tracker.
            self.queue.push(CacheOperation::Create(sector));

            // Fetch the data from the disk.
            self.disk.read(sector, &mut block.data)?;

            // Handle the block through the closure, and resolve respective verification issues.
            match map(&block.data) {
                Err(err) => {
                    // The verifier failed, so the data is likely corrupt. We'll try to recover the
                    // data through the vdev's redundancy, then we read it again and see if it passes
                    // verification this time. If not, healing failed, and we cannot do anything about
                    // it.
                    warn!(self, "data verification failed"; "sector" => sector, "error" => err);

                    // Attempt to heal the sector.
                    self.disk.heal(sector)?;
                    // Read it again.
                    self.disk.read(sector, &mut block.data)?;

                    // Try to verify it once again.
                    map(&block.data)
                },
                x => x,
            }
        }
    }

    /// Trim the cache.
    ///
    /// This reduces the cache to exactly `to` blocks. Note that this is quite expensive, and
    /// should thus only be called once in a whle.
    fn trim(&self, to: usize) -> Result<(), disk::Error> {
        info!(self, "trimming cache"; "to" => to);

        // Lock the cache tracker.
        let tracker = self.tracker.lock();
        // Commit the buffered operations to the tracker.
        while let Some(op) = self.queue.try_pop() {
            match op {
                // Create new cache block.
                CacheOperation::Create(sector) => tracker.create(sector),
                // Touch a cache block.
                CacheOperation::Touch(sector) => tracker.touch(sector),
            }
        }

        // The set of blocks to trim.
        let mut flush: HashSet<_> = tracker.trim(to).collect();
        // Exhaust the set until it is empty.
        while let Some(tl_sector) = flush.drain().first() {
            debug!(self, "flushing and removing block"; "sector" => tl_sector);

            // Acquire the lock. To avoid changes while we traverse, we use mutable locks,
            // excluding other writes.
            // TODO: Perhaps use immutable locks and then upgrade them to mutable when changing the
            //       dirty flag. This could improve performance significantly.
            let tl_block = self.sector_map.get_mut(tl_sector);
            // Skip flushing, if the block is not dirty.
            if !tl_block.dirty {
                continue;
            }
            // Start with an empty stack to do our search. This stack will hold the state of the
            // traversal, following a variant of DFS, where we dive as deep as possible first, and
            // then backtrack when we can go deeper. Every element must be a dirty block.
            let mut stack = Vec::new();
            // Push the sector we will flush to the stack.
            stack.push((tl_sector, tl_block));

            // Traverse!
            loop {
                // Pop the top of the stack to deepen it.
                if let Some((sector, block)) = stack.pop() {
                    // See if the block has flush dependencies, which must be flushed before.
                    if let Some(dep) = block.flush_dependencies.pop() {
                        // It got at least one flush dependencies.
                        trace!(self, "traversing dependency";
                               "sector" => sector,
                               "depending sector" => dep);

                        // Since it could potentially have more than one dependencies, we push it
                        // back so that we can reinvestigate later.
                        stack.push((sector, block));

                        // Check if the block is dirty, or we can skip it. This holds up the
                        // invariant that every block in `stack` are dirty.
                        if block.dirty {
                            // Push the dependency to the stack.
                            stack.push((dep, self.sector_map.get_mut(sector)));
                        }
                    } else {
                        // The block is dirty and needs to be flushed. Note that we need not to
                        // check if it is dirty, as our invariant states that al blocks in `stack`
                        // are dirty.
                        debug!(self, "flushing block"; "sector" => sector);

                        // No more flush dependencies on the former top of the stack (`block`), so
                        // we can safely write the sector, knowing that all dependencies have been
                        // flushed.
                        self.driver.write(sector, block.data)?;
                        // Unset the dirty flag.
                        block.dirty = false;

                        // Clean up the block if it is a top-level block (a block which will be
                        // removed).
                        if flush.remove(sector) || sector == tl_sector {
                            // We've now removed the block from `flush`, so we won't flush it later
                            // on.

                            // Remove the sector from the cache tracker.
                            tracker.remove(sector);
                            // Finally, remove the block from the sector map.
                            self.sector_map.remove(sector);
                        }

                        // We don't need to pop from the stack, since we have already popped an
                        // element, which we won't push back. The lock originating from `get_mut`
                        // is dropped here, and the block can then freely be modified.
                    }
                } else {
                    // The stack is empty, and we've traversed everything.
                    break;
                }
            }
        }
    }
}

impl Drop for Cache {
    fn drop(&mut self) {
        info!(self, "closing cache");

        self.trim(0);
    }
}

delegate_log!(Cache.driver);

// TODO: Add tests.
<|endoftext|>


<commit_before>#![crate_name = "hotel"]
#![crate_type = "rlib"]
#![no_std]
#![feature(asm,const_fn)]

extern crate cortexm3;
extern crate common;
extern crate hil;
extern crate support;

pub mod chip;
pub mod gpio;
pub mod pinmux;
pub mod pmu;
pub mod timeus;
pub mod uart;

unsafe extern "C" fn unhandled_interrupt() {
    let mut interrupt_number: u32;

    // IPSR[8:0] holds the currently active interrupt
    asm!(
        "mrs    r0, ipsr                    "
        : "={r0}"(interrupt_number)
        :
        : "r0"
        :
        );

    interrupt_number = interrupt_number & 0x1ff;

    panic!("Unhandled Interrupt. ISR {} is active.", interrupt_number);
}

extern {
    // _estack is not really a function, but it makes the types work
    // You should never actually invoke it!!
    fn _estack();

    // Defined in src/main/main.rs
    fn main();

    fn SVC_Handler();

    fn generic_isr();

    fn systick_handler();

    static mut _ero : u32;
    static mut _sdata : u32;
    static mut _edata : u32;
    static mut _sbss : u32;
    static mut _ebss : u32;
}

// marks the end of the app code segment with a null byte
#[link_section=".endapp"]
pub static ENDAPP: usize = 0;

#[link_section=".vectors"]
pub static ISR_VECTOR: [Option<unsafe extern fn()>; 16] = [
    /* Stack top */     Option::Some(_estack),
    /* Reset */         Option::Some(reset_handler),
    /* NMI */           Option::Some(unhandled_interrupt),
    /* Hard Fault */    Option::Some(unhandled_interrupt),
    /* MemManage */     Option::Some(unhandled_interrupt),
    /* BusFault */      Option::Some(unhandled_interrupt),
    /* UsageFault*/     Option::Some(unhandled_interrupt),
    None, None, None, None,
    /* SVC */           Option::Some(SVC_Handler),
    /* DebugMon */      Option::Some(unhandled_interrupt),
    None,
    /* PendSV */        Option::Some(unhandled_interrupt),
    /* SysTick */       Option::Some(systick_handler),
];

#[link_section=".vectors"]
pub static IRQS: [unsafe extern fn(); 0] = [generic_isr; 0];

#[no_mangle]
pub static INTERRUPT_TABLE: [Option<unsafe extern fn()>; 0] = [];

unsafe extern "C" fn reset_handler() {
    // Relocate data segment.
    // Assumes data starts right after text segment as specified by the linker
    // file.
    let mut pdest  = &mut _sdata as *mut u32;
    let pend  = &mut _edata as *mut u32;
    let mut psrc = &_ero as *const u32;

    if psrc != pdest {
        while (pdest as *const u32) < pend {
            *pdest = *psrc;
            pdest = pdest.offset(1);
            psrc = psrc.offset(1);
        }
    }

    // Clear the zero segment (BSS)
    let pzero = &_ebss as *const u32;
    pdest = &mut _sbss as *mut u32;

    while (pdest as *const u32) < pzero {
        *pdest = 0;
        pdest = pdest.offset(1);
    }

    main()
}

<commit_msg>Add no_mangle to ISR_VECTOR and IRQS to prevent them from being removed<commit_after>#![crate_name = "hotel"]
#![crate_type = "rlib"]
#![no_std]
#![feature(asm,const_fn)]

extern crate cortexm3;
extern crate common;
extern crate hil;
extern crate support;

pub mod chip;
pub mod gpio;
pub mod pinmux;
pub mod pmu;
pub mod timeus;
pub mod uart;

unsafe extern "C" fn unhandled_interrupt() {
    let mut interrupt_number: u32;

    // IPSR[8:0] holds the currently active interrupt
    asm!(
        "mrs    r0, ipsr                    "
        : "={r0}"(interrupt_number)
        :
        : "r0"
        :
        );

    interrupt_number = interrupt_number & 0x1ff;

    panic!("Unhandled Interrupt. ISR {} is active.", interrupt_number);
}

extern {
    // _estack is not really a function, but it makes the types work
    // You should never actually invoke it!!
    fn _estack();

    // Defined in src/main/main.rs
    fn main();

    fn SVC_Handler();

    fn generic_isr();

    fn systick_handler();

    static mut _ero : u32;
    static mut _sdata : u32;
    static mut _edata : u32;
    static mut _sbss : u32;
    static mut _ebss : u32;
}

// marks the end of the app code segment with a null byte
#[link_section=".endapp"]
pub static ENDAPP: usize = 0;

#[link_section=".vectors"]
#[no_mangle]
pub static ISR_VECTOR: [Option<unsafe extern fn()>; 16] = [
    /* Stack top */     Option::Some(_estack),
    /* Reset */         Option::Some(reset_handler),
    /* NMI */           Option::Some(unhandled_interrupt),
    /* Hard Fault */    Option::Some(unhandled_interrupt),
    /* MemManage */     Option::Some(unhandled_interrupt),
    /* BusFault */      Option::Some(unhandled_interrupt),
    /* UsageFault*/     Option::Some(unhandled_interrupt),
    None, None, None, None,
    /* SVC */           Option::Some(SVC_Handler),
    /* DebugMon */      Option::Some(unhandled_interrupt),
    None,
    /* PendSV */        Option::Some(unhandled_interrupt),
    /* SysTick */       Option::Some(systick_handler),
];

#[link_section=".vectors"]
#[no_mangle]
pub static IRQS: [unsafe extern fn(); 0] = [generic_isr; 0];

#[no_mangle]
pub static INTERRUPT_TABLE: [Option<unsafe extern fn()>; 0] = [];

unsafe extern "C" fn reset_handler() {
    // Relocate data segment.
    // Assumes data starts right after text segment as specified by the linker
    // file.
    let mut pdest  = &mut _sdata as *mut u32;
    let pend  = &mut _edata as *mut u32;
    let mut psrc = &_ero as *const u32;

    if psrc != pdest {
        while (pdest as *const u32) < pend {
            *pdest = *psrc;
            pdest = pdest.offset(1);
            psrc = psrc.offset(1);
        }
    }

    // Clear the zero segment (BSS)
    let pzero = &_ebss as *const u32;
    pdest = &mut _sbss as *mut u32;

    while (pdest as *const u32) < pzero {
        *pdest = 0;
        pdest = pdest.offset(1);
    }

    main()
}

<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/AKS_test_for_primes
#[cfg(not(test))]
fn main() {
    for p in range(0u, 8) {
        println!("{}: {}", p, coefficients(p));
    }

    for p in range(1u, 51).filter(|&x| is_prime(x)) {
        print!("{} ", p);
    }
}

fn coefficients(p: uint) -> Vec<i64> {
    if p==0 {
        vec![1]
    } else {
        let mut result = vec![1, -1];
        let zero = Some(0i64);
        for _ in range(1u, p) {
            result = {
                let a = result.iter().chain(zero.iter());
                let b = zero.iter().chain(result.iter());
                a.zip(b).map(|(x, &y)| x-y).collect()
            };
        }
        result
    }
}

fn is_prime(p: uint) -> bool {
    if p<2 {
        false
    } else {
        let mut c = coefficients(p);
        *c.get_mut(0) -= 1;
        for i in range(0, c.len()/2) {
            if (*c.get(i) % (p as i64)) != 0 {
                return false
            }
        }
        true
    }
}

#[test]
fn test_solution() {
    let exp_coefficients =  vec![
                            vec![1i64],
                            vec![1, -1],
                            vec![1, -2, 1],
                            vec![1, -3, 3, -1],
                            vec![1, -4, 6, -4, 1],
                            vec![1, -5, 10, -10, 5, -1],
                            vec![1, -6, 15, -20, 15, -6, 1],
                            vec![1, -7, 21, -35, 35, -21, 7, -1]];
    let exp_primes = &[2u, 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

    for (i, exp) in exp_coefficients.iter().enumerate() {
        assert_eq!(*exp, coefficients(i));
    }

    let primes: Vec<uint> = range(1u, 51).filter(|&i| is_prime(i)).collect();
    assert_eq!(exp_primes, primes.as_slice());
}<commit_msg>aks_test_for_primes to use index.<commit_after>// http://rosettacode.org/wiki/AKS_test_for_primes
#[cfg(not(test))]
fn main() {
    for p in range(0u, 8) {
        println!("{}: {}", p, coefficients(p));
    }

    for p in range(1u, 51).filter(|&x| is_prime(x)) {
        print!("{} ", p);
    }
}

fn coefficients(p: uint) -> Vec<i64> {
    if p==0 {
        vec![1]
    } else {
        let mut result = vec![1, -1];
        let zero = Some(0i64);
        for _ in range(1u, p) {
            result = {
                let a = result.iter().chain(zero.iter());
                let b = zero.iter().chain(result.iter());
                a.zip(b).map(|(x, &y)| x-y).collect()
            };
        }
        result
    }
}

fn is_prime(p: uint) -> bool {
    if p<2 {
        false
    } else {
        let mut c = coefficients(p);
        *c.get_mut(0) -= 1;
        for i in range(0, c.len()/2) {
            if (c[i] % (p as i64)) != 0 {
                return false
            }
        }
        true
    }
}

#[test]
fn test_solution() {
    let exp_coefficients =  vec![
                            vec![1i64],
                            vec![1, -1],
                            vec![1, -2, 1],
                            vec![1, -3, 3, -1],
                            vec![1, -4, 6, -4, 1],
                            vec![1, -5, 10, -10, 5, -1],
                            vec![1, -6, 15, -20, 15, -6, 1],
                            vec![1, -7, 21, -35, 35, -21, 7, -1]];
    let exp_primes = &[2u, 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

    for (i, exp) in exp_coefficients.iter().enumerate() {
        assert_eq!(*exp, coefficients(i));
    }

    let primes: Vec<uint> = range(1u, 51).filter(|&i| is_prime(i)).collect();
    assert_eq!(exp_primes, primes.as_slice());
}
<|endoftext|>


<commit_before>use std::sync::Arc;

use num_complex::Complex;
use num_traits::Zero;

use common::{FFTnum, verify_length, verify_length_divisible};

use ::{Length, IsInverse, FFT};

/// Implementation of Bluestein's Algorithm
///
/// This algorithm computes a FFT of any size by using converting it to a convolution, where a longer FFT of an "easy" length is used.
/// The primary use is for prime-sized FFTs of lengths where Rader's alorithm is slow.
/// When performing a FFT the inner FFT is run twice. These FFTs make up nearly all the processing time.
/// There are also simple O(n) processing steps before, in between and after the inner FFTs.
///
/// This implementation is based on the one in the [fourier library](https://github.com/calebzulawski/fourier) by Caleb Zulawski.
/// ~~~
/// // Computes a forward FFT of size 1201 (prime number), using Bluesteins's Algorithm
/// use rustfft::algorithm::Bluesteins;
/// use rustfft::{FFT, FFTplanner};
/// use rustfft::num_complex::Complex;
/// use rustfft::num_traits::Zero;
///
/// let mut input:  Vec<Complex<f32>> = vec![Zero::zero(); 1201];
/// let mut output: Vec<Complex<f32>> = vec![Zero::zero(); 1201];
///
/// // Plan a forward FFT for the nearest power of two larger or equal to 2 * 1201 - 1 -> 4096
/// // Note that the inner fft determines if the Bluestein fft is a forward or inverse transform.
/// let mut planner = FFTplanner::new(false);
/// let inner_fft = planner.plan_fft(4096);
///
/// let fft = Bluesteins::new(1201, inner_fft);
/// fft.process(&mut input, &mut output);
/// ~~~
///
/// Bluestein's algorithm is mainly useful for prime-length FFTs, and in particular for the lengths where
/// Rader's algorithm is slow due to hitting a Cunningham Chain.

pub struct Bluesteins<T> {
    len: usize,
    inner_fft: Arc<FFT<T>>,
    w_twiddles: Box<[Complex<T>]>,
    x_twiddles: Box<[Complex<T>]>,
}

fn calculate_twiddle<T: FFTnum>(index: f64, len: usize) -> Complex<T> {
    let theta = index * core::f64::consts::PI / len as f64;
    Complex::new(
        T::from_f64(theta.cos()).unwrap(),
        T::from_f64(-theta.sin()).unwrap(),
    )
}

/// Calculate the "w" twiddles.
fn calculate_w_twiddles<T: FFTnum>(
    len: usize,
    fft: &Arc<FFT<T>>,
    twiddles: &mut [Complex<T>],
) {
    let mut scratch = vec![Complex::zero(); fft.len()];
    let scale = T::one() / T::from_usize(fft.len()).unwrap();
    for (i, tw) in scratch.iter_mut().enumerate() {
        if let Some(index) = {
            if i < len {
                Some((i as f64).powi(2))
            } else if i > fft.len() - len {
                Some(((i as f64) - (fft.len() as f64)).powi(2))
            } else {
                None
            }
        } {
            *tw = calculate_twiddle(index, len).conj()*scale;
        }
    }
    fft.process(&mut scratch, &mut twiddles[..]);
    if fft.is_inverse() {
        for tw in twiddles.iter_mut() {
            *tw = tw.conj();
        }
    }
}

/// Calculate the "x" twiddles.
fn calculate_x_twiddles<T: FFTnum>(
    len: usize,
    twiddles: &mut [Complex<T>],
    inverse: bool,
) {
    if inverse {
        for (i, tw) in twiddles.iter_mut().enumerate() {
            *tw = calculate_twiddle(-(i as f64).powi(2), len);
        }
    }
    else {
        for (i, tw) in twiddles.iter_mut().enumerate() {
            *tw = calculate_twiddle(-(i as f64).powi(2), len).conj();
        }
    }
}

impl<T: FFTnum > Bluesteins<T> {
    /// Creates a FFT instance which will process inputs/outputs of size `len`. The inner FFT can be any length that is equal to or larger than `2 * len - 1`.
    /// The inner FFT determines if this becomes a forward or inverse transform.
    ///
    /// Note that this constructor is quite expensive to run; This algorithm must run a FFT within the
    /// constructor.
    pub fn new(len: usize, inner_fft: Arc<FFT<T>> ) -> Self {
        let min_inner_fft_len = 2 * len - 1;
        assert!(inner_fft.len() >= min_inner_fft_len, "For Bluesteins algorithm, inner_fft.len() must be equal to or larger than 2*self.len() - 1. Expected at least {}, got {}", min_inner_fft_len, inner_fft.len());

        let mut w_twiddles = vec![Complex::zero(); inner_fft.len()];
        let mut x_twiddles = vec![Complex::zero(); len];
        calculate_w_twiddles(len, &inner_fft, &mut w_twiddles);
        calculate_x_twiddles(len, &mut x_twiddles, inner_fft.is_inverse());
        Self {
            len,
            inner_fft,
            w_twiddles: w_twiddles.into_boxed_slice(),
            x_twiddles: x_twiddles.into_boxed_slice(),
        }
    }

    fn perform_fft(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        assert_eq!(self.len(), input.len());

        let mut scratch = vec![Complex::zero(); 2*self.inner_fft.len()];
        let (mut scratch_a, mut scratch_b) = scratch.split_at_mut(self.inner_fft.len());
        for (w, (x, i)) in scratch_a.iter_mut().zip(self.x_twiddles.iter().zip(input.iter())) {
            *w = x * i;
        }
        self.inner_fft.process(&mut scratch_a, &mut scratch_b);
        for (w, wi) in scratch_b.iter_mut().zip(self.w_twiddles.iter()) {
            *w = (*w * wi).conj();
        }
        self.inner_fft.process(&mut scratch_b, &mut scratch_a);
        for (i, (w, xi)) in output.iter_mut().zip(scratch_a.iter().zip(self.x_twiddles.iter())) {
            *i = w.conj() * xi;
        }
    }

}

impl<T: FFTnum> FFT<T> for Bluesteins<T> {
    fn process(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length(input, output, self.len());

        self.perform_fft(input, output);
    }
    fn process_multi(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length_divisible(input, output, self.len());

        for (in_chunk, out_chunk) in input.chunks_mut(self.len()).zip(output.chunks_mut(self.len())) {
            self.perform_fft(in_chunk, out_chunk);
        }
    }
}
impl<T> Length for Bluesteins<T> {
    #[inline(always)]
    fn len(&self) -> usize {
        self.len
    }
}
impl<T> IsInverse for Bluesteins<T> {
    #[inline(always)]
    fn is_inverse(&self) -> bool {
        self.inner_fft.is_inverse()
    }
}

#[cfg(test)]
mod unit_tests {
    use super::*;
    use std::sync::Arc;
    use test_utils::check_fft_algorithm;
    use algorithm::DFT;

    #[test]
    fn test_bluestein() {
        for &len in &[3,5,7,11,13] {
            test_bluestein_with_length(len, false);
            test_bluestein_with_length(len, true);
        }
    }

    fn test_bluestein_with_length(len: usize, inverse: bool) {
        let inner_fft_len = (2 * len - 1).checked_next_power_of_two().unwrap();
        let inner_fft = Arc::new(DFT::new(inner_fft_len, inverse));
        let fft = Bluesteins::new(len, inner_fft);

        check_fft_algorithm(&fft, len, inverse);
    }
}
<commit_msg>Conjugate to use FFT as iFFT and vice versa, comment steps<commit_after>use std::sync::Arc;

use num_complex::Complex;
use num_traits::Zero;

use common::{FFTnum, verify_length, verify_length_divisible};

use ::{Length, IsInverse, FFT};

/// Implementation of Bluestein's Algorithm
///
/// This algorithm computes a FFT of any size by using converting it to a convolution, where a longer FFT of an "easy" length is used.
/// The primary use is for prime-sized FFTs of lengths where Rader's alorithm is slow.
/// When performing a FFT the inner FFT is run twice. These FFTs make up nearly all the processing time.
/// There are also simple O(n) processing steps before, in between and after the inner FFTs.
///
/// This implementation is based on the one in the [fourier library](https://github.com/calebzulawski/fourier) by Caleb Zulawski.
/// ~~~
/// // Computes a forward FFT of size 1201 (prime number), using Bluesteins's Algorithm
/// use rustfft::algorithm::Bluesteins;
/// use rustfft::{FFT, FFTplanner};
/// use rustfft::num_complex::Complex;
/// use rustfft::num_traits::Zero;
///
/// let mut input:  Vec<Complex<f32>> = vec![Zero::zero(); 1201];
/// let mut output: Vec<Complex<f32>> = vec![Zero::zero(); 1201];
///
/// // Plan a forward FFT for the nearest power of two larger or equal to 2 * 1201 - 1 -> 4096
/// // Note that the inner fft determines if the Bluestein fft is a forward or inverse transform.
/// let mut planner = FFTplanner::new(false);
/// let inner_fft = planner.plan_fft(4096);
///
/// let fft = Bluesteins::new(1201, inner_fft);
/// fft.process(&mut input, &mut output);
/// ~~~
///
/// Bluestein's algorithm is mainly useful for prime-length FFTs, and in particular for the lengths where
/// Rader's algorithm is slow due to hitting a Cunningham Chain.

pub struct Bluesteins<T> {
    len: usize,
    inner_fft: Arc<FFT<T>>,
    w_twiddles: Box<[Complex<T>]>,
    x_twiddles: Box<[Complex<T>]>,
}

fn calculate_twiddle<T: FFTnum>(index: f64, len: usize) -> Complex<T> {
    let theta = index * core::f64::consts::PI / len as f64;
    Complex::new(
        T::from_f64(theta.cos()).unwrap(),
        T::from_f64(-theta.sin()).unwrap(),
    )
}

/// Calculate the "w" twiddles.
fn calculate_w_twiddles<T: FFTnum>(
    len: usize,
    fft: &Arc<FFT<T>>,
    twiddles: &mut [Complex<T>],
) {
    let mut scratch = vec![Complex::zero(); fft.len()];
    let scale = T::one() / T::from_usize(fft.len()).unwrap();
    for (i, tw) in scratch.iter_mut().enumerate() {
        if let Some(index) = {
            if i < len {
                Some((i as f64).powi(2))
            } else if i > fft.len() - len {
                Some(((i as f64) - (fft.len() as f64)).powi(2))
            } else {
                None
            }
        } {
            *tw = calculate_twiddle(index, len).conj()*scale;
        }
    }
    fft.process(&mut scratch, &mut twiddles[..]);
    if fft.is_inverse() {
        for tw in twiddles.iter_mut() {
            *tw = tw.conj();
        }
    }
}

/// Calculate the "x" twiddles.
fn calculate_x_twiddles<T: FFTnum>(
    len: usize,
    twiddles: &mut [Complex<T>],
    inverse: bool,
) {
    if inverse {
        for (i, tw) in twiddles.iter_mut().enumerate() {
            *tw = calculate_twiddle(-(i as f64).powi(2), len);
        }
    }
    else {
        for (i, tw) in twiddles.iter_mut().enumerate() {
            *tw = calculate_twiddle(-(i as f64).powi(2), len).conj();
        }
    }
}

impl<T: FFTnum > Bluesteins<T> {
    /// Creates a FFT instance which will process inputs/outputs of size `len`. The inner FFT can be any length that is equal to or larger than `2 * len - 1`.
    /// The inner FFT determines if this becomes a forward or inverse transform.
    ///
    /// Note that this constructor is quite expensive to run; This algorithm must run a FFT within the
    /// constructor.
    pub fn new(len: usize, inner_fft: Arc<FFT<T>> ) -> Self {
        let min_inner_fft_len = 2 * len - 1;
        assert!(inner_fft.len() >= min_inner_fft_len, "For Bluesteins algorithm, inner_fft.len() must be equal to or larger than 2*self.len() - 1. Expected at least {}, got {}", min_inner_fft_len, inner_fft.len());

        let mut w_twiddles = vec![Complex::zero(); inner_fft.len()];
        let mut x_twiddles = vec![Complex::zero(); len];
        calculate_w_twiddles(len, &inner_fft, &mut w_twiddles);
        calculate_x_twiddles(len, &mut x_twiddles, inner_fft.is_inverse());
        Self {
            len,
            inner_fft,
            w_twiddles: w_twiddles.into_boxed_slice(),
            x_twiddles: x_twiddles.into_boxed_slice(),
        }
    }

    fn perform_fft(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        // The steps of this algorithm are:
        // - Multiply inputs with the X twiddles, and store in the first `len` elements of longer vector.
        // - Perform a forward FFT of this vector to get a "spectrum".
        // - Multipy the spectrum with the W twiddles.
        // - Inverse transform the modified spectrum.
        // - Multiply first `len` elements of the iFFT output with the X-twiddles, and store in the output.
        //
        // By using the fact that iFFT(X) = FFT(X*)* and FFT(X) = iFFT(X*)*, we can use a single inner
        // FFT for both forward and inverse transform, by conjugating the inputs and outputs as needed.

        assert_eq!(self.len(), input.len());

        let mut scratch = vec![Complex::zero(); 2*self.inner_fft.len()];
        let (mut scratch_a, mut scratch_b) = scratch.split_at_mut(self.inner_fft.len());
        // Copy input data to scratch vector, and multiply with X twiddles.
        // If the inner FFT is inverse, then we conjugate the input here to make the first FFT step a forward transform
        if self.inner_fft.is_inverse() {
            for (w, (x, i)) in scratch_a.iter_mut().zip(self.x_twiddles.iter().zip(input.iter())) {
                *w = (x * i).conj();
            }
        }
        else {
            for (w, (x, i)) in scratch_a.iter_mut().zip(self.x_twiddles.iter().zip(input.iter())) {
                *w = x * i;
            }
        }

        // Perform forward FFT (either directly or using an inverse FFT with conjugated inputs and outputs).
        self.inner_fft.process(&mut scratch_a, &mut scratch_b);

        // Multiply spectrum with W twiddles.
        // If the inner FFT is inverse, then we conjugate the results from the first FFT step to make it a forward transform.
        if self.inner_fft.is_inverse() {
            for (w, wi) in scratch_b.iter_mut().zip(self.w_twiddles.iter()) {
                *w = w.conj() * wi;
            }
        }
        // If the inner FFT is forward, then we conjugate the input to the second FFT step here to make it an inverse transform
        else {
            for (w, wi) in scratch_b.iter_mut().zip(self.w_twiddles.iter()) {
                *w = (*w * wi).conj();
            }
        }

        // Perform inverse FFT (either directly or using a forward FFT with conjugated inputs and outputs).
        self.inner_fft.process(&mut scratch_b, &mut scratch_a);

        // Multiply with X twiddles and store in output.
        // If the inner FFT is inverse, use the output directly.
        if self.inner_fft.is_inverse() {
            for (i, (w, xi)) in output.iter_mut().zip(scratch_a.iter().zip(self.x_twiddles.iter())) {
                *i = w * xi;
            }
        }
        // If the inner FFT is forward, then we conjugate the output from the second FFT step to make it an inverse transform.
        else {
            for (i, (w, xi)) in output.iter_mut().zip(scratch_a.iter().zip(self.x_twiddles.iter())) {
                *i = w.conj() * xi;
            }
        }
    }

}

impl<T: FFTnum> FFT<T> for Bluesteins<T> {
    fn process(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length(input, output, self.len());

        self.perform_fft(input, output);
    }
    fn process_multi(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length_divisible(input, output, self.len());

        for (in_chunk, out_chunk) in input.chunks_mut(self.len()).zip(output.chunks_mut(self.len())) {
            self.perform_fft(in_chunk, out_chunk);
        }
    }
}
impl<T> Length for Bluesteins<T> {
    #[inline(always)]
    fn len(&self) -> usize {
        self.len
    }
}
impl<T> IsInverse for Bluesteins<T> {
    #[inline(always)]
    fn is_inverse(&self) -> bool {
        self.inner_fft.is_inverse()
    }
}

#[cfg(test)]
mod unit_tests {
    use super::*;
    use std::sync::Arc;
    use test_utils::check_fft_algorithm;
    use algorithm::DFT;

    #[test]
    fn test_bluestein() {
        for &len in &[3,5,7,11,13,123] {
            test_bluestein_with_length(len, false);
            test_bluestein_with_length(len, true);
        }
    }

    fn test_bluestein_with_length(len: usize, inverse: bool) {
        let inner_fft_len = (2 * len - 1).checked_next_power_of_two().unwrap();
        let inner_fft = Arc::new(DFT::new(inner_fft_len, inverse));
        let fft = Bluesteins::new(len, inner_fft);

        check_fft_algorithm(&fft, len, inverse);
    }
}
<|endoftext|>


<commit_before>//! Service for datagram transport.

use std::io;
use std::mem;
use std::net::SocketAddr;
use std::time::Duration;
use futures::{Async, Future, Poll};
use futures::stream::Stream;
use tokio_core::channel::{Receiver, channel};
use tokio_core::reactor;
use ::bits::{ComposeResult, MessageBuf, MessageBuilder, Question};
use super::error::Error;
use super::pending::PendingRequests;
use super::request::Request;
use super::resolver::ServiceHandle;

//------------ DgramTransport ------------------------------------------------

pub trait DgramTransport {
    fn send_to(&self, buf: &[u8], target: &SocketAddr) -> io::Result<usize>;
    fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>;
    fn poll_read(&self) -> Async<()>;
}

//------------ DgramFactory --------------------------------------------------

pub trait DgramFactory: Send + 'static {
    type Transport: DgramTransport;
    type Future: Future<Item=Self::Transport, Error=io::Error>;

    fn bind(&self, reactor: &reactor::Handle) -> Self::Future;
}

//------------ DgramService --------------------------------------------------

pub struct DgramService<T: DgramTransport> {
    recv: Option<Receiver<Request>>,
    sock: T,
    peer: SocketAddr,
    write: Option<DgramRequest>,
    pending: PendingRequests<DgramRequest>,
    msg_size: usize,
}

impl<T: DgramTransport + 'static> DgramService<T> {
    pub fn new<F>(factory: F, peer: SocketAddr, reactor: reactor::Handle,
                  request_timeout: Duration, msg_size: usize)
                  -> io::Result<ServiceHandle>
               where F: DgramFactory<Transport=T> {
        let (tx, rx) = try!(channel(&reactor));
        let idle = rx.into_future().map_err(|(_, _)| ());
        let received = idle.and_then(|(item, recv)| {
            match item {
                Some(request) => Ok((request, recv)),
                None => Err(())
            }
        });
        let bind_handle = reactor.clone();
        let binding = received.and_then(move |(request, recv)| {
            factory.bind(&bind_handle)
                   .map(|sock| (sock, request, recv))
                   .map_err(|_| ())
        });
        let pending_handle = reactor.clone();
        let fut = binding.and_then(move |(sock, request, recv)| {
            let mut pending = PendingRequests::new(pending_handle,
                                                   request_timeout);
            let write = DgramRequest::new(request, &mut pending, msg_size);
            let res = DgramService {
                recv: Some(recv), sock: sock, peer: peer,
                write: write, pending: pending, msg_size: msg_size,
            };
            res.map_err(|_| ())
        });
        reactor.spawn(fut);
        Ok(ServiceHandle::from_sender(tx))
    }
}

impl<T: DgramTransport> Future for DgramService<T> {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        match self.poll_recv() {
            Ok(Async::Ready(())) => return Ok(Async::Ready(())),
            Err(err) => return Err(err),
            Ok(Async::NotReady) => { }
        }
        self.poll_pending();
        try!(self.poll_write());
        try!(self.poll_read());
        Ok(Async::NotReady)
    }
}

impl<T: DgramTransport> DgramService<T> {
    fn poll_recv(&mut self) -> Poll<(), io::Error> {
        loop {
            if let Some(ref mut recv) = self.recv {
                if self.write.is_none() {
                    if let Some(request) = try_ready!(recv.poll()) {
                        self.write = DgramRequest::new(request,
                                                       &mut self.pending,
                                                       self.msg_size);
                        return Ok(Async::NotReady)
                    }
                }
                else { return Ok(Async::NotReady) }
            }
            else {
                if self.pending.is_empty() { return Ok(Async::Ready(())) }
                else { return Ok(Async::NotReady) }
            };
            self.recv = None;
        }
    }

    fn poll_pending(&mut self) {
        self.pending.expire(|item| item.timeout())
    }

    fn poll_write(&mut self) -> io::Result<()> {
        loop {
            let success = if let Some(ref mut request) = self.write {
                let written = match self.sock.send_to(request.buf(),
                                                      &self.peer) {
                    Ok(written) => written,
                    Err(ref e) if e.kind() == io::ErrorKind::WouldBlock
                    => {
                        return Ok(())
                    }
                    Err(err) => return Err(err)
                };
                written == request.buf().len()
            }
            else {
                return Ok(())
            };
            if let Some(request) = mem::replace(&mut self.write, None) {
                if success {
                    self.pending.push(request.id(), request)
                }
                else {
                    request.fail(io::Error::new(io::ErrorKind::Other,
                                                "short write").into());
                }
            }
        }
    }

    fn poll_read(&mut self) -> io::Result<()> {
        while let Async::Ready(()) = self.sock.poll_read() {
            let mut buf = vec![0u8; self.msg_size];
            let (size, addr) = match self.sock.recv_from(&mut buf) {
                Ok(some) => some,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    return Ok(())
                }
                Err(err) => return Err(err)
            };
            if addr != self.peer {
                return Ok(())
            }
            buf.resize(size, 0);
            let msg = match MessageBuf::from_vec(buf) {
                Ok(msg) => msg,
                Err(_) => return Ok(())
            };
            let id = msg.header().id();
            if let Some(request) = self.pending.pop(id) {
                request.respond(msg)
            }
        }
        Ok(())
    }
}

//------------ DgramRequest --------------------------------------------------

struct DgramRequest {
    request: Request,
    id: u16,
    buf: MessageBuf,
}

impl DgramRequest {
    fn new(request: Request, pending: &mut PendingRequests<Self>,
           msg_size: usize) -> Option<Self> {
        let id = match pending.reserve() {
            Ok(id) => id,
            Err(_) => {
                request.fail(io::Error::new(io::ErrorKind::Other,
                                            "too many pending queries")
                                       .into());
                return None
            }
        };
        let buf = match Self::new_buf(&request, id, msg_size) {
            Ok(buf) => buf,
            Err(err) => {
                request.fail(err.into());
                return None
            }
        };
        Some(DgramRequest{request: request, id: id, buf: buf})
    }

    fn new_buf(request: &Request, id: u16, msg_size: usize)
               -> ComposeResult<MessageBuf> {
        let mut buf = try!(MessageBuilder::new(Some(msg_size), true));
        buf.header_mut().set_id(id);
        buf.header_mut().set_rd(true);
        try!(Question::push(&mut buf, &request.query().name,
                            request.query().rtype, request.query().class));
        Ok(MessageBuf::from_vec(try!(buf.finish()).finish()).unwrap())
    }

    fn buf(&self) -> &[u8] {
        self.buf.as_bytes()
    }

    fn id(&self) -> u16 {
        self.id
    }

    fn respond(self, response: MessageBuf) {
        if response.is_answer(&self.buf) {
            self.request.succeed(response)
        }
        else {
            self.request.fail(io::Error::new(io::ErrorKind::Other,
                                             "server error").into())
        }
    }

    fn fail(self, err: Error) {
        self.request.fail(err)
    }

    fn timeout(self) {
        self.request.fail(Error::Timeout)
    }
}

<commit_msg>Refactor DgramService::poll_recv().<commit_after>//! Service for datagram transport.

use std::io;
use std::mem;
use std::net::SocketAddr;
use std::time::Duration;
use futures::{Async, Future, Poll};
use futures::stream::Stream;
use tokio_core::channel::{Receiver, channel};
use tokio_core::reactor;
use ::bits::{ComposeResult, MessageBuf, MessageBuilder, Question};
use super::error::Error;
use super::pending::PendingRequests;
use super::request::Request;
use super::resolver::ServiceHandle;

//------------ DgramTransport ------------------------------------------------

/// A trait for datagram transports.
///
/// This is all the methods from `UdpSocket` that `DgramService` needs.
pub trait DgramTransport {
    fn send_to(&self, buf: &[u8], target: &SocketAddr) -> io::Result<usize>;
    fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>;
    fn poll_read(&self) -> Async<()>;
}

//------------ DgramFactory --------------------------------------------------

/// A factory that creates datagram sockets.
pub trait DgramFactory: Send + 'static {
    /// The transport type produced by this factory.
    type Transport: DgramTransport;

    /// The type of the future that will eventually produce a transport.
    type Future: Future<Item=Self::Transport, Error=io::Error>;

    /// Creates a future that will resolve into a socket on the given reactor.
    fn bind(&self, reactor: &reactor::Handle) -> Self::Future;
}

//------------ DgramService --------------------------------------------------

/// A DNS service using a datagram transport.
///
/// Each datagram service communicates with exactly one remote server.
pub struct DgramService<T: DgramTransport> {
    /// The receiving end of a channel of incoming requests.
    recv: Option<Receiver<Request>>,

    /// The datagram socket.
    sock: T,

    /// The remote address to communicate with.
    peer: SocketAddr,

    /// The current outgoing request if there is one.
    write: Option<DgramRequest>,

    /// The map of outstanding requests.
    pending: PendingRequests<DgramRequest>,

    /// The maximum message size of our socket.
    msg_size: usize,
}

impl<T: DgramTransport + 'static> DgramService<T> {
    /// Creates a new datagram service and returns its service handle.
    ///
    /// What this actually does is create a convoluted future that will
    /// listen on the receiving side of the service handle’s channel until
    /// the first request arrives and only then actually create the service
    /// which will then be alive until the channel is disconnected or the
    /// datagram socket is closed.
    pub fn new<F>(factory: F, peer: SocketAddr, reactor: reactor::Handle,
                  request_timeout: Duration, msg_size: usize)
                  -> io::Result<ServiceHandle>
               where F: DgramFactory<Transport=T> {
        let (tx, rx) = try!(channel(&reactor));
        let idle = rx.into_future().map_err(|(_, _)| ());
        let received = idle.and_then(|(item, recv)| {
            match item {
                Some(request) => Ok((request, recv)),
                None => Err(())
            }
        });
        let bind_handle = reactor.clone();
        let binding = received.and_then(move |(request, recv)| {
            factory.bind(&bind_handle)
                   .map(|sock| (sock, request, recv))
                   .map_err(|_| ())
        });
        let pending_handle = reactor.clone();
        let fut = binding.and_then(move |(sock, request, recv)| {
            let mut pending = PendingRequests::new(pending_handle,
                                                   request_timeout);
            let write = DgramRequest::new(request, &mut pending, msg_size);
            let res = DgramService {
                recv: Some(recv), sock: sock, peer: peer,
                write: write, pending: pending, msg_size: msg_size,
            };
            res.map_err(|_| ())
        });
        reactor.spawn(fut);
        Ok(ServiceHandle::from_sender(tx))
    }
}

/// # Polling Helpers
///
impl<T: DgramTransport> DgramService<T> {
    /// Polls the request receiver.
    ///
    /// Returns ready iff the receiver is gone and there are no more pending
    /// requests.
    fn poll_recv(&mut self) -> Async<()> {
        if let Some(ref mut recv) = self.recv {
            if self.write.is_none() {
                match recv.poll() {
                    Ok(Async::Ready(Some(request))) => {
                        self.write = DgramRequest::new(request,
                                                       &mut self.pending,
                                                       self.msg_size);
                        return Async::NotReady
                    }
                    Ok(Async::NotReady) => return Async::NotReady,
                    Ok(Async::Ready(None)) | Err(_) => { }
                }
            }
            else { return Async::NotReady }
        }
        else {
            if self.pending.is_empty() { return Async::Ready(()) }
            else { return Async::NotReady }
        };
        self.recv = None;
        Async::NotReady
    }

    /// Poll the pending requests.
    ///
    /// That is, times out all expired requests.
    fn poll_pending(&mut self) {
        self.pending.expire(|item| item.timeout())
    }

    fn poll_write(&mut self) -> io::Result<()> {
        loop {
            let success = if let Some(ref mut request) = self.write {
                let written = match self.sock.send_to(request.buf(),
                                                      &self.peer) {
                    Ok(written) => written,
                    Err(ref e) if e.kind() == io::ErrorKind::WouldBlock
                    => {
                        return Ok(())
                    }
                    Err(err) => return Err(err)
                };
                written == request.buf().len()
            }
            else {
                return Ok(())
            };
            if let Some(request) = mem::replace(&mut self.write, None) {
                if success {
                    self.pending.push(request.id(), request)
                }
                else {
                    request.fail(io::Error::new(io::ErrorKind::Other,
                                                "short write").into());
                }
            }
        }
    }

    fn poll_read(&mut self) -> io::Result<()> {
        while let Async::Ready(()) = self.sock.poll_read() {
            let mut buf = vec![0u8; self.msg_size];
            let (size, addr) = match self.sock.recv_from(&mut buf) {
                Ok(some) => some,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    return Ok(())
                }
                Err(err) => return Err(err)
            };
            if addr != self.peer {
                return Ok(())
            }
            buf.resize(size, 0);
            let msg = match MessageBuf::from_vec(buf) {
                Ok(msg) => msg,
                Err(_) => return Ok(())
            };
            let id = msg.header().id();
            if let Some(request) = self.pending.pop(id) {
                request.respond(msg)
            }
        }
        Ok(())
    }
}

//--- Future

impl<T: DgramTransport> Future for DgramService<T> {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        match self.poll_recv() {
            Async::Ready(()) => return Ok(Async::Ready(())),
            Async::NotReady => { }
        }
        self.poll_pending();
        try!(self.poll_write());
        try!(self.poll_read());
        Ok(Async::NotReady)
    }
}

//------------ DgramRequest --------------------------------------------------

struct DgramRequest {
    request: Request,
    id: u16,
    buf: MessageBuf,
}

impl DgramRequest {
    fn new(request: Request, pending: &mut PendingRequests<Self>,
           msg_size: usize) -> Option<Self> {
        let id = match pending.reserve() {
            Ok(id) => id,
            Err(_) => {
                request.fail(io::Error::new(io::ErrorKind::Other,
                                            "too many pending queries")
                                       .into());
                return None
            }
        };
        let buf = match Self::new_buf(&request, id, msg_size) {
            Ok(buf) => buf,
            Err(err) => {
                request.fail(err.into());
                return None
            }
        };
        Some(DgramRequest{request: request, id: id, buf: buf})
    }

    fn new_buf(request: &Request, id: u16, msg_size: usize)
               -> ComposeResult<MessageBuf> {
        let mut buf = try!(MessageBuilder::new(Some(msg_size), true));
        buf.header_mut().set_id(id);
        buf.header_mut().set_rd(true);
        try!(Question::push(&mut buf, &request.query().name,
                            request.query().rtype, request.query().class));
        Ok(MessageBuf::from_vec(try!(buf.finish()).finish()).unwrap())
    }

    fn buf(&self) -> &[u8] {
        self.buf.as_bytes()
    }

    fn id(&self) -> u16 {
        self.id
    }

    fn respond(self, response: MessageBuf) {
        if response.is_answer(&self.buf) {
            self.request.succeed(response)
        }
        else {
            self.request.fail(io::Error::new(io::ErrorKind::Other,
                                             "server error").into())
        }
    }

    fn fail(self, err: Error) {
        self.request.fail(err)
    }

    fn timeout(self) {
        self.request.fail(Error::Timeout)
    }
}

<|endoftext|>


<commit_before>pub mod info;
pub mod user;
pub mod list;

use chrono;
use chrono::NaiveDateTime;
use chrono::format;
use serde::de::{self, Deserializer, Visitor, Unexpected};
use std::fmt;
use std::marker::PhantomData;

pub fn stringly_int<'de, D>(deserializer: D) -> Result<i64, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<i64>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = i64;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"int\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
			match v.parse::<i64>() {
				Ok(int) => Ok(int),
				Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &self))
			}
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

pub fn stringly_array_spaces<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<Vec<String>>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = Vec<String>;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"string\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {

			let mut list: Vec<String> = Vec::new();

			// for item in v.to_string().split_whitespace() {
			// 	list.push(item.to_string());
			// }

			v.to_string()
				.split_whitespace()
				.for_each(|x| list.push(x.to_string()));

			Ok(list)
			// Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &self))
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

/// total clusterfuck
pub fn stringly_timestamp_weird<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<NaiveDateTime>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = NaiveDateTime;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"stringed datetime\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::parse_from_str(v, "%F %T")
				.expect(&format!("failed to parse: {}", v));

			Ok(time)
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

/// better but still fucked up clusterfuck
pub fn stringly_timestamp_unix<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<NaiveDateTime>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = NaiveDateTime;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"stringed datetime\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::parse_from_str(v, "%s").unwrap();

			Ok(time)
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum Kat {
	Anime,
	Manga,
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum Medium {
	#[serde(rename = "animeseries")]
	AnimeSeries,
	#[serde(rename = "movie")]
	Movie,
	#[serde(rename = "ova")]
	OVA,
	#[serde(rename = "hentai")]
	Hentai,
	#[serde(rename = "mangaseries")]
	Manga,
	#[serde(rename = "oneshot")]
	OneShot,
	#[serde(rename = "doujin")]
	Doujin,
	#[serde(rename = "hmanga")]
	HManga,
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum State {
	#[serde(rename = "0")]
	PreAiring,
	#[serde(rename = "1")]
	Finished,
	#[serde(rename = "2")]
	Airing,
	#[serde(rename = "3")]
	Cancelled,
	#[serde(rename = "4")]
	NoSub,
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum Season {
	#[serde(rename = "0")]
	Unknown,
	#[serde(rename = "1")]
	Winter,
	#[serde(rename = "2")]
	Spring,
	#[serde(rename = "3")]
	Summer,
	#[serde(rename = "4")]
	Autumn,
}
<commit_msg>implement another custom parser: nonstringly-unix-timestamp O.o<commit_after>pub mod info;
pub mod user;
pub mod list;

use chrono;
use chrono::NaiveDateTime;
use chrono::format;
use serde::de::{self, Deserializer, Visitor, Unexpected};
use std::fmt;
use std::marker::PhantomData;

pub fn stringly_int<'de, D>(deserializer: D) -> Result<i64, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<i64>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = i64;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"int\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
			match v.parse::<i64>() {
				Ok(int) => Ok(int),
				Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &self))
			}
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

pub fn stringly_array_spaces<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<Vec<String>>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = Vec<String>;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"string\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {

			let mut list: Vec<String> = Vec::new();

			// for item in v.to_string().split_whitespace() {
			// 	list.push(item.to_string());
			// }

			v.to_string()
				.split_whitespace()
				.for_each(|x| list.push(x.to_string()));

			Ok(list)
			// Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &self))
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

/// total clusterfuck
pub fn stringly_timestamp_weird<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<NaiveDateTime>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = NaiveDateTime;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"stringed datetime\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::parse_from_str(v, "%F %T")
				.expect(&format!("failed to parse: {}", v));

			Ok(time)
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

/// better but still fucked up clusterfuck
pub fn stringly_timestamp_unix<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<NaiveDateTime>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = NaiveDateTime;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"stringed unix-timestamp\"")
		}

		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::parse_from_str(v, "%s").unwrap();

			Ok(time)
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

pub fn timestamp_unix<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
    D: Deserializer<'de>
{

	struct IntVisitor(PhantomData<NaiveDateTime>);

	impl<'a> Visitor<'a> for IntVisitor {
		type Value = NaiveDateTime;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("\"unix-timestamp\"")
		}

		fn visit_i64<E: de::Error>(self, v: i64) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::from_timestamp(v, 0);

			Ok(time)
		}

		fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::from_timestamp(v as i64, 0);

			Ok(time)
		}

		fn visit_i32<E: de::Error>(self, v: i32) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::from_timestamp(v as i64, 0);

			Ok(time)
		}

		fn visit_u32<E: de::Error>(self, v: u32) -> Result<Self::Value, E> {
			// timestamp: "2016-06-19 14:13:26",
			let time = NaiveDateTime::from_timestamp(v as i64, 0);

			Ok(time)
		}
	}

	deserializer.deserialize_any(IntVisitor(PhantomData))
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum Kat {
	Anime,
	Manga,
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum Medium {
	#[serde(rename = "animeseries")]
	AnimeSeries,
	#[serde(rename = "movie")]
	Movie,
	#[serde(rename = "ova")]
	OVA,
	#[serde(rename = "hentai")]
	Hentai,
	#[serde(rename = "mangaseries")]
	Manga,
	#[serde(rename = "oneshot")]
	OneShot,
	#[serde(rename = "doujin")]
	Doujin,
	#[serde(rename = "hmanga")]
	HManga,
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum State {
	#[serde(rename = "0")]
	PreAiring,
	#[serde(rename = "1")]
	Finished,
	#[serde(rename = "2")]
	Airing,
	#[serde(rename = "3")]
	Cancelled,
	#[serde(rename = "4")]
	NoSub,
}

#[derive(Debug, Clone, Deserialize, Hash)]
pub enum Season {
	#[serde(rename = "0")]
	Unknown,
	#[serde(rename = "1")]
	Winter,
	#[serde(rename = "2")]
	Spring,
	#[serde(rename = "3")]
	Summer,
	#[serde(rename = "4")]
	Autumn,
}
<|endoftext|>


<commit_before>extern crate serde_json;
extern crate tokio_minihttp;

extern crate futures;
extern crate futures_cpupool;

use std::io;
use std::vec::Vec;
use futures::{BoxFuture, Future};
use http::{Request, Response};
use tokio_service::Service;
use weld;
use slog;

pub struct RestService {
    pub logger: slog::Logger,
}

impl RestService {
    /// Prepares an error response , logs it, wraps to BoxFuture.
    pub fn error(&self,
                 response: Response,
                 code: u32,
                 message: &str)
                 -> BoxFuture<Response, io::Error> {
        let mut response_mut = response;
        error!(self.logger, message);
        response_mut.status_code(code, message);
        response_mut.body(message);
        return futures::future::ok(response_mut).boxed();
    }

    /// Prepares an success response, wraps to BoxFuture.
    pub fn success(&self,
                   response: Response,
                   value: &serde_json::Value)
                   -> BoxFuture<Response, io::Error> {
        let mut response_mut = response;
        let body = serde_json::to_string(&value).unwrap();
        response_mut.body(&body);
        debug!(self.logger,"Response {}",&body);
        return futures::future::ok(response_mut).boxed();
    }
}

impl Service for RestService {
    type Request = Request;
    type Response = Response;
    type Error = io::Error;
    type Future = BoxFuture<Response, io::Error>;

    fn call(&self, req: Request) -> Self::Future {
        let path = req.path();
        info!(self.logger, "{} : {} - {:?}", &path, req.method(),req);
        let parts = path.split("/").filter(|x| !x.is_empty()).collect::<Vec<_>>();

        let mut db = weld::DATABASE.lock().unwrap();
        let mut response = Response::new();
        response.header("Content-Type", "application/json");

        match parts.len() {
            // Table list
            0 => return self.success(response,&serde_json::to_value(&db.tables()).unwrap()),
            1 | 2 => {
                // Record list or record
                let table = parts.get(0).unwrap();
                let mut id = -1;
                match parts.get(1) {
                    Some(val) => {
                        if !val.is_empty() {
                            match i64::from_str_radix(val, 10) {
                                Ok(parsed) => id = parsed,
                                Err(e) => {
                                    return self.error(response,
                                                      412,
                                                      &format!("Non parsable id Error: {}", e))
                                }

                            }
                        }
                    }
                    None => {}
                }
                match req.method(){
                    "GET"=>{
                        match db.read(table, &id) {
                            Some(record) => return self.success(response, &record),
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    "POST"=>{
                        let mut payload: serde_json::Value = serde_json::from_str(req.body()).unwrap();
                        let mut payload_mut = payload.as_object_mut().unwrap();
                        match db.insert(table,payload_mut) {
                            Some(record) => {db.flush(); return self.success(response, &record)}
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    "PUT"=>{
                        let payload: serde_json::Value = serde_json::from_str(req.body()).unwrap();
                        match db.update(table,payload.as_object().unwrap().clone()) {
                            Some(record) => {db.flush(); return self.success(response, &record)}
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    "DELETE"=>{
                        match db.delete(table,&id) {
                            Some(record) => {db.flush();return self.success(response, &record)}
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    _ =>{
                        self.error(response, 405, "Method Not Allowed")
                    }
                }
            }
            _ => {
                return self.error(response, 500, "Nested structures are not implemented yet.");
            }
        }
    }
}

<commit_msg>build fixed.<commit_after>extern crate serde_json;
extern crate tokio_minihttp;

extern crate futures;
extern crate futures_cpupool;

use std::io;
use std::vec::Vec;
use futures::{BoxFuture, Future};
use http::{Request, Response};
use tokio_service::Service;
use weld;
use slog;

pub struct RestService {
    pub logger: slog::Logger,
}

impl RestService {
    /// Prepares an error response , logs it, wraps to BoxFuture.
    pub fn error(&self,
                 response: Response,
                 code: u32,
                 message: &str)
                 -> BoxFuture<Response, io::Error> {
        let mut response_mut = response;
        error!(self.logger, &message);
        response_mut.status_code(code, message);
        response_mut.body(message);
        return futures::future::ok(response_mut).boxed();
    }

    /// Prepares an success response, wraps to BoxFuture.
    pub fn success(&self,
                   response: Response,
                   value: &serde_json::Value)
                   -> BoxFuture<Response, io::Error> {
        let mut response_mut = response;
        let body = serde_json::to_string(&value).unwrap();
        response_mut.body(&body);
        debug!(self.logger,"Response {}",&body);
        return futures::future::ok(response_mut).boxed();
    }
}

impl Service for RestService {
    type Request = Request;
    type Response = Response;
    type Error = io::Error;
    type Future = BoxFuture<Response, io::Error>;

    fn call(&self, req: Request) -> Self::Future {
        let path = req.path();
        info!(self.logger, "{} : {} - {:?}", &path, req.method(),req);
        let parts = path.split("/").filter(|x| !x.is_empty()).collect::<Vec<_>>();

        let mut db = weld::DATABASE.lock().unwrap();
        let mut response = Response::new();
        response.header("Content-Type", "application/json");

        match parts.len() {
            // Table list
            0 => return self.success(response,&serde_json::to_value(&db.tables()).unwrap()),
            1 | 2 => {
                // Record list or record
                let table = parts.get(0).unwrap();
                let mut id = -1;
                match parts.get(1) {
                    Some(val) => {
                        if !val.is_empty() {
                            match i64::from_str_radix(val, 10) {
                                Ok(parsed) => id = parsed,
                                Err(e) => {
                                    return self.error(response,
                                                      412,
                                                      &format!("Non parsable id Error: {}", e))
                                }

                            }
                        }
                    }
                    None => {}
                }
                match req.method(){
                    "GET"=>{
                        match db.read(table, &id) {
                            Some(record) => return self.success(response, &record),
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    "POST"=>{
                        let mut payload: serde_json::Value = serde_json::from_str(req.body()).unwrap();
                        let mut payload_mut = payload.as_object_mut().unwrap();
                        match db.insert(table,payload_mut) {
                            Some(record) => {db.flush(); return self.success(response, &record)}
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    "PUT"=>{
                        let payload: serde_json::Value = serde_json::from_str(req.body()).unwrap();
                        match db.update(table,payload.as_object().unwrap().clone()) {
                            Some(record) => {db.flush(); return self.success(response, &record)}
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    "DELETE"=>{
                        match db.delete(table,&id) {
                            Some(record) => {db.flush();return self.success(response, &record)}
                            None => return self.error(response, 404, "Record not found"),
                        }
                    }
                    _ =>{
                        self.error(response, 405, "Method Not Allowed")
                    }
                }
            }
            _ => {
                return self.error(response, 500, "Nested structures are not implemented yet.");
            }
        }
    }
}

<|endoftext|>


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

#![allow(dead_code)]

#[derive(Default)]
/// Provides a checked way to access memory offsets from a range of raw memory
pub struct MemoryRegion {
    base: u64,
    length: u64,
}

impl MemoryRegion {
    pub const fn new(base: u64, length: u64) -> MemoryRegion {
        MemoryRegion { base, length }
    }

    /// Take a slice and turn it into a region of memory
    pub fn from_bytes(data: &mut [u8]) -> MemoryRegion {
        MemoryRegion {
            base: data.as_ptr() as u64,
            length: data.len() as u64,
        }
    }

    // Expose the entire region as a byte slice
    pub fn as_bytes(&mut self) -> &mut [u8] {
        self.as_mut_slice(0, self.length)
    }

    /// Expose a section of the memory region as a slice
    pub fn as_mut_slice<T>(&mut self, offset: u64, length: u64) -> &mut [T] {
        assert!((offset + (length * core::mem::size_of::<T>() as u64)) <= self.length);
        unsafe { core::slice::from_raw_parts_mut((self.base + offset) as *mut T, length as usize) }
    }

    /// Read a value from a given offset
    fn read<T>(&self, offset: u64) -> T
    where
        T: Copy,
    {
        assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
        unsafe { *((self.base + offset) as *const T) }
    }

    /// Read a single byte at a given offset
    pub fn read_u8(&self, offset: u64) -> u8 {
        self.read(offset)
    }

    /// Read a single word at a given offset
    pub fn read_u16(&self, offset: u64) -> u16 {
        self.read(offset)
    }

    /// Read a single dword at a given offset
    pub fn read_u32(&self, offset: u64) -> u32 {
        self.read(offset)
    }

    // Read a single qword at a given offset
    pub fn read_u64(&self, offset: u64) -> u64 {
        self.read(offset)
    }

    /// Write a value at the given offset
    pub fn write<T>(&self, offset: u64, value: T) {
        assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
        unsafe {
            *((self.base + offset) as *mut T) = value;
        }
    }

    /// Write a single byte at given offset
    pub fn write_u8(&self, offset: u64, value: u8) {
        self.write(offset, value)
    }

    /// Write a single word at given offset
    pub fn write_u16(&self, offset: u64, value: u16) {
        self.write(offset, value)
    }

    /// Write a single dword at given offset
    pub fn write_u32(&self, offset: u64, value: u32) {
        self.write(offset, value)
    }

    /// Write a single qword at given offset
    pub fn write_u64(&self, offset: u64, value: u64) {
        assert!(offset + 7 < self.length);
        unsafe {
            *((self.base + offset) as *mut u64) = value;
        }
    }

    /// Read a value at given offset with a mechanism suitable for MMIO
    fn io_read<T>(&self, offset: u64) -> T {
        assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
        unsafe { core::ptr::read_volatile((self.base + offset) as *const T) }
    }

    /// Read a single byte at given offset with a mechanism suitable for MMIO
    pub fn io_read_u8(&self, offset: u64) -> u8 {
        self.io_read(offset)
    }

    /// Read a single word at given offset with a mechanism suitable for MMIO
    pub fn io_read_u16(&self, offset: u64) -> u16 {
        self.io_read(offset)
    }

    /// Read a single dword at given offset with a mechanism suitable for MMIO
    pub fn io_read_u32(&self, offset: u64) -> u32 {
        self.io_read(offset)
    }

    /// Read a single qword at given offset with a mechanism suitable for MMIO
    pub fn io_read_u64(&self, offset: u64) -> u64 {
        self.io_read(offset)
    }

    /// Write a value at given offset using a mechanism suitable for MMIO
    fn io_write<T>(&self, offset: u64, value: T) {
        assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
        unsafe {
            core::ptr::write_volatile((self.base + offset) as *mut T, value);
        }
    }

    /// Write a single byte at given offset with a mechanism suitable for MMIO
    pub fn io_write_u8(&self, offset: u64, value: u8) {
        self.io_write(offset, value)
    }

    /// Write a single word at given offset with a mechanism suitable for MMIO
    pub fn io_write_u16(&self, offset: u64, value: u16) {
        self.io_write(offset, value)
    }

    /// Write a single dword at given offset with a mechanism suitable for MMIO
    pub fn io_write_u32(&self, offset: u64, value: u32) {
        self.io_write(offset, value)
    }

    /// Write a single qword at given offset with a mechanism suitable for MMIO
    pub fn io_write_u64(&self, offset: u64, value: u64) {
        self.io_write(offset, value)
    }
}
<commit_msg>Remove unused methods. (#3167)<commit_after>// Copyright © 2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(dead_code)]

#[derive(Default)]
/// Provides a checked way to access memory offsets from a range of raw memory
pub struct MemoryRegion {
    base: u64,
    length: u64,
}

impl MemoryRegion {
    pub const fn new(base: u64, length: u64) -> MemoryRegion {
        MemoryRegion { base, length }
    }

    /// Read a value at given offset with a mechanism suitable for MMIO
    fn io_read<T>(&self, offset: u64) -> T {
        assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
        unsafe { core::ptr::read_volatile((self.base + offset) as *const T) }
    }

    /// Read a single byte at given offset with a mechanism suitable for MMIO
    pub fn io_read_u8(&self, offset: u64) -> u8 {
        self.io_read(offset)
    }

    /// Read a single word at given offset with a mechanism suitable for MMIO
    pub fn io_read_u16(&self, offset: u64) -> u16 {
        self.io_read(offset)
    }

    /// Read a single dword at given offset with a mechanism suitable for MMIO
    pub fn io_read_u32(&self, offset: u64) -> u32 {
        self.io_read(offset)
    }

    /// Read a single qword at given offset with a mechanism suitable for MMIO
    pub fn io_read_u64(&self, offset: u64) -> u64 {
        self.io_read(offset)
    }

    /// Write a value at given offset using a mechanism suitable for MMIO
    fn io_write<T>(&self, offset: u64, value: T) {
        assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
        unsafe {
            core::ptr::write_volatile((self.base + offset) as *mut T, value);
        }
    }

    /// Write a single byte at given offset with a mechanism suitable for MMIO
    pub fn io_write_u8(&self, offset: u64, value: u8) {
        self.io_write(offset, value)
    }

    /// Write a single word at given offset with a mechanism suitable for MMIO
    pub fn io_write_u16(&self, offset: u64, value: u16) {
        self.io_write(offset, value)
    }

    /// Write a single dword at given offset with a mechanism suitable for MMIO
    pub fn io_write_u32(&self, offset: u64, value: u32) {
        self.io_write(offset, value)
    }

    /// Write a single qword at given offset with a mechanism suitable for MMIO
    pub fn io_write_u64(&self, offset: u64, value: u64) {
        self.io_write(offset, value)
    }
}
<|endoftext|>