<commit_before>use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::ptr;
use std::str::{self, FromStr};

use libc;
use url::Url;

use glib::translate::*;
use glib_sys::{gboolean, gpointer, GList};

use crate::allowed_url::AllowedUrl;
use crate::attributes::Attribute;
use crate::croco::*;
use crate::error::LoadingError;
use crate::io::{self, BinaryData};
use crate::properties::SpecifiedValues;
use crate::util::utf8_cstr;

struct Declaration {
    prop_value: String,
    important: bool,
}

// Maps property_name -> Declaration
type DeclarationList = HashMap<String, Declaration>;

/// Contains all the mappings of selectors to style declarations
/// that result from loading an SVG document.
pub struct CssRules {
    selectors_to_declarations: HashMap<String, DeclarationList>,
}

impl CssRules {
    pub fn new() -> CssRules {
        CssRules {
            selectors_to_declarations: HashMap::new(),
        }
    }

    pub fn parse(&mut self, base_url: Option<&Url>, buf: &str) {
        if buf.len() == 0 {
            return; // libcroco doesn't like empty strings :(
        }

        unsafe {
            let mut handler_data = DocHandlerData {
                base_url,
                css_rules: self,
                selector: ptr::null_mut(),
            };

            let doc_handler = cr_doc_handler_new();
            init_cr_doc_handler(&mut *doc_handler);

            (*doc_handler).app_data = &mut handler_data as *mut _ as gpointer;

            let buf_ptr = buf.as_ptr() as *mut _;
            let buf_len = buf.len() as libc::c_ulong;

            let parser = cr_parser_new_from_buf(buf_ptr, buf_len, CR_UTF_8, false.to_glib());
            if parser.is_null() {
                cr_doc_handler_unref(doc_handler);
                return;
            }

            cr_parser_set_sac_handler(parser, doc_handler);
            cr_doc_handler_unref(doc_handler);

            cr_parser_set_use_core_grammar(parser, false.to_glib());
            cr_parser_parse(parser);

            cr_parser_destroy(parser);
        }
    }

    pub fn load_css(&mut self, aurl: &AllowedUrl) -> Result<(), LoadingError> {
        io::acquire_data(aurl, None)
            .and_then(|data| {
                let BinaryData {
                    data: bytes,
                    content_type,
                } = data;

                if content_type.as_ref().map(String::as_ref) == Some("text/css") {
                    Ok(bytes)
                } else {
                    rsvg_log!("\"{}\" is not of type text/css; ignoring", aurl);
                    Err(LoadingError::BadCss)
                }
            })
            .and_then(|bytes| {
                String::from_utf8(bytes).map_err(|_| {
                    rsvg_log!(
                        "\"{}\" does not contain valid UTF-8 CSS data; ignoring",
                        aurl
                    );
                    LoadingError::BadCss
                })
            })
            .and_then(|utf8| {
                self.parse(Some(&aurl), &utf8);
                Ok(()) // FIXME: return CSS parsing errors
            })
    }

    fn define(&mut self, selector: &str, prop_name: &str, prop_value: &str, important: bool) {
        let decl_list = self
            .selectors_to_declarations
            .entry(selector.to_string())
            .or_insert_with(|| DeclarationList::new());

        match decl_list.entry(prop_name.to_string()) {
            Entry::Occupied(mut e) => {
                let decl = e.get_mut();

                if !decl.important {
                    decl.prop_value = prop_value.to_string();
                    decl.important = important;
                }
            }

            Entry::Vacant(v) => {
                v.insert(Declaration {
                    prop_value: prop_value.to_string(),
                    important,
                });
            }
        }
    }

    pub fn lookup_apply(
        &self,
        selector: &str,
        values: &mut SpecifiedValues,
        important_styles: &mut HashSet<Attribute>,
    ) -> bool {
        if let Some(decl_list) = self.selectors_to_declarations.get(selector) {
            for (prop_name, declaration) in decl_list.iter() {
                if let Ok(attr) = Attribute::from_str(prop_name) {
                    // FIXME: this is ignoring errors
                    let _ = values.parse_style_pair(
                        attr,
                        &declaration.prop_value,
                        declaration.important,
                        important_styles,
                    );
                }
            }

            true
        } else {
            false
        }
    }
}

struct DocHandlerData<'a> {
    base_url: Option<&'a Url>,
    css_rules: &'a mut CssRules,
    selector: *mut CRSelector,
}

macro_rules! get_doc_handler_data {
    ($doc_handler:expr) => {
        &mut *((*$doc_handler).app_data as *mut DocHandlerData)
    };
}

fn init_cr_doc_handler(handler: &mut CRDocHandler) {
    handler.import_style = Some(css_import_style);
    handler.start_selector = Some(css_start_selector);
    handler.end_selector = Some(css_end_selector);
    handler.property = Some(css_property);
    handler.error = Some(css_error);
    handler.unrecoverable_error = Some(css_unrecoverable_error);
}

unsafe extern "C" fn css_import_style(
    a_this: *mut CRDocHandler,
    _a_media_list: *mut GList,
    a_uri: CRString,
    _a_uri_default_ns: CRString,
    _a_location: CRParsingLocation,
) {
    let handler_data = get_doc_handler_data!(a_this);

    if a_uri.is_null() {
        return;
    }

    let raw_uri = cr_string_peek_raw_str(a_uri);
    let uri = utf8_cstr(raw_uri);

    if let Ok(aurl) = AllowedUrl::from_href(uri, handler_data.base_url) {
        // FIXME: handle CSS errors
        let _ = handler_data.css_rules.load_css(&aurl);
    } else {
        rsvg_log!("disallowed URL \"{}\" for importing CSS", uri);
    }
}

unsafe extern "C" fn css_start_selector(
    a_this: *mut CRDocHandler,
    a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data!(a_this);

    cr_selector_ref(a_selector_list);
    handler_data.selector = a_selector_list;
}

unsafe extern "C" fn css_end_selector(
    a_this: *mut CRDocHandler,
    _a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data!(a_this);

    cr_selector_unref(handler_data.selector);
    handler_data.selector = ptr::null_mut();
}

unsafe extern "C" fn css_property(
    a_this: *mut CRDocHandler,
    a_name: CRString,
    a_expression: CRTerm,
    a_is_important: gboolean,
) {
    let handler_data = get_doc_handler_data!(a_this);

    if a_name.is_null() || a_expression.is_null() || handler_data.selector.is_null() {
        return;
    }

    let mut cur_sel = handler_data.selector;
    while !cur_sel.is_null() {
        let simple_sel = (*cur_sel).simple_sel;

        if !simple_sel.is_null() {
            let raw_selector_name = cr_simple_sel_to_string(simple_sel) as *mut libc::c_char;

            if !raw_selector_name.is_null() {
                let raw_prop_name = cr_string_peek_raw_str(a_name);
                let prop_name = utf8_cstr(raw_prop_name);

                let prop_value =
                    <String as FromGlibPtrFull<_>>::from_glib_full(cr_term_to_string(a_expression));

                let selector_name =
                    <String as FromGlibPtrFull<_>>::from_glib_full(raw_selector_name);

                let important = from_glib(a_is_important);

                handler_data
                    .css_rules
                    .define(&selector_name, prop_name, &prop_value, important);
            }
        }

        cur_sel = (*cur_sel).next;
    }
}

unsafe extern "C" fn css_error(_a_this: *mut CRDocHandler) {
    println!("CSS parsing error");
}

unsafe extern "C" fn css_unrecoverable_error(_a_this: *mut CRDocHandler) {
    println!("CSS unrecoverable error");
}
<commit_msg>Comment what a function does<commit_after>use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::ptr;
use std::str::{self, FromStr};

use libc;
use url::Url;

use glib::translate::*;
use glib_sys::{gboolean, gpointer, GList};

use crate::allowed_url::AllowedUrl;
use crate::attributes::Attribute;
use crate::croco::*;
use crate::error::LoadingError;
use crate::io::{self, BinaryData};
use crate::properties::SpecifiedValues;
use crate::util::utf8_cstr;

struct Declaration {
    prop_value: String,
    important: bool,
}

// Maps property_name -> Declaration
type DeclarationList = HashMap<String, Declaration>;

/// Contains all the mappings of selectors to style declarations
/// that result from loading an SVG document.
pub struct CssRules {
    selectors_to_declarations: HashMap<String, DeclarationList>,
}

impl CssRules {
    pub fn new() -> CssRules {
        CssRules {
            selectors_to_declarations: HashMap::new(),
        }
    }

    pub fn parse(&mut self, base_url: Option<&Url>, buf: &str) {
        if buf.len() == 0 {
            return; // libcroco doesn't like empty strings :(
        }

        unsafe {
            let mut handler_data = DocHandlerData {
                base_url,
                css_rules: self,
                selector: ptr::null_mut(),
            };

            let doc_handler = cr_doc_handler_new();
            init_cr_doc_handler(&mut *doc_handler);

            (*doc_handler).app_data = &mut handler_data as *mut _ as gpointer;

            let buf_ptr = buf.as_ptr() as *mut _;
            let buf_len = buf.len() as libc::c_ulong;

            let parser = cr_parser_new_from_buf(buf_ptr, buf_len, CR_UTF_8, false.to_glib());
            if parser.is_null() {
                cr_doc_handler_unref(doc_handler);
                return;
            }

            cr_parser_set_sac_handler(parser, doc_handler);
            cr_doc_handler_unref(doc_handler);

            cr_parser_set_use_core_grammar(parser, false.to_glib());
            cr_parser_parse(parser);

            cr_parser_destroy(parser);
        }
    }

    pub fn load_css(&mut self, aurl: &AllowedUrl) -> Result<(), LoadingError> {
        io::acquire_data(aurl, None)
            .and_then(|data| {
                let BinaryData {
                    data: bytes,
                    content_type,
                } = data;

                if content_type.as_ref().map(String::as_ref) == Some("text/css") {
                    Ok(bytes)
                } else {
                    rsvg_log!("\"{}\" is not of type text/css; ignoring", aurl);
                    Err(LoadingError::BadCss)
                }
            })
            .and_then(|bytes| {
                String::from_utf8(bytes).map_err(|_| {
                    rsvg_log!(
                        "\"{}\" does not contain valid UTF-8 CSS data; ignoring",
                        aurl
                    );
                    LoadingError::BadCss
                })
            })
            .and_then(|utf8| {
                self.parse(Some(&aurl), &utf8);
                Ok(()) // FIXME: return CSS parsing errors
            })
    }

    fn define(&mut self, selector: &str, prop_name: &str, prop_value: &str, important: bool) {
        let decl_list = self
            .selectors_to_declarations
            .entry(selector.to_string())
            .or_insert_with(|| DeclarationList::new());

        match decl_list.entry(prop_name.to_string()) {
            Entry::Occupied(mut e) => {
                let decl = e.get_mut();

                if !decl.important {
                    decl.prop_value = prop_value.to_string();
                    decl.important = important;
                }
            }

            Entry::Vacant(v) => {
                v.insert(Declaration {
                    prop_value: prop_value.to_string(),
                    important,
                });
            }
        }
    }

    /// Takes CSS rules which match the given `selector` name and applies them
    /// to the `values`.
    pub fn lookup_apply(
        &self,
        selector: &str,
        values: &mut SpecifiedValues,
        important_styles: &mut HashSet<Attribute>,
    ) -> bool {
        if let Some(decl_list) = self.selectors_to_declarations.get(selector) {
            for (prop_name, declaration) in decl_list.iter() {
                if let Ok(attr) = Attribute::from_str(prop_name) {
                    // FIXME: this is ignoring errors
                    let _ = values.parse_style_pair(
                        attr,
                        &declaration.prop_value,
                        declaration.important,
                        important_styles,
                    );
                }
            }

            true
        } else {
            false
        }
    }
}

struct DocHandlerData<'a> {
    base_url: Option<&'a Url>,
    css_rules: &'a mut CssRules,
    selector: *mut CRSelector,
}

macro_rules! get_doc_handler_data {
    ($doc_handler:expr) => {
        &mut *((*$doc_handler).app_data as *mut DocHandlerData)
    };
}

fn init_cr_doc_handler(handler: &mut CRDocHandler) {
    handler.import_style = Some(css_import_style);
    handler.start_selector = Some(css_start_selector);
    handler.end_selector = Some(css_end_selector);
    handler.property = Some(css_property);
    handler.error = Some(css_error);
    handler.unrecoverable_error = Some(css_unrecoverable_error);
}

unsafe extern "C" fn css_import_style(
    a_this: *mut CRDocHandler,
    _a_media_list: *mut GList,
    a_uri: CRString,
    _a_uri_default_ns: CRString,
    _a_location: CRParsingLocation,
) {
    let handler_data = get_doc_handler_data!(a_this);

    if a_uri.is_null() {
        return;
    }

    let raw_uri = cr_string_peek_raw_str(a_uri);
    let uri = utf8_cstr(raw_uri);

    if let Ok(aurl) = AllowedUrl::from_href(uri, handler_data.base_url) {
        // FIXME: handle CSS errors
        let _ = handler_data.css_rules.load_css(&aurl);
    } else {
        rsvg_log!("disallowed URL \"{}\" for importing CSS", uri);
    }
}

unsafe extern "C" fn css_start_selector(
    a_this: *mut CRDocHandler,
    a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data!(a_this);

    cr_selector_ref(a_selector_list);
    handler_data.selector = a_selector_list;
}

unsafe extern "C" fn css_end_selector(
    a_this: *mut CRDocHandler,
    _a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data!(a_this);

    cr_selector_unref(handler_data.selector);
    handler_data.selector = ptr::null_mut();
}

unsafe extern "C" fn css_property(
    a_this: *mut CRDocHandler,
    a_name: CRString,
    a_expression: CRTerm,
    a_is_important: gboolean,
) {
    let handler_data = get_doc_handler_data!(a_this);

    if a_name.is_null() || a_expression.is_null() || handler_data.selector.is_null() {
        return;
    }

    let mut cur_sel = handler_data.selector;
    while !cur_sel.is_null() {
        let simple_sel = (*cur_sel).simple_sel;

        if !simple_sel.is_null() {
            let raw_selector_name = cr_simple_sel_to_string(simple_sel) as *mut libc::c_char;

            if !raw_selector_name.is_null() {
                let raw_prop_name = cr_string_peek_raw_str(a_name);
                let prop_name = utf8_cstr(raw_prop_name);

                let prop_value =
                    <String as FromGlibPtrFull<_>>::from_glib_full(cr_term_to_string(a_expression));

                let selector_name =
                    <String as FromGlibPtrFull<_>>::from_glib_full(raw_selector_name);

                let important = from_glib(a_is_important);

                handler_data
                    .css_rules
                    .define(&selector_name, prop_name, &prop_value, important);
            }
        }

        cur_sel = (*cur_sel).next;
    }
}

unsafe extern "C" fn css_error(_a_this: *mut CRDocHandler) {
    println!("CSS parsing error");
}

unsafe extern "C" fn css_unrecoverable_error(_a_this: *mut CRDocHandler) {
    println!("CSS unrecoverable error");
}
<|endoftext|>


<commit_before>use core::arch::x86_64 as arch;
use rand::prelude::*;
use std::env;
use std::f64::consts::PI;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::net::{TcpListener, TcpStream};
use std::str;
use std::thread;
use std::time::Instant;
use std::vec;

mod laplace;
mod matmul;

pub use matmul::test_matmul_strassen;

pub fn random_number() -> Result<(), ()> {
	let mut rng = rand::thread_rng();
	let y: f64 = rng.gen(); // generates a float between 0 and 1

	println!("random: {}", y);

	Ok(())
}

#[inline]
fn get_timestamp_rdtscp() -> u64 {
	unsafe {
		let mut _aux = 0;
		let value = arch::__rdtscp(&mut _aux);
		arch::_mm_lfence();
		value
	}
}

pub fn thread_creation() -> Result<(), ()> {
	const N: usize = 1000;

	// cache warmup
	let _ = get_timestamp_rdtscp();

	let start = get_timestamp_rdtscp();
	let mut end: u64 = 0;
	for _ in 0..N {
		let builder = thread::Builder::new();
		let child = builder.spawn(|| get_timestamp_rdtscp()).unwrap();
		thread::yield_now();
		match child.join() {
			Ok(ret) => {
				end = ret;
			}
			Err(_) => {
				println!("Unable to join thread!");
			}
		}
	}

	println!("Time to create a thread {} ticks", (end - start) / N as u64);

	Ok(())
}

pub fn bench_sched_one_thread() -> Result<(), ()> {
	let n = 1000000;

	// cache warmup
	thread::yield_now();
	thread::yield_now();
	let _ = get_timestamp_rdtscp();

	let start = get_timestamp_rdtscp();
	for _ in 0..n {
		thread::yield_now();
	}
	let ticks = get_timestamp_rdtscp() - start;

	println!("Scheduling time {} ticks (1 thread)", ticks / n);

	Ok(())
}

pub fn bench_sched_two_threads() -> Result<(), ()> {
	let n = 1000000;
	let nthreads = 2;

	// cache warmup
	thread::yield_now();
	thread::yield_now();
	let _ = get_timestamp_rdtscp();

	let start = get_timestamp_rdtscp();
	let threads: Vec<_> = (0..nthreads - 1)
		.map(|_| {
			thread::spawn(move || {
				for _ in 0..n {
					thread::yield_now();
				}
			})
		})
		.collect();

	for _ in 0..n {
		thread::yield_now();
	}

	let ticks = get_timestamp_rdtscp() - start;

	for t in threads {
		t.join().unwrap();
	}

	println!(
		"Scheduling time {} ticks (2 threads)",
		ticks / (nthreads * n)
	);

	Ok(())
}

pub fn pi_sequential(num_steps: u64) -> Result<(), ()> {
	let step = 1.0 / num_steps as f64;
	let mut sum = 0 as f64;

	for i in 0..num_steps {
		let x = (i as f64 + 0.5) * step;
		sum += 4.0 / (1.0 + x * x);
	}

	let mypi = sum * (1.0 / num_steps as f64);
	println!("Pi: {} (sequential)", mypi);

	if (mypi - PI).abs() < 0.00001 {
		Ok(())
	} else {
		Err(())
	}
}

pub fn pi_parallel(nthreads: u64, num_steps: u64) -> Result<(), ()> {
	let step = 1.0 / num_steps as f64;
	let mut sum = 0.0 as f64;

	let threads: Vec<_> = (0..nthreads)
		.map(|tid| {
			thread::spawn(move || {
				let mut partial_sum = 0 as f64;
				let start = (num_steps / nthreads) * tid;
				let end = (num_steps / nthreads) * (tid + 1);

				for i in start..end {
					let x = (i as f64 + 0.5) * step;
					partial_sum += 4.0 / (1.0 + x * x);
				}

				partial_sum
			})
		})
		.collect();

	for t in threads {
		sum += t.join().unwrap();
	}

	let mypi = sum * (1.0 / num_steps as f64);
	println!("Pi: {} (with {} threads)", mypi, nthreads);

	if (mypi - PI).abs() < 0.00001 {
		Ok(())
	} else {
		Err(())
	}
}

pub fn read_file() -> Result<(), std::io::Error> {
	let mut file = File::open("/etc/hostname")?;
	let mut contents = String::new();
	file.read_to_string(&mut contents)?;

	println!("Hostname: {}", contents);

	Ok(())
}

pub fn create_file() -> Result<(), std::io::Error> {
	{
		let mut file = File::create("/tmp/foo.txt")?;
		file.write_all(b"Hello, world!")?;
	}

	let contents = {
		let mut file = File::open("/tmp/foo.txt")?;
		let mut contents = String::new();
		file.read_to_string(&mut contents)?;
		contents
	};

	// delete temporary file
	std::fs::remove_file("/tmp/foo.txt")?;

	if contents == "Hello, world!" {
		Ok(())
	} else {
		let kind = std::io::ErrorKind::Other;
		Err(std::io::Error::from(kind))
	}
}

pub fn print_argv() -> Result<(), ()> {
	let args = env::args();

	// Prints each argument on a separate line
	for (i, argument) in args.enumerate() {
		println!("argument[{}] = {}", i, argument);
	}

	Ok(())
}

pub fn print_env() -> Result<(), ()> {
	let envs = env::vars();

	// We will iterate through the references to the element returned by
	// env::vars();
	for (key, value) in envs {
		println!("{}: {}", key, value);
	}

	Ok(())
}

pub fn hello() -> Result<(), ()> {
	println!("Hello, world!");

	Ok(())
}

pub fn threading() -> Result<(), ()> {
	// Make a vector to hold the children which are spawned.
	let mut children = vec![];

	for i in 0..2 {
		// Spin up another thread
		children.push(thread::spawn(move || {
			println!("this is thread number {}", i);
		}));
	}

	for child in children {
		// Wait for the thread to finish. Returns a result.
		let _ = child.join();
	}

	Ok(())
}

pub fn laplace(size_x: usize, size_y: usize) -> Result<(), ()> {
	let matrix = matrix_setup(size_x, size_y);

	let now = Instant::now();
	let (iterations, res) = laplace::compute(matrix, size_x, size_y);
	println!(
		"Time to solve {} s, iterations {}, residuum {}",
		now.elapsed().as_secs_f64(),
		iterations,
		res
	);

	if res < 0.01 {
		Ok(())
	} else {
		Err(())
	}
}

pub fn matrix_setup(size_x: usize, size_y: usize) -> vec::Vec<vec::Vec<f64>> {
	let mut matrix = vec![vec![0.0; size_x * size_y]; 2];

	// top row
	for x in 0..size_x {
		matrix[0][x] = 1.0;
		matrix[1][x] = 1.0;
	}

	// bottom row
	for x in 0..size_x {
		matrix[0][(size_y - 1) * size_x + x] = 1.0;
		matrix[1][(size_y - 1) * size_x + x] = 1.0;
	}

	// left row
	for y in 0..size_y {
		matrix[0][y * size_x] = 1.0;
		matrix[1][y * size_x] = 1.0;
	}

	// right row
	for y in 0..size_y {
		matrix[0][y * size_x + size_x - 1] = 1.0;
		matrix[1][y * size_x + size_x - 1] = 1.0;
	}

	matrix
}

fn send_http_rquest() -> Result<Vec<u8>, std::io::Error> {
	let mut stream = TcpStream::connect("10.0.5.1:7878")?;
	let buf =
		b"GET / HTTP/1.1\r\nHost: 10.0.5.1\r\nUser-Agent: hermit/0.3.16\r\nAccept: */*\r\n\r\n";
	stream.write_all(buf)?;

	let mut buf = Vec::new();
	stream.read_to_end(&mut buf)?;

	Ok(buf)
}

pub fn test_http_request() -> Result<(), std::io::Error> {
	let buf = send_http_rquest()?;
	let data = str::from_utf8(&buf).unwrap().to_owned();

	//println!("Receive {}", data);

	match data.starts_with("HTTP/1.1 200 OK") {
		true => println!("Check http response... ok"),
		_ => println!("Check http response... failed!"),
	};

	Ok(())
}
<commit_msg>revise benchmark, measure thread create + join time<commit_after>use core::arch::x86_64 as arch;
use rand::prelude::*;
use std::env;
use std::f64::consts::PI;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::net::{TcpListener, TcpStream};
use std::str;
use std::thread;
use std::time::Instant;
use std::vec;

mod laplace;
mod matmul;

pub use matmul::test_matmul_strassen;

pub fn random_number() -> Result<(), ()> {
	let mut rng = rand::thread_rng();
	let y: f64 = rng.gen(); // generates a float between 0 and 1

	println!("random: {}", y);

	Ok(())
}

#[inline]
fn get_timestamp_rdtscp() -> u64 {
	unsafe {
		let mut _aux = 0;
		let value = arch::__rdtscp(&mut _aux);
		arch::_mm_lfence();
		value
	}
}

pub fn thread_creation() -> Result<(), ()> {
	const N: usize = 1000;

	// cache warmup
	let _ = get_timestamp_rdtscp();

	let start = get_timestamp_rdtscp();
	for _ in 0..N {
		let builder = thread::Builder::new();
		let child = builder.spawn(|| { }).unwrap();
		let _ = child.join();
	}
	let end = get_timestamp_rdtscp();

	println!("Time to create and to join a thread: {} ticks", (end - start) / N as u64);

	Ok(())
}

pub fn bench_sched_one_thread() -> Result<(), ()> {
	let n = 1000000;

	// cache warmup
	thread::yield_now();
	thread::yield_now();
	let _ = get_timestamp_rdtscp();

	let start = get_timestamp_rdtscp();
	for _ in 0..n {
		thread::yield_now();
	}
	let ticks = get_timestamp_rdtscp() - start;

	println!("Scheduling time {} ticks (1 thread)", ticks / n);

	Ok(())
}

pub fn bench_sched_two_threads() -> Result<(), ()> {
	let n = 1000000;
	let nthreads = 2;

	// cache warmup
	thread::yield_now();
	thread::yield_now();
	let _ = get_timestamp_rdtscp();

	let start = get_timestamp_rdtscp();
	let threads: Vec<_> = (0..nthreads - 1)
		.map(|_| {
			thread::spawn(move || {
				for _ in 0..n {
					thread::yield_now();
				}
			})
		})
		.collect();

	for _ in 0..n {
		thread::yield_now();
	}

	let ticks = get_timestamp_rdtscp() - start;

	for t in threads {
		t.join().unwrap();
	}

	println!(
		"Scheduling time {} ticks (2 threads)",
		ticks / (nthreads * n)
	);

	Ok(())
}

pub fn pi_sequential(num_steps: u64) -> Result<(), ()> {
	let step = 1.0 / num_steps as f64;
	let mut sum = 0 as f64;

	for i in 0..num_steps {
		let x = (i as f64 + 0.5) * step;
		sum += 4.0 / (1.0 + x * x);
	}

	let mypi = sum * (1.0 / num_steps as f64);
	println!("Pi: {} (sequential)", mypi);

	if (mypi - PI).abs() < 0.00001 {
		Ok(())
	} else {
		Err(())
	}
}

pub fn pi_parallel(nthreads: u64, num_steps: u64) -> Result<(), ()> {
	let step = 1.0 / num_steps as f64;
	let mut sum = 0.0 as f64;

	let threads: Vec<_> = (0..nthreads)
		.map(|tid| {
			thread::spawn(move || {
				let mut partial_sum = 0 as f64;
				let start = (num_steps / nthreads) * tid;
				let end = (num_steps / nthreads) * (tid + 1);

				for i in start..end {
					let x = (i as f64 + 0.5) * step;
					partial_sum += 4.0 / (1.0 + x * x);
				}

				partial_sum
			})
		})
		.collect();

	for t in threads {
		sum += t.join().unwrap();
	}

	let mypi = sum * (1.0 / num_steps as f64);
	println!("Pi: {} (with {} threads)", mypi, nthreads);

	if (mypi - PI).abs() < 0.00001 {
		Ok(())
	} else {
		Err(())
	}
}

pub fn read_file() -> Result<(), std::io::Error> {
	let mut file = File::open("/etc/hostname")?;
	let mut contents = String::new();
	file.read_to_string(&mut contents)?;

	println!("Hostname: {}", contents);

	Ok(())
}

pub fn create_file() -> Result<(), std::io::Error> {
	{
		let mut file = File::create("/tmp/foo.txt")?;
		file.write_all(b"Hello, world!")?;
	}

	let contents = {
		let mut file = File::open("/tmp/foo.txt")?;
		let mut contents = String::new();
		file.read_to_string(&mut contents)?;
		contents
	};

	// delete temporary file
	std::fs::remove_file("/tmp/foo.txt")?;

	if contents == "Hello, world!" {
		Ok(())
	} else {
		let kind = std::io::ErrorKind::Other;
		Err(std::io::Error::from(kind))
	}
}

pub fn print_argv() -> Result<(), ()> {
	let args = env::args();

	// Prints each argument on a separate line
	for (i, argument) in args.enumerate() {
		println!("argument[{}] = {}", i, argument);
	}

	Ok(())
}

pub fn print_env() -> Result<(), ()> {
	let envs = env::vars();

	// We will iterate through the references to the element returned by
	// env::vars();
	for (key, value) in envs {
		println!("{}: {}", key, value);
	}

	Ok(())
}

pub fn hello() -> Result<(), ()> {
	println!("Hello, world!");

	Ok(())
}

pub fn threading() -> Result<(), ()> {
	// Make a vector to hold the children which are spawned.
	let mut children = vec![];

	for i in 0..2 {
		// Spin up another thread
		children.push(thread::spawn(move || {
			println!("this is thread number {}", i);
		}));
	}

	for child in children {
		// Wait for the thread to finish. Returns a result.
		let _ = child.join();
	}

	Ok(())
}

pub fn laplace(size_x: usize, size_y: usize) -> Result<(), ()> {
	let matrix = matrix_setup(size_x, size_y);

	let now = Instant::now();
	let (iterations, res) = laplace::compute(matrix, size_x, size_y);
	println!(
		"Time to solve {} s, iterations {}, residuum {}",
		now.elapsed().as_secs_f64(),
		iterations,
		res
	);

	if res < 0.01 {
		Ok(())
	} else {
		Err(())
	}
}

pub fn matrix_setup(size_x: usize, size_y: usize) -> vec::Vec<vec::Vec<f64>> {
	let mut matrix = vec![vec![0.0; size_x * size_y]; 2];

	// top row
	for x in 0..size_x {
		matrix[0][x] = 1.0;
		matrix[1][x] = 1.0;
	}

	// bottom row
	for x in 0..size_x {
		matrix[0][(size_y - 1) * size_x + x] = 1.0;
		matrix[1][(size_y - 1) * size_x + x] = 1.0;
	}

	// left row
	for y in 0..size_y {
		matrix[0][y * size_x] = 1.0;
		matrix[1][y * size_x] = 1.0;
	}

	// right row
	for y in 0..size_y {
		matrix[0][y * size_x + size_x - 1] = 1.0;
		matrix[1][y * size_x + size_x - 1] = 1.0;
	}

	matrix
}

fn send_http_rquest() -> Result<Vec<u8>, std::io::Error> {
	let mut stream = TcpStream::connect("10.0.5.1:7878")?;
	let buf =
		b"GET / HTTP/1.1\r\nHost: 10.0.5.1\r\nUser-Agent: hermit/0.3.16\r\nAccept: */*\r\n\r\n";
	stream.write_all(buf)?;

	let mut buf = Vec::new();
	stream.read_to_end(&mut buf)?;

	Ok(buf)
}

pub fn test_http_request() -> Result<(), std::io::Error> {
	let buf = send_http_rquest()?;
	let data = str::from_utf8(&buf).unwrap().to_owned();

	//println!("Receive {}", data);

	match data.starts_with("HTTP/1.1 200 OK") {
		true => println!("Check http response... ok"),
		_ => println!("Check http response... failed!"),
	};

	Ok(())
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate eve;

use std::env;
use std::fs::OpenOptions;

use eve::server::*;

#[test]
fn test_examples() {
    let inputs = walk_dir("./test-inputs").unwrap().collect::<Vec<_>>();
    let outputs = walk_dir("./test-outputs").unwrap().collect::<Vec<_>>();
    assert_eq!(inputs.len(), outputs.len());
    for (input_entry, output_entry) in inputs.into_iter().zip(outputs.into_iter()) {
        let input_filename = input_entry.unwrap().path().to_str().unwrap().to_owned();
        let output_filename = output_entry.unwrap().path().to_str().unwrap().to_owned();
        println!("Testing {:?} against {:?}", input_filename, output_filename);
        let flow = load(&input_filename[..]);
        let mut output_string = String::new();
        let mut output_file = OpenOptions::new().open(output_filename).unwrap();
        output_file.read_to_string(&mut output_string).unwrap();
        let output = Json::from_str(&output_string).unwrap();
        for (view_id, json) in output.as_object().unwrap().iter() {
            let test_rows: Vec<Vec<Value>> = flow.get_output(&view_id[..]).index.clone().into_iter().collect();
            let output_rows: Vec<Vec<Value>> = FromJson::from_json(json);
            assert_eq!(test_rows, output_rows);
        }
    }
}

#[allow(dead_code)]
fn main() {
	for argument in env::args() {
    	match &*argument {
    		"clean" => {
    			OpenOptions::new().create(true).truncate(true).open("./events").unwrap();
    			()
    		},
    		_ => continue,
    	}
	}

    run()
}<commit_msg>Revert "Fix warnings"<commit_after>#![feature(fs_walk)]

extern crate rustc_serialize;
extern crate eve;

use std::env;
use std::fs::{OpenOptions, walk_dir};
use std::io::prelude::*;
use rustc_serialize::json::Json;

use eve::server::*;
use eve::value::*;

#[test]
fn test_examples() {
    let inputs = walk_dir("./test-inputs").unwrap().collect::<Vec<_>>();
    let outputs = walk_dir("./test-outputs").unwrap().collect::<Vec<_>>();
    assert_eq!(inputs.len(), outputs.len());
    for (input_entry, output_entry) in inputs.into_iter().zip(outputs.into_iter()) {
        let input_filename = input_entry.unwrap().path().to_str().unwrap().to_owned();
        let output_filename = output_entry.unwrap().path().to_str().unwrap().to_owned();
        println!("Testing {:?} against {:?}", input_filename, output_filename);
        let flow = load(&input_filename[..]);
        let mut output_string = String::new();
        let mut output_file = OpenOptions::new().open(output_filename).unwrap();
        output_file.read_to_string(&mut output_string).unwrap();
        let output = Json::from_str(&output_string).unwrap();
        for (view_id, json) in output.as_object().unwrap().iter() {
            let test_rows: Vec<Vec<Value>> = flow.get_output(&view_id[..]).index.clone().into_iter().collect();
            let output_rows: Vec<Vec<Value>> = FromJson::from_json(json);
            assert_eq!(test_rows, output_rows);
        }
    }
}

#[allow(dead_code)]
fn main() {
	for argument in env::args() {
    	match &*argument {
    		"clean" => {
    			OpenOptions::new().create(true).truncate(true).open("./events").unwrap();
    			()
    		},
    		_ => continue,
    	}
	}

    run()
}<|endoftext|>


<commit_before>// #![ warn( missing_docs ) ]
// #![ warn( missing_debug_implementations ) ]

use former::Former;

///
/// Either delimeter or delimeted with the slice on its string.
///

#[ derive( Debug ) ]
pub struct Split< 'a >
{
  string : &'a str,
  typ : SplitType,
}

impl< 'a > From< Split< 'a > > for String
{
  fn from( src : Split ) -> Self
  {
    src.string.into()
  }
}

///
/// Either delimeter or delimeted
///

#[ derive( Debug ) ]
pub enum SplitType
{
  /// Substring of the original string with text inbetween delimeters.
  Delimeted,
  /// Delimeter.
  Delimeter,
}

///
/// Split iterator.
///

#[ derive( Debug ) ]
pub struct SplitIterator< 'a >
{
  iterator : std::iter::Peekable< std::str::Split< 'a, &'a str > >,
  counter : i32,
  delimeter : &'a str,
}

//

impl< 'a > SplitIterator< 'a >
{
  fn new( src : &'a str, delimeter : &'a str ) -> Self
  {
    let counter = 0;
    // let delimeter = delimeter.clone();
    let delimeter_slice = unsafe
    {
      let slice = core::slice::from_raw_parts( delimeter.as_ptr(), delimeter.len() );
      core::str::from_utf8_unchecked( slice )
    };
    let iterator = src.split( delimeter_slice ).peekable();
    Self
    {
      iterator,
      delimeter,
      counter,
    }
  }
}

//

impl< 'a > Iterator for SplitIterator< 'a >
{
  type Item = Split< 'a >;

  fn next( &mut self ) -> Option< Self::Item >
  {
    self.counter += 1;
    if self.counter % 2 == 1
    {
      let next = self.iterator.next();
      if let Some( next ) = next
      {
        Some( Split { string : next, typ : SplitType::Delimeted } )
      }
      else
      {
        None
      }
    }
    else
    {
      if self.iterator.peek().is_none()
      {
        self.iterator.next();
        return None;
      }
      Some( Split { string : self.delimeter, typ : SplitType::Delimeter } )
      // Some( Split::Delimeter( self.delimeter.clone() ) )
    }
  }
}

///
/// Options of function split.
///

#[ derive( Debug ) ]
#[ derive( Former ) ]
#[ form_after( fn split( self ) -> SplitIterator< 'a > ) ]
pub struct SplitOptions< 'a >
{

  #[ default( "" ) ]
  src : &'a str,
  #[ default( "" ) ]
  delimeter : &'a str,
  #[ default( true ) ]
  preserving_empty : bool,
  #[ default( true ) ]
  preserving_delimeters : bool,

  // #[ method ]
  // fn split( self ) -> SplitIterator< 'a >
  // where
  //   Self : Sized,
  // {
  //   SplitIterator::new( self.src(), self.delimeter() )
  // }

  // result : HashMap< Box< str >, Box< str > >,
}

///
/// Adapter for Split Options.
///

pub trait SplitOptionsAdapter< 'a >
{
  /// A string to split.
  fn src( &self ) -> &'a str;
  /// A delimeter to split string.
  fn delimeter( &self ) -> &'a str;
  /// Preserving or dropping empty splits.
  fn preserving_empty( &self ) -> bool;
  /// Preserving or dropping delimeters.
  fn preserving_delimeters( &self ) -> bool;
  /// Do splitting.
  fn split( self ) -> SplitIterator< 'a >
  where
    Self : Sized,
  {
    SplitIterator::new( self.src(), self.delimeter() )
  }
}

//

impl< 'a > SplitOptionsAdapter< 'a > for SplitOptions< 'a >
{
  fn src( &self ) -> &'a str
  {
    self.src
  }
  fn delimeter( &self ) -> &'a str
  {
    self.delimeter
  }
  fn preserving_empty( &self ) -> bool
  {
    self.preserving_empty
  }
  fn preserving_delimeters( &self ) -> bool
  {
    self.preserving_delimeters
  }
}

///
/// Function to split a string.
///
/// It produces former. To convert former into options and run algorithm of splitting call `form()`.
///
/// # Sample
/// ```
///   let iter = wstring_tools::string::split()
///   .src( "abc def" )
///   .delimeter( " " )
///   .form();
/// ```

pub fn split< 'a >() -> SplitOptionsFormer< 'a >
{
  SplitOptions::former()
}
<commit_msg>Extend `SplitIterator` by options, extend behavior of iterator<commit_after>// #![ warn( missing_docs ) ]
// #![ warn( missing_debug_implementations ) ]

use former::Former;

///
/// Either delimeter or delimeted with the slice on its string.
///

#[ derive( Debug ) ]
pub struct Split< 'a >
{
  string : &'a str,
  typ : SplitType,
}

impl< 'a > From< Split< 'a > > for String
{
  fn from( src : Split ) -> Self
  {
    src.string.into()
  }
}

///
/// Either delimeter or delimeted
///

#[ derive( Debug ) ]
pub enum SplitType
{
  /// Substring of the original string with text inbetween delimeters.
  Delimeted,
  /// Delimeter.
  Delimeter,
}

///
/// Split iterator.
///

#[ derive( Debug ) ]
pub struct SplitIterator< 'a >
{
  iterator : std::iter::Peekable< std::str::Split< 'a, &'a str > >,
  counter : i32,
  delimeter : &'a str,
  preserving_empty : bool,
  preserving_delimeters : bool,
  stripping : bool,
}

//

impl< 'a > SplitIterator< 'a >
{
  fn new
  (
    src : &'a str,
    delimeter : &'a str,
    preserving_empty : bool,
    preserving_delimeters : bool,
    stripping : bool
  ) -> Self
  {
    let counter = 0;
    // let delimeter = delimeter.clone();
    let delimeter_slice = unsafe
    {
      let slice = core::slice::from_raw_parts( delimeter.as_ptr(), delimeter.len() );
      core::str::from_utf8_unchecked( slice )
    };
    let iterator = src.split( delimeter_slice ).peekable();
    Self
    {
      iterator,
      delimeter,
      counter,
      preserving_empty,
      preserving_delimeters,
      stripping,
    }
  }
}

//

impl< 'a > Iterator for SplitIterator< 'a >
{
  type Item = Split< 'a >;

  fn next( &mut self ) -> Option< Self::Item >
  {
    self.counter += 1;

    if self.counter % 2 == 1
    {
      let next = self.iterator.next();
      if let Some( mut next ) = next
      {
        if self.stripping
        {
          next = next.trim();
        }

        Some( Split { string : next, typ : SplitType::Delimeted } )
      }
      else
      {
        None
      }
    }
    else
    {
      if self.iterator.peek().is_none()
      {
        self.iterator.next();
        return None;
      }

      let mut string = self.delimeter;

      if self.stripping
      {
        string = string.trim();
      }

      if !self.preserving_empty
      {
        if string.is_empty()
        {
          return Some( Split { string : self.iterator.next().unwrap(), typ : SplitType::Delimeted } );
        }
      }

      if self.preserving_delimeters
      {
        return Some( Split { string, typ : SplitType::Delimeter } );
      }

      Some( Split { string : self.iterator.next().unwrap(), typ : SplitType::Delimeted } )
    }
  }
}

///
/// Options of function split.
///

#[ derive( Debug ) ]
#[ derive( Former ) ]
#[ form_after( fn split( self ) -> SplitIterator< 'a > ) ]
pub struct SplitOptions< 'a >
{

  #[ default( "" ) ]
  src : &'a str,
  #[ default( "" ) ]
  delimeter : &'a str,
  #[ default( true ) ]
  preserving_empty : bool,
  #[ default( true ) ]
  preserving_delimeters : bool,
  #[ default( true ) ]
  stripping : bool,

  // #[ method ]
  // fn split( self ) -> SplitIterator< 'a >
  // where
  //   Self : Sized,
  // {
  //   SplitIterator::new( self.src(), self.delimeter() )
  // }

  // result : HashMap< Box< str >, Box< str > >,
}

///
/// Adapter for Split Options.
///

pub trait SplitOptionsAdapter< 'a >
{
  /// A string to split.
  fn src( &self ) -> &'a str;
  /// A delimeter to split string.
  fn delimeter( &self ) -> &'a str;
  /// Preserving or dropping empty splits.
  fn preserving_empty( &self ) -> bool;
  /// Preserving or dropping delimeters.
  fn preserving_delimeters( &self ) -> bool;
  /// Stripping.
  fn stripping( &self ) -> bool;
  /// Do splitting.
  fn split( self ) -> SplitIterator< 'a >
  where
    Self : Sized,
  {
    SplitIterator::new
    (
      self.src(),
      self.delimeter(),
      self.preserving_empty(),
      self.preserving_delimeters(),
      self.stripping()
    )
  }
}

//

impl< 'a > SplitOptionsAdapter< 'a > for SplitOptions< 'a >
{
  fn src( &self ) -> &'a str
  {
    self.src
  }
  fn delimeter( &self ) -> &'a str
  {
    self.delimeter
  }
  fn preserving_empty( &self ) -> bool
  {
    self.preserving_empty
  }
  fn preserving_delimeters( &self ) -> bool
  {
    self.preserving_delimeters
  }
  fn stripping( &self ) -> bool
  {
    self.stripping
  }
}

///
/// Function to split a string.
///
/// It produces former. To convert former into options and run algorithm of splitting call `form()`.
///
/// # Sample
/// ```
///   let iter = wstring_tools::string::split()
///   .src( "abc def" )
///   .delimeter( " " )
///   .form();
/// ```

pub fn split< 'a >() -> SplitOptionsFormer< 'a >
{
  SplitOptions::former()
}
<|endoftext|>


<commit_before>//https://rust-lang.github.io/book/ch04-04-slices.html

fn first_word(s: &String) -> usize {

    // Since we need to go through the String element by element, and
    // check if a value is a space, we will convert our String to an
    // array of bytes, using the `.as_bytes()` method.
    let bytes = s.as_bytes();

    // We discussed using the iter() method with for in Chapter 3.7. Here,
    // we’re adding another method: enumerate(). While iter() returns each
    // element, enumerate() modifies the result of iter(), and returns a
    // tuple instead. The first element of the tuple is the index, and the
    // second element is a reference to the element itself. This is a bit
    // nicer than calculating the index ourselves.
    //
    // Since it’s a tuple, we can use patterns, just like elsewhere in Rust.
    // So we match against the tuple with i for the index, and &byte for
    // the byte itself.
    //for (i, &byte) in bytes.iter().enumerate() {
    let heart = '❤';//lol wait, outdated doc? https://doc.rust-lang.org/std/primitive.char.html#representation
    println!("{}", heart);//yup, looks like it - rust nightly can do this.
    //let heart2 = '❤'; //oh, wait - nevermind! I guess this looks the same but it's different!!! - aka this errors!
    for (i, chr) in s.chars().enumerate() {

        //println!("Processing {} {}",i,byte);
        println!("Processing {} {}",i,chr);
        // 32 is the value of a space in UTF-8
        //if chr == 0x20 {
        if chr == '\u{0020}' {

            // We found a space! Return this position.
            return i;
        }
    }

    // If we got here, we didn’t find a space, so this whole thing must be a
    // word. So return the length.
    s.len()
}

fn main() {
    //ok, apparently 0x20 isn't part of any unicode char seen as utf-8 as far as i tested until
    //here(not all):
    //http://www.utf8-chartable.de/unicode-utf8-table.pl?start=121856&number=1024&utf8=0x
    //about to search here next(as soon as internet is back):
    //http://www.fileformat.info/search/search.htm?q=0x20
    //ok this explains it: http://www.joelonsoftware.com/articles/Unicode.html
    //since high bits are always at least 10, there won't be any 0x20 dangling around as part of
    //the utf8 represented unicode - except 0x20 itself :D
    let s=String::from("❤Ԡ123԰4Ġ❤we❤ll❤ok");//ok this last ❤ is one codepoint!!!
    //❤ is two unicode code points which is why you'll see a blank after it!
    //src: https://doc.rust-lang.org/std/primitive.char.html
    let word = first_word(&s);
    // word is now totally invalid! There’s no more word here.
    println!("{}", '\u{2764}');//since this is ... good enough for the heart!
    println!("{}", '\u{fe0f}');//why is this needed? well, ok: https://www.fileformat.info/info/unicode/char/2764/index.htm variation selector
    println!("{}",word);
}
<commit_msg>heart len<commit_after>//https://rust-lang.github.io/book/ch04-04-slices.html

fn first_word(s: &String) -> usize {

    // Since we need to go through the String element by element, and
    // check if a value is a space, we will convert our String to an
    // array of bytes, using the `.as_bytes()` method.
    let bytes = s.as_bytes();

    // We discussed using the iter() method with for in Chapter 3.7. Here,
    // we’re adding another method: enumerate(). While iter() returns each
    // element, enumerate() modifies the result of iter(), and returns a
    // tuple instead. The first element of the tuple is the index, and the
    // second element is a reference to the element itself. This is a bit
    // nicer than calculating the index ourselves.
    //
    // Since it’s a tuple, we can use patterns, just like elsewhere in Rust.
    // So we match against the tuple with i for the index, and &byte for
    // the byte itself.
    //for (i, &byte) in bytes.iter().enumerate() {
    let heart = '❤';//lol wait, outdated doc? https://doc.rust-lang.org/std/primitive.char.html#representation
    println!("{}", heart);//yup, looks like it - rust nightly can do this.
    //let heart2 = '❤'; //oh, wait - nevermind! I guess this looks the same but it's different!!! - aka this errors!
    for (i, chr) in s.chars().enumerate() {

        //println!("Processing {} {}",i,byte);
        println!("Processing {} {}",i,chr);
        // 32 is the value of a space in UTF-8
        //if chr == 0x20 {
        if chr == '\u{0020}' {

            // We found a space! Return this position.
            return i;
        }
    }

    // If we got here, we didn’t find a space, so this whole thing must be a
    // word. So return the length.
    s.len()
}

fn main() {
    //ok, apparently 0x20 isn't part of any unicode char seen as utf-8 as far as i tested until
    //here(not all):
    //http://www.utf8-chartable.de/unicode-utf8-table.pl?start=121856&number=1024&utf8=0x
    //about to search here next(as soon as internet is back):
    //http://www.fileformat.info/search/search.htm?q=0x20
    //ok this explains it: http://www.joelonsoftware.com/articles/Unicode.html
    //since high bits are always at least 10, there won't be any 0x20 dangling around as part of
    //the utf8 represented unicode - except 0x20 itself :D
    let s=String::from("❤Ԡ123԰4Ġ❤we❤ll❤ok");//ok this last ❤ is one codepoint!!!
    //❤ is two unicode code points which is why you'll see a blank after it!
    //src: https://doc.rust-lang.org/std/primitive.char.html
    let word = first_word(&s);
    // word is now totally invalid! There’s no more word here.
    println!("{}", '\u{2764}');//since this is ... good enough for the heart!
    println!("{}", '\u{fe0f}');//why is this needed? well, ok: https://www.fileformat.info/info/unicode/char/2764/index.htm variation selector
    println!("{}",word);
    println!("heart.len {}",String::from("❤").len());//6
}
<|endoftext|>


<commit_before>//! Error handling utilities.

use CL::*;
use std::fmt::{Show, Formatter, Result};

impl Show for CLStatus {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f.buf, "{:?}", *self)
    }
}

macro_rules! convert(
    ($e: expr, $x: ident) => (if $e == $x as cl_int {
        Some($x)
    } else { None });

    ($e: expr, $x: ident, $($xs: ident),+) => (if $e == $x as cl_int {
        Some($x)
    } else { convert!($e, $($xs),+) })
)

pub fn try_convert(status: cl_int) -> Option<CLStatus> {
    convert!(status,
             CL_SUCCESS,
             CL_DEVICE_NOT_FOUND,
             CL_DEVICE_NOT_AVAILABLE,
             CL_COMPILER_NOT_AVAILABLE,
             CL_MEM_OBJECT_ALLOCATION_FAILURE,
             CL_OUT_OF_RESOURCES,
             CL_OUT_OF_HOST_MEMORY,
             CL_PROFILING_INFO_NOT_AVAILABLE,
             CL_MEM_COPY_OVERLAP,
             CL_IMAGE_FORMAT_MISMATCH,
             CL_IMAGE_FORMAT_NOT_SUPPORTED,
             CL_BUILD_PROGRAM_FAILURE,
             CL_MAP_FAILURE,
             CL_MISALIGNED_SUB_BUFFER_OFFSET,
             CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST,
             CL_INVALID_VALUE,
             CL_INVALID_DEVICE_TYPE,
             CL_INVALID_PLATFORM,
             CL_INVALID_DEVICE,
             CL_INVALID_CONTEXT,
             CL_INVALID_QUEUE_PROPERTIES,
             CL_INVALID_COMMAND_QUEUE,
             CL_INVALID_HOST_PTR,
             CL_INVALID_MEM_OBJECT,
             CL_INVALID_IMAGE_FORMAT_DESCRIPTOR,
             CL_INVALID_IMAGE_SIZE,
             CL_INVALID_SAMPLER,
             CL_INVALID_BINARY,
             CL_INVALID_BUILD_OPTIONS,
             CL_INVALID_PROGRAM,
             CL_INVALID_PROGRAM_EXECUTABLE,
             CL_INVALID_KERNEL_NAME,
             CL_INVALID_KERNEL_DEFINITION,
             CL_INVALID_KERNEL,
             CL_INVALID_ARG_INDEX,
             CL_INVALID_ARG_VALUE,
             CL_INVALID_ARG_SIZE,
             CL_INVALID_KERNEL_ARGS,
             CL_INVALID_WORK_DIMENSION,
             CL_INVALID_WORK_GROUP_SIZE,
             CL_INVALID_WORK_ITEM_SIZE,
             CL_INVALID_GLOBAL_OFFSET,
             CL_INVALID_EVENT_WAIT_LIST,
             CL_INVALID_EVENT,
             CL_INVALID_OPERATION,
             CL_INVALID_GL_OBJECT,
             CL_INVALID_BUFFER_SIZE,
             CL_INVALID_MIP_LEVEL,
             CL_INVALID_GLOBAL_WORK_SIZE,
             CL_INVALID_PROPERTY)
}

pub fn convert(status: cl_int) -> CLStatus {
    match try_convert(status) {
        Some(s) => s,
        None => fail!(format!("Uknown OpenCL Status Code: {:?}", status))
    }
}

fn error_str(status: cl_int) -> ~str {
    match try_convert(status) {
        Some(s) => s.to_str(),
        None => format!("Unknown Error: {:?}", status)
    }
}

pub fn check(status: cl_int, message: &str) {
    if status != CL_SUCCESS as cl_int {
        fail!(format!("{:?} ({:?})", message, error_str(status)))
    }
}
<commit_msg>Fix typo in error message<commit_after>//! Error handling utilities.

use CL::*;
use std::fmt::{Show, Formatter, Result};

impl Show for CLStatus {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f.buf, "{:?}", *self)
    }
}

macro_rules! convert(
    ($e: expr, $x: ident) => (if $e == $x as cl_int {
        Some($x)
    } else { None });

    ($e: expr, $x: ident, $($xs: ident),+) => (if $e == $x as cl_int {
        Some($x)
    } else { convert!($e, $($xs),+) })
)

pub fn try_convert(status: cl_int) -> Option<CLStatus> {
    convert!(status,
             CL_SUCCESS,
             CL_DEVICE_NOT_FOUND,
             CL_DEVICE_NOT_AVAILABLE,
             CL_COMPILER_NOT_AVAILABLE,
             CL_MEM_OBJECT_ALLOCATION_FAILURE,
             CL_OUT_OF_RESOURCES,
             CL_OUT_OF_HOST_MEMORY,
             CL_PROFILING_INFO_NOT_AVAILABLE,
             CL_MEM_COPY_OVERLAP,
             CL_IMAGE_FORMAT_MISMATCH,
             CL_IMAGE_FORMAT_NOT_SUPPORTED,
             CL_BUILD_PROGRAM_FAILURE,
             CL_MAP_FAILURE,
             CL_MISALIGNED_SUB_BUFFER_OFFSET,
             CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST,
             CL_INVALID_VALUE,
             CL_INVALID_DEVICE_TYPE,
             CL_INVALID_PLATFORM,
             CL_INVALID_DEVICE,
             CL_INVALID_CONTEXT,
             CL_INVALID_QUEUE_PROPERTIES,
             CL_INVALID_COMMAND_QUEUE,
             CL_INVALID_HOST_PTR,
             CL_INVALID_MEM_OBJECT,
             CL_INVALID_IMAGE_FORMAT_DESCRIPTOR,
             CL_INVALID_IMAGE_SIZE,
             CL_INVALID_SAMPLER,
             CL_INVALID_BINARY,
             CL_INVALID_BUILD_OPTIONS,
             CL_INVALID_PROGRAM,
             CL_INVALID_PROGRAM_EXECUTABLE,
             CL_INVALID_KERNEL_NAME,
             CL_INVALID_KERNEL_DEFINITION,
             CL_INVALID_KERNEL,
             CL_INVALID_ARG_INDEX,
             CL_INVALID_ARG_VALUE,
             CL_INVALID_ARG_SIZE,
             CL_INVALID_KERNEL_ARGS,
             CL_INVALID_WORK_DIMENSION,
             CL_INVALID_WORK_GROUP_SIZE,
             CL_INVALID_WORK_ITEM_SIZE,
             CL_INVALID_GLOBAL_OFFSET,
             CL_INVALID_EVENT_WAIT_LIST,
             CL_INVALID_EVENT,
             CL_INVALID_OPERATION,
             CL_INVALID_GL_OBJECT,
             CL_INVALID_BUFFER_SIZE,
             CL_INVALID_MIP_LEVEL,
             CL_INVALID_GLOBAL_WORK_SIZE,
             CL_INVALID_PROPERTY)
}

pub fn convert(status: cl_int) -> CLStatus {
    match try_convert(status) {
        Some(s) => s,
        None => fail!(format!("Unknown OpenCL Status Code: {:?}", status))
    }
}

fn error_str(status: cl_int) -> ~str {
    match try_convert(status) {
        Some(s) => s.to_str(),
        None => format!("Unknown Error: {:?}", status)
    }
}

pub fn check(status: cl_int, message: &str) {
    if status != CL_SUCCESS as cl_int {
        fail!(format!("{:?} ({:?})", message, error_str(status)))
    }
}
<|endoftext|>


<commit_before>#![doc="Sorting algorithms
"]

pub mod quick_sort;
pub mod insertion_sort;

/// Returns whether the slice is sorted in ascending order or not.
pub fn is_ascending_slice<T : PartialOrd>(data : & [T]) -> bool {
    let n = data.len();
    if n == 0 {
        return true;
    }
    for i in 0..(n-1){
        if data[i] > data[i + 1]{
            return false;
        }
    }
    true
}

/// Returns whether the slice is sorted in descending order or not.
pub fn is_descending_slice<T : PartialOrd>(data : & [T]) -> bool {
    let n = data.len();
    if n == 0 {
        return true;
    }
    for i in 0..(n-1){
        if data[i] < data[i + 1]{
            return false;
        }
    }
    true
}

/// Returns whether the data in buffer is sorted in ascending order or not.
pub unsafe fn is_ascending_buffer<T : PartialOrd>(data : *const T, n : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    for _ in 0..(n-1){
        if *ptr > *ptr.offset(1){
            return false;
        }
        ptr = ptr.offset(1);
    }
    true
}

/// Returns whether the data in buffer is sorted in descending order or not.
pub unsafe fn is_descending_buffer<T : PartialOrd>(data : *const T, n : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    for _ in 0..(n-1){
        if *ptr < *ptr.offset(1){
            return false;
        }
        ptr = ptr.offset(1);
    }
    true
}

/// Returns whether the data in strided buffer is sorted in ascending order or not
/// every stride-th entry is considered in the buffer
/// assumes that the buffer as at least n* stride entries
pub unsafe fn is_ascending_buffer_strided<T : PartialOrd>(data : *const T,
    n : usize,
    stride : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    let stride = stride as isize;
    for _ in 0..(n-1){
        if *ptr > *ptr.offset(stride){
            return false;
        }
        ptr = ptr.offset(stride);
    }
    true
}

/// Returns whether the data in strided buffer is sorted in ascending order or not
/// every stride-th entry is considered in the buffer
/// assumes that the buffer as at least n* stride entries
pub unsafe fn is_descending_buffer_strided<T : PartialOrd>(data : *const T,
    n : usize,
    stride : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    let stride = stride as isize;
    for _ in 0..(n-1){
        if *ptr < *ptr.offset(stride){
            return false;
        }
        ptr = ptr.offset(stride);
    }
    true
}

/******************************************************
 *
 *   Unit tests
 *
 *******************************************************/

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

    #[test]
    fn test_is_ascending_slice(){
        let v = vec!(1i32, 2, 3, 4);
        assert!(is_ascending_slice(v.as_slice()));
        let v = vec!(1i32);
        assert!(is_ascending_slice(v.as_slice()));
        let v : Vec<i32> = vec!();
        assert!(is_ascending_slice(v.as_slice()));
        let v = vec!(2i32, 1);
        assert!(!is_ascending_slice(v.as_slice()));
        let v = vec!(3i32, 2, 1);
        assert!(!is_ascending_slice(v.as_slice()));
        let v = vec!(1i32, 3, 2);
        assert!(!is_ascending_slice(v.as_slice()));
        let v = vec!(2i32, 1, 3);
        assert!(!is_ascending_slice(v.as_slice()));
    }

    #[test]
    fn test_is_ascending_buffer(){
        unsafe {
            let v = vec!(1i32, 2, 3, 4);
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32);
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
            let v : Vec<i32> = vec!();
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(2i32, 1);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(3i32, 2, 1);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32, 3, 2);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(2i32, 1, 3);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
        }
    }

    #[test]
    fn test_is_descending_slice(){
        let v = vec!(4i32, 3, 2, 1);
        assert!(is_descending_slice(v.as_slice()));
        let v = vec!(1i32);
        assert!(is_descending_slice(v.as_slice()));
        let v : Vec<i32> = vec!();
        assert!(is_descending_slice(v.as_slice()));
        let v = vec!(1i32, 2);
        assert!(!is_descending_slice(v.as_slice()));
        let v = vec!(1i32, 2, 3);
        assert!(!is_descending_slice(v.as_slice()));
        let v = vec!(2i32, 3, 1);
        assert!(!is_descending_slice(v.as_slice()));
        let v = vec!(3i32, 1, 2);
        assert!(!is_descending_slice(v.as_slice()));
    }

    #[test]
    fn test_is_descending_buffer(){
        unsafe {
            let v = vec!(4i32, 3, 2, 1);
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32);
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
            let v : Vec<i32> = vec!();
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32, 2);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32, 2, 3);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(2i32, 3, 1);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(3i32, 1, 2);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
        }
    }

    #[test]
    fn test_is_ascending_buffer_strided(){
        unsafe {
            let v = vec!(4i32, 3, 2, 1);
            assert!(!is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
            let v = vec!(4i32, 3, 5, 1);
            assert!(is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
            let v = vec!(4i32, 1, 5, 2, 3, 7);
            assert!(!is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
            let v = vec!(4i32, 3, 5, 2, 7, 1);
            assert!(is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
        }
    }

}

/******************************************************
 *
 *   Bench marks
 *
 *******************************************************/

#[cfg(test)]
mod bench{
    extern crate test;
    use self::test::Bencher;
    use super::*;
    #[bench]
    fn bench_is_ascending_slice(b: &mut Bencher){
        let v = (0..10000).map(|idx| (20000 - idx)).collect::<Vec<i32>>();
        b.iter(|| {
            assert!(is_ascending_slice(v.as_slice()));
                });
    }
    #[bench]
    fn bench_is_ascending_buffer(b: &mut Bencher){
        let v = (0..10000).map(|idx| (20000 - idx)).collect::<Vec<i32>>();
        b.iter(|| unsafe {
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
                });
    }
    #[bench]
    fn bench_is_descending_slice(b: &mut Bencher){
        let v = (0..10000).map(|idx| (20000 - idx)).collect::<Vec<i32>>();
        b.iter(|| {
            assert!(is_descending_slice(v.as_slice()));
                });
    }
    #[bench]
    fn bench_is_descending_buffer(b: &mut Bencher){
        let v = (0..10000).map(|idx| (20000 - idx)).collect::<Vec<i32>>();
        b.iter(|| unsafe {
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
                });
    }
}

<commit_msg>Fix two tests<commit_after>#![doc="Sorting algorithms
"]

pub mod quick_sort;
pub mod insertion_sort;

/// Returns whether the slice is sorted in ascending order or not.
pub fn is_ascending_slice<T : PartialOrd>(data : & [T]) -> bool {
    let n = data.len();
    if n == 0 {
        return true;
    }
    for i in 0..(n-1){
        if data[i] > data[i + 1]{
            return false;
        }
    }
    true
}

/// Returns whether the slice is sorted in descending order or not.
pub fn is_descending_slice<T : PartialOrd>(data : & [T]) -> bool {
    let n = data.len();
    if n == 0 {
        return true;
    }
    for i in 0..(n-1){
        if data[i] < data[i + 1]{
            return false;
        }
    }
    true
}

/// Returns whether the data in buffer is sorted in ascending order or not.
pub unsafe fn is_ascending_buffer<T : PartialOrd>(data : *const T, n : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    for _ in 0..(n-1){
        if *ptr > *ptr.offset(1){
            return false;
        }
        ptr = ptr.offset(1);
    }
    true
}

/// Returns whether the data in buffer is sorted in descending order or not.
pub unsafe fn is_descending_buffer<T : PartialOrd>(data : *const T, n : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    for _ in 0..(n-1){
        if *ptr < *ptr.offset(1){
            return false;
        }
        ptr = ptr.offset(1);
    }
    true
}

/// Returns whether the data in strided buffer is sorted in ascending order or not
/// every stride-th entry is considered in the buffer
/// assumes that the buffer as at least n* stride entries
pub unsafe fn is_ascending_buffer_strided<T : PartialOrd>(data : *const T,
    n : usize,
    stride : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    let stride = stride as isize;
    for _ in 0..(n-1){
        if *ptr > *ptr.offset(stride){
            return false;
        }
        ptr = ptr.offset(stride);
    }
    true
}

/// Returns whether the data in strided buffer is sorted in ascending order or not
/// every stride-th entry is considered in the buffer
/// assumes that the buffer as at least n* stride entries
pub unsafe fn is_descending_buffer_strided<T : PartialOrd>(data : *const T,
    n : usize,
    stride : usize) -> bool {
    if n == 0 {
        return true;
    }
    let mut ptr = data;
    let stride = stride as isize;
    for _ in 0..(n-1){
        if *ptr < *ptr.offset(stride){
            return false;
        }
        ptr = ptr.offset(stride);
    }
    true
}

/******************************************************
 *
 *   Unit tests
 *
 *******************************************************/

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

    #[test]
    fn test_is_ascending_slice(){
        let v = vec!(1i32, 2, 3, 4);
        assert!(is_ascending_slice(v.as_slice()));
        let v = vec!(1i32);
        assert!(is_ascending_slice(v.as_slice()));
        let v : Vec<i32> = vec!();
        assert!(is_ascending_slice(v.as_slice()));
        let v = vec!(2i32, 1);
        assert!(!is_ascending_slice(v.as_slice()));
        let v = vec!(3i32, 2, 1);
        assert!(!is_ascending_slice(v.as_slice()));
        let v = vec!(1i32, 3, 2);
        assert!(!is_ascending_slice(v.as_slice()));
        let v = vec!(2i32, 1, 3);
        assert!(!is_ascending_slice(v.as_slice()));
    }

    #[test]
    fn test_is_ascending_buffer(){
        unsafe {
            let v = vec!(1i32, 2, 3, 4);
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32);
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
            let v : Vec<i32> = vec!();
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(2i32, 1);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(3i32, 2, 1);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32, 3, 2);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
            let v = vec!(2i32, 1, 3);
            assert!(!is_ascending_buffer(v.as_ptr(), v.len()));
        }
    }

    #[test]
    fn test_is_descending_slice(){
        let v = vec!(4i32, 3, 2, 1);
        assert!(is_descending_slice(v.as_slice()));
        let v = vec!(1i32);
        assert!(is_descending_slice(v.as_slice()));
        let v : Vec<i32> = vec!();
        assert!(is_descending_slice(v.as_slice()));
        let v = vec!(1i32, 2);
        assert!(!is_descending_slice(v.as_slice()));
        let v = vec!(1i32, 2, 3);
        assert!(!is_descending_slice(v.as_slice()));
        let v = vec!(2i32, 3, 1);
        assert!(!is_descending_slice(v.as_slice()));
        let v = vec!(3i32, 1, 2);
        assert!(!is_descending_slice(v.as_slice()));
    }

    #[test]
    fn test_is_descending_buffer(){
        unsafe {
            let v = vec!(4i32, 3, 2, 1);
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32);
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
            let v : Vec<i32> = vec!();
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32, 2);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(1i32, 2, 3);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(2i32, 3, 1);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
            let v = vec!(3i32, 1, 2);
            assert!(!is_descending_buffer(v.as_ptr(), v.len()));
        }
    }

    #[test]
    fn test_is_ascending_buffer_strided(){
        unsafe {
            let v = vec!(4i32, 3, 2, 1);
            assert!(!is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
            let v = vec!(4i32, 3, 5, 1);
            assert!(is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
            let v = vec!(4i32, 1, 5, 2, 3, 7);
            assert!(!is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
            let v = vec!(4i32, 3, 5, 2, 7, 1);
            assert!(is_ascending_buffer_strided(v.as_ptr(), v.len() / 2, 2));
        }
    }

}

/******************************************************
 *
 *   Bench marks
 *
 *******************************************************/

#[cfg(test)]
mod bench{
    extern crate test;
    use self::test::Bencher;
    use super::*;
    #[bench]
    fn bench_is_ascending_slice(b: &mut Bencher){
        let v = (0..10000).collect::<Vec<i32>>();
        b.iter(|| {
            assert!(is_ascending_slice(v.as_slice()));
                });
    }
    #[bench]
    fn bench_is_ascending_buffer(b: &mut Bencher){
        let v = (0..10000).collect::<Vec<i32>>();
        b.iter(|| unsafe {
            assert!(is_ascending_buffer(v.as_ptr(), v.len()));
                });
    }
    #[bench]
    fn bench_is_descending_slice(b: &mut Bencher){
        let v = (0..10000).map(|idx| (20000 - idx)).collect::<Vec<i32>>();
        b.iter(|| {
            assert!(is_descending_slice(v.as_slice()));
                });
    }
    #[bench]
    fn bench_is_descending_buffer(b: &mut Bencher){
        let v = (0..10000).map(|idx| (20000 - idx)).collect::<Vec<i32>>();
        b.iter(|| unsafe {
            assert!(is_descending_buffer(v.as_ptr(), v.len()));
                });
    }
}

<|endoftext|>


<commit_before>/// Lazy iterator over bits of a vector of bytes, starting with the LSB
/// (least-significat bit) of the first element of the vector.
pub struct BitIterator<'a> {
    object: &'a Vec<u8>,
    current_byte: usize,
    current_bit: usize
}

impl<'a> BitIterator<'a> {
    pub fn new(obj: &'a Vec<u8>) -> BitIterator {
        BitIterator { object: obj, current_byte: 0, current_bit: 0 }
    }
}

impl<'a> Iterator for BitIterator<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        let result = self.object[self.current_byte] >> self.current_bit & 0x1;

        if self.current_bit + 1 == ::std::u8::BITS {
            self.current_byte += 1;
        }
        self.current_bit = (self.current_bit + 1) % ::std::u8::BITS;

        if self.current_byte == self.object.len() {
            return None;
        } else {
            return Some(result);
        }
    }
}

#[test]
fn test_iterator() {
    let bytes = vec!(0xCA, 0xFE);
    let expected_bits = vec!(0,1,0,1, 0,0,1,1, 0,1,1,1, 1,1,1,1);
    let mut i = 0;

    for bit in BitIterator::new(&bytes) {
        println!("{} == {}", bit, expected_bits[i]);
        assert_eq!(bit, expected_bits[i]);
        i += 1;
    }
}
<commit_msg>fixes for nightly<commit_after>/// Lazy iterator over bits of a vector of bytes, starting with the LSB
/// (least-significat bit) of the first element of the vector.
pub struct BitIterator<'a> {
    object: &'a Vec<u8>,
    current_byte: usize,
    current_bit: usize
}

impl<'a> BitIterator<'a> {
    pub fn new(obj: &'a Vec<u8>) -> BitIterator {
        BitIterator { object: obj, current_byte: 0, current_bit: 0 }
    }
}

impl<'a> Iterator for BitIterator<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        let result = self.object[self.current_byte] >> self.current_bit & 0x1;

        if self.current_bit + 1 == ::std::u8::BITS as usize {
            self.current_byte += 1;
        }
        self.current_bit = (self.current_bit + 1) % ::std::u8::BITS as usize;

        if self.current_byte == self.object.len() {
            return None;
        } else {
            return Some(result);
        }
    }
}

#[test]
fn test_iterator() {
    let bytes = vec!(0xCA, 0xFE);
    let expected_bits = vec!(0,1,0,1, 0,0,1,1, 0,1,1,1, 1,1,1,1);
    let mut i = 0;

    for bit in BitIterator::new(&bytes) {
        println!("{} == {}", bit, expected_bits[i]);
        assert_eq!(bit, expected_bits[i]);
        i += 1;
    }
}
<|endoftext|>


<commit_before>use search_algorithms::board::ExtendedBoard;
use search_algorithms::board::GameResult;
use search_algorithms::alpha_beta::Score;
use pgn::PgnBoard;
use rayon::prelude::*;

pub trait TunableBoard {
    const PARAMS: &'static [f32];

    fn static_eval_with_params(&self, params: &[f32]) -> f32;
}

pub fn get_critical_positions<B>(positions: &mut [B], params: &[f32]) -> Vec<B>
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send {
    positions.into_par_iter()
        .map(|board| {
            if let (Score::Val(_), pv) = qsearch(&mut board.clone(), Score::Loss(0),
                                     Score::Win(0), params) {
                let mut cloned_board = board.clone();

                for mv in pv {
                    cloned_board.do_move(mv);
                }
                cloned_board
            }
            else {
                warn!("Found mate score while tuning {}.", board.to_fen());
                board.clone()
            }

        })
        .collect()
}

pub fn gradient_descent<B>(positions: &mut [B], results: &[GameResult],
                           test_positions: &mut[B], test_results: &[GameResult],
                           params: &[f32]) -> Vec<f32>
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send {
    assert_eq!(positions.len(), results.len());
    assert_eq!(test_positions.len(), test_results.len());

    const ETA: f32 = 0.1;

    let mut errors = vec![std::f32::MAX];
    let mut paramss: Vec<Vec<f32>> = vec![params.to_vec()];

    loop {
        let last_params = paramss.last().unwrap().clone();
        let gradients = gradients(positions, results, &last_params);
        println!("Gradients: {:?}", gradients);

        let new_params: Vec<f32> = last_params.iter()
            .zip(gradients)
            .map(|(param, grad)| param + grad * ETA)
            .collect();
        println!("New parameters: {:?}", new_params);

        let error = average_error(test_positions, test_results, &new_params);
        println!("Error now {}\n", error);

        if !errors.len() > 2
            && error > errors[errors.len() - 1]
            && errors[errors.len() - 1] > errors[errors.len() - 2]
            && errors[errors.len() - 2] > errors[errors.len() - 3]
        {
            return paramss[paramss.len() - 3].clone()
        }
        else {
            errors.push(error);
            paramss.push(new_params);
        }
    }
}

pub fn gradients<B>(positions: &mut [B], results: &[GameResult], params: &[f32]) -> Vec<f32>
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send {

    let critical_positions = get_critical_positions(positions, params);

    const EPSILON : f32 = 0.001;

    params.iter().enumerate()
        .map(|(i, p)| {
            let mut params_hat: Vec<f32> = params.iter().cloned().collect();
            params_hat[i] = p + EPSILON;
            critical_positions.iter()
                .zip(results)
                .map(|(board, &game_result)| {
                    let score1 = board.static_eval_with_params(params);
                    let score2 = board.static_eval_with_params(&params_hat);
                    error(score1, game_result) - error(score2, game_result)
                })
                .sum()
        })
        .collect()
}

pub fn average_error<B>(positions: &mut [B], results: &[GameResult], params: &[f32]) -> f32
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send {
    assert_eq!(positions.len(), results.len());
    positions.into_par_iter().zip(results)
        .map(|(board, game_result)| {
            let color = board.side_to_move();
            if let (Score::Val(qsearc_eval), _) = qsearch(&mut board.clone(), Score::Loss(0),
                                                     Score::Win(0), params) {
                let eval = qsearc_eval * color.multiplier() as f32;
                error(eval, game_result.clone())

            }
            else {
                warn!("Found mate score while tuning {}.", board.to_fen());
                0.0
            }
        })
        .sum::<f32>() / (positions.len() as f32)

}

pub fn error(eval: f32, game_result: GameResult) -> f32 {
    const K: f32 = 1.6;
    let answer = match game_result {
        GameResult::WhiteWin => 1.0,
        GameResult::Draw => 0.5,
        GameResult::BlackWin => 0.0,
    };

    let error = f32::powf(answer - sigmoid(eval, K), 2.0);
    error
}

pub fn sigmoid(eval: f32, k: f32) -> f32 {
    1.0 + 10.0_f32.powf(k * eval / 400.0)
}

fn qsearch<B: ExtendedBoard>(board: &mut B, mut alpha: Score, beta: Score, params: &[f32])
    -> (Score, Vec<B::Move>)
    where B: TunableBoard + ExtendedBoard {
    let color = board.side_to_move();

    if let Some(result) = board.game_result() {
        return (Score::from_game_result(result, color), vec![])
    }

    let stand_pat = Score::Val(board.static_eval_with_params(params) * color.multiplier() as f32);

    if stand_pat >= beta {
        return (beta, vec![]);
    }

    alpha = alpha.max(stand_pat);
    let mut best_pv = vec![];
    let mut best_move = None;

    let mut active_moves = vec![];
    board.active_moves(&mut active_moves);

    for mv in active_moves {
        let reverse_move = board.do_move(mv.clone());

        let (mut score, mut pv) = qsearch(board, beta, alpha, params);

        score = !score;
        board.reverse_move(reverse_move);

        if score >= beta {
            return (score, vec![mv]);
        }
        if score > alpha {
            alpha = score;
            best_pv = pv;
            best_move = Some(mv);
        }
    }
    best_pv.extend(best_move);
    return (alpha, best_pv);

}<commit_msg>Fix sigmoid and tuning qsearch<commit_after>use search_algorithms::board::ExtendedBoard;
use search_algorithms::board::GameResult;
use search_algorithms::alpha_beta::Score;
use pgn::PgnBoard;
use rayon::prelude::*;
use std::fmt::Debug;

pub trait TunableBoard {
    const PARAMS: &'static [f32];

    fn static_eval_with_params(&self, params: &[f32]) -> f32;
}

pub fn get_critical_positions<B>(positions: &mut [B], params: &[f32]) -> Vec<B>
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send {
    positions.into_par_iter()
        .map(|board| {
            if let (Score::Val(_), pv) = qsearch(&mut board.clone(), Score::Loss(0),
                                     Score::Win(0), params) {
                let mut cloned_board = board.clone();

                for mv in pv.into_iter().rev() {
                    cloned_board.do_move(mv);
                }
                cloned_board
            }
            else {
                warn!("Found mate score while tuning {}.", board.to_fen());
                board.clone()
            }

        })
        .collect()
}

pub fn gradient_descent<B>(positions: &mut [B], results: &[GameResult],
                           test_positions: &mut[B], test_results: &[GameResult],
                           params: &[f32]) -> Vec<f32>
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send + Debug {
    assert_eq!(positions.len(), results.len());
    assert_eq!(test_positions.len(), test_results.len());

    const ETA: f32 = 0.02;

    let mut errors = vec![std::f32::MAX];
    let mut paramss: Vec<Vec<f32>> = vec![params.to_vec()];

    loop {
        let last_params = paramss.last().unwrap().clone();
        let gradients = gradients(positions, results, &last_params);
        println!("Gradients: {:?}", gradients);

        let new_params: Vec<f32> = last_params.iter()
            .zip(gradients)
            .map(|(param, grad)| param + grad * ETA)
            .collect();
        println!("New parameters: {:?}", new_params);

        let error = average_error(test_positions, test_results, &new_params);
        println!("Error now {}\n", error);

        if !errors.len() > 2
            && error > errors[errors.len() - 1]
            && errors[errors.len() - 1] > errors[errors.len() - 2]
            && errors[errors.len() - 2] > errors[errors.len() - 3]
        {
            return paramss[paramss.len() - 3].clone()
        }
        else {
            errors.push(error);
            paramss.push(new_params);
        }
    }
}

pub fn gradients<B>(positions: &mut [B], results: &[GameResult], params: &[f32]) -> Vec<f32>
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send {

    let critical_positions = get_critical_positions(positions, params);

    const EPSILON : f32 = 0.001;

    params.iter().enumerate()
        .map(|(i, p)| {
            let mut params_hat: Vec<f32> = params.iter().cloned().collect();
            params_hat[i] = p + EPSILON;
            critical_positions.iter()
                .zip(results)
                .map(|(board, &game_result)| {
                    let score1 = board.static_eval_with_params(params);
                    let score2 = board.static_eval_with_params(&params_hat);
                    error(score1, game_result) - error(score2, game_result)
                })
                .sum()
        })
        .collect()
}

pub fn average_error<B>(positions: &mut [B], results: &[GameResult], params: &[f32]) -> f32
    where B: TunableBoard + ExtendedBoard + PgnBoard + Send + Debug {
    assert_eq!(positions.len(), results.len());
    positions.into_par_iter().zip(results)
        .map(|(board, game_result)| {
            let color = board.side_to_move();
            if let (Score::Val(qsearc_eval), _) = qsearch(&mut board.clone(), Score::Loss(0),
                                                     Score::Win(0), params) {
                let eval = qsearc_eval * color.multiplier() as f32;
                error(eval, game_result.clone())

            }
            else {
                warn!("Found mate score while tuning {}.", board.to_fen());
                0.0
            }
        })
        .sum::<f32>() / (positions.len() as f32)

}

pub fn error(eval: f32, game_result: GameResult) -> f32 {
    let answer = match game_result {
        GameResult::WhiteWin => 1.0,
        GameResult::Draw => 0.5,
        GameResult::BlackWin => 0.0,
    };

    let error = f32::powf(answer - sigmoid(eval), 2.0);
    error
}

pub fn sigmoid(eval: f32) -> f32 {
    let k = 0.97;
    1.0 / (1.0 + 10.0_f32.powf(-k * eval / 4.0))
}

/// Run quiescence search and returns a score from the side to move's perspective
fn qsearch<B: ExtendedBoard>(board: &mut B, mut alpha: Score, beta: Score, params: &[f32])
    -> (Score, Vec<B::Move>)
    where B: TunableBoard + ExtendedBoard {
    let color = board.side_to_move();

    if let Some(result) = board.game_result() {
        return (Score::from_game_result(result, color), vec![])
    }

    let stand_pat = Score::Val(board.static_eval_with_params(params) * color.multiplier() as f32);

    if stand_pat >= beta {
        return (beta, vec![]);
    }

    alpha = alpha.max(stand_pat);
    let mut best_pv = vec![];
    let mut best_move = None;

    let mut active_moves = vec![];
    board.active_moves(&mut active_moves);

    for mv in active_moves {
        let reverse_move = board.do_move(mv.clone());

        let (mut score, mut pv) = qsearch(board, !beta, !alpha, params);

        score = !score;
        board.reverse_move(reverse_move);

        if score >= beta {
            return (score, vec![mv]);
        }
        if score > alpha {
            alpha = score;
            best_pv = pv;
            best_move = Some(mv);
        }
    }
    best_pv.extend(best_move);
    return (alpha, best_pv);

}<|endoftext|>


<commit_before>use crate::api::{CairoRenderer, IntrinsicDimensions, Length, RenderingError};
use float_cmp::approx_eq;

use super::handle::CairoRectangleExt;

/// Extension methods to compute the SVG's size suitable for the legacy C API.
///
/// The legacy C API can compute an SVG document's size from the
/// `width`, `height`, and `viewBox` attributes of the toplevel `<svg>`
/// element.  If these are not available, then the size must be computed
/// by actually measuring the geometries of elements in the document.
///
/// See https://www.w3.org/TR/css-images-3/#sizing-terms for terminology and logic.
pub trait LegacySize {
    fn legacy_document_size(&self) -> Result<(f64, f64), RenderingError> {
        let (ink_r, _) = self.legacy_layer_geometry(None)?;
        Ok((ink_r.width, ink_r.height))
    }

    fn legacy_layer_geometry(
        &self,
        id: Option<&str>,
    ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError>;
}

impl<'a> LegacySize for CairoRenderer<'a> {
    fn legacy_layer_geometry(
        &self,
        id: Option<&str>,
    ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
        match id {
            Some(id) => Ok(self.geometry_for_layer(Some(id), &unit_rectangle())?),

            None => {
                let size_from_intrinsic_dimensions =
                    self.intrinsic_size_in_pixels().or_else(|| {
                        size_in_pixels_from_percentage_width_and_height(
                            &self.intrinsic_dimensions(),
                        )
                    });

                if let Some((w, h)) = size_from_intrinsic_dimensions {
                    // We have a size directly computed from the <svg> attributes
                    let rect = cairo::Rectangle::from_size(w, h);
                    Ok((rect, rect))
                } else {
                    self.geometry_for_layer(None, &unit_rectangle())
                }
            }
        }
    }
}

fn unit_rectangle() -> cairo::Rectangle {
    cairo::Rectangle::from_size(1.0, 1.0)
}

/// If the width and height are in percentage units, computes a size equal to the
/// `viewBox`'s aspect ratio if it exists, or else returns None.
///
/// For example, a `viewBox="0 0 100 200"` will yield `Some(100.0, 200.0)`.
///
/// Note that this only checks that the width and height are in percentage units, but
/// it actually ignores their values.  This is because at the point this function is
/// called, there is no viewport to embed the SVG document in, so those percentage
/// units cannot be resolved against anything in particular.  The idea is to return
/// some dimensions with the correct aspect ratio.
fn size_in_pixels_from_percentage_width_and_height(
    dim: &IntrinsicDimensions,
) -> Option<(f64, f64)> {
    let IntrinsicDimensions {
        width,
        height,
        vbox,
    } = *dim;

    use crate::api::LengthUnit::*;

    // If both width and height are 100%, just use the vbox size as a pixel size.
    // This gives a size with the correct aspect ratio.

    match (width, height, vbox) {
        (None, None, Some(vbox)) => Some((vbox.width, vbox.height)),

        (
            Some(Length {
                length: w,
                unit: Percent,
            }),
            Some(Length {
                length: h,
                unit: Percent,
            }),
            Some(vbox),
        ) if approx_eq!(f64, w, 1.0) && approx_eq!(f64, h, 1.0) => Some((vbox.width, vbox.height)),

        _ => None,
    }
}
<commit_msg>Document c_api/sizing<commit_after>//! Compute an SVG document's size with the legacy logic.
//!
//! See the documentation for [`LegacySize`](trait.LegacySize.html).  The legacy C API
//! functions like `rsvg_handle_render_cairo()` do not take a viewport argument: they do
//! not know how big the caller would like to render the document; instead they compute a
//! "natural size" for the document based on its `width`/`height`/`viewBox` and some
//! heuristics for when they are missing.
//!
//! The new style C functions like `rsvg_handle_render_document()` actually take a
//! viewport, which indicates how big the result should be.  This matches the expectations
//! of the web platform, which assumes that all embedded content goes into a viewport.

use crate::api::{CairoRenderer, IntrinsicDimensions, Length, RenderingError};
use float_cmp::approx_eq;

use super::handle::CairoRectangleExt;

/// Extension methods to compute the SVG's size suitable for the legacy C API.
///
/// The legacy C API can compute an SVG document's size from the
/// `width`, `height`, and `viewBox` attributes of the toplevel `<svg>`
/// element.  If these are not available, then the size must be computed
/// by actually measuring the geometries of elements in the document.
///
/// See https://www.w3.org/TR/css-images-3/#sizing-terms for terminology and logic.
pub trait LegacySize {
    fn legacy_document_size(&self) -> Result<(f64, f64), RenderingError> {
        let (ink_r, _) = self.legacy_layer_geometry(None)?;
        Ok((ink_r.width, ink_r.height))
    }

    fn legacy_layer_geometry(
        &self,
        id: Option<&str>,
    ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError>;
}

impl<'a> LegacySize for CairoRenderer<'a> {
    fn legacy_layer_geometry(
        &self,
        id: Option<&str>,
    ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
        match id {
            Some(id) => Ok(self.geometry_for_layer(Some(id), &unit_rectangle())?),

            None => {
                let size_from_intrinsic_dimensions =
                    self.intrinsic_size_in_pixels().or_else(|| {
                        size_in_pixels_from_percentage_width_and_height(
                            &self.intrinsic_dimensions(),
                        )
                    });

                if let Some((w, h)) = size_from_intrinsic_dimensions {
                    // We have a size directly computed from the <svg> attributes
                    let rect = cairo::Rectangle::from_size(w, h);
                    Ok((rect, rect))
                } else {
                    self.geometry_for_layer(None, &unit_rectangle())
                }
            }
        }
    }
}

fn unit_rectangle() -> cairo::Rectangle {
    cairo::Rectangle::from_size(1.0, 1.0)
}

/// If the width and height are in percentage units, computes a size equal to the
/// `viewBox`'s aspect ratio if it exists, or else returns None.
///
/// For example, a `viewBox="0 0 100 200"` will yield `Some(100.0, 200.0)`.
///
/// Note that this only checks that the width and height are in percentage units, but
/// it actually ignores their values.  This is because at the point this function is
/// called, there is no viewport to embed the SVG document in, so those percentage
/// units cannot be resolved against anything in particular.  The idea is to return
/// some dimensions with the correct aspect ratio.
fn size_in_pixels_from_percentage_width_and_height(
    dim: &IntrinsicDimensions,
) -> Option<(f64, f64)> {
    let IntrinsicDimensions {
        width,
        height,
        vbox,
    } = *dim;

    use crate::api::LengthUnit::*;

    // If both width and height are 100%, just use the vbox size as a pixel size.
    // This gives a size with the correct aspect ratio.

    match (width, height, vbox) {
        (None, None, Some(vbox)) => Some((vbox.width, vbox.height)),

        (
            Some(Length {
                length: w,
                unit: Percent,
            }),
            Some(Length {
                length: h,
                unit: Percent,
            }),
            Some(vbox),
        ) if approx_eq!(f64, w, 1.0) && approx_eq!(f64, h, 1.0) => Some((vbox.width, vbox.height)),

        _ => None,
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

#[macro_use]
extern crate slog;
extern crate slog_json;

extern crate test;

use std::io;
use test::Bencher;
use slog::*;

struct BlackBoxDrain;

impl Drain for BlackBoxDrain {
    fn log(&self,
           buf: &mut Vec<u8>,
           ri: &Record, o : &OwnedKeyValueList) -> io::Result<()> {

        test::black_box((buf, ri, o));
        Ok(())
    }
}

struct BlackBoxWriter;

impl io::Write for BlackBoxWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        test::black_box(buf);
        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[bench]
fn log_discard_empty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        info!(log, "");
    });
}

#[bench]
fn log_discard_nonempty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!("build" => "123456", "id" => 123456));

    b.iter(|| {
        info!(log, "", "what" => "write");
    });
}

#[bench]
fn logger_clone_empty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        log.clone()
    });
}

#[bench]
fn logger_clone_nonempty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!("build" => "123456", "id" => 123456));

    b.iter(|| {
        log.clone()
    });
}

#[bench]
fn logger_new_empty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        log.new(o!())
    });
}

#[bench]
fn logger_new_nonempty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!("build" => "123456", "id" => 123456));

    b.iter(|| {
        log.new(o!("what" => "write"));
    });
}

#[bench]
fn log_discard_i32val(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        info!(log, "", "i32" => 5);
    });
}

#[bench]
fn log_discard_i32closure(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        info!(log, "", "i32" => |_:&Record|{5});
    });
}

#[bench]
fn log_stream_json_blackbox_i32val(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "",  "i32" => 5);
    });
}

#[bench]
fn log_stream_json_blackbox_i32closure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "i32" => |_:&Record|{5});
    });
}

#[bench]
fn log_stream_json_blackbox_i32pushclosure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "i32" => PushLazy(|_:&Record, ser : ValueSerializer|{
            ser.serialize(5)
        }));
    });
}

const LONG_STRING : &'static str = "A long string that would take some time to allocate";

#[bench]
fn log_stream_json_blackbox_strclosure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "str" => |_:&Record| {
            String::from(LONG_STRING)
        });
    });
}

#[bench]
fn log_stream_json_blackbox_strpushclosure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "str" => PushLazy(|_:&Record, ser : ValueSerializer|{
            ser.serialize(LONG_STRING)
        }));
    });
}
<commit_msg>Bench filtering out things.<commit_after>#![feature(test)]

#[macro_use]
extern crate slog;
extern crate slog_json;

extern crate test;

use std::io;
use test::Bencher;
use slog::*;

struct BlackBoxDrain;

impl Drain for BlackBoxDrain {
    fn log(&self,
           buf: &mut Vec<u8>,
           ri: &Record, o : &OwnedKeyValueList) -> io::Result<()> {

        test::black_box((buf, ri, o));
        Ok(())
    }
}

struct BlackBoxWriter;

impl io::Write for BlackBoxWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        test::black_box(buf);
        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}
#[bench]
fn log_filter_out_empty(b: &mut Bencher) {
    let log = Logger::root(LevelFilter::new(BlackBoxDrain, Level::Warning), o!());

    b.iter(|| {
        info!(log, "");
    });
}

#[bench]
fn log_discard_empty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        info!(log, "");
    });
}

#[bench]
fn log_discard_nonempty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!("build" => "123456", "id" => 123456));

    b.iter(|| {
        info!(log, "", "what" => "write");
    });
}

#[bench]
fn logger_clone_empty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        log.clone()
    });
}

#[bench]
fn logger_clone_nonempty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!("build" => "123456", "id" => 123456));

    b.iter(|| {
        log.clone()
    });
}

#[bench]
fn logger_new_empty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        log.new(o!())
    });
}

#[bench]
fn logger_new_nonempty(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!("build" => "123456", "id" => 123456));

    b.iter(|| {
        log.new(o!("what" => "write"));
    });
}

#[bench]
fn log_discard_i32val(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        info!(log, "", "i32" => 5);
    });
}

#[bench]
fn log_discard_i32closure(b: &mut Bencher) {
    let log = Logger::root(BlackBoxDrain, o!());

    b.iter(|| {
        info!(log, "", "i32" => |_:&Record|{5});
    });
}

#[bench]
fn log_stream_json_blackbox_i32val(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "",  "i32" => 5);
    });
}

#[bench]
fn log_stream_json_blackbox_i32closure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "i32" => |_:&Record|{5});
    });
}

#[bench]
fn log_stream_json_blackbox_i32pushclosure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "i32" => PushLazy(|_:&Record, ser : ValueSerializer|{
            ser.serialize(5)
        }));
    });
}

const LONG_STRING : &'static str = "A long string that would take some time to allocate";

#[bench]
fn log_stream_json_blackbox_strclosure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "str" => |_:&Record| {
            String::from(LONG_STRING)
        });
    });
}

#[bench]
fn log_stream_json_blackbox_strpushclosure(b: &mut Bencher) {
    let drain = stream(BlackBoxWriter, slog_json::new());

    let log = Logger::root(drain, o!());

    b.iter(|| {
        info!(log, "", "str" => PushLazy(|_:&Record, ser : ValueSerializer|{
            ser.serialize(LONG_STRING)
        }));
    });
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #4452 - moz-gfx:github-sync, r=auto<commit_after><|endoftext|>


<commit_before><commit_msg>Backed out changeset 455d161a3fa9 (bug 1594524) for causing Wrench failure in adb wait-for-device shell cat /sys/class/power_supply/battery/input_suspend 2>/dev/null. CLOSED TREE<commit_after><|endoftext|>