<commit_before>// Implements http://rosettacode.org/wiki/Closest-pair_problem

// We interpret complex numbers as points in the Cartesian plane, here.
// We also use the sweepline/plane sweep closest pairs algorithm
// (http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairPS.html) instead
// of the divide-and-conquer algorithm, since it's (arguably)
// easier to implement, and an efficient implementation does not require
// use of unsafe.

extern crate num;

use std::collections::TreeSet;
use std::cmp::{PartialOrd, Ordering};
use num::complex::Complex;

type Point = Complex<f32>;

// Wrapper around Point (i.e. Complex<f32>) so that we can use a TreeSet
#[deriving(PartialEq)]
struct YSortedPoint {
    point: Point
}

impl PartialOrd for YSortedPoint {
    fn partial_cmp(&self, other: &YSortedPoint) -> Option<Ordering> {
        (self.point.im, self.point.re).partial_cmp(&(other.point.im, other.point.re))
    }
}

impl Ord for YSortedPoint {
    fn cmp(&self, other: &YSortedPoint) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl Eq for YSortedPoint {}

fn closest_pair(points: &mut [Point]) -> Option<(Point, Point)> {
    if points.len() < 2 {
        return None
    }

    points.sort_by(|a, b| (a.re, a.im).partial_cmp(&(b.re, b.im)).unwrap());

    let mut closest_pair = (points[0], points[1]);
    let mut closest_distance_sqr = (points[0] - points[1]).norm_sqr();
    let mut closest_distance = closest_distance_sqr.sqrt();

    // the strip that we inspect for closest pairs as we sweep right
    let mut strip: TreeSet<YSortedPoint> = TreeSet::new();
    strip.insert(YSortedPoint { point: points[0].clone() });
    strip.insert(YSortedPoint { point: points[1].clone() });

    // index of the leftmost point on the strip (on points)
    let mut leftmost_idx = 0;

    // Start the sweep!
    for (idx, point) in points.iter().enumerate().skip(2) {
        // Remove all points farther than `closest_distance` away from `point`
        // along the x-axis
        while leftmost_idx < idx {
            let leftmost_point = &points[leftmost_idx];
            if (leftmost_point.re - point.re).powi(2) < closest_distance_sqr {
                break;
            }
            strip.remove(&YSortedPoint { point: leftmost_point.clone() });
            leftmost_idx += 1;
        }

        // Compare to points in bounding box
        {
            let mut strip_iter = strip.upper_bound(&YSortedPoint {
                point: Point { re: std::num::Float::infinity(), im: point.im - closest_distance }
            });
            loop {
                let point2 = match strip_iter.next() {
                    None => break,
                    Some(p) => p.point
                };
                if point2.im - point.im >= closest_distance {
                    // we've reached the end of the box
                    break;
                }
                let dist_sqr = (point - point2).norm_sqr();
                if dist_sqr < closest_distance_sqr {
                    closest_pair = (point2, *point);
                    closest_distance_sqr = dist_sqr;
                    closest_distance = dist_sqr.sqrt();
                }
            }
        }

        // Insert point into strip
        strip.insert(YSortedPoint { point: point.clone() });
    }

    Some(closest_pair)
}

#[cfg(not(test))]
pub fn main() {
    let mut test_data = [
        Complex::new(0.654682, 0.925557),
        Complex::new(0.409382, 0.619391),
        Complex::new(0.891663, 0.888594),
        Complex::new(0.716629, 0.996200),
        Complex::new(0.477721, 0.946355),
        Complex::new(0.925092, 0.818220),
        Complex::new(0.624291, 0.142924),
        Complex::new(0.211332, 0.221507),
        Complex::new(0.293786, 0.691701),
        Complex::new(0.839186, 0.728260)
    ];
    let (p1, p2) = closest_pair(test_data.as_mut_slice()).unwrap();
    println!("Closest pair: {} and {}", p1, p2);
    println!("Distance: {}", (p1 - p2).norm_sqr().sqrt());
}

#[cfg(test)]
mod test {
    use super::{Point, closest_pair};
    use num::complex::Complex;

    #[test]
    fn random_floats() {
        let mut test_data = [
            Complex::new(0.654682, 0.925557),
            Complex::new(0.409382, 0.619391),
            Complex::new(0.891663, 0.888594),
            Complex::new(0.716629, 0.996200),
            Complex::new(0.477721, 0.946355),
            Complex::new(0.925092, 0.818220),
            Complex::new(0.624291, 0.142924),
            Complex::new(0.211332, 0.221507),
            Complex::new(0.293786, 0.691701),
            Complex::new(0.839186, 0.728260)
        ];
        let (p1, p2) = closest_pair(test_data.as_mut_slice()).unwrap();
        assert!((p1.re - 0.891663).abs() < 1e-6f32);
        assert!((p1.im - 0.888594).abs() < 1e-6f32);
        assert!((p2.re - 0.925092).abs() < 1e-6f32);
        assert!((p2.im - 0.818220).abs() < 1e-6f32);
        assert!(((p1 - p2).norm_sqr() - 0.0779102f32.powi(2)).abs() < 1e-6f32);
    }
}
<commit_msg>Remove unused import in closest-pair.rs.<commit_after>// Implements http://rosettacode.org/wiki/Closest-pair_problem

// We interpret complex numbers as points in the Cartesian plane, here.
// We also use the sweepline/plane sweep closest pairs algorithm
// (http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairPS.html) instead
// of the divide-and-conquer algorithm, since it's (arguably)
// easier to implement, and an efficient implementation does not require
// use of unsafe.

extern crate num;

use std::collections::TreeSet;
use std::cmp::{PartialOrd, Ordering};
use num::complex::Complex;

type Point = Complex<f32>;

// Wrapper around Point (i.e. Complex<f32>) so that we can use a TreeSet
#[deriving(PartialEq)]
struct YSortedPoint {
    point: Point
}

impl PartialOrd for YSortedPoint {
    fn partial_cmp(&self, other: &YSortedPoint) -> Option<Ordering> {
        (self.point.im, self.point.re).partial_cmp(&(other.point.im, other.point.re))
    }
}

impl Ord for YSortedPoint {
    fn cmp(&self, other: &YSortedPoint) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl Eq for YSortedPoint {}

fn closest_pair(points: &mut [Point]) -> Option<(Point, Point)> {
    if points.len() < 2 {
        return None
    }

    points.sort_by(|a, b| (a.re, a.im).partial_cmp(&(b.re, b.im)).unwrap());

    let mut closest_pair = (points[0], points[1]);
    let mut closest_distance_sqr = (points[0] - points[1]).norm_sqr();
    let mut closest_distance = closest_distance_sqr.sqrt();

    // the strip that we inspect for closest pairs as we sweep right
    let mut strip: TreeSet<YSortedPoint> = TreeSet::new();
    strip.insert(YSortedPoint { point: points[0].clone() });
    strip.insert(YSortedPoint { point: points[1].clone() });

    // index of the leftmost point on the strip (on points)
    let mut leftmost_idx = 0;

    // Start the sweep!
    for (idx, point) in points.iter().enumerate().skip(2) {
        // Remove all points farther than `closest_distance` away from `point`
        // along the x-axis
        while leftmost_idx < idx {
            let leftmost_point = &points[leftmost_idx];
            if (leftmost_point.re - point.re).powi(2) < closest_distance_sqr {
                break;
            }
            strip.remove(&YSortedPoint { point: leftmost_point.clone() });
            leftmost_idx += 1;
        }

        // Compare to points in bounding box
        {
            let mut strip_iter = strip.upper_bound(&YSortedPoint {
                point: Point { re: std::num::Float::infinity(), im: point.im - closest_distance }
            });
            loop {
                let point2 = match strip_iter.next() {
                    None => break,
                    Some(p) => p.point
                };
                if point2.im - point.im >= closest_distance {
                    // we've reached the end of the box
                    break;
                }
                let dist_sqr = (point - point2).norm_sqr();
                if dist_sqr < closest_distance_sqr {
                    closest_pair = (point2, *point);
                    closest_distance_sqr = dist_sqr;
                    closest_distance = dist_sqr.sqrt();
                }
            }
        }

        // Insert point into strip
        strip.insert(YSortedPoint { point: point.clone() });
    }

    Some(closest_pair)
}

#[cfg(not(test))]
pub fn main() {
    let mut test_data = [
        Complex::new(0.654682, 0.925557),
        Complex::new(0.409382, 0.619391),
        Complex::new(0.891663, 0.888594),
        Complex::new(0.716629, 0.996200),
        Complex::new(0.477721, 0.946355),
        Complex::new(0.925092, 0.818220),
        Complex::new(0.624291, 0.142924),
        Complex::new(0.211332, 0.221507),
        Complex::new(0.293786, 0.691701),
        Complex::new(0.839186, 0.728260)
    ];
    let (p1, p2) = closest_pair(test_data.as_mut_slice()).unwrap();
    println!("Closest pair: {} and {}", p1, p2);
    println!("Distance: {}", (p1 - p2).norm_sqr().sqrt());
}

#[cfg(test)]
mod test {
    use super::closest_pair;
    use num::complex::Complex;

    #[test]
    fn random_floats() {
        let mut test_data = [
            Complex::new(0.654682, 0.925557),
            Complex::new(0.409382, 0.619391),
            Complex::new(0.891663, 0.888594),
            Complex::new(0.716629, 0.996200),
            Complex::new(0.477721, 0.946355),
            Complex::new(0.925092, 0.818220),
            Complex::new(0.624291, 0.142924),
            Complex::new(0.211332, 0.221507),
            Complex::new(0.293786, 0.691701),
            Complex::new(0.839186, 0.728260)
        ];
        let (p1, p2) = closest_pair(test_data.as_mut_slice()).unwrap();
        assert!((p1.re - 0.891663).abs() < 1e-6f32);
        assert!((p1.im - 0.888594).abs() < 1e-6f32);
        assert!((p2.re - 0.925092).abs() < 1e-6f32);
        assert!((p2.im - 0.818220).abs() < 1e-6f32);
        assert!(((p1 - p2).norm_sqr() - 0.0779102f32.powi(2)).abs() < 1e-6f32);
    }
}
<|endoftext|>


<commit_before>use codegen::buffer::*;
use codegen::emit;
use codegen::x64::emit::*;
use codegen::x64::reg::*;
use codegen::x64::reg::Reg::*;

use parser::ast::ctxt::*;
use parser::ast::*;
use parser::ast::Expr::*;

use sym::BuiltinType;

pub enum ExprLoc {
    LocConst(i32),
    LocReg(Reg),
    LocStack(i32),
}

pub struct ExprGen<'a, 'ast: 'a> {
    ctxt: &'a Context<'a, 'ast>,
    fct: &'ast Function,
    buf: &'a mut Buffer,
}

impl<'a, 'ast> ExprGen<'a, 'ast> where 'ast: 'a {
    pub fn new(
        ctxt: &'a Context<'a, 'ast>,
        fct: &'ast Function,
        buf: &'a mut Buffer
    ) -> ExprGen<'a, 'ast> {
        ExprGen {
            ctxt: ctxt,
            fct: fct,
            buf: buf,
        }
    }

    pub fn generate(&mut self, e: &'ast Expr) -> Reg {
        match *e {
            ExprLitInt(ref expr) => self.emit_lit_int(expr),
            ExprLitBool(ref expr) => self.emit_lit_bool(expr),
            ExprUn(ref expr) => self.emit_un(expr),
            ExprIdent(ref expr) => self.emit_ident(expr),
            _ => unreachable!(),
        }

        REG_RESULT
    }

    fn emit_lit_int(&mut self, lit: &'ast ExprLitIntType) {
        emit_movl_imm_reg(self.buf, lit.value as u32, REG_RESULT);
    }

    fn emit_lit_bool(&mut self, lit: &'ast ExprLitBoolType) {
        let value : u32 = if lit.value { 1 } else { 0 };
        emit_movl_imm_reg(self.buf, value, REG_RESULT);
    }

    fn emit_ident(&mut self, e: &'ast ExprIdentType) {
        let defs = self.ctxt.defs.borrow();
        let varid = *defs.get(&e.id).unwrap();

        emit::var_load(self.buf, self.ctxt, varid, REG_RESULT);
    }

    fn emit_un(&mut self, e: &'ast ExprUnType) {
        self.generate(&e.opnd);

        match e.op {
            UnOp::Plus => {},
            UnOp::Neg => emit_negl_reg(self.buf, REG_RESULT),
            UnOp::BitNot => emit_notl_reg(self.buf, REG_RESULT),
            UnOp::Not => {
                emit_xorb_imm_reg(self.buf, 1, REG_RESULT);
                emit_andb_imm_reg(self.buf, 1, REG_RESULT);
            },
        }
    }
}
<commit_msg>codegen: get dest register as parameter<commit_after>use codegen::buffer::*;
use codegen::emit;
use codegen::x64::emit::*;
use codegen::x64::reg::*;
use codegen::x64::reg::Reg::*;

use parser::ast::ctxt::*;
use parser::ast::*;
use parser::ast::Expr::*;

use sym::BuiltinType;

pub enum ExprLoc {
    LocConst(i32),
    LocReg(Reg),
    LocStack(i32),
}

pub struct ExprGen<'a, 'ast: 'a> {
    ctxt: &'a Context<'a, 'ast>,
    fct: &'ast Function,
    buf: &'a mut Buffer,
}

impl<'a, 'ast> ExprGen<'a, 'ast> where 'ast: 'a {
    pub fn new(
        ctxt: &'a Context<'a, 'ast>,
        fct: &'ast Function,
        buf: &'a mut Buffer
    ) -> ExprGen<'a, 'ast> {
        ExprGen {
            ctxt: ctxt,
            fct: fct,
            buf: buf,
        }
    }

    pub fn generate(&mut self, e: &'ast Expr) -> Reg {
        let dest = REG_RESULT;

        match *e {
            ExprLitInt(ref expr) => self.emit_lit_int(expr, dest),
            ExprLitBool(ref expr) => self.emit_lit_bool(expr, dest),
            ExprUn(ref expr) => self.emit_un(expr, dest),
            ExprIdent(ref expr) => self.emit_ident(expr, dest),
            _ => unreachable!(),
        }

        dest
    }

    fn emit_lit_int(&mut self, lit: &'ast ExprLitIntType, dest: Reg) {
        emit_movl_imm_reg(self.buf, lit.value as u32, dest);
    }

    fn emit_lit_bool(&mut self, lit: &'ast ExprLitBoolType, dest: Reg) {
        let value : u32 = if lit.value { 1 } else { 0 };
        emit_movl_imm_reg(self.buf, value, dest);
    }

    fn emit_ident(&mut self, e: &'ast ExprIdentType, dest: Reg) {
        let defs = self.ctxt.defs.borrow();
        let varid = *defs.get(&e.id).unwrap();

        emit::var_load(self.buf, self.ctxt, varid, dest);
    }

    fn emit_un(&mut self, e: &'ast ExprUnType, dest: Reg) {
        self.generate(&e.opnd);

        match e.op {
            UnOp::Plus => {},
            UnOp::Neg => emit_negl_reg(self.buf, dest),
            UnOp::BitNot => emit_notl_reg(self.buf, dest),
            UnOp::Not => {
                emit_xorb_imm_reg(self.buf, 1, dest);
                emit_andb_imm_reg(self.buf, 1, dest);
            },
        }
    }
}
<|endoftext|>


<commit_before>use command::{Command, Query};

#[derive(Clone, Debug)]
pub struct CommandLine {
    command: Command,
    arguments: Query,
}

impl CommandLine {
    pub fn new(command: Command, query: Query) -> CommandLine {
        CommandLine {
            command: command,
            arguments: query,
        }
    }

    /// Get command enum constant to construct url encoded query.
    pub fn get_command(&mut self) -> Command {
        self.command.clone()
    }

    /// Get vectorize `("key", "value")` pairs to construct url encoded query.
    pub fn get_argument(&mut self) -> Query {
        self.arguments.clone()
    }

    /// Set vectorize `("key", "value")` pairs to construct url encoded query.
    pub fn set_argument(&mut self, arguments: Query) {
        self.arguments = arguments
    }

    /// Create command line style command query.
    ///
    /// `vec![("key","value")]` interprets to `"--key value"`.
    /// And two or more value pair are concatinate with ` `(a space).
    pub fn make_command(&mut self) -> String {
        let mut output = String::new();
        for query in self.arguments.clone() {
            let (key, value) = query;
            if output.len() > 0 {
                output.push_str(" ");
            }
            let format_string = format!("--{} {}", &*key, &*value);
            output.push_str(format_string.as_str());
        }
        output
    }

    ///
    /// Create Groonga command line style command.
    pub fn encode(&mut self) -> String {
        format!("{} {}", self.get_command(), self.make_command())
            .trim()
            .to_owned()
    }
}

#[cfg(test)]
mod test {
    use super::CommandLine;
    use select::SelectCommand;
    use load::{LoadCommand, InputType};
    use status::StatusCommand;
    use dump::DumpCommand;
    use delete::DeleteCommand;
    use table_create::TableCreateCommand;
    use types::table_flag_type::TableFlagType;
    use column_create::ColumnCreateCommand;
    use types::data_type::DataType;

    #[test]
    fn test_select() {
        let (command, query) = SelectCommand::new("Test".to_string())
                                   .filter("output_column @ \"type_safe\"".to_string())
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "select --table Test --filter \'output_column @ \"type_safe\"\'";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_load() {
        let load_data: &'static str = r#"[
{"_key":"http://example.org/","title":"This is test record 1!"},
]"#;
        let (command, query, values) = LoadCommand::new("Test".to_string(), load_data.to_string())
                                           .input_type(InputType::Json)
                                           .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "load --table Test --input_type json";
        assert_eq!(cli_encoded.to_string(), command.encode());
        assert_eq!(load_data.to_string(), values);
    }

    #[test]
    fn test_status() {
        let (command, query) = StatusCommand::new().build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "status";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_dump() {
        let (command, query) = DumpCommand::new()
                                   .tables(vec!["Books".to_string(), "Categories".to_string()])
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "dump --tables Books,Categories";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_delete() {
        let (command, query) = DeleteCommand::new("Books".to_string())
                                   .filter("author == unknown".to_string())
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "delete --table Books --filter \'author == unknown\'";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_table_create() {
        let (command, query) = TableCreateCommand::new("Test".to_string())
                                   .flags(vec![(TableFlagType::PatKey),
                                               (TableFlagType::KeyWithSIS)])
                                   .build();
        let mut command = CommandLine::new(command, query);
        let url_encoded = "table_create --name Test --flags TABLE_PAT_KEY|KEY_WITH_SIS";
        assert_eq!(url_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_column_create() {
        let (command, query) = ColumnCreateCommand::new("Test".to_string(), "element".to_string())
                                   .column_type(DataType::LongText)
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "column_create --table Test --name element --type LongText";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }
}
<commit_msg>command_line: Fix rustdoc<commit_after>use command::{Command, Query};

#[derive(Clone, Debug)]
pub struct CommandLine {
    command: Command,
    arguments: Query,
}

impl CommandLine {
    pub fn new(command: Command, query: Query) -> CommandLine {
        CommandLine {
            command: command,
            arguments: query,
        }
    }

    /// Get command enum constant to construct command line query.
    pub fn get_command(&mut self) -> Command {
        self.command.clone()
    }

    /// Get vectorize `("key", "value")` pairs to construct command line query.
    pub fn get_argument(&mut self) -> Query {
        self.arguments.clone()
    }

    /// Set vectorize `("key", "value")` pairs to construct command line query.
    pub fn set_argument(&mut self, arguments: Query) {
        self.arguments = arguments
    }

    /// Create command line style command query.
    ///
    /// `vec![("key","value")]` interprets to `"--key value"`.
    /// And two or more value pair are concatinate with ` `(a space).
    pub fn make_command(&mut self) -> String {
        let mut output = String::new();
        for query in self.arguments.clone() {
            let (key, value) = query;
            if output.len() > 0 {
                output.push_str(" ");
            }
            let format_string = format!("--{} {}", &*key, &*value);
            output.push_str(format_string.as_str());
        }
        output
    }

    ///
    /// Create Groonga command line style command.
    pub fn encode(&mut self) -> String {
        format!("{} {}", self.get_command(), self.make_command())
            .trim()
            .to_owned()
    }
}

#[cfg(test)]
mod test {
    use super::CommandLine;
    use select::SelectCommand;
    use load::{LoadCommand, InputType};
    use status::StatusCommand;
    use dump::DumpCommand;
    use delete::DeleteCommand;
    use table_create::TableCreateCommand;
    use types::table_flag_type::TableFlagType;
    use column_create::ColumnCreateCommand;
    use types::data_type::DataType;

    #[test]
    fn test_select() {
        let (command, query) = SelectCommand::new("Test".to_string())
                                   .filter("output_column @ \"type_safe\"".to_string())
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "select --table Test --filter \'output_column @ \"type_safe\"\'";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_load() {
        let load_data: &'static str = r#"[
{"_key":"http://example.org/","title":"This is test record 1!"},
]"#;
        let (command, query, values) = LoadCommand::new("Test".to_string(), load_data.to_string())
                                           .input_type(InputType::Json)
                                           .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "load --table Test --input_type json";
        assert_eq!(cli_encoded.to_string(), command.encode());
        assert_eq!(load_data.to_string(), values);
    }

    #[test]
    fn test_status() {
        let (command, query) = StatusCommand::new().build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "status";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_dump() {
        let (command, query) = DumpCommand::new()
                                   .tables(vec!["Books".to_string(), "Categories".to_string()])
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "dump --tables Books,Categories";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_delete() {
        let (command, query) = DeleteCommand::new("Books".to_string())
                                   .filter("author == unknown".to_string())
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "delete --table Books --filter \'author == unknown\'";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_table_create() {
        let (command, query) = TableCreateCommand::new("Test".to_string())
                                   .flags(vec![(TableFlagType::PatKey),
                                               (TableFlagType::KeyWithSIS)])
                                   .build();
        let mut command = CommandLine::new(command, query);
        let url_encoded = "table_create --name Test --flags TABLE_PAT_KEY|KEY_WITH_SIS";
        assert_eq!(url_encoded.to_string(), command.encode());
    }

    #[test]
    fn test_column_create() {
        let (command, query) = ColumnCreateCommand::new("Test".to_string(), "element".to_string())
                                   .column_type(DataType::LongText)
                                   .build();
        let mut command = CommandLine::new(command, query);
        let cli_encoded = "column_create --table Test --name element --type LongText";
        assert_eq!(cli_encoded.to_string(), command.encode());
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate custom_derive;
#[macro_use] extern crate derive_builder;

custom_derive!{
    /// This is a doc comment for the struct
    #[warn(missing_docs)]
    #[allow(non_snake_case)]
    #[derive(Debug, PartialEq, Default, Builder)]
    struct Lorem {
        /// This is a doc comment for a field
        field_with_doc_comment: String,
        #[allow(missing_docs)]
        undocumented: String,
        #[allow(non_snake_case)]
        CamelCase: i32,
        #[cfg(target_os = "macos")] // TODO: this fails on linux builds
        mac_only: (),
        #[cfg(target_os = "linux")] // TODO: this fails on mac builds
        linux_only: (),
    }
}

#[test]
fn annotations() {
    // this is currently just a compile-test (may switch to token comparisons here)
    // https://github.com/colin-kiegel/rust-derive-builder/issues/19
}
<commit_msg>fix failing tests on stable<commit_after>#[macro_use] extern crate custom_derive;
#[macro_use] extern crate derive_builder;

custom_derive!{
    /// This is a doc comment for the struct
    #[warn(missing_docs)]
    #[allow(non_snake_case, dead_code)]
    #[derive(Builder)]
    struct Lorem {
        /// This is a doc comment for a field
        field_with_doc_comment: String,
        #[allow(missing_docs)]
        undocumented: String,
        #[allow(non_snake_case)]
        CamelCase: i32,
        #[cfg(target_os = "macos")] // TODO: this fails on linux builds
        mac_only: (),
        #[cfg(target_os = "linux")] // TODO: this fails on mac builds
        linux_only: (),
    }
}

#[test]
fn annotations() {
    // this is currently just a compile-test (may switch to token comparisons here)
    // https://github.com/colin-kiegel/rust-derive-builder/issues/19
}
<|endoftext|>


<commit_before>// Copyright © 2018 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use client::render::Palette;
use client::render::bsp::BspRenderer;
use common::bsp::BspModel;
use common::mdl;
use common::mdl::AliasModel;
use common::pak::Pak;
use common::sprite;
use common::sprite::SpriteModel;

use cgmath::Vector3;
use gfx;

#[derive(Debug, FromPrimitive)]
pub enum SyncType {
    Sync = 0,
    Rand = 1,
}

#[derive(Debug)]
pub struct Model {
    pub name: String,
    pub kind: ModelKind,
}

#[derive(Debug)]
pub enum ModelKind {
    // TODO: find a more elegant way to express the null model
    None,
    Brush(BspModel),
    Alias(AliasModel),
    Sprite(SpriteModel),
}

impl Model {
    pub fn none() -> Model {
        Model {
            name: String::new(),
            kind: ModelKind::None,
        }
    }

    pub fn kind(&self) -> &ModelKind {
        &self.kind
    }

    pub fn load<S>(pak: &Pak, name: S) -> Model
    where
        S: AsRef<str>,
    {
        let name = name.as_ref();
        // TODO: original engine uses the magic numbers of each format instead of the extension.
        if name.ends_with(".bsp") {
            panic!("BSP files may contain multiple models, use bsp::load for this");
        } else if name.ends_with(".mdl") {
            match pak.open(name) {
                Some(m) => Model::from_alias_model(name.to_owned(), mdl::load(m).unwrap()),
                None => panic!("No such file: {}", name),
            }
        } else if name.ends_with(".spr") {
            match pak.open(name) {
                Some(m) => Model::from_sprite_model(name.to_owned(), sprite::load(m)),
                None => panic!("No such file: {}", name),
            }
        } else {
            panic!("Unrecognized model type: {}", name);
        }
    }

    /// Construct a new generic model from a brush model.
    pub fn from_brush_model<S>(name: S, brush_model: BspModel) -> Model
    where
        S: AsRef<str>,
    {
        Model {
            name: name.as_ref().to_owned(),
            kind: ModelKind::Brush(brush_model),
        }
    }

    /// Construct a new generic model from an alias model.
    pub fn from_alias_model<S>(name: S, alias_model: AliasModel) -> Model
    where
        S: AsRef<str>,
    {
        Model {
            name: name.as_ref().to_owned(),
            kind: ModelKind::Alias(alias_model),
        }
    }

    /// Construct a new generic model from a sprite model.
    pub fn from_sprite_model<S>(name: S, sprite_model: SpriteModel) -> Model
    where
        S: AsRef<str>,
    {
        Model {
            name: name.as_ref().to_owned(),
            kind: ModelKind::Sprite(sprite_model),
        }
    }

    /// Return the name of this model.
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Return the minimum extent of this model.
    pub fn min(&self) -> Vector3<f32> {
        debug!("Retrieving min of model {}", self.name);
        match self.kind {
            ModelKind::None => panic!("attempted to take min() of NULL model"),
            ModelKind::Brush(ref bmodel) => bmodel.min(),
            ModelKind::Sprite(ref smodel) => smodel.min(),

            // TODO: maybe change this?
            // https://github.com/id-Software/Quake/blob/master/WinQuake/gl_model.c#L1625
            ModelKind::Alias(_) => Vector3::new(-16.0, -16.0, -16.0),
        }
    }

    /// Return the maximum extent of this model.
    pub fn max(&self) -> Vector3<f32> {
        debug!("Retrieving max of model {}", self.name);
        match self.kind {
            ModelKind::None => panic!("attempted to take max() of NULL model"),
            ModelKind::Brush(ref bmodel) => bmodel.max(),
            ModelKind::Sprite(ref smodel) => smodel.max(),

            // TODO: maybe change this?
            // https://github.com/id-Software/Quake/blob/master/WinQuake/gl_model.c#L1625
            ModelKind::Alias(_) => Vector3::new(16.0, 16.0, 16.0),
        }
    }

    pub fn sync_type(&self) -> SyncType {
        match self.kind {
            ModelKind::None => panic!("Attempted to take sync_type() of NULL model"),
            ModelKind::Brush(_) => SyncType::Sync,
            // TODO: expose sync_type in Sprite and reflect it here
            ModelKind::Sprite(ref smodel) => SyncType::Sync,
            // TODO: expose sync_type in Mdl and reflect it here
            ModelKind::Alias(ref amodel) => SyncType::Sync,
        }
    }
}
<commit_msg>Add ModelFlags type<commit_after>// Copyright © 2018 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use client::render::Palette;
use client::render::bsp::BspRenderer;
use common::bsp::BspModel;
use common::mdl;
use common::mdl::AliasModel;
use common::pak::Pak;
use common::sprite;
use common::sprite::SpriteModel;

use cgmath::Vector3;
use gfx;

#[derive(Debug, FromPrimitive)]
pub enum SyncType {
    Sync = 0,
    Rand = 1,
}

bitflags! {
    pub struct ModelFlags: u8 {
        const ROCKET  = 0b00000001;
        const GRENADE = 0b00000010;
        const GIB     = 0b00000100;
        const ROTATE  = 0b00001000;
        const TRACER  = 0b00010000;
        const ZOMGIB  = 0b00100000;
        const TRACER2 = 0b01000000;
        const TRACER3 = 0b10000000;
    }
}

#[derive(Debug)]
pub struct Model {
    pub name: String,
    pub kind: ModelKind,
    pub flags: ModelFlags,
}

#[derive(Debug)]
pub enum ModelKind {
    // TODO: find a more elegant way to express the null model
    None,
    Brush(BspModel),
    Alias(AliasModel),
    Sprite(SpriteModel),
}

impl Model {
    pub fn none() -> Model {
        Model {
            name: String::new(),
            kind: ModelKind::None,
            flags: ModelFlags::empty(),
        }
    }

    pub fn kind(&self) -> &ModelKind {
        &self.kind
    }

    pub fn load<S>(pak: &Pak, name: S) -> Model
    where
        S: AsRef<str>,
    {
        let name = name.as_ref();
        // TODO: original engine uses the magic numbers of each format instead of the extension.
        if name.ends_with(".bsp") {
            panic!("BSP files may contain multiple models, use bsp::load for this");
        } else if name.ends_with(".mdl") {
            match pak.open(name) {
                Some(m) => Model::from_alias_model(name.to_owned(), mdl::load(m).unwrap()),
                None => panic!("No such file: {}", name),
            }
        } else if name.ends_with(".spr") {
            match pak.open(name) {
                Some(m) => Model::from_sprite_model(name.to_owned(), sprite::load(m)),
                None => panic!("No such file: {}", name),
            }
        } else {
            panic!("Unrecognized model type: {}", name);
        }
    }

    /// Construct a new generic model from a brush model.
    pub fn from_brush_model<S>(name: S, brush_model: BspModel) -> Model
    where
        S: AsRef<str>,
    {
        Model {
            name: name.as_ref().to_owned(),
            kind: ModelKind::Brush(brush_model),
            flags: ModelFlags::empty(),
        }
    }

    /// Construct a new generic model from an alias model.
    pub fn from_alias_model<S>(name: S, alias_model: AliasModel) -> Model
    where
        S: AsRef<str>,
    {
        Model {
            name: name.as_ref().to_owned(),
            kind: ModelKind::Alias(alias_model),
            flags: ModelFlags::empty(),
        }
    }

    /// Construct a new generic model from a sprite model.
    pub fn from_sprite_model<S>(name: S, sprite_model: SpriteModel) -> Model
    where
        S: AsRef<str>,
    {
        Model {
            name: name.as_ref().to_owned(),
            kind: ModelKind::Sprite(sprite_model),
            flags: ModelFlags::empty(),
        }
    }

    /// Return the name of this model.
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Return the minimum extent of this model.
    pub fn min(&self) -> Vector3<f32> {
        debug!("Retrieving min of model {}", self.name);
        match self.kind {
            ModelKind::None => panic!("attempted to take min() of NULL model"),
            ModelKind::Brush(ref bmodel) => bmodel.min(),
            ModelKind::Sprite(ref smodel) => smodel.min(),

            // TODO: maybe change this?
            // https://github.com/id-Software/Quake/blob/master/WinQuake/gl_model.c#L1625
            ModelKind::Alias(_) => Vector3::new(-16.0, -16.0, -16.0),
        }
    }

    /// Return the maximum extent of this model.
    pub fn max(&self) -> Vector3<f32> {
        debug!("Retrieving max of model {}", self.name);
        match self.kind {
            ModelKind::None => panic!("attempted to take max() of NULL model"),
            ModelKind::Brush(ref bmodel) => bmodel.max(),
            ModelKind::Sprite(ref smodel) => smodel.max(),

            // TODO: maybe change this?
            // https://github.com/id-Software/Quake/blob/master/WinQuake/gl_model.c#L1625
            ModelKind::Alias(_) => Vector3::new(16.0, 16.0, 16.0),
        }
    }

    pub fn sync_type(&self) -> SyncType {
        match self.kind {
            ModelKind::None => panic!("Attempted to take sync_type() of NULL model"),
            ModelKind::Brush(_) => SyncType::Sync,
            // TODO: expose sync_type in Sprite and reflect it here
            ModelKind::Sprite(ref smodel) => SyncType::Sync,
            // TODO: expose sync_type in Mdl and reflect it here
            ModelKind::Alias(ref amodel) => SyncType::Sync,
        }
    }

    pub fn get_flags(&self) -> ModelFlags {
        self.flags
    }
}
<|endoftext|>


<commit_before>/// Asserts that constant expressions evaluate to `true`.
///
/// Constant expressions can be ensured to have certain properties via this
/// macro If the expression evaluates to `false`, the file will fail to compile.
/// This is synonymous to [`static_assert` in C++][static_assert].
///
/// # Alternatives
///
/// There also exists [`const_assert_eq`](macro.const_assert_eq.html) for
/// validating whether a sequence of expressions are equal to one another.
///
/// # Examples
///
/// A common use case is to guarantee properties about a constant value that's
/// generated via meta-programming.
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const VALUE: i32 = // ...
/// # 3;
///
/// const_assert!(VALUE >= 2);
/// ```
///
/// Inputs are type-checked as booleans:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert!(!0);
/// ```
///
/// Despite this being a macro, we see this produces a type error:
///
/// ```txt
///   | const_assert!(!0);
///   |               ^^ expected bool, found integral variable
///   |
///   = note: expected type `bool`
///              found type `{integer}`
/// ```
///
/// The following fails to compile because multiplying by 5 does not have an
/// identity property:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert!(5 * 5 == 5);
/// ```
///
/// [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
#[macro_export]
macro_rules! const_assert {
    ($x:expr $(,)?) => {
        #[allow(unknown_lints, eq_op)]
        const _: [(); 0 - !{ const ASSERT: bool = $x; ASSERT } as usize] = [];
    };
}

/// Asserts that constants are equal in value.
///
/// # Examples
///
/// This works as a shorthand for `const_assert!(a == b)`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const TWO: usize = 2;
///
/// const_assert_eq!(TWO * TWO, TWO + TWO);
/// ```
///
/// Just because 2 × 2 = 2 + 2 doesn't mean it holds true for other numbers:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert_eq!(4 + 4, 4 * 4);
/// ```
#[macro_export(local_inner_macros)]
macro_rules! const_assert_eq {
    ($x:expr, $y:expr $(,)?) => {
        const_assert!($x == $y);
    };
}

/// Asserts that constants are **not** equal in value.
///
/// # Examples
///
/// This works as a shorthand for `const_assert!(a != b)`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const NUM: usize = 32;
///
/// const_assert_ne!(NUM * NUM, 64);
/// ```
///
/// The following example fails to compile because 2 is magic and 2 × 2 = 2 + 2:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert_ne!(2 + 2, 2 * 2);
/// ```
#[macro_export(local_inner_macros)]
macro_rules! const_assert_ne {
    ($x:expr, $y:expr $(,)?) => {
        const_assert!($x != $y);
    };
}
<commit_msg>Improve const_assert error messages<commit_after>/// Asserts that constant expressions evaluate to `true`.
///
/// Constant expressions can be ensured to have certain properties via this
/// macro If the expression evaluates to `false`, the file will fail to compile.
/// This is synonymous to [`static_assert` in C++][static_assert].
///
/// # Alternatives
///
/// There also exists [`const_assert_eq`](macro.const_assert_eq.html) for
/// validating whether a sequence of expressions are equal to one another.
///
/// # Examples
///
/// A common use case is to guarantee properties about a constant value that's
/// generated via meta-programming.
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const VALUE: i32 = // ...
/// # 3;
///
/// const_assert!(VALUE >= 2);
/// ```
///
/// Inputs are type-checked as booleans:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert!(!0);
/// ```
///
/// Despite this being a macro, we see this produces a type error:
///
/// ```txt
///   | const_assert!(!0);
///   |               ^^ expected bool, found integral variable
///   |
///   = note: expected type `bool`
///              found type `{integer}`
/// ```
///
/// The following fails to compile because multiplying by 5 does not have an
/// identity property:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert!(5 * 5 == 5);
/// ```
///
/// [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
#[macro_export]
macro_rules! const_assert {
    ($x:expr $(,)?) => {
        #[allow(unknown_lints, eq_op)]
        const _: () = {
            #[derive(Copy, Clone)]
            struct True;
            #[derive(Copy, Clone)]
            struct False;

            trait ToBool {
                type Value;
                fn to_bool(_: Self) -> Self::Value;
            }
            impl ToBool for [(); 0] {
                type Value = False;
                fn to_bool(_: Self) -> Self::Value {
                    False
                }
            }
            impl ToBool for [(); 1] {
                type Value = True;
                fn to_bool(_: Self) -> Self::Value {
                    True
                }
            }
            fn const_assert() {
                const ASSERT: bool = $x;
                let _: True = ToBool::to_bool([(); ASSERT as usize]);
            }
        };
    };
}

/// Asserts that constants are equal in value.
///
/// # Examples
///
/// This works as a shorthand for `const_assert!(a == b)`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const TWO: usize = 2;
///
/// const_assert_eq!(TWO * TWO, TWO + TWO);
/// ```
///
/// Just because 2 × 2 = 2 + 2 doesn't mean it holds true for other numbers:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert_eq!(4 + 4, 4 * 4);
/// ```
#[macro_export(local_inner_macros)]
macro_rules! const_assert_eq {
    ($x:expr, $y:expr $(,)?) => {
        const_assert!($x == $y);
    };
}

/// Asserts that constants are **not** equal in value.
///
/// # Examples
///
/// This works as a shorthand for `const_assert!(a != b)`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const NUM: usize = 32;
///
/// const_assert_ne!(NUM * NUM, 64);
/// ```
///
/// The following example fails to compile because 2 is magic and 2 × 2 = 2 + 2:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// const_assert_ne!(2 + 2, 2 * 2);
/// ```
#[macro_export(local_inner_macros)]
macro_rules! const_assert_ne {
    ($x:expr, $y:expr $(,)?) => {
        const_assert!($x != $y);
    };
}
<|endoftext|>


<commit_before>use crate::modules::*;
use criterion::Criterion;
use lucet_runtime::{DlModule, InstanceHandle, Limits, Module, Region, RegionCreate};
use lucet_wasi::WasiCtxBuilder;
use lucetc::OptLevel;
use std::path::Path;
use std::sync::Arc;
use tempfile::TempDir;

const HEAP_SIZES_KB: &'static [usize] = &[0, 32, 128, 512, 1024, 2 * 1024, 4 * 1024];

/// End-to-end instance instantiation.
///
/// This is meant to simulate our startup time when we start from scratch, with no module loaded and
/// no region created at all. This would be unusual for a server application, but reflects what
/// one-shot command-line tools like `lucet-wasi` do.
///
/// To minimize the effects of filesystem cache on the `DlModule::load()`, this runs `sync` between
/// each iteration.
fn hello_load_mkregion_and_instantiate<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: RegionCreate + 'static>(so_file: &Path) -> InstanceHandle {
        let module = DlModule::load(so_file).unwrap();
        let region = R::create(1, &Limits::default()).unwrap();
        region.new_instance(module).unwrap()
    }

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    c.bench_function(
        &format!("hello_load_mkregion_and_instantiate ({})", R::TYPE_NAME),
        move |b| {
            b.iter_batched(
                || unsafe { nix::libc::sync() },
                |_| body::<R>(&so_file),
                criterion::BatchSize::PerIteration,
            )
        },
    );

    workdir.close().unwrap();
}

/// Instance instantiation.
///
/// This simulates a typical case for a server process like Terrarium: the region and module stay
/// initialized, but a new instance is created for each request.
fn hello_instantiate<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: Region>(module: Arc<dyn Module>, region: Arc<R>) -> InstanceHandle {
        region.new_instance(module).unwrap()
    }

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    let module = DlModule::load(&so_file).unwrap();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("hello_instantiate ({})", R::TYPE_NAME), move |b| {
        b.iter(|| body(module.clone(), region.clone()))
    });

    workdir.close().unwrap();
}

/// Instance instantiation with a large, dense heap.
fn instantiate_with_dense_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: Region>(module: Arc<dyn Module>, region: Arc<R>) -> InstanceHandle {
        region.new_instance(module).unwrap()
    }

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("instantiate_with_dense_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            let module = large_dense_heap_mock(heap_kb);
            b.iter(|| body(module.clone(), region.clone()))
        },
        HEAP_SIZES_KB,
    );
}

/// Instance instantiation with a large, sparse heap.
fn instantiate_with_sparse_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: Region>(module: Arc<dyn Module>, region: Arc<R>) -> InstanceHandle {
        region.new_instance(module).unwrap()
    }

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("instantiate_with_sparse_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            // 8 means that only every eighth page has non-zero data
            let module = large_sparse_heap_mock(heap_kb, 8);
            b.iter(|| body(module.clone(), region.clone()))
        },
        HEAP_SIZES_KB,
    );
}

/// Instance destruction.
///
/// Instances have some cleanup to do with memory management and freeing their slot on their region.
fn hello_drop_instance<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(_inst: InstanceHandle) {}

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    let module = DlModule::load(&so_file).unwrap();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(
        &format!("hello_drop_instance ({})", R::TYPE_NAME),
        move |b| {
            b.iter_batched(
                || region.new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
    );

    workdir.close().unwrap();
}

/// Instance destruction with a large, dense heap.
fn drop_instance_with_dense_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(_inst: InstanceHandle) {}

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("drop_instance_with_dense_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            let module = large_dense_heap_mock(heap_kb);
            b.iter_batched(
                || region.clone().new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
        HEAP_SIZES_KB,
    );
}

/// Instance destruction with a large, sparse heap.
fn drop_instance_with_sparse_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(_inst: InstanceHandle) {}

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("drop_instance_with_sparse_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            // 8 means that only every eighth page has non-zero data
            let module = large_sparse_heap_mock(heap_kb, 8);
            b.iter_batched(
                || region.clone().new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
        HEAP_SIZES_KB,
    );
}

/// Run a trivial guest function.
///
/// This is primarily a measurement of the signal handler installation and removal, and the context
/// switching overhead.
fn run_null<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"f", &[]).unwrap();
    }

    let module = null_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_null ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

/// Run a computation-heavy guest function from a mock module.
///
/// Since this is running code in a mock module, the cost of the computation should overwhelm the
/// cost of the Lucet runtime.
fn run_fib<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"f", &[]).unwrap();
    }

    let module = fib_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_fib ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

/// Run a trivial WASI program.
fn run_hello<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"_start", &[]).unwrap();
    }

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    let module = DlModule::load(&so_file).unwrap();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_hello ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || {
                let null = std::fs::File::open("/dev/null").unwrap();
                let ctx = WasiCtxBuilder::new()
                    .args(&["hello"])
                    .fd(1, null)
                    .build()
                    .unwrap();
                region
                    .new_instance_builder(module.clone())
                    .with_embed_ctx(ctx)
                    .build()
                    .unwrap()
            },
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

/// Run a trivial guest function that takes a bunch of arguments.
///
/// This is primarily interesting as a comparison to `run_null`; the difference is the overhead of
/// installing the arguments into the guest registers and stack.
///
/// `rustfmt` hates this function.
fn run_many_args<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(
            b"f",
            &[
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
            ],
        )
        .unwrap();
    }

    let module = many_args_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_many_args ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

fn run_hostcall_wrapped<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"wrapped", &[]).unwrap();
    }

    let module = hostcalls_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(
        &format!("run_hostcall_wrapped ({})", R::TYPE_NAME),
        move |b| {
            b.iter_batched_ref(
                || region.new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
    );
}

fn run_hostcall_raw<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"raw", &[]).unwrap();
    }

    let module = hostcalls_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_hostcall_raw ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

pub fn seq_benches<R: RegionCreate + 'static>(c: &mut Criterion) {
    hello_load_mkregion_and_instantiate::<R>(c);
    hello_instantiate::<R>(c);
    instantiate_with_dense_heap::<R>(c);
    instantiate_with_sparse_heap::<R>(c);
    hello_drop_instance::<R>(c);
    drop_instance_with_dense_heap::<R>(c);
    drop_instance_with_sparse_heap::<R>(c);
    run_null::<R>(c);
    run_fib::<R>(c);
    run_hello::<R>(c);
    run_many_args::<R>(c);
    run_hostcall_wrapped::<R>(c);
    run_hostcall_raw::<R>(c);
}
<commit_msg>[lucet-benchmarks] use different heap sizes for dense and sparse<commit_after>use crate::modules::*;
use criterion::Criterion;
use lucet_runtime::{DlModule, InstanceHandle, Limits, Module, Region, RegionCreate};
use lucet_wasi::WasiCtxBuilder;
use lucetc::OptLevel;
use std::path::Path;
use std::sync::Arc;
use tempfile::TempDir;

const DENSE_HEAP_SIZES_KB: &'static [usize] = &[0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2 * 1024, 4 * 1024];

const SPARSE_HEAP_SIZES_KB: &'static [usize] = &[0, 256, 512, 1024, 2 * 1024, 4 * 1024];

/// End-to-end instance instantiation.
///
/// This is meant to simulate our startup time when we start from scratch, with no module loaded and
/// no region created at all. This would be unusual for a server application, but reflects what
/// one-shot command-line tools like `lucet-wasi` do.
///
/// To minimize the effects of filesystem cache on the `DlModule::load()`, this runs `sync` between
/// each iteration.
fn hello_load_mkregion_and_instantiate<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: RegionCreate + 'static>(so_file: &Path) -> InstanceHandle {
        let module = DlModule::load(so_file).unwrap();
        let region = R::create(1, &Limits::default()).unwrap();
        region.new_instance(module).unwrap()
    }

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    c.bench_function(
        &format!("hello_load_mkregion_and_instantiate ({})", R::TYPE_NAME),
        move |b| {
            b.iter_batched(
                || unsafe { nix::libc::sync() },
                |_| body::<R>(&so_file),
                criterion::BatchSize::PerIteration,
            )
        },
    );

    workdir.close().unwrap();
}

/// Instance instantiation.
///
/// This simulates a typical case for a server process like Terrarium: the region and module stay
/// initialized, but a new instance is created for each request.
fn hello_instantiate<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: Region>(module: Arc<dyn Module>, region: Arc<R>) -> InstanceHandle {
        region.new_instance(module).unwrap()
    }

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    let module = DlModule::load(&so_file).unwrap();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("hello_instantiate ({})", R::TYPE_NAME), move |b| {
        b.iter(|| body(module.clone(), region.clone()))
    });

    workdir.close().unwrap();
}

/// Instance instantiation with a large, dense heap.
fn instantiate_with_dense_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: Region>(module: Arc<dyn Module>, region: Arc<R>) -> InstanceHandle {
        region.new_instance(module).unwrap()
    }

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("instantiate_with_dense_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            let module = large_dense_heap_mock(heap_kb);
            b.iter(|| body(module.clone(), region.clone()))
        },
        DENSE_HEAP_SIZES_KB,
    );
}

/// Instance instantiation with a large, sparse heap.
fn instantiate_with_sparse_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body<R: Region>(module: Arc<dyn Module>, region: Arc<R>) -> InstanceHandle {
        region.new_instance(module).unwrap()
    }

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("instantiate_with_sparse_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            // 8 means that only every eighth page has non-zero data
            let module = large_sparse_heap_mock(heap_kb, 8);
            b.iter(|| body(module.clone(), region.clone()))
        },
        SPARSE_HEAP_SIZES_KB,
    );
}

/// Instance destruction.
///
/// Instances have some cleanup to do with memory management and freeing their slot on their region.
fn hello_drop_instance<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(_inst: InstanceHandle) {}

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    let module = DlModule::load(&so_file).unwrap();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(
        &format!("hello_drop_instance ({})", R::TYPE_NAME),
        move |b| {
            b.iter_batched(
                || region.new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
    );

    workdir.close().unwrap();
}

/// Instance destruction with a large, dense heap.
fn drop_instance_with_dense_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(_inst: InstanceHandle) {}

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("drop_instance_with_dense_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            let module = large_dense_heap_mock(heap_kb);
            b.iter_batched(
                || region.clone().new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
        DENSE_HEAP_SIZES_KB,
    );
}

/// Instance destruction with a large, sparse heap.
fn drop_instance_with_sparse_heap<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(_inst: InstanceHandle) {}

    let limits = Limits {
        heap_memory_size: 1024 * 1024 * 1024,
        ..Limits::default()
    };

    let region = R::create(1, &limits).unwrap();

    c.bench_function_over_inputs(
        &format!("drop_instance_with_sparse_heap ({})", R::TYPE_NAME),
        move |b, &&heap_kb| {
            // 8 means that only every eighth page has non-zero data
            let module = large_sparse_heap_mock(heap_kb, 8);
            b.iter_batched(
                || region.clone().new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
        SPARSE_HEAP_SIZES_KB,
    );
}

/// Run a trivial guest function.
///
/// This is primarily a measurement of the signal handler installation and removal, and the context
/// switching overhead.
fn run_null<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"f", &[]).unwrap();
    }

    let module = null_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_null ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

/// Run a computation-heavy guest function from a mock module.
///
/// Since this is running code in a mock module, the cost of the computation should overwhelm the
/// cost of the Lucet runtime.
fn run_fib<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"f", &[]).unwrap();
    }

    let module = fib_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_fib ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

/// Run a trivial WASI program.
fn run_hello<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"_start", &[]).unwrap();
    }

    let workdir = TempDir::new().expect("create working directory");

    let so_file = workdir.path().join("out.so");
    compile_hello(&so_file, OptLevel::Best);

    let module = DlModule::load(&so_file).unwrap();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_hello ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || {
                let null = std::fs::File::open("/dev/null").unwrap();
                let ctx = WasiCtxBuilder::new()
                    .args(&["hello"])
                    .fd(1, null)
                    .build()
                    .unwrap();
                region
                    .new_instance_builder(module.clone())
                    .with_embed_ctx(ctx)
                    .build()
                    .unwrap()
            },
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

/// Run a trivial guest function that takes a bunch of arguments.
///
/// This is primarily interesting as a comparison to `run_null`; the difference is the overhead of
/// installing the arguments into the guest registers and stack.
///
/// `rustfmt` hates this function.
fn run_many_args<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(
            b"f",
            &[
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
                0xAFu8.into(),
                0xAFu16.into(),
                0xAFu32.into(),
                0xAFu64.into(),
                175.0f32.into(),
                175.0f64.into(),
            ],
        )
        .unwrap();
    }

    let module = many_args_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_many_args ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

fn run_hostcall_wrapped<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"wrapped", &[]).unwrap();
    }

    let module = hostcalls_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(
        &format!("run_hostcall_wrapped ({})", R::TYPE_NAME),
        move |b| {
            b.iter_batched_ref(
                || region.new_instance(module.clone()).unwrap(),
                |inst| body(inst),
                criterion::BatchSize::PerIteration,
            )
        },
    );
}

fn run_hostcall_raw<R: RegionCreate + 'static>(c: &mut Criterion) {
    fn body(inst: &mut InstanceHandle) {
        inst.run(b"raw", &[]).unwrap();
    }

    let module = hostcalls_mock();
    let region = R::create(1, &Limits::default()).unwrap();

    c.bench_function(&format!("run_hostcall_raw ({})", R::TYPE_NAME), move |b| {
        b.iter_batched_ref(
            || region.new_instance(module.clone()).unwrap(),
            |inst| body(inst),
            criterion::BatchSize::PerIteration,
        )
    });
}

pub fn seq_benches<R: RegionCreate + 'static>(c: &mut Criterion) {
    hello_load_mkregion_and_instantiate::<R>(c);
    hello_instantiate::<R>(c);
    instantiate_with_dense_heap::<R>(c);
    instantiate_with_sparse_heap::<R>(c);
    hello_drop_instance::<R>(c);
    drop_instance_with_dense_heap::<R>(c);
    drop_instance_with_sparse_heap::<R>(c);
    run_null::<R>(c);
    run_fib::<R>(c);
    run_hello::<R>(c);
    run_many_args::<R>(c);
    run_hostcall_wrapped::<R>(c);
    run_hostcall_raw::<R>(c);
}
<|endoftext|>


<commit_before>//! Quicksort algorithm.
//!
//! The `efficient` module contains the efficient sorting algorithm "Quicksort".
//!
//! Source: https://en.wikipedia.org/wiki/Quicksort

extern crate libc;

use std::slice;

/// Quicksort
///
/// # Details
///
/// Quicksort is the defacto standard of sorting algorithms. It recursively sorts a vector in place
/// by finding a pivot and by re-arranging the vector so that all smaller elements are on the
/// left and all larger elements are on the right of that pivot.
///
/// # Scaling
///
/// It's average case complexity is O(N log N). To prevent the worst case complexity of O(N^2) when
/// the vector is already sorted, the median of the first, middle and last elements is taken as the
/// pivot ("median-of-three").
///
/// # Optimizations
///
/// Use median as pivot.
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::efficientsorts::quick::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
pub fn sort<T: PartialOrd>(array: &mut [T]) {
    let n = array.len();

    if n <= 1 {
        // Don't do anything
    } else if n == 2 {
        if array.first() > array.last() {
            array.swap(0, 1);
        }
    } else {
        // Choose the pivot element: Select the median between the first, middle and last element.
        let mut pivot = {
            let mut piv_choices: Vec<usize> = vec![0, n/2, n-1];
            // Find maximum value between the first, middle and last element.
            let mut max_val_i: usize = 0;
            for i in 1..3 {
                if array[piv_choices[max_val_i]] < array[piv_choices[i]] {
                    max_val_i = i;
                }
            }
            // Remove that index from the choice of pivot.
            piv_choices.remove(max_val_i);
            // The pivot will be the maximum of the remaining two (the median of initial
            // piv_choices vector).
            assert_eq!(piv_choices.len(), 2);
            if array[piv_choices[0]] > array[piv_choices[1]] {
                piv_choices[0]
            } else {
                piv_choices[1]
            }
        };

        // Place pivot at i=0 and loop over the remaining of the vector.
        array.swap(pivot, 0);
        pivot = 0;

        for i in 1..n {
            // The loop element is smaller than the pivot. Shuffle things around to place that
            // element before the pivot.
            if array[pivot] > array[i] {
                // First, let's swap the element and the pivot.
                array.swap(pivot, i);
                // Two cases are possible here:
                //     1) The element was the one next to the pivot in the vector. As such, the
                //        new pivot's location is the index "i".
                //     2) The element swaped was further down the vector. If we just swap the pivot
                //        and that element, we are sending the pivot _after_ larger elements,
                //        breaking the ordering! Additionally to the first swap, the pivot (now
                //        being at index "i" after the first swap) is again swapped with the
                //        element that was next to it before (index "pivot+1").
                if i == pivot+1 {
                    pivot = i;
                } else {
                    array.swap(i, pivot+1);
                    pivot = pivot+1;
                }
            }
        }

        // Recursively call the function on slices of the vector.
        sort(&mut array[0..pivot+1]);
        sort(&mut array[pivot+1..n]);
    }
}

#[no_mangle]
pub extern "C" fn ffi_quicksort_i8(array_pointer: *const libc::int8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_i16(array_pointer: *const libc::int16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_i32(array_pointer: *const libc::int32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_i64(array_pointer: *const libc::int64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_quicksort_u8(array_pointer: *const libc::uint8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_u16(array_pointer: *const libc::uint16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_u32(array_pointer: *const libc::uint32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_u64(array_pointer: *const libc::uint64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_quicksort_f32(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_f64(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f64, n as usize)
    };
    sort(&mut to_sort);
}
<commit_msg>Comment about quicksort.<commit_after>//! Quicksort algorithm.
//!
//! The `efficient` module contains the efficient sorting algorithm "Quicksort".
//!
//! Source: https://en.wikipedia.org/wiki/Quicksort

extern crate libc;

use std::slice;

/// Quicksort
///
/// # Details
///
/// Quicksort is the defacto standard of sorting algorithms. It recursively sorts a vector in place
/// by finding a pivot and by re-arranging the vector so that all smaller elements are on the
/// left and all larger elements are on the right of that pivot.
///
/// # Scaling
///
/// It's average case complexity is O(N log N). To prevent the worst case complexity of O(N^2) when
/// the vector is already sorted, the median of the first, middle and last elements is taken as the
/// pivot ("median-of-three").
///
/// # Optimizations
///
/// Use median as pivot.
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::efficientsorts::quick::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
pub fn sort<T: PartialOrd>(array: &mut [T]) {
    let n = array.len();

    // NOTE: Insertion could be used for "small" number of elements as an optimization. It is not
    //       used here as to show exactly how quicksort works.

    if n <= 1 {
        // Don't do anything
    } else if n == 2 {
        if array.first() > array.last() {
            array.swap(0, 1);
        }
    } else {
        // Choose the pivot element: Select the median between the first, middle and last element.
        let mut pivot = {
            let mut piv_choices: Vec<usize> = vec![0, n/2, n-1];
            // Find maximum value between the first, middle and last element.
            let mut max_val_i: usize = 0;
            for i in 1..3 {
                if array[piv_choices[max_val_i]] < array[piv_choices[i]] {
                    max_val_i = i;
                }
            }
            // Remove that index from the choice of pivot.
            piv_choices.remove(max_val_i);
            // The pivot will be the maximum of the remaining two (the median of initial
            // piv_choices vector).
            assert_eq!(piv_choices.len(), 2);
            if array[piv_choices[0]] > array[piv_choices[1]] {
                piv_choices[0]
            } else {
                piv_choices[1]
            }
        };

        // Place pivot at i=0 and loop over the remaining of the vector.
        array.swap(pivot, 0);
        pivot = 0;

        for i in 1..n {
            // The loop element is smaller than the pivot. Shuffle things around to place that
            // element before the pivot.
            if array[pivot] > array[i] {
                // First, let's swap the element and the pivot.
                array.swap(pivot, i);
                // Two cases are possible here:
                //     1) The element was the one next to the pivot in the vector. As such, the
                //        new pivot's location is the index "i".
                //     2) The element swaped was further down the vector. If we just swap the pivot
                //        and that element, we are sending the pivot _after_ larger elements,
                //        breaking the ordering! Additionally to the first swap, the pivot (now
                //        being at index "i" after the first swap) is again swapped with the
                //        element that was next to it before (index "pivot+1").
                if i == pivot+1 {
                    pivot = i;
                } else {
                    array.swap(i, pivot+1);
                    pivot = pivot+1;
                }
            }
        }

        // Recursively call the function on slices of the vector.
        sort(&mut array[0..pivot+1]);
        sort(&mut array[pivot+1..n]);
    }
}

#[no_mangle]
pub extern "C" fn ffi_quicksort_i8(array_pointer: *const libc::int8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_i16(array_pointer: *const libc::int16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_i32(array_pointer: *const libc::int32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_i64(array_pointer: *const libc::int64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_quicksort_u8(array_pointer: *const libc::uint8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_u16(array_pointer: *const libc::uint16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_u32(array_pointer: *const libc::uint32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_u64(array_pointer: *const libc::uint64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_quicksort_f32(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_quicksort_f64(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f64, n as usize)
    };
    sort(&mut to_sort);
}
<|endoftext|>


<commit_before>//! Procedurally generating the game world.
//!

use world::{CHUNK_SIZE, Chunk, ChunkIndex, ChunkProvider, HeightType, HexPillar};
use world::{GroundMaterial, PillarSection, Prop, PropType};
use rand::{Rand, SeedableRng, XorShiftRng};
use gen::PlantGenerator;

/// Main type to generate the game world. Implements the `ChunkProvider` trait
/// (TODO, see #8).
pub struct WorldGenerator {
    seed: u64,
}

impl WorldGenerator {
    /// Creates the generator with the given seed.
    pub fn with_seed(seed: u64) -> Self {
        WorldGenerator { seed: seed }
    }

    /// Returns the seed of this world generator.
    pub fn seed(&self) -> u64 {
        self.seed
    }
}

impl ChunkProvider for WorldGenerator {
    fn load_chunk(&self, index: ChunkIndex) -> Option<Chunk> {
        let mut pillars = Vec::new();
        let q = index.0.q * CHUNK_SIZE as i32;
        let r = index.0.r * CHUNK_SIZE as i32;

        // FIXME: XorShift doesn't handle this form of seeding very well, the first value generated
        // after this is almost always the same (or very close). Introduce better seeding methods
        // and/or use a different RNG.
        let mut rng = XorShiftRng::from_seed([(self.seed >> 32) as u32,
                                              self.seed as u32,
                                              q as u32,
                                              r as u32]);

        for i in q..q + CHUNK_SIZE as i32 {
            for j in r..r + CHUNK_SIZE as i32 {
                let height = (((i as f32) * 0.25).sin() * 10.0 + ((j as f32) * 0.25).sin() * 10.0 +
                              100.0) as u16;

                let ground_section =
                    PillarSection::new(GroundMaterial::Dirt, HeightType(0), HeightType(height));
                let mut props = Vec::new();

                // Place a test plant every few blocks
                const TREE_SPACING: i32 = 8;
                if i % TREE_SPACING == 0 && j % TREE_SPACING == 0 {

                    let gen = PlantGenerator::rand(&mut rng);

                    props.push(Prop {
                        baseline: HeightType(height),
                        prop: PropType::Plant(gen.generate(&mut rng)),
                    });
                }

                pillars.push(HexPillar::new(vec![ground_section], props));
            }
        }

        Some(Chunk::from_pillars(pillars))
    }

    fn is_chunk_loadable(&self, _: ChunkIndex) -> bool {
        // for the moment returns true
        true
    }
}
<commit_msg>format moar<commit_after>//! Procedurally generating the game world.
//!

use world::{CHUNK_SIZE, Chunk, ChunkIndex, ChunkProvider, HeightType, HexPillar};
use world::{GroundMaterial, PillarSection, Prop, PropType};
use rand::{Rand, SeedableRng, XorShiftRng};
use gen::PlantGenerator;

/// Main type to generate the game world. Implements the `ChunkProvider` trait
/// (TODO, see #8).
pub struct WorldGenerator {
    seed: u64,
}

impl WorldGenerator {
    /// Creates the generator with the given seed.
    pub fn with_seed(seed: u64) -> Self {
        WorldGenerator { seed: seed }
    }

    /// Returns the seed of this world generator.
    pub fn seed(&self) -> u64 {
        self.seed
    }
}

impl ChunkProvider for WorldGenerator {
    fn load_chunk(&self, index: ChunkIndex) -> Option<Chunk> {
        let mut pillars = Vec::new();
        let q = index.0.q * CHUNK_SIZE as i32;
        let r = index.0.r * CHUNK_SIZE as i32;

        // FIXME: XorShift doesn't handle this form of seeding very well, the first
        // value generated after this is almost always the same (or very close).
        // Introduce better seeding methods and/or use a different RNG.
        let mut rng = XorShiftRng::from_seed([(self.seed >> 32) as u32,
                                              self.seed as u32,
                                              q as u32,
                                              r as u32]);

        for i in q..q + CHUNK_SIZE as i32 {
            for j in r..r + CHUNK_SIZE as i32 {
                let height = (((i as f32) * 0.25).sin() * 10.0 + ((j as f32) * 0.25).sin() * 10.0 +
                              100.0) as u16;

                let ground_section =
                    PillarSection::new(GroundMaterial::Dirt, HeightType(0), HeightType(height));
                let mut props = Vec::new();

                // Place a test plant every few blocks
                const TREE_SPACING: i32 = 8;
                if i % TREE_SPACING == 0 && j % TREE_SPACING == 0 {

                    let gen = PlantGenerator::rand(&mut rng);

                    props.push(Prop {
                        baseline: HeightType(height),
                        prop: PropType::Plant(gen.generate(&mut rng)),
                    });
                }

                pillars.push(HexPillar::new(vec![ground_section], props));
            }
        }

        Some(Chunk::from_pillars(pillars))
    }

    fn is_chunk_loadable(&self, _: ChunkIndex) -> bool {
        // for the moment returns true
        true
    }
}
<|endoftext|>


<commit_before>extern crate libc;
use libc::*;

pub const RS_DELTA_MAGIC: c_int = 0x72730236;
<commit_msg>Working on the first function to export<commit_after>#[allow(bad_style)]

extern crate libc;
use libc::*;

pub const RS_DELTA_MAGIC: c_int = 0x72730236;
pub const RS_MD4_SIG_MAGIC: c_int = 0x72730136;
pub const RS_BLAKE2_SIG_MAGIC: c_int = 0x72730137;

#[repr(C)]
pub struct rs_job_t {
    dogtag: c_int,
    job_name: *const c_char,
// TODO
//    int                 dogtag;
//    const char          *job_name;
//    rs_buffers_t *stream;
//    rs_result           (*statefn)(rs_job_t *);
//    rs_result final_result;
//    int                 block_len;
//    int                 strong_sum_len;
//    rs_signature_t      *signature;
//    unsigned char       op;
//    rs_weak_sum_t       weak_sig;
//    Rollsum             weak_sum;
//    rs_long_t           param1, param2;
//    struct rs_prototab_ent const *cmd;
//    rs_mdfour_t      output_md4;
//    rs_stats_t          stats;
//    rs_byte_t   *scoop_buf;          /* the allocation pointer */
//    rs_byte_t   *scoop_next;         /* the data pointer */
//    size_t      scoop_alloc;           /* the allocation size */
//    size_t      scoop_avail;           /* the data size */
//    size_t      scoop_pos;             /* the scan position */
//    rs_byte_t   write_buf[36];
//    int         write_len;
//    rs_long_t   copy_len;
//    rs_long_t       basis_pos, basis_len;
//    rs_copy_cb      *copy_cb;
//    void            *copy_arg;
//    int             magic;
}

extern {
    pub fn rs_sig_begin(new_block_len: size_t,
                        strong_sum_len: size_t,
                        sig_magic: c_int/*rs_magic_number*/)
                        -> *mut rs_job_t;
}
<|endoftext|>


<commit_before>//! Utilities to work with files, produced by macros.
use std::iter::successors;

use hir::InFile;
use ra_db::FileId;
use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxToken};

use crate::{db::RootDatabase, FileRange};

pub(crate) fn original_range(db: &RootDatabase, node: InFile<&SyntaxNode>) -> FileRange {
    let expansion = match node.file_id.expansion_info(db) {
        None => {
            return FileRange {
                file_id: node.file_id.original_file(db),
                range: node.value.text_range(),
            }
        }
        Some(it) => it,
    };
    // FIXME: the following completely wrong.
    //
    // *First*, we should try to map first and last tokens of node, and, if that
    // fails, return the range of the overall macro expansions.
    //
    // *Second*, we should handle recurside macro expansions

    let token = node
        .value
        .descendants_with_tokens()
        .filter_map(|it| it.into_token())
        .find_map(|it| expansion.map_token_up(node.with_value(&it)));

    match token {
        Some(it) => {
            FileRange { file_id: it.file_id.original_file(db), range: it.value.text_range() }
        }
        None => {
            FileRange { file_id: node.file_id.original_file(db), range: node.value.text_range() }
        }
    }
}

pub(crate) fn descend_into_macros(
    db: &RootDatabase,
    file_id: FileId,
    token: SyntaxToken,
) -> InFile<SyntaxToken> {
    let src = InFile::new(file_id.into(), token);

    successors(Some(src), |token| {
        let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
        let tt = macro_call.token_tree()?;
        if !token.value.text_range().is_subrange(&tt.syntax().text_range()) {
            return None;
        }
        let source_analyzer =
            hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None);
        let exp = source_analyzer.expand(db, token.with_value(&macro_call))?;
        exp.map_token_down(db, token.as_ref())
    })
    .last()
    .unwrap()
}
<commit_msg>Map first and last node in original_range<commit_after>//! Utilities to work with files, produced by macros.
use std::iter::successors;

use hir::InFile;
use ra_db::FileId;
use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxToken, TextRange};

use crate::{db::RootDatabase, FileRange};

pub(crate) fn original_range(db: &RootDatabase, node: InFile<&SyntaxNode>) -> FileRange {
    let expansion = match node.file_id.expansion_info(db) {
        None => {
            return FileRange {
                file_id: node.file_id.original_file(db),
                range: node.value.text_range(),
            }
        }
        Some(it) => it,
    };
    // FIXME: We should handle recurside macro expansions

    let range = node.value.descendants_with_tokens().find_map(|it| {
        match it.as_token() {
            // FIXME: Remove this branch after all `tt::TokenTree`s have a proper `TokenId`,
            // and return the range of the overall macro expansions if mapping first and last tokens fails.
            Some(token) => {
                let token = expansion.map_token_up(node.with_value(&token))?;
                Some(token.with_value(token.value.text_range()))
            }
            None => {
                // Try to map first and last tokens of node, and, if success, return the union range of mapped tokens
                let n = it.into_node()?;
                let first = expansion.map_token_up(node.with_value(&n.first_token()?))?;
                let last = expansion.map_token_up(node.with_value(&n.last_token()?))?;

                // FIXME: Is is possible ?
                if first.file_id != last.file_id {
                    return None;
                }

                // FIXME: Add union method in TextRange
                let range = union_range(first.value.text_range(), last.value.text_range());
                Some(first.with_value(range))
            }
        }
    });

    return match range {
        Some(it) => FileRange { file_id: it.file_id.original_file(db), range: it.value },
        None => {
            FileRange { file_id: node.file_id.original_file(db), range: node.value.text_range() }
        }
    };

    fn union_range(a: TextRange, b: TextRange) -> TextRange {
        let start = a.start().min(b.start());
        let end = a.end().max(b.end());
        TextRange::from_to(start, end)
    }
}

pub(crate) fn descend_into_macros(
    db: &RootDatabase,
    file_id: FileId,
    token: SyntaxToken,
) -> InFile<SyntaxToken> {
    let src = InFile::new(file_id.into(), token);

    successors(Some(src), |token| {
        let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
        let tt = macro_call.token_tree()?;
        if !token.value.text_range().is_subrange(&tt.syntax().text_range()) {
            return None;
        }
        let source_analyzer =
            hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None);
        let exp = source_analyzer.expand(db, token.with_value(&macro_call))?;
        exp.map_token_down(db, token.as_ref())
    })
    .last()
    .unwrap()
}
<|endoftext|>