<commit_before>use std::time::Duration;
use std::thread;

use game::*;
use ecs::*;
use util::Schedule;
use math::Coord;

const FAILED_ACTION_DELAY: u64 = 10;

#[derive(Clone, Copy)]
pub struct ActionEnv<'a> {
    pub ecs: &'a EcsCtx,
    pub id: u64,
}

#[derive(Clone, Copy)]
pub struct Turn<'a> {
    pub ecs: &'a EcsCtx,
    pub id: u64,
}

pub enum TurnResolution {
    Quit,
    Schedule(EntityId, u64),
}

pub struct TurnEnv<'a, 'b, 'c: 'a> {
    pub turn_id: u64,
    pub action_id: &'a mut u64,
    pub level_id: isize,
    pub entity_id: EntityId,
    pub pc_id: EntityId,
    pub renderer: &'a mut AnsiRenderer<'c>,
    pub ecs: &'b mut EcsCtx,
    pub spatial_hash: &'b mut SpatialHashTable,
    pub behaviour_ctx: &'a BehaviourCtx,
    pub rules: &'a Vec<Box<Rule>>,
    pub rule_resolution: &'a mut RuleResolution,
    pub ecs_action: &'a mut EcsAction,
    pub action_schedule: &'a mut Schedule<ActionArgs>,
    pub pc_observer: &'a Shadowcast,
    pub entity_ids: &'a EntityIdReserver,
}

impl<'a> Turn<'a> {
    pub fn new(ecs: &'a EcsCtx, id: u64) -> Self {
        Turn {
            ecs: ecs,
            id: id,
        }
    }
}

impl<'a> ActionEnv<'a> {
    pub fn new(ecs: &'a EcsCtx, id: u64) -> Self {
        ActionEnv {
            ecs: ecs,
            id: id,
        }
    }
}

const RENDER_WIDTH: usize = 37;
const RENDER_HEIGHT: usize = 26;

impl<'a, 'b, 'c: 'a> TurnEnv<'a, 'b, 'c> {
    pub fn turn(&mut self) -> Result<TurnResolution> {

        self.pc_render_ansi()?;

        match self.get_meta_action()? {
            MetaAction::External(External::Quit) => Ok(TurnResolution::Quit),
            MetaAction::ActionArgs(action_args) => {
                if let Some(delay) = self.try_commit_action(action_args)? {
                    self.declare_action_return(true)?;
                    Ok(TurnResolution::Schedule(self.entity_id, delay))
                } else {
                    self.declare_action_return(false)?;
                    Ok(TurnResolution::Schedule(self.entity_id, FAILED_ACTION_DELAY))
                }
            }
        }
    }

    fn check_rules(&mut self) -> Result<()> {
        self.rule_resolution.reset();

        let rule_env = RuleEnv {
            ecs: self.ecs,
            spatial_hash: self.spatial_hash,
        };

        for rule in self.rules {
            rule.check(rule_env, self.ecs_action, self.rule_resolution)?;

            if self.rule_resolution.is_reject() {
                return Ok(())
            }
        }
        Ok(())
    }

    fn commit(&mut self) {
        self.spatial_hash.update(ActionEnv::new(self.ecs, *self.action_id), self.ecs_action);
        self.ecs.commit(self.ecs_action);
    }

    fn pc_render_ansi(&mut self) -> Result<bool> {
        let entity = self.ecs.entity(self.pc_id);
        let mut knowledge = entity.ansi_drawable_knowledge_borrow_mut().ok_or(Error::MissingComponent)?;
        let level_knowledge = knowledge.level_mut(self.level_id);
        let position = entity.position().ok_or(Error::MissingComponent)?;
        let vision_distance = entity.vision_distance().ok_or(Error::MissingComponent)?;
        let action_env = ActionEnv::new(self.ecs, *self.action_id);

        if self.pc_observer.observe(position, self.spatial_hash, vision_distance, level_knowledge, action_env) {
            self.renderer.render(level_knowledge, *self.action_id, Coord::new(0, 0), RENDER_WIDTH, RENDER_HEIGHT);
            Ok(true)
        } else {
            Ok(false)
        }
    }

    fn try_commit_action(&mut self, action: ActionArgs) -> Result<Option<u64>> {

        let mut turn_time = None;

        self.action_schedule.insert(action, 0);

        while let Some(action_event) = self.action_schedule.next() {

            // render the scene if time has passed
            if action_event.time_delta != 0 {
                if self.pc_render_ansi()? {
                    // if the change in scene was visible, add a delay
                    thread::sleep(Duration::from_millis(action_event.time_delta));
                }
            }

            *self.action_id += 1;

            // construct an action from the action args
            action_event.event.to_action(&mut self.ecs_action, self.ecs, self.entity_ids)?;

            self.check_rules()?;

            let mut action_time = 0;

            if self.rule_resolution.is_accept() {
                if turn_time.is_none() {
                    turn_time = Some(self.ecs_action.turn_time().unwrap_or(0));
                }
                action_time = self.ecs_action.action_time_ms().unwrap_or(0);

                self.commit();
            } else {
                // Committing the action clears its data.
                // It must be cleared explicitly if the action is rejected.
                self.ecs_action.clear();
            }

            for reaction in self.rule_resolution.drain_reactions() {
                self.action_schedule.insert(reaction.action, action_time + reaction.delay);
            }
        }

        Ok(turn_time)
    }

    fn get_meta_action(&self) -> Result<MetaAction> {
        let entity = self.ecs.entity(self.entity_id);
        let mut behaviour_state = entity.behaviour_state_borrow_mut().ok_or(Error::MissingComponent)?;
        if !behaviour_state.is_initialised() {
            let behaviour_type = entity.behaviour_type().ok_or(Error::MissingComponent)?;
            behaviour_state.initialise(self.behaviour_ctx.graph(), self.behaviour_ctx.nodes().index(behaviour_type))?;
        }
        let input = BehaviourInput { entity: entity };
        Ok(behaviour_state.run(self.behaviour_ctx.graph(), input)?)
    }

    fn declare_action_return(&self, value: bool) -> Result<()> {
        let entity = self.ecs.entity(self.entity_id);
        let mut behaviour_state = entity.behaviour_state_borrow_mut().ok_or(Error::MissingComponent)?;
        behaviour_state.declare_return(value)?;
        Ok(())
    }
}
<commit_msg>Added minimum turn time<commit_after>use std::time::Duration;
use std::thread;
use std::cmp;

use game::*;
use ecs::*;
use util::Schedule;
use math::Coord;

const FAILED_ACTION_DELAY: u64 = 10;
const MIN_TURN_TIME: u64 = 1;

#[derive(Clone, Copy)]
pub struct ActionEnv<'a> {
    pub ecs: &'a EcsCtx,
    pub id: u64,
}

#[derive(Clone, Copy)]
pub struct Turn<'a> {
    pub ecs: &'a EcsCtx,
    pub id: u64,
}

pub enum TurnResolution {
    Quit,
    Schedule(EntityId, u64),
}

pub struct TurnEnv<'a, 'b, 'c: 'a> {
    pub turn_id: u64,
    pub action_id: &'a mut u64,
    pub level_id: isize,
    pub entity_id: EntityId,
    pub pc_id: EntityId,
    pub renderer: &'a mut AnsiRenderer<'c>,
    pub ecs: &'b mut EcsCtx,
    pub spatial_hash: &'b mut SpatialHashTable,
    pub behaviour_ctx: &'a BehaviourCtx,
    pub rules: &'a Vec<Box<Rule>>,
    pub rule_resolution: &'a mut RuleResolution,
    pub ecs_action: &'a mut EcsAction,
    pub action_schedule: &'a mut Schedule<ActionArgs>,
    pub pc_observer: &'a Shadowcast,
    pub entity_ids: &'a EntityIdReserver,
}

impl<'a> Turn<'a> {
    pub fn new(ecs: &'a EcsCtx, id: u64) -> Self {
        Turn {
            ecs: ecs,
            id: id,
        }
    }
}

impl<'a> ActionEnv<'a> {
    pub fn new(ecs: &'a EcsCtx, id: u64) -> Self {
        ActionEnv {
            ecs: ecs,
            id: id,
        }
    }
}

const RENDER_WIDTH: usize = 37;
const RENDER_HEIGHT: usize = 26;

impl<'a, 'b, 'c: 'a> TurnEnv<'a, 'b, 'c> {
    pub fn turn(&mut self) -> Result<TurnResolution> {

        self.pc_render_ansi()?;

        match self.get_meta_action()? {
            MetaAction::External(External::Quit) => Ok(TurnResolution::Quit),
            MetaAction::ActionArgs(action_args) => {
                if let Some(delay) = self.try_commit_action(action_args)? {
                    self.declare_action_return(true)?;
                    Ok(TurnResolution::Schedule(self.entity_id, delay))
                } else {
                    self.declare_action_return(false)?;
                    Ok(TurnResolution::Schedule(self.entity_id, FAILED_ACTION_DELAY))
                }
            }
        }
    }

    fn check_rules(&mut self) -> Result<()> {
        self.rule_resolution.reset();

        let rule_env = RuleEnv {
            ecs: self.ecs,
            spatial_hash: self.spatial_hash,
        };

        for rule in self.rules {
            rule.check(rule_env, self.ecs_action, self.rule_resolution)?;

            if self.rule_resolution.is_reject() {
                return Ok(())
            }
        }
        Ok(())
    }

    fn commit(&mut self) {
        self.spatial_hash.update(ActionEnv::new(self.ecs, *self.action_id), self.ecs_action);
        self.ecs.commit(self.ecs_action);
    }

    fn pc_render_ansi(&mut self) -> Result<bool> {
        let entity = self.ecs.entity(self.pc_id);
        let mut knowledge = entity.ansi_drawable_knowledge_borrow_mut().ok_or(Error::MissingComponent)?;
        let level_knowledge = knowledge.level_mut(self.level_id);
        let position = entity.position().ok_or(Error::MissingComponent)?;
        let vision_distance = entity.vision_distance().ok_or(Error::MissingComponent)?;
        let action_env = ActionEnv::new(self.ecs, *self.action_id);

        if self.pc_observer.observe(position, self.spatial_hash, vision_distance, level_knowledge, action_env) {
            self.renderer.render(level_knowledge, *self.action_id, Coord::new(0, 0), RENDER_WIDTH, RENDER_HEIGHT);
            Ok(true)
        } else {
            Ok(false)
        }
    }

    fn try_commit_action(&mut self, action: ActionArgs) -> Result<Option<u64>> {

        let mut turn_time = None;

        self.action_schedule.insert(action, 0);

        while let Some(action_event) = self.action_schedule.next() {

            // render the scene if time has passed
            if action_event.time_delta != 0 {
                if self.pc_render_ansi()? {
                    // if the change in scene was visible, add a delay
                    thread::sleep(Duration::from_millis(action_event.time_delta));
                }
            }

            *self.action_id += 1;

            // construct an action from the action args
            action_event.event.to_action(&mut self.ecs_action, self.ecs, self.entity_ids)?;

            self.check_rules()?;

            let mut action_time = 0;

            if self.rule_resolution.is_accept() {
                if turn_time.is_none() {
                    turn_time = Some(self.ecs_action.turn_time().unwrap_or(0));
                }
                action_time = self.ecs_action.action_time_ms().unwrap_or(0);

                self.commit();
            } else {
                // Committing the action clears its data.
                // It must be cleared explicitly if the action is rejected.
                self.ecs_action.clear();
            }

            for reaction in self.rule_resolution.drain_reactions() {
                self.action_schedule.insert(reaction.action, action_time + reaction.delay);
            }
        }

        Ok(turn_time.map(|t| cmp::max(t, MIN_TURN_TIME)))
    }

    fn get_meta_action(&self) -> Result<MetaAction> {
        let entity = self.ecs.entity(self.entity_id);
        let mut behaviour_state = entity.behaviour_state_borrow_mut().ok_or(Error::MissingComponent)?;
        if !behaviour_state.is_initialised() {
            let behaviour_type = entity.behaviour_type().ok_or(Error::MissingComponent)?;
            behaviour_state.initialise(self.behaviour_ctx.graph(), self.behaviour_ctx.nodes().index(behaviour_type))?;
        }
        let input = BehaviourInput { entity: entity };
        Ok(behaviour_state.run(self.behaviour_ctx.graph(), input)?)
    }

    fn declare_action_return(&self, value: bool) -> Result<()> {
        let entity = self.ecs.entity(self.entity_id);
        let mut behaviour_state = entity.behaviour_state_borrow_mut().ok_or(Error::MissingComponent)?;
        behaviour_state.declare_return(value)?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Gray_code

fn gray_encode(integer: uint) -> uint {
	(integer >> 1) ^ integer
}

fn gray_decode(integer: uint) -> uint {
	match integer {
		0 => 0,
		_ => integer ^ gray_decode(integer >> 1)
	}
}

fn main() {
	for i in range(0u,32u) {
		println!("{:2} {:0>5t} {:0>5t} {:2}", i, i, gray_encode(i),
			gray_decode(i));
	}

}<commit_msg>Added test to gray code<commit_after>// Implements http://rosettacode.org/wiki/Gray_code

// Encode an uint
fn gray_encode(integer: uint) -> uint {
	(integer >> 1) ^ integer
}

// Decode an uint
fn gray_decode(integer: uint) -> uint {
	match integer {
		0 => 0,
		_ => integer ^ gray_decode(integer >> 1)
	}
}

#[cfg(not(test))]
fn main() {
	for i in range(0u,32u) {
		println!("{:2} {:0>5t} {:0>5t} {:2}", i, i, gray_encode(i),
			gray_decode(i));
	}
}

#[test]
fn test_coherence() {
    assert!(range(0u, 1000).all(|x| gray_decode(gray_encode(x)) == x));
}<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Hailstone_sequence

// Define a struct which we can make into an interator.
struct Hailstone {
  current: int, // Accessible online only to itself.
  start:   int  // Accessible to everything.
}

// Define a constructor for the struct.
impl Hailstone {
  fn new(n: int) -> Hailstone {
    Hailstone { current: n, start: n }
  }
}

// Implement the hailstone iteration sequence.
impl Iterator<int> for Hailstone {
  // This gets called to fetch the next item of the iterator.
  fn next(&mut self) -> Option<int> {
    let current = self.current;    // We need to cache the current value.
    match current {
      0               => {
        // Resets the iterator.
        self.current = self.start;
        None
      },
      1               => {
        // At the end, yield 1 and roll over next time called.
        self.current = 0;
        Some(1)
      },
      x if x % 2 == 0 => {
        // Got an even.
        self.current = x / 2;
        Some(current)
      },
      x if x % 2 == 1 => {
        // Got an odd.
        self.current = (3 * x) + 1;
        Some(current)
      },
      _               => None
    }
  }
}

fn main() {
  // Find the hailstone for 27.
  let two_seven: ~[int] = Hailstone::new(27).collect();
  println!("Testing: {}, Length: {}, Values: {}...{}", two_seven[0], two_seven.len(), two_seven.slice(0,4).to_str(), two_seven.slice(two_seven.len()-4, two_seven.len()).to_str());
  // Find the longest.
  let mut biggest = range(0, 100000).map(|x| Hailstone::new(x)).max_by(|&mut x| x.len()).unwrap();
  let size = biggest.len();
  println!("Largest: {}, Size: {}", biggest.start, size);
}
<commit_msg>Added tests to hailstone<commit_after>// Implements http://rosettacode.org/wiki/Hailstone_sequence

// Define a struct which we can make into an interator.
struct Hailstone {
  current: uint, // Accessible online only to itself.
  start:   uint  // Accessible to everything.
}

// Define a constructor for the struct.
impl Hailstone {
  fn new(n: uint) -> Hailstone {
    Hailstone { current: n, start: n }
  }
}

// Implement the hailstone iteration sequence.
impl Iterator<uint> for Hailstone {
  // This gets called to fetch the next item of the iterator.
  fn next(&mut self) -> Option<uint> {
    let current = self.current;    // We need to cache the current value.
    match current {
      0               => {
        // Resets the iterator.
        self.current = self.start;
        None
      },
      1               => {
        // At the end, yield 1 and roll over next time called.
        self.current = 0;
        Some(1)
      },
      x if x % 2 == 0 => {
        // Got an even.
        self.current = x / 2;
        Some(current)
      },
      x if x % 2 == 1 => {
        // Got an odd.
        self.current = (3 * x) + 1;
        Some(current)
      },
      _               => None
    }
  }
}

// Returns the number and length of the longest hailstone sequence up to `limit`
fn biggest_hailstone(limit: uint) -> (uint, uint) {
    let mut biggest = range(0u, limit).map(|x| Hailstone::new(x)).max_by(|&mut x| x.len()).unwrap();
    (biggest.start, biggest.len())
}

#[cfg(not(test))]
fn main() {
  // Find the hailstone for 27.
  let two_seven: ~[uint] = Hailstone::new(27).collect();
  println!("Testing: {}, Length: {}, Values: {}...{}", two_seven[0], two_seven.len(), two_seven.slice(0,4).to_str(), two_seven.slice(two_seven.len()-4, two_seven.len()).to_str());

  // Find the longest.
  let (biggest, length) = biggest_hailstone(100000);
  println!("Largest: {}, Size: {}", biggest, length);
}

#[test]
fn test_27() {
    let seq: ~[uint] = Hailstone::new(27).collect();

    assert!(seq.slice(0, 4) == [27, 82, 41, 124]);
    assert!(seq.slice(seq.len() - 4, seq.len()) == [8, 4, 2, 1]);
}

#[test]
fn test_biggest() {
    let (biggest, length) = biggest_hailstone(100000);
    assert!(biggest == 77031);
    assert!(length == 351);
}<|endoftext|>


<commit_before>use libc::{uint64_t, int64_t, c_void, c_char, c_double};
use std::ffi::CString;
use std::ptr;
use energymon_sys::energymon::EnergyMon;

#[link(name = "hbt-acc-pow")]
extern {
    fn heartbeat_acc_pow_init(parent: *mut c_void,
                              window_size: uint64_t,
                              buffer_depth: uint64_t,
                              log_name: *const c_char,
                              num_energy_impls: uint64_t,
                              energy_impls: *mut EnergyMon) -> *mut c_void;

    fn heartbeat_acc(hb: *mut c_void,
                     user_tag: uint64_t,
                     work: uint64_t,
                     accuracy: c_double,
                     hb_prev: *mut c_void) -> int64_t;

    fn heartbeat_finish(hb: *mut c_void);

    fn hb_get_user_tag(hb: *const c_void) -> uint64_t;

    fn hb_get_window_rate(hb: *const c_void) -> c_double;

    fn hb_get_window_power(hb: *const c_void) -> c_double;
}

pub struct Heartbeat {
    pub hb: *mut c_void,
}

impl Heartbeat {
    pub fn new(parent: Option<&mut Heartbeat>,
               window_size: u64,
               buffer_depth: u64,
               log_name: Option<&str>,
               energy_impl: Option<&mut EnergyMon>) -> Result<Heartbeat, String> {
        let parent = match parent {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        let log_name = match log_name {
          Some(n) => CString::new(n).unwrap().as_ptr(),
          None => ptr::null(),
        };
        let num_energy_impls: u64;
        let mut em: *mut EnergyMon;
        if energy_impl.is_some() {
            num_energy_impls = 1;
            em = energy_impl.unwrap();
        } else {
            num_energy_impls = 0;
            em = ptr::null_mut();
        }
        let heart = unsafe {
            heartbeat_acc_pow_init(parent, window_size, buffer_depth, log_name,
                                   num_energy_impls, em)
        };
        if heart.is_null() {
            return Err("Failed to initialize heartbeat".to_string());
        }
        Ok(Heartbeat { hb: heart, })
    }

    pub fn heartbeat(&mut self,
                     tag: u64,
                     work: u64,
                     accuracy: f64,
                     hb_prev: Option<&Heartbeat>) -> i64 {
        let hb_prev = match hb_prev {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        unsafe {
            heartbeat_acc(self.hb, tag, work, accuracy, hb_prev)
        }
    }

    pub fn get_tag(&mut self) -> u64 {
        unsafe {
            hb_get_user_tag(self.hb)
        }
    }

    pub fn get_window_perf(&mut self) -> f64 {
        unsafe {
            hb_get_window_rate(self.hb)
        }
    }

    pub fn get_window_pwr(&mut self) -> f64 {
        unsafe {
            hb_get_window_power(self.hb)
        }
    }
}

impl Drop for Heartbeat {
    fn drop(&mut self) {
        unsafe {
            heartbeat_finish(self.hb);
        }
    }
}

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

    #[test]
    fn test_no_energymon() {
        let mut hb = Heartbeat::new(None, 20, 20, None, None).unwrap();
        hb.heartbeat(0, 1, 0.0, None);
    }
}
<commit_msg>Documentation<commit_after>use libc::{uint64_t, int64_t, c_void, c_char, c_double};
use std::ffi::CString;
use std::ptr;
use energymon_sys::energymon::EnergyMon;

#[link(name = "hbt-acc-pow")]
extern {
    fn heartbeat_acc_pow_init(parent: *mut c_void,
                              window_size: uint64_t,
                              buffer_depth: uint64_t,
                              log_name: *const c_char,
                              num_energy_impls: uint64_t,
                              energy_impls: *mut EnergyMon) -> *mut c_void;

    fn heartbeat_acc(hb: *mut c_void,
                     user_tag: uint64_t,
                     work: uint64_t,
                     accuracy: c_double,
                     hb_prev: *mut c_void) -> int64_t;

    fn heartbeat_finish(hb: *mut c_void);

    fn hb_get_user_tag(hb: *const c_void) -> uint64_t;

    fn hb_get_window_rate(hb: *const c_void) -> c_double;

    fn hb_get_window_power(hb: *const c_void) -> c_double;
}

/// A `Heartbeat` is used for tracking performance/accuracy/power of recurring jobs.
pub struct Heartbeat {
    /// The underlying C struct `heartbeat_t`.
    pub hb: *mut c_void,
}

impl Heartbeat {
    /// Allocate and initialize a new `Heartbeat` with its underlying C struct.
    pub fn new(parent: Option<&mut Heartbeat>,
               window_size: u64,
               buffer_depth: u64,
               log_name: Option<&str>,
               energy_impl: Option<&mut EnergyMon>) -> Result<Heartbeat, String> {
        let parent = match parent {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        let log_name = match log_name {
          Some(n) => CString::new(n).unwrap().as_ptr(),
          None => ptr::null(),
        };
        let num_energy_impls: u64;
        let mut em: *mut EnergyMon;
        if energy_impl.is_some() {
            num_energy_impls = 1;
            em = energy_impl.unwrap();
        } else {
            num_energy_impls = 0;
            em = ptr::null_mut();
        }
        let heart = unsafe {
            heartbeat_acc_pow_init(parent, window_size, buffer_depth, log_name,
                                   num_energy_impls, em)
        };
        if heart.is_null() {
            return Err("Failed to initialize heartbeat".to_string());
        }
        Ok(Heartbeat { hb: heart, })
    }

    /// Issue a heartbeat.
    pub fn heartbeat(&mut self,
                     tag: u64,
                     work: u64,
                     accuracy: f64,
                     hb_prev: Option<&Heartbeat>) -> i64 {
        let hb_prev = match hb_prev {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        unsafe {
            heartbeat_acc(self.hb, tag, work, accuracy, hb_prev)
        }
    }

    /// Utility function to get the most recent user-specified tag
    pub fn get_tag(&mut self) -> u64 {
        unsafe {
            hb_get_user_tag(self.hb)
        }
    }

    /// Utility function to get the current window performance.
    pub fn get_window_perf(&mut self) -> f64 {
        unsafe {
            hb_get_window_rate(self.hb)
        }
    }

    /// Utility function to get the current window power.
    pub fn get_window_pwr(&mut self) -> f64 {
        unsafe {
            hb_get_window_power(self.hb)
        }
    }
}

impl Drop for Heartbeat {
    /// Cleans up and deallocates the underlying C struct.
    fn drop(&mut self) {
        unsafe {
            heartbeat_finish(self.hb);
        }
    }
}

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

    #[test]
    fn test_no_energymon() {
        let mut hb = Heartbeat::new(None, 20, 20, None, None).unwrap();
        hb.heartbeat(0, 1, 0.0, None);
    }
}
<|endoftext|>


<commit_before>use std::hash::Hash;
use std::collections::HashMap;

use page_manager::{RamPageCache};
use index::listing::Listing;
use index::posting::{DocId, Posting};
use index::vocabulary::{Vocabulary, TermId};

pub mod vocabulary;
pub mod posting;
mod listing;

pub struct Index<TTerm> {
    page_manager: RamPageCache,
    listings: Vec<(TermId, Listing)>,
    vocabulary: HashMap<TTerm, TermId>,
}

impl<TTerm> Index<TTerm>
    where TTerm: Hash + Ord
{
    pub fn index_document<TIter>(&mut self, iter: &mut TIter) -> DocId
        where TIter: Iterator<Item = TTerm>
    {
        DocId::none()
    }

    pub fn query_atom(&self, atom: &TTerm) -> Vec<Posting> {
        if let Some(term_id) = self.vocabulary.get(atom) {
            if let Ok(index) = self.listings.binary_search_by_key(term_id, |&(t_id, _)| t_id) {
                return self.listings[index].1.posting_iter(&self.page_manager).collect::<Vec<_>>();
            }
        }
        vec![]
    }
}
<commit_msg>basic indexing<commit_after>use std::hash::Hash;
use std::collections::HashMap;

use page_manager::RamPageCache;
use index::listing::Listing;
use index::posting::{DocId, Posting};
use index::vocabulary::{Vocabulary, TermId};

pub mod vocabulary;
pub mod posting;
mod listing;

pub struct Index<TTerm> {
    page_manager: RamPageCache,
    listings: Vec<(TermId, Listing)>,
    vocabulary: HashMap<TTerm, TermId>,
    doc_count: u64,
}

impl<TTerm> Index<TTerm>
    where TTerm: Hash + Ord
{
    pub fn new(page_manager: RamPageCache) -> Self {
        Index {
            page_manager: page_manager,
            listings: Vec::new(),
            vocabulary: HashMap::new(),
            doc_count: 0,
        }

    }

    pub fn index_document<TIter>(&mut self, document: TIter) -> DocId
        where TIter: Iterator<Item = TTerm>
    {
        let doc_id = DocId(self.doc_count);
        self.doc_count += 1;
        let mut buff = Vec::new();
        for term in document {
            let term_id = self.vocabulary.get_or_add(term);
            buff.push(term_id);
        }
        buff.sort();
        buff.dedup();
        for term_id in buff {
            // get or add listing
            let index = match self.listings.binary_search_by_key(&term_id, |&(t_id, _)| t_id) {
                Ok(index) => index,
                Err(index) => {
                    self.listings.insert(index, (term_id, Listing::new()));
                    index
                }
            };
            self.listings[index].1.add(&[Posting(doc_id)], &mut self.page_manager);
        }
        doc_id
    }

    pub fn commit(&mut self) {
        for listing in self.listings.iter_mut() {
            listing.1.commit(&mut self.page_manager);
        }
    }

    pub fn query_atom(&self, atom: &TTerm) -> Vec<Posting> {
        if let Some(term_id) = self.vocabulary.get(atom) {
            if let Ok(index) = self.listings.binary_search_by_key(term_id, |&(t_id, _)| t_id) {
                return self.listings[index].1.posting_iter(&self.page_manager).collect::<Vec<_>>();
            }
        }
        vec![]
    }
}

#[cfg(test)]
mod tests {

    use test_utils::create_test_dir;
    use super::Index;
    use index::posting::{Posting, DocId};
    use page_manager::{BlockManager, FsPageManager, Page, RamPageCache, PageId, Block, BlockId,
                       BLOCKSIZE};

    fn new_cache(name: &str) -> RamPageCache {
        let path = &create_test_dir(format!("index/{}", name).as_str());
        let pmgr = FsPageManager::new(&path.join("pages.bin"));
        RamPageCache::new(pmgr)
    }

    #[test]
    fn basic_indexing() {
        let cache = new_cache("basic_indexing");
        let mut index = Index::<usize>::new(cache);

        assert_eq!(index.index_document((0..2000)), DocId(0));
        assert_eq!(index.index_document((2000..4000)), DocId(1));
        assert_eq!(index.index_document((500..600)), DocId(2));
        index.commit();

        assert_eq!(index.query_atom(&0), vec![Posting(DocId(0))]);
    }

    #[test]
    fn extended_indexing()  {
        let cache = new_cache("extended_indexing");
        let mut index = Index::<usize>::new(cache);
        println!("index");
        for i in 0..200 {
            assert_eq!(index.index_document((i..i+200)), DocId(i as u64));
        }
        println!("commit");
        index.commit();

        assert_eq!(index.query_atom(&0), vec![Posting(DocId(0))]);
        assert_eq!(index.query_atom(&99), (0..100).map(|i| Posting(DocId(i))).collect::<Vec<_>>());

    }
}
<|endoftext|>


<commit_before>extern crate builtins;

pub fn read(command_line: &str) {
	/*match control_machine(command_line) {
		Ok(mut tree) => tree.execute_command(),
		Err(err) => println!("{}", err),
	}*/
	let token_list = tokenize(command_line);
	let mut token_iter = token_list.iter();
	let tree = generate_tree(&mut token_iter);
}

#[derive(Copy, Clone)] // this enum takes 8b therefore copying it is better than having a 32b or 64b pointer
pub enum TokenMachineState {
	Start,
	StrCmd(usize),
	SeparateWs,
	StrArg(usize),
}

pub enum Token<'a, 'b> {
	LeftParen,
	RightParen,
	Cmd(&'a str),
	Arg(&'b str),
}

fn tokenize(command_line: &str) -> Vec<Token> {
	use self::TokenMachineState::*;
	use self::Token::*;

	let mut state = Start;
	let mut token_list = Vec::new();

	let mut char_it = command_line.char_indices();

	loop {
		if let Some((i, curr_char)) = char_it.next() {
			match (state, curr_char) {
				(Start, ' ') | (Start, '\t') => {},
				(Start, '(') => token_list.push(LeftParen),
				(Start, _) => state = StrCmd(i),

				(StrCmd(slice_start), ')') => {
					token_list.push(Cmd(&command_line[slice_start..i]));
					state = Start;
				},
				(StrCmd(slice_start), ' ') | (StrCmd(slice_start), '\t') => {
					token_list.push(Cmd(&command_line[slice_start..i]));
					state = SeparateWs;
				},
				(StrCmd(_), _) => {},

				(SeparateWs, ' ') | (SeparateWs, '\t') => {},
				(SeparateWs, ')') => {
					token_list.push(RightParen);
					state = Start;
				},
				(SeparateWs, '(') => {
					token_list.push(LeftParen);
					state = Start;
				},
				(SeparateWs, _) => state = StrArg(i),

				(StrArg(slice_start), ' ') | (StrArg(slice_start), '\t') => {
					token_list.push(Arg(&command_line[slice_start..i]));
					state = SeparateWs;
				},
				(StrArg(slice_start), ')') => {
					token_list.push(Arg(&command_line[slice_start..i]));
					state = Start;
				}
				(StrArg(_), _) => {},
			}
		}
	}
}

#[derive(PartialEq, Copy, Clone)] // this enum takes 8b therefore copying it is better than having a 32b or 64b pointer
enum ParseMachineState {
	Start,
	//CollectCmd,
	CollectArg,
	SubcommandEnd,
}

use std::slice::Iter;

fn generate_tree<'a>(token_iter: &mut Iter<Token<'a, 'a>>) -> Result<Command<'a>, &'static str> {
	use self::ParseMachineState::*;

	let (res, state) = parse(token_iter);

	if state != CollectArg { // accepting state when not doing recursion
		Err("Parse error")
	} else {
		res
	}
}

fn parse<'a>(token_iter: &mut Iter<Token<'a, 'a>>) -> (Result<Command<'a>, &'static str>, ParseMachineState) {
	use self::ParseMachineState::*;
	use self::Token::*;

	let mut state = Start;
	let mut cmd = Command::new();

	loop {
		if let Some(token) = token_iter.next() {
			match (state, token) {
				(Start, &Cmd(cmd_name)) => {
					cmd.cmd = Some(Box::new(Param::Arg(cmd_name)));
					state = CollectArg;
				},
				(Start, &LeftParen) => {
					// do recursion
					let (res, recur_state) = parse(token_iter);
					if recur_state != SubcommandEnd {
						panic!("ERROR");
					} else {
						match res {
							Err(_) => return(res, state),
							Ok(subcmd) => cmd.cmd = Some(Box::new(Param::Cmd(subcmd))),
						}
					}
				},
				(Start, &RightParen) => return (Err("Unexpected ')'"), state),
				(Start, &Arg(_)) => unreachable!(), // if that happens the tokenizer is buggy

				(CollectArg, &Arg(arg_str)) => {
					cmd.params.push(Param::Arg(arg_str));
				}
				(CollectArg, &Cmd(_)) => unreachable!(), // if that happens the tokenizer is buggy
				(CollectArg, &RightParen) => return (Ok(cmd), SubcommandEnd),
				(CollectArg, &LeftParen) => {
					//do recursion
					let (res, recur_state) = parse(token_iter);
					if recur_state != SubcommandEnd {
						panic!("ERROR");
					} else {
						match res {
							Err(_) => return(res, state),
							Ok(subcmd) => cmd.params.push(Param::Cmd(subcmd)),
						}
					}
				}

				(SubcommandEnd, _) => unreachable!(),
			}
		} else {
			break;
		}
	}

	(Err("Empy commands are not allowed"), state)
}

struct Command<'a> {
	cmd: Option<Box<Param<'a>>>,
	params: Vec<Param<'a>>,
}
impl<'a> Command<'a> {
	fn new() -> Command<'a> {
		Command {
			cmd: None,
			params: Vec::new(),
		}
	}
	fn get_final_arglist(&mut self) -> Vec<&str> {
		let mut final_arglist: Vec<&str> = Vec::with_capacity(self.params.len());

		/*for arg in self.params.iter_mut() { // substitue subcommands recursively
			let stdout = if let Param::Cmd(ref mut subcommand) = *arg {
				Some(subcommand.execute_subcommand())
			} else {
				None
			};

			if let Some(stdout) = stdout {
				*arg = Param::Arg(stdout); // the datastructure holds the `String`
			}

			if let Param::Arg(ref arg_str) = *arg { // at this point this always happen because `Cmd` became `Arg`s
				final_arglist.push(arg_str);
			}
		}*/

		final_arglist
	}
	fn execute_command(&mut self) {//returns stdout - possibly return a array of strings?
		/*match &self.cmd[..] {
			"" => {},
			/*"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_command(self),
		};*/
	}
	fn execute_subcommand(&mut self) -> String {
		/*match &self.cmd[..] {
			/*"" => {},
			"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_subcommand(self),
		}*/ "fuck you".to_string()
	}
}
enum Param<'a> {
	Arg(&'a str),
	Cmd(Command<'a>),

}
fn invoke_command(command: &mut Command) {
	use std::process::Command;
	/*match Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.spawn() {
			Ok(mut subproc) => {
				subproc.wait();
			},
			Err(err) => println!("{}", err),
	}*/
}
fn invoke_subcommand(command: &mut Command) -> String {
	/*{
		for arg in command.get_final_arglist() {
			println!("shitty debugging: {}", arg);
		}
	}
	use std::process::Command;
	let output = Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.output()
		.expect("Failed to start command");

	String::from_utf8(output.stdout).unwrap()*/ "fuck you".to_string()
}
<commit_msg>Add unit tests for the tokenizer and fix bugs found with them<commit_after>extern crate builtins;

pub fn read(command_line: &str) {
	/*match control_machine(command_line) {
		Ok(mut tree) => tree.execute_command(),
		Err(err) => println!("{}", err),
	}*/
	let token_list = tokenize(command_line);
	let mut token_iter = token_list.iter();
	let tree = generate_tree(&mut token_iter);
}

#[derive(Copy, Clone)] // this enum takes 8b therefore copying it is better than having a 32b or 64b pointer
enum TokenMachineState {
	Start,
	StrCmd(usize),
	SeparateWs,
	StrArg(usize),
}

#[derive(PartialEq, Debug)] // used for tests
enum Token<'a, 'b> {
	LeftParen,
	RightParen,
	Cmd(&'a str),
	Arg(&'b str),
}

fn tokenize(command_line: &str) -> Vec<Token> {
	use self::TokenMachineState::*;
	use self::Token::*;

	let mut state = Start;
	let mut token_list = Vec::new();

	let mut char_it = command_line.char_indices();

	loop {
		if let Some((i, curr_char)) = char_it.next() {
			match (state, curr_char) {
				(Start, ' ') | (Start, '\t') => {},
				(Start, '(') => token_list.push(LeftParen),
				(Start, ')') => token_list.push(RightParen), // this is invalid but it's the parser's job to find it out
				(Start, _) => state = StrCmd(i),

				(StrCmd(slice_start), ')') => {
					token_list.push(Cmd(&command_line[slice_start..i]));
					token_list.push(RightParen);
					state = Start;
				},
				(StrCmd(slice_start), ' ') | (StrCmd(slice_start), '\t') => {
					token_list.push(Cmd(&command_line[slice_start..i]));
					state = SeparateWs;
				},
				(StrCmd(_), _) => {},

				(SeparateWs, ' ') | (SeparateWs, '\t') => {},
				(SeparateWs, ')') => {
					token_list.push(RightParen);
					state = Start;
				},
				(SeparateWs, '(') => {
					token_list.push(LeftParen);
					state = Start;
				},
				(SeparateWs, _) => state = StrArg(i),

				(StrArg(slice_start), ' ') | (StrArg(slice_start), '\t') => {
					token_list.push(Arg(&command_line[slice_start..i]));
					state = SeparateWs;
				},
				(StrArg(slice_start), ')') => {
					token_list.push(Arg(&command_line[slice_start..i]));
					token_list.push(RightParen);
					state = Start;
				}
				(StrArg(_), _) => {},
			}
		} else {
			break;
		}
	}

	token_list
}

#[derive(PartialEq, Copy, Clone)] // this enum takes 8b therefore copying it is better than having a 32b or 64b pointer
enum ParseMachineState {
	Start,
	//CollectCmd,
	CollectArg,
	SubcommandEnd,
}

use std::slice::Iter;

fn generate_tree<'a>(token_iter: &mut Iter<Token<'a, 'a>>) -> Result<Command<'a>, &'static str> {
	use self::ParseMachineState::*;

	let (res, state) = parse(token_iter);

	if state != CollectArg { // accepting state when not doing recursion
		Err("Parse error")
	} else {
		res
	}
}

fn parse<'a>(token_iter: &mut Iter<Token<'a, 'a>>) -> (Result<Command<'a>, &'static str>, ParseMachineState) {
	use self::ParseMachineState::*;
	use self::Token::*;

	let mut state = Start;
	let mut cmd = Command::new();

	loop {
		if let Some(token) = token_iter.next() {
			match (state, token) {
				(Start, &Cmd(cmd_name)) => {
					cmd.cmd = Some(Box::new(Param::Arg(cmd_name)));
					state = CollectArg;
				},
				(Start, &LeftParen) => {
					// do recursion
					let (res, recur_state) = parse(token_iter);
					match res {
						Err(_) => return(res, state),
						Ok(subcmd) => {
							if recur_state != SubcommandEnd {
								panic!("ERROR");
							} else {
								cmd.cmd = Some(Box::new(Param::Cmd(subcmd)));
							}
						},
					}
				},
				(Start, &RightParen) => return (Err("Unexpected ')'"), state),
				(Start, &Arg(_)) => unreachable!(), // if that happens the tokenizer is buggy

				(CollectArg, &Arg(arg_str)) => {
					cmd.params.push(Param::Arg(arg_str));
				}
				(CollectArg, &Cmd(_)) => unreachable!(), // if that happens the tokenizer is buggy
				(CollectArg, &RightParen) => return (Ok(cmd), SubcommandEnd),
				(CollectArg, &LeftParen) => {
					//do recursion
					let (res, recur_state) = parse(token_iter);
					match res {
						Err(_) => return(res, state),
						Ok(subcmd) => {
							if recur_state != SubcommandEnd {
								panic!("ERROR");
							} else {
								cmd.params.push(Param::Cmd(subcmd));
							}
						},
					}
				}

				(SubcommandEnd, _) => unreachable!(),
			}
		} else {
			break;
		}
	}

	(Err("Empy commands are not allowed"), state)
}

struct Command<'a> {
	cmd: Option<Box<Param<'a>>>,
	params: Vec<Param<'a>>,
}
impl<'a> Command<'a> {
	fn new() -> Command<'a> {
		Command {
			cmd: None,
			params: Vec::new(),
		}
	}
	fn get_final_arglist(&mut self) -> Vec<&str> {
		let mut final_arglist: Vec<&str> = Vec::with_capacity(self.params.len());

		/*for arg in self.params.iter_mut() { // substitue subcommands recursively
			let stdout = if let Param::Cmd(ref mut subcommand) = *arg {
				Some(subcommand.execute_subcommand())
			} else {
				None
			};

			if let Some(stdout) = stdout {
				*arg = Param::Arg(stdout); // the datastructure holds the `String`
			}

			if let Param::Arg(ref arg_str) = *arg { // at this point this always happen because `Cmd` became `Arg`s
				final_arglist.push(arg_str);
			}
		}*/

		final_arglist
	}
	fn execute_command(&mut self) {//returns stdout - possibly return a array of strings?
		/*match &self.cmd[..] {
			"" => {},
			/*"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_command(self),
		};*/
	}
	fn execute_subcommand(&mut self) -> String {
		/*match &self.cmd[..] {
			/*"" => {},
			"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_subcommand(self),
		}*/ "fuck you".to_string()
	}
}
enum Param<'a> {
	Arg(&'a str),
	Cmd(Command<'a>),

}
fn invoke_command(command: &mut Command) {
	use std::process::Command;
	/*match Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.spawn() {
			Ok(mut subproc) => {
				subproc.wait();
			},
			Err(err) => println!("{}", err),
	}*/
}
fn invoke_subcommand(command: &mut Command) -> String {
	/*{
		for arg in command.get_final_arglist() {
			println!("shitty debugging: {}", arg);
		}
	}
	use std::process::Command;
	let output = Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.output()
		.expect("Failed to start command");

	String::from_utf8(output.stdout).unwrap()*/ "fuck you".to_string()
}

#[cfg(test)]
mod tests {
	#[test]
	fn tokenize() {
		use super::tokenize;
		use super::Token::*;

		assert_eq!(
			[Cmd("echo"), Arg("lol"), LeftParen, Cmd("srnaeinei"), RightParen],
			tokenize("echo lol (srnaeinei)").as_slice()
		);

		assert_eq!(
			[LeftParen, RightParen],
			tokenize("()").as_slice()
		);
	}
}
<|endoftext|>


<commit_before>use core::{Distribution, IntoDistribution};
use uniform_range::UniformPrimitiveIntegerRange;

use rand::Rng;
use std;

/// A distribution that always returns the same value.
///
/// # Example
///
/// ```rust
/// # extern crate rand;
/// # extern crate distributions;
/// # fn main() {
///     use distributions::Distribution;
///
///     let d = distributions::Constant(42);
///     let v = d.sample(&mut rand::thread_rng());
///     assert_eq!(v, 42);
/// # }
/// ```
#[derive(Copy, Clone)]
pub struct Constant<T>(pub T);

impl<T: Clone> Distribution for Constant<T> {
    type Output=T;

    #[inline]
    fn sample<R: Rng>(&self, _: &mut R) -> T {
        self.0.clone()
    }
}

macro_rules! into_constant_distribution {
    ($($ty:ty),* ) => {
        $(
            impl IntoDistribution<$ty> for $ty {
                type Distribution = Constant<Self>;

                #[inline]
                fn into_distribution(self) -> Constant<Self> {
                    Constant(self)
                }
            }
        )*
    }
}

into_constant_distribution! {
    u8, u16, u32, u64, usize,
    i8, i16, i32, i64, isize,
    bool, char
}

macro_rules! generic_into_constant_distribution {
    ($ty:ty, $($ident:ident),* ) => {
        impl <$($ident),*> IntoDistribution<$ty> for $ty where
            $ty: Clone {
            type Distribution = Constant<Self>;

            #[inline]
            fn into_distribution(self) -> Constant<Self> {
                Constant(self)
            }
        }
    }
}

generic_into_constant_distribution! { Vec<T>, T }
generic_into_constant_distribution! { std::collections::VecDeque<T>, T }
generic_into_constant_distribution! { std::collections::LinkedList<T>, T }
generic_into_constant_distribution! { std::collections::HashMap<K, V>, K, V }
generic_into_constant_distribution! { std::collections::BTreeMap<K, V>, K, V }
generic_into_constant_distribution! { std::collections::HashSet<T>, T }
generic_into_constant_distribution! { std::collections::BTreeSet<T>, T }
generic_into_constant_distribution! { std::collections::BinaryHeap<T>, T }

pub enum WeightedBool {
    AlwaysTrue,
    OneIn(UniformPrimitiveIntegerRange<u32>)
}

impl WeightedBool {
    #[inline]
    pub fn new(n: u32) -> WeightedBool {
        if n <= 1 {
            WeightedBool::AlwaysTrue
        } else {
            WeightedBool::OneIn(UniformPrimitiveIntegerRange::new(0, n))
        }
    }
}

impl Distribution for WeightedBool {
    type Output = bool;

    #[inline]
    fn sample<R: Rng>(&self, r: &mut R) -> bool {
        match *self {
            WeightedBool::AlwaysTrue => true,
            WeightedBool::OneIn(d) => d.sample(r) == 0
        }
    }
}

pub struct RandomElement<'a, T: 'a> {
    values: &'a [T],
    range: UniformPrimitiveIntegerRange<usize>
}

impl <'a, T> RandomElement<'a, T> {
    #[inline]
    pub fn from(values: &'a [T]) -> Option<RandomElement<'a, T>> {
        if values.len() == 0 {
            None
        } else {
            let range_distribution = UniformPrimitiveIntegerRange::new(0, values.len());
            Some(RandomElement { values: values, range: range_distribution })
        }
    }
}

impl <'a, T> Distribution for RandomElement<'a, T> {
    type Output = &'a T;

    #[inline]
    fn sample<R: Rng>(&self, r: &mut R) -> &'a T {
        &self.values[self.range.sample(r)]
    }
}

impl <'a, T: 'a> IntoDistribution<&'a T> for &'a [T] {
    type Distribution = RandomElement<'a, T>;

    #[inline]
    fn into_distribution(self) -> RandomElement<'a, T> {
        RandomElement::from(self).expect("Tried to convert an empty slice into a `Distribution`")
    }
}

pub struct Alphanum(RandomElement<'static, u8>);

impl Alphanum {
    #[inline]
    pub fn new() -> Alphanum {
        const GEN_ASCII_STR_CHARSET: &'static [u8] =
            b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
              abcdefghijklmnopqrstuvwxyz\
              0123456789";
        Alphanum(RandomElement::from(GEN_ASCII_STR_CHARSET).unwrap())
    }
}

impl Distribution for Alphanum {
    type Output = char;

    #[inline]
    fn sample<R: Rng>(&self, r: &mut R) -> char {
        *self.0.sample(r) as char
    }
}

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

    use core::{Distribution, IntoDistribution};
    use rand::{self, Rng, thread_rng};
    use rng_ext::RngExt;

    fn create_rng() -> rand::XorShiftRng {
        rand::thread_rng().gen()
    }

    #[test]
    fn test_generate_u8() {
        let mut rng = create_rng();

        let v: u8 =  Constant(42).sample(&mut rng);
        assert_eq!(v, 42);
    }

    #[test]
    fn test_into_distribution() {
        let mut rng = create_rng();

        let v: u8 =  42u8.into_distribution().sample(&mut rng);
        assert_eq!(v, 42);
    }

    #[test]
    fn test_vec_into_distribution() {
        let mut rng = create_rng();

        let v: Vec<u8> =  vec![42u8].into_distribution().sample(&mut rng);
        assert_eq!(v, vec![42u8]);
    }

    #[test]
    fn test_weighted_bool_trivial() {
        let mut rng = create_rng();

        let d = WeightedBool::new(1);
        let v = d.sample(&mut rng);
        assert_eq!(v, true);
    }

    #[test]
    fn test_random_element_on_empty_vec() {
        let mut rng = create_rng();

        let v: Vec<usize> = vec![];
        let d = RandomElement::from(&v);
        let s = d.sample(&mut rng);

        assert_eq!(s, None);
    }

    #[test]
    fn test_alphanum() {
        let mut rng = create_rng();

        let d = Alphanum::new();
        let _: String = rng.generate_iter(&d).take(100).collect();
    }
}
<commit_msg>Drop some #[inline]s<commit_after>use core::{Distribution, IntoDistribution};
use uniform_range::UniformPrimitiveIntegerRange;

use rand::Rng;
use std;

/// A distribution that always returns the same value.
///
/// # Example
///
/// ```rust
/// # extern crate rand;
/// # extern crate distributions;
/// # fn main() {
///     use distributions::Distribution;
///
///     let d = distributions::Constant(42);
///     let v = d.sample(&mut rand::thread_rng());
///     assert_eq!(v, 42);
/// # }
/// ```
#[derive(Copy, Clone)]
pub struct Constant<T>(pub T);

impl<T: Clone> Distribution for Constant<T> {
    type Output=T;

    #[inline]
    fn sample<R: Rng>(&self, _: &mut R) -> T {
        self.0.clone()
    }
}

macro_rules! into_constant_distribution {
    ($($ty:ty),* ) => {
        $(
            impl IntoDistribution<$ty> for $ty {
                type Distribution = Constant<Self>;

                #[inline]
                fn into_distribution(self) -> Constant<Self> {
                    Constant(self)
                }
            }
        )*
    }
}

into_constant_distribution! {
    u8, u16, u32, u64, usize,
    i8, i16, i32, i64, isize,
    bool, char
}

macro_rules! generic_into_constant_distribution {
    ($ty:ty, $($ident:ident),* ) => {
        impl <$($ident),*> IntoDistribution<$ty> for $ty where
            $ty: Clone {
            type Distribution = Constant<Self>;

            #[inline]
            fn into_distribution(self) -> Constant<Self> {
                Constant(self)
            }
        }
    }
}

generic_into_constant_distribution! { Vec<T>, T }
generic_into_constant_distribution! { std::collections::VecDeque<T>, T }
generic_into_constant_distribution! { std::collections::LinkedList<T>, T }
generic_into_constant_distribution! { std::collections::HashMap<K, V>, K, V }
generic_into_constant_distribution! { std::collections::BTreeMap<K, V>, K, V }
generic_into_constant_distribution! { std::collections::HashSet<T>, T }
generic_into_constant_distribution! { std::collections::BTreeSet<T>, T }
generic_into_constant_distribution! { std::collections::BinaryHeap<T>, T }

pub enum WeightedBool {
    AlwaysTrue,
    OneIn(UniformPrimitiveIntegerRange<u32>)
}

impl WeightedBool {
    pub fn new(n: u32) -> WeightedBool {
        if n <= 1 {
            WeightedBool::AlwaysTrue
        } else {
            WeightedBool::OneIn(UniformPrimitiveIntegerRange::new(0, n))
        }
    }
}

impl Distribution for WeightedBool {
    type Output = bool;

    #[inline]
    fn sample<R: Rng>(&self, r: &mut R) -> bool {
        match *self {
            WeightedBool::AlwaysTrue => true,
            WeightedBool::OneIn(d) => d.sample(r) == 0
        }
    }
}

pub struct RandomElement<'a, T: 'a> {
    values: &'a [T],
    range: UniformPrimitiveIntegerRange<usize>
}

impl <'a, T> RandomElement<'a, T> {
    pub fn from(values: &'a [T]) -> Option<RandomElement<'a, T>> {
        if values.len() == 0 {
            None
        } else {
            let range_distribution = UniformPrimitiveIntegerRange::new(0, values.len());
            Some(RandomElement { values: values, range: range_distribution })
        }
    }
}

impl <'a, T> Distribution for RandomElement<'a, T> {
    type Output = &'a T;

    #[inline]
    fn sample<R: Rng>(&self, r: &mut R) -> &'a T {
        &self.values[self.range.sample(r)]
    }
}

impl <'a, T: 'a> IntoDistribution<&'a T> for &'a [T] {
    type Distribution = RandomElement<'a, T>;

    #[inline]
    fn into_distribution(self) -> RandomElement<'a, T> {
        RandomElement::from(self).expect("Tried to convert an empty slice into a `Distribution`")
    }
}

pub struct Alphanum(RandomElement<'static, u8>);

impl Alphanum {
    pub fn new() -> Alphanum {
        const GEN_ASCII_STR_CHARSET: &'static [u8] =
            b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
              abcdefghijklmnopqrstuvwxyz\
              0123456789";
        Alphanum(RandomElement::from(GEN_ASCII_STR_CHARSET).unwrap())
    }
}

impl Distribution for Alphanum {
    type Output = char;

    #[inline]
    fn sample<R: Rng>(&self, r: &mut R) -> char {
        *self.0.sample(r) as char
    }
}

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

    use core::{Distribution, IntoDistribution};
    use rand::{self, Rng, thread_rng};
    use rng_ext::RngExt;

    fn create_rng() -> rand::XorShiftRng {
        rand::thread_rng().gen()
    }

    #[test]
    fn test_generate_u8() {
        let mut rng = create_rng();

        let v: u8 =  Constant(42).sample(&mut rng);
        assert_eq!(v, 42);
    }

    #[test]
    fn test_into_distribution() {
        let mut rng = create_rng();

        let v: u8 =  42u8.into_distribution().sample(&mut rng);
        assert_eq!(v, 42);
    }

    #[test]
    fn test_vec_into_distribution() {
        let mut rng = create_rng();

        let v: Vec<u8> =  vec![42u8].into_distribution().sample(&mut rng);
        assert_eq!(v, vec![42u8]);
    }

    #[test]
    fn test_weighted_bool_trivial() {
        let mut rng = create_rng();

        let d = WeightedBool::new(1);
        let v = d.sample(&mut rng);
        assert_eq!(v, true);
    }

    #[test]
    fn test_random_element_on_empty_vec() {
        let mut rng = create_rng();

        let v: Vec<usize> = vec![];
        let d = RandomElement::from(&v);
        let s = d.sample(&mut rng);

        assert_eq!(s, None);
    }

    #[test]
    fn test_alphanum() {
        let mut rng = create_rng();

        let d = Alphanum::new();
        let _: String = rng.generate_iter(&d).take(100).collect();
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::rc::Rc;

// We have to share a lot of things around, so use reference-counting to keep
// track of them.
pub type SharedBasicBlock = Rc<RefCell<BasicBlock>>;
pub type SharedFunction = Rc<RefCell<Function>>;
pub type SharedValue = Rc<RefCell<Value>>;

#[derive(Debug)]
pub struct Unit {
    pub locals: Vec<String>,
    pub functions: Vec<SharedFunction>,
}

impl Unit {
    pub fn new() -> Self {
        Self {
            locals: vec![],
            functions: vec![Rc::new(RefCell::new(Function::new(0, "main")))],
        }
    }

    pub fn main_function(&self) -> SharedFunction {
        self.functions[0].clone()
    }
}

pub type Address = u32;

#[derive(Debug)]
pub struct Value {
    pub id: u32,
    // List of all the instructions that read this value.
    pub dependents: Vec<Address>,
}

impl Value {
    fn new(id: u32) -> Self {
        Value {
            id,
            dependents: vec![],
        }
    }

    fn null() -> Self {
        Value {
            id: 0,
            dependents: vec![],
        }
    }

    fn is_null(&self) -> bool {
        self.id == 0
    }

    // Call this to track that an instruction uses this value.
    fn used_by(&mut self, address: Address) {
        // The null register can be used freely.
        if self.is_null() {
            return;
        }
        if !self.dependents.contains(&address) {
            self.dependents.push(address)
        }
    }
}

impl PartialEq for Value {
    fn eq(&self, other: &Value) -> bool {
        self.id == other.id
    }
}

#[derive(Debug, PartialEq)]
pub struct Function {
    pub id: u16,
    pub name: String,
    pub locals: Vec<String>,

    // Always keep track of where we entered.
    entry: SharedBasicBlock,
    // Keep track of where we are.
    current: SharedBasicBlock,
    // Used for compilation.
    pub basic_blocks: Vec<SharedBasicBlock>,

    // All the values allocated within the function.
    pub values: Vec<SharedValue>,
    // Use to generate monotonically-increasing instruction addresses.
    pub instruction_counter: u32,
}

impl Function {
    fn new<V: Into<String>>(id: u16, name: V) -> Self {
        let entry = Rc::new(RefCell::new(BasicBlock::new("entry")));
        Self {
            id,
            name: name.into(),
            locals: vec![],
            entry: entry.clone(),
            current: entry.clone(),
            basic_blocks: vec![entry],
            values: vec![],
            instruction_counter: 0,
        }
    }

    pub fn null_value(&self) -> SharedValue {
        Rc::new(RefCell::new(Value::null()))
    }

    pub fn have_local(&self, local: &String) -> bool {
        self.locals.contains(local)
    }

    pub fn get_local(&self, local: &String) -> u8 {
        self.locals
            .iter()
            .position(|existing| existing == local)
            .expect("Local not found") as u8
    }

    pub fn get_or_add_local(&mut self, local: String) -> u8 {
        let position = self.locals.iter().position(|existing| existing == &local);
        match position {
            Some(index) => index as u8,
            None => {
                self.locals.push(local);
                (self.locals.len() - 1) as u8
            }
        }
    }

    fn next_address(&mut self) -> Address {
        let address = self.instruction_counter;
        self.instruction_counter += 1;
        address
    }
}

pub trait InstructionBuilder {
    // Build a new `Value`.
    fn new_value(&mut self) -> SharedValue;

    // Push an instruction: returns the address of the new instruction.
    fn push(&mut self, instruction: Instruction) -> Address;

    // Add an instruction address to the value's list of dependents.
    fn track(&mut self, rval: SharedValue, address: Address);

    fn build_get_local(&mut self, index: u8) -> SharedValue {
        let lval = self.new_value();
        self.push(Instruction::GetLocal(lval.clone(), index));
        lval
    }

    fn build_get_local_lexical(&mut self, name: String) -> SharedValue {
        let lval = self.new_value();
        self.push(Instruction::GetLocalLexical(lval.clone(), name));
        lval
    }

    fn build_set_local(&mut self, index: u8, rval: SharedValue) {
        let address = self.push(Instruction::SetLocal(index, rval.clone()));
        self.track(rval, address);
    }

    fn build_set_local_lexical(&mut self, name: String, rval: SharedValue) {
        let address = self.push(Instruction::SetLocalLexical(name, rval.clone()));
        self.track(rval, address);
    }

    fn build_make_integer(&mut self, value: i64) -> SharedValue {
        let lval = self.new_value();
        self.push(Instruction::MakeInteger(lval.clone(), value));
        lval
    }

    fn build_call(&mut self, target: SharedValue, arguments: Vec<SharedValue>) -> SharedValue {
        let lval = self.new_value();
        let address = self.push(Instruction::Call(
            lval.clone(),
            target.clone(),
            arguments.clone(),
        ));
        self.track(target, address);
        for argument in arguments {
            self.track(argument, address);
        }
        lval
    }
}

impl InstructionBuilder for Function {
    fn new_value(&mut self) -> SharedValue {
        let id = (self.values.len() as u32) + 1;
        let value = Rc::new(RefCell::new(Value::new(id)));
        self.values.push(value.clone());
        value
    }

    fn push(&mut self, instruction: Instruction) -> Address {
        let address = self.next_address();
        self.current
            .borrow_mut()
            .instructions
            .push((address, instruction));
        address
    }

    fn track(&mut self, rval: SharedValue, address: Address) {
        rval.borrow_mut().used_by(address)
    }
}

#[derive(Debug, PartialEq)]
pub enum Instruction {
    GetLocal(SharedValue, u8),
    GetLocalLexical(SharedValue, String),
    SetLocal(u8, SharedValue),
    SetLocalLexical(String, SharedValue),
    MakeInteger(SharedValue, i64),
    Call(SharedValue, SharedValue, Vec<SharedValue>),
}

#[derive(Debug, PartialEq)]
pub struct BasicBlock {
    pub name: String,
    pub instructions: Vec<(Address, Instruction)>,
}

impl BasicBlock {
    fn new<V: Into<String>>(name: V) -> Self {
        Self {
            name: name.into(),
            instructions: vec![],
        }
    }
}
<commit_msg>Give IR values unique identifiers so that they can be more easily tracked and compared<commit_after>use std::cell::RefCell;
use std::rc::Rc;

// We have to share a lot of things around, so use reference-counting to keep
// track of them.
pub type SharedBasicBlock = Rc<RefCell<BasicBlock>>;
pub type SharedFunction = Rc<RefCell<Function>>;
pub type SharedValue = Rc<RefCell<Value>>;

#[derive(Debug)]
pub struct Unit {
    pub locals: Vec<String>,
    pub functions: Vec<SharedFunction>,
}

impl Unit {
    pub fn new() -> Self {
        Self {
            locals: vec![],
            functions: vec![Rc::new(RefCell::new(Function::new(0, "main")))],
        }
    }

    pub fn main_function(&self) -> SharedFunction {
        self.functions[0].clone()
    }
}

pub type Address = u32;

pub type ValueId = u32;

#[derive(Debug)]
pub struct Value {
    pub id: ValueId,
    // List of all the instructions that read this value.
    pub dependents: Vec<Address>,
}

impl Value {
    fn new(id: ValueId) -> Self {
        Value {
            id,
            dependents: vec![],
        }
    }

    fn null() -> Self {
        Value {
            id: 0,
            dependents: vec![],
        }
    }

    pub fn is_null(&self) -> bool {
        self.id == 0
    }

    // Call this to track that an instruction uses this value.
    fn used_by(&mut self, address: Address) {
        // The null register can be used freely.
        if self.is_null() {
            return;
        }
        if !self.dependents.contains(&address) {
            self.dependents.push(address)
        }
    }
}

impl PartialEq for Value {
    fn eq(&self, other: &Value) -> bool {
        self.id == other.id
    }
}

#[derive(Debug, PartialEq)]
pub struct Function {
    pub id: u16,
    pub name: String,
    pub locals: Vec<String>,

    // Always keep track of where we entered.
    entry: SharedBasicBlock,
    // Keep track of where we are.
    current: SharedBasicBlock,
    // Used for compilation.
    pub basic_blocks: Vec<SharedBasicBlock>,

    // All the values allocated within the function.
    pub values: Vec<SharedValue>,
    // Use to generate monotonically-increasing instruction addresses.
    pub instruction_counter: u32,
}

impl Function {
    fn new<V: Into<String>>(id: u16, name: V) -> Self {
        let entry = Rc::new(RefCell::new(BasicBlock::new("entry")));
        Self {
            id,
            name: name.into(),
            locals: vec![],
            entry: entry.clone(),
            current: entry.clone(),
            basic_blocks: vec![entry],
            values: vec![],
            instruction_counter: 0,
        }
    }

    pub fn null_value(&self) -> SharedValue {
        Rc::new(RefCell::new(Value::null()))
    }

    pub fn have_local(&self, local: &String) -> bool {
        self.locals.contains(local)
    }

    pub fn get_local(&self, local: &String) -> u8 {
        self.locals
            .iter()
            .position(|existing| existing == local)
            .expect("Local not found") as u8
    }

    pub fn get_or_add_local(&mut self, local: String) -> u8 {
        let position = self.locals.iter().position(|existing| existing == &local);
        match position {
            Some(index) => index as u8,
            None => {
                self.locals.push(local);
                (self.locals.len() - 1) as u8
            }
        }
    }

    fn next_address(&mut self) -> Address {
        let address = self.instruction_counter;
        self.instruction_counter += 1;
        address
    }
}

pub trait InstructionBuilder {
    // Build a new `Value`.
    fn new_value(&mut self) -> SharedValue;

    // Push an instruction: returns the address of the new instruction.
    fn push(&mut self, instruction: Instruction) -> Address;

    // Add an instruction address to the value's list of dependents.
    fn track(&mut self, rval: SharedValue, address: Address);

    fn build_get_local(&mut self, index: u8) -> SharedValue {
        let lval = self.new_value();
        self.push(Instruction::GetLocal(lval.clone(), index));
        lval
    }

    fn build_get_local_lexical(&mut self, name: String) -> SharedValue {
        let lval = self.new_value();
        self.push(Instruction::GetLocalLexical(lval.clone(), name));
        lval
    }

    fn build_set_local(&mut self, index: u8, rval: SharedValue) {
        let address = self.push(Instruction::SetLocal(index, rval.clone()));
        self.track(rval, address);
    }

    fn build_set_local_lexical(&mut self, name: String, rval: SharedValue) {
        let address = self.push(Instruction::SetLocalLexical(name, rval.clone()));
        self.track(rval, address);
    }

    fn build_make_integer(&mut self, value: i64) -> SharedValue {
        let lval = self.new_value();
        self.push(Instruction::MakeInteger(lval.clone(), value));
        lval
    }

    fn build_call(&mut self, target: SharedValue, arguments: Vec<SharedValue>) -> SharedValue {
        let lval = self.new_value();
        let address = self.push(Instruction::Call(
            lval.clone(),
            target.clone(),
            arguments.clone(),
        ));
        self.track(target, address);
        for argument in arguments {
            self.track(argument, address);
        }
        lval
    }
}

impl InstructionBuilder for Function {
    fn new_value(&mut self) -> SharedValue {
        let id = (self.values.len() as u32) + 1;
        let value = Rc::new(RefCell::new(Value::new(id)));
        self.values.push(value.clone());
        value
    }

    fn push(&mut self, instruction: Instruction) -> Address {
        let address = self.next_address();
        self.current
            .borrow_mut()
            .instructions
            .push((address, instruction));
        address
    }

    fn track(&mut self, rval: SharedValue, address: Address) {
        rval.borrow_mut().used_by(address)
    }
}

#[derive(Debug, PartialEq)]
pub enum Instruction {
    GetLocal(SharedValue, u8),
    GetLocalLexical(SharedValue, String),
    SetLocal(u8, SharedValue),
    SetLocalLexical(String, SharedValue),
    MakeInteger(SharedValue, i64),
    Call(SharedValue, SharedValue, Vec<SharedValue>),
}

#[derive(Debug, PartialEq)]
pub struct BasicBlock {
    pub name: String,
    pub instructions: Vec<(Address, Instruction)>,
}

impl BasicBlock {
    fn new<V: Into<String>>(name: V) -> Self {
        Self {
            name: name.into(),
            instructions: vec![],
        }
    }
}
<|endoftext|>


<commit_before>extern crate fragment;

use self::fragment::matching;
use walkdir::{DirEntry, Error, WalkDir};
use std::path::PathBuf;
use std::clone::Clone;

pub struct Index {
    path: PathBuf,
    entries: Vec<IndexedPath>,
}

#[derive(Debug, PartialEq)]
pub struct IndexedPath(PathBuf);

impl ToString for IndexedPath {
    fn to_string(&self) -> String {
        self.0.to_string_lossy().into_owned()
    }
}

impl Clone for IndexedPath {
    fn clone(&self) -> Self {
        IndexedPath(self.0.clone())
    }

    fn clone_from(&mut self, source: &Self) {
        self.0 = source.0.clone()
    }
}

impl Index {
    pub fn new(path: PathBuf) -> Index {
        Index {
            path: path,
            entries: Vec::new(),
        }
    }

    /// Finds all files inside and beneath the index path
    /// and adds them to the index entries vector.
    pub fn populate(&mut self) {
        // The entries listed by read_dir include the root index path; we want
        // relative paths, so we get this length so that we can strip it.
        let prefix_length = match self.path.to_str() {
            Some(path) => path.len()+1,
            None => return,
        };

        // Start indexing at the specified path.
        for entry in WalkDir::new(&self.path) {
            match relative_entry_path(entry, prefix_length) {
                Some(entry_path) => self.entries.push(IndexedPath(PathBuf::from(entry_path))),
                _ => (),
            }
        }
    }

    pub fn find(&self, term: &str, limit: usize) -> Vec<matching::Result<IndexedPath>> {
        matching::find(term, &self.entries, limit)
    }
}

/// Transforms a DirEntry object into an optional relative path string,
/// returning None if any errors occur or if the entry is not a file.
fn relative_entry_path(entry: Result<DirEntry, Error>, prefix_length: usize) -> Option<String> {
    match entry {
        Ok(e) => match e.path().metadata() {
            Ok(metadata) => if metadata.is_file() {
                match e.path().to_str() {
                    Some(path) => Some(path[prefix_length..].to_string()),
                    _ => None,
                }
            } else {
                None
            },
            _ => None,
        },
        _ => None,
    }
}

#[cfg(test)]
mod tests {
    extern crate fragment;

    use super::{Index, IndexedPath};
    use std::path::PathBuf;
    use self::fragment::matching;

    #[test]
    fn populate_adds_all_files_to_entries() {
        let path = PathBuf::from("tests/sample");
        let mut index = Index::new(path);
        let expected_entries = vec![
            IndexedPath(PathBuf::from("directory/nested_file")),
            IndexedPath(PathBuf::from("root_file"))
        ];
        index.populate();

        assert_eq!(index.entries, expected_entries);
    }

    #[test]
    fn find_defers_to_matching_module() {
        let path = PathBuf::from("tests/sample");
        let mut index = Index::new(path);
        index.populate();
        let term = "root";
        let limit = 5;
        let expected_results = matching::find(
            term,
            &vec![
                IndexedPath(PathBuf::from("root_file")),
                IndexedPath(PathBuf::from("directory/nested_file"))
            ],
            limit
        );

        assert_eq!(index.find(term, limit), expected_results);
    }
}
<commit_msg>Update find to return set of paths, not results. Rustfmt!<commit_after>extern crate fragment;

use self::fragment::matching;
use walkdir::{DirEntry, Error, WalkDir};
use std::path::PathBuf;
use std::clone::Clone;

pub struct Index {
    path: PathBuf,
    entries: Vec<IndexedPath>,
}

#[derive(Debug, PartialEq)]
pub struct IndexedPath(PathBuf);

impl ToString for IndexedPath {
    fn to_string(&self) -> String {
        self.0.to_string_lossy().into_owned()
    }
}

impl Clone for IndexedPath {
    fn clone(&self) -> Self {
        IndexedPath(self.0.clone())
    }

    fn clone_from(&mut self, source: &Self) {
        self.0 = source.0.clone()
    }
}

impl Index {
    pub fn new(path: PathBuf) -> Index {
        Index {
            path: path,
            entries: Vec::new(),
        }
    }

    /// Finds all files inside and beneath the index path
    /// and adds them to the index entries vector.
    pub fn populate(&mut self) {
        // The entries listed by read_dir include the root index path; we want
        // relative paths, so we get this length so that we can strip it.
        let prefix_length = match self.path.to_str() {
            Some(path) => path.len() + 1,
            None => return,
        };

        // Start indexing at the specified path.
        for entry in WalkDir::new(&self.path) {
            match relative_entry_path(entry, prefix_length) {
                Some(entry_path) => self.entries.push(IndexedPath(PathBuf::from(entry_path))),
                _ => (),
            }
        }
    }

    pub fn find(&self, term: &str, limit: usize) -> Vec<PathBuf> {
        matching::find(term, &self.entries, limit)
            .into_iter()
            .map(|r| {
                let IndexedPath(other_thing) = r.clone();
                other_thing
            })
            .collect()
    }
}

/// Transforms a DirEntry object into an optional relative path string,
/// returning None if any errors occur or if the entry is not a file.
fn relative_entry_path(entry: Result<DirEntry, Error>, prefix_length: usize) -> Option<String> {
    match entry {
        Ok(e) => {
            match e.path().metadata() {
                Ok(metadata) => {
                    if metadata.is_file() {
                        match e.path().to_str() {
                            Some(path) => Some(path[prefix_length..].to_string()),
                            _ => None,
                        }
                    } else {
                        None
                    }
                }
                _ => None,
            }
        }
        _ => None,
    }
}

#[cfg(test)]
mod tests {
    extern crate fragment;

    use super::{Index, IndexedPath};
    use std::path::PathBuf;
    use self::fragment::matching;

    #[test]
    fn populate_adds_all_files_to_entries() {
        let path = PathBuf::from("tests/sample");
        let mut index = Index::new(path);
        let expected_entries = vec![IndexedPath(PathBuf::from("directory/nested_file")),
                                    IndexedPath(PathBuf::from("root_file"))];
        index.populate();

        assert_eq!(index.entries, expected_entries);
    }

    #[test]
    fn find_defers_to_matching_module() {
        let path = PathBuf::from("tests/sample");
        let mut index = Index::new(path);
        index.populate();
        let term = "root";
        let limit = 5;

        // Get a string version of the results (PathBuf doesn't implement the display trait).
        let results: Vec<String> = index.find(term, limit)
                                        .iter()
                                        .map(|r| r.to_string_lossy().into_owned())
                                        .collect();

        assert_eq!(results,
                   vec!["root_file".to_string(), "directory/nested_file".to_string()]);
    }
}
<|endoftext|>


<commit_before>use std;
/// Computes the signed distance function from a line segment given as the _zero_ level set of a
/// linear function on an isosceles right triangle.
///
/// Inputs are `u`, the values at the vertices. The vertex 0 is the one with the right angle.
///
/// The function returns the values of the signed distance function or `None` if the zero level set
/// does not pass through the triangle.
pub fn triangle_dist(u: [f64; 3]) -> Option<[f64; 3]> {
    let mut u = u;
    // normalize so that u[0] >= 0.
    if u[0] < 0. {
        for u in &mut u {
            *u = -*u;
        }
    }

    // gradient vector
    let gx = u[1] - u[0];
    let gy = u[2] - u[0];
    let g_norm = (gx * gx + gy * gy).sqrt();

    if u[1] >= 0. {
        if u[2] >= 0. {
            // well isn't this ugly, we need to handle possible zeros
            match (u[0], u[1], u[2]) {
                (0., 0., 0.) => Some([0., 0., 0.]),
                (_, 0., 0.) => Some([(0.5f64).sqrt(), 0., 0.]),
                (0., _, 0.) => Some([0., 1., 0.]),
                (0., 0., _) => Some([0., 0., 1.]),
                (0., _, _) => Some([0., 1., 1.]),
                (_, 0., _) => Some([1., 0., (2f64).sqrt()]),
                (_, _, 0.) => Some([1., (2f64).sqrt(), 0.]),
                _ => None,
            }
        } else {
            // u[2] < 0.
            // intersect position
            let i02 = u[0] / (u[0] - u[2]);
            let i12 = (2f64).sqrt() * u[1] / (u[1] - u[2]);
            // find the direction of the gradient
            // to deduce the vertex that is closest to the line
            if gx <= 0. {
                // 0
                Some([u[0] / g_norm, i12, 1. - i02])
            } else if gx > -gy {
                // 1
                Some([i02, u[1] / g_norm, (2f64).sqrt() - i12])
            } else {
                // 2
                Some([i02, i12, -u[2] / g_norm])
            }
        }
    } else if u[2] >= 0. {
        // u[1] < 0.
        // intersect position
        let i01 = u[0] / (u[0] - u[1]);
        let i12 = (2f64).sqrt() * u[1] / (u[1] - u[2]);
        // find the direction of the gradient
        // to deduce the vertex that is closest to the line
        if gy <= 0. {
            // 0
            Some([u[0] / g_norm, 1. - i01, (2f64).sqrt() - i12])
        } else if -gx > gy {
            // 1
            Some([i01, -u[1] / g_norm, (2f64).sqrt() - i12])
        } else {
            // 2
            Some([i01, i12, u[2] / g_norm])
        }
    } else {
        // u[2] < 0.
        // intersect position
        let i10 = u[1] / (u[1] - u[0]);
        let i20 = u[2] / (u[2] - u[0]);

        Some([u[0] / g_norm, i10, i20])
    }

}

/// Initializes the distance around the free boundary.
///
/// Based on the level set function with values `u` given on a regular grid, it computes the
/// distance from the _zero_ level set in the nodes of the triangles through which the level set
/// passes.  Stores the result in the preallocated slice `d`.
///
/// Nodes away from the boundary have their value set to `std::f64::MAX`.
///
/// Splits every square into two triangles and computes the distance on each of them.
pub fn init_dist(d: &mut [f64], u: &[f64], dim: (usize, usize)) {
    let (nx, ny) = dim;
    assert_eq!(nx * ny, u.len());
    assert_eq!(nx * ny, d.len());

    for d in &mut *d {
        *d = std::f64::MAX;
    }

    for j in 1..ny {
        for i in 1..nx {
            let s = j * nx + i;
            let r = triangle_dist([u[s - nx - 1], u[s - nx], u[s - 1]]);
            if let Some(e) = r {
                d[s - nx - 1] = e[0].min(d[s - nx - 1]);
                d[s - nx] = e[1].min(d[s - nx]);
                d[s - 1] = e[2].min(d[s - 1]);
            }
            let r = triangle_dist([u[s], u[s - nx], u[s - 1]]);
            if let Some(e) = r {
                d[s] = e[0].min(d[s]);
                d[s - nx] = e[1].min(d[s - nx]);
                d[s - 1] = e[2].min(d[s - 1]);
            }
        }
    }
}

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

    #[test]
    fn simple_triangles() {
        assert_eq!(triangle_dist([0., 0., 0.]), Some([0., 0., 0.]));
        assert_eq!(triangle_dist([-1., 0., 0.]),
                   Some([(0.5f64).sqrt(), 0., 0.]));
        assert_eq!(triangle_dist([0., 1., 0.]), Some([0., 1., 0.]));
        assert_eq!(triangle_dist([0., -1., -1.]), Some([0., 1., 1.]));
        assert_eq!(triangle_dist([0., 1., 1.]), Some([0., 1., 1.]));
        assert_eq!(triangle_dist([1., 1., 0.]), Some([1., (2f64).sqrt(), 0.]));
    }
}
<commit_msg>Function declaration<commit_after>use std;

/// Computes the signed distance function from a plane given as the _zero_ level set of a
/// linear function on a tetrahedron with right angle at the 0 vertex.
///
/// The vertex coordinates are: (0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1)
///
/// Inputs are `u`, the values at the vertices. The vertex 0 is the one with the right angle.
///
/// The function returns the values of the signed distance function or `None` if the zero level set
/// does not pass through the tetrahedron.
pub fn tetrahedron_dist(u: [f64; 4]) -> Option<[f64; 4]> {
    let mut u = u;
    let tiny = 1e-15;
    // TODO:
    // 1. add `tiny` if u[i] >= 0. to avoid degenerate case u[i] == 0. (this way u[i] can be only
    //    positive or negative)
    // 2. find the triangle of the level set withing the tetrahedron
    // 3. compute the distance to the tetrahedron for each vertex
    for u in &mut u {
        if *u >= 0. {
            *u += tiny;
        }
    }

    for i in 0..3 {
        for j in i+1..4 {
        }
    }

    // gradient vector
    let gx = u[1] - u[0];
    let gy = u[2] - u[0];
    let gz = u[3] - u[0];
    let g_norm = (gx * gx + gy * gy + gz * gz).sqrt();

    Some([0.; 4])
}
/// Computes the signed distance function from a line segment given as the _zero_ level set of a
/// linear function on an isosceles right triangle.
///
/// Inputs are `u`, the values at the vertices. The vertex 0 is the one with the right angle.
///
/// The function returns the values of the signed distance function or `None` if the zero level set
/// does not pass through the triangle.
pub fn triangle_dist(u: [f64; 3]) -> Option<[f64; 3]> {
    let mut u = u;
    // normalize so that u[0] >= 0.
    if u[0] < 0. {
        for u in &mut u {
            *u = -*u;
        }
    }

    // gradient vector
    let gx = u[1] - u[0];
    let gy = u[2] - u[0];
    let g_norm = (gx * gx + gy * gy).sqrt();

    if u[1] >= 0. {
        if u[2] >= 0. {
            // well isn't this ugly, we need to handle possible zeros
            match (u[0], u[1], u[2]) {
                (0., 0., 0.) => Some([0., 0., 0.]),
                (_, 0., 0.) => Some([(0.5f64).sqrt(), 0., 0.]),
                (0., _, 0.) => Some([0., 1., 0.]),
                (0., 0., _) => Some([0., 0., 1.]),
                (0., _, _) => Some([0., 1., 1.]),
                (_, 0., _) => Some([1., 0., (2f64).sqrt()]),
                (_, _, 0.) => Some([1., (2f64).sqrt(), 0.]),
                _ => None,
            }
        } else {
            // u[2] < 0.
            // intersect position
            let i02 = u[0] / (u[0] - u[2]);
            let i12 = (2f64).sqrt() * u[1] / (u[1] - u[2]);
            // find the direction of the gradient
            // to deduce the vertex that is closest to the line
            if gx <= 0. {
                // 0
                Some([u[0] / g_norm, i12, 1. - i02])
            } else if gx > -gy {
                // 1
                Some([i02, u[1] / g_norm, (2f64).sqrt() - i12])
            } else {
                // 2
                Some([i02, i12, -u[2] / g_norm])
            }
        }
    } else if u[2] >= 0. {
        // u[1] < 0.
        // intersect position
        let i01 = u[0] / (u[0] - u[1]);
        let i12 = (2f64).sqrt() * u[1] / (u[1] - u[2]);
        // find the direction of the gradient
        // to deduce the vertex that is closest to the line
        if gy <= 0. {
            // 0
            Some([u[0] / g_norm, 1. - i01, (2f64).sqrt() - i12])
        } else if -gx > gy {
            // 1
            Some([i01, -u[1] / g_norm, (2f64).sqrt() - i12])
        } else {
            // 2
            Some([i01, i12, u[2] / g_norm])
        }
    } else {
        // u[2] < 0.
        // intersect position
        let i10 = u[1] / (u[1] - u[0]);
        let i20 = u[2] / (u[2] - u[0]);

        Some([u[0] / g_norm, i10, i20])
    }

}

/// Initializes the distance around the free boundary.
///
/// Based on the level set function with values `u` given on a regular grid, it computes the
/// distance from the _zero_ level set in the nodes of the triangles through which the level set
/// passes.  Stores the result in the preallocated slice `d`.
///
/// Nodes away from the boundary have their value set to `std::f64::MAX`.
///
/// Splits every square into two triangles and computes the distance on each of them.
pub fn init_dist(d: &mut [f64], u: &[f64], dim: (usize, usize)) {
    let (nx, ny) = dim;
    assert_eq!(nx * ny, u.len());
    assert_eq!(nx * ny, d.len());

    for d in &mut *d {
        *d = std::f64::MAX;
    }

    for j in 1..ny {
        for i in 1..nx {
            let s = j * nx + i;
            let r = triangle_dist([u[s - nx - 1], u[s - nx], u[s - 1]]);
            if let Some(e) = r {
                d[s - nx - 1] = e[0].min(d[s - nx - 1]);
                d[s - nx] = e[1].min(d[s - nx]);
                d[s - 1] = e[2].min(d[s - 1]);
            }
            let r = triangle_dist([u[s], u[s - nx], u[s - 1]]);
            if let Some(e) = r {
                d[s] = e[0].min(d[s]);
                d[s - nx] = e[1].min(d[s - nx]);
                d[s - 1] = e[2].min(d[s - 1]);
            }
        }
    }
}

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

    #[test]
    fn simple_triangles() {
        assert_eq!(triangle_dist([0., 0., 0.]), Some([0., 0., 0.]));
        assert_eq!(triangle_dist([-1., 0., 0.]),
                   Some([(0.5f64).sqrt(), 0., 0.]));
        assert_eq!(triangle_dist([0., 1., 0.]), Some([0., 1., 0.]));
        assert_eq!(triangle_dist([0., -1., -1.]), Some([0., 1., 1.]));
        assert_eq!(triangle_dist([0., 1., 1.]), Some([0., 1., 1.]));
        assert_eq!(triangle_dist([1., 1., 0.]), Some([1., (2f64).sqrt(), 0.]));
    }
}
<|endoftext|>