<commit_before>use std::ops::{Mul, Add, Div, Sub, Index};
use math::linalg::vector::Vector;
use math::utils;

struct Matrix {
	cols: usize,
	rows: usize,
	data: Vec<f32>
}

impl Matrix {
    fn new(cols: usize, rows: usize, data: Vec<f32>) -> Matrix {
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    fn zeros(cols: usize, rows: usize) -> Matrix {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![0.0; cols*rows]
        }
    }

    fn identity(size: usize) -> Matrix {
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = 1.0;
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn from_diag(diag: &Vec<f32>) -> Matrix {
    	let size = diag.len();
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn transpose(&self) -> Matrix {
        let mut new_data = vec![0.0; self.cols * self.rows];
        for i in 0..self.cols
        {
            for j in 0..self.rows
            {
                new_data[j*self.cols+i] = self.data[i*self.rows + j];
            }
        }

        Matrix {
            cols: self.rows,
            rows: self.cols,
            data: new_data
        }
    }
}

impl Mul<f32> for Matrix {
    type Output = Matrix;

    fn mul(self, f: f32) -> Matrix {
        let new_data = self.data.into_iter().map(|v| v * f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Mul<Matrix> for Matrix {
	type Output = Matrix;

	fn mul(self, m: Matrix) -> Matrix {
		// Will use Strassen algorithm if large, traditional otherwise
		self
	}
}

impl Mul<Vector> for Matrix {
    type Output = Vector;

    fn mul(self, v: Vector) -> Vector {
        assert!(v.size == self.cols);

        let mut new_data = vec![0.0; self.rows];

        for i in 0..self.rows
        {
            new_data[i] = utils::dot(&self.data[i*self.cols..(i+1)*self.cols], &v.data);
        }

        return Vector {
            size: v.size,
            data: new_data
        }
    }
}

impl Add<f32> for Matrix {
	type Output = Matrix;

	fn add(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v + f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Sub<f32> for Matrix {
	type Output = Matrix;

	fn sub(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v - f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Add<Matrix> for Matrix {
	type Output = Matrix;

	fn add(self, m: Matrix) -> Matrix {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v + m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Sub<Matrix> for Matrix {
	type Output = Matrix;

	fn sub(self, m: Matrix) -> Matrix {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v - m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Div<f32> for Matrix {
	type Output = Matrix;

	fn div(self, f: f32) -> Matrix {
		assert!(f != 0.0);

		let new_data = self.data.into_iter().map(|v| v / f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Index<[usize; 2]> for Matrix {
	type Output = f32;

	fn index(&self, idx : [usize; 2]) -> &f32 {
		assert!(idx[0] < self.cols);
		assert!(idx[1] < self.rows);

		&self.data[idx[0] * self.cols + idx[1]]
	}
}<commit_msg>Implemented vectorized matrix multiplication (simple iterative)<commit_after>use std::ops::{Mul, Add, Div, Sub, Index};
use math::linalg::vector::Vector;
use math::utils;

struct Matrix {
	cols: usize,
	rows: usize,
	data: Vec<f32>
}

impl Matrix {
    fn new(cols: usize, rows: usize, data: Vec<f32>) -> Matrix {
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    fn zeros(cols: usize, rows: usize) -> Matrix {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![0.0; cols*rows]
        }
    }

    fn identity(size: usize) -> Matrix {
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = 1.0;
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn from_diag(diag: &Vec<f32>) -> Matrix {
    	let size = diag.len();
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn transpose(&self) -> Matrix {
        let mut new_data = vec![0.0; self.cols * self.rows];
        for i in 0..self.cols
        {
            for j in 0..self.rows
            {
                new_data[j*self.cols+i] = self.data[i*self.rows + j];
            }
        }

        Matrix {
            cols: self.rows,
            rows: self.cols,
            data: new_data
        }
    }
}

impl Mul<f32> for Matrix {
    type Output = Matrix;

    fn mul(self, f: f32) -> Matrix {
        let new_data = self.data.into_iter().map(|v| v * f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Mul<Matrix> for Matrix {
	type Output = Matrix;

	fn mul(self, m: Matrix) -> Matrix {
		// Will use Strassen algorithm if large, traditional otherwise
		assert!(self.cols == m.rows);

        let mut new_data = vec![0.0; self.rows * m.cols];

        let mt = &m.transpose();

        for i in 0..self.rows
        {
            for j in 0..m.cols
            {
                new_data[i * m.cols + j] = utils::dot( &self.data[(i * self.cols)..((i+1)*self.cols)], &mt.data[(j*m.rows)..((j+1)*m.rows)] );
            }
        }

        Matrix {
            cols: self.cols,
            rows: m.rows,
            data: new_data
        }
	}
}

impl Mul<Vector> for Matrix {
    type Output = Vector;

    fn mul(self, v: Vector) -> Vector {
        assert!(v.size == self.cols);

        let mut new_data = vec![0.0; self.rows];

        for i in 0..self.rows
        {
            new_data[i] = utils::dot(&self.data[i*self.cols..(i+1)*self.cols], &v.data);
        }

        return Vector {
            size: v.size,
            data: new_data
        }
    }
}

impl Add<f32> for Matrix {
	type Output = Matrix;

	fn add(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v + f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Sub<f32> for Matrix {
	type Output = Matrix;

	fn sub(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v - f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Add<Matrix> for Matrix {
	type Output = Matrix;

	fn add(self, m: Matrix) -> Matrix {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v + m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Sub<Matrix> for Matrix {
	type Output = Matrix;

	fn sub(self, m: Matrix) -> Matrix {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v - m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Div<f32> for Matrix {
	type Output = Matrix;

	fn div(self, f: f32) -> Matrix {
		assert!(f != 0.0);

		let new_data = self.data.into_iter().map(|v| v / f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Index<[usize; 2]> for Matrix {
	type Output = f32;

	fn index(&self, idx : [usize; 2]) -> &f32 {
		assert!(idx[0] < self.cols);
		assert!(idx[1] < self.rows);

		&self.data[idx[0] * self.cols + idx[1]]
	}
}<|endoftext|>


<commit_before>use core::Controller;
use domains::{Domain, Observation};
use geometry::Space;
use slog::{Logger, Record, Result as LogResult, Serializer, KV};

/// Container for episodic statistics.
#[derive(Debug)]
pub struct Episode {
    /// The number of steps taken to reach the terminal state.
    pub steps: u64,

    /// The total accumulated reward over the episode.
    pub reward: f64,
}

impl KV for Episode {
    fn serialize(&self, _: &Record, serializer: &mut Serializer) -> LogResult {
        serializer.emit_u64("steps", self.steps)?;
        serializer.emit_f64("reward", self.reward)?;

        Ok(())
    }
}

/// Helper function for running experiments.
pub fn run(
    runner: impl Iterator<Item = Episode>,
    n_episodes: usize,
    logger: Option<Logger>,
) -> Vec<Episode>
{
    let exp = runner.take(n_episodes);

    match logger {
        Some(logger) => exp
            .zip(1..(n_episodes + 1))
            .inspect(|&(ref res, i)| {
                info!(logger, "episode {}", i; res);
            })
            .map(|(res, _)| res)
            .collect(),

        None => exp.collect(),
    }
}

/// Utility for running a single evaluation episode.
pub struct Evaluation<'a, C: 'a, D> {
    agent: &'a mut C,
    domain_factory: Box<Fn() -> D>,
}

impl<'a, S: Space, A: Space, C, D> Evaluation<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    pub fn new(agent: &'a mut C, domain_factory: Box<Fn() -> D>) -> Evaluation<'a, C, D> {
        Evaluation {
            agent,
            domain_factory,
        }
    }
}

impl<'a, S: Space, A: Space, C, D> Iterator for Evaluation<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    type Item = Episode;

    fn next(&mut self) -> Option<Episode> {
        let mut domain = (self.domain_factory)();
        let mut a = self.agent.sample_target(&domain.emit().state());

        let mut e = Episode {
            steps: 1,
            reward: 0.0,
        };

        loop {
            let t = domain.step(a);

            e.steps += 1;
            e.reward += t.reward;

            a = match t.to {
                Observation::Terminal(_) => {
                    self.agent.handle_terminal(&t);
                    break;
                },
                _ => self.agent.sample_target(&t.to.state()),
            };
        }

        Some(e)
    }
}

/// Utility for running a sequence of training episodes.
pub struct SerialExperiment<'a, C: 'a, D> {
    agent: &'a mut C,
    domain_factory: Box<Fn() -> D>,

    step_limit: u64,
}

impl<'a, S: Space, A: Space, C, D> SerialExperiment<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    pub fn new(
        agent: &'a mut C,
        domain_factory: Box<Fn() -> D>,
        step_limit: u64,
    ) -> SerialExperiment<'a, C, D>
    {
        SerialExperiment {
            agent,
            domain_factory,
            step_limit,
        }
    }
}

impl<'a, S: Space, A: Space, C, D> Iterator for SerialExperiment<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    type Item = Episode;

    fn next(&mut self) -> Option<Episode> {
        let mut domain = (self.domain_factory)();
        let mut a = self.agent.sample_behaviour(domain.emit().state());

        let mut e = Episode {
            steps: 1,
            reward: 0.0,
        };

        for j in 1..(self.step_limit + 1) {
            let t = domain.step(a);

            e.steps = j;
            e.reward += t.reward;

            self.agent.handle_sample(&t);

            // TODO: Clean this mess up!
            if let Observation::Terminal(_) = t.to {
                self.agent.handle_terminal(&t);
                break;
            } else if j >= self.step_limit {
                self.agent.handle_terminal(&t);
                break;
            } else {
                a = self.agent.sample_behaviour(&t.to.state());
            }
        }

        Some(e)
    }
}
<commit_msg>refactor(core): only call handle_sample if non-terminal<commit_after>use core::Controller;
use domains::{Domain, Observation};
use geometry::Space;
use slog::{Logger, Record, Result as LogResult, Serializer, KV};

/// Container for episodic statistics.
#[derive(Debug)]
pub struct Episode {
    /// The number of steps taken to reach the terminal state.
    pub steps: u64,

    /// The total accumulated reward over the episode.
    pub reward: f64,
}

impl KV for Episode {
    fn serialize(&self, _: &Record, serializer: &mut Serializer) -> LogResult {
        serializer.emit_u64("steps", self.steps)?;
        serializer.emit_f64("reward", self.reward)?;

        Ok(())
    }
}

/// Helper function for running experiments.
pub fn run(
    runner: impl Iterator<Item = Episode>,
    n_episodes: usize,
    logger: Option<Logger>,
) -> Vec<Episode>
{
    let exp = runner.take(n_episodes);

    match logger {
        Some(logger) => exp
            .zip(1..(n_episodes + 1))
            .inspect(|&(ref res, i)| {
                info!(logger, "episode {}", i; res);
            })
            .map(|(res, _)| res)
            .collect(),

        None => exp.collect(),
    }
}

/// Utility for running a single evaluation episode.
pub struct Evaluation<'a, C: 'a, D> {
    agent: &'a mut C,
    domain_factory: Box<Fn() -> D>,
}

impl<'a, S: Space, A: Space, C, D> Evaluation<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    pub fn new(agent: &'a mut C, domain_factory: Box<Fn() -> D>) -> Evaluation<'a, C, D> {
        Evaluation {
            agent,
            domain_factory,
        }
    }
}

impl<'a, S: Space, A: Space, C, D> Iterator for Evaluation<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    type Item = Episode;

    fn next(&mut self) -> Option<Episode> {
        let mut domain = (self.domain_factory)();
        let mut a = self.agent.sample_target(&domain.emit().state());

        let mut e = Episode {
            steps: 1,
            reward: 0.0,
        };

        loop {
            let t = domain.step(a);

            e.steps += 1;
            e.reward += t.reward;

            a = match t.to {
                Observation::Terminal(_) => {
                    self.agent.handle_terminal(&t);
                    break;
                },
                _ => self.agent.sample_target(&t.to.state()),
            };
        }

        Some(e)
    }
}

/// Utility for running a sequence of training episodes.
pub struct SerialExperiment<'a, C: 'a, D> {
    agent: &'a mut C,
    domain_factory: Box<Fn() -> D>,

    step_limit: u64,
}

impl<'a, S: Space, A: Space, C, D> SerialExperiment<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    pub fn new(
        agent: &'a mut C,
        domain_factory: Box<Fn() -> D>,
        step_limit: u64,
    ) -> SerialExperiment<'a, C, D>
    {
        SerialExperiment {
            agent,
            domain_factory,
            step_limit,
        }
    }
}

impl<'a, S: Space, A: Space, C, D> Iterator for SerialExperiment<'a, C, D>
where
    C: Controller<S::Value, A::Value>,
    D: Domain<StateSpace = S, ActionSpace = A>,
{
    type Item = Episode;

    fn next(&mut self) -> Option<Episode> {
        let mut domain = (self.domain_factory)();
        let mut a = self.agent.sample_behaviour(domain.emit().state());

        let mut e = Episode {
            steps: 1,
            reward: 0.0,
        };

        for j in 1..(self.step_limit + 1) {
            let t = domain.step(a);

            e.steps = j;
            e.reward += t.reward;

            // TODO: Clean this mess up!
            if let Observation::Terminal(_) = t.to {
                self.agent.handle_terminal(&t);
                break;
            } else if j >= self.step_limit {
                self.agent.handle_sample(&t);
                break;
            } else {
                self.agent.handle_sample(&t);

                a = self.agent.sample_behaviour(&t.to.state());
            }
        }

        Some(e)
    }
}
<|endoftext|>


<commit_before>pub mod line;

use core::codepointinfo::CodepointInfo;

use self::line::Line;

#[derive(Debug, Clone)]
struct Dimension {
    l: usize,
    c: usize,
    w: usize,
    h: usize,
}

// the screen is composed of lines
#[derive(Debug, Clone)]
pub struct Screen {
    pub line: Vec<Line>,
    pub used: usize, // number of used line
    pub width: usize,
    pub height: usize,
}

impl Screen {
    pub fn new(width: usize, height: usize) -> Screen {
        let mut line: Vec<Line> = Vec::new();
        for _ in 0..height {
            line.push(Line::new(width));
        }

        Screen {
            line: line,
            used: 0,
            width: width,
            height: height,
        }
    }

    pub fn resize(&mut self, width: usize, height: usize) {

        self.line.resize(height, Line::new(width));
        for i in 0..height {
            self.line[i].chars.resize(width, CodepointInfo::new());
            self.line[i].width = width;
            self.line[i].used = 0;
        }
        self.width = width;
        self.height = height;
        self.used = 0;
    }

    /// append
    pub fn push(&mut self, cpi: CodepointInfo) -> (bool, usize) {

        if self.used == self.height {
            return (false, self.used);
        }

        if self.line[self.used].read_only {
            self.used += 1;
        }

        if self.used == self.height {
            return (false, self.used);
        }

        let cp = cpi.cp;
        let line = &mut self.line[self.used];
        let (ok, _) = line.push(cpi);

        if ok == true {
            if cp == '\n' || cp == '\r' {
                line.read_only = true;
            }
        }
        (ok, self.used)
    }

    pub fn clear(&mut self) {
        for h in 0..self.height {
            self.line[h].clear();
        }
        self.used = 0;
    }

    pub fn get_mut_line(&mut self, index: usize) -> Option<&mut Line> {
        if index < self.height {
            Some(&mut self.line[index])
        } else {
            None
        }
    }

    pub fn get_line(&self, index: usize) -> Option<&Line> {
        if index < self.height {
            Some(&self.line[index])
        } else {
            None
        }
    }

    pub fn get_mut_used_line(&mut self, index: usize) -> Option<&mut Line> {
        if index < self.used {
            Some(&mut self.line[index])
        } else {
            None
        }
    }

    pub fn get_used_line(&self, index: usize) -> Option<&Line> {
        if index < self.used {
            Some(&self.line[index])
        } else {
            None
        }
    }

    pub fn get_cpinfo(&self, x: usize, y: usize) -> Option<&CodepointInfo> {
        match self.get_line(y) {
            None => None,
            Some(l) => l.get_cpi(x),
        }
    }

    pub fn get_mut_cpinfo(&mut self, x: usize, y: usize) -> Option<&mut CodepointInfo> {
        match self.get_mut_line(y) {
            None => None,
            Some(l) => l.get_mut_cpi(x),
        }
    }

    pub fn get_used_cpinfo(&self, x: usize, y: usize) -> Option<&CodepointInfo> {
        match self.get_used_line(y) {
            None => None,
            Some(l) => l.get_used_cpi(x),
        }
    }

    pub fn get_mut_used_cpinfo(&mut self, x: usize, y: usize) -> Option<&mut CodepointInfo> {
        match self.get_mut_used_line(y) {
            None => None,
            Some(l) => l.get_mut_used_cpi(x),
        }
    }

    pub fn get_mut_first_cpinfo(&mut self) -> (Option<&mut CodepointInfo>, usize, usize) {
        match self.get_mut_used_line(0) {
            None => (None, 0, 0),
            Some(l) => (l.get_mut_used_cpi(0), 0, 0),
        }
    }

    pub fn get_mut_last_cpinfo(&mut self) -> (Option<&mut CodepointInfo>, usize, usize) {
        let y = self.used;
        match self.get_mut_used_line(y) {
            None => (None, 0, 0),
            Some(l) => {
                let x = l.used;
                (l.get_mut_used_cpi(0), x, y)
            }
        }
    }

    pub fn get_first_cpinfo(&self) -> (Option<&CodepointInfo>, usize, usize) {
        match self.get_used_line(0) {
            None => (None, 0, 0),
            Some(l) => (l.get_used_cpi(0), 0, 0),
        }
    }

    pub fn get_last_cpinfo(&self) -> (Option<&CodepointInfo>, usize, usize) {
        let y = self.used;
        match self.get_used_line(y) {
            None => (None, 0, 0),
            Some(l) => {
                let x = l.used;
                (l.get_used_cpi(0), x, y)
            }
        }
    }

    pub fn find_cpi_by_offset(&self, offset: u64) -> (Option<&CodepointInfo>, usize, usize) {
        // TODO: use dichotomic search
        for y in 0..self.height {
            let l = self.get_line(y).unwrap();
            for x in 0..l.width {
                let cpi = l.get_cpi(x).unwrap();
                if cpi.offset == offset {
                    return (Some(cpi), x, y);
                }
            }
        }
        (None, 0, 0)
    }

    pub fn contains_offset(&self, offset: u64) -> bool {
        //TODO: cache first/las_ offset as self.members
        let (cpi, _, _) = self.find_cpi_by_offset(offset);
        match cpi {
            Some(_) => true,
            _ => false,
        }
    }
}

#[test]
fn test_screen() {

    let mut scr = Screen::new(640, 480);
    assert_eq!(640, scr.width);
    assert_eq!(480, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());

    scr.resize(800, 600);
    assert_eq!(800, scr.width);
    assert_eq!(600, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());

    scr.resize(1024, 768);
    assert_eq!(1024, scr.width);
    assert_eq!(768, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());

    scr.resize(640, 480);
    assert_eq!(640, scr.width);
    assert_eq!(480, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());
}
<commit_msg>Screen : rename some fields : used -> current_line_index<commit_after>pub mod line;

use core::codepointinfo::CodepointInfo;

use self::line::Line;

// the screen is composed of lines
#[derive(Debug, Clone)]
pub struct Screen {
    pub line: Vec<Line>,
    pub current_line_index: usize,
    pub width: usize,
    pub height: usize,
}

impl Screen {
    pub fn new(width: usize, height: usize) -> Screen {
        let mut line: Vec<Line> = Vec::new();
        for _ in 0..height {
            line.push(Line::new(width));
        }

        Screen {
            line: line,
            current_line_index: 0,
            width: width,
            height: height,
        }
    }

    pub fn resize(&mut self, width: usize, height: usize) {

        self.line.resize(height, Line::new(width));
        for i in 0..height {
            self.line[i].chars.resize(width, CodepointInfo::new());
            self.line[i].width = width;
            self.line[i].used = 0;
        }
        self.width = width;
        self.height = height;
        self.current_line_index = 0;
    }

    /// append
    pub fn push(&mut self, cpi: CodepointInfo) -> (bool, usize) {

        if self.current_line_index == self.height {
            return (false, self.current_line_index);
        }

        if self.line[self.current_line_index].read_only {
            self.current_line_index += 1;
        }

        if self.current_line_index == self.height {
            return (false, self.current_line_index);
        }

        let cp = cpi.cp;
        let line = &mut self.line[self.current_line_index];
        let (ok, _) = line.push(cpi);

        if ok == true {
            if cp == '\n' || cp == '\r' {
                line.read_only = true;
            }
        }
        (ok, self.current_line_index)
    }

    pub fn clear(&mut self) {
        for h in 0..self.height {
            self.line[h].clear();
        }
        self.current_line_index = 0;
    }

    pub fn get_mut_line(&mut self, index: usize) -> Option<&mut Line> {
        if index < self.height {
            Some(&mut self.line[index])
        } else {
            None
        }
    }

    pub fn get_line(&self, index: usize) -> Option<&Line> {
        if index < self.height {
            Some(&self.line[index])
        } else {
            None
        }
    }

    pub fn get_mut_used_line(&mut self, index: usize) -> Option<&mut Line> {
        if index < self.current_line_index {
            Some(&mut self.line[index])
        } else {
            None
        }
    }

    pub fn get_used_line(&self, index: usize) -> Option<&Line> {
        if index < self.current_line_index {
            Some(&self.line[index])
        } else {
            None
        }
    }

    pub fn get_cpinfo(&self, x: usize, y: usize) -> Option<&CodepointInfo> {
        match self.get_line(y) {
            None => None,
            Some(l) => l.get_cpi(x),
        }
    }

    pub fn get_mut_cpinfo(&mut self, x: usize, y: usize) -> Option<&mut CodepointInfo> {
        match self.get_mut_line(y) {
            None => None,
            Some(l) => l.get_mut_cpi(x),
        }
    }

    pub fn get_used_cpinfo(&self, x: usize, y: usize) -> Option<&CodepointInfo> {
        match self.get_used_line(y) {
            None => None,
            Some(l) => l.get_used_cpi(x),
        }
    }

    pub fn get_mut_used_cpinfo(&mut self, x: usize, y: usize) -> Option<&mut CodepointInfo> {
        match self.get_mut_used_line(y) {
            None => None,
            Some(l) => l.get_mut_used_cpi(x),
        }
    }

    pub fn get_mut_first_cpinfo(&mut self) -> (Option<&mut CodepointInfo>, usize, usize) {
        match self.get_mut_used_line(0) {
            None => (None, 0, 0),
            Some(l) => (l.get_mut_used_cpi(0), 0, 0),
        }
    }

    pub fn get_mut_last_cpinfo(&mut self) -> (Option<&mut CodepointInfo>, usize, usize) {
        let y = self.current_line_index;
        match self.get_mut_used_line(y) {
            None => (None, 0, 0),
            Some(l) => {
                let x = l.used;
                (l.get_mut_used_cpi(0), x, y)
            }
        }
    }

    pub fn get_first_cpinfo(&self) -> (Option<&CodepointInfo>, usize, usize) {
        match self.get_used_line(0) {
            None => (None, 0, 0),
            Some(l) => (l.get_used_cpi(0), 0, 0),
        }
    }

    pub fn get_last_cpinfo(&self) -> (Option<&CodepointInfo>, usize, usize) {
        let y = self.current_line_index;
        match self.get_used_line(y) {
            None => (None, 0, 0),
            Some(l) => {
                let x = l.used;
                (l.get_used_cpi(0), x, y)
            }
        }
    }

    pub fn find_cpi_by_offset(&self, offset: u64) -> (Option<&CodepointInfo>, usize, usize) {
        // TODO: use dichotomic search
        for y in 0..self.height {
            let l = self.get_line(y).unwrap();
            for x in 0..l.width {
                let cpi = l.get_cpi(x).unwrap();
                if cpi.offset == offset {
                    return (Some(cpi), x, y);
                }
            }
        }
        (None, 0, 0)
    }

    pub fn contains_offset(&self, offset: u64) -> bool {
        //TODO: cache first/las_ offset as self.members
        let (cpi, _, _) = self.find_cpi_by_offset(offset);
        match cpi {
            Some(_) => true,
            _ => false,
        }
    }
}

#[test]
fn test_screen() {

    let mut scr = Screen::new(640, 480);
    assert_eq!(640, scr.width);
    assert_eq!(480, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());

    scr.resize(800, 600);
    assert_eq!(800, scr.width);
    assert_eq!(600, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());

    scr.resize(1024, 768);
    assert_eq!(1024, scr.width);
    assert_eq!(768, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());

    scr.resize(640, 480);
    assert_eq!(640, scr.width);
    assert_eq!(480, scr.height);
    assert_eq!(scr.height, scr.line.len());
    assert_eq!(scr.width, scr.line[0].chars.len());
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

#![feature(async_await)]

use clap::{App, Arg};
use futures::{
    future::{self, Ready},
    prelude::*,
};
use service::World;
use std::{io, net::SocketAddr};
use tarpc::{
    context,
    server::{self, Channel, Handler},
};

// This is the type that implements the generated World trait. It is the business logic
// and is used to start the server.
#[derive(Clone)]
struct HelloServer(SocketAddr);

impl World for HelloServer {
    // Each defined rpc generates two items in the trait, a fn that serves the RPC, and
    // an associated type representing the future output by the fn.

    type HelloFut = Ready<String>;

    fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
        future::ready(format!(
            "Hello, {}! You are connected from {:?}.",
            name, self.0
        ))
    }
}

#[tokio::main]
async fn main() -> io::Result<()> {
    env_logger::init();

    let flags = App::new("Hello Server")
        .version("0.1")
        .author("Tim <tikue@google.com>")
        .about("Say hello!")
        .arg(
            Arg::with_name("port")
                .short("p")
                .long("port")
                .value_name("NUMBER")
                .help("Sets the port number to listen on")
                .required(true)
                .takes_value(true),
        )
        .get_matches();

    let port = flags.value_of("port").unwrap();
    let port = port
        .parse()
        .unwrap_or_else(|e| panic!(r#"--port value "{}" invalid: {}"#, port, e));

    let server_addr = ([0, 0, 0, 0], port).into();

    // bincode_transport is provided by the associated crate bincode-transport. It makes it easy
    // to start up a serde-powered bincode serialization strategy over TCP.
    tarpc_json_transport::listen(&server_addr)?
        // Ignore accept errors.
        .filter_map(|r| future::ready(r.ok()))
        .map(server::BaseChannel::with_defaults)
        // Limit channels to 1 per IP.
        .max_channels_per_key(1, |t| t.as_ref().peer_addr().unwrap().ip())
        // serve is generated by the service attribute. It takes as input any type implementing
        // the generated World trait.
        .map(|channel| {
            let server = HelloServer(channel.as_ref().as_ref().peer_addr().unwrap());
            channel.respond_with(server.serve()).execute()
        })
        // Max 10 channels.
        .buffer_unordered(10)
        .for_each(|_| async {})
        .await;

    Ok(())
}
<commit_msg>Fix comment in example service<commit_after>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

#![feature(async_await)]

use clap::{App, Arg};
use futures::{
    future::{self, Ready},
    prelude::*,
};
use service::World;
use std::{io, net::SocketAddr};
use tarpc::{
    context,
    server::{self, Channel, Handler},
};

// This is the type that implements the generated World trait. It is the business logic
// and is used to start the server.
#[derive(Clone)]
struct HelloServer(SocketAddr);

impl World for HelloServer {
    // Each defined rpc generates two items in the trait, a fn that serves the RPC, and
    // an associated type representing the future output by the fn.

    type HelloFut = Ready<String>;

    fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
        future::ready(format!(
            "Hello, {}! You are connected from {:?}.",
            name, self.0
        ))
    }
}

#[tokio::main]
async fn main() -> io::Result<()> {
    env_logger::init();

    let flags = App::new("Hello Server")
        .version("0.1")
        .author("Tim <tikue@google.com>")
        .about("Say hello!")
        .arg(
            Arg::with_name("port")
                .short("p")
                .long("port")
                .value_name("NUMBER")
                .help("Sets the port number to listen on")
                .required(true)
                .takes_value(true),
        )
        .get_matches();

    let port = flags.value_of("port").unwrap();
    let port = port
        .parse()
        .unwrap_or_else(|e| panic!(r#"--port value "{}" invalid: {}"#, port, e));

    let server_addr = ([0, 0, 0, 0], port).into();

    // tarpc_json_transport is provided by the associated crate tarpc-json-transport. It makes it easy
    // to start up a serde-powered json serialization strategy over TCP.
    tarpc_json_transport::listen(&server_addr)?
        // Ignore accept errors.
        .filter_map(|r| future::ready(r.ok()))
        .map(server::BaseChannel::with_defaults)
        // Limit channels to 1 per IP.
        .max_channels_per_key(1, |t| t.as_ref().peer_addr().unwrap().ip())
        // serve is generated by the service attribute. It takes as input any type implementing
        // the generated World trait.
        .map(|channel| {
            let server = HelloServer(channel.as_ref().as_ref().peer_addr().unwrap());
            channel.respond_with(server.serve()).execute()
        })
        // Max 10 channels.
        .buffer_unordered(10)
        .for_each(|_| async {})
        .await;

    Ok(())
}
<|endoftext|>


<commit_before>#[cfg(feature = "std")]
use crate::convert::Convert;
use crate::{AHasher};
#[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
use const_random::const_random;
use core::fmt;
use core::hash::BuildHasher;
use core::hash::Hasher;
#[cfg(feature = "std")]
use lazy_static::*;
use core::sync::atomic::{AtomicUsize, Ordering};

#[cfg(feature = "std")]
lazy_static! {
    static ref SEEDS: [[u64; 4]; 2] = {
        let mut result: [u8; 64] = [0; 64];
        getrandom::getrandom(&mut result).expect("getrandom::getrandom() failed.");
        result.convert()
    };
}
static COUNTER: AtomicUsize = AtomicUsize::new(0);

pub(crate) const PI: [u64; 4] = [
    0x243f_6a88_85a3_08d3,
    0x1319_8a2e_0370_7344,
    0xa409_3822_299f_31d0,
    0x082e_fa98_ec4e_6c89,
];

#[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
const PI2: [u64; 4] = [
    0x4528_21e6_38d0_1377,
    0xbe54_66cf_34e9_0c6c,
    0xc0ac_29b7_c97c_50dd,
    0x3f84_d5b5_b547_0917,
];

#[inline]
pub(crate) fn seeds() -> [u64; 4] {
    #[cfg(feature = "std")]
    { SEEDS[1] }

    #[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
    { [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)] }

    #[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
    { PI }
}

/// Provides a [Hasher] factory. This is typically used (e.g. by [HashMap]) to create
/// [AHasher]s in order to hash the keys of the map. See `build_hasher` below.
///
/// [build_hasher]: ahash::
/// [Hasher]: std::hash::Hasher
/// [BuildHasher]: std::hash::BuildHasher
/// [HashMap]: std::collections::HashMap
#[derive(Clone)]
pub struct RandomState {
    pub(crate) k0: u64,
    pub(crate) k1: u64,
    pub(crate) k2: u64,
    pub(crate) k3: u64,
}

impl fmt::Debug for RandomState {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.pad("RandomState { .. }")
    }
}

impl RandomState {
    /// Use randomly generated keys
    #[inline]
    pub fn new() -> RandomState {
        #[cfg(feature = "std")]
        {
            RandomState::from_keys(SEEDS[0], SEEDS[1])
        }

        #[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
        {
            RandomState::from_keys(
                [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)],
                [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)],
            )
        }

        #[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
        {
            RandomState::from_keys(PI, PI2)
        }
    }

    /// Allows for supplying seeds, but each time it is called the resulting state will be different.
    /// This is done using a static counter, so it can safely be used with a fixed keys.
    #[inline]
    pub fn generate_with(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
        RandomState::from_keys(seeds(), [k0, k1, k2, k3])
    }

    fn from_keys(a: [u64; 4], b: [u64; 4]) -> RandomState {
        let [k0, k1, k2, k3] = a;
        let mut hasher = AHasher::from_random_state(&RandomState { k0, k1, k2, k3 });

        let stack_mem_loc = &hasher as *const _ as usize;
        hasher.write_usize(COUNTER.fetch_add(stack_mem_loc, Ordering::Relaxed));
        let mix = |k: u64| {
            let mut h = hasher.clone();
            h.write_u64(k);
            h.finish()
        };

        RandomState { k0: mix(b[0]), k1: mix(b[1]), k2: mix(b[2]), k3: mix(b[3]) }
    }

    /// Internal. Used by Default.
    #[inline]
    pub(crate) fn with_fixed_keys() -> RandomState {
        let [k0, k1, k2, k3] = seeds();
        RandomState { k0, k1, k2, k3 }
    }

    /// Allows for explicitly setting the seeds to used.
    #[inline]
    pub const fn with_seeds(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
        RandomState { k0, k1, k2, k3 }
    }
}

impl Default for RandomState {
    #[inline]
    fn default() -> Self {
        Self::new()
    }
}

impl BuildHasher for RandomState {
    type Hasher = AHasher;

    /// Constructs a new [AHasher] with keys based on this [RandomState] object.
    /// This means that two different [RandomState]s will will generate
    /// [AHasher]s that will return different hashcodes, but [Hasher]s created from the same [BuildHasher]
    /// will generate the same hashes for the same input data.
    ///
    /// # Examples
    ///
    /// ```
    /// use ahash::{AHasher, RandomState};
    /// use std::hash::{Hasher, BuildHasher};
    ///
    /// let build_hasher = RandomState::new();
    /// let mut hasher_1 = build_hasher.build_hasher();
    /// let mut hasher_2 = build_hasher.build_hasher();
    ///
    /// hasher_1.write_u32(1234);
    /// hasher_2.write_u32(1234);
    ///
    /// assert_eq!(hasher_1.finish(), hasher_2.finish());
    ///
    /// let other_build_hasher = RandomState::new();
    /// let mut different_hasher = other_build_hasher.build_hasher();
    /// different_hasher.write_u32(1234);
    /// assert_ne!(different_hasher.finish(), hasher_1.finish());
    /// ```
    /// [Hasher]: std::hash::Hasher
    /// [BuildHasher]: std::hash::BuildHasher
    /// [HashMap]: std::collections::HashMap
    #[inline]
    fn build_hasher(&self) -> AHasher {
        AHasher::from_random_state(self)
    }
}

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

    #[test]
    fn test_unique() {
        let a = RandomState::new();
        let b = RandomState::new();
        assert_ne!(a.build_hasher().finish(), b.build_hasher().finish());
    }

    #[test]
    fn test_with_seeds_const() {
        const _CONST_RANDOM_STATE: RandomState = RandomState::with_seeds(17, 19, 21, 23);
    }
}
<commit_msg>Only deref seeds once.<commit_after>#[cfg(feature = "std")]
use crate::convert::Convert;
use crate::{AHasher};
#[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
use const_random::const_random;
use core::fmt;
use core::hash::BuildHasher;
use core::hash::Hasher;
#[cfg(feature = "std")]
use lazy_static::*;
use core::sync::atomic::{AtomicUsize, Ordering};

#[cfg(feature = "std")]
lazy_static! {
    static ref SEEDS: [[u64; 4]; 2] = {
        let mut result: [u8; 64] = [0; 64];
        getrandom::getrandom(&mut result).expect("getrandom::getrandom() failed.");
        result.convert()
    };
}
static COUNTER: AtomicUsize = AtomicUsize::new(0);

pub(crate) const PI: [u64; 4] = [
    0x243f_6a88_85a3_08d3,
    0x1319_8a2e_0370_7344,
    0xa409_3822_299f_31d0,
    0x082e_fa98_ec4e_6c89,
];

#[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
const PI2: [u64; 4] = [
    0x4528_21e6_38d0_1377,
    0xbe54_66cf_34e9_0c6c,
    0xc0ac_29b7_c97c_50dd,
    0x3f84_d5b5_b547_0917,
];

#[inline]
pub(crate) fn seeds() -> [u64; 4] {
    #[cfg(feature = "std")]
    { SEEDS[1] }
    #[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
    { [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)] }
    #[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
    { PI }
}

/// Provides a [Hasher] factory. This is typically used (e.g. by [HashMap]) to create
/// [AHasher]s in order to hash the keys of the map. See `build_hasher` below.
///
/// [build_hasher]: ahash::
/// [Hasher]: std::hash::Hasher
/// [BuildHasher]: std::hash::BuildHasher
/// [HashMap]: std::collections::HashMap
#[derive(Clone)]
pub struct RandomState {
    pub(crate) k0: u64,
    pub(crate) k1: u64,
    pub(crate) k2: u64,
    pub(crate) k3: u64,
}

impl fmt::Debug for RandomState {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.pad("RandomState { .. }")
    }
}

impl RandomState {
    /// Use randomly generated keys
    #[inline]
    pub fn new() -> RandomState {
        #[cfg(feature = "std")]
        {
            let seeds = *SEEDS;
            RandomState::from_keys(seeds[0], seeds[1])
        }
        #[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
        {
            RandomState::from_keys(
                [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)],
                [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)],
            )
        }
        #[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
        {
            RandomState::from_keys(PI, PI2)
        }
    }

    /// Allows for supplying seeds, but each time it is called the resulting state will be different.
    /// This is done using a static counter, so it can safely be used with a fixed keys.
    #[inline]
    pub fn generate_with(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
        RandomState::from_keys(seeds(), [k0, k1, k2, k3])
    }

    fn from_keys(a: [u64; 4], b: [u64; 4]) -> RandomState {
        let [k0, k1, k2, k3] = a;
        let mut hasher = AHasher::from_random_state(&RandomState { k0, k1, k2, k3 });

        let stack_mem_loc = &hasher as *const _ as usize;
        hasher.write_usize(COUNTER.fetch_add(stack_mem_loc, Ordering::Relaxed));
        let mix = |k: u64| {
            let mut h = hasher.clone();
            h.write_u64(k);
            h.finish()
        };

        RandomState { k0: mix(b[0]), k1: mix(b[1]), k2: mix(b[2]), k3: mix(b[3]) }
    }

    /// Internal. Used by Default.
    #[inline]
    pub(crate) fn with_fixed_keys() -> RandomState {
        let [k0, k1, k2, k3] = seeds();
        RandomState { k0, k1, k2, k3 }
    }

    /// Allows for explicitly setting the seeds to used.
    #[inline]
    pub const fn with_seeds(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
        RandomState { k0, k1, k2, k3 }
    }
}

impl Default for RandomState {
    #[inline]
    fn default() -> Self {
        Self::new()
    }
}

impl BuildHasher for RandomState {
    type Hasher = AHasher;

    /// Constructs a new [AHasher] with keys based on this [RandomState] object.
    /// This means that two different [RandomState]s will will generate
    /// [AHasher]s that will return different hashcodes, but [Hasher]s created from the same [BuildHasher]
    /// will generate the same hashes for the same input data.
    ///
    /// # Examples
    ///
    /// ```
    /// use ahash::{AHasher, RandomState};
    /// use std::hash::{Hasher, BuildHasher};
    ///
    /// let build_hasher = RandomState::new();
    /// let mut hasher_1 = build_hasher.build_hasher();
    /// let mut hasher_2 = build_hasher.build_hasher();
    ///
    /// hasher_1.write_u32(1234);
    /// hasher_2.write_u32(1234);
    ///
    /// assert_eq!(hasher_1.finish(), hasher_2.finish());
    ///
    /// let other_build_hasher = RandomState::new();
    /// let mut different_hasher = other_build_hasher.build_hasher();
    /// different_hasher.write_u32(1234);
    /// assert_ne!(different_hasher.finish(), hasher_1.finish());
    /// ```
    /// [Hasher]: std::hash::Hasher
    /// [BuildHasher]: std::hash::BuildHasher
    /// [HashMap]: std::collections::HashMap
    #[inline]
    fn build_hasher(&self) -> AHasher {
        AHasher::from_random_state(self)
    }
}

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

    #[test]
    fn test_unique() {
        let a = RandomState::new();
        let b = RandomState::new();
        assert_ne!(a.build_hasher().finish(), b.build_hasher().finish());
    }

    #[test]
    fn test_with_seeds_const() {
        const _CONST_RANDOM_STATE: RandomState = RandomState::with_seeds(17, 19, 21, 23);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) <2015> <lummax>
// Licensed under MIT (http://opensource.org/licenses/MIT)

use std::collections::RingBuf;

use gc_object::GCObjectRef;
use line_allocator::LineAllocator;

pub struct RCCollector {
    old_root_buffer: RingBuf<GCObjectRef>,
    decrement_buffer: RingBuf<GCObjectRef>,
    modified_buffer: RingBuf<GCObjectRef>,
}

impl RCCollector {
    pub fn new() -> RCCollector {
        return RCCollector {
            old_root_buffer: RingBuf::new(),
            decrement_buffer: RingBuf::new(),
            modified_buffer: RingBuf::new(),
        };
    }

    pub fn collect(&mut self, line_allocator: &mut LineAllocator,
                   roots: &[GCObjectRef]) {
        debug!("Start RC collection");
        self.process_old_roots();
        self.process_current_roots(line_allocator, roots);
        self.process_mod_buffer(line_allocator);
        self.process_decrement_buffer(line_allocator);
        debug!("Complete collection");
    }

    pub fn write_barrier(&mut self, object: GCObjectRef) {
        debug!("Write barrier on object {}", object);
        self.modified(object);
        for child in unsafe{ (*object).children() }.into_iter() {
            self.decrement(child);
        }
        unsafe{ (*object).set_logged(true); }
    }

    fn modified(&mut self, object: GCObjectRef) {
        debug!("Push object {} into mod buffer", object);
        self.modified_buffer.push_back(object);
    }

    fn decrement(&mut self, object: GCObjectRef) {
        debug!("Push object {} into dec buffer", object);
        self.decrement_buffer.push_back(object);
    }

    fn increment(&mut self, line_allocator: &mut LineAllocator, object: GCObjectRef) {
        debug!("Increment object {}", object);
        if unsafe{ (*object).increment() } {
            line_allocator.increment_lines(object);
            self.modified(object);
        }
    }

    fn process_old_roots(&mut self) {
        debug!("Process old roots (size {})", self.old_root_buffer.len());
        self.decrement_buffer.extend(self.old_root_buffer.drain());
    }

    fn process_current_roots(&mut self, line_allocator: &mut LineAllocator,
                             roots: &[GCObjectRef]) {
        debug!("Process current roots (size {})", roots.len());
        for root in roots.iter().map(|o| *o) {
            debug!("Process root object: {}", root);
            self.increment(line_allocator, root);
            self.old_root_buffer.push_back(root);
        }
    }

    fn process_mod_buffer(&mut self, line_allocator: &mut LineAllocator) {
        debug!("Process mod buffer (size {})", self.modified_buffer.len());
        loop {
            match self.modified_buffer.pop_front() {
                None => break,
                Some(object) => {
                    debug!("Process object {} in mod buffer", object);
                    unsafe { (*object).set_logged(false); }
                    for child in unsafe{ (*object).children() }.into_iter() {
                        self.increment(line_allocator, child);
                    }
                }
            }
        }
    }

    fn process_decrement_buffer(&mut self, line_allocator: &mut LineAllocator) {
        debug!("Process dec buffer (size {})", self.decrement_buffer.len());
        loop {
            match self.decrement_buffer.pop_front() {
                None => break,
                Some(object) => {
                    debug!("Process object {} in dec buffer", object);
                    if unsafe{ (*object).decrement() } {
                        line_allocator.unset_gc_object(object);
                        line_allocator.decrement_lines(object);
                        for child in unsafe{ (*object).children() }.into_iter() {
                            self.decrement(child);
                        }
                    }
                }
            }
        }
    }
}
<commit_msg>Reorganize methods for RCCollector<commit_after>// Copyright (c) <2015> <lummax>
// Licensed under MIT (http://opensource.org/licenses/MIT)

use std::collections::RingBuf;

use gc_object::GCObjectRef;
use line_allocator::LineAllocator;

pub struct RCCollector {
    old_root_buffer: RingBuf<GCObjectRef>,
    decrement_buffer: RingBuf<GCObjectRef>,
    modified_buffer: RingBuf<GCObjectRef>,
}

impl RCCollector {
    pub fn new() -> RCCollector {
        return RCCollector {
            old_root_buffer: RingBuf::new(),
            decrement_buffer: RingBuf::new(),
            modified_buffer: RingBuf::new(),
        };
    }

    pub fn collect(&mut self, line_allocator: &mut LineAllocator,
                   roots: &[GCObjectRef]) {
        debug!("Start RC collection");
        self.process_old_roots();
        self.process_current_roots(line_allocator, roots);
        self.process_mod_buffer(line_allocator);
        self.process_decrement_buffer(line_allocator);
        debug!("Complete collection");
    }

    pub fn write_barrier(&mut self, object: GCObjectRef) {
        debug!("Write barrier on object {}", object);
        self.modified(object);
        for child in unsafe{ (*object).children() }.into_iter() {
            self.decrement(child);
        }
        unsafe{ (*object).set_logged(true); }
    }
}

impl RCCollector {
    fn modified(&mut self, object: GCObjectRef) {
        debug!("Push object {} into mod buffer", object);
        self.modified_buffer.push_back(object);
    }

    fn decrement(&mut self, object: GCObjectRef) {
        debug!("Push object {} into dec buffer", object);
        self.decrement_buffer.push_back(object);
    }

    fn increment(&mut self, line_allocator: &mut LineAllocator, object: GCObjectRef) {
        debug!("Increment object {}", object);
        if unsafe{ (*object).increment() } {
            line_allocator.increment_lines(object);
            self.modified(object);
        }
    }

    fn process_old_roots(&mut self) {
        debug!("Process old roots (size {})", self.old_root_buffer.len());
        self.decrement_buffer.extend(self.old_root_buffer.drain());
    }

    fn process_current_roots(&mut self, line_allocator: &mut LineAllocator,
                             roots: &[GCObjectRef]) {
        debug!("Process current roots (size {})", roots.len());
        for root in roots.iter().map(|o| *o) {
            debug!("Process root object: {}", root);
            self.increment(line_allocator, root);
            self.old_root_buffer.push_back(root);
        }
    }

    fn process_mod_buffer(&mut self, line_allocator: &mut LineAllocator) {
        debug!("Process mod buffer (size {})", self.modified_buffer.len());
        loop {
            match self.modified_buffer.pop_front() {
                None => break,
                Some(object) => {
                    debug!("Process object {} in mod buffer", object);
                    unsafe { (*object).set_logged(false); }
                    for child in unsafe{ (*object).children() }.into_iter() {
                        self.increment(line_allocator, child);
                    }
                }
            }
        }
    }

    fn process_decrement_buffer(&mut self, line_allocator: &mut LineAllocator) {
        debug!("Process dec buffer (size {})", self.decrement_buffer.len());
        loop {
            match self.decrement_buffer.pop_front() {
                None => break,
                Some(object) => {
                    debug!("Process object {} in dec buffer", object);
                    if unsafe{ (*object).decrement() } {
                        line_allocator.unset_gc_object(object);
                        line_allocator.decrement_lines(object);
                        for child in unsafe{ (*object).children() }.into_iter() {
                            self.decrement(child);
                        }
                    }
                }
            }
        }
    }
}
<|endoftext|>


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

//! Shader parameter handling.

use std::cell::Cell;
use std::rc::Rc;
use dev = device::shade;

/// Helper trait to transform base types into their corresponding uniforms
pub trait ToUniform {
    /// Create a `UniformValue` representing this value.
    fn to_uniform(&self) -> dev::UniformValue;
}

impl ToUniform for i32 {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueI32(*self)
    }
}

impl ToUniform for f32 {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueF32(*self)
    }
}

impl ToUniform for [i32, ..4] {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueI32Vec(*self)
    }
}

impl ToUniform for [f32, ..4] {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueF32Vec(*self)
    }
}
impl ToUniform for [[f32, ..4], ..4] {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueF32Matrix(*self)
    }
}

/// Variable index of a uniform.
pub type VarUniform = u16;

/// Variable index of a uniform block.
pub type VarBlock = u8;

/// Variable index of a texture.
pub type VarTexture = u8;

/// A texture parameter: consists of a texture handle with an optional sampler.
pub type TextureParam = (super::TextureHandle, Option<super::SamplerHandle>);

/// Borrowed parts of the `ProgramMeta`, used for data link construction
pub type ParamLinkInput<'a> = (
    &'a [dev::UniformVar],
    &'a [dev::BlockVar],
    &'a [dev::SamplerVar]
);

/// A borrowed mutable storage for shader parameter values.
// Not sure if it's the best data structure to represent it.
pub struct ParamValues<'a> {
    /// uniform values to be provided
    pub uniforms: &'a mut [Option<dev::UniformValue>],
    /// uniform buffers to be provided
    pub blocks  : &'a mut [Option<super::BufferHandle>],
    /// textures to be provided
    pub textures: &'a mut [Option<TextureParam>],
}

/// Encloses a shader program with its parameter
pub trait ProgramShell {
    /// Get the contained program
    fn get_program(&self) -> super::ProgramHandle;
    /// Get all the contained parameter values
    fn fill_params(&self, ParamValues);
}

impl ProgramShell for super::ProgramHandle {
    fn get_program(&self) -> super::ProgramHandle {
        self.clone()
    }

    fn fill_params(&self, params: ParamValues) {
        debug_assert!(
            params.uniforms.is_empty() &&
            params.blocks.is_empty() &&
            params.textures.is_empty()
        );
    }
}

/// An error type on either the parameter storage or the program side
#[deriving(Clone, Show)]
pub enum ParameterError<'a> {
    /// Internal error
    ErrorInternal,
    /// Error with the named uniform
    ErrorUniform(&'a str),
    /// Error with the named uniform block
    ErrorBlock(&'a str),
    /// Error with the named texture.
    ErrorTexture(&'a str),
}

/// An error type for the link creation
#[deriving(Clone, Show)]
pub enum ParameterLinkError<'a> {
    /// Program is not valid
    ErrorBadProgram,
    /// A given parameter is not used by the program
    ErrorUnusedParameter(ParameterError<'a>),
    /// A program parameter that is not provided
    ErrorMissingParameter(ParameterError<'a>),
}

/// Abstracts the shader parameter structure, generated by the `shader_param` attribute
pub trait ShaderParam<L> {
    /// Creates a new link, self is passed as a workaround for Rust to not be lost in generics
    fn create_link(&self, ParamLinkInput) -> Result<L, ParameterError<'static>>;
    /// Get all the contained parameter values, using a given link.
    fn fill_params(&self, &L, ParamValues);
}

/// A bundle that encapsulates a program and a custom user-provided
/// structure containing the program parameters.
/// # Type parameters:
///
/// * `L` - auto-generated structure that has a variable index for every field of T
/// * `T` - user-provided structure containing actual parameter values
#[deriving(Clone)]
pub struct CustomShell<L, T> {
    /// Shader program
    program: super::ProgramHandle,
    /// Hidden link that provides parameter indices for user data
    link: L,
    /// Global data in a user-provided struct
    pub data: T,
}

impl<L, T: ShaderParam<L>> CustomShell<L, T> {
    /// Create a new custom shell
    pub fn new(program: super::ProgramHandle, link: L, data: T) -> CustomShell<L, T> {
        CustomShell {
            program: program,
            link: link,
            data: data,
        }
    }
}

impl<L, T: ShaderParam<L>> ProgramShell for CustomShell<L, T> {
    fn get_program(&self) -> super::ProgramHandle {
        self.program
    }

    fn fill_params(&self, params: ParamValues) {
        self.data.fill_params(&self.link, params);
    }
}

/// A named cell containing arbitrary value
pub struct NamedCell<T> {
    /// Name
    pub name: String,
    /// Value
    pub value: Cell<T>,
}

/// A dictionary of parameters, meant to be shared between different programs
pub struct ParamDictionary {
    /// Uniform dictionary
    pub uniforms: Vec<NamedCell<dev::UniformValue>>,
    /// Block dictionary
    pub blocks: Vec<NamedCell<super::BufferHandle>>,
    /// Texture dictionary
    pub textures: Vec<NamedCell<TextureParam>>,
}

/// An associated link structure for `ParamDictionary` that redirects program
/// input to the relevant dictionary cell.
pub struct ParamDictionaryLink {
    uniforms: Vec<uint>,
    blocks: Vec<uint>,
    textures: Vec<uint>,
}

impl<'a> ShaderParam<ParamDictionaryLink> for &'a ParamDictionary {
    fn create_link(&self, (in_uni, in_buf, in_tex): ParamLinkInput)
                   -> Result<ParamDictionaryLink, ParameterError<'static>> {
        //TODO: proper error checks
        Ok(ParamDictionaryLink {
            uniforms: in_uni.iter().map(|var|
                self.uniforms.iter().position(|c| c.name == var.name).unwrap()
            ).collect(),
            blocks: in_buf.iter().map(|var|
                self.blocks  .iter().position(|c| c.name == var.name).unwrap()
            ).collect(),
            textures: in_tex.iter().map(|var|
                self.textures.iter().position(|c| c.name == var.name).unwrap()
            ).collect(),
        })
    }

    fn fill_params(&self, link: &ParamDictionaryLink, out: ParamValues) {
        for (&id, var) in link.uniforms.iter().zip(out.uniforms.mut_iter()) {
            *var = Some(self.uniforms[id].value.get());
        }
        for (&id, var) in link.blocks.iter().zip(out.blocks.mut_iter()) {
            *var = Some(self.blocks[id].value.get());
        }
        for (&id, var) in link.textures.iter().zip(out.textures.mut_iter()) {
            *var = Some(self.textures[id].value.get());
        }
    }
}

impl ShaderParam<ParamDictionaryLink> for Rc<ParamDictionary> {
    fn create_link(&self, input: ParamLinkInput) -> Result<ParamDictionaryLink,
                   ParameterError<'static>> {
        self.deref().create_link(input)
    }

    fn fill_params(&self, link: &ParamDictionaryLink, out: ParamValues) {
        self.deref().fill_params(link, out)
    }
}
<commit_msg>Add error message for assertion in ProgramHandle::fill_params<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Shader parameter handling.

use std::cell::Cell;
use std::rc::Rc;
use dev = device::shade;

/// Helper trait to transform base types into their corresponding uniforms
pub trait ToUniform {
    /// Create a `UniformValue` representing this value.
    fn to_uniform(&self) -> dev::UniformValue;
}

impl ToUniform for i32 {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueI32(*self)
    }
}

impl ToUniform for f32 {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueF32(*self)
    }
}

impl ToUniform for [i32, ..4] {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueI32Vec(*self)
    }
}

impl ToUniform for [f32, ..4] {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueF32Vec(*self)
    }
}
impl ToUniform for [[f32, ..4], ..4] {
    fn to_uniform(&self) -> dev::UniformValue {
        dev::ValueF32Matrix(*self)
    }
}

/// Variable index of a uniform.
pub type VarUniform = u16;

/// Variable index of a uniform block.
pub type VarBlock = u8;

/// Variable index of a texture.
pub type VarTexture = u8;

/// A texture parameter: consists of a texture handle with an optional sampler.
pub type TextureParam = (super::TextureHandle, Option<super::SamplerHandle>);

/// Borrowed parts of the `ProgramMeta`, used for data link construction
pub type ParamLinkInput<'a> = (
    &'a [dev::UniformVar],
    &'a [dev::BlockVar],
    &'a [dev::SamplerVar]
);

/// A borrowed mutable storage for shader parameter values.
// Not sure if it's the best data structure to represent it.
pub struct ParamValues<'a> {
    /// uniform values to be provided
    pub uniforms: &'a mut [Option<dev::UniformValue>],
    /// uniform buffers to be provided
    pub blocks  : &'a mut [Option<super::BufferHandle>],
    /// textures to be provided
    pub textures: &'a mut [Option<TextureParam>],
}

/// Encloses a shader program with its parameter
pub trait ProgramShell {
    /// Get the contained program
    fn get_program(&self) -> super::ProgramHandle;
    /// Get all the contained parameter values
    fn fill_params(&self, ParamValues);
}

impl ProgramShell for super::ProgramHandle {
    fn get_program(&self) -> super::ProgramHandle {
        self.clone()
    }

    fn fill_params(&self, params: ParamValues) {
        debug_assert!(
            params.uniforms.is_empty() &&
            params.blocks.is_empty() &&
            params.textures.is_empty(),
            "trying to bind a program that has uniforms ; please call renderer.connect_program first"
        );
    }
}

/// An error type on either the parameter storage or the program side
#[deriving(Clone, Show)]
pub enum ParameterError<'a> {
    /// Internal error
    ErrorInternal,
    /// Error with the named uniform
    ErrorUniform(&'a str),
    /// Error with the named uniform block
    ErrorBlock(&'a str),
    /// Error with the named texture.
    ErrorTexture(&'a str),
}

/// An error type for the link creation
#[deriving(Clone, Show)]
pub enum ParameterLinkError<'a> {
    /// Program is not valid
    ErrorBadProgram,
    /// A given parameter is not used by the program
    ErrorUnusedParameter(ParameterError<'a>),
    /// A program parameter that is not provided
    ErrorMissingParameter(ParameterError<'a>),
}

/// Abstracts the shader parameter structure, generated by the `shader_param` attribute
pub trait ShaderParam<L> {
    /// Creates a new link, self is passed as a workaround for Rust to not be lost in generics
    fn create_link(&self, ParamLinkInput) -> Result<L, ParameterError<'static>>;
    /// Get all the contained parameter values, using a given link.
    fn fill_params(&self, &L, ParamValues);
}

/// A bundle that encapsulates a program and a custom user-provided
/// structure containing the program parameters.
/// # Type parameters:
///
/// * `L` - auto-generated structure that has a variable index for every field of T
/// * `T` - user-provided structure containing actual parameter values
#[deriving(Clone)]
pub struct CustomShell<L, T> {
    /// Shader program
    program: super::ProgramHandle,
    /// Hidden link that provides parameter indices for user data
    link: L,
    /// Global data in a user-provided struct
    pub data: T,
}

impl<L, T: ShaderParam<L>> CustomShell<L, T> {
    /// Create a new custom shell
    pub fn new(program: super::ProgramHandle, link: L, data: T) -> CustomShell<L, T> {
        CustomShell {
            program: program,
            link: link,
            data: data,
        }
    }
}

impl<L, T: ShaderParam<L>> ProgramShell for CustomShell<L, T> {
    fn get_program(&self) -> super::ProgramHandle {
        self.program
    }

    fn fill_params(&self, params: ParamValues) {
        self.data.fill_params(&self.link, params);
    }
}

/// A named cell containing arbitrary value
pub struct NamedCell<T> {
    /// Name
    pub name: String,
    /// Value
    pub value: Cell<T>,
}

/// A dictionary of parameters, meant to be shared between different programs
pub struct ParamDictionary {
    /// Uniform dictionary
    pub uniforms: Vec<NamedCell<dev::UniformValue>>,
    /// Block dictionary
    pub blocks: Vec<NamedCell<super::BufferHandle>>,
    /// Texture dictionary
    pub textures: Vec<NamedCell<TextureParam>>,
}

/// An associated link structure for `ParamDictionary` that redirects program
/// input to the relevant dictionary cell.
pub struct ParamDictionaryLink {
    uniforms: Vec<uint>,
    blocks: Vec<uint>,
    textures: Vec<uint>,
}

impl<'a> ShaderParam<ParamDictionaryLink> for &'a ParamDictionary {
    fn create_link(&self, (in_uni, in_buf, in_tex): ParamLinkInput)
                   -> Result<ParamDictionaryLink, ParameterError<'static>> {
        //TODO: proper error checks
        Ok(ParamDictionaryLink {
            uniforms: in_uni.iter().map(|var|
                self.uniforms.iter().position(|c| c.name == var.name).unwrap()
            ).collect(),
            blocks: in_buf.iter().map(|var|
                self.blocks  .iter().position(|c| c.name == var.name).unwrap()
            ).collect(),
            textures: in_tex.iter().map(|var|
                self.textures.iter().position(|c| c.name == var.name).unwrap()
            ).collect(),
        })
    }

    fn fill_params(&self, link: &ParamDictionaryLink, out: ParamValues) {
        for (&id, var) in link.uniforms.iter().zip(out.uniforms.mut_iter()) {
            *var = Some(self.uniforms[id].value.get());
        }
        for (&id, var) in link.blocks.iter().zip(out.blocks.mut_iter()) {
            *var = Some(self.blocks[id].value.get());
        }
        for (&id, var) in link.textures.iter().zip(out.textures.mut_iter()) {
            *var = Some(self.textures[id].value.get());
        }
    }
}

impl ShaderParam<ParamDictionaryLink> for Rc<ParamDictionary> {
    fn create_link(&self, input: ParamLinkInput) -> Result<ParamDictionaryLink,
                   ParameterError<'static>> {
        self.deref().create_link(input)
    }

    fn fill_params(&self, link: &ParamDictionaryLink, out: ParamValues) {
        self.deref().fill_params(link, out)
    }
}
<|endoftext|>


<commit_before>/// The `mutate` trait returns a mutation version of a type that implements it.
///
/// Implementer should try to create persisted data-structures

extern crate rand;

use self::rand::Rng;
use super::super::structure::{Program,Condition,Expression,Sensor,Command};

pub trait Mutate {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Self;
}

enum MutateType {
    ThisLevel,
    NextLevel,
}

impl rand::Rand for MutateType {
    fn rand<R: rand::Rng>(_: &mut R) -> Self {
        pick![
            1, MutateType::ThisLevel,
            1, MutateType::NextLevel
        ]
    }
}

impl Mutate for Program {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Program {
        let mutate_type: MutateType = rand::random();
        match mutate_type {
            MutateType::ThisLevel => {
                let mutation: Program = rand::random();
                mutation
            },
            MutateType::NextLevel => {
                match *self {
                    Program::If(ref condition, ref left, ref right) => {
                        match rng.gen_range(0, 3) {
                            0 => { /* mutate condition */
                                      let mutation: Condition = condition.mutate(rng);
                                      Program::If(Box::new(mutation), left.clone(), right.clone())
                            },
                            1 => { /* mutate left */
                                      let mutation: Program = left.mutate(rng);
                                      Program::If(condition.clone(), Box::new(mutation), right.clone())
                            },
                            2 => { /* mutate right */
                                      let mutation: Program = right.mutate(rng);
                                      Program::If(condition.clone(), left.clone(), Box::new(mutation))
                            },
                            _ => { panic!(/* this should not happen */)},
                        }
                    },
                    Program::Command(ref command) => {
                        let mutation: Command = command.mutate(rng);
                        Program::Command(Box::new(mutation))
                    }
                }
            },
        }
    }
}

impl Mutate for Condition {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Condition {
        let mutate_type: MutateType = rand::random();
        match mutate_type {
            MutateType::ThisLevel => {
                let mutation: Condition = rand::random();
                mutation
            },
            MutateType::NextLevel => {
                match *self {
                    Condition::True => Condition::False,
                    Condition::False => Condition::True,
                    Condition::Not(ref condition) => {
                        let mutation: Condition = condition.mutate(rng);
                        Condition::Not(Box::new(mutation))
                    },
                    Condition::Or(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Condition = left.mutate(rng);
                            Condition::Or(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Condition = right.mutate(rng);
                            Condition::Or(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::And(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Condition = left.mutate(rng);
                            Condition::And(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Condition = right.mutate(rng);
                            Condition::And(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::Less(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::Less(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::Less(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::LessEqual(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::LessEqual(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::LessEqual(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::Equal(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::Equal(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::Equal(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::GreaterEqual(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::GreaterEqual(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::GreaterEqual(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::Greater(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::Greater(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::Greater(left.clone(), Box::new(mutation))
                        }
                    }
                }
            }
        }
    }
}

impl Mutate for Expression {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Expression {
        let mutate_type: MutateType = rand::random();
        match mutate_type {
            MutateType::ThisLevel => {
                let mutation: Expression = rand::random();
                mutation
            },
            MutateType::NextLevel => {
                match *self {
                    Expression::Constant(_) => {
                        let mutation: f32 = rand::random();
                        Expression::Constant(mutation)
                    },
                    Expression::Sensor(ref sensor) => {
                        let mutation: Sensor = sensor.mutate(rng);
                        Expression::Sensor(Box::new(mutation))
                    },
                    Expression::Plus(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Plus(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Plus(left.clone(),Box::new(mutation))
                        }
                    },
                    Expression::Minus(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Minus(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Minus(left.clone(), Box::new(mutation))
                        }
                    },
                    Expression::Multiply(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Multiply(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Multiply(left.clone(), Box::new(mutation))
                        }
                    },
                    Expression::Divide(ref left, ref right) => {
                        let mutate_left: bool = rand::random();
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Divide(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Divide(left.clone(), Box::new(mutation))
                        }
                    },
                }
            }
        }
    }
}

impl Mutate for Sensor {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Sensor {
        let mutation: Sensor = rand::random();
        mutation
    }
}

impl Mutate for Command {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Command {
        let mutation: Command = rand::random();
        mutation
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::rand::Rng;
    use structure::{Expression,Sensor};

    #[derive(PartialEq,Debug)]
    enum Dummy {
        A, B,
    }

    impl super::Mutate for Dummy {
        fn mutate<R: super::rand::Rng>(&self, rng: &mut R) -> Dummy {
            match *self {
                Dummy::A => Dummy::B,
                Dummy::B => Dummy::A
            }
        }
    }

    #[test]
    fn should_mutate_mutate_dummy() {
        let original = Dummy::A;
        let mut rng = super::rand::thread_rng();

        let mutation = original.mutate(&mut rng);

        assert_eq!(mutation, Dummy::B);
    }

    #[test]
    fn should_mutate_expression_without_panicing() {
        let mut rng = super::rand::thread_rng();
        let constant: Expression = Expression::Constant(0.0);
        constant.mutate(&mut rng);

        let sensor: Expression = Expression::Sensor(Box::new(Sensor::Vx));
        sensor.mutate(&mut rng);
    }
}
<commit_msg>Use random generator passed in mutate method<commit_after>/// The `mutate` trait returns a mutation version of a type that implements it.
///
/// Implementer should try to create persisted data-structures

extern crate rand;

use self::rand::Rng;
use self::rand::Rand;
use super::super::structure::{Program,Condition,Expression,Sensor,Command};

pub trait Mutate {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Self;
}

enum MutateType {
    ThisLevel,
    NextLevel,
}

impl rand::Rand for MutateType {
    fn rand<R: rand::Rng>(_: &mut R) -> Self {
        pick![
            1, MutateType::ThisLevel,
            1, MutateType::NextLevel
        ]
    }
}

impl Mutate for Program {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Program {
        let mutate_type: MutateType = MutateType::rand(rng);
        match mutate_type {
            MutateType::ThisLevel => {
                let mutation: Program = Program::rand(rng);
                mutation
            },
            MutateType::NextLevel => {
                match *self {
                    Program::If(ref condition, ref left, ref right) => {
                        match rng.gen_range(0, 3) {
                            0 => { /* mutate condition */
                                      let mutation: Condition = condition.mutate(rng);
                                      Program::If(Box::new(mutation), left.clone(), right.clone())
                            },
                            1 => { /* mutate left */
                                      let mutation: Program = left.mutate(rng);
                                      Program::If(condition.clone(), Box::new(mutation), right.clone())
                            },
                            2 => { /* mutate right */
                                      let mutation: Program = right.mutate(rng);
                                      Program::If(condition.clone(), left.clone(), Box::new(mutation))
                            },
                            _ => { panic!(/* this should not happen */)},
                        }
                    },
                    Program::Command(ref command) => {
                        let mutation: Command = command.mutate(rng);
                        Program::Command(Box::new(mutation))
                    }
                }
            },
        }
    }
}

impl Mutate for Condition {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Condition {
        let mutate_type: MutateType = MutateType::rand(rng);
        match mutate_type {
            MutateType::ThisLevel => {
                let mutation: Condition = Condition::rand(rng);
                mutation
            },
            MutateType::NextLevel => {
                match *self {
                    Condition::True => Condition::False,
                    Condition::False => Condition::True,
                    Condition::Not(ref condition) => {
                        let mutation: Condition = condition.mutate(rng);
                        Condition::Not(Box::new(mutation))
                    },
                    Condition::Or(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Condition = left.mutate(rng);
                            Condition::Or(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Condition = right.mutate(rng);
                            Condition::Or(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::And(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Condition = left.mutate(rng);
                            Condition::And(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Condition = right.mutate(rng);
                            Condition::And(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::Less(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::Less(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::Less(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::LessEqual(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::LessEqual(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::LessEqual(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::Equal(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::Equal(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::Equal(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::GreaterEqual(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::GreaterEqual(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::GreaterEqual(left.clone(), Box::new(mutation))
                        }
                    },
                    Condition::Greater(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);

                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Condition::Greater(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Condition::Greater(left.clone(), Box::new(mutation))
                        }
                    }
                }
            }
        }
    }
}

impl Mutate for Expression {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Expression {
        let mutate_type: MutateType = MutateType::rand(rng);
        match mutate_type {
            MutateType::ThisLevel => {
                let mutation: Expression = Expression::rand(rng);
                mutation
            },
            MutateType::NextLevel => {
                match *self {
                    Expression::Constant(_) => {
                        let mutation: f32 = f32::rand(rng);
                        Expression::Constant(mutation)
                    },
                    Expression::Sensor(ref sensor) => {
                        let mutation: Sensor = sensor.mutate(rng);
                        Expression::Sensor(Box::new(mutation))
                    },
                    Expression::Plus(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Plus(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Plus(left.clone(),Box::new(mutation))
                        }
                    },
                    Expression::Minus(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Minus(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Minus(left.clone(), Box::new(mutation))
                        }
                    },
                    Expression::Multiply(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Multiply(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Multiply(left.clone(), Box::new(mutation))
                        }
                    },
                    Expression::Divide(ref left, ref right) => {
                        let mutate_left: bool = bool::rand(rng);
                        if mutate_left {
                            let mutation: Expression = left.mutate(rng);
                            Expression::Divide(Box::new(mutation), right.clone())
                        } else {
                            let mutation: Expression = right.mutate(rng);
                            Expression::Divide(left.clone(), Box::new(mutation))
                        }
                    },
                }
            }
        }
    }
}

impl Mutate for Sensor {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Sensor {
        let mutation: Sensor = Sensor::rand(rng);
        mutation
    }
}

impl Mutate for Command {
    fn mutate<R: rand::Rng>(&self, rng: &mut R) -> Command {
        let mutation: Command = Command::rand(rng);
        mutation
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use structure::{Expression,Sensor};

    #[derive(PartialEq,Debug)]
    enum Dummy {
        A, B,
    }

    impl super::Mutate for Dummy {
        fn mutate<R: super::rand::Rng>(&self, _: &mut R) -> Dummy {
            match *self {
                Dummy::A => Dummy::B,
                Dummy::B => Dummy::A
            }
        }
    }

    #[test]
    fn should_mutate_mutate_dummy() {
        let original = Dummy::A;
        let mut rng = super::rand::thread_rng();

        let mutation = original.mutate(&mut rng);

        assert_eq!(mutation, Dummy::B);
    }

    #[test]
    fn should_mutate_expression_without_panicing() {
        let mut rng = super::rand::thread_rng();
        let constant: Expression = Expression::Constant(0.0);
        constant.mutate(&mut rng);

        let sensor: Expression = Expression::Sensor(Box::new(Sensor::Vx));
        sensor.mutate(&mut rng);
    }
}
<|endoftext|>


<commit_before>use db::row::Row;
// mis info about what's on each page.
const HEADER_SIZE_IN_BYTES : usize = 64;
pub const PAGE_SIZE : usize = 4096;

pub struct Page {
    header: Header,
    data: [u8; PAGE_SIZE - HEADER_SIZE_IN_BYTES],
    bytes_used: usize, // tracking where we are in the current page

                                      // if we go past the page boundary on a write we fault
}

#[derive(Debug)]
enum PageError {
    Full
}

type PageResult<T> = Result<T, PageError>;

struct Header;

// page deals with bytes, and has zero knowledge of a Row
// storage engine needs to serialize
impl Page {
    pub fn new() -> Page {
        Page{header: Header::new(),
             data: [0; 4096 - HEADER_SIZE_IN_BYTES],
             bytes_used: HEADER_SIZE_IN_BYTES,
             }
    }

    // attempt to write to a page
    // can fail if the page is already full
    // if it fails, the storage engine will have to flush this page
    // then allocate a new page
    fn write(&mut self, bytes: &[u8]) -> PageResult<()> {
        Err(PageError::Full)
    }

    fn space_available(self) -> usize {
        PAGE_SIZE - self.bytes_used
    }

}

impl Header {
    fn new() -> Header {
        Header{}
    }
}

#[cfg(test)]
mod tests {
    use super::{Page, HEADER_SIZE_IN_BYTES};
    #[test]
    fn test_page_insert_ok() {
        let mut p = Page::new();
        let data: [u8; 16] = [0; 16];
        p.write(&data).expect("Data written");
        assert_eq!(p.bytes_used, HEADER_SIZE_IN_BYTES + 16);
    }

    #[test]
    fn test_page_fault() {

    }
}

<commit_msg>fixing space available and bytes used<commit_after>use db::row::Row;
// mis info about what's on each page.
const HEADER_SIZE_IN_BYTES : usize = 64;
pub const PAGE_SIZE : usize = 4096;

pub struct Page {
    header: Header,
    data: [u8; PAGE_SIZE - HEADER_SIZE_IN_BYTES],
    bytes_used: usize, // tracking where we are in the current page

                                      // if we go past the page boundary on a write we fault
}

#[derive(Debug)]
enum PageError {
    Full
}

type PageResult<T> = Result<T, PageError>;

struct Header;

// page deals with bytes, and has zero knowledge of a Row
// storage engine needs to serialize
impl Page {
    pub fn new() -> Page {
        Page{header: Header::new(),
             data: [0; 4096 - HEADER_SIZE_IN_BYTES],
             bytes_used: 0,
             }
    }

    // attempt to write to a page
    // can fail if the page is already full
    // if it fails, the storage engine will have to flush this page
    // then allocate a new page
    fn write(&mut self, bytes: &[u8]) -> PageResult<()> {
        if bytes.len() > self.space_available() {
            return Err(PageError::Full)
        }

        Err(PageError::Full)
    }

    fn space_available(&self) -> usize {
        PAGE_SIZE - HEADER_SIZE_IN_BYTES - self.bytes_used
    }

}

impl Header {
    fn new() -> Header {
        Header{}
    }
}

#[cfg(test)]
mod tests {
    use super::{Page, HEADER_SIZE_IN_BYTES, PAGE_SIZE};
    #[test]
    fn test_page_insert_ok() {
        let mut p = Page::new();
        assert_eq!(p.space_available(), PAGE_SIZE - HEADER_SIZE_IN_BYTES);
        let data: [u8; 16] = [0; 16];
        p.write(&data).expect("Data written");
        assert_eq!(p.bytes_used, HEADER_SIZE_IN_BYTES + 16);
    }

    #[test]
    fn test_page_fault() {

    }
}

<|endoftext|>