<commit_before><commit_msg>Added some basic 2d linear algebra stuff<commit_after>
use std::ops::{Add, Sub, Mul, Neg, Div};
use std::num::Float;

// ---------------------------------------------------------------------------

#[derive(Copy)]
pub struct Vec2 {
    pub x: f32,
    pub y: f32,
}

#[derive(Copy)]
pub struct Mat3 {
    pub a00: f32, pub a01: f32, pub a02: f32,
    pub a10: f32, pub a11: f32, pub a12: f32,
    pub a20: f32, pub a21: f32, pub a22: f32,
}

#[derive(Copy)]
pub struct LineSeg {
    pub a: Vec2,
    pub b: Vec2,
}

pub const V2_ORIGIN: Vec2 = Vec2 {x:0.0, y:0.0};

pub const M3_IDENTITY: Mat3 = Mat3 {
    a00: 0.0, a01: 0.0, a02: 0.0,
    a10: 0.0, a11: 0.0, a12: 0.0,
    a20: 0.0, a21: 0.0, a22: 0.0,
};

// ----- Operator overloading ------------------------------------------------

impl Add<Vec2> for Vec2 {
    type Output = Vec2;
    fn add(self, rhs: Vec2) -> Vec2 {
        Vec2 {x: self.x + rhs.x, y: self.y + rhs.y}
    }
}

impl Sub<Vec2> for Vec2 {
    type Output = Vec2;
    fn sub(self, rhs: Vec2) -> Vec2 {
        Vec2 {x: self.x - rhs.x, y: self.y - rhs.y}
    }
}

impl Mul<f32> for Vec2 {
    type Output = Vec2;
    fn mul(self, rhs: f32) -> Vec2 {
        Vec2 {x: self.x * rhs, y: self.y * rhs}
    }
}

impl Div<f32> for Vec2 {
    type Output = Vec2;
    fn div(self, rhs: f32) -> Vec2 {
        Vec2 {x: self.x / rhs, y: self.y / rhs}
    }
}

impl Neg for Vec2 {
    type Output = Vec2;
    fn neg(self) -> Vec2 {
        Vec2 {x: -self.x, y: -self.y}
    }
}

impl Mul<Mat3> for Mat3 {
    type Output = Mat3;
    fn mul(self, rhs: Mat3) -> Mat3 {
        M3_IDENTITY //TODO
    }
}

impl Mul<Vec2> for Mat3 {
    type Output = Vec2;
    fn mul(self, rhs: Vec2) -> Vec2 {
        V2_ORIGIN //TODO
    }
}

// ---------------------------------------------------------------------------

impl Vec2 {
    pub fn new(x: f32, y: f32) -> Vec2 {
        Vec2 {x: x, y: y}
    }

    pub fn get_length_sqr(self) -> f32 {
        self.x * self.x + self.y * self.y
    }

    pub fn get_length(self) -> f32 {
        Float::sqrt(self.get_length_sqr())
    }

    pub fn dot(self, rhs: Vec2) -> f32 {
        0.0 //TODO
    }

    pub fn cross(self, rhs: Vec2) -> f32 {
        0.0 //TODO
    }

    pub fn normalize(self) -> Vec2 {
        self / self.get_length()
    }
}

impl Mat3 {
    pub fn new(a00: f32, a01: f32, a02: f32,
               a10: f32, a11: f32, a12: f32,
               a20: f32, a21: f32, a22: f32) -> Mat3 {
        Mat3 { a00: a00, a01: a01, a02: a02,
                   a10: a10, a11: a11, a12: a12,
                   a20: a20, a21: a21, a22: a22 }
    }
}

impl LineSeg {
    pub fn intersects_at(self, rhs: LineSeg) -> Option<f32> {
        None // TODO
    }

    pub fn point_at(self, t: f32) -> Vec2 {
        V2_ORIGIN // TODO
    }
}

// ---------------------------------------------------------------------------

fn main() {
    let a = Vec2 {x: -50.0, y:-50.0};
    let b = Vec2 {x:  1.0, y: 2.0};
    let c = a + b;
    println!("{}, {}", c.x, c.y);
    //println!("{}, {}", (c / 2).x, -b.y);
}

<|endoftext|>


<commit_before><commit_msg>add forgotton file<commit_after>extern crate termion;

use std::cmp::Ord;
use std::cmp::Ordering::Equal;
use std::collections::VecDeque;
use common::{prepend, move_to_front};
use ordered_vec_map::OrderedVecMap;
use termion::event::Key;

type KeyMap<T> = OrderedVecMap<Vec<termion::event::Key>, T>;
type KeyRemap = KeyMap<Vec<termion::event::Key>>;

pub struct Mode<'a, T> {
    typeahead: &'a VecDeque<Key>,
    mode: T,
}

pub struct NormalMode {}

pub struct InsertMode {}

pub struct Op {}

// TODO use an enum for modes then pattern match the return type of each mode's
// process() method, which can return any mode but modes only implement From
// a given mode type when it's appropriate!

impl<'a> Mode<'a, NormalMode> {
    pub fn new(typeahead: &'a VecDeque<Key>) -> Self {
        Mode {
            typeahead: typeahead,
            mode: NormalMode {},
        }
    }

    pub fn echo(self, string: &str) {
        println!("{}", string)
    }
}

impl<'a> From<Mode<'a, InsertMode>> for Mode<'a, NormalMode> {
    fn from(current: Mode<'a, InsertMode>) -> Mode<'a, NormalMode> {
        Mode {
            typeahead: current.typeahead,
            mode: NormalMode {},
        }
    }
}

impl<'a> From<Mode<'a, NormalMode>> for Mode<'a, InsertMode> {
    fn from(current: Mode<'a, NormalMode>) -> Mode<'a, InsertMode> {
        Mode {
            typeahead: current.typeahead,
            mode: InsertMode {},
        }
    }
}

enum Match<T> {
    FullMatch(T),
    PartialMatch(T),
    NoMatch,
}

fn find_match<'a, T>(map: &'a KeyMap<T>, query: &Vec<Key>) -> Match<&'a T> {
    let partial_matcher = |probe: &(Vec<Key>, T)| if probe.0.len() >
        query.len() &&
        probe.0.starts_with(query)
    {
        return Equal;
    } else {
        return probe.0.cmp(query);
    };

    // Check for any partial matches against the entire input, where all input
    // keys match the first N map keys.
    map.find_by(partial_matcher).map_or(
        // Then, check for full matches. If any are found, return the longest
        // full match, where all map keys match the first N input keys.
        // Otherwise, return no match.
        map.find(query).map_or(Match::NoMatch, |full| {
            Match::FullMatch(full)
        }),
        |partial| Match::PartialMatch(partial),
    )
}

pub struct ModeMap {
    // TODO Handle noremap (key,value) by surrounding value with non-input-able
    // keys, so if it gets put in the typeahead, it cannot possibly be remapped.
    // This would also mean such values would be ignored by the op-map.
    key_remap: KeyRemap,
    op_map: KeyMap<Op>,
}

fn remap(
    map: &KeyRemap,
    front: &mut Vec<Key>,
    typeahead: &mut VecDeque<Key>,
) -> bool {
    match find_match(map, front) {
        Match::FullMatch(mapped_keys) => {
            // Put mapped keys in front of the typeahead buffer.
            prepend(mapped_keys, typeahead);
            // Clear front (ergo, we'll skip matching noremap and op
            // until next iteration).
            front.clear();
            false
        }
        Match::PartialMatch(_) => {
            // Keep searching.
            false
        }
        Match::NoMatch => {
            // We're done searching this map.
            true
        }
    }
}

fn do_op(
    map: &KeyMap<Op>,
    front: &mut Vec<Key>,
    typeahead: &mut VecDeque<Key>,
) -> bool {
    match find_match(map, front) {
        Match::FullMatch(op) => {
            // TODO Apply op.
            // op()

            // Clear front (ergo, we'll skip matching noremap and op
            // until next iteration).
            front.clear();
            false
        }
        Match::PartialMatch(_) => {
            // Keep searching.
            false
        }
        Match::NoMatch => {
            // We're done searching this map.
            true
        }
    }
}

impl ModeMap {
    // Loop until a partly matching mapping is found or all (local) mappings
    // have been checked.  The longest full match is remembered in "mp_match".
    // A full match is only accepted if there is no partly match, so "aa" and
    // "aaa" can both be mapped.
    // https://github.com/vim/vim/blob/master/src/getchar.c#L2140-L2146
    pub fn process(&self, mut typeahead: &mut VecDeque<Key>) {
        // Grab incrementally more keys from the front of the queue, looking for
        // matches.
        let mut front = Vec::<Key>::with_capacity(typeahead.len());
        let mut remap_done = false;
        let mut op_done = false;
        while !typeahead.is_empty() && (!remap_done || !op_done) {
            front.push(typeahead.pop_front().unwrap());
            remap_done = remap_done ||
                remap(&self.key_remap, &mut front, &mut typeahead);
            op_done = op_done ||
                do_op(&self.op_map, &mut front, &mut typeahead);
        }
        // Put whatever is left back in the typeahead buffer.
        move_to_front(&mut front, typeahead);
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_insert_from_normal() {
        let typeahead = VecDeque::<Key>::new();
        let normal_mode = Mode::<NormalMode>::new(&typeahead);
        let _ = Mode::<InsertMode>::from(normal_mode);
    }

    #[test]
    fn test_normal_from_insert() {
        let typeahead = VecDeque::<Key>::new();
        let normal_mode = Mode::<NormalMode>::new(&typeahead);
        let insert_mode = Mode::<InsertMode>::from(normal_mode);
        let _ = Mode::<NormalMode>::from(insert_mode);
    }
}
<|endoftext|>


<commit_before><commit_msg>S1C5.<commit_after>extern crate rustc_serialize as serialize;

use serialize::hex::{ToHex};
use std::vec::Vec;

const STRING: &'static str =
    "Burning 'em, if you ain't quick and nimble\n\
    I go crazy when I hear a cymbal";

fn repeating_key_xor(text: &str, key: &str) -> String {
    let text_bytes = text.as_bytes();
    let key_bytes  = key.as_bytes();

    let mut xored: Vec<u8> = vec![0; text_bytes.len()];

    for (idx, val) in text_bytes.iter().enumerate() {
        let byte_idx   = idx % key_bytes.len();
            xored[idx] = val ^ key_bytes[byte_idx];
    }

    xored.to_hex()
}

fn main() {
    println!("{}", STRING);
    println!("{}", repeating_key_xor(STRING, "ICE"));
}

// to read from stdin:
//
// use std::io::{self, Read};
//
// let mut buffer = String::new();
//
//  io::stdin().read_to_string(&mut buffer)
//      .expect("Couldn't read.");
//
//  println!("{}", &buffer);
//  println!("{}", repeating_key_xor(&buffer, "ICE"));

<|endoftext|>


<commit_before>use std::mem;

use cell::AtomicCell;

/// A slot in memory intended to represent the communication channel between one
/// producer and one consumer.
///
/// Each slot contains space for a piece of data, `T`, and space for callbacks.
/// The callbacks can be run when the data is either full or empty.
pub struct Slot<T> {
    slot: AtomicCell<Option<T>>,
    callback: AtomicCell<Option<Box<FnBox<T>>>>,
}

/// Error value returned from erroneous calls to `try_produce`.
pub struct TryProduceError<T>(T);

/// Error value returned from erroneous calls to `try_consume`.
pub struct TryConsumeError(());

/// Error value returned from erroneous calls to `on_full`.
pub struct OnFullError(());

fn _is_send<T: Send>() {}
fn _is_sync<T: Send>() {}

fn _assert() {
    _is_send::<Slot<i32>>();
    _is_sync::<Slot<u32>>();
}

impl<T: 'static> Slot<T> {
    pub fn new(val: Option<T>) -> Slot<T> {
        Slot {
            slot: AtomicCell::new(val),
            callback: AtomicCell::new(None),
        }
    }

    pub fn try_produce(&self, t: T) -> Result<(), TryProduceError<T>> {
        let mut slot = match self.slot.borrow() {
            Some(borrow) => borrow,
            None => return Err(TryProduceError(t)),
        };
        match mem::replace(&mut *slot, Some(t)) {
            Some(t) => return Err(TryProduceError(t)),
            None => {}
        }
        drop(slot);
        let callback = self.callback.borrow().and_then(|mut cb| {
            mem::replace(&mut *cb, None)
        });
        if let Some(callback) = callback {
            callback.call_box(self);
        }
        Ok(())
    }

    pub fn on_full<F>(&self, f: F) -> Result<(), OnFullError>
        where F: FnOnce(&Slot<T>) + Send + 'static
    {
        if self.slot.borrow().map(|s| s.is_some()) == Some(true) {
            return Ok(f(self))
        }
        match self.callback.borrow() {
            Some(mut callback) => *callback = Some(Box::new(f)),
            None => return Ok(f(self)),
        }

        if self.slot.borrow().map(|s| s.is_some()) == Some(true) {
            let cb = self.callback.borrow().and_then(|mut cb| {
                mem::replace(&mut *cb, None)
            });
            if let Some(cb) = cb {
                cb.call_box(self);
            }
        }
        Ok(())
    }

    pub fn try_consume(&self) -> Result<T, TryConsumeError> {
        let mut slot = match self.slot.borrow() {
            Some(borrow) => borrow,
            None => return Err(TryConsumeError(())),
        };
        match mem::replace(&mut *slot, None) {
            Some(t) => Ok(t),
            None => Err(TryConsumeError(())),
        }
    }
}

trait FnBox<T: 'static>: Send + 'static {
    fn call_box(self: Box<Self>, other: &Slot<T>);
}

impl<T, F> FnBox<T> for F
    where F: FnOnce(&Slot<T>) + Send + 'static,
          T: 'static,
{
    fn call_box(self: Box<F>, other: &Slot<T>) {
        (*self)(other)
    }
}
<commit_msg>slot WIP<commit_after>use cell::AtomicCell;

/// A slot in memory intended to represent the communication channel between one
/// producer and one consumer.
///
/// Each slot contains space for a piece of data, `T`, and space for callbacks.
/// The callbacks can be run when the data is either full or empty.
pub struct Slot<T> {
    slot: AtomicCell<Option<T>>,
    callback: AtomicCell<Option<Box<FnBox<T>>>>,
}

/// Error value returned from erroneous calls to `try_produce`.
#[derive(Debug, PartialEq)]
pub struct TryProduceError<T>(T);

/// Error value returned from erroneous calls to `try_consume`.
#[derive(Debug, PartialEq)]
pub struct TryConsumeError(());

/// Error value returned from erroneous calls to `on_full`.
#[derive(Debug, PartialEq)]
pub struct OnFullError(());

/// Error value returned from erroneous calls to `on_empty`.
#[derive(Debug, PartialEq)]
pub struct OnEmptyError(());

fn _is_send<T: Send>() {}
fn _is_sync<T: Send>() {}

fn _assert() {
    _is_send::<Slot<i32>>();
    _is_sync::<Slot<u32>>();
}

impl<T: 'static> Slot<T> {
    pub fn new(val: Option<T>) -> Slot<T> {
        Slot {
            slot: AtomicCell::new(val),
            callback: AtomicCell::new(None),
        }
    }

    // PRODUCER
    pub fn try_produce(&self, t: T) -> Result<(), TryProduceError<T>> {
        let mut slot = match self.slot.borrow() {
            Some(borrow) => borrow,
            None => {
                println!("producer interference");
                return Err(TryProduceError(t))
            }
        };
        if slot.is_some() {
            println!("producer already produced");
            return Err(TryProduceError(t))
        }
        *slot = Some(t);
        println!("producer producing");
        drop(slot);
        let callback = self.callback.borrow().and_then(|mut cb| cb.take());
        if let Some(callback) = callback {
            println!("producer running callback");
            callback.call_box(self);
        }
        Ok(())
    }

    // PRODUCER
    pub fn on_empty<F>(&self, f: F) -> Result<(), OnEmptyError>
        where F: FnOnce(&Slot<T>) + Send + 'static
    {
        if self.slot.borrow().map(|s| s.is_none()) == Some(true) {
            println!("on_empty immediate");
            return Ok(f(self))
        }
        match self.callback.borrow() {
            Some(mut callback) => {
                if callback.is_some() {
                    println!("on_empty already full");
                    drop(callback);
                    return Ok(f(self))
                } else {
                    *callback = Some(Box::new(f));
                    println!("on_empty callback registered");
                }
            }
            None => {
                println!("on_empty interference");
                return Ok(f(self))
            }
        }

        if self.slot.borrow().map(|s| s.is_none()) == Some(true) {
            println!("on_empty looking for callback");
            let cb = self.callback.borrow().and_then(|mut cb| cb.take());
            if let Some(cb) = cb {
                println!("on_empty running callback");
                cb.call_box(self);
            }
        }
        Ok(())
    }

    // CONSUMER
    pub fn try_consume(&self) -> Result<T, TryConsumeError> {
        let mut slot = match self.slot.borrow() {
            Some(borrow) => borrow,
            None => {
                println!("consumer interference");
                return Err(TryConsumeError(()))
            }
        };
        let val = match slot.take() {
            Some(t) => t,
            None => {
                println!("consumer nothing available");
                return Err(TryConsumeError(()))
            }
        };
        println!("consumer consumed");
        drop(slot);
        let callback = self.callback.borrow().and_then(|mut cb| cb.take());
        if let Some(callback) = callback {
            println!("consumer running callback");
            callback.call_box(self);
        }
        Ok(val)
    }

    // CONSUMER
    pub fn on_full<F>(&self, f: F) -> Result<(), OnFullError>
        where F: FnOnce(&Slot<T>) + Send + 'static
    {
        if self.slot.borrow().map(|s| s.is_some()) == Some(true) {
            println!("on full immediate");
            return Ok(f(self))
        }

        match self.callback.borrow() {
            Some(mut callback) => {
                if callback.is_some() {
                    println!("on full already full");
                    drop(callback);
                    return Ok(f(self))
                } else {
                    *callback = Some(Box::new(f));
                    println!("on_full callback registered");
                }
            }
            None => {
                println!("on full interference");
                return Ok(f(self))
            }
        }

        if self.slot.borrow().map(|s| s.is_some()) == Some(true) {
            println!("on full looking for callback");
            let cb = self.callback.borrow().and_then(|mut cb| cb.take());
            if let Some(cb) = cb {
                println!("on full callback");
                cb.call_box(self);
            }
        }
        Ok(())
    }
}

trait FnBox<T: 'static>: Send + 'static {
    fn call_box(self: Box<Self>, other: &Slot<T>);
}

impl<T, F> FnBox<T> for F
    where F: FnOnce(&Slot<T>) + Send + 'static,
          T: 'static,
{
    fn call_box(self: Box<F>, other: &Slot<T>) {
        (*self)(other)
    }
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    use super::Slot;

    #[test]
    fn sequential() {
        let slot = Slot::new(Some(1));

        // We can consume once
        assert_eq!(slot.try_consume(), Ok(1));
        assert!(slot.try_consume().is_err());

        // Consume a production
        assert_eq!(slot.try_produce(2), Ok(()));
        assert_eq!(slot.try_consume(), Ok(2));

        // Can't produce twice
        assert_eq!(slot.try_produce(3), Ok(()));
        assert!(slot.try_produce(3).is_err());

        // on_full is run immediately if full
        let hit = Arc::new(AtomicUsize::new(0));
        let hit2 = hit.clone();
        assert!(slot.on_full(move |_s| {
            hit2.fetch_add(1, Ordering::SeqCst);
        }).is_ok());
        assert_eq!(hit.load(Ordering::SeqCst), 1);

        // on_full can be run twice, and we can consume in the callback
        let hit2 = hit.clone();
        assert!(slot.on_full(move |s| {
            hit2.fetch_add(1, Ordering::SeqCst);
            assert_eq!(s.try_consume(), Ok(3));
        }).is_ok());
        assert_eq!(hit.load(Ordering::SeqCst), 2);

        // Production can't run a previous callback
        assert_eq!(slot.try_produce(4), Ok(()));
        assert_eq!(hit.load(Ordering::SeqCst), 2);
        assert_eq!(slot.try_consume(), Ok(4));

        // Productions run new callbacks
        let hit2 = hit.clone();
        assert!(slot.on_full(move |s| {
            hit2.fetch_add(1, Ordering::SeqCst);
            assert_eq!(s.try_consume(), Ok(5));
        }).is_ok());
        assert_eq!(slot.try_produce(5), Ok(()));
        assert_eq!(hit.load(Ordering::SeqCst), 3);

        // callbacks don't run when consuming
        assert!(slot.on_full(|_s| {}).is_ok());
        assert!(slot.try_consume().is_err());
        assert!(slot.try_produce(4).is_ok());
    }

    #[test]
    fn channel() {
        const N: usize = 1000;

        struct Sender {
            slot: Arc<Slot<usize>>,
            hit: Arc<AtomicUsize>,
        }

        struct Receiver {
            slot: Arc<Slot<usize>>,
            hit: Arc<AtomicUsize>,
        }

        impl Sender {
            fn send(&self, val: usize) {
                if self.slot.try_produce(val).is_ok() {
                    return
                }
                let me = thread::current();
                self.hit.store(0, Ordering::SeqCst);
                let hit = self.hit.clone();
                assert!(self.slot.on_empty(move |_slot| {
                    hit.store(1, Ordering::SeqCst);
                    me.unpark();
                }).is_ok());
                while self.hit.load(Ordering::SeqCst) == 0 {
                    thread::park();
                }
                self.slot.try_produce(val).expect("can't produce after on_empty")
            }
        }

        impl Receiver {
            fn recv(&self) -> usize {
                if let Ok(i) = self.slot.try_consume() {
                    return i
                }

                let me = thread::current();
                self.hit.store(0, Ordering::SeqCst);
                let hit = self.hit.clone();
                assert!(self.slot.on_full(move |_slot| {
                    hit.store(1, Ordering::SeqCst);
                    me.unpark();
                }).is_ok());
                while self.hit.load(Ordering::SeqCst) == 0 {
                    thread::park();
                }
                self.slot.try_consume().expect("can't consume after on_full")
            }
        }

        let slot = Arc::new(Slot::new(None));
        let slot2 = slot.clone();

        let tx = Sender { slot: slot2, hit: Arc::new(AtomicUsize::new(0)) };
        let rx = Receiver { slot: slot, hit: Arc::new(AtomicUsize::new(0)) };

        let a = thread::spawn(move || {
            for i in 0..N {
                assert_eq!(rx.recv(), i);
            }
        });

        for i in 0..N {
            tx.send(i);
        }

        a.join().unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>Forgot text module<commit_after>use Renderable;
use std::collections::HashMap;

pub struct Text{
    text: String
}

impl Renderable for Text {
    fn render (&self, context: &HashMap<String, String>) -> String{
        self.text.to_string()
    }
}

impl Text {
    pub fn new(text: &str) -> Text {
        Text{text: text.to_string()}
    }
}

<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;

use chrono::naive::datetime::NaiveDateTime;
use chrono::Datelike;
use chrono::Timelike;

use libimagstore::storeid::StoreId;

use datepath::accuracy::Accuracy;
use datepath::format::Format;
use datepath::result::Result;
use datepath::error::DatePathCompilerErrorKind as DPCEK;
use datepath::error::MapErrInto;

pub struct DatePathCompiler {
    accuracy : Accuracy,
    format   : Format,
}

impl DatePathCompiler {

    pub fn new(accuracy: Accuracy, format: Format) -> DatePathCompiler {
        DatePathCompiler {
            accuracy : accuracy,
            format   : format,
        }
    }

    /// Compile a NaiveDateTime object into a StoreId object.
    ///
    /// # More information
    ///
    /// See the documentations of the `Format` and the `Accuracy` types as well.
    ///
    /// # Warnings
    ///
    /// This does _not_ guarantee that the StoreId can be created, is not yet in the store or
    /// anything else. Overall, this is just a `spec->path` compiler which is really stupid.
    ///
    /// # Return value
    ///
    /// The `StoreId` object on success.
    ///
    pub fn compile(&self, module_name: &str, datetime: &NaiveDateTime) -> Result<StoreId> {
        let mut s = format!("{}/", module_name);

        if self.accuracy.has_year_accuracy() /* always true */ {
            s.push_str(&format!("{}", datetime.year()));
        }

        if self.accuracy.has_month_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    | Format::YearIsFolder
                    => s.push_str(&format!("/{}", datetime.month())),
            }
        }

        if self.accuracy.has_day_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("/{}", datetime.day())),
                Format::YearIsFolder
                    => s.push_str(&format!("-{}", datetime.day())),
            }
        }

        if self.accuracy.has_hour_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("/{}", datetime.hour())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("-{}", datetime.hour())),
            }
        }

        if self.accuracy.has_minute_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.minute())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.minute())),
            }
        }

        if self.accuracy.has_second_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.second())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.second())),
            }
        }

        StoreId::new_baseless(PathBuf::from(s))
            .map_err_into(DPCEK::StoreIdBuildFailed)
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use datepath::accuracy::Accuracy;
    use datepath::format::Format;

    use chrono::naive::date::NaiveDate;

    #[test]
    fn test_compiler_compile_simple() {
        let dt       = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        let compiler = DatePathCompiler::new(Accuracy::default(), Format::default())
        let res      = compiler.compile("testmodule", &dt);

        assert!(res.is_ok());
        let res = res.unwrap();

        let s = res.to_str();

        assert!(s.is_ok());
        let s = s.unwrap();

        assert_eq!("testmodule/2000/1/1/0/0/0", s);
    }

}

<commit_msg>Add more tests<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;

use chrono::naive::datetime::NaiveDateTime;
use chrono::Datelike;
use chrono::Timelike;

use libimagstore::storeid::StoreId;

use datepath::accuracy::Accuracy;
use datepath::format::Format;
use datepath::result::Result;
use datepath::error::DatePathCompilerErrorKind as DPCEK;
use datepath::error::MapErrInto;

pub struct DatePathCompiler {
    accuracy : Accuracy,
    format   : Format,
}

impl DatePathCompiler {

    pub fn new(accuracy: Accuracy, format: Format) -> DatePathCompiler {
        DatePathCompiler {
            accuracy : accuracy,
            format   : format,
        }
    }

    /// Compile a NaiveDateTime object into a StoreId object.
    ///
    /// # More information
    ///
    /// See the documentations of the `Format` and the `Accuracy` types as well.
    ///
    /// # Warnings
    ///
    /// This does _not_ guarantee that the StoreId can be created, is not yet in the store or
    /// anything else. Overall, this is just a `spec->path` compiler which is really stupid.
    ///
    /// # Return value
    ///
    /// The `StoreId` object on success.
    ///
    pub fn compile(&self, module_name: &str, datetime: &NaiveDateTime) -> Result<StoreId> {
        let mut s = format!("{}/", module_name);

        if self.accuracy.has_year_accuracy() /* always true */ {
            s.push_str(&format!("{}", datetime.year()));
        }

        if self.accuracy.has_month_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    | Format::YearIsFolder
                    => s.push_str(&format!("/{}", datetime.month())),
            }
        }

        if self.accuracy.has_day_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("/{}", datetime.day())),
                Format::YearIsFolder
                    => s.push_str(&format!("-{}", datetime.day())),
            }
        }

        if self.accuracy.has_hour_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("/{}", datetime.hour())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("-{}", datetime.hour())),
            }
        }

        if self.accuracy.has_minute_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.minute())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.minute())),
            }
        }

        if self.accuracy.has_second_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.second())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.second())),
            }
        }

        StoreId::new_baseless(PathBuf::from(s))
            .map_err_into(DPCEK::StoreIdBuildFailed)
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use datepath::accuracy::Accuracy;
    use datepath::format::Format;

    use chrono::naive::date::NaiveDate;
    use chrono::naive::datetime::NaiveDateTime;

    #[test]
    fn test_compiler_compile_simple() {
        let dt       = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        let compiler = DatePathCompiler::new(Accuracy::default(), Format::default());
        let res      = compiler.compile("testmodule", &dt);

        assert!(res.is_ok());
        let res = res.unwrap();

        let s = res.to_str();

        assert!(s.is_ok());
        let s = s.unwrap();

        assert_eq!("testmodule/2000/1/1/0/0/0", s);
    }

    fn test_accuracy(acc: Accuracy, dt: NaiveDateTime, modname: &str, matchstr: &str) {
        let compiler = DatePathCompiler::new(acc, Format::default());
        let res      = compiler.compile(modname, &dt);

        assert!(res.is_ok());
        let res = res.unwrap();

        let s = res.to_str();

        assert!(s.is_ok());
        let s = s.unwrap();

        assert_eq!(matchstr, s);
    }

    #[test]
    fn test_compiler_compile_year_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Year, dt, "module", "module/2000");
    }

    #[test]
    fn test_compiler_compile_month_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Month, dt, "module", "module/2000/1");
    }

    #[test]
    fn test_compiler_compile_day_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Day, dt, "module", "module/2000/1/1");
    }

}

<|endoftext|>


<commit_before><commit_msg>Add test for {impl,declare}_lint_pass macros<commit_after>// compile-flags: -Z unstable-options
// check-pass

#![feature(rustc_private)]

extern crate rustc_session;

use rustc_session::lint::{LintArray, LintPass};
use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};

declare_lint! {
    pub TEST_LINT,
    Allow,
    "test"
}

struct Foo;

struct Bar<'a>(&'a u32);

impl_lint_pass!(Foo => [TEST_LINT]);
impl_lint_pass!(Bar<'_> => [TEST_LINT]);

declare_lint_pass!(Baz => [TEST_LINT]);

fn main() {}
<|endoftext|>


<commit_before><commit_msg>rust snippets: minor modification<commit_after><|endoftext|>


<commit_before>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type hashfn<K> = pure fn~(K) -> uint;
type eqfn<K> = pure fn~(K, K) -> bool;

/// Open addressing with linear probing.
mod linear {
    export linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    type bucket<K,V> = {hash: uint, key: K, value: V};
    enum linear_map<K,V> {
        linear_map_({
            hashfn: pure fn~(x: &K) -> uint,
            eqfn: pure fn~(x: &K, y: &K) -> bool,
            resize_at: uint,
            size: uint,
            buckets: ~[option<bucket<K,V>>]})
    }

    // FIXME(#2979) -- with #2979 we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    enum search_result {
        found_entry(uint), found_hole(uint), table_full
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn linear_map<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> linear_map<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> linear_map<K,V> {

        linear_map_({
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| none)})
    }

    // FIXME(#2979) would allow us to use region type for k
    unsafe fn borrow<K>(&&k: K) -> &K {
        let p: *K = ptr::addr_of(k);
        p as &K
    }

    impl private_methods<K,V> for &const linear_map<K,V> {
        #[inline(always)]
        pure fn to_bucket(h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(idx: uint, len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!{"next_bucket(%?, %?) = %?", idx, len_buckets, n};
            }
            ret n;
        }

        #[inline(always)]
        pure fn bucket_sequence(hash: uint, op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    ret idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    ret start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(
            buckets: &[option<bucket<K,V>>],
            k: &K) -> search_result {

            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(
            buckets: &[option<bucket<K,V>>],
            hash: uint,
            k: &K) -> search_result {

            let _ = for self.bucket_sequence(hash) |i| {
                alt buckets[i] {
                  some(bkt) {
                    if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                        ret found_entry(i);
                    }
                  }
                  none => {
                    ret found_hole(i);
                  }
                }
            };
            ret table_full;
        }
    }

    impl private_methods<K,V> for &mut linear_map<K,V> {
        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand() {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| none);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = none;
                bucket <-> old_buckets[i];
                if bucket.is_some() {
                    self.insert_bucket(bucket);
                }
            }
        }

        fn insert_bucket(+bucket: option<bucket<K,V>>) {
            let {hash, key, value} <- option::unwrap(bucket);
            let _ = self.insert_internal(hash, key, value);
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(hash: uint, +k: K, +v: V) -> bool {
            alt self.bucket_for_key_with_hash(self.buckets, hash,
                                              unsafe{borrow(k)}) {
              table_full => {fail ~"Internal logic error";}
              found_hole(idx) {
                debug!{"insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                self.size += 1;
                ret true;
              }
              found_entry(idx) => {
                debug!{"insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                ret false;
              }
            }
        }
    }

    impl public_methods<K,V> for &mut linear_map<K,V> {
        fn insert(+k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(unsafe{borrow(k)});
            self.insert_internal(hash, k, v)
        }

        fn remove(k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = alt self.bucket_for_key(self.buckets, k) {
              table_full | found_hole(_) => {
                ret false;
              }
              found_entry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = none;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = none;
                bucket <-> self.buckets[idx];
                self.insert_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            ret true;
        }
    }

    impl private_methods<K,V> for &linear_map<K,V> {
        fn search(hash: uint, op: fn(x: &option<bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl public_methods<K,V> for &const linear_map<K,V> {
        fn size() -> uint {
            self.size
        }

        fn contains_key(k: &K) -> bool {
            alt self.bucket_for_key(self.buckets, k) {
              found_entry(_) => {true}
              table_full | found_hole(_) => {false}
            }
        }
    }

    impl public_methods<K,V: copy> for &const linear_map<K,V> {
        fn find(k: &K) -> option<V> {
            alt self.bucket_for_key(self.buckets, k) {
              found_entry(idx) => {
                alt check self.buckets[idx] {
                  some(bkt) => {some(copy bkt.value)}
                }
              }
              table_full | found_hole(_) => {
                none
              }
            }
        }

        fn get(k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!{"No entry found for key: %?", k};
            }
            option::unwrap(value)
        }

        fn [](k: &K) -> V {
            self.get(k)
        }
    }

    /*
    FIXME --- #2979 must be fixed to typecheck this
    impl imm_methods<K,V> for &linear_map<K,V> {
        fn find_ptr(k: K) -> option<&V> {
            //XXX this should not type check as written, but it should
            //be *possible* to typecheck it...
            self.with_ptr(k, |v| v)
        }
    }
    */
}

#[test]
mod test {

    import linear::linear_map;

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> linear_map<uint,V> {
        ret linear_map(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }
}<commit_msg>Add send_map::each{,_key,_value}<commit_after>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type hashfn<K> = pure fn~(K) -> uint;
type eqfn<K> = pure fn~(K, K) -> bool;

/// Open addressing with linear probing.
mod linear {
    export linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    type bucket<K,V> = {hash: uint, key: K, value: V};
    enum linear_map<K,V> {
        linear_map_({
            hashfn: pure fn~(x: &K) -> uint,
            eqfn: pure fn~(x: &K, y: &K) -> bool,
            resize_at: uint,
            size: uint,
            buckets: ~[option<bucket<K,V>>]})
    }

    // FIXME(#2979) -- with #2979 we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    enum search_result {
        found_entry(uint), found_hole(uint), table_full
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn linear_map<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> linear_map<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> linear_map<K,V> {

        linear_map_({
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| none)})
    }

    // FIXME(#2979) would allow us to use region type for k
    unsafe fn borrow<K>(&&k: K) -> &K {
        let p: *K = ptr::addr_of(k);
        p as &K
    }

    impl private_methods<K,V> for &const linear_map<K,V> {
        #[inline(always)]
        pure fn to_bucket(h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(idx: uint, len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!{"next_bucket(%?, %?) = %?", idx, len_buckets, n};
            }
            ret n;
        }

        #[inline(always)]
        pure fn bucket_sequence(hash: uint, op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    ret idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    ret start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(
            buckets: &[option<bucket<K,V>>],
            k: &K) -> search_result {

            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(
            buckets: &[option<bucket<K,V>>],
            hash: uint,
            k: &K) -> search_result {

            let _ = for self.bucket_sequence(hash) |i| {
                alt buckets[i] {
                  some(bkt) {
                    if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                        ret found_entry(i);
                    }
                  }
                  none => {
                    ret found_hole(i);
                  }
                }
            };
            ret table_full;
        }
    }

    impl private_methods<K,V> for &mut linear_map<K,V> {
        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand() {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| none);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = none;
                bucket <-> old_buckets[i];
                if bucket.is_some() {
                    self.insert_bucket(bucket);
                }
            }
        }

        fn insert_bucket(+bucket: option<bucket<K,V>>) {
            let {hash, key, value} <- option::unwrap(bucket);
            let _ = self.insert_internal(hash, key, value);
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(hash: uint, +k: K, +v: V) -> bool {
            alt self.bucket_for_key_with_hash(self.buckets, hash,
                                              unsafe{borrow(k)}) {
              table_full => {fail ~"Internal logic error";}
              found_hole(idx) {
                debug!{"insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                self.size += 1;
                ret true;
              }
              found_entry(idx) => {
                debug!{"insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                ret false;
              }
            }
        }
    }

    impl public_methods<K,V> for &mut linear_map<K,V> {
        fn insert(+k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(unsafe{borrow(k)});
            self.insert_internal(hash, k, v)
        }

        fn remove(k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = alt self.bucket_for_key(self.buckets, k) {
              table_full | found_hole(_) => {
                ret false;
              }
              found_entry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = none;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = none;
                bucket <-> self.buckets[idx];
                self.insert_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            ret true;
        }
    }

    impl private_methods<K,V> for &linear_map<K,V> {
        fn search(hash: uint, op: fn(x: &option<bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl public_methods<K,V> for &const linear_map<K,V> {
        fn size() -> uint {
            self.size
        }

        fn contains_key(k: &K) -> bool {
            alt self.bucket_for_key(self.buckets, k) {
              found_entry(_) => {true}
              table_full | found_hole(_) => {false}
            }
        }
    }

    impl public_methods<K,V: copy> for &const linear_map<K,V> {
        fn find(k: &K) -> option<V> {
            alt self.bucket_for_key(self.buckets, k) {
              found_entry(idx) => {
                alt check self.buckets[idx] {
                  some(bkt) => {some(copy bkt.value)}
                }
              }
              table_full | found_hole(_) => {
                none
              }
            }
        }

        fn get(k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!{"No entry found for key: %?", k};
            }
            option::unwrap(value)
        }

        fn [](k: &K) -> V {
            self.get(k)
        }
    }

    impl imm_methods<K,V> for &linear_map<K,V> {
        /*
        FIXME --- #2979 must be fixed to typecheck this
        fn find_ptr(k: K) -> option<&V> {
            //XXX this should not type check as written, but it should
            //be *possible* to typecheck it...
            self.with_ptr(k, |v| v)
        }
        */

        fn each(blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }
        fn each_key(blk: fn(k: &K) -> bool) {
            self.each(|k, _v| blk(k))
        }
        fn each_value(blk: fn(v: &V) -> bool) {
            self.each(|_k, v| blk(v))
        }
    }
}

#[test]
mod test {

    import linear::linear_map;

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> linear_map<uint,V> {
        ret linear_map(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }
}
<|endoftext|>


<commit_before>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type HashFn<K> = pure fn~(K) -> uint;
type EqFn<K> = pure fn~(K, K) -> bool;

trait send_map<K, V: copy> {
    // FIXME(#3148)  ^^^^ once find_ref() works, we can drop V:copy

    fn insert(&mut self, +k: K, +v: V) -> bool;
    fn remove(&mut self, k: &K) -> bool;
    fn clear(&mut self);
    pure fn len(&const self) -> uint;
    pure fn is_empty(&const self) -> bool;
    fn contains_key(&const self, k: &K) -> bool;
    fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool);
    fn each_key_ref(&self, blk: fn(k: &K) -> bool);
    fn each_value_ref(&self, blk: fn(v: &V) -> bool);
    fn find(&const self, k: &K) -> Option<V>;
    fn get(&const self, k: &K) -> V;
}

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    struct Bucket<K,V> {
        hash: uint;
        key: K;
        value: V;
    }
    struct LinearMap<K,V> {
        hashfn: pure fn~(x: &K) -> uint;
        eqfn: pure fn~(x: &K, y: &K) -> bool;
        resize_at: uint;
        size: uint;
        buckets: ~[Option<Bucket<K,V>>];
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn LinearMap<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> LinearMap<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> LinearMap<K,V> {

        LinearMap {
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| None)
        }
    }

    priv impl<K, V> LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(&const self,
                          h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(&const self,
                            idx: uint,
                            len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n);
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(&const self,
                                hash: uint,
                                op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(&const self,
                               buckets: &[Option<Bucket<K,V>>],
                               k: &K) -> SearchResult {
            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(&const self,
                                         buckets: &[Option<Bucket<K,V>>],
                                         hash: uint,
                                         k: &K) -> SearchResult {
            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                  Some(bkt) => if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                    return FoundEntry(i);
                  },
                  None => return FoundHole(i)
                }
            };
            return TableFull;
        }

        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand(&mut self) {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| None);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = None;
                bucket <-> old_buckets[i];
                self.insert_opt_bucket(bucket);
            }
        }

        fn insert_opt_bucket(&mut self, +bucket: Option<Bucket<K,V>>) {
            match move bucket {
              Some(Bucket {hash: move hash,
                           key: move key,
                           value: move value}) => {
                self.insert_internal(hash, key, value);
              }
              None => {}
            }
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
              TableFull => {fail ~"Internal logic error";}
              FoundHole(idx) => {
                debug!("insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = Some(Bucket {hash: hash,
                                                 key: k,
                                                 value: v});
                self.size += 1;
                return true;
              }
              FoundEntry(idx) => {
                debug!("insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = Some(Bucket {hash: hash,
                                                 key: k,
                                                 value: v});
                return false;
              }
            }
        }

        fn search(&self,
                  hash: uint,
                  op: fn(x: &Option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K,V> LinearMap<K,V> {
        fn insert(&mut self, +k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(&k);
            self.insert_internal(hash, k, v)
        }

        fn remove(&mut self, k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
              TableFull | FoundHole(_) => {
                return false;
              }
              FoundEntry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = None;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = None;
                bucket <-> self.buckets[idx];
                self.insert_opt_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear(&mut self) {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = None;
            }
            self.size = 0;
        }

        pure fn len(&const self) -> uint {
            self.size
        }

        pure fn is_empty(&const self) -> bool {
            self.len() == 0
        }

        fn contains_key(&const self,
                        k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(_) => {true}
              TableFull | FoundHole(_) => {false}
            }
        }

        /*
        FIXME(#3148)--region inference fails to capture needed deps

        fn find_ref(&self, k: &K) -> option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(ref bkt) => some(&bkt.value)
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }
        */

        fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }

        fn each_key_ref(&self, blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }

        fn each_value_ref(&self, blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K,V: copy> LinearMap<K,V> {
        fn find(&const self, k: &K) -> Option<V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                // FIXME (#3148): Once we rewrite found_entry, this
                // failure case won't be necessary
                match self.buckets[idx] {
                    Some(bkt) => {Some(copy bkt.value)}
                    None => fail ~"LinearMap::find: internal logic error"
                }
              }
              TableFull | FoundHole(_) => {
                None
              }
            }
        }

        fn get(&const self, k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!("No entry found for key: %?", k);
            }
            option::unwrap(value)
        }

    }

    impl<K: copy, V: copy> LinearMap<K,V> {
        fn each(&self, blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: copy, V> LinearMap<K,V> {
        fn each_key(&self, blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K, V: copy> LinearMap<K,V> {
        fn each_value(&self, blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    import linear::LinearMap;

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return LinearMap(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        for uint::range(0, 32) |i| {
            assert (&mut m).insert(i, i*2);
        }
        let mut observed = 0;
        for (&m).each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }
}
<commit_msg>correct name of SendMap trait<commit_after>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type HashFn<K> = pure fn~(K) -> uint;
type EqFn<K> = pure fn~(K, K) -> bool;

trait SendMap<K, V: copy> {
    // FIXME(#3148)  ^^^^ once find_ref() works, we can drop V:copy

    fn insert(&mut self, +k: K, +v: V) -> bool;
    fn remove(&mut self, k: &K) -> bool;
    fn clear(&mut self);
    pure fn len(&const self) -> uint;
    pure fn is_empty(&const self) -> bool;
    fn contains_key(&const self, k: &K) -> bool;
    fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool);
    fn each_key_ref(&self, blk: fn(k: &K) -> bool);
    fn each_value_ref(&self, blk: fn(v: &V) -> bool);
    fn find(&const self, k: &K) -> Option<V>;
    fn get(&const self, k: &K) -> V;
}

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    struct Bucket<K,V> {
        hash: uint;
        key: K;
        value: V;
    }
    struct LinearMap<K,V> {
        hashfn: pure fn~(x: &K) -> uint;
        eqfn: pure fn~(x: &K, y: &K) -> bool;
        resize_at: uint;
        size: uint;
        buckets: ~[Option<Bucket<K,V>>];
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn LinearMap<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> LinearMap<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> LinearMap<K,V> {

        LinearMap {
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| None)
        }
    }

    priv impl<K, V> LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(&const self,
                          h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(&const self,
                            idx: uint,
                            len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n);
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(&const self,
                                hash: uint,
                                op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(&const self,
                               buckets: &[Option<Bucket<K,V>>],
                               k: &K) -> SearchResult {
            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(&const self,
                                         buckets: &[Option<Bucket<K,V>>],
                                         hash: uint,
                                         k: &K) -> SearchResult {
            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                  Some(bkt) => if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                    return FoundEntry(i);
                  },
                  None => return FoundHole(i)
                }
            };
            return TableFull;
        }

        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand(&mut self) {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| None);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = None;
                bucket <-> old_buckets[i];
                self.insert_opt_bucket(bucket);
            }
        }

        fn insert_opt_bucket(&mut self, +bucket: Option<Bucket<K,V>>) {
            match move bucket {
              Some(Bucket {hash: move hash,
                           key: move key,
                           value: move value}) => {
                self.insert_internal(hash, key, value);
              }
              None => {}
            }
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
              TableFull => {fail ~"Internal logic error";}
              FoundHole(idx) => {
                debug!("insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = Some(Bucket {hash: hash,
                                                 key: k,
                                                 value: v});
                self.size += 1;
                return true;
              }
              FoundEntry(idx) => {
                debug!("insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = Some(Bucket {hash: hash,
                                                 key: k,
                                                 value: v});
                return false;
              }
            }
        }

        fn search(&self,
                  hash: uint,
                  op: fn(x: &Option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K,V> LinearMap<K,V> {
        fn insert(&mut self, +k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(&k);
            self.insert_internal(hash, k, v)
        }

        fn remove(&mut self, k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
              TableFull | FoundHole(_) => {
                return false;
              }
              FoundEntry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = None;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = None;
                bucket <-> self.buckets[idx];
                self.insert_opt_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear(&mut self) {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = None;
            }
            self.size = 0;
        }

        pure fn len(&const self) -> uint {
            self.size
        }

        pure fn is_empty(&const self) -> bool {
            self.len() == 0
        }

        fn contains_key(&const self,
                        k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(_) => {true}
              TableFull | FoundHole(_) => {false}
            }
        }

        /*
        FIXME(#3148)--region inference fails to capture needed deps

        fn find_ref(&self, k: &K) -> option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(ref bkt) => some(&bkt.value)
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }
        */

        fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }

        fn each_key_ref(&self, blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }

        fn each_value_ref(&self, blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K,V: copy> LinearMap<K,V> {
        fn find(&const self, k: &K) -> Option<V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                // FIXME (#3148): Once we rewrite found_entry, this
                // failure case won't be necessary
                match self.buckets[idx] {
                    Some(bkt) => {Some(copy bkt.value)}
                    None => fail ~"LinearMap::find: internal logic error"
                }
              }
              TableFull | FoundHole(_) => {
                None
              }
            }
        }

        fn get(&const self, k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!("No entry found for key: %?", k);
            }
            option::unwrap(value)
        }

    }

    impl<K: copy, V: copy> LinearMap<K,V> {
        fn each(&self, blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: copy, V> LinearMap<K,V> {
        fn each_key(&self, blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K, V: copy> LinearMap<K,V> {
        fn each_value(&self, blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    import linear::LinearMap;

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return LinearMap(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        for uint::range(0, 32) |i| {
            assert (&mut m).insert(i, i*2);
        }
        let mut observed = 0;
        for (&m).each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }
}
<|endoftext|>


<commit_before><commit_msg>rearrange stuff<commit_after><|endoftext|>


<commit_before><commit_msg>Adding more commentted out sections back<commit_after><|endoftext|>


<commit_before><commit_msg>Add bench server example with settings usage.<commit_after>
/// WebSocket server used for testing the bench example.
extern crate ws;

use ws::{Builder, Settings, Sender};

fn main () {
    Builder::new().with_settings(Settings {
        max_connections: 10_000,
        ..Settings::default()
    }).build(|out: Sender| {
        move |msg| {
            out.send(msg)
        }
    }).unwrap().listen("127.0.0.1:3012").unwrap();
}
<|endoftext|>