<commit_before>use super::{Document,Root,RootChild,Element};

struct Parser;

struct ParsedElement<'a> {
    name: &'a str,
    attributes: Vec<ParsedAttribute<'a>>,
}

struct ParsedAttribute<'a> {
    name: &'a str,
    value: &'a str,
}

macro_rules! try_parse(
    ($e:expr) => ({
        match $e {
            None => return None,
            Some(x) => x,
        }
    })
)

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

    fn parse_preamble<'a>(&self, xml: &'a str) -> &'a str {
        // Parse the preamble
        let idx = xml.find_str("?>").expect("No preamble end");
        let end_of_preamble = idx + "?>".len();
        xml.slice_from(end_of_preamble)
    }

    fn optional_space<'a>(&self, xml: &'a str) -> &'a str {
        match xml.slice_space() {
            Some((_, next_xml)) => next_xml,
            None => xml,
        }
    }

    fn parse_attribute_value_quote<'a>(&self, xml: &'a str, quote: &str) -> Option<(&'a str, &'a str)> {
        let (_, xml) = match xml.slice_literal(quote) {
            None => return None,
            Some(x) => x,
        };
        // TODO: don't consume & or <
        let (value, xml) = xml.slice_until(quote).expect("No value");
        let (_, xml) = xml.slice_literal(quote).expect("No quote");

        Some((value, xml))
    }

    fn parse_attribute<'a>(&self, xml: &'a str) -> Option<(ParsedAttribute<'a>, &'a str)> {
        let (name, xml) = match xml.slice_name() {
            Some(x) => x,
            None => return None,
        };

        let xml = self.optional_space(xml);
        let (_, xml) = xml.slice_literal("=").expect("No equal sign");
        let xml = self.optional_space(xml);

        // Pattern: alternate
        let (value, xml) = match self.parse_attribute_value_quote(xml, "'") {
            Some(x) => x,
            None => match self.parse_attribute_value_quote(xml, "\"") {
                Some(x) => x,
                None => fail!("No attribute value"),
            },
        };

        Some((ParsedAttribute{name: name, value: value}, xml))
    }

    fn parse_attributes<'a>(&self, xml: &'a str) -> (Vec<ParsedAttribute<'a>>, &'a str) {
        let mut xml = xml;
        let mut attrs = Vec::new();

        // Pattern: zero-or-more
        // On failure, return the end of the last successful parse
        loop {
            let (_, after_space) = match xml.slice_space() {
                None => return (attrs, xml),
                Some(x) => x,
            };

            xml = match self.parse_attribute(after_space) {
                None => return (attrs, xml),
                Some((attr, after_attr)) => {
                    attrs.push(attr);
                    after_attr
                },
            };
        }
    }

    fn parse_empty_element<'a>(&self, xml: &'a str) -> Option<(ParsedElement<'a>, &'a str)> {
        let (_, xml) = try_parse!(xml.slice_literal("<"));
        let (name, xml) = try_parse!(xml.slice_name());
        let (attrs, xml) = self.parse_attributes(xml);
        let xml = self.optional_space(xml);
        let (_, xml) = try_parse!(xml.slice_literal("/>"));

        Some((ParsedElement{name: name, attributes: attrs}, xml))
    }

    fn parse_element_start<'a>(&self, xml: &'a str) -> Option<(ParsedElement<'a>, &'a str)> {
        let (_, xml) = try_parse!(xml.slice_literal("<"));
        let (name, xml) = try_parse!(xml.slice_name());
        let (attrs, xml) = self.parse_attributes(xml);
        let xml = self.optional_space(xml);
        let (_, xml) = try_parse!(xml.slice_literal(">"));

        Some((ParsedElement{name: name, attributes: attrs}, xml))
    }

    fn parse_element_end<'a>(&self, xml: &'a str) -> Option<(&'a str, &'a str)> {
        let (_, xml) = try_parse!(xml.slice_literal("</"));
        let (name, xml) = try_parse!(xml.slice_name());
        let xml = self.optional_space(xml);
        let (_, xml) = try_parse!(xml.slice_literal(">"));
        Some((name, xml))
    }

    fn parse_non_empty_element<'a>(&self, xml: &'a str) -> Option<(ParsedElement<'a>, &'a str)> {
        let (element, xml) = try_parse!(self.parse_element_start(xml));
        let (name, xml) = try_parse!(self.parse_element_end(xml));

        if element.name != name {
            fail!("tags do not match!");
        }

        Some((element, xml))
    }

    fn parse_element<'a>(&self, doc: Document, xml: &'a str) -> Option<(Element, &'a str)> {
        // Pattern: alternate
        let (element_data, xml) = match self.parse_empty_element(xml) {
            Some(x) => x,
            None => match self.parse_non_empty_element(xml) {
                Some(x) => x,
                None => fail!("No element!"),
            },
        };

        let e = doc.new_element(element_data.name.to_string());
        for attr in element_data.attributes.iter() {
            e.set_attribute(attr.name.to_string(), attr.value.to_string());
        }

        Some((e, xml))
    }

    fn parse(&self, xml: &str) -> Document {
        let doc = Document::new();

        let after_preamble = self.parse_preamble(xml);

        let (element, _tail) = self.parse_element(doc.clone(), after_preamble).expect("no element");
        doc.root().append_child(element);

        doc
    }
}

trait XmlStr<'a> {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str);
    fn slice_until(&self, s: &str) -> Option<(&'a str, &'a str)>;
    fn slice_literal(&self, expected: &str) -> Option<(&'a str, &'a str)>;
    fn slice_start_rest(&self, is_first: |char| -> bool, is_rest: |char| -> bool) -> Option<(&'a str, &'a str)>;
    fn slice_name(&self) -> Option<(&'a str, &'a str)>;
    fn slice_space(&self) -> Option<(&'a str, &'a str)>;
}

impl<'a> XmlStr<'a> for &'a str {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str) {
        (self.slice_to(position), self.slice_from(position))
    }

    fn slice_until(&self, s: &str) -> Option<(&'a str, &'a str)> {
        match self.find_str(s) {
            Some(position) => Some(self.slice_at(position)),
            None => None
        }
    }

    fn slice_literal(&self, expected: &str) -> Option<(&'a str, &'a str)> {
        if self.starts_with(expected) {
            Some(self.slice_at(expected.len()))
        } else {
            None
        }
    }

    fn slice_start_rest(&self,
                        is_first: |char| -> bool,
                        is_rest: |char| -> bool)
                        -> Option<(&'a str, &'a str)>
    {
        let mut positions = self.char_indices();

        match positions.next() {
            Some((_, c)) if is_first(c) => (),
            Some((_, _)) => return None,
            None => return None,
        };

        let mut positions = positions.skip_while(|&(_, c)| is_rest(c));
        match positions.next() {
            Some((offset, _)) => Some(self.slice_at(offset)),
            None => Some((self.clone(), "")),
        }
    }

    fn slice_name(&self) -> Option<(&'a str, &'a str)> {
        self.slice_start_rest(|c| c.is_name_start_char(), |c| c.is_name_char())
    }

    fn slice_space(&self) -> Option<(&'a str, &'a str)> {
        self.slice_start_rest(|c| c.is_space_char(), |c| c.is_space_char())
    }
}

trait XmlChar {
    fn is_name_start_char(&self) -> bool;
    fn is_name_char(&self) -> bool;
    fn is_space_char(&self) -> bool;
}

impl XmlChar for char {
    fn is_name_start_char(&self) -> bool {
        match *self {
            ':'                        |
            'A'..'Z'                   |
            '_'                        |
            'a'..'z'                   |
            '\U000000C0'..'\U000000D6' |
            '\U000000D8'..'\U000000F6' |
            '\U000000F8'..'\U000002FF' |
            '\U00000370'..'\U0000037D' |
            '\U0000037F'..'\U00001FFF' |
            '\U0000200C'..'\U0000200D' |
            '\U00002070'..'\U0000218F' |
            '\U00002C00'..'\U00002FEF' |
            '\U00003001'..'\U0000D7FF' |
            '\U0000F900'..'\U0000FDCF' |
            '\U0000FDF0'..'\U0000FFFD' |
            '\U00010000'..'\U000EFFFF' => true,
            _ => false,
        }
    }

    fn is_name_char(&self) -> bool {
        if self.is_name_start_char() { return true; }
        match *self {
            '-'                |
            '.'                |
            '0'..'9'           |
            '\u00B7'           |
            '\u0300'..'\u036F' |
            '\u203F'..'\u2040' => true,
            _ => false
        }
    }

    fn is_space_char(&self) -> bool {
        match *self {
            '\x20' |
            '\x09' |
            '\x0D' |
            '\x0A' => true,
            _ => false,
        }
    }
}

trait Hax {
    fn first_child(&self) -> Option<RootChild>;
}

impl Hax for Root {
    fn first_child(&self) -> Option<RootChild> {
        self.children().remove(0)
    }
}

#[test]
fn parses_a_document_with_a_single_element() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello />");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.name().as_slice(), "hello");
}

#[test]
fn parses_an_element_with_an_attribute() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello scope='world'/>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.get_attribute("scope").unwrap().as_slice(), "world");
}

#[test]
fn parses_an_element_with_an_attribute_using_double_quotes() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello scope=\"world\"/>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.get_attribute("scope").unwrap().as_slice(), "world");
}

#[test]
fn parses_an_element_with_multiple_attributes() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello scope=\"world\" happy='true'/>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.get_attribute("scope").unwrap().as_slice(), "world");
    assert_eq!(top.get_attribute("happy").unwrap().as_slice(), "true");
}

#[test]
fn parses_an_element_that_is_not_self_closing() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello></hello>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.name().as_slice(), "hello");
}
<commit_msg>Parse nested elements<commit_after>use super::{Document,Root,RootChild,Element,ElementChild};

struct Parser;

struct ParsedElement<'a> {
    name: &'a str,
    attributes: Vec<ParsedAttribute<'a>>,
    children: Vec<ParsedElement<'a>>,
}

struct ParsedAttribute<'a> {
    name: &'a str,
    value: &'a str,
}

macro_rules! try_parse(
    ($e:expr) => ({
        match $e {
            None => return None,
            Some(x) => x,
        }
    })
)

// Pattern: 0-or-1
macro_rules! optional_parse(
    ($f:expr, $start:expr) => ({
        match $f {
            None => (None, $start),
            Some((value, next)) => (Some(value), next),
        }
    })
)

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

    fn parse_preamble<'a>(&self, xml: &'a str) -> &'a str {
        // Parse the preamble
        let idx = xml.find_str("?>").expect("No preamble end");
        let end_of_preamble = idx + "?>".len();
        xml.slice_from(end_of_preamble)
    }

    fn optional_space<'a>(&self, xml: &'a str) -> &'a str {
        match xml.slice_space() {
            Some((_, next_xml)) => next_xml,
            None => xml,
        }
    }

    fn parse_attribute_value_quote<'a>(&self, xml: &'a str, quote: &str) -> Option<(&'a str, &'a str)> {
        let (_, xml) = match xml.slice_literal(quote) {
            None => return None,
            Some(x) => x,
        };
        // TODO: don't consume & or <
        let (value, xml) = xml.slice_until(quote).expect("No value");
        let (_, xml) = xml.slice_literal(quote).expect("No quote");

        Some((value, xml))
    }

    fn parse_attribute<'a>(&self, xml: &'a str) -> Option<(ParsedAttribute<'a>, &'a str)> {
        let (name, xml) = match xml.slice_name() {
            Some(x) => x,
            None => return None,
        };

        let xml = self.optional_space(xml);
        let (_, xml) = xml.slice_literal("=").expect("No equal sign");
        let xml = self.optional_space(xml);

        // Pattern: alternate
        let (value, xml) = match self.parse_attribute_value_quote(xml, "'") {
            Some(x) => x,
            None => match self.parse_attribute_value_quote(xml, "\"") {
                Some(x) => x,
                None => fail!("No attribute value"),
            },
        };

        Some((ParsedAttribute{name: name, value: value}, xml))
    }

    fn parse_attributes<'a>(&self, xml: &'a str) -> (Vec<ParsedAttribute<'a>>, &'a str) {
        let mut xml = xml;
        let mut attrs = Vec::new();

        // Pattern: zero-or-more
        // On failure, return the end of the last successful parse
        loop {
            let (_, after_space) = match xml.slice_space() {
                None => return (attrs, xml),
                Some(x) => x,
            };

            xml = match self.parse_attribute(after_space) {
                None => return (attrs, xml),
                Some((attr, after_attr)) => {
                    attrs.push(attr);
                    after_attr
                },
            };
        }
    }

    fn parse_empty_element<'a>(&self, xml: &'a str) -> Option<(ParsedElement<'a>, &'a str)> {
        let (_, xml) = try_parse!(xml.slice_literal("<"));
        let (name, xml) = try_parse!(xml.slice_name());
        let (attrs, xml) = self.parse_attributes(xml);
        let xml = self.optional_space(xml);
        let (_, xml) = try_parse!(xml.slice_literal("/>"));

        Some((ParsedElement{name: name, attributes: attrs, children: Vec::new()}, xml))
    }

    fn parse_element_start<'a>(&self, xml: &'a str) -> Option<(ParsedElement<'a>, &'a str)> {
        let (_, xml) = try_parse!(xml.slice_literal("<"));
        let (name, xml) = try_parse!(xml.slice_name());
        let (attrs, xml) = self.parse_attributes(xml);
        let xml = self.optional_space(xml);
        let (_, xml) = try_parse!(xml.slice_literal(">"));

        Some((ParsedElement{name: name, attributes: attrs, children: Vec::new()}, xml))
    }

    fn parse_element_end<'a>(&self, xml: &'a str) -> Option<(&'a str, &'a str)> {
        let (_, xml) = try_parse!(xml.slice_literal("</"));
        let (name, xml) = try_parse!(xml.slice_name());
        let xml = self.optional_space(xml);
        let (_, xml) = try_parse!(xml.slice_literal(">"));
        Some((name, xml))
    }

    fn parse_non_empty_element<'a>(&self, xml: &'a str) -> Option<(ParsedElement<'a>, &'a str)> {
        let (mut element, xml) = try_parse!(self.parse_element_start(xml));
        let (child, xml) = optional_parse!(self.parse_element(xml), xml);
        let (name, xml) = try_parse!(self.parse_element_end(xml));

        if element.name != name {
            fail!("tags do not match!");
        }

        child.map(|c| element.children.push(c));

        Some((element, xml))
    }

    fn parse_element<'a>(&self, xml: &'a str) -> Option<(ParsedElement<'a>, &'a str)> {
        // Pattern: alternate
        match self.parse_empty_element(xml) {
            Some(x) => Some(x),
            None => match self.parse_non_empty_element(xml) {
                Some(x) => Some(x),
                None => None,
            },
        }
    }

    fn hydrate_parsed_data(&self, element_data: ParsedElement) -> Document {
        let doc = Document::new();

        let element = doc.new_element(element_data.name.to_string());
        for attr in element_data.attributes.iter() {
            element.set_attribute(attr.name.to_string(), attr.value.to_string());
        }
        for child in element_data.children.iter() {
            let c = doc.new_element(child.name.to_string());//attrs; recursive
            element.append_child(c);
        }
        doc.root().append_child(element);

        doc
    }

    fn parse(&self, xml: &str) -> Document {
        let after_preamble = self.parse_preamble(xml);

        let (element, _tail) = self.parse_element(after_preamble).expect("no element");

        self.hydrate_parsed_data(element)
    }
}

trait XmlStr<'a> {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str);
    fn slice_until(&self, s: &str) -> Option<(&'a str, &'a str)>;
    fn slice_literal(&self, expected: &str) -> Option<(&'a str, &'a str)>;
    fn slice_start_rest(&self, is_first: |char| -> bool, is_rest: |char| -> bool) -> Option<(&'a str, &'a str)>;
    fn slice_name(&self) -> Option<(&'a str, &'a str)>;
    fn slice_space(&self) -> Option<(&'a str, &'a str)>;
}

impl<'a> XmlStr<'a> for &'a str {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str) {
        (self.slice_to(position), self.slice_from(position))
    }

    fn slice_until(&self, s: &str) -> Option<(&'a str, &'a str)> {
        match self.find_str(s) {
            Some(position) => Some(self.slice_at(position)),
            None => None
        }
    }

    fn slice_literal(&self, expected: &str) -> Option<(&'a str, &'a str)> {
        if self.starts_with(expected) {
            Some(self.slice_at(expected.len()))
        } else {
            None
        }
    }

    fn slice_start_rest(&self,
                        is_first: |char| -> bool,
                        is_rest: |char| -> bool)
                        -> Option<(&'a str, &'a str)>
    {
        let mut positions = self.char_indices();

        match positions.next() {
            Some((_, c)) if is_first(c) => (),
            Some((_, _)) => return None,
            None => return None,
        };

        let mut positions = positions.skip_while(|&(_, c)| is_rest(c));
        match positions.next() {
            Some((offset, _)) => Some(self.slice_at(offset)),
            None => Some((self.clone(), "")),
        }
    }

    fn slice_name(&self) -> Option<(&'a str, &'a str)> {
        self.slice_start_rest(|c| c.is_name_start_char(), |c| c.is_name_char())
    }

    fn slice_space(&self) -> Option<(&'a str, &'a str)> {
        self.slice_start_rest(|c| c.is_space_char(), |c| c.is_space_char())
    }
}

trait XmlChar {
    fn is_name_start_char(&self) -> bool;
    fn is_name_char(&self) -> bool;
    fn is_space_char(&self) -> bool;
}

impl XmlChar for char {
    fn is_name_start_char(&self) -> bool {
        match *self {
            ':'                        |
            'A'..'Z'                   |
            '_'                        |
            'a'..'z'                   |
            '\U000000C0'..'\U000000D6' |
            '\U000000D8'..'\U000000F6' |
            '\U000000F8'..'\U000002FF' |
            '\U00000370'..'\U0000037D' |
            '\U0000037F'..'\U00001FFF' |
            '\U0000200C'..'\U0000200D' |
            '\U00002070'..'\U0000218F' |
            '\U00002C00'..'\U00002FEF' |
            '\U00003001'..'\U0000D7FF' |
            '\U0000F900'..'\U0000FDCF' |
            '\U0000FDF0'..'\U0000FFFD' |
            '\U00010000'..'\U000EFFFF' => true,
            _ => false,
        }
    }

    fn is_name_char(&self) -> bool {
        if self.is_name_start_char() { return true; }
        match *self {
            '-'                |
            '.'                |
            '0'..'9'           |
            '\u00B7'           |
            '\u0300'..'\u036F' |
            '\u203F'..'\u2040' => true,
            _ => false
        }
    }

    fn is_space_char(&self) -> bool {
        match *self {
            '\x20' |
            '\x09' |
            '\x0D' |
            '\x0A' => true,
            _ => false,
        }
    }
}

trait Hax {
    fn first_child(&self) -> Option<RootChild>;
}

impl Hax for Root {
    fn first_child(&self) -> Option<RootChild> {
        self.children().remove(0)
    }
}

trait Hax2 {
    fn first_child(&self) -> Option<ElementChild>;
}

impl Hax2 for Element {
    fn first_child(&self) -> Option<ElementChild> {
        self.children().remove(0)
    }
}

#[test]
fn parses_a_document_with_a_single_element() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello />");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.name().as_slice(), "hello");
}

#[test]
fn parses_an_element_with_an_attribute() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello scope='world'/>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.get_attribute("scope").unwrap().as_slice(), "world");
}

#[test]
fn parses_an_element_with_an_attribute_using_double_quotes() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello scope=\"world\"/>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.get_attribute("scope").unwrap().as_slice(), "world");
}

#[test]
fn parses_an_element_with_multiple_attributes() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello scope=\"world\" happy='true'/>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.get_attribute("scope").unwrap().as_slice(), "world");
    assert_eq!(top.get_attribute("happy").unwrap().as_slice(), "true");
}

#[test]
fn parses_an_element_that_is_not_self_closing() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello></hello>");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.name().as_slice(), "hello");
}

#[test]
fn parses_nested_elements() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello><world/></hello>");
    let nested = doc.root().first_child().unwrap().element().unwrap().first_child().unwrap().element().unwrap();

    assert_eq!(nested.name().as_slice(), "world");
}
<|endoftext|>


<commit_before>// Copyright 2019 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(test)]

extern crate test;

const RAND_BENCH_N: u64 = 1000;

use test::Bencher;
use rand::Rng;
use rand::distributions::WeightedIndex;

#[bench]
fn weighted_index_creation(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    b.iter(|| {
        let weights = [1u32, 2, 4, 0, 5, 1, 7, 1, 2, 3, 4, 5, 6, 7];
        let distr = WeightedIndex::new(weights.to_vec()).unwrap();
        rng.sample(distr)
    })
}

#[bench]
fn weighted_index_modification(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    let weights = [1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7];
    let mut distr = WeightedIndex::new(weights.to_vec()).unwrap();
    b.iter(|| {
        distr.update_weights(&[(2, &4), (5, &1)]).unwrap();
        rng.sample(&distr)
    })
}
<commit_msg>WeightedIndex: Clean up benchmark<commit_after>// Copyright 2019 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(test)]

extern crate test;

use test::Bencher;
use rand::Rng;
use rand::distributions::WeightedIndex;

#[bench]
fn weighted_index_creation(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    let weights = [1u32, 2, 4, 0, 5, 1, 7, 1, 2, 3, 4, 5, 6, 7];
    b.iter(|| {
        let distr = WeightedIndex::new(weights.to_vec()).unwrap();
        rng.sample(distr)
    })
}

#[bench]
fn weighted_index_modification(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    let weights = [1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7];
    let mut distr = WeightedIndex::new(weights.to_vec()).unwrap();
    b.iter(|| {
        distr.update_weights(&[(2, &4), (5, &1)]).unwrap();
        rng.sample(&distr)
    })
}
<|endoftext|>


<commit_before>use assembler::x64::{Addr, R64};
use assembler::x64::R64::*;
use assembler::x64::traits::*;
use assembler::emit::{Emit, Label};

use template_interp::shared::{Dispatchable, build_interp, breakpoint};

use std::mem;
use std::env;

#[derive(Debug, Clone, Copy)]
#[repr(C)]
struct Instr {
    op: Op,
    a: i8,
    imm: [i8; 2],
}

impl Instr {
    fn op_a(op: Op, a: i8) -> Self {
        Instr::op_ai(op, a, 0)
    }

    fn op_i(op: Op, i: i16) -> Self {
        Instr::op_ai(op, 0, i)
    }

    fn op_ai(op: Op, a: i8, i: i16) -> Self {
        Instr {
            op: op,
            a: a,
            imm: unsafe { mem::transmute(i) },
        }
    }

    fn op_abc(op: Op, a: i8, b: i8, c: i8) -> Self {
        Instr {
            op: op,
            a: a,
            imm: [b, c],
        }
    }

    fn op_ab(op: Op, a: i8, b: i8) -> Self {
        Instr::op_abc(op, a, b, 0)
    }
}

fn instrs_to_bs(is: &[Instr]) -> Vec<u8> {
    let mut res = vec![];
    for i in is {
        res.push(i.op as u8);
        res.push(i.a as u8);
        res.push(i.imm[0] as u8);
        res.push(i.imm[1] as u8);
    }
    res
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy)]
enum Rator {
    A_SX,
    B_SX,
    C_SX,
    I_SX,
}

#[derive(Debug, Clone, Copy)]
#[repr(u8)]
enum Op {
    // stack[A] = Imm_i16
    LoadI16 = 0,

    // stack[A] = stack[B] + C_i16
    AddI,

    // stack[A] = stack[B] + stack[C];
    Add,

    // if stack[A] < stack[B]: pc += C_i8
    BLt,

    // if stack[A] < B: pc += C_i8
    BLtI,

    // Callee clears the stack.
    // stack[B] = call(func_table[A_u8])
    // The [B] slot will actually be used by the matching return instr.
    Call,

    // Usually directly consumed by the call instr. Still need to generate
    // impl for it since it can also happen in the entry point.
    // sp += 8 * I_i16
    Enter,

    // t = stack[A]; sp += 8 * I_i16; pc = stack.pop(); stack[pc.B] = t;
    Ret,

    // rax = stack[A]; sp += 8 * I_i16; halt
    Halt,
}

const LAST_OP: Op = Op::Halt;

impl From<u8> for Op {
    fn from(repr: u8) -> Self {
        unsafe { mem::transmute(repr) }
    }
}

impl From<Op> for u8 {
    fn from(repr: Op) -> Self {
        repr as u8
    }
}

struct VMRegs {
    pc: R64,
    dispatch_table: R64,
    func_table: R64,
    tmpa: R64,
    tmpb: R64,
    tmpc: R64,
    sp: R64,
}

impl VMRegs {
    fn new() -> Self {
        VMRegs {
            pc: rdi,
            dispatch_table: rsi,
            func_table: rdx,
            tmpa: rcx,
            tmpb: r8,
            tmpc: r9,
            sp: rsp,
        }
    }
}

const INSTR_SIZE: i32 = 4;

fn dispatch_next_pc_offset(emit: &mut Emit, vr: &VMRegs, offset: i32) {
    if offset == 0 {
        emit.movsb(vr.tmpc, &Addr::B(vr.pc));
        emit.movsb(vr.tmpa, &(vr.pc + 1));
    } else {
        emit.movsb(vr.tmpc, &(vr.pc + offset * INSTR_SIZE))
            .movsb(vr.tmpa, &(vr.pc + (offset * INSTR_SIZE + 1)))
            .add(vr.pc, offset * INSTR_SIZE);
    }

    emit.jmp(&(vr.dispatch_table + vr.tmpc * 8));
}

fn dispatch_next(emit: &mut Emit, vr: &VMRegs) {
    dispatch_next_pc_offset(emit, vr, 1);
}

fn sp_ref(vr: &VMRegs, ix: R64) -> Addr {
    vr.sp + ix * 8
}

fn load_rator(emit: &mut Emit, vr: &VMRegs, rator: Rator) -> R64 {
    use self::Rator::*;
    match rator {
        A_SX => {
            vr.tmpa
        }
        B_SX => {
            emit.movsb(vr.tmpb, &(vr.pc + 2));
            vr.tmpb
        }
        C_SX => {
            emit.movsb(vr.tmpc, &(vr.pc + 3));
            vr.tmpc
        }
        I_SX => {
            emit.movsw(vr.tmpb, &(vr.pc + 2));
            vr.tmpb
        }
    }
}

fn build_dispatch_case(op: Op, emit: &mut Emit, vr: &VMRegs) {
    use self::Op::*;
    match op {
        LoadI16 => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.mov(&sp_ref(vr, vr.tmpa), i);
        }
        AddI => {
            let b = load_rator(emit, vr, Rator::B_SX);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.mov(b, &sp_ref(vr, b))
                .add(b, c)
                .mov(&sp_ref(vr, vr.tmpa), b);
        }
        Add => {
            let b = load_rator(emit, vr, Rator::B_SX);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.mov(b, &sp_ref(vr, b))
                .add(b, &sp_ref(vr, c))
                .mov(&sp_ref(vr, vr.tmpa), b);
        }
        BLt => {
            let mut lt = Label::new();
            let b = load_rator(emit, vr, Rator::B_SX);
            emit.mov(vr.tmpa, &sp_ref(vr, vr.tmpa))
                .cmp(vr.tmpa, &sp_ref(vr, b))
                .jl(&mut lt);
            dispatch_next(emit, vr);

            emit.bind(&mut lt);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.lea(vr.pc, &(vr.pc + c * (INSTR_SIZE as u8) + INSTR_SIZE));
            dispatch_next_pc_offset(emit, vr, 0);
            return;
        }
        BLtI => {
            let mut lt = Label::new();
            let b = load_rator(emit, vr, Rator::B_SX);
            emit.cmp(&sp_ref(vr, vr.tmpa), b)
                .jl(&mut lt);
            dispatch_next(emit, vr);

            emit.bind(&mut lt);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.lea(vr.pc, &(vr.pc + c * (INSTR_SIZE as u8) + INSTR_SIZE));
            dispatch_next_pc_offset(emit, vr, 0);
            return;
        }
        Call => {
            emit.push(vr.pc)
                .mov(vr.pc, &(vr.func_table + vr.tmpa * 8));
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.lea(vr.sp, &(vr.sp + i * 8));
        }
        Enter => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.lea(vr.sp, &(vr.sp + i * 8));
        }
        Ret => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.mov(vr.tmpa, &sp_ref(vr, vr.tmpa))
                .lea(vr.sp, &(vr.sp + i * 8))
                .pop(vr.pc);
            let b = load_rator(emit, vr, Rator::B_SX);
            emit.mov(&sp_ref(vr, b), vr.tmpa);
        }
        Halt => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.mov(rax, &sp_ref(vr, vr.tmpa))
                .lea(vr.sp, &(vr.sp + i * 8))
                .ret();
            return;
        }
    }
    dispatch_next(emit, vr);
}

impl Dispatchable<VMRegs> for Op {
    fn build_dispatch_case(self, emit: &mut Emit, vr: &VMRegs) {
        build_dispatch_case(self, emit, vr)
    }

    // Also decodes instr.A.
    fn build_dispatch_with_pc_offset(emit: &mut Emit, vr: &VMRegs, offset: i32) {
        dispatch_next_pc_offset(emit, vr, offset);
    }
}

pub fn main(n: u8) {
    use self::Op::*;

    let (labels, jm) = build_interp(LAST_OP, &VMRegs::new());

    let main_code = instrs_to_bs(&[
        Instr::op_i(Enter, -1),
        Instr::op_ai(LoadI16, 0, n as i16),
        Instr::op_ab(Call, 2 /* fibo */, 0 /* ->sp[0] */),
        Instr::op_ai(Halt, 0, 1),
    ]);

    let retk_code = instrs_to_bs(&[
        Instr::op_i(Enter, -100),
        Instr::op_ai(LoadI16, 99, 42),
        Instr::op_ai(Ret, 99, 100),
    ]);

    let fibo_code = instrs_to_bs(&[
        Instr::op_i(Enter, -2),
        Instr::op_abc(BLtI, 3, 2, 6),

        // Recur case.
        Instr::op_abc(AddI, 0, 3, -1),
        Instr::op_ab(Call, 2, 1),
        Instr::op_abc(AddI, 0, 3, -2),
        Instr::op_ab(Call, 2, 0),
        Instr::op_abc(Add, 0, 0, 1),
        Instr::op_ai(Ret, 0, 2),

        // Base case.
        Instr::op_ai(Ret, 3, 2),
    ]);

    let func_table = [
        main_code.as_ptr(),
        retk_code.as_ptr(),
        fibo_code.as_ptr(),
    ];

    let res = unsafe {
        let pc = main_code.as_ptr() as isize;
        let lbl_ptr = labels.as_ptr() as isize;
        let func_table_ptr = func_table.as_ptr() as isize;
        if env::var("BREAK").is_ok() {
            breakpoint();
        }
        jm.call_ptr6_ptr(pc, lbl_ptr, func_table_ptr, 0, 0, 0)
    };
    println!("res = {}", res);
}
<commit_msg>Too tired today...<commit_after>use assembler::x64::{Addr, R64};
use assembler::x64::R64::*;
use assembler::x64::traits::*;
use assembler::emit::{Emit, Label};

use template_interp::shared::{Dispatchable, build_interp, breakpoint};

use std::mem;
use std::env;

#[derive(Debug, Clone, Copy)]
#[repr(C)]
struct Instr {
    op: Op,
    a: i8,
    imm: [i8; 2],
}

impl Instr {
    fn op_a(op: Op, a: i8) -> Self {
        Instr::op_ai(op, a, 0)
    }

    fn op_i(op: Op, i: i16) -> Self {
        Instr::op_ai(op, 0, i)
    }

    fn op_ai(op: Op, a: i8, i: i16) -> Self {
        Instr {
            op: op,
            a: a,
            imm: unsafe { mem::transmute(i) },
        }
    }

    fn op_abc(op: Op, a: i8, b: i8, c: i8) -> Self {
        Instr {
            op: op,
            a: a,
            imm: [b, c],
        }
    }

    fn op_ab(op: Op, a: i8, b: i8) -> Self {
        Instr::op_abc(op, a, b, 0)
    }
}

fn instrs_to_bs(is: &[Instr]) -> Vec<u8> {
    let mut res = vec![];
    for i in is {
        res.push(i.op as u8);
        res.push(i.a as u8);
        res.push(i.imm[0] as u8);
        res.push(i.imm[1] as u8);
    }
    res
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy)]
enum Rator {
    A_SX,
    B_SX,
    C_SX,
    I_SX,
}

#[derive(Debug, Clone, Copy)]
#[repr(u8)]
enum Op {
    // stack[A] = Imm_i16
    LoadI16 = 0,

    // stack[A] = stack[B] + C_i16
    AddI,

    // stack[A] = stack[B] + stack[C];
    Add,

    // if stack[A] < stack[B]: pc += C_i8
    BLt,

    // if stack[A] < B: pc += C_i8
    BLtI,

    // Callee clears the stack.
    // stack[B] = call(func_table[A_u8])
    // The [B] slot will actually be used by the matching return instr.
    Call,

    // Usually directly consumed by the call instr. Still need to generate
    // impl for it since it can also happen in the entry point.
    // sp += 8 * I_i16
    Enter,

    // t = stack[A]; sp += 8 * I_i16; pc = stack.pop(); stack[pc.B] = t;
    Ret,

    // rax = stack[A]; sp += 8 * I_i16; halt
    Halt,
}

const LAST_OP: Op = Op::Halt;

impl From<u8> for Op {
    fn from(repr: u8) -> Self {
        unsafe { mem::transmute(repr) }
    }
}

impl From<Op> for u8 {
    fn from(repr: Op) -> Self {
        repr as u8
    }
}

struct VMRegs {
    pc: R64,
    dispatch_table: R64,
    func_table: R64,
    tmpa: R64,
    tmpb: R64,
    tmpc: R64,
    sp: R64,
}

impl VMRegs {
    fn new() -> Self {
        VMRegs {
            pc: rdi,
            dispatch_table: rsi,
            func_table: rdx,
            tmpa: rcx,
            tmpb: r8,
            tmpc: r9,
            sp: rsp,
        }
    }
}

const INSTR_SIZE: i32 = 4;

fn dispatch_next_pc_offset(emit: &mut Emit, vr: &VMRegs, offset: i32) {
    if offset == 0 {
        emit.movsb(vr.tmpc, &Addr::B(vr.pc))
            .movsb(vr.tmpa, &(vr.pc + 1));
    } else {
        emit.movsb(vr.tmpc, &(vr.pc + offset * INSTR_SIZE))
            .movsb(vr.tmpa, &(vr.pc + (offset * INSTR_SIZE + 1)))
            .add(vr.pc, offset * INSTR_SIZE);
    }

    emit.jmp(&(vr.dispatch_table + vr.tmpc * 8));
}

fn dispatch_next(emit: &mut Emit, vr: &VMRegs) {
    dispatch_next_pc_offset(emit, vr, 1);
}

fn sp_ref(vr: &VMRegs, ix: R64) -> Addr {
    vr.sp + ix * 8
}

fn load_rator(emit: &mut Emit, vr: &VMRegs, rator: Rator) -> R64 {
    use self::Rator::*;
    match rator {
        A_SX => {
            vr.tmpa
        }
        B_SX => {
            emit.movsb(vr.tmpb, &(vr.pc + 2));
            vr.tmpb
        }
        C_SX => {
            emit.movsb(vr.tmpc, &(vr.pc + 3));
            vr.tmpc
        }
        I_SX => {
            emit.movsw(vr.tmpb, &(vr.pc + 2));
            vr.tmpb
        }
    }
}

fn build_dispatch_case(op: Op, emit: &mut Emit, vr: &VMRegs) {
    use self::Op::*;
    match op {
        LoadI16 => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.mov(&sp_ref(vr, vr.tmpa), i);
        }
        AddI => {
            let b = load_rator(emit, vr, Rator::B_SX);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.mov(b, &sp_ref(vr, b))
                .add(b, c)
                .mov(&sp_ref(vr, vr.tmpa), b);
        }
        Add => {
            let b = load_rator(emit, vr, Rator::B_SX);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.mov(b, &sp_ref(vr, b))
                .add(b, &sp_ref(vr, c))
                .mov(&sp_ref(vr, vr.tmpa), b);
        }
        BLt => {
            let mut lt = Label::new();
            let b = load_rator(emit, vr, Rator::B_SX);
            emit.mov(vr.tmpa, &sp_ref(vr, vr.tmpa))
                .cmp(vr.tmpa, &sp_ref(vr, b))
                .jl(&mut lt);
            dispatch_next(emit, vr);

            emit.bind(&mut lt);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.lea(vr.pc, &(vr.pc + c * (INSTR_SIZE as u8) + INSTR_SIZE));
            dispatch_next_pc_offset(emit, vr, 0);
            return;
        }
        BLtI => {
            let mut lt = Label::new();
            let b = load_rator(emit, vr, Rator::B_SX);
            emit.cmp(&sp_ref(vr, vr.tmpa), b)
                .jl(&mut lt);
            dispatch_next(emit, vr);

            emit.bind(&mut lt);
            let c = load_rator(emit, vr, Rator::C_SX);
            emit.lea(vr.pc, &(vr.pc + c * (INSTR_SIZE as u8) + INSTR_SIZE));
            dispatch_next_pc_offset(emit, vr, 0);
            return;
        }
        Call => {
            emit.push(vr.pc)
                .mov(vr.pc, &(vr.func_table + vr.tmpa * 8));
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.lea(vr.sp, &(vr.sp + i * 8));
        }
        Enter => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.lea(vr.sp, &(vr.sp + i * 8));
        }
        Ret => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.mov(vr.tmpa, &sp_ref(vr, vr.tmpa))
                .lea(vr.sp, &(vr.sp + i * 8))
                .pop(vr.pc);
            let b = load_rator(emit, vr, Rator::B_SX);
            emit.mov(&sp_ref(vr, b), vr.tmpa);
        }
        Halt => {
            let i = load_rator(emit, vr, Rator::I_SX);
            emit.mov(rax, &sp_ref(vr, vr.tmpa))
                .lea(vr.sp, &(vr.sp + i * 8))
                .ret();
            return;
        }
    }
    dispatch_next(emit, vr);
}

impl Dispatchable<VMRegs> for Op {
    fn build_dispatch_case(self, emit: &mut Emit, vr: &VMRegs) {
        build_dispatch_case(self, emit, vr)
    }

    // Also decodes instr.A.
    fn build_dispatch_with_pc_offset(emit: &mut Emit, vr: &VMRegs, offset: i32) {
        dispatch_next_pc_offset(emit, vr, offset);
    }
}

pub fn main(n: u8) {
    use self::Op::*;

    let (labels, jm) = build_interp(LAST_OP, &VMRegs::new());

    let main_code = instrs_to_bs(&[
        Instr::op_i(Enter, -1),
        Instr::op_ai(LoadI16, 0, n as i16),
        Instr::op_ab(Call, 2 /* fibo */, 0 /* ->sp[0] */),
        Instr::op_ai(Halt, 0, 1),
    ]);

    let retk_code = instrs_to_bs(&[
        Instr::op_i(Enter, -100),
        Instr::op_ai(LoadI16, 99, 42),
        Instr::op_ai(Ret, 99, 100),
    ]);

    let fibo_code = instrs_to_bs(&[
        Instr::op_i(Enter, -2),
        Instr::op_abc(BLtI, 3, 2, 6),

        // Recur case.
        Instr::op_abc(AddI, 0, 3, -1),
        Instr::op_ab(Call, 2, 1),
        Instr::op_abc(AddI, 0, 3, -2),
        Instr::op_ab(Call, 2, 0),
        Instr::op_abc(Add, 0, 0, 1),
        Instr::op_ai(Ret, 0, 2),

        // Base case.
        Instr::op_ai(Ret, 3, 2),
    ]);

    let func_table = [
        main_code.as_ptr(),
        retk_code.as_ptr(),
        fibo_code.as_ptr(),
    ];

    let res = unsafe {
        let pc = main_code.as_ptr() as isize;
        let lbl_ptr = labels.as_ptr() as isize;
        let func_table_ptr = func_table.as_ptr() as isize;
        if env::var("BREAK").is_ok() {
            breakpoint();
        }
        jm.call_ptr6_ptr(pc, lbl_ptr, func_table_ptr, 0, 0, 0)
    };
    println!("res = {}", res);
}
<|endoftext|>


<commit_before>#[derive(Debug)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }
}

impl Tree {
    fn new(v: &i32) -> Tree {
        Tree {
            enter: Node::new(v),
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };
        //println!("target is -> {:?}", target);
        match target {
            Some(next) => {
                //println!("next is -> {:?}", &next);
                next.insert(v)
            }
            None => {
                let new_node = Node::new(v);
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> Result<&mut Self, String> {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up_while(&mut self, v: &i32) -> Result<&mut Self, String> {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }
}

fn main() {
    let mut a = Tree::new(&3);
    a.insert(&2);
    a.insert(&1);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    println!("{:?}", a.look_up_while(&1));
}
<commit_msg>switch function name<commit_after>#[derive(Debug)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }
}

impl Tree {
    fn new(v: &i32) -> Tree {
        Tree {
            enter: Node::new(v),
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };
        //println!("target is -> {:?}", target);
        match target {
            Some(next) => {
                //println!("next is -> {:?}", &next);
                next.insert(v)
            }
            None => {
                let new_node = Node::new(v);
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> Result<&mut Self, String> {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> Result<&mut Self, String> {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn left_shift(&mut self, v: &i32) {}
}

fn main() {
    let mut a = Tree::new(&3);
    a.insert(&2);
    a.insert(&1);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    println!("{:?}", a.look_up(&1));
    println!("{:?}", a);
}
<|endoftext|>


<commit_before>use std::sync::{Arc, RwLock};
use std::option::Option;
use std::clone::Clone;

use uuid::Uuid;

type OptInt32 = Option<i32>;
type OptInt64 = Option<i64>;
type OptString = Option<String>;

#[derive(Clone)]
pub enum CellType {
    Int32 (OptInt32),
    Int64 (OptInt64),
    Text  (OptString)
}

pub struct CellFormat {
    pub fieldname: String,
    pub fieldtype: CellType
}

pub struct RecFormat {
    pub cols: Vec<CellFormat>
}

impl RecFormat {
    pub fn new(fields: Vec<CellFormat>) -> Arc<RwLock<RecFormat>> {
        return Arc::new(RwLock::new(RecFormat { cols: fields } ));
    }
}

/*
trait Formattable {
    fn own_format(&mut self) {
        self.format = RecFormat::new(self.format.cols);
    }
}
*/

pub struct Rec {
    pub guid: Uuid,
    pub cells: Vec<CellType>,
    pub format: Arc<RwLock<RecFormat>>
}

impl Rec {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> Rec {
        let cells = format
                        .read()
                        .unwrap()
                        .cols
                        .iter()
                        .map(|x| x.fieldtype.clone()).collect::<Vec<CellType>>();
        return Rec { guid: Uuid::new_v4(),
                     cells: cells,
                     format: format
                   };
    }
}

/*
impl Formattable for Rec {
}
*/

pub struct RecCollection {
    pub rows: Vec<Rec>,
    pub format: Arc<RwLock<RecFormat>>
}

impl RecCollection {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> RecCollection {
        return Table {
            format: format,
            rows: Vec::new()
        };
    }
}

pub struct Table {
    pub data: RecCollection,
    pub guid: Uuid,
    pub name: String
}<commit_msg>Fix build<commit_after>use std::sync::{Arc, RwLock};
use std::option::Option;
use std::clone::Clone;

use uuid::Uuid;

type OptInt32 = Option<i32>;
type OptInt64 = Option<i64>;
type OptString = Option<String>;

#[derive(Clone)]
pub enum CellType {
    Int32 (OptInt32),
    Int64 (OptInt64),
    Text  (OptString)
}

pub struct CellFormat {
    pub fieldname: String,
    pub fieldtype: CellType
}

pub struct RecFormat {
    pub cols: Vec<CellFormat>
}

impl RecFormat {
    pub fn new(fields: Vec<CellFormat>) -> Arc<RwLock<RecFormat>> {
        return Arc::new(RwLock::new(RecFormat { cols: fields } ));
    }
}

/*
trait Formattable {
    fn own_format(&mut self) {
        self.format = RecFormat::new(self.format.cols);
    }
}
*/

pub struct Rec {
    pub guid: Uuid,
    pub cells: Vec<CellType>,
    pub format: Arc<RwLock<RecFormat>>
}

impl Rec {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> Rec {
        let cells = format
                        .read()
                        .unwrap()
                        .cols
                        .iter()
                        .map(|x| x.fieldtype.clone()).collect::<Vec<CellType>>();
        return Rec { guid: Uuid::new_v4(),
                     cells: cells,
                     format: format
                   };
    }
}

/*
impl Formattable for Rec {
}
*/

pub struct RecCollection {
    pub rows: Vec<Rec>,
    pub format: Arc<RwLock<RecFormat>>
}

impl RecCollection {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> RecCollection {
        return RecCollection {
            format: format,
            rows: Vec::new()
        };
    }
}

pub struct Table {
    pub data: RecCollection,
    pub guid: Uuid,
    pub name: String
}<|endoftext|>


<commit_before>use std::sync::{Arc, RwLock};
use std::option::Option;
use std::clone::Clone;

use uuid::Uuid;

type OptInt32 = Option<i32>;
type OptInt64 = Option<i64>;
type OptString = Option<String>;

#[derive(Clone)]
pub enum CellType {
    Int32 (OptInt32),
    Int64 (OptInt64),
    Text  (OptString)
}

pub struct CellFormat {
    pub fieldname: String,
    pub fieldtype: CellType
}

pub struct RecFormat {
    pub cols: Vec<CellFormat>
}

impl RecFormat {
    pub fn new(fields: Vec<CellFormat>) -> Arc<RwLock<RecFormat>> {
        return Arc::new(RwLock::new(RecFormat { cols: fields } ));
    }
}

trait Formattable {
    fn own_format(&mut self) {
        self.format = RecFormat::new(self.format.cols);
    }
}

pub struct Rec {
    pub guid: Uuid,
    pub cells: Vec<CellType>,
    pub format: Arc<RwLock<RecFormat>>
}

impl Rec {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> Rec {
        let cells = format
                        .read()
                        .unwrap()
                        .cols
                        .iter()
                        .map(|x| x.type_.clone()).collect::<Vec<CellType>>();
        return Rec { guid: Uuid::new_v4(),
                     cells: cells,
                     format: format
                   };
    }
}

impl Formattable for Rec {
}

pub struct Table {
    pub name: String,
    pub rows: Vec<Rec>,
    pub format: Arc<RwLock<RecFormat>>
}

impl Table {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> Table {
        return Table {
            format: format
        };
    }
}
<commit_msg>Add another custom constructor for Table<commit_after>use std::sync::{Arc, RwLock};
use std::option::Option;
use std::clone::Clone;

use uuid::Uuid;

type OptInt32 = Option<i32>;
type OptInt64 = Option<i64>;
type OptString = Option<String>;

#[derive(Clone)]
pub enum CellType {
    Int32 (OptInt32),
    Int64 (OptInt64),
    Text  (OptString)
}

pub struct CellFormat {
    pub fieldname: String,
    pub fieldtype: CellType
}

pub struct RecFormat {
    pub cols: Vec<CellFormat>
}

impl RecFormat {
    pub fn new(fields: Vec<CellFormat>) -> Arc<RwLock<RecFormat>> {
        return Arc::new(RwLock::new(RecFormat { cols: fields } ));
    }
}

/*
trait Formattable {
    fn own_format(&mut self) {
        self.format = RecFormat::new(self.format.cols);
    }
}
*/

pub struct Rec {
    pub guid: Uuid,
    pub cells: Vec<CellType>,
    pub format: Arc<RwLock<RecFormat>>
}

impl Rec {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> Rec {
        let cells = format
                        .read()
                        .unwrap()
                        .cols
                        .iter()
                        .map(|x| x.type_.clone()).collect::<Vec<CellType>>();
        return Rec { guid: Uuid::new_v4(),
                     cells: cells,
                     format: format
                   };
    }
}

/*
impl Formattable for Rec {
}
*/

pub struct Table {
    pub name: String,
    pub rows: Vec<Rec>,
    pub format: Arc<RwLock<RecFormat>>
}

impl Table {
    pub fn new(format: Arc<RwLock<RecFormat>>) -> Table {
        return Table {
            format: format
        };
    }
    pub fn new(format: Arc<RwLock<RecFormat>>, name: String) -> Table {
        return Table {
            name: name,
            format: format
        };
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! The style bloom filter is used as an optimization when matching deep
//! descendant selectors.

#![deny(missing_docs)]

use dom::{SendElement, TElement};
use selectors::bloom::BloomFilter;
use smallvec::SmallVec;

/// A struct that allows us to fast-reject deep descendant selectors avoiding
/// selector-matching.
///
/// This is implemented using a counting bloom filter, and it's a standard
/// optimization. See Gecko's `AncestorFilter`, and Blink's and WebKit's
/// `SelectorFilter`.
///
/// The constraints for Servo's style system are a bit different compared to
/// traditional style systems given Servo does a parallel breadth-first
/// traversal instead of a sequential depth-first traversal.
///
/// This implies that we need to track a bit more state than other browsers to
/// ensure we're doing the correct thing during the traversal, and being able to
/// apply this optimization effectively.
///
/// Concretely, we have a bloom filter instance per worker thread, and we track
/// the current DOM depth in order to find a common ancestor when it doesn't
/// match the previous element we've styled.
///
/// This is usually a pretty fast operation (we use to be one level deeper than
/// the previous one), but in the case of work-stealing, we may needed to push
/// and pop multiple elements.
///
/// See the `insert_parents_recovering`, where most of the magic happens.
///
/// Regarding thread-safety, this struct is safe because:
///
///  * We clear this after a restyle.
///  * The DOM shape and attributes (and every other thing we access here) are
///    immutable during a restyle.
///
pub struct StyleBloom<E: TElement> {
    /// The bloom filter per se.
    filter: Box<BloomFilter>,

    /// The stack of elements that this bloom filter contains.
    elements: Vec<SendElement<E>>,
}

fn each_relevant_element_hash<E, F>(element: E, mut f: F)
    where E: TElement,
          F: FnMut(u32),
{
    f(element.get_local_name().get_hash());
    f(element.get_namespace().get_hash());

    if let Some(id) = element.get_id() {
        f(id.get_hash());
    }

    // TODO: case-sensitivity depends on the document type and quirks mode.
    //
    // TODO(emilio): It's not clear whether that's relevant here though?
    // Classes and ids should be normalized already I think.
    element.each_class(|class| {
        f(class.get_hash())
    });
}

impl<E: TElement> StyleBloom<E> {
    /// Create an empty `StyleBloom`.
    pub fn new() -> Self {
        StyleBloom {
            filter: Box::new(BloomFilter::new()),
            elements: vec![],
        }
    }

    /// Return the bloom filter used properly by the `selectors` crate.
    pub fn filter(&self) -> &BloomFilter {
        &*self.filter
    }

    /// Push an element to the bloom filter, knowing that it's a child of the
    /// last element parent.
    pub fn push(&mut self, element: E) {
        if cfg!(debug_assertions) {
            if self.elements.is_empty() {
                assert!(element.traversal_parent().is_none());
            }
        }
        self.push_internal(element);
    }

    /// Same as `push`, but without asserting, in order to use it from
    /// `rebuild`.
    fn push_internal(&mut self, element: E) {
        each_relevant_element_hash(element, |hash| {
            self.filter.insert_hash(hash);
        });
        self.elements.push(unsafe { SendElement::new(element) });
    }

    /// Pop the last element in the bloom filter and return it.
    fn pop(&mut self) -> Option<E> {
        let popped = self.elements.pop().map(|el| *el);

        if let Some(popped) = popped {
            each_relevant_element_hash(popped, |hash| {
                self.filter.remove_hash(hash);
            })
        }

        popped
    }

    /// Returns true if the bloom filter is empty.
    pub fn is_empty(&self) -> bool {
        self.elements.is_empty()
    }

    /// Returns the DOM depth of elements that can be correctly
    /// matched against the bloom filter (that is, the number of
    /// elements in our list).
    pub fn matching_depth(&self) -> usize {
        self.elements.len()
    }

    /// Clears the bloom filter.
    pub fn clear(&mut self) {
        self.filter.clear();
        self.elements.clear();
    }

    /// Rebuilds the bloom filter up to the parent of the given element.
    pub fn rebuild(&mut self, mut element: E) {
        self.clear();

        let mut parents_to_insert = SmallVec::<[E; 16]>::new();
        while let Some(parent) = element.traversal_parent() {
            parents_to_insert.push(parent);
            element = parent;
        }

        for parent in parents_to_insert.drain().rev() {
            self.push(parent);
        }
    }

    /// In debug builds, asserts that all the parents of `element` are in the
    /// bloom filter.
    ///
    /// Goes away in release builds.
    pub fn assert_complete(&self, mut element: E) {
        if cfg!(debug_assertions) {
            let mut checked = 0;
            while let Some(parent) = element.traversal_parent() {
                assert_eq!(parent, *self.elements[self.elements.len() - 1 - checked]);
                element = parent;
                checked += 1;
            }
            assert_eq!(checked, self.elements.len());
        }
    }

    /// Get the element that represents the chain of things inserted
    /// into the filter right now.  That chain is the given element
    /// (if any) and its ancestors.
    #[inline]
    pub fn current_parent(&self) -> Option<E> {
        self.elements.last().map(|el| **el)
    }

    /// Insert the parents of an element in the bloom filter, trying to recover
    /// the filter if the last element inserted doesn't match.
    ///
    /// Gets the element depth in the dom, to make it efficient, or if not
    /// provided always rebuilds the filter from scratch.
    ///
    /// Returns the new bloom filter depth, that the traversal code is
    /// responsible to keep around if it wants to get an effective filter.
    pub fn insert_parents_recovering(&mut self,
                                     element: E,
                                     element_depth: usize)
    {
        // Easy case, we're in a different restyle, or we're empty.
        if self.elements.is_empty() {
            self.rebuild(element);
            return;
        }

        let traversal_parent = match element.traversal_parent() {
            Some(parent) => parent,
            None => {
                // Yay, another easy case.
                self.clear();
                return;
            }
        };

        if self.current_parent() == Some(traversal_parent) {
            // Ta da, cache hit, we're all done.
            return;
        }

        if element_depth == 0 {
            self.clear();
            return;
        }

        // We should've early exited above.
        debug_assert!(element_depth != 0,
                      "We should have already cleared the bloom filter");
        debug_assert!(!self.elements.is_empty(),
                      "How! We should've just rebuilt!");

        // Now the fun begins: We have the depth of the dom and the depth of the
        // last element inserted in the filter, let's try to find a common
        // parent.
        //
        // The current depth, that is, the depth of the last element inserted in
        // the bloom filter, is the number of elements _minus one_, that is: if
        // there's one element, it must be the root -> depth zero.
        let mut current_depth = self.elements.len() - 1;

        // If the filter represents an element too deep in the dom, we need to
        // pop ancestors.
        while current_depth > element_depth - 1 {
            self.pop().expect("Emilio is bad at math");
            current_depth -= 1;
        }

        // Now let's try to find a common parent in the bloom filter chain,
        // starting with traversal_parent.
        let mut common_parent = traversal_parent;
        let mut common_parent_depth = element_depth - 1;

        // Let's collect the parents we are going to need to insert once we've
        // found the common one.
        let mut parents_to_insert = SmallVec::<[E; 16]>::new();

        // If the bloom filter still doesn't have enough elements, the common
        // parent is up in the dom.
        while common_parent_depth > current_depth {
            // TODO(emilio): Seems like we could insert parents here, then
            // reverse the slice.
            parents_to_insert.push(common_parent);
            common_parent =
                common_parent.traversal_parent().expect("We were lied to");
            common_parent_depth -= 1;
        }

        // Now the two depths are the same.
        debug_assert_eq!(common_parent_depth, current_depth);

        // Happy case: The parents match, we only need to push the ancestors
        // we've collected and we'll never enter in this loop.
        //
        // Not-so-happy case: Parent's don't match, so we need to keep going up
        // until we find a common ancestor.
        //
        // Gecko currently models native anonymous content that conceptually
        // hangs off the document (such as scrollbars) as a separate subtree
        // from the document root.
        //
        // Thus it's possible with Gecko that we do not find any common
        // ancestor.
        while **self.elements.last().unwrap() != common_parent {
            parents_to_insert.push(common_parent);
            self.pop().unwrap();
            common_parent = match common_parent.traversal_parent() {
                Some(parent) => parent,
                None => {
                    debug_assert!(self.elements.is_empty());
                    if cfg!(feature = "gecko") {
                        break;
                    } else {
                        panic!("should have found a common ancestor");
                    }
                }
            }
        }

        // Now the parents match, so insert the stack of elements we have been
        // collecting so far.
        for parent in parents_to_insert.drain().rev() {
            self.push(parent);
        }

        debug_assert_eq!(self.elements.len(), element_depth);

        // We're done! Easy.
    }
}
<commit_msg>Switch the bloom element list to a SmallVec and track pushed hashes.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! The style bloom filter is used as an optimization when matching deep
//! descendant selectors.

#![deny(missing_docs)]

use dom::{SendElement, TElement};
use selectors::bloom::BloomFilter;
use smallvec::SmallVec;

/// A struct that allows us to fast-reject deep descendant selectors avoiding
/// selector-matching.
///
/// This is implemented using a counting bloom filter, and it's a standard
/// optimization. See Gecko's `AncestorFilter`, and Blink's and WebKit's
/// `SelectorFilter`.
///
/// The constraints for Servo's style system are a bit different compared to
/// traditional style systems given Servo does a parallel breadth-first
/// traversal instead of a sequential depth-first traversal.
///
/// This implies that we need to track a bit more state than other browsers to
/// ensure we're doing the correct thing during the traversal, and being able to
/// apply this optimization effectively.
///
/// Concretely, we have a bloom filter instance per worker thread, and we track
/// the current DOM depth in order to find a common ancestor when it doesn't
/// match the previous element we've styled.
///
/// This is usually a pretty fast operation (we use to be one level deeper than
/// the previous one), but in the case of work-stealing, we may needed to push
/// and pop multiple elements.
///
/// See the `insert_parents_recovering`, where most of the magic happens.
///
/// Regarding thread-safety, this struct is safe because:
///
///  * We clear this after a restyle.
///  * The DOM shape and attributes (and every other thing we access here) are
///    immutable during a restyle.
///
pub struct StyleBloom<E: TElement> {
    /// The bloom filter per se.
    filter: Box<BloomFilter>,

    /// The stack of elements that this bloom filter contains, along with the
    /// number of hashes pushed for each element.
    elements: SmallVec<[PushedElement<E>; 16]>,

    /// Stack of hashes that have been pushed onto this filter.
    pushed_hashes: SmallVec<[u32; 64]>,
}

struct PushedElement<E: TElement> {
    /// The element that was pushed.
    element: SendElement<E>,

    /// The number of hashes pushed for the element.
    num_hashes: usize,
}

impl<E: TElement> PushedElement<E> {
    fn new(el: E, num_hashes: usize) -> Self {
        PushedElement {
            element: unsafe { SendElement::new(el) },
            num_hashes: num_hashes,
        }
    }
}

fn each_relevant_element_hash<E, F>(element: E, mut f: F)
    where E: TElement,
          F: FnMut(u32),
{
    f(element.get_local_name().get_hash());
    f(element.get_namespace().get_hash());

    if let Some(id) = element.get_id() {
        f(id.get_hash());
    }

    // TODO: case-sensitivity depends on the document type and quirks mode.
    //
    // TODO(emilio): It's not clear whether that's relevant here though?
    // Classes and ids should be normalized already I think.
    element.each_class(|class| {
        f(class.get_hash())
    });
}

impl<E: TElement> StyleBloom<E> {
    /// Create an empty `StyleBloom`.
    pub fn new() -> Self {
        StyleBloom {
            filter: Box::new(BloomFilter::new()),
            elements: Default::default(),
            pushed_hashes: Default::default(),
        }
    }

    /// Return the bloom filter used properly by the `selectors` crate.
    pub fn filter(&self) -> &BloomFilter {
        &*self.filter
    }

    /// Push an element to the bloom filter, knowing that it's a child of the
    /// last element parent.
    pub fn push(&mut self, element: E) {
        if cfg!(debug_assertions) {
            if self.elements.is_empty() {
                assert!(element.traversal_parent().is_none());
            }
        }
        self.push_internal(element);
    }

    /// Same as `push`, but without asserting, in order to use it from
    /// `rebuild`.
    fn push_internal(&mut self, element: E) {
        let mut count = 0;
        each_relevant_element_hash(element, |hash| {
            count += 1;
            self.filter.insert_hash(hash);
            self.pushed_hashes.push(hash);
        });
        self.elements.push(PushedElement::new(element, count));
    }

    /// Pop the last element in the bloom filter and return it.
    #[inline]
    fn pop(&mut self) -> Option<E> {
        let (popped_element, num_hashes)  = match self.elements.pop() {
            None => return None,
            Some(x) => (*x.element, x.num_hashes),
        };

        // Verify that the pushed hashes match the ones we'd get from the element.
        let mut expected_hashes = vec![];
        if cfg!(debug_assertions) {
            each_relevant_element_hash(popped_element, |hash| expected_hashes.push(hash));
        }

        for _ in 0..num_hashes {
            let hash = self.pushed_hashes.pop().unwrap();
            debug_assert_eq!(expected_hashes.pop().unwrap(), hash);
            self.filter.remove_hash(hash);
        }

        Some(popped_element)
    }

    /// Returns true if the bloom filter is empty.
    pub fn is_empty(&self) -> bool {
        self.elements.is_empty()
    }

    /// Returns the DOM depth of elements that can be correctly
    /// matched against the bloom filter (that is, the number of
    /// elements in our list).
    pub fn matching_depth(&self) -> usize {
        self.elements.len()
    }

    /// Clears the bloom filter.
    pub fn clear(&mut self) {
        self.filter.clear();
        self.elements.clear();
    }

    /// Rebuilds the bloom filter up to the parent of the given element.
    pub fn rebuild(&mut self, mut element: E) {
        self.clear();

        let mut parents_to_insert = SmallVec::<[E; 16]>::new();
        while let Some(parent) = element.traversal_parent() {
            parents_to_insert.push(parent);
            element = parent;
        }

        for parent in parents_to_insert.drain().rev() {
            self.push(parent);
        }
    }

    /// In debug builds, asserts that all the parents of `element` are in the
    /// bloom filter.
    ///
    /// Goes away in release builds.
    pub fn assert_complete(&self, mut element: E) {
        if cfg!(debug_assertions) {
            let mut checked = 0;
            while let Some(parent) = element.traversal_parent() {
                assert_eq!(parent, *(self.elements[self.elements.len() - 1 - checked].element));
                element = parent;
                checked += 1;
            }
            assert_eq!(checked, self.elements.len());
        }
    }

    /// Get the element that represents the chain of things inserted
    /// into the filter right now.  That chain is the given element
    /// (if any) and its ancestors.
    #[inline]
    pub fn current_parent(&self) -> Option<E> {
        self.elements.last().map(|ref el| *el.element)
    }

    /// Insert the parents of an element in the bloom filter, trying to recover
    /// the filter if the last element inserted doesn't match.
    ///
    /// Gets the element depth in the dom, to make it efficient, or if not
    /// provided always rebuilds the filter from scratch.
    ///
    /// Returns the new bloom filter depth, that the traversal code is
    /// responsible to keep around if it wants to get an effective filter.
    pub fn insert_parents_recovering(&mut self,
                                     element: E,
                                     element_depth: usize)
    {
        // Easy case, we're in a different restyle, or we're empty.
        if self.elements.is_empty() {
            self.rebuild(element);
            return;
        }

        let traversal_parent = match element.traversal_parent() {
            Some(parent) => parent,
            None => {
                // Yay, another easy case.
                self.clear();
                return;
            }
        };

        if self.current_parent() == Some(traversal_parent) {
            // Ta da, cache hit, we're all done.
            return;
        }

        if element_depth == 0 {
            self.clear();
            return;
        }

        // We should've early exited above.
        debug_assert!(element_depth != 0,
                      "We should have already cleared the bloom filter");
        debug_assert!(!self.elements.is_empty(),
                      "How! We should've just rebuilt!");

        // Now the fun begins: We have the depth of the dom and the depth of the
        // last element inserted in the filter, let's try to find a common
        // parent.
        //
        // The current depth, that is, the depth of the last element inserted in
        // the bloom filter, is the number of elements _minus one_, that is: if
        // there's one element, it must be the root -> depth zero.
        let mut current_depth = self.elements.len() - 1;

        // If the filter represents an element too deep in the dom, we need to
        // pop ancestors.
        while current_depth > element_depth - 1 {
            self.pop().expect("Emilio is bad at math");
            current_depth -= 1;
        }

        // Now let's try to find a common parent in the bloom filter chain,
        // starting with traversal_parent.
        let mut common_parent = traversal_parent;
        let mut common_parent_depth = element_depth - 1;

        // Let's collect the parents we are going to need to insert once we've
        // found the common one.
        let mut parents_to_insert = SmallVec::<[E; 16]>::new();

        // If the bloom filter still doesn't have enough elements, the common
        // parent is up in the dom.
        while common_parent_depth > current_depth {
            // TODO(emilio): Seems like we could insert parents here, then
            // reverse the slice.
            parents_to_insert.push(common_parent);
            common_parent =
                common_parent.traversal_parent().expect("We were lied to");
            common_parent_depth -= 1;
        }

        // Now the two depths are the same.
        debug_assert_eq!(common_parent_depth, current_depth);

        // Happy case: The parents match, we only need to push the ancestors
        // we've collected and we'll never enter in this loop.
        //
        // Not-so-happy case: Parent's don't match, so we need to keep going up
        // until we find a common ancestor.
        //
        // Gecko currently models native anonymous content that conceptually
        // hangs off the document (such as scrollbars) as a separate subtree
        // from the document root.
        //
        // Thus it's possible with Gecko that we do not find any common
        // ancestor.
        while *(self.elements.last().unwrap().element) != common_parent {
            parents_to_insert.push(common_parent);
            self.pop().unwrap();
            common_parent = match common_parent.traversal_parent() {
                Some(parent) => parent,
                None => {
                    debug_assert!(self.elements.is_empty());
                    if cfg!(feature = "gecko") {
                        break;
                    } else {
                        panic!("should have found a common ancestor");
                    }
                }
            }
        }

        // Now the parents match, so insert the stack of elements we have been
        // collecting so far.
        for parent in parents_to_insert.drain().rev() {
            self.push(parent);
        }

        debug_assert_eq!(self.elements.len(), element_depth);

        // We're done! Easy.
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate enum_map;

use enum_map::{EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;

#[derive(Copy, Clone, Debug, EnumMap, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_option_bool() {
    let mut map = enum_map! { None => 1, Some(false) => 2, Some(true) => 3};
    assert_eq!(map[None], 1);
    assert_eq!(map[Some(false)], 2);
    assert_eq!(map[Some(true)], 3);
    map[None] = 4;
    map[Some(false)] = 5;
    map[Some(true)] = 6;
    assert_eq!(map[None], 4);
    assert_eq!(map[Some(false)], 5);
    assert_eq!(map[Some(true)], 6);
    assert_eq!(map.as_slice(), [4, 5, 6]);
    assert_eq!(
        map.into_iter().collect::<Vec<_>>(),
        [(None, 4), (Some(false), 5), (Some(true), 6)]
    );
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn discriminants() {
    #[derive(Debug, EnumMap, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(EnumMap)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }.into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn test_u8() {
    let map = enum_map! { b'a' => 4, _ => 0 };
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
}

#[derive(EnumMap)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map!{};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}
<commit_msg>Test next_back for IterMut<commit_after>#[macro_use]
extern crate enum_map;

use enum_map::{EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;

#[derive(Copy, Clone, Debug, EnumMap, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_option_bool() {
    let mut map = enum_map! { None => 1, Some(false) => 2, Some(true) => 3};
    assert_eq!(map[None], 1);
    assert_eq!(map[Some(false)], 2);
    assert_eq!(map[Some(true)], 3);
    map[None] = 4;
    map[Some(false)] = 5;
    map[Some(true)] = 6;
    assert_eq!(map[None], 4);
    assert_eq!(map[Some(false)], 5);
    assert_eq!(map[Some(true)], 6);
    assert_eq!(map.as_slice(), [4, 5, 6]);
    assert_eq!(
        map.into_iter().collect::<Vec<_>>(),
        [(None, 4), (Some(false), 5), (Some(true), 6)]
    );
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn discriminants() {
    #[derive(Debug, EnumMap, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(EnumMap)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }.into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn test_u8() {
    let map = enum_map! { b'a' => 4, _ => 0 };
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
}

#[derive(EnumMap)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map!{};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}
<|endoftext|>