<commit_before>use mcpat;

use std::fs;
use std::path::Path;

use {Database, Options, Result};

pub struct Experiment {
    system: mcpat::System,
    database: Database,
}

impl Experiment {
    pub fn new(options: Options) -> Result<Experiment> {
        let Options { config, database, .. } = options;

        let config = match config {
            Some(config) => config,
            None => raise!("a configuration file is required"),
        };
        if !exists(&config) {
            raise!("the configuration file does not exist");
        }

        let database = match database {
            Some(database) => database,
            None => raise!("a database file is required"),
        };

        let system = ok!(mcpat::open(&config));
        let database = try!(Database::open(&database));

        {
            let system = system.raw();
            assert!(system.Private_L2 != 0);
        }

        Ok(Experiment { system: system, database: database })
    }

    pub fn run(&mut self) -> Result<()> {
        use mcpat::{Component, Power};

        macro_rules! push(
            ($power:expr, $items:expr) => ({
                for item in $items {
                    let Power { dynamic, leakage } = item.power();
                    $power.push(dynamic);
                    $power.push(leakage);
                }
            });
        );

        let mut recorder = try!(self.database.recorder(&self.names()));
        let mut power = Vec::with_capacity(recorder.len());

        let processor = ok!(self.system.processor());
        push!(power, processor.cores());
        push!(power, processor.l3s());

        if power.len() != recorder.len() {
            raise!("encoundered a dimensionality mismatch");
        }

        try!(recorder.write(0, &power));

        Ok(())
    }

    pub fn prepare(&self) -> Result<()> {
        try!(self.database.prepare(&self.names()));
        Ok(())
    }

    fn names(&self) -> Vec<String> {
        let (cores, l3s) = (self.cores(), self.l3s());
        generate(&[("core#_dynamic", cores), ("core#_leakage", cores),
                   ("l3#_dynamic", l3s), ("l3#_leakage", l3s)])
    }

    fn cores(&self) -> usize {
        let system = self.system.raw();
        if system.homogeneous_cores != 0 { 1 } else {
            system.number_of_cores as usize
        }
    }

    fn l3s(&self) -> usize {
        let system = self.system.raw();
        if system.homogeneous_L3s != 0 { 1 } else {
            system.number_of_L3s as usize
        }
    }
}

fn exists(path: &Path) -> bool {
    match fs::metadata(path) {
        Ok(metadata) => !metadata.is_dir(),
        Err(_) => false,
    }
}

fn generate(pairs: &[(&str, usize)]) -> Vec<String> {
    let mut names = vec![];
    for &(name, count) in pairs.iter() {
        let (prefix, suffix) = {
            let i = name.find('#').unwrap();
            (&name[0..i], &name[(i + 1)..])
        };
        for i in 0..count {
            names.push(format!("{}{}{}", prefix, i, suffix));
        }
    }
    names
}
<commit_msg>Explain unsupported configurations<commit_after>use mcpat;

use std::fs;
use std::path::Path;

use {Database, Options, Result};

pub struct Experiment {
    system: mcpat::System,
    database: Database,
}

impl Experiment {
    pub fn new(options: Options) -> Result<Experiment> {
        let Options { config, database, .. } = options;

        let config = match config {
            Some(config) => config,
            None => raise!("a configuration file is required"),
        };
        if !exists(&config) {
            raise!("the configuration file does not exist");
        }

        let database = match database {
            Some(database) => database,
            None => raise!("a database file is required"),
        };

        let system = ok!(mcpat::open(&config));
        let database = try!(Database::open(&database));

        {
            let system = system.raw();
            if system.number_of_L2s > 0 && system.Private_L2 == 0 {
                raise!("shared L2 caches are currently not supported");
            }
        }

        Ok(Experiment { system: system, database: database })
    }

    pub fn run(&mut self) -> Result<()> {
        use mcpat::{Component, Power};

        macro_rules! push(
            ($power:expr, $items:expr) => ({
                for item in $items {
                    let Power { dynamic, leakage } = item.power();
                    $power.push(dynamic);
                    $power.push(leakage);
                }
            });
        );

        let mut recorder = try!(self.database.recorder(&self.names()));
        let mut power = Vec::with_capacity(recorder.len());

        let processor = ok!(self.system.processor());
        push!(power, processor.cores());
        push!(power, processor.l3s());

        if power.len() != recorder.len() {
            raise!("encoundered a dimensionality mismatch");
        }

        try!(recorder.write(0, &power));

        Ok(())
    }

    pub fn prepare(&self) -> Result<()> {
        try!(self.database.prepare(&self.names()));
        Ok(())
    }

    fn names(&self) -> Vec<String> {
        let (cores, l3s) = (self.cores(), self.l3s());
        generate(&[("core#_dynamic", cores), ("core#_leakage", cores),
                   ("l3#_dynamic", l3s), ("l3#_leakage", l3s)])
    }

    fn cores(&self) -> usize {
        let system = self.system.raw();
        if system.homogeneous_cores != 0 { 1 } else {
            system.number_of_cores as usize
        }
    }

    fn l3s(&self) -> usize {
        let system = self.system.raw();
        if system.homogeneous_L3s != 0 { 1 } else {
            system.number_of_L3s as usize
        }
    }
}

fn exists(path: &Path) -> bool {
    match fs::metadata(path) {
        Ok(metadata) => !metadata.is_dir(),
        Err(_) => false,
    }
}

fn generate(pairs: &[(&str, usize)]) -> Vec<String> {
    let mut names = vec![];
    for &(name, count) in pairs.iter() {
        let (prefix, suffix) = {
            let i = name.find('#').unwrap();
            (&name[0..i], &name[(i + 1)..])
        };
        for i in 0..count {
            names.push(format!("{}{}{}", prefix, i, suffix));
        }
    }
    names
}
<|endoftext|>


<commit_before>use std::fmt;
use std::ops::Index;
use stack::Stack;
use evaluate::Evaluate;
use variable::DummyVariables;
use convert_ref::{TryFromRef, TryIntoRef};

/// Used to specify an `Operand` or an `Evaluator`.
#[derive(Debug, Copy, Clone)]
pub enum Arithm<T, V, E: Evaluate<T>> {
    Operand(T),
    Variable(V),
    Evaluator(E),
}

/// Interpret a [`Reverse Polish notated`] expression (cf. `3 4 +`).
///
/// `Evaluate` method returns the valid result or an [`Evaluate::Err`]
/// if the evaluation fails.
///
/// `Expressions` are constructed from [`str`] the most of the time.
/// Use the [`try_into_ref()`] method to create an `Expression` type,
/// the result contain informations about the possible error at conversion time.
///
/// [`Reverse Polish notated`]: https://en.wikipedia.org/wiki/Reverse_Polish_notation
/// [`Evaluate::Err`]: ../evaluate/trait.Evaluate.html#associatedtype.Err
/// [`str`]: https://doc.rust-lang.org/std/str/index.html
/// [`try_into_ref()`]: ../convert_ref/trait.TryIntoRef.html
#[derive(Debug)]
pub struct Expression<T, V, E: Evaluate<T>> {
    stack_max: usize, // TODO rename max_stack
    expr: Vec<Arithm<T, V, E>>,
}

impl<T: Copy, V: Copy, E: Evaluate<T> + Copy> Expression<T, V, E> {
    /// Evaluate the `RPN` expression. Returns the result
    /// or the [`evaluate Error`](../evaluate/trait.Evaluate.html#associatedtype.Err).
    pub fn evaluate(&self) -> Result<T, E::Err> where (): From<V> {
        self.evaluate_with_variables(DummyVariables::default())
    }

    pub fn evaluate_with_variables<I, C>(&self, variables: C) -> Result<T, E::Err>
        where V: Into<I>,
              C: Index<I, Output=T>
    {
        let mut stack = Stack::with_capacity(self.stack_max);
        for arithm in &self.expr {
            match *arithm {
                Arithm::Operand(operand) => stack.push(operand),
                Arithm::Variable(var) => stack.push(*variables.index(var.into())),
                Arithm::Evaluator(evaluator) => evaluator.evaluate(&mut stack)?,
            }
        }
        Ok(stack.pop().unwrap())
    }
}

impl<T, V, E: Evaluate<T>> Expression<T, V, E> {
    pub fn from_iter<A, I>(iter: I) -> Result<Expression<T, V, E>,
                                              ExprResult<<E as TryFromRef<A>>::Err,
                                                         <V as TryFromRef<A>>::Err,
                                                         <T as TryFromRef<A>>::Err>>
        where T: TryFromRef<A>,
              V: TryFromRef<A>,
              E: TryFromRef<A>,
              I: IntoIterator<Item=A>
    {
        let final_expr: Result<Vec<_>, _> = iter.into_iter().map(|token| {
            match TryIntoRef::<E>::try_into_ref(&token) {
                Ok(eval) => Ok(Arithm::Evaluator(eval)),
                Err(eval_err) => {
                    match TryIntoRef::<V>::try_into_ref(&token) {
                        Ok(var) => Ok(Arithm::Variable(var)),
                        Err(var_err) => {
                            match TryIntoRef::<T>::try_into_ref(&token) {
                                Ok(op) => Ok(Arithm::Operand(op)),
                                Err(op_err) => Err(ExprResult::InvalidToken {
                                    evaluator: eval_err,
                                    variable: var_err,
                                    operand: op_err,
                                })
                            }
                        }
                    }
                }
            }
        }).collect();
        final_expr.and_then(|final_expr| {
            match Expression::check_validity(&final_expr) {
                Ok(_) => Ok(Expression {
                    stack_max: Expression::compute_stack_max(&final_expr),
                    expr: final_expr
                }),
                Err(err) => Err(ExprResult::OperandErr(err)),
            }
        })
    }
}

/// Used to specify the error during the conversion.
#[derive(Debug, PartialEq)]
pub enum ExprResult<A, B, C> {
    OperandErr(OperandErr),
    InvalidToken {
        evaluator: A,
        variable: B,
        operand: C
    },
}

/// Used to specify an error related to wrong number of operands in expression.
#[derive(Debug, PartialEq)]
pub enum OperandErr {
    TooManyOperands,
    NotEnoughOperand,
}

impl<T, V, E: Evaluate<T>> Expression<T, V, E> {
    fn check_validity(expr: &[Arithm<T, V, E>]) -> Result<(), OperandErr> {
        // TODO https://doc.rust-lang.org/1.2.0/std/result/fn.fold.html
        use self::OperandErr::*;
        let mut num_operands: usize = 0;
        for arithm in expr {
            match *arithm {
                Arithm::Operand(_) | Arithm::Variable(_) => num_operands += 1,
                Arithm::Evaluator(ref evaluator) => {
                    let needed = evaluator.operands_needed();
                    num_operands = num_operands.checked_sub(needed).ok_or(NotEnoughOperand)?;
                    num_operands += evaluator.operands_generated();
                },
            }
        }
        match num_operands {
            0 => Err(NotEnoughOperand),
            1 => Ok(()),
            _ => Err(TooManyOperands),
        }
    }
}

impl<T, V, E: Evaluate<T>> Expression<T, V, E> {
    fn compute_stack_max(expr: &[Arithm<T, V, E>]) -> usize {
        expr.iter().map(|arithm| {
            match *arithm {
                Arithm::Operand(_) | Arithm::Variable(_) => 1,
                Arithm::Evaluator(ref op) => {
                    op.operands_generated() as isize - op.operands_needed() as isize
                }
            }
        }).fold((0, 0isize), |(max, acc_count), count| {
            let acc = (acc_count + count) as usize;
            if acc > max { (acc, acc as isize) } else { (max, acc as isize) }
        }).0
    }
}

impl<T, V, E> fmt::Display for Expression<T, V, E>
    where T: fmt::Display,
          V: fmt::Display,
          E: fmt::Display + Evaluate<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let len = self.expr.len();
        for (i, arithm) in self.expr.iter().enumerate() {
            match *arithm {
                Arithm::Operand(ref operand) => operand.fmt(f)?,
                Arithm::Variable(ref variable) => variable.fmt(f)?,
                Arithm::Evaluator(ref evaluator) => evaluator.fmt(f)?,
            }
            if i != len - 1 {
                f.write_str(" ")?
            }
        }
        Ok(())
    }
}
<commit_msg>expression: Rename stack_max to max_stack for more clarity<commit_after>use std::fmt;
use std::ops::Index;
use stack::Stack;
use evaluate::Evaluate;
use variable::DummyVariables;
use convert_ref::{TryFromRef, TryIntoRef};

/// Used to specify an `Operand` or an `Evaluator`.
#[derive(Debug, Copy, Clone)]
pub enum Arithm<T, V, E: Evaluate<T>> {
    Operand(T),
    Variable(V),
    Evaluator(E),
}

/// Interpret a [`Reverse Polish notated`] expression (cf. `3 4 +`).
///
/// `Evaluate` method returns the valid result or an [`Evaluate::Err`]
/// if the evaluation fails.
///
/// `Expressions` are constructed from [`str`] the most of the time.
/// Use the [`try_into_ref()`] method to create an `Expression` type,
/// the result contain informations about the possible error at conversion time.
///
/// [`Reverse Polish notated`]: https://en.wikipedia.org/wiki/Reverse_Polish_notation
/// [`Evaluate::Err`]: ../evaluate/trait.Evaluate.html#associatedtype.Err
/// [`str`]: https://doc.rust-lang.org/std/str/index.html
/// [`try_into_ref()`]: ../convert_ref/trait.TryIntoRef.html
#[derive(Debug)]
pub struct Expression<T, V, E: Evaluate<T>> {
    max_stack: usize,
    expr: Vec<Arithm<T, V, E>>,
}

impl<T: Copy, V: Copy, E: Evaluate<T> + Copy> Expression<T, V, E> {
    /// Evaluate the `RPN` expression. Returns the result
    /// or the [`evaluate Error`](../evaluate/trait.Evaluate.html#associatedtype.Err).
    pub fn evaluate(&self) -> Result<T, E::Err> where (): From<V> {
        self.evaluate_with_variables(DummyVariables::default())
    }

    pub fn evaluate_with_variables<I, C>(&self, variables: C) -> Result<T, E::Err>
        where V: Into<I>,
              C: Index<I, Output=T>
    {
        let mut stack = Stack::with_capacity(self.max_stack);
        for arithm in &self.expr {
            match *arithm {
                Arithm::Operand(operand) => stack.push(operand),
                Arithm::Variable(var) => stack.push(*variables.index(var.into())),
                Arithm::Evaluator(evaluator) => evaluator.evaluate(&mut stack)?,
            }
        }
        Ok(stack.pop().unwrap())
    }
}

impl<T, V, E: Evaluate<T>> Expression<T, V, E> {
    pub fn from_iter<A, I>(iter: I) -> Result<Expression<T, V, E>,
                                              ExprResult<<E as TryFromRef<A>>::Err,
                                                         <V as TryFromRef<A>>::Err,
                                                         <T as TryFromRef<A>>::Err>>
        where T: TryFromRef<A>,
              V: TryFromRef<A>,
              E: TryFromRef<A>,
              I: IntoIterator<Item=A>
    {
        let final_expr: Result<Vec<_>, _> = iter.into_iter().map(|token| {
            match TryIntoRef::<E>::try_into_ref(&token) {
                Ok(eval) => Ok(Arithm::Evaluator(eval)),
                Err(eval_err) => {
                    match TryIntoRef::<V>::try_into_ref(&token) {
                        Ok(var) => Ok(Arithm::Variable(var)),
                        Err(var_err) => {
                            match TryIntoRef::<T>::try_into_ref(&token) {
                                Ok(op) => Ok(Arithm::Operand(op)),
                                Err(op_err) => Err(ExprResult::InvalidToken {
                                    evaluator: eval_err,
                                    variable: var_err,
                                    operand: op_err,
                                })
                            }
                        }
                    }
                }
            }
        }).collect();
        final_expr.and_then(|final_expr| {
            match Expression::check_validity(&final_expr) {
                Ok(_) => Ok(Expression {
                    max_stack: Expression::compute_stack_max(&final_expr),
                    expr: final_expr
                }),
                Err(err) => Err(ExprResult::OperandErr(err)),
            }
        })
    }
}

/// Used to specify the error during the conversion.
#[derive(Debug, PartialEq)]
pub enum ExprResult<A, B, C> {
    OperandErr(OperandErr),
    InvalidToken {
        evaluator: A,
        variable: B,
        operand: C
    },
}

/// Used to specify an error related to wrong number of operands in expression.
#[derive(Debug, PartialEq)]
pub enum OperandErr {
    TooManyOperands,
    NotEnoughOperand,
}

impl<T, V, E: Evaluate<T>> Expression<T, V, E> {
    fn check_validity(expr: &[Arithm<T, V, E>]) -> Result<(), OperandErr> {
        // TODO https://doc.rust-lang.org/1.2.0/std/result/fn.fold.html
        use self::OperandErr::*;
        let mut num_operands: usize = 0;
        for arithm in expr {
            match *arithm {
                Arithm::Operand(_) | Arithm::Variable(_) => num_operands += 1,
                Arithm::Evaluator(ref evaluator) => {
                    let needed = evaluator.operands_needed();
                    num_operands = num_operands.checked_sub(needed).ok_or(NotEnoughOperand)?;
                    num_operands += evaluator.operands_generated();
                },
            }
        }
        match num_operands {
            0 => Err(NotEnoughOperand),
            1 => Ok(()),
            _ => Err(TooManyOperands),
        }
    }
}

impl<T, V, E: Evaluate<T>> Expression<T, V, E> {
    fn compute_stack_max(expr: &[Arithm<T, V, E>]) -> usize {
        expr.iter().map(|arithm| {
            match *arithm {
                Arithm::Operand(_) | Arithm::Variable(_) => 1,
                Arithm::Evaluator(ref op) => {
                    op.operands_generated() as isize - op.operands_needed() as isize
                }
            }
        }).fold((0, 0isize), |(max, acc_count), count| {
            let acc = (acc_count + count) as usize;
            if acc > max { (acc, acc as isize) } else { (max, acc as isize) }
        }).0
    }
}

impl<T, V, E> fmt::Display for Expression<T, V, E>
    where T: fmt::Display,
          V: fmt::Display,
          E: fmt::Display + Evaluate<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let len = self.expr.len();
        for (i, arithm) in self.expr.iter().enumerate() {
            match *arithm {
                Arithm::Operand(ref operand) => operand.fmt(f)?,
                Arithm::Variable(ref variable) => variable.fmt(f)?,
                Arithm::Evaluator(ref evaluator) => evaluator.fmt(f)?,
            }
            if i != len - 1 {
                f.write_str(" ")?
            }
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate bf;

use bf::ast;
use bf::rle;
use bf::peephole;
use bf::traits::Interpretable;
use bf::test_helpers;

use test::Bencher;

#[bench]
fn compile_factor(b: &mut Bencher) {
    let program = ast::parse_program(test_helpers::FACTOR_SRC).unwrap();

    b.iter(|| {
        let program = rle::compile(&program);
        peephole::compile(&program)
    });
}

#[bench]
fn interpret_factor_million(b: &mut Bencher) {
    let program = ast::parse_program(test_helpers::FACTOR_SRC).unwrap();
    let program = rle::compile(&program);
    let program = peephole::compile(&program);

    b.iter(|| {
        program.interpret_memory(None, b"1000000\n").unwrap()
    });
}<commit_msg>Using compilation trait for one benchmark. Worth it?<commit_after>#![feature(test)]

extern crate test;
extern crate bf;

use bf::ast;
use bf::rle;
use bf::peephole::PeepholeCompilable;
use bf::traits::Interpretable;
use bf::test_helpers;

use test::Bencher;

#[bench]
fn compile_factor(b: &mut Bencher) {
    let program = ast::parse_program(test_helpers::FACTOR_SRC).unwrap();

    b.iter(|| {
        let program = rle::compile(&program);
        program.peephole_compile()
    });
}

#[bench]
fn interpret_factor_million(b: &mut Bencher) {
    let program = ast::parse_program(test_helpers::FACTOR_SRC).unwrap();
    let program = program.peephole_compile();

    b.iter(|| {
        program.interpret_memory(None, b"1000000\n").unwrap()
    });
}<|endoftext|>


<commit_before>//! This module contains the implementation details of the HIR for ADTs, i.e.
//! structs and enums (and unions).

use std::sync::Arc;

use ra_arena::{RawId, Arena, impl_arena_id};
use ra_syntax::{
    TreeArc,
    ast::{self, NameOwner, StructFlavor}
};

use crate::{
    Name, AsName, Struct, Enum, EnumVariant, Crate,
    HirDatabase, HirFileId,
    type_ref::TypeRef,
};

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AdtDef {
    Struct(Struct),
    Enum(Enum),
}
impl_froms!(AdtDef: Struct, Enum);

impl AdtDef {
    pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
        match self {
            AdtDef::Struct(s) => s.module(db),
            AdtDef::Enum(e) => e.module(db),
        }
        .krate(db)
    }
}

impl Struct {
    pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
        db.struct_data((*self).into()).variant_data.clone()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructData {
    pub(crate) name: Option<Name>,
    pub(crate) variant_data: Arc<VariantData>,
}

impl StructData {
    fn new(struct_def: &ast::StructDef) -> StructData {
        let name = struct_def.name().map(|n| n.as_name());
        let variant_data = VariantData::new(struct_def.flavor());
        let variant_data = Arc::new(variant_data);
        StructData { name, variant_data }
    }

    pub(crate) fn struct_data_query(db: &impl HirDatabase, struct_: Struct) -> Arc<StructData> {
        let (_, struct_def) = struct_.source(db);
        Arc::new(StructData::new(&*struct_def))
    }
}

fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> {
    enum_def
        .variant_list()
        .into_iter()
        .flat_map(|it| it.variants())
}

impl EnumVariant {
    pub(crate) fn source_impl(
        &self,
        db: &impl HirDatabase,
    ) -> (HirFileId, TreeArc<ast::EnumVariant>) {
        let (file_id, enum_def) = self.parent.source(db);
        let var = variants(&*enum_def)
            .zip(db.enum_data(self.parent).variants.iter())
            .find(|(_syntax, (id, _))| *id == self.id)
            .unwrap()
            .0
            .to_owned();
        (file_id, var)
    }
    pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
        db.enum_data(self.parent).variants[self.id]
            .variant_data
            .clone()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumData {
    pub(crate) name: Option<Name>,
    pub(crate) variants: Arena<EnumVariantId, EnumVariantData>,
}

impl EnumData {
    pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> {
        let (_file_id, enum_def) = e.source(db);
        let name = enum_def.name().map(|n| n.as_name());
        let variants = variants(&*enum_def)
            .map(|var| EnumVariantData {
                name: var.name().map(|it| it.as_name()),
                variant_data: Arc::new(VariantData::new(var.flavor())),
            })
            .collect();
        Arc::new(EnumData { name, variants })
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct EnumVariantId(RawId);
impl_arena_id!(EnumVariantId);

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumVariantData {
    pub(crate) name: Option<Name>,
    pub(crate) variant_data: Arc<VariantData>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct StructFieldId(RawId);
impl_arena_id!(StructFieldId);

/// A single field of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructFieldData {
    pub(crate) name: Name,
    pub(crate) type_ref: TypeRef,
}

/// Fields of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariantData(VariantDataInner);

#[derive(Debug, Clone, PartialEq, Eq)]
enum VariantDataInner {
    Struct(Arena<StructFieldId, StructFieldData>),
    Tuple(Arena<StructFieldId, StructFieldData>),
    Unit,
}

impl VariantData {
    pub(crate) fn fields(&self) -> Option<&Arena<StructFieldId, StructFieldData>> {
        match &self.0 {
            VariantDataInner::Struct(fields) | VariantDataInner::Tuple(fields) => Some(fields),
            _ => None,
        }
    }
}

impl VariantData {
    fn new(flavor: StructFlavor) -> Self {
        let inner = match flavor {
            StructFlavor::Tuple(fl) => {
                let fields = fl
                    .fields()
                    .enumerate()
                    .map(|(i, fd)| StructFieldData {
                        name: Name::tuple_field_name(i),
                        type_ref: TypeRef::from_ast_opt(fd.type_ref()),
                    })
                    .collect();
                VariantDataInner::Tuple(fields)
            }
            StructFlavor::Named(fl) => {
                let fields = fl
                    .fields()
                    .map(|fd| StructFieldData {
                        name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
                        type_ref: TypeRef::from_ast_opt(fd.type_ref()),
                    })
                    .collect();
                VariantDataInner::Struct(fields)
            }
            StructFlavor::Unit => VariantDataInner::Unit,
        };
        VariantData(inner)
    }

    // pub(crate) fn get_field_type_ref(&self, field_name: &Name) -> Option<&TypeRef> {
    //     self.fields()
    //         .iter()
    //         .find(|f| f.name == *field_name)
    //         .map(|f| &f.type_ref)
    // }
}
<commit_msg>reduce visibility<commit_after>//! This module contains the implementation details of the HIR for ADTs, i.e.
//! structs and enums (and unions).

use std::sync::Arc;

use ra_arena::{RawId, Arena, impl_arena_id};
use ra_syntax::{
    TreeArc,
    ast::{self, NameOwner, StructFlavor}
};

use crate::{
    Name, AsName, Struct, Enum, EnumVariant, Crate,
    HirDatabase, HirFileId,
    type_ref::TypeRef,
};

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AdtDef {
    Struct(Struct),
    Enum(Enum),
}
impl_froms!(AdtDef: Struct, Enum);

impl AdtDef {
    pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
        match self {
            AdtDef::Struct(s) => s.module(db),
            AdtDef::Enum(e) => e.module(db),
        }
        .krate(db)
    }
}

impl Struct {
    pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
        db.struct_data((*self).into()).variant_data.clone()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructData {
    pub(crate) name: Option<Name>,
    pub(crate) variant_data: Arc<VariantData>,
}

impl StructData {
    fn new(struct_def: &ast::StructDef) -> StructData {
        let name = struct_def.name().map(|n| n.as_name());
        let variant_data = VariantData::new(struct_def.flavor());
        let variant_data = Arc::new(variant_data);
        StructData { name, variant_data }
    }

    pub(crate) fn struct_data_query(db: &impl HirDatabase, struct_: Struct) -> Arc<StructData> {
        let (_, struct_def) = struct_.source(db);
        Arc::new(StructData::new(&*struct_def))
    }
}

fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> {
    enum_def
        .variant_list()
        .into_iter()
        .flat_map(|it| it.variants())
}

impl EnumVariant {
    pub(crate) fn source_impl(
        &self,
        db: &impl HirDatabase,
    ) -> (HirFileId, TreeArc<ast::EnumVariant>) {
        let (file_id, enum_def) = self.parent.source(db);
        let var = variants(&*enum_def)
            .zip(db.enum_data(self.parent).variants.iter())
            .find(|(_syntax, (id, _))| *id == self.id)
            .unwrap()
            .0
            .to_owned();
        (file_id, var)
    }
    pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
        db.enum_data(self.parent).variants[self.id]
            .variant_data
            .clone()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumData {
    pub(crate) name: Option<Name>,
    pub(crate) variants: Arena<EnumVariantId, EnumVariantData>,
}

impl EnumData {
    pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> {
        let (_file_id, enum_def) = e.source(db);
        let name = enum_def.name().map(|n| n.as_name());
        let variants = variants(&*enum_def)
            .map(|var| EnumVariantData {
                name: var.name().map(|it| it.as_name()),
                variant_data: Arc::new(VariantData::new(var.flavor())),
            })
            .collect();
        Arc::new(EnumData { name, variants })
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct EnumVariantId(RawId);
impl_arena_id!(EnumVariantId);

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct EnumVariantData {
    pub(crate) name: Option<Name>,
    variant_data: Arc<VariantData>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct StructFieldId(RawId);
impl_arena_id!(StructFieldId);

/// A single field of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructFieldData {
    pub(crate) name: Name,
    pub(crate) type_ref: TypeRef,
}

/// Fields of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct VariantData(VariantDataInner);

#[derive(Debug, Clone, PartialEq, Eq)]
enum VariantDataInner {
    Struct(Arena<StructFieldId, StructFieldData>),
    Tuple(Arena<StructFieldId, StructFieldData>),
    Unit,
}

impl VariantData {
    pub(crate) fn fields(&self) -> Option<&Arena<StructFieldId, StructFieldData>> {
        match &self.0 {
            VariantDataInner::Struct(fields) | VariantDataInner::Tuple(fields) => Some(fields),
            _ => None,
        }
    }
}

impl VariantData {
    fn new(flavor: StructFlavor) -> Self {
        let inner = match flavor {
            StructFlavor::Tuple(fl) => {
                let fields = fl
                    .fields()
                    .enumerate()
                    .map(|(i, fd)| StructFieldData {
                        name: Name::tuple_field_name(i),
                        type_ref: TypeRef::from_ast_opt(fd.type_ref()),
                    })
                    .collect();
                VariantDataInner::Tuple(fields)
            }
            StructFlavor::Named(fl) => {
                let fields = fl
                    .fields()
                    .map(|fd| StructFieldData {
                        name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
                        type_ref: TypeRef::from_ast_opt(fd.type_ref()),
                    })
                    .collect();
                VariantDataInner::Struct(fields)
            }
            StructFlavor::Unit => VariantDataInner::Unit,
        };
        VariantData(inner)
    }
}
<|endoftext|>


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

extern crate glfw;

use glfw::{Action, Context, Key, WindowEvent, RenderContext};

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    let (mut window, events) = glfw.create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    window.set_all_polling(true);
    let mut render_context = window.render_context();

    // Render asynchronously from the main event loop. This prevents a pause in rendering
    // during some window interactions (e.g. resizing) on platforms like Windows.
    let thread = std::thread::spawn(move || {
        render_context.make_current();
        while !render_context.should_close() {
            for (_, event) in glfw::flush_messages(&events) {
                handle_window_event(&mut render_context, event);
            }
            render_context.swap_buffers();
        }
    });

    while !window.should_close() {
        glfw.poll_events_unbuffered(|window_id, event| {
            // Multiple windows may be identified by their `window_id`
            assert_eq!(window.window_id(), window_id);

            // Intercept the close request and reset the flag
            if let (_, WindowEvent::Close) = event {
                window.set_should_close(false);
            };

            // Forward the event to the render thread via the `events` receiver
            // to be processed asynchronously from the main event loop thread.
            // Returning `None` here would consume the event.
            Some(event)
        });
    }

    thread.join().unwrap();
}

fn handle_window_event(render_context: &mut RenderContext, event: glfw::WindowEvent) {
    match event {
        glfw::WindowEvent::Close | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
            render_context.set_should_close(true);
        }
        _ => {}
    }
}
<commit_msg>Use wait_events_unbuffered in example<commit_after>// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate glfw;

use glfw::{Action, Context, Key, WindowEvent, RenderContext};

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    let (mut window, events) = glfw.create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    window.set_all_polling(true);
    let mut render_context = window.render_context();

    // Render asynchronously from the main event loop. This prevents a pause in rendering
    // during some window interactions (e.g. resizing) on platforms like Windows.
    let thread = std::thread::spawn(move || {
        render_context.make_current();
        while !render_context.should_close() {
            for (_, event) in glfw::flush_messages(&events) {
                handle_window_event(&mut render_context, event);
            }
            render_context.swap_buffers();
        }
    });

    while !window.should_close() {
        glfw.wait_events_unbuffered(|window_id, event| {
            // Multiple windows may be identified by their `window_id`
            assert_eq!(window.window_id(), window_id);

            // Intercept the close request and reset the flag
            if let (_, WindowEvent::Close) = event {
                window.set_should_close(false);
            };

            // Forward the event to the render thread via the `events` receiver
            // to be processed asynchronously from the main event loop thread.
            // Returning `None` here would consume the event.
            Some(event)
        });
    }

    thread.join().unwrap();
}

fn handle_window_event(render_context: &mut RenderContext, event: glfw::WindowEvent) {
    match event {
        glfw::WindowEvent::Close | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
            render_context.set_should_close(true);
        }
        _ => {}
    }
}
<|endoftext|>


<commit_before>pub mod faculty;
pub mod stud;

pub fn add(a: i32, b: i32) -> isize {
    (a + b) as isize
}

pub fn sub(a: i32, b: i32) -> isize {
    (a + b) as isize
}

pub fn branch(a: i32) -> isize {
    if a < 10 {
        0
    } else {
        1
    }
}

#[test]
fn test() {
    assert_eq!(10isize, add(4, 6));
    assert_eq!(0isize, branch(4));
}
<commit_msg>branch coverage<commit_after>pub mod faculty;
pub mod stud;

pub fn add(a: i32, b: i32) -> isize {
    (a + b) as isize
}

pub fn sub(a: i32, b: i32) -> isize {
    (a + b) as isize
}

pub fn branch_not_covered(a: i32) -> isize {
    if a < 10 {
        0
    } else if a == 10 {
        1
    } else {
        2
    }
}

pub fn branch_covered(a: i32) -> isize {
    if a < 10 {
        0
    } else if a == 10 {
        1
    } else {
        2
    }
}

#[test]
fn test() {
    assert_eq!(10isize, add(4, 6));

    assert_eq!(0isize, branch_not_covered(4));
    assert_eq!(2isize, branch_not_covered(20));

    assert_eq!(0isize, branch_covered(4));
    assert_eq!(1isize, branch_covered(10));
}
<|endoftext|>


<commit_before>
// Copyright 2017 Ryan Hagenson.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of the RNA alphabet.
//!
//! # Example
//!
//! ```
//! use bio::alphabets;
//! let alphabet = alphabets::rna::alphabet();
//! assert!(alphabet.is_word(b"GAUUACA"));
//! assert!(alphabet.is_word(b"gauuaca"));
//! assert!(!alphabet.is_word(b"ACGT"));
//! ```

use alphabets::Alphabet;
use utils::IntoTextIterator;

/// The RNA alphabet (uppercase and lowercase).
pub fn alphabet() -> Alphabet {
    Alphabet::new(b"ACGUacgu")
}

/// The RNA alphabet including N (uppercase and lowercase).
pub fn n_alphabet() -> Alphabet {
    Alphabet::new(b"ACGUNacgun")
}

/// The IUPAC RNA alphabet (uppercase and lowercase).
pub fn iupac_alphabet() -> Alphabet {
    Alphabet::new(b"ACGTURYSWKMBDHVNZacgturyswkmbdhvnz")
}

lazy_static! {
    static ref COMPLEMENT: Vec<u8> = {
        let mut comp = Vec::new();
        comp.resize(256, 0);
        for (v, mut a) in comp.iter_mut().enumerate() {
            *a = v as u8;
        }
        for (&a, &b) in b"AGCUYRWSKMDVHBNZ".iter().zip(b"UCGARYSWMKHBDVNZ".iter()) {
            comp[a as usize] = b;
            comp[a as usize + 32] = b + 32;  // lowercase variants
        }
        comp
    };
}

/// Return complement of given RNA alphabet character (IUPAC alphabet supported).
pub fn complement(a: u8) -> u8 {
    COMPLEMENT[a as usize]
}

/// Calculate reverse complement of given text (IUPAC alphabet supported).
pub fn revcomp<'a, T: IntoTextIterator<'a>>(text: T) -> Vec<u8>
    where T::IntoIter: DoubleEndedIterator
{
    text.into_iter().rev().map(|&a| complement(a)).collect()
}

#[cfg(test)]
mod tests {
    fn validate_height(node: &Node<i64, String>) {
        let left_height = node.left.as_ref().map_or(0, |n| n.height);
        let right_height = node.right.as_ref().map_or(0, |n| n.height);
        assert!((left_height - right_height).abs() <= 1);
        assert_eq!(node.height, cmp::max(left_height, right_height) + 1)
    }
}
<commit_msg>Add tests and remove T from IUPAC alphabet<commit_after>
// Copyright 2017 Ryan Hagenson.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of the RNA alphabet.
//!
//! # Example
//!
//! ```
//! use bio::alphabets;
//! let alphabet = alphabets::rna::alphabet();
//! assert!(alphabet.is_word(b"GAUUACA"));
//! assert!(alphabet.is_word(b"gauuaca"));
//! assert!(!alphabet.is_word(b"ACGT"));
//! ```

use alphabets::Alphabet;
use utils::IntoTextIterator;

/// The RNA alphabet (uppercase and lowercase).
pub fn alphabet() -> Alphabet {
    Alphabet::new(b"ACGUacgu")
}

/// The RNA alphabet including N (uppercase and lowercase).
pub fn n_alphabet() -> Alphabet {
    Alphabet::new(b"ACGUNacgun")
}

/// The IUPAC RNA alphabet (uppercase and lowercase).
pub fn iupac_alphabet() -> Alphabet {
    Alphabet::new(b"ACGURYSWKMBDHVNZacguryswkmbdhvnz")
}

lazy_static! {
    static ref COMPLEMENT: Vec<u8> = {
        let mut comp = Vec::new();
        comp.resize(256, 0);
        for (v, mut a) in comp.iter_mut().enumerate() {
            *a = v as u8;
        }
        for (&a, &b) in b"AGCUYRWSKMDVHBNZ".iter().zip(b"UCGARYSWMKHBDVNZ".iter()) {
            comp[a as usize] = b;
            comp[a as usize + 32] = b + 32;  // lowercase variants
        }
        comp
    };
}

/// Return complement of given RNA alphabet character (IUPAC alphabet supported).
pub fn complement(a: u8) -> u8 {
    COMPLEMENT[a as usize]
}

/// Calculate reverse complement of given text (IUPAC alphabet supported).
pub fn revcomp<'a, T: IntoTextIterator<'a>>(text: T) -> Vec<u8>
    where T::IntoIter: DoubleEndedIterator
{
    text.into_iter().rev().map(|&a| complement(a)).collect()
}

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

    #[test]
    fn is_word() {
        assert!(alphabet().is_word(b"GAUUACA"));
    }

    #[test]
    fn is_no_word() {
        assert!(!alphabet().is_word(b"gaTTaca"));
    }

    #[test]
    fn symbol_is_no_word() {
        assert!(!alphabet().is_word(b"#"));
    }

    #[test]
    fn number_is_no_word() {
        assert!(!alphabet().is_word(b"42"));
    }

    #[test]
    fn test_reverse_complement() {
        assert_eq!(revcomp(b"GAUUACA"), b"UGUAAUC");
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

// For the purpose of this example all unused code is allowed.
#![allow(dead_code)]

extern crate examples;
extern crate cgmath;
extern crate winit;
extern crate time;

#[macro_use]
extern crate vulkano;
#[macro_use]
extern crate vulkano_shader_derive;
extern crate vulkano_win;

use vulkano_win::VkSurfaceBuild;
use vulkano::sync::GpuFuture;

use std::sync::Arc;

fn main() {
    // The start of this example is exactly the same as `triangle`. You should read the
    // `triangle` example if you haven't done so yet.

    let extensions = vulkano_win::required_extensions();
    let instance = vulkano::instance::Instance::new(None, &extensions, None).expect("failed to create instance");

    let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
                            .next().expect("no device available");
    println!("Using device: {} (type: {:?})", physical.name(), physical.ty());

    let mut events_loop = winit::EventsLoop::new();
    let window = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();

    let queue = physical.queue_families().find(|&q| q.supports_graphics() &&
                                                   window.surface().is_supported(q).unwrap_or(false))
                                                .expect("couldn't find a graphical queue family");

    let device_ext = vulkano::device::DeviceExtensions {
        khr_swapchain: true,
        .. vulkano::device::DeviceExtensions::none()
    };

    let (device, mut queues) = vulkano::device::Device::new(physical, physical.supported_features(),
                                                            &device_ext, [(queue, 0.5)].iter().cloned())
                               .expect("failed to create device");
    let queue = queues.next().unwrap();

    let (swapchain, images) = {
        let caps = window.surface().capabilities(physical).expect("failed to get surface capabilities");

        let dimensions = caps.current_extent.unwrap_or([1280, 1024]);
        let usage = caps.supported_usage_flags;
        let format = caps.supported_formats[0].0;

        vulkano::swapchain::Swapchain::new(device.clone(), window.surface().clone(), caps.min_image_count, format, dimensions, 1,
                                           usage, &queue, vulkano::swapchain::SurfaceTransform::Identity,
                                           vulkano::swapchain::CompositeAlpha::Opaque,
                                           vulkano::swapchain::PresentMode::Fifo, true, None).expect("failed to create swapchain")
    };

    let depth_buffer = vulkano::image::attachment::AttachmentImage::transient(device.clone(), images[0].dimensions(), vulkano::format::D16Unorm).unwrap();

    let vertex_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer
                                ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()), examples::VERTICES.iter().cloned())
                                .expect("failed to create buffer");

    let normals_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer
                                ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()), examples::NORMALS.iter().cloned())
                                .expect("failed to create buffer");

    let index_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer
                                ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()), examples::INDICES.iter().cloned())
                                .expect("failed to create buffer");

    // note: this teapot was meant for OpenGL where the origin is at the lower left
    //       instead the origin is at the upper left in vulkan, so we reverse the Y axis
    let proj = cgmath::perspective(cgmath::Rad(std::f32::consts::FRAC_PI_2), { let d = images[0].dimensions(); d[0] as f32 / d[1] as f32 }, 0.01, 100.0);
    let view = cgmath::Matrix4::look_at(cgmath::Point3::new(0.3, 0.3, 1.0), cgmath::Point3::new(0.0, 0.0, 0.0), cgmath::Vector3::new(0.0, -1.0, 0.0));
    let scale = cgmath::Matrix4::from_scale(0.01);

    let uniform_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer::<vs::ty::Data>
                               ::from_data(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()),
                                vs::ty::Data {
                                    world : <cgmath::Matrix4<f32> as cgmath::SquareMatrix>::identity().into(),
                                    view : (view * scale).into(),
                                    proj : proj.into(),
                                })
                               .expect("failed to create buffer");

    let vs = vs::Shader::load(device.clone()).expect("failed to create shader module");
    let fs = fs::Shader::load(device.clone()).expect("failed to create shader module");

    let renderpass = Arc::new(
        single_pass_renderpass!(device.clone(),
            attachments: {
                color: {
                    load: Clear,
                    store: Store,
                    format: swapchain.format(),
                    samples: 1,
                },
                depth: {
                    load: Clear,
                    store: DontCare,
                    format: vulkano::format::Format::D16Unorm,
                    samples: 1,
                }
            },
            pass: {
                color: [color],
                depth_stencil: {depth}
            }
        ).unwrap()
    );

    let pipeline = Arc::new(vulkano::pipeline::GraphicsPipeline::start()
        .vertex_input(vulkano::pipeline::vertex::TwoBuffersDefinition::new())
        .vertex_shader(vs.main_entry_point(), ())
        .triangle_list()
        .viewports(std::iter::once(vulkano::pipeline::viewport::Viewport {
            origin: [0.0, 0.0],
            depth_range: 0.0 .. 1.0,
            dimensions: [images[0].dimensions()[0] as f32, images[0].dimensions()[1] as f32],
        }))
        .fragment_shader(fs.main_entry_point(), ())
        .depth_stencil_simple_depth()
        .render_pass(vulkano::framebuffer::Subpass::from(renderpass.clone(), 0).unwrap())
        .build(device.clone())
        .unwrap());

    let set = Arc::new(vulkano::descriptor::descriptor_set::PersistentDescriptorSet::start(pipeline.clone(), 0)
        .add_buffer(uniform_buffer.clone()).unwrap()
        .build().unwrap()
    );

    let framebuffers = images.iter().map(|image| {
        Arc::new(vulkano::framebuffer::Framebuffer::start(renderpass.clone())
            .add(image.clone()).unwrap()
            .add(depth_buffer.clone()).unwrap()
            .build().unwrap())
    }).collect::<Vec<_>>();

    let mut previous_frame = Box::new(vulkano::sync::now(device.clone())) as Box<GpuFuture>;

    loop {
        previous_frame.cleanup_finished();

        {
            // aquiring write lock for the uniform buffer
            let mut buffer_content = uniform_buffer.write().unwrap();

            let rotation = cgmath::Matrix3::from_angle_y(cgmath::Rad(time::precise_time_ns() as f32 * 0.000000001));

            // since write lock implementd Deref and DerefMut traits,
            // we can update content directly
            buffer_content.world = cgmath::Matrix4::from(rotation).into();
        }

        let (image_num, acquire_future) = vulkano::swapchain::acquire_next_image(swapchain.clone(), None).unwrap();

        let command_buffer = vulkano::command_buffer::AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap()
            .begin_render_pass(
                framebuffers[image_num].clone(), false,
                vec![
                    [0.0, 0.0, 1.0, 1.0].into(),
                    1f32.into()
                ]).unwrap()
            .draw_indexed(
                pipeline.clone(), vulkano::command_buffer::DynamicState::none(),
                (vertex_buffer.clone(), normals_buffer.clone()),
                index_buffer.clone(), set.clone(), ()).unwrap()
            .end_render_pass().unwrap()
            .build().unwrap();

        let future = previous_frame.join(acquire_future)
            .then_execute(queue.clone(), command_buffer).unwrap()
            .then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
            .then_signal_fence_and_flush().unwrap();
        previous_frame = Box::new(future) as Box<_>;

        let mut done = false;
        events_loop.poll_events(|ev| {
            match ev {
                winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => done = true,
                _ => ()
            }
        });
        if done { return; }
    }
}

mod vs {
    #[derive(VulkanoShader)]
    #[ty = "vertex"]
    #[src = "
#version 450

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;

layout(location = 0) out vec3 v_normal;

layout(set = 0, binding = 0) uniform Data {
    mat4 world;
    mat4 view;
    mat4 proj;
} uniforms;

void main() {
    mat4 worldview = uniforms.view * uniforms.world;
    v_normal = transpose(inverse(mat3(worldview))) * normal;
    gl_Position = uniforms.proj * worldview * vec4(position, 1.0);
}
"]
    struct Dummy;
}

mod fs {
    #[derive(VulkanoShader)]
    #[ty = "fragment"]
    #[src = "
#version 450

layout(location = 0) in vec3 v_normal;
layout(location = 0) out vec4 f_color;

const vec3 LIGHT = vec3(0.0, 0.0, 1.0);

void main() {
    float brightness = dot(normalize(v_normal), normalize(LIGHT));
    vec3 dark_color = vec3(0.6, 0.0, 0.0);
    vec3 regular_color = vec3(1.0, 0.0, 0.0);

    f_color = vec4(mix(dark_color, regular_color, brightness), 1.0);
}
"]
    struct Dummy;
}
<commit_msg>Fix teapot rotation slowly<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

// For the purpose of this example all unused code is allowed.
#![allow(dead_code)]

extern crate examples;
extern crate cgmath;
extern crate winit;
extern crate time;

#[macro_use]
extern crate vulkano;
#[macro_use]
extern crate vulkano_shader_derive;
extern crate vulkano_win;

use vulkano_win::VkSurfaceBuild;
use vulkano::sync::GpuFuture;

use std::sync::Arc;

fn main() {
    // The start of this example is exactly the same as `triangle`. You should read the
    // `triangle` example if you haven't done so yet.

    let extensions = vulkano_win::required_extensions();
    let instance = vulkano::instance::Instance::new(None, &extensions, None).expect("failed to create instance");

    let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
                            .next().expect("no device available");
    println!("Using device: {} (type: {:?})", physical.name(), physical.ty());

    let mut events_loop = winit::EventsLoop::new();
    let window = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();

    let queue = physical.queue_families().find(|&q| q.supports_graphics() &&
                                                   window.surface().is_supported(q).unwrap_or(false))
                                                .expect("couldn't find a graphical queue family");

    let device_ext = vulkano::device::DeviceExtensions {
        khr_swapchain: true,
        .. vulkano::device::DeviceExtensions::none()
    };

    let (device, mut queues) = vulkano::device::Device::new(physical, physical.supported_features(),
                                                            &device_ext, [(queue, 0.5)].iter().cloned())
                               .expect("failed to create device");
    let queue = queues.next().unwrap();

    let (swapchain, images) = {
        let caps = window.surface().capabilities(physical).expect("failed to get surface capabilities");

        let dimensions = caps.current_extent.unwrap_or([1280, 1024]);
        let usage = caps.supported_usage_flags;
        let format = caps.supported_formats[0].0;

        vulkano::swapchain::Swapchain::new(device.clone(), window.surface().clone(), caps.min_image_count, format, dimensions, 1,
                                           usage, &queue, vulkano::swapchain::SurfaceTransform::Identity,
                                           vulkano::swapchain::CompositeAlpha::Opaque,
                                           vulkano::swapchain::PresentMode::Fifo, true, None).expect("failed to create swapchain")
    };

    let depth_buffer = vulkano::image::attachment::AttachmentImage::transient(device.clone(), images[0].dimensions(), vulkano::format::D16Unorm).unwrap();

    let vertex_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer
                                ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()), examples::VERTICES.iter().cloned())
                                .expect("failed to create buffer");

    let normals_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer
                                ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()), examples::NORMALS.iter().cloned())
                                .expect("failed to create buffer");

    let index_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer
                                ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()), examples::INDICES.iter().cloned())
                                .expect("failed to create buffer");

    // note: this teapot was meant for OpenGL where the origin is at the lower left
    //       instead the origin is at the upper left in vulkan, so we reverse the Y axis
    let proj = cgmath::perspective(cgmath::Rad(std::f32::consts::FRAC_PI_2), { let d = images[0].dimensions(); d[0] as f32 / d[1] as f32 }, 0.01, 100.0);
    let view = cgmath::Matrix4::look_at(cgmath::Point3::new(0.3, 0.3, 1.0), cgmath::Point3::new(0.0, 0.0, 0.0), cgmath::Vector3::new(0.0, -1.0, 0.0));
    let scale = cgmath::Matrix4::from_scale(0.01);

    let uniform_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer::<vs::ty::Data>
                               ::from_data(device.clone(), vulkano::buffer::BufferUsage::all(), Some(queue.family()),
                                vs::ty::Data {
                                    world : <cgmath::Matrix4<f32> as cgmath::SquareMatrix>::identity().into(),
                                    view : (view * scale).into(),
                                    proj : proj.into(),
                                })
                               .expect("failed to create buffer");

    let vs = vs::Shader::load(device.clone()).expect("failed to create shader module");
    let fs = fs::Shader::load(device.clone()).expect("failed to create shader module");

    let renderpass = Arc::new(
        single_pass_renderpass!(device.clone(),
            attachments: {
                color: {
                    load: Clear,
                    store: Store,
                    format: swapchain.format(),
                    samples: 1,
                },
                depth: {
                    load: Clear,
                    store: DontCare,
                    format: vulkano::format::Format::D16Unorm,
                    samples: 1,
                }
            },
            pass: {
                color: [color],
                depth_stencil: {depth}
            }
        ).unwrap()
    );

    let pipeline = Arc::new(vulkano::pipeline::GraphicsPipeline::start()
        .vertex_input(vulkano::pipeline::vertex::TwoBuffersDefinition::new())
        .vertex_shader(vs.main_entry_point(), ())
        .triangle_list()
        .viewports(std::iter::once(vulkano::pipeline::viewport::Viewport {
            origin: [0.0, 0.0],
            depth_range: 0.0 .. 1.0,
            dimensions: [images[0].dimensions()[0] as f32, images[0].dimensions()[1] as f32],
        }))
        .fragment_shader(fs.main_entry_point(), ())
        .depth_stencil_simple_depth()
        .render_pass(vulkano::framebuffer::Subpass::from(renderpass.clone(), 0).unwrap())
        .build(device.clone())
        .unwrap());

    let set = Arc::new(vulkano::descriptor::descriptor_set::PersistentDescriptorSet::start(pipeline.clone(), 0)
        .add_buffer(uniform_buffer.clone()).unwrap()
        .build().unwrap()
    );

    let framebuffers = images.iter().map(|image| {
        Arc::new(vulkano::framebuffer::Framebuffer::start(renderpass.clone())
            .add(image.clone()).unwrap()
            .add(depth_buffer.clone()).unwrap()
            .build().unwrap())
    }).collect::<Vec<_>>();

    let mut previous_frame = Box::new(vulkano::sync::now(device.clone())) as Box<GpuFuture>;
    let rotation_start = std::time::Instant::now();

    loop {
        previous_frame.cleanup_finished();

        {
            // aquiring write lock for the uniform buffer
            let mut buffer_content = uniform_buffer.write().unwrap();

            let elapsed = rotation_start.elapsed();
            let rotation = elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1_000_000_000.0;
            let rotation = cgmath::Matrix3::from_angle_y(cgmath::Rad(rotation as f32));

            // since write lock implementd Deref and DerefMut traits,
            // we can update content directly
            buffer_content.world = cgmath::Matrix4::from(rotation).into();
        }

        let (image_num, acquire_future) = vulkano::swapchain::acquire_next_image(swapchain.clone(), None).unwrap();

        let command_buffer = vulkano::command_buffer::AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap()
            .begin_render_pass(
                framebuffers[image_num].clone(), false,
                vec![
                    [0.0, 0.0, 1.0, 1.0].into(),
                    1f32.into()
                ]).unwrap()
            .draw_indexed(
                pipeline.clone(), vulkano::command_buffer::DynamicState::none(),
                (vertex_buffer.clone(), normals_buffer.clone()),
                index_buffer.clone(), set.clone(), ()).unwrap()
            .end_render_pass().unwrap()
            .build().unwrap();

        let future = previous_frame.join(acquire_future)
            .then_execute(queue.clone(), command_buffer).unwrap()
            .then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
            .then_signal_fence_and_flush().unwrap();
        previous_frame = Box::new(future) as Box<_>;

        let mut done = false;
        events_loop.poll_events(|ev| {
            match ev {
                winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => done = true,
                _ => ()
            }
        });
        if done { return; }
    }
}

mod vs {
    #[derive(VulkanoShader)]
    #[ty = "vertex"]
    #[src = "
#version 450

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;

layout(location = 0) out vec3 v_normal;

layout(set = 0, binding = 0) uniform Data {
    mat4 world;
    mat4 view;
    mat4 proj;
} uniforms;

void main() {
    mat4 worldview = uniforms.view * uniforms.world;
    v_normal = transpose(inverse(mat3(worldview))) * normal;
    gl_Position = uniforms.proj * worldview * vec4(position, 1.0);
}
"]
    struct Dummy;
}

mod fs {
    #[derive(VulkanoShader)]
    #[ty = "fragment"]
    #[src = "
#version 450

layout(location = 0) in vec3 v_normal;
layout(location = 0) out vec4 f_color;

const vec3 LIGHT = vec3(0.0, 0.0, 1.0);

void main() {
    float brightness = dot(normalize(v_normal), normalize(LIGHT));
    vec3 dark_color = vec3(0.6, 0.0, 0.0);
    vec3 regular_color = vec3(1.0, 0.0, 0.0);

    f_color = vec4(mix(dark_color, regular_color, brightness), 1.0);
}
"]
    struct Dummy;
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
// use std::{mem};

use typed_arena::Arena;

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

#[derive(Debug)]
struct Node<'a> {
    weight: usize,
    count: usize,
    tail: Option<&'a mut Node<'a>>,
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    count: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List<'a> {
    lookahead0: &'a Node<'a>,
    lookahead1: &'a Node<'a>,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], max_bits: usize) -> Vec<u32> {
    let num_freqs = frequencies.len();
    let mut bit_lengths = vec![0; num_freqs];

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, count: i })
        .collect();

    let num_symbols = leaves.len();

    // Short circuit some special cases

    // TODO:
    // if ((1 << maxbits) < numsymbols) {
    //   free(leaves);
    //   return 1;  /* Error, too few maxbits to represent symbols. */
    // }

    if num_symbols == 0 {
        // There are no non-zero frequencies.
        return bit_lengths;
    }
    if num_symbols == 1 {
        bit_lengths[leaves[0].count] = 1;
        return bit_lengths;
    }
    if num_symbols == 2 {
        bit_lengths[leaves[0].count] = 1;
        bit_lengths[leaves[1].count] = 1;
        return bit_lengths;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_bits = if num_symbols - 1 < max_bits {
        num_symbols - 1
    } else {
        max_bits
    };

    let arena_capacity = max_bits * 2 * num_symbols;
    let node_arena: Arena<Node> = Arena::with_capacity(arena_capacity);

    let node0 = node_arena.alloc(Node {
        weight: leaves[0].weight,
        count: 1,
        tail: None,
    });

    let node1 = node_arena.alloc(Node {
        weight: leaves[1].weight,
        count: 2,
        tail: None,
    });

    let mut lists: Vec<List> = vec![
        List {
            lookahead0: node0,
            lookahead1: node1,
        };
        max_bits
    ];

    // let max_num_leaves = 2 * num_symbols - 2;
    // let mut lists = vec![
    //     List {
    //         lookahead0: Node::new(leaves[0].weight, 1, max_num_leaves),
    //         lookahead1: Node::new(leaves[1].weight, 2, max_num_leaves),
    //         next_leaf_index: 2,
    //     };
    //     max_bits
    // ];
    //
    // // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // // are already created in the initialization. Each boundary_pm run creates one.
    // let num_boundary_pm_runs = max_num_leaves - 2;
    // for _ in 0..num_boundary_pm_runs {
    //     boundary_pm_toplevel(&mut lists[..], &leaves);
    // }
    //
    // let mut a = lists.pop().unwrap().lookahead1.leaf_counts.into_iter().rev().peekable();
    //
    // let mut bitlength_value = 1;
    // while let Some(leaf_count) = a.next() {
    //     let next_count = *a.peek().unwrap_or(&0);
    //     for leaf in &leaves[next_count..leaf_count] {
    //         bit_lengths[leaf.count] = bitlength_value;
    //     }
    //     bitlength_value += 1;
    // }

    bit_lengths
}

// fn lowest_list(lists: &mut [List], leaves: &[Leaf]) {
//     // We're in the lowest list, just add another leaf to the lookaheads
//     // There will always be more leaves to be added on level 0 so this is safe.
//     let mut current_list = &mut lists[0];
//     let next_leaf = &leaves[current_list.next_leaf_index];
//     current_list.lookahead1.weight = next_leaf.weight;
//
//     current_list.lookahead1.leaf_counts[0] = current_list.lookahead0.leaf_counts.last().unwrap() + 1;
//     current_list.next_leaf_index += 1;
// }

// fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
//     let mut current_list = &mut lists[current_list_index];
//
//     // The next leaf goes next; counting itself makes the leaf_count increase by one.
//     current_list.lookahead1.weight = leaves[current_list.next_leaf_index].weight;
//     current_list.lookahead1.leaf_counts.clear();
//     current_list.lookahead1.leaf_counts.extend_from_slice(&current_list.lookahead0.leaf_counts);
//     let last_index = current_list.lookahead1.leaf_counts.len() - 1;
//     current_list.lookahead1.leaf_counts[last_index] += 1;
//     current_list.next_leaf_index += 1;
// }

// fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
//     {
//         let (head, tail) = lists.split_at_mut(current_list_index);
//         let prev_list = head.last_mut().unwrap();
//         let current_list = tail.first_mut().unwrap();
//
//         let previous_list_leaf_counts = &prev_list.lookahead1.leaf_counts;
//
//         // Make a tree from the lookaheads from the previous list; that goes next.
//         // This is not a leaf node, so the leaf count stays the same.
//         current_list.lookahead1.weight = weight_sum;
//         current_list.lookahead1.leaf_counts.clear();
//
//         current_list.lookahead1.leaf_counts.extend_from_slice(previous_list_leaf_counts);
//         current_list.lookahead1.leaf_counts.push(*current_list.lookahead0.leaf_counts.last().unwrap());
//     }
//
//     // The previous list needs two new lookahead nodes.
//     boundary_pm(lists, leaves, current_list_index - 1);
//     boundary_pm(lists, leaves, current_list_index - 1);
// }

// fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
//     let last_index = lists.len() - 1;
//     boundary_pm(lists, leaves, last_index);
// }

// fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
//     let next_leaf_index = lists[current_list_index].next_leaf_index;
//     let num_symbols = leaves.len();
//
//     if current_list_index == 0 && next_leaf_index == num_symbols {
//         // We've added all the leaves to the lowest list, so we're done here
//         return;
//     }
//
//     mem::swap(&mut lists[current_list_index].lookahead0, &mut lists[current_list_index].lookahead1);
//
//     if current_list_index == 0 {
//         lowest_list(lists, leaves);
//     } else {
//         // We're at a list other than the lowest list.
//         let weight_sum = {
//             let previous_list = &lists[current_list_index - 1];
//             previous_list.lookahead0.weight + previous_list.lookahead1.weight
//         };
//
//         if next_leaf_index < num_symbols && weight_sum > leaves[next_leaf_index].weight {
//             next_leaf(lists, leaves, current_list_index);
//         } else {
//             next_tree(weight_sum, lists, leaves, current_list_index);
//         }
//     }
// }

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<commit_msg>Introduce an owner for everything; implement boundary_pm on it<commit_after>use std::cmp::Ordering;

use typed_arena::Arena;

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

struct Thing<'a> {
    node_arena: &'a Arena<Node<'a>>,
    leaves: Vec<Leaf>,
    lists: Vec<List<'a>>,
}

#[derive(Debug)]
struct Node<'a> {
    weight: usize,
    count: usize,
    tail: Option<&'a Node<'a>>,
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    count: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List<'a> {
    lookahead0: &'a Node<'a>,
    lookahead1: &'a Node<'a>,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], max_bits: usize) -> Vec<u32> {
    let num_freqs = frequencies.len();
    let mut bit_lengths = vec![0; num_freqs];

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, count: i })
        .collect();

    let num_symbols = leaves.len();

    // Short circuit some special cases

    // TODO:
    // if ((1 << maxbits) < numsymbols) {
    //   free(leaves);
    //   return 1;  /* Error, too few maxbits to represent symbols. */
    // }

    if num_symbols == 0 {
        // There are no non-zero frequencies.
        return bit_lengths;
    }
    if num_symbols == 1 {
        bit_lengths[leaves[0].count] = 1;
        return bit_lengths;
    }
    if num_symbols == 2 {
        bit_lengths[leaves[0].count] = 1;
        bit_lengths[leaves[1].count] = 1;
        return bit_lengths;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_bits = if num_symbols - 1 < max_bits {
        num_symbols - 1
    } else {
        max_bits
    };

    let arena_capacity = max_bits * 2 * num_symbols;
    let node_arena: Arena<Node> = Arena::with_capacity(arena_capacity);

    let node0 = node_arena.alloc(Node {
        weight: leaves[0].weight,
        count: 1,
        tail: None,
    });

    let node1 = node_arena.alloc(Node {
        weight: leaves[1].weight,
        count: 2,
        tail: None,
    });

    let lists: Vec<List> = vec![
        List {
            lookahead0: node0,
            lookahead1: node1,
        };
        max_bits
    ];

    let mut thing = Thing {
        node_arena: &node_arena,
        leaves,
        lists,
    };

    // In the last list, 2 * num_symbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = 2 * num_symbols - 4;
    for _ in 0..num_boundary_pm_runs - 1 {
        thing.boundary_pm(max_bits - 1);
    }

    // TODO: boundary_pm_final

    // let mut a = lists.pop().unwrap().lookahead1.leaf_counts.into_iter().rev().peekable();
    //
    // let mut bitlength_value = 1;
    // while let Some(leaf_count) = a.next() {
    //     let next_count = *a.peek().unwrap_or(&0);
    //     for leaf in &leaves[next_count..leaf_count] {
    //         bit_lengths[leaf.count] = bitlength_value;
    //     }
    //     bitlength_value += 1;
    // }

    bit_lengths
}

impl<'a> Thing<'a> {
    fn boundary_pm(&mut self, index: usize) {
        let num_symbols = self.leaves.len();

        let last_count = self.lists[index].lookahead1.count; // Count of last chain of list.

        if index == 0 && last_count >= num_symbols {
            return
        }

        self.lists[index].lookahead0 = self.lists[index].lookahead1;

        if index == 0 {
            // New leaf node in list 0.
            let new_chain = self.node_arena.alloc(Node {
               weight: self.leaves[last_count].weight,
               count: last_count + 1,
               tail: self.lists[index].lookahead0.tail,
            });
            self.lists[index].lookahead1 = new_chain;
        } else {
            let weight_sum = {
                let previous_list = &self.lists[index - 1];
                previous_list.lookahead0.weight + previous_list.lookahead1.weight
            };

            if last_count < num_symbols && weight_sum > self.leaves[last_count].weight {
                // New leaf inserted in list, so count is incremented.
                let new_chain = self.node_arena.alloc(Node {
                   weight: self.leaves[last_count].weight,
                   count: last_count + 1,
                   tail: self.lists[index].lookahead0.tail,
                });
                self.lists[index].lookahead1 = new_chain;
            } else {
                let new_chain = self.node_arena.alloc(Node {
                   weight: weight_sum,
                   count: last_count,
                   tail: Some(self.lists[index - 1].lookahead1),
                });
                self.lists[index].lookahead1 = new_chain;

                // Two lookahead chains of previous list used up, create new ones.
                self.boundary_pm(index - 1);
                self.boundary_pm(index - 1);
            }
        }
    }
}

// fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
//     let mut current_list = &mut lists[current_list_index];
//
//     // The next leaf goes next; counting itself makes the leaf_count increase by one.
//     current_list.lookahead1.weight = leaves[current_list.next_leaf_index].weight;
//     current_list.lookahead1.leaf_counts.clear();
//     current_list.lookahead1.leaf_counts.extend_from_slice(&current_list.lookahead0.leaf_counts);
//     let last_index = current_list.lookahead1.leaf_counts.len() - 1;
//     current_list.lookahead1.leaf_counts[last_index] += 1;
//     current_list.next_leaf_index += 1;
// }

// fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
//     {
//         let (head, tail) = lists.split_at_mut(current_list_index);
//         let prev_list = head.last_mut().unwrap();
//         let current_list = tail.first_mut().unwrap();
//
//         let previous_list_leaf_counts = &prev_list.lookahead1.leaf_counts;
//
//         // Make a tree from the lookaheads from the previous list; that goes next.
//         // This is not a leaf node, so the leaf count stays the same.
//         current_list.lookahead1.weight = weight_sum;
//         current_list.lookahead1.leaf_counts.clear();
//
//         current_list.lookahead1.leaf_counts.extend_from_slice(previous_list_leaf_counts);
//         current_list.lookahead1.leaf_counts.push(*current_list.lookahead0.leaf_counts.last().unwrap());
//     }
//
//     // The previous list needs two new lookahead nodes.
//     boundary_pm(lists, leaves, current_list_index - 1);
//     boundary_pm(lists, leaves, current_list_index - 1);
// }

// fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
//     let last_index = lists.len() - 1;
//     boundary_pm(lists, leaves, last_index);
// }

// fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
//     let next_leaf_index = lists[current_list_index].next_leaf_index;
//     let num_symbols = leaves.len();
//
//     if current_list_index == 0 && next_leaf_index == num_symbols {
//         // We've added all the leaves to the lowest list, so we're done here
//         return;
//     }
//
//     mem::swap(&mut lists[current_list_index].lookahead0, &mut lists[current_list_index].lookahead1);
//
//     if current_list_index == 0 {
//         lowest_list(lists, leaves);
//     } else {
//         // We're at a list other than the lowest list.
//         let weight_sum = {
//             let previous_list = &lists[current_list_index - 1];
//             previous_list.lookahead0.weight + previous_list.lookahead1.weight
//         };
//
//         if next_leaf_index < num_symbols && weight_sum > leaves[next_leaf_index].weight {
//             next_leaf(lists, leaves, current_list_index);
//         } else {
//             next_tree(weight_sum, lists, leaves, current_list_index);
//         }
//     }
// }

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<|endoftext|>


<commit_before>use term;

use std::convert::AsRef;
use std::io;
use std::io::Write;
use std::fmt::Display;

/// The level of information to display to a logger
///
/// This enum should only be used as parameters for `Logger` or `Book` methods. Library
/// users should **not** do exhaustive pattern matching on the variants of the enums,
/// as it might grow variants later.
#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
pub enum InfoLevel {
    /// Debug: the lowest level
    Debug = 0,
    /// Warning: won't be displayed by default
    Warning,
    /// Info: won't be displayed by default
    Info,
    /// Error
    Error,
    /// Quiet
    Quiet,

    /// Hint that destructuring should not be exhaustive
    #[doc(hidden)]
    __NonExhaustive,
}

use self::InfoLevel::*;

/// Abstract over either term output or (if it fails) io::stderr()
enum Output {
    Terminal(Box<term::StderrTerminal>),
    Stderr(io::Stderr),
}

impl Output {
    /// Creates a new Output
    pub fn new() -> Output {
        if let Some(term) = term::stderr() {
            if (*term).supports_color() {
                return Output::Terminal(term)
            }
        }
        return Output::Stderr(io::stderr())
    }

    /// Print a msg prefixed by a coloured `level` message
    pub fn print_msg<S: Display>(&mut self, level: InfoLevel, msg: S) {
        let (colour, head_msg) = match level {
            Debug => (term::color::BRIGHT_BLUE, lformat!("Debug: ")),
            Warning => (term::color::BRIGHT_YELLOW, lformat!("Warning: ")),
            Info => (term::color::BRIGHT_GREEN, lformat!("Info: ")),
            Error => (term::color::BRIGHT_RED, lformat!("Error: ")),
            _ => unreachable!(),
        };
        match *self {
            Output::Stderr(ref mut stderr) => {
                writeln!(stderr, "{}{}",
                       head_msg,
                       msg)
                    .unwrap();
            },
            Output::Terminal(ref mut term) => {
                let _ = term.fg(colour);
                let _ = term.attr(term::Attr::Bold);
                write!(term, "{}",
                       head_msg)
                    .unwrap();
                let _ = term.reset();
                writeln!(term, "{}",
                       msg)
                    .unwrap();
            }
        }
    }
}

/// Logs info and warning message and choose whether to display them
/// according to verbosity
#[derive(Debug)]
pub struct Logger {
    verbosity: InfoLevel,
}

impl Logger {
    /// Creates a new logger with default verbosity
    pub fn new() -> Logger {
        Logger { verbosity: InfoLevel::Info }
    }

    /// Sets verbosity
    pub fn set_verbosity(&mut self, verbosity: InfoLevel) -> &mut Logger {
        self.verbosity = verbosity;
        self
    }

    /// Prints a message
    pub fn display_msg<S: AsRef<str>>(level: InfoLevel, s: S) {
        let mut output = Output::new();
        output.print_msg(level, s.as_ref());
    }

    /// Prints a debug message
    pub fn display_debug<S: AsRef<str>>(s: S) {
        Self::display_msg(Debug, s);
    }

    /// Prints an info message
    pub fn display_info<S: AsRef<str>>(s: S) {
        Self::display_msg(Info, s);
    }

    /// Prints a warning message
    pub fn display_warning<S: AsRef<str>>(s: S) {
        Self::display_msg(Warning, s);
    }

    /// Prints an error message
    pub fn display_error<S: AsRef<str>>(s: S) {
        Self::display_msg(Error, s);
    }

    /// Prints a message if logger's verbosity <= level
    pub fn log<S: AsRef<str>>(&self, level: InfoLevel, s: S) {
        if level >= self.verbosity {
            match level {
                Debug => Self::display_debug(s),
                Info => Self::display_info(s),
                Warning => Self::display_warning(s),
                Error => Self::display_error(s),
                Quiet => unreachable!(),
                __NonExhaustive => unreachable!(),
            }
        }
    }

    /// Equivalent of log(Debug, s)
    pub fn debug<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Debug, s);
    }

    /// Equivalent of log(Info, s)
    pub fn info<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Info, s);
    }

    /// Equivalent of log(Warning, s)
    pub fn warning<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Warning, s);
    }

    /// Equivalent of log(Error, s)
    pub fn error<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Error, s);
    }
}

<commit_msg>Improve Logger's documentation<commit_after>use term;

use std::convert::AsRef;
use std::io;
use std::io::Write;
use std::fmt::Display;

/// The level of information to display to a logger
///
/// This enum should only be used as parameters for `Logger` or `Book` methods. Library
/// users should **not** do exhaustive pattern matching on the variants of the enums,
/// as it might grow variants later.
#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
pub enum InfoLevel {
    /// Debug: the lowest level
    Debug = 0,
    /// Warning: won't be displayed by default
    Warning,
    /// Info: won't be displayed by default
    Info,
    /// Error
    Error,
    /// Quiet
    Quiet,

    /// Hint that destructuring should not be exhaustive
    #[doc(hidden)]
    __NonExhaustive,
}

use self::InfoLevel::*;

/// Abstract over either term output or (if it fails) io::stderr()
enum Output {
    Terminal(Box<term::StderrTerminal>),
    Stderr(io::Stderr),
}

impl Output {
    /// Creates a new Output
    pub fn new() -> Output {
        if let Some(term) = term::stderr() {
            if (*term).supports_color() {
                return Output::Terminal(term)
            }
        }
        return Output::Stderr(io::stderr())
    }

    /// Print a msg prefixed by a coloured `level` message
    pub fn print_msg<S: Display>(&mut self, level: InfoLevel, msg: S) {
        let (colour, head_msg) = match level {
            Debug => (term::color::BRIGHT_BLUE, lformat!("Debug: ")),
            Warning => (term::color::BRIGHT_YELLOW, lformat!("Warning: ")),
            Info => (term::color::BRIGHT_GREEN, lformat!("Info: ")),
            Error => (term::color::BRIGHT_RED, lformat!("Error: ")),
            _ => unreachable!(),
        };
        match *self {
            Output::Stderr(ref mut stderr) => {
                writeln!(stderr, "{}{}",
                       head_msg,
                       msg)
                    .unwrap();
            },
            Output::Terminal(ref mut term) => {
                let _ = term.fg(colour);
                let _ = term.attr(term::Attr::Bold);
                write!(term, "{}",
                       head_msg)
                    .unwrap();
                let _ = term.reset();
                writeln!(term, "{}",
                       msg)
                    .unwrap();
            }
        }
    }
}

/// Logs info and warning message and choose whether to display them
/// according to verbosity.
///
/// This struct has two families of methods:
///
/// * `logger.{level}`: will only print the message if `level` is below or equal
///   `logger`'s current verbosity level;
/// * `Logger::display_{level}`: will print the message in any case, since they are static
///   methods and don't depend on the current verbosity.
///
/// # Example
///
/// ```
/// use crowbook::{Logger, InfoLevel};
/// let mut logger = Logger::new();
/// logger.warning("Won't be printed since default level is above that");
/// logger.set_verbosity(InfoLevel::Warning);
/// logger.warning("Now, this will be printed");
/// Logger::display_debug("Display in any cases");
/// ```
///
/// # See also
/// * `InfoLevel`
#[derive(Debug)]
pub struct Logger {
    verbosity: InfoLevel,
}

impl Logger {
    /// Creates a new logger with default verbosity (`Info`).
    pub fn new() -> Logger {
        Logger { verbosity: InfoLevel::Info }
    }

    /// Sets verbosity
    pub fn set_verbosity(&mut self, verbosity: InfoLevel) -> &mut Logger {
        self.verbosity = verbosity;
        self
    }

    /// Prints a message
    pub fn display_msg<S: AsRef<str>>(level: InfoLevel, s: S) {
        let mut output = Output::new();
        output.print_msg(level, s.as_ref());
    }

    /// Prints a debug message
    pub fn display_debug<S: AsRef<str>>(s: S) {
        Self::display_msg(Debug, s);
    }

    /// Prints an info message
    pub fn display_info<S: AsRef<str>>(s: S) {
        Self::display_msg(Info, s);
    }

    /// Prints a warning message
    pub fn display_warning<S: AsRef<str>>(s: S) {
        Self::display_msg(Warning, s);
    }

    /// Prints an error message
    pub fn display_error<S: AsRef<str>>(s: S) {
        Self::display_msg(Error, s);
    }

    /// Prints a message if logger's verbosity <= level
    pub fn log<S: AsRef<str>>(&self, level: InfoLevel, s: S) {
        if level >= self.verbosity {
            match level {
                Debug => Self::display_debug(s),
                Info => Self::display_info(s),
                Warning => Self::display_warning(s),
                Error => Self::display_error(s),
                Quiet => unreachable!(),
                __NonExhaustive => unreachable!(),
            }
        }
    }

    /// Equivalent of log(Debug, s)
    pub fn debug<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Debug, s);
    }

    /// Equivalent of log(Info, s)
    pub fn info<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Info, s);
    }

    /// Equivalent of log(Warning, s)
    pub fn warning<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Warning, s);
    }

    /// Equivalent of log(Error, s)
    pub fn error<S: AsRef<str>>(&self, s: S) {
        self.log(InfoLevel::Error, s);
    }
}

<|endoftext|>