<commit_before>use std;
use x86intrin::*;

#[derive(Clone, Copy)]
pub struct FieldBit {
    m: m128i,
}

impl FieldBit {
    pub fn new(m: m128i) -> FieldBit {
        FieldBit {
            m: m,
        }
    }

    pub fn new_empty() -> FieldBit {
        FieldBit {
            m: mm_setzero_si128()
        }
    }

    pub fn from_values(v1: u16, v2: u16, v3: u16, v4: u16, v5: u16, v6: u16, v7: u16, v8: u16) -> FieldBit {
        FieldBit {
            m: mm_setr_epi16(v1 as i16, v2 as i16, v3 as i16, v4 as i16,
                             v5 as i16, v6 as i16, v7 as i16, v8 as i16)
        }
    }

    pub fn from_onebit(x: usize, y: usize) -> FieldBit {
        FieldBit {
            m: FieldBit::onebit(x, y)
        }
    }

    pub fn from_str(s: &str) -> FieldBit {
        let mut f = FieldBit::new_empty();

        assert!(s.len() % 6 == 0);

        let mut cnt = 0;
        for b in s.bytes().rev() {
            let x = 6 - (cnt % 6);
            let y = (cnt / 6) + 1;
            if b == b'1' {
                f.set(x, y);
            }
            cnt += 1;
        }

        f
    }

    pub fn as_m128i(&self) -> m128i {
        self.m
    }

    pub fn get(&self, x: usize, y: usize) -> bool {
        debug_assert!(FieldBit::check_in_range(x, y));
        mm_testz_si128(FieldBit::onebit(x, y), self.m) == 0
    }

    pub fn set(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_or_si128(FieldBit::onebit(x, y), self.m)
    }

    pub fn unset(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_andnot_si128(FieldBit::onebit(x, y), self.m)
    }

    pub fn masked_field_12(&self) -> FieldBit {
        FieldBit {
            m: mm_and_si128(self.m, mm_setr_epi16(0, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0)),
        }
    }

    pub fn masked_field_13(&self) -> FieldBit {
        FieldBit {
            m: mm_and_si128(self.m, mm_setr_epi16(0, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0)),
        }
    }

    pub fn popcount(&self) -> usize {
        let x = self.m.as_u64x2();
        let low: u64 = x.extract(0);
        let high: u64 = x.extract(1);
        (low.count_ones() + high.count_ones()) as usize
    }

    pub fn expand(&self, mask: &FieldBit) -> FieldBit {
        let mut seed = self.m;
        loop {
            let mut expanded = seed;
            expanded = mm_or_si128(mm_slli_epi16(seed, 1), expanded);
            expanded = mm_or_si128(mm_srli_epi16(seed, 1), expanded);
            expanded = mm_or_si128(mm_slli_si128(seed, 2), expanded);
            expanded = mm_or_si128(mm_srli_si128(seed, 2), expanded);
            expanded = mm_and_si128(mask.m, expanded);

            if mm_testc_si128(seed, expanded) != 0 { // seed == expanded
                return FieldBit { m: expanded };
            }
            seed = expanded;
        }
    }

    pub fn expand1(&self, mask: &FieldBit) -> FieldBit {
        let seed = self.m;
        let v1 = mm_slli_epi16(seed, 1);
        let v2 = mm_srli_epi16(seed, 1);
        let v3 = mm_slli_si128(seed, 2);
        let v4 = mm_srli_si128(seed, 2);

        let m = ((seed | v1) | (v2 | v3) | v4) & mask.m;
        FieldBit { m: m }
    }

    fn check_in_range(x: usize, y: usize) -> bool {
        x < 8 && y < 16
    }

    fn onebit(x: usize, y: usize) -> m128i {
        debug_assert!(FieldBit::check_in_range(x, y));

        let shift = ((x << 4) | y) & 0x3F;
        let hi: i64 = (x as i64) >> 2;
        let lo: i64 = hi ^ 1;

        mm_set_epi64x(hi << shift, lo << shift)
    }
}

impl std::fmt::Display for FieldBit {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        let x = self.m.as_u16x8();
        write!(f, "({}, {}, {}, {}, {}, {}, {}, {})",
               x.extract(0), x.extract(1), x.extract(2), x.extract(3),
               x.extract(4), x.extract(5), x.extract(6), x.extract(7))
    }
}

#[cfg(test)]
mod tests {
    use field;
    use field_bit::FieldBit;

    #[test]
    fn test_empty() {
        let fb = FieldBit::new_empty();
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), false);
            }
        }
    }

    #[test]
    fn test_from_value() {
        let fb = FieldBit::from_values(1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), x == y, "failed at x={}, y={}, fb.get(x, y)={}", x, y, fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_from_str() {
        let fb = FieldBit::from_str(concat!(
            "111...",
            "......",
            "111..."));

        for x in 0 .. 8 {
            for y in 0 .. 16 {
                let b = (y == 1 || y == 3) && (1 <= x && x <= 3);
                assert_eq!(fb.get(x, y), b, "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_set_get() {
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                let mut fb = FieldBit::new_empty();
                assert!(!fb.get(x, y));
                fb.set(x, y);
                assert!(fb.get(x, y));
                fb.unset(x, y);
                assert!(!fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_masked_field() {
        let fb = FieldBit::from_values(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
        let fb12 = fb.masked_field_12();
        let fb13 = fb.masked_field_13();

        for x in 0 .. field::MAP_WIDTH {
            for y in 0 .. field::MAP_HEIGHT {
                assert!(fb.get(x, y), "x={}, y={}", x, y);
                assert_eq!(fb12.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 12, "x={}, y={}", x, y);
                assert_eq!(fb13.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 13, "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_popcount() {
        let fb = FieldBit::from_values(1, 2, 3, 4, 5, 6, 7, 8);
        assert_eq!(fb.popcount(), 1 + 1 + 2 + 1 + 2 + 2 + 3 + 1)
    }

    #[test]
    fn test_expand() {
        let mask = FieldBit::from_str(concat!(
            ".1....",
            "1.11..",
            "1.1...",
            "1.1...",
        ));

        let expected = FieldBit::from_str(concat!(
            "..11..",
            "..1...",
            "..1..."));

        let actual = FieldBit::from_onebit(3, 1).expand(&mask);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(actual.get(x, y), expected.get(x, y), "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_expand1() {
        let mask = FieldBit::from_str(concat!(
            "111111",
            "111111",
            "111111"));

        let seed = FieldBit::from_str(concat!(
            "......",
            "1...1.",
            "......"));

        let expected = FieldBit::from_str(concat!(
            "1...1.",
            "11.111",
            "1...1."));

        let actual = seed.expand1(&mask);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(actual.get(x, y), expected.get(x, y), "x={}, y={}", x, y);
            }
        }
    }
}
<commit_msg>Add PartialEq and BitOr to FieldBit<commit_after>use std;
use x86intrin::*;

#[derive(Clone, Copy, Debug)]
pub struct FieldBit {
    m: m128i,
}

impl FieldBit {
    pub fn new(m: m128i) -> FieldBit {
        FieldBit {
            m: m,
        }
    }

    pub fn new_empty() -> FieldBit {
        FieldBit {
            m: mm_setzero_si128()
        }
    }

    pub fn from_values(v1: u16, v2: u16, v3: u16, v4: u16, v5: u16, v6: u16, v7: u16, v8: u16) -> FieldBit {
        FieldBit {
            m: mm_setr_epi16(v1 as i16, v2 as i16, v3 as i16, v4 as i16,
                             v5 as i16, v6 as i16, v7 as i16, v8 as i16)
        }
    }

    pub fn from_onebit(x: usize, y: usize) -> FieldBit {
        FieldBit {
            m: FieldBit::onebit(x, y)
        }
    }

    pub fn from_str(s: &str) -> FieldBit {
        let mut f = FieldBit::new_empty();

        assert!(s.len() % 6 == 0);

        let mut cnt = 0;
        for b in s.bytes().rev() {
            let x = 6 - (cnt % 6);
            let y = (cnt / 6) + 1;
            if b == b'1' {
                f.set(x, y);
            }
            cnt += 1;
        }

        f
    }

    pub fn as_m128i(&self) -> m128i {
        self.m
    }

    pub fn get(&self, x: usize, y: usize) -> bool {
        debug_assert!(FieldBit::check_in_range(x, y));
        mm_testz_si128(FieldBit::onebit(x, y), self.m) == 0
    }

    pub fn set(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_or_si128(FieldBit::onebit(x, y), self.m)
    }

    pub fn unset(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_andnot_si128(FieldBit::onebit(x, y), self.m)
    }

    pub fn masked_field_12(&self) -> FieldBit {
        FieldBit {
            m: mm_and_si128(self.m, mm_setr_epi16(0, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0)),
        }
    }

    pub fn masked_field_13(&self) -> FieldBit {
        FieldBit {
            m: mm_and_si128(self.m, mm_setr_epi16(0, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0)),
        }
    }

    pub fn popcount(&self) -> usize {
        let x = self.m.as_u64x2();
        let low: u64 = x.extract(0);
        let high: u64 = x.extract(1);
        (low.count_ones() + high.count_ones()) as usize
    }

    pub fn expand(&self, mask: &FieldBit) -> FieldBit {
        let mut seed = self.m;
        loop {
            let mut expanded = seed;
            expanded = mm_or_si128(mm_slli_epi16(seed, 1), expanded);
            expanded = mm_or_si128(mm_srli_epi16(seed, 1), expanded);
            expanded = mm_or_si128(mm_slli_si128(seed, 2), expanded);
            expanded = mm_or_si128(mm_srli_si128(seed, 2), expanded);
            expanded = mm_and_si128(mask.m, expanded);

            if mm_testc_si128(seed, expanded) != 0 { // seed == expanded
                return FieldBit { m: expanded };
            }
            seed = expanded;
        }
    }

    pub fn expand1(&self, mask: &FieldBit) -> FieldBit {
        let seed = self.m;
        let v1 = mm_slli_epi16(seed, 1);
        let v2 = mm_srli_epi16(seed, 1);
        let v3 = mm_slli_si128(seed, 2);
        let v4 = mm_srli_si128(seed, 2);

        let m = ((seed | v1) | (v2 | v3) | v4) & mask.m;
        FieldBit { m: m }
    }

    fn check_in_range(x: usize, y: usize) -> bool {
        x < 8 && y < 16
    }

    fn onebit(x: usize, y: usize) -> m128i {
        debug_assert!(FieldBit::check_in_range(x, y));

        let shift = ((x << 4) | y) & 0x3F;
        let hi: i64 = (x as i64) >> 2;
        let lo: i64 = hi ^ 1;

        mm_set_epi64x(hi << shift, lo << shift)
    }
}

impl std::ops::BitOr for FieldBit {
    type Output = FieldBit;

    fn bitor(self, rhs: FieldBit) -> FieldBit {
        FieldBit::new(mm_or_si128(self.m, rhs.m))
    }
}

impl std::cmp::PartialEq<FieldBit> for FieldBit {
    fn eq(&self, other: &FieldBit) -> bool {
        let x = mm_xor_si128(self.m, other.m);
        mm_testz_si128(x, x) == 1
    }
}

impl std::fmt::Display for FieldBit {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        let x = self.m.as_u16x8();
        write!(f, "({}, {}, {}, {}, {}, {}, {}, {})",
               x.extract(0), x.extract(1), x.extract(2), x.extract(3),
               x.extract(4), x.extract(5), x.extract(6), x.extract(7))
    }
}

#[cfg(test)]
mod tests {
    use field;
    use field_bit::FieldBit;

    #[test]
    fn test_empty() {
        let fb = FieldBit::new_empty();
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), false);
            }
        }
    }

    #[test]
    fn test_from_value() {
        let fb = FieldBit::from_values(1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), x == y, "failed at x={}, y={}, fb.get(x, y)={}", x, y, fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_from_str() {
        let fb = FieldBit::from_str(concat!(
            "111...",
            "......",
            "111..."));

        for x in 0 .. 8 {
            for y in 0 .. 16 {
                let b = (y == 1 || y == 3) && (1 <= x && x <= 3);
                assert_eq!(fb.get(x, y), b, "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_set_get() {
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                let mut fb = FieldBit::new_empty();
                assert!(!fb.get(x, y));
                fb.set(x, y);
                assert!(fb.get(x, y));
                fb.unset(x, y);
                assert!(!fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_masked_field() {
        let fb = FieldBit::from_values(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
        let fb12 = fb.masked_field_12();
        let fb13 = fb.masked_field_13();

        for x in 0 .. field::MAP_WIDTH {
            for y in 0 .. field::MAP_HEIGHT {
                assert!(fb.get(x, y), "x={}, y={}", x, y);
                assert_eq!(fb12.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 12, "x={}, y={}", x, y);
                assert_eq!(fb13.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 13, "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_popcount() {
        let fb = FieldBit::from_values(1, 2, 3, 4, 5, 6, 7, 8);
        assert_eq!(fb.popcount(), 1 + 1 + 2 + 1 + 2 + 2 + 3 + 1)
    }

    #[test]
    fn test_expand() {
        let mask = FieldBit::from_str(concat!(
            ".1....",
            "1.11..",
            "1.1...",
            "1.1...",
        ));

        let expected = FieldBit::from_str(concat!(
            "..11..",
            "..1...",
            "..1..."));

        let actual = FieldBit::from_onebit(3, 1).expand(&mask);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(actual.get(x, y), expected.get(x, y), "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_expand1() {
        let mask = FieldBit::from_str(concat!(
            "111111",
            "111111",
            "111111"));

        let seed = FieldBit::from_str(concat!(
            "......",
            "1...1.",
            "......"));

        let expected = FieldBit::from_str(concat!(
            "1...1.",
            "11.111",
            "1...1."));

        let actual = seed.expand1(&mask);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(actual.get(x, y), expected.get(x, y), "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_eq() {
        let fb1 = FieldBit::from_str(concat!(
            "1....1",
            "1....1",
            "111111"));
        let fb2 = FieldBit::from_str(concat!(
            "111111",
            "1....1",
            "1....1"));

        assert!(fb1 == fb1);
        assert!(fb2 == fb2);
        assert!(fb1 != fb2);
    }

    #[test]
    fn test_bitor() {
        let fb1 = FieldBit::from_str(concat!(
            "1....1",
            "1....1",
            "111111"));
        let fb2 = FieldBit::from_str(concat!(
            "111111",
            "1....1",
            "1....1"));
        let expected = FieldBit::from_str(concat!(
            "111111",
            "1....1",
            "111111"));

        assert_eq!(expected, fb1 | fb2);
    }
}
<|endoftext|>


<commit_before>#![doc = include_str!("core_arch_docs.md")]
#![allow(improper_ctypes_definitions)]
#![allow(dead_code)]
#![allow(unused_features)]
#![deny(rust_2018_idioms)]
#![feature(
    asm,
    const_fn,
    const_fn_union,
    const_fn_transmute,
    custom_inner_attributes,
    link_llvm_intrinsics,
    platform_intrinsics,
    repr_simd,
    simd_ffi,
    proc_macro_hygiene,
    stmt_expr_attributes,
    core_intrinsics,
    no_core,
    rustc_attrs,
    stdsimd,
    staged_api,
    doc_cfg,
    tbm_target_feature,
    sse4a_target_feature,
    arm_target_feature,
    aarch64_target_feature,
    cmpxchg16b_target_feature,
    avx512_target_feature,
    mips_target_feature,
    powerpc_target_feature,
    wasm_target_feature,
    abi_unadjusted,
    adx_target_feature,
    rtm_target_feature,
    f16c_target_feature,
    external_doc,
    allow_internal_unstable,
    decl_macro,
    extended_key_value_attributes,
    bench_black_box
)]
#![cfg_attr(test, feature(test, abi_vectorcall))]
#![cfg_attr(all(test, target_arch = "wasm32"), feature(wasm_simd))]
#![deny(clippy::missing_inline_in_public_items)]
#![allow(
    clippy::inline_always,
    clippy::too_many_arguments,
    clippy::cast_sign_loss,
    clippy::cast_lossless,
    clippy::cast_possible_wrap,
    clippy::cast_possible_truncation,
    clippy::cast_precision_loss,
    clippy::shadow_reuse,
    clippy::cognitive_complexity,
    clippy::similar_names,
    clippy::many_single_char_names
)]
#![cfg_attr(test, allow(unused_imports))]
#![no_std]
#![unstable(feature = "stdsimd", issue = "27731")]
#![doc(
    test(attr(deny(warnings))),
    test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
)]

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
#[macro_use]
extern crate std_detect;
#[path = "mod.rs"]
mod core_arch;

pub use self::core_arch::arch;

#[allow(unused_imports)]
use core::{convert, ffi, hint, intrinsics, marker, mem, ops, ptr, sync};
<commit_msg>remvoe const_fn leftovers<commit_after>#![doc = include_str!("core_arch_docs.md")]
#![allow(improper_ctypes_definitions)]
#![allow(dead_code)]
#![allow(unused_features)]
#![deny(rust_2018_idioms)]
#![feature(
    asm,
    const_fn_union,
    const_fn_transmute,
    custom_inner_attributes,
    link_llvm_intrinsics,
    platform_intrinsics,
    repr_simd,
    simd_ffi,
    proc_macro_hygiene,
    stmt_expr_attributes,
    core_intrinsics,
    no_core,
    rustc_attrs,
    stdsimd,
    staged_api,
    doc_cfg,
    tbm_target_feature,
    sse4a_target_feature,
    arm_target_feature,
    aarch64_target_feature,
    cmpxchg16b_target_feature,
    avx512_target_feature,
    mips_target_feature,
    powerpc_target_feature,
    wasm_target_feature,
    abi_unadjusted,
    adx_target_feature,
    rtm_target_feature,
    f16c_target_feature,
    external_doc,
    allow_internal_unstable,
    decl_macro,
    extended_key_value_attributes,
    bench_black_box
)]
#![cfg_attr(test, feature(test, abi_vectorcall))]
#![cfg_attr(all(test, target_arch = "wasm32"), feature(wasm_simd))]
#![deny(clippy::missing_inline_in_public_items)]
#![allow(
    clippy::inline_always,
    clippy::too_many_arguments,
    clippy::cast_sign_loss,
    clippy::cast_lossless,
    clippy::cast_possible_wrap,
    clippy::cast_possible_truncation,
    clippy::cast_precision_loss,
    clippy::shadow_reuse,
    clippy::cognitive_complexity,
    clippy::similar_names,
    clippy::many_single_char_names
)]
#![cfg_attr(test, allow(unused_imports))]
#![no_std]
#![unstable(feature = "stdsimd", issue = "27731")]
#![doc(
    test(attr(deny(warnings))),
    test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
)]

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
#[macro_use]
extern crate std_detect;
#[path = "mod.rs"]
mod core_arch;

pub use self::core_arch::arch;

#[allow(unused_imports)]
use core::{convert, ffi, hint, intrinsics, marker, mem, ops, ptr, sync};
<|endoftext|>


<commit_before>use std::{
    sync::Arc,
    time,
};

use ra_db::{
    CheckCanceled, FileId, Canceled, SourceDatabase,
    salsa::{self, Database},
};

use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};

#[salsa::database(
    ra_db::SourceDatabaseStorage,
    LineIndexDatabaseStorage,
    symbol_index::SymbolsDatabaseStorage,
    hir::db::InternDatabaseStorage,
    hir::db::AstDatabaseStorage,
    hir::db::DefDatabaseStorage,
    hir::db::HirDatabaseStorage
)]
#[derive(Debug)]
pub(crate) struct RootDatabase {
    runtime: salsa::Runtime<RootDatabase>,
    pub(crate) last_gc: time::Instant,
    pub(crate) last_gc_check: time::Instant,
}

impl salsa::Database for RootDatabase {
    fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
        &self.runtime
    }
    fn on_propagated_panic(&self) -> ! {
        Canceled::throw()
    }
    fn salsa_event(&self, event: impl Fn() -> salsa::Event<RootDatabase>) {
        match event().kind {
            salsa::EventKind::DidValidateMemoizedValue { .. }
            | salsa::EventKind::WillExecute { .. } => {
                self.check_canceled();
            }
            _ => (),
        }
    }
}

impl Default for RootDatabase {
    fn default() -> RootDatabase {
        RootDatabase::new(None)
    }
}

impl RootDatabase {
    pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
        let mut db = RootDatabase {
            runtime: salsa::Runtime::default(),
            last_gc: time::Instant::now(),
            last_gc_check: time::Instant::now(),
        };
        db.set_crate_graph(Default::default());
        db.set_local_roots(Default::default());
        db.set_library_roots(Default::default());
        let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP);
        db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);
        db.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity);
        db
    }
}

impl salsa::ParallelDatabase for RootDatabase {
    fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
        salsa::Snapshot::new(RootDatabase {
            runtime: self.runtime.snapshot(self),
            last_gc: self.last_gc.clone(),
            last_gc_check: self.last_gc_check.clone(),
        })
    }
}

#[salsa::query_group(LineIndexDatabaseStorage)]
pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
    fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
}

fn line_index(db: &impl ra_db::SourceDatabase, file_id: FileId) -> Arc<LineIndex> {
    let text = db.file_text(file_id);
    Arc::new(LineIndex::new(&*text))
}
<commit_msg>collect more macros, they are heavy<commit_after>use std::{
    sync::Arc,
    time,
};

use ra_db::{
    CheckCanceled, FileId, Canceled, SourceDatabase,
    salsa::{self, Database},
};

use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};

#[salsa::database(
    ra_db::SourceDatabaseStorage,
    LineIndexDatabaseStorage,
    symbol_index::SymbolsDatabaseStorage,
    hir::db::InternDatabaseStorage,
    hir::db::AstDatabaseStorage,
    hir::db::DefDatabaseStorage,
    hir::db::HirDatabaseStorage
)]
#[derive(Debug)]
pub(crate) struct RootDatabase {
    runtime: salsa::Runtime<RootDatabase>,
    pub(crate) last_gc: time::Instant,
    pub(crate) last_gc_check: time::Instant,
}

impl salsa::Database for RootDatabase {
    fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
        &self.runtime
    }
    fn on_propagated_panic(&self) -> ! {
        Canceled::throw()
    }
    fn salsa_event(&self, event: impl Fn() -> salsa::Event<RootDatabase>) {
        match event().kind {
            salsa::EventKind::DidValidateMemoizedValue { .. }
            | salsa::EventKind::WillExecute { .. } => {
                self.check_canceled();
            }
            _ => (),
        }
    }
}

impl Default for RootDatabase {
    fn default() -> RootDatabase {
        RootDatabase::new(None)
    }
}

impl RootDatabase {
    pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
        let mut db = RootDatabase {
            runtime: salsa::Runtime::default(),
            last_gc: time::Instant::now(),
            last_gc_check: time::Instant::now(),
        };
        db.set_crate_graph(Default::default());
        db.set_local_roots(Default::default());
        db.set_library_roots(Default::default());
        let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP);
        db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);
        db.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity);
        db.query_mut(hir::db::MacroExpandQuery).set_lru_capacity(lru_capacity);
        db
    }
}

impl salsa::ParallelDatabase for RootDatabase {
    fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
        salsa::Snapshot::new(RootDatabase {
            runtime: self.runtime.snapshot(self),
            last_gc: self.last_gc.clone(),
            last_gc_check: self.last_gc_check.clone(),
        })
    }
}

#[salsa::query_group(LineIndexDatabaseStorage)]
pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
    fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
}

fn line_index(db: &impl ra_db::SourceDatabase, file_id: FileId) -> Arc<LineIndex> {
    let text = db.file_text(file_id);
    Arc::new(LineIndex::new(&*text))
}
<|endoftext|>


<commit_before>use std::ops::{Neg};
use std::vec::Vec;
use num;
use num::traits::{Num};

use internalutil::{alloc_dirty_vec};

use matrix::Matrix;

impl<T : Copy> Matrix<T> {
  #[inline]
  pub fn get_mut_data<'a>(&'a mut self) -> &'a mut Vec<T> { &mut self.data }

  pub fn get_mref<'lt>(&'lt mut self, row : usize, col : usize) -> &'lt mut T {
    assert!(row < self.no_rows && col < self.cols());
    let no_cols = self.cols();
    &mut self.data[row * no_cols + col]
  }

  pub fn mmap(&mut self, f : &Fn(&T) -> T) {
    for i in 0..self.data.len() {
      self.data[i] = f(&self.data[i]);
    }
  }
}

impl<T : Num + Neg<Output = T> + Copy> Matrix<T> {
  pub fn mneg(&mut self) {
    for i in 0..self.data.len() {
      self.data[i] = - self.data[i];
    }
  }

  pub fn mscale(&mut self, factor : T) {
    for i in 0..self.data.len() {
      self.data[i] = factor * self.data[i];
    }
  }

  pub fn madd(&mut self, m : &Matrix<T>) {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] + m.data[i];
    }
  }

  pub fn msub(&mut self, m : &Matrix<T>) {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] - m.data[i]
    }
  }

  pub fn melem_mul(&mut self, m : &Matrix<T>) {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] * m.data[i];
    }
  }

  pub fn melem_div(&mut self, m : &Matrix<T>) {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] / m.data[i];
    }
  }

  pub fn mmul(&mut self, m : &Matrix<T>) {
    assert!(self.cols() == m.no_rows);

    let elems = self.no_rows * m.cols();
    let mut d = alloc_dirty_vec(elems);
    for row in 0..self.no_rows {
      for col in 0..m.cols() {
        let mut res : T = num::zero();
        for idx in 0..self.cols() {
          res = res + self.get(row, idx) * m.get(idx, col);
        }
        d[row * m.cols() + col] = res;
      }
    }

    self.data = d
  }
}

impl<T : Copy> Matrix<T> {
  pub fn set(&mut self, row : usize, col : usize, val : T) {
    assert!(row < self.no_rows && col < self.cols());
    let no_cols = self.cols();
    self.data[row * no_cols + col] = val
  }

  pub fn mt(&mut self) {
    let mut visited = vec![false; self.data.len()];

    for cycle_idx in 1..(self.data.len() - 1) {
      if visited[cycle_idx] {
        continue;
      }

      let mut idx = cycle_idx;
      let mut prev_value = self.data[idx];
      loop {
        idx = (self.no_rows * idx) % (self.data.len() - 1);
        let current_value = self.data[idx];
        self.data[idx] = prev_value;
        if idx == cycle_idx {
          break;
        }

        prev_value = current_value;
        visited[idx] = true;
      }
    }

    self.no_rows = self.cols();
  }
}

#[test]
fn test_get_set() {
  let mut m = m!(1, 2; 3, 4);
  *m.get_mref(0, 0) = 10;
  assert!(m.get(0, 0) == 10);

  m.set(1, 1, 5);
  assert!(m.get(1, 1) == 5);
}

#[test]
#[should_panic]
fn test_get_mref_out_of_bounds_x() {
  let mut m = m!(1, 2; 3, 4);
  let _ = m.get_mref(2, 0);
}

#[test]
#[should_panic]
fn test_get_mref_out_of_bounds_y() {
  let mut m = m!(1, 2; 3, 4);
  let _ = m.get_mref(0, 2);
}

#[test]
#[should_panic]
fn test_set_out_of_bounds_x() {
  let mut m = m!(1, 2; 3, 4);
  m.set(2, 0, 0);
}

#[test]
#[should_panic]
fn test_set_out_of_bounds_y() {
  let mut m = m!(1, 2; 3, 4);
  m.set(0, 2, 0);
}

#[test]
fn test_map() {
  let mut m = m!(1, 2; 3, 4);
  m.mmap(&|x : &usize| { *x + 2 });
  assert!(m.data == vec![3, 4, 5, 6]);
}

#[test]
fn test_t() {
  let mut m = m!(1, 2; 3, 4);
  m.mt();
  assert!(m.data == vec![1, 3, 2, 4]);

  let mut m = m!(1, 2, 3; 4, 5, 6);
  m.mt();
  assert!(m.rows() == 3);
  assert!(m.cols() == 2);
  assert!(m.data == vec![1, 4, 2, 5, 3, 6]);
}

#[test]
fn test_algebra() {
  let mut a = m!(1, 2; 3, 4);
  a.mneg();
  assert!(a.data == vec![-1, -2, -3, -4]);

  let mut a = m!(1, 2; 3, 4);
  a.mscale(2);
  assert!(a.data == vec![2, 4, 6, 8]);

  let mut a = m!(1, 2; 3, 4);
  let b = m!(3, 4; 5, 6);
  a.madd(&b);
  assert!(a.data == vec![4, 6, 8, 10]);

  let a = m!(1, 2; 3, 4);
  let mut b = m!(3, 4; 5, 6);
  b.msub(&a);
  assert!(b.data == vec![2, 2, 2, 2]);

  let mut a = m!(1, 2; 3, 4);
  let b = m!(3, 4; 5, 6);
  a.melem_mul(&b);
  assert!(a.data == vec![3, 8, 15, 24]);

  let a = m!(1, 2; 3, 4);
  let mut b = m!(3, 4; 5, 6);
  b.melem_div(&a);
  assert!(b.data == vec![3, 2, 1, 1]);
}

#[test]
fn test_mmul() {
  let mut a = m!(1, 2; 3, 4);
  let b = m!(3, 4; 5, 6);
  a.mmul(&b);
  assert!(a.data == vec![13, 16, 29, 36]);
}

#[test]
#[should_panic]
fn test_mmul_incompatible() {
  let mut a = m!(1, 2; 3, 4);
  let b = m!(1, 2; 3, 4; 5, 6);
  a.mmul(&b);
}

<commit_msg>Make mutable matrix interface fluent.<commit_after>use std::ops::{Neg};
use std::vec::Vec;
use num;
use num::traits::{Num};

use internalutil::{alloc_dirty_vec};

use matrix::Matrix;

impl<T : Copy> Matrix<T> {
  #[inline]
  pub fn get_mut_data<'a>(&'a mut self) -> &'a mut Vec<T> { &mut self.data }

  pub fn get_mref<'lt>(&'lt mut self, row : usize, col : usize) -> &'lt mut T {
    assert!(row < self.no_rows && col < self.cols());
    let no_cols = self.cols();
    &mut self.data[row * no_cols + col]
  }

  pub fn mmap<'a>(&'a mut self, f : &Fn(&T) -> T) -> &'a mut Matrix<T> {
    for i in 0..self.data.len() {
      self.data[i] = f(&self.data[i]);
    }
    self
  }
}

impl<T : Num + Neg<Output = T> + Copy> Matrix<T> {
  pub fn mneg<'a>(&'a mut self) -> &'a mut Matrix<T> {
    for i in 0..self.data.len() {
      self.data[i] = - self.data[i];
    }
    self
  }

  pub fn mscale<'a> (&'a mut self, factor : T) -> &'a mut Matrix<T> {
    for i in 0..self.data.len() {
      self.data[i] = factor * self.data[i];
    }
    self
  }

  pub fn madd<'a>(&'a mut self, m : &Matrix<T>) -> &'a mut Matrix<T> {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] + m.data[i];
    }
    self
  }

  pub fn msub<'a>(&'a mut self, m : &Matrix<T>) -> &'a mut Matrix<T> {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] - m.data[i]
    }
    self
  }

  pub fn melem_mul<'a>(&'a mut self, m : &Matrix<T>) -> &'a mut Matrix<T> {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] * m.data[i];
    }
    self
  }

  pub fn melem_div<'a>(&'a mut self, m : &Matrix<T>) -> &'a mut Matrix<T> {
    assert!(self.no_rows == m.no_rows);
    assert!(self.cols() == m.cols());

    for i in 0..self.data.len() {
      self.data[i] = self.data[i] / m.data[i];
    }
    self
  }

  pub fn mmul<'a>(&'a mut self, m : &Matrix<T>) -> &'a mut Matrix<T> {
    assert!(self.cols() == m.no_rows);

    let elems = self.no_rows * m.cols();
    let mut d = alloc_dirty_vec(elems);
    for row in 0..self.no_rows {
      for col in 0..m.cols() {
        let mut res : T = num::zero();
        for idx in 0..self.cols() {
          res = res + self.get(row, idx) * m.get(idx, col);
        }
        d[row * m.cols() + col] = res;
      }
    }

    self.data = d;
    self
  }
}

impl<T : Copy> Matrix<T> {
  pub fn set<'a>(&'a mut self, row : usize, col : usize, val : T) -> &'a mut Matrix<T> {
    assert!(row < self.no_rows && col < self.cols());
    let no_cols = self.cols();
    self.data[row * no_cols + col] = val;
    self
  }

  pub fn mt<'a>(&'a mut self) -> &'a mut Matrix<T> {
    let mut visited = vec![false; self.data.len()];

    for cycle_idx in 1..(self.data.len() - 1) {
      if visited[cycle_idx] {
        continue;
      }

      let mut idx = cycle_idx;
      let mut prev_value = self.data[idx];
      loop {
        idx = (self.no_rows * idx) % (self.data.len() - 1);
        let current_value = self.data[idx];
        self.data[idx] = prev_value;
        if idx == cycle_idx {
          break;
        }

        prev_value = current_value;
        visited[idx] = true;
      }
    }

    self.no_rows = self.cols();
    self
  }
}

#[test]
fn test_get_set() {
  let mut m = m!(1, 2; 3, 4);
  *m.get_mref(0, 0) = 10;
  assert!(m.get(0, 0) == 10);

  m.set(1, 1, 5);
  assert!(m.get(1, 1) == 5);
}

#[test]
#[should_panic]
fn test_get_mref_out_of_bounds_x() {
  let mut m = m!(1, 2; 3, 4);
  let _ = m.get_mref(2, 0);
}

#[test]
#[should_panic]
fn test_get_mref_out_of_bounds_y() {
  let mut m = m!(1, 2; 3, 4);
  let _ = m.get_mref(0, 2);
}

#[test]
#[should_panic]
fn test_set_out_of_bounds_x() {
  let mut m = m!(1, 2; 3, 4);
  m.set(2, 0, 0);
}

#[test]
#[should_panic]
fn test_set_out_of_bounds_y() {
  let mut m = m!(1, 2; 3, 4);
  m.set(0, 2, 0);
}

#[test]
fn test_map() {
  let mut m = m!(1, 2; 3, 4);
  m.mmap(&|x : &usize| { *x + 2 });
  assert!(m.data == vec![3, 4, 5, 6]);
}

#[test]
fn test_t() {
  let mut m = m!(1, 2; 3, 4);
  m.mt();
  assert!(m.data == vec![1, 3, 2, 4]);

  let mut m = m!(1, 2, 3; 4, 5, 6);
  m.mt();
  assert!(m.rows() == 3);
  assert!(m.cols() == 2);
  assert!(m.data == vec![1, 4, 2, 5, 3, 6]);
}

#[test]
fn test_algebra() {
  let mut a = m!(1, 2; 3, 4);
  a.mneg();
  assert!(a.data == vec![-1, -2, -3, -4]);

  let mut a = m!(1, 2; 3, 4);
  a.mscale(2);
  assert!(a.data == vec![2, 4, 6, 8]);

  let mut a = m!(1, 2; 3, 4);
  let b = m!(3, 4; 5, 6);
  a.madd(&b);
  assert!(a.data == vec![4, 6, 8, 10]);

  let a = m!(1, 2; 3, 4);
  let mut b = m!(3, 4; 5, 6);
  b.msub(&a);
  assert!(b.data == vec![2, 2, 2, 2]);

  let mut a = m!(1, 2; 3, 4);
  let b = m!(3, 4; 5, 6);
  a.melem_mul(&b);
  assert!(a.data == vec![3, 8, 15, 24]);

  let a = m!(1, 2; 3, 4);
  let mut b = m!(3, 4; 5, 6);
  b.melem_div(&a);
  assert!(b.data == vec![3, 2, 1, 1]);

  let mut a = m!(1, 2; 3, 4);
  let b = m!(3, 4; 5, 6);
  a.mneg()
   .mscale(2)
   .madd(&b);
  assert!(a.data == vec![1, 0, -1, -2]);
}

#[test]
fn test_mmul() {
  let mut a = m!(1, 2; 3, 4);
  let b = m!(3, 4; 5, 6);
  a.mmul(&b);
  assert!(a.data == vec![13, 16, 29, 36]);
}

#[test]
#[should_panic]
fn test_mmul_incompatible() {
  let mut a = m!(1, 2; 3, 4);
  let b = m!(1, 2; 3, 4; 5, 6);
  a.mmul(&b);
}

<|endoftext|>


<commit_before>use futures::{Future, Stream};
use futures::Async::*;

use std::rc::Rc;
use std::str::Utf8Error;
use std::{fmt, str};

use server::boundary::BoundaryFinder;
use server::{Internal, BodyChunk, StreamError};

use super::{FieldHeaders, FieldData};

use helpers::*;

enum ChunkStack<C> {
    Empty,
    One(C),
    Two(C, C),
}

impl<C> Default for ChunkStack<C> {
    fn default() -> Self {
        ChunkStack::Empty
    }
}

impl<C: BodyChunk> ChunkStack<C> {
    /// Push a chunk onto the stack
    fn push(&mut self, chunk: C) {
        use self::ChunkStack::*;

        *self = match replace_default(self) {
            Empty => One(chunk),
            // This way pushes and pops only have to move one value
            One(one) => Two(one, chunk),
            // print in stream order
            Two(one, two) => panic!("Chunk buffer full: [{}], [{}], [{}]",
                                    show_bytes(chunk.as_slice()), show_bytes(two.as_slice()),
                                    show_bytes(one.as_slice())),
        };
    }

    /// Pop a chunk from the stack
    fn pop(&mut self) -> Option<C> {
        use self::ChunkStack::*;

        match replace_default(self) {
            Empty => None,
            One(one) => { Some(one) },
            Two(one, two) => { *self = One(one); Some(two) }
        }
    }
}

impl<C: BodyChunk> fmt::Debug for ChunkStack<C> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ChunkStack::*;

        match *self {
            Empty => write!(f, "<empty>"),
            One(ref one) => write!(f, "[{}]", show_bytes(one.as_slice())),
            Two(ref one, ref two) => write!(f, "[{}] + [{}]", show_bytes(one.as_slice()),
                                            show_bytes(two.as_slice())),
        }
    }
}

/// The result of reading a `Field` to text.
#[derive(Clone, Debug)]
pub struct TextField {
    /// The headers for the original field, provided as a convenience.
    pub headers: Rc<FieldHeaders>,
    /// The text of the field.
    pub text: String,
}

/// A `Future` which attempts to read a field's data to a string.
///
/// ### Charset
/// For simplicity, the default UTF-8 character set is assumed, as defined in
/// [IETF RFC 7578 Section 5.1.2](https://tools.ietf.org/html/rfc7578#section-5.1.2).
/// If the field body cannot be decoded as UTF-8, an error is returned.
///
/// Decoding text in a different charset (except ASCII which is compatible with UTF-8) is,
/// currently, beyond the scope of this crate. However, as a convention, web browsers will send
/// `multipart/form-data` requests in the same charset as that of the document (page or frame)
/// containing the form, so if you only serve ASCII/UTF-8 pages then you won't have to worry
/// too much about decoding strange charsets.
///
/// ### Warning About Leaks
/// If this value or the contained `FieldData` is leaked (via `mem::forget()` or some
/// other mechanism), then the parent `Multipart` will never be able to yield the next field in the
/// stream. The task waiting on the `Multipart` will also never be notified, which, depending on the
/// event loop/reactor/executor implementation, may cause a deadlock.
#[derive(Default)]
pub struct ReadTextField<S: Stream> {
    stream: Option<S>,
    accum: String,
    chunks: ChunkStack<S::Item>,
    /// The headers for the original field, provided as a convenience.
    pub headers: Rc<FieldHeaders>,
    /// The length limit for the string, in bytes, to avoid potential DoS attacks from
    /// attackers running the server out of memory. If an incoming chunk is expected to push the
    /// string over this limit, an error is returned and the offending chunk is pushed back
    /// to the head of the stream.
    pub limit: usize,
}

// RFC on these numbers, they're pretty much arbitrary
const DEFAULT_LIMIT: usize = 65536; // 65KiB--reasonable enough for one field, right?
const MAX_LIMIT: usize = 16_777_216; // 16MiB--highest sane value for one field, IMO

pub fn read_text<S: Stream>(headers: Rc<FieldHeaders>, data: S) -> ReadTextField<S> {
    ReadTextField {
        headers, stream: Some(data), limit: DEFAULT_LIMIT, accum: String::new(),
        chunks: Default::default()
    }
}

impl<S: Stream> ReadTextField<S> {
    /// Set the length limit, in bytes, for the collected text. If an incoming chunk is expected to
    /// push the string over this limit, an error is returned and the offending chunk is pushed back
    /// to the head of the stream.
    ///
    /// Setting a value higher than a few megabytes is not recommended as it could allow an attacker
    /// to DoS the server by running it out of memory, causing it to panic on allocation or spend
    /// forever swapping pagefiles to disk. Remember that this limit is only for a single field
    /// as well.
    ///
    /// Setting this to `usize::MAX` is equivalent to removing the limit as the string
    /// would overflow its capacity value anyway.
    pub fn limit(self, limit: usize) -> Self {
        Self { limit, .. self}
    }

    /// Soft max limit if the default isn't large enough.
    ///
    /// Going higher than this is allowed, but not recommended.
    pub fn limit_max(self) -> Self {
        self.limit(MAX_LIMIT)
    }

    /// Take the text that has been collected so far, leaving an empty string in its place.
    ///
    /// If the length limit was hit, this allows the field to continue being read.
    pub fn take_string(&mut self) -> String {
        replace_default(&mut self.accum)
    }

    /// The text that has been collected so far.
    pub fn ref_text(&self) -> &str {
        &self.accum
    }

    /// Destructure this future, taking the internal `FieldData` instance back.
    ///
    /// Will be `None` if the field was read to completion, because the internal `FieldData`
    /// instance is dropped afterwards to allow the parent `Multipart` to immediately start
    /// working on the next field.
    pub fn into_data(self) -> Option<S> {
        self.stream
    }
}

impl<S: Stream> ReadTextField<S> where S::Item: BodyChunk {
    fn next_chunk(&mut self) -> PollOpt<S::Item, S::Error> {
        if let Some(chunk) = self.chunks.pop() {
            return ready(Some(chunk));
        }

        if let Some(ref mut stream) = self.stream {
            stream.poll()
        } else {
            ready(None)
        }
    }

    /// Try to poll for another chunk; if successful, return both of them, otherwise push the first
    /// chunk back.
    fn another_chunk(&mut self, first: S::Item) -> PollOpt<(S::Item, S::Item), S::Error> {
        match self.next_chunk() {
            Ok(Ready(Some(second))) => ready(Some((first, second))),
            Ok(Ready(None)) => ready(None),
            Ok(NotReady) => { self.chunks.push(first); not_ready() }
            Err(e) => { self.chunks.push(first); Err(e) },
        }
    }
}

impl<S: Stream> Future for ReadTextField<S> where S::Item: BodyChunk, S::Error: StreamError {
    type Item = TextField;
    type Error = S::Error;

    fn poll(&mut self) -> Poll<Self::Item, S::Error> {
        loop {
            let chunk = match try_ready!(self.next_chunk()) {
                Some(val) => val,
                _ => break,
            };

            // This also catches capacity overflows
            if self.accum.len().saturating_add(chunk.len()) > self.limit {
                self.chunks.push(chunk);
                ret_err!("text field {:?} exceeded limit of {} bytes", self.headers, self.limit);
            }

            // Try to convert the chunk to UTF-8 and append it to the accumulator
            let split_idx = match str::from_utf8(chunk.as_slice()) {
                Ok(s) => { self.accum.push_str(s); continue },
                Err(e) => if e.valid_up_to() > chunk.len() - 4 {
                    // this may just be a valid sequence split across two chunks
                    e.valid_up_to()
                } else {
                    // definitely was an invalid byte sequence
                    return utf8_err(e);
                },
            };

            let (valid, invalid) = chunk.split_at(split_idx);

            self.accum.push_str(str::from_utf8(valid.as_slice())
                .expect("a `StreamChunk` was UTF-8 before, now it's not"));

            // Recombine the cutoff UTF-8 sequence
            let char_width = utf8_char_width(invalid.as_slice()[0]);
            let needed_len =  char_width - invalid.len();

            // Get a second chunk or push the first chunk back
            let (first, second) = match try_ready!(self.another_chunk(invalid)) {
                Some(pair) => pair,
                // this also happens if we have some invalid bytes right at the end of the string
                // should be rare and the end result is the same
                None => ret_err!("unexpected end of stream while decoding a UTF-8 sequence"),
            };

            if second.len() < needed_len {
                ret_err!("got a chunk smaller than the {} byte(s) needed to finish \
                          decoding this UTF-8 sequence: {:?}",
                         needed_len, first.as_slice());
            }

            if self.accum.len().saturating_add(first.len()).saturating_add(second.len()) > self.limit {
                // push chunks in reverse order
                self.chunks.push(second);
                self.chunks.push(first);
                ret_err!("text field {:?} exceeded limit of {} bytes", self.headers, self.limit);
            }

            let mut buf = [0u8; 4];

            // first.len() will be between 1 and 4 as guaranteed by `Utf8Error::valid_up_to()`
            buf[..first.len()].copy_from_slice(first.as_slice());
            buf[first.len()..].copy_from_slice(&second.as_slice()[..needed_len]);

            // if this fails we definitely got an invalid byte sequence
            str::from_utf8(&buf[..char_width]).map(|s| self.accum.push_str(s))
                .or_else(utf8_err)?;

            let (_, rem) = second.split_at(needed_len);

            if !rem.is_empty() {
                self.chunks.push(rem);
            }
        }

        // Optimization: free the `FieldData` so the parent `Multipart` can yield
        // the next field.
        self.stream = None;

        ready(TextField {
            headers: self.headers.clone(),
            text: self.take_string(),
        })
    }
}

impl<S: Stream> fmt::Debug for ReadTextField<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("ReadFieldText")
            .field("accum", &self.accum)
            .field("headers", &self.headers)
            .field("limit", &self.limit)
            .finish()
    }
}

// Below lifted from https://github.com/rust-lang/rust/blob/1.19.0/src/libcore/str/mod.rs#L1461-L1485
// because they're being selfish with their UTF-8 implementation internals
static UTF8_CHAR_WIDTH: [u8; 256] = [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
    0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
    4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
];

#[inline]
fn utf8_char_width(b: u8) -> usize {
    return UTF8_CHAR_WIDTH[b as usize] as usize;
}
<commit_msg>ReadTextField: use checked math instead of saturating math<commit_after>use futures::{Future, Stream};
use futures::Async::*;

use std::rc::Rc;
use std::str::Utf8Error;
use std::{fmt, str};

use server::boundary::BoundaryFinder;
use server::{Internal, BodyChunk, StreamError};

use super::{FieldHeaders, FieldData};

use helpers::*;

enum ChunkStack<C> {
    Empty,
    One(C),
    Two(C, C),
}

impl<C> Default for ChunkStack<C> {
    fn default() -> Self {
        ChunkStack::Empty
    }
}

impl<C: BodyChunk> ChunkStack<C> {
    /// Push a chunk onto the stack
    fn push(&mut self, chunk: C) {
        use self::ChunkStack::*;

        *self = match replace_default(self) {
            Empty => One(chunk),
            // This way pushes and pops only have to move one value
            One(one) => Two(one, chunk),
            // print in stream order
            Two(one, two) => panic!("Chunk buffer full: [{}], [{}], [{}]",
                                    show_bytes(chunk.as_slice()), show_bytes(two.as_slice()),
                                    show_bytes(one.as_slice())),
        };
    }

    /// Pop a chunk from the stack
    fn pop(&mut self) -> Option<C> {
        use self::ChunkStack::*;

        match replace_default(self) {
            Empty => None,
            One(one) => { Some(one) },
            Two(one, two) => { *self = One(one); Some(two) }
        }
    }
}

impl<C: BodyChunk> fmt::Debug for ChunkStack<C> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ChunkStack::*;

        match *self {
            Empty => write!(f, "<empty>"),
            One(ref one) => write!(f, "[{}]", show_bytes(one.as_slice())),
            Two(ref one, ref two) => write!(f, "[{}] + [{}]", show_bytes(one.as_slice()),
                                            show_bytes(two.as_slice())),
        }
    }
}

/// The result of reading a `Field` to text.
#[derive(Clone, Debug)]
pub struct TextField {
    /// The headers for the original field, provided as a convenience.
    pub headers: Rc<FieldHeaders>,
    /// The text of the field.
    pub text: String,
}

/// A `Future` which attempts to read a field's data to a string.
///
/// ### Charset
/// For simplicity, the default UTF-8 character set is assumed, as defined in
/// [IETF RFC 7578 Section 5.1.2](https://tools.ietf.org/html/rfc7578#section-5.1.2).
/// If the field body cannot be decoded as UTF-8, an error is returned.
///
/// Decoding text in a different charset (except ASCII which is compatible with UTF-8) is,
/// currently, beyond the scope of this crate. However, as a convention, web browsers will send
/// `multipart/form-data` requests in the same charset as that of the document (page or frame)
/// containing the form, so if you only serve ASCII/UTF-8 pages then you won't have to worry
/// too much about decoding strange charsets.
///
/// ### Warning About Leaks
/// If this value or the contained `FieldData` is leaked (via `mem::forget()` or some
/// other mechanism), then the parent `Multipart` will never be able to yield the next field in the
/// stream. The task waiting on the `Multipart` will also never be notified, which, depending on the
/// event loop/reactor/executor implementation, may cause a deadlock.
#[derive(Default)]
pub struct ReadTextField<S: Stream> {
    stream: Option<S>,
    accum: String,
    chunks: ChunkStack<S::Item>,
    /// The headers for the original field, provided as a convenience.
    pub headers: Rc<FieldHeaders>,
    /// The length limit for the string, in bytes, to avoid potential DoS attacks from
    /// attackers running the server out of memory. If an incoming chunk is expected to push the
    /// string over this limit, an error is returned and the offending chunk is pushed back
    /// to the head of the stream.
    pub limit: usize,
}

// RFC on these numbers, they're pretty much arbitrary
const DEFAULT_LIMIT: usize = 65536; // 65KiB--reasonable enough for one text field, right?
const MAX_LIMIT: usize = 16_777_216; // 16MiB--highest sane value for one text field, IMO

pub fn read_text<S: Stream>(headers: Rc<FieldHeaders>, data: S) -> ReadTextField<S> {
    ReadTextField {
        headers, stream: Some(data), limit: DEFAULT_LIMIT, accum: String::new(),
        chunks: Default::default()
    }
}

impl<S: Stream> ReadTextField<S> {
    /// Set the length limit, in bytes, for the collected text. If an incoming chunk is expected to
    /// push the string over this limit, an error is returned and the offending chunk is pushed back
    /// to the head of the stream.
    ///
    /// Setting a value higher than a few megabytes is not recommended as it could allow an attacker
    /// to DoS the server by running it out of memory, causing it to panic on allocation or spend
    /// forever swapping pagefiles to disk. Remember that this limit is only for a single field
    /// as well.
    ///
    /// Setting this to `usize::MAX` is equivalent to removing the limit as the string
    /// would overflow its capacity value anyway.
    pub fn limit(self, limit: usize) -> Self {
        Self { limit, .. self}
    }

    /// Soft max limit if the default isn't large enough.
    ///
    /// Going higher than this is allowed, but not recommended.
    pub fn limit_max(self) -> Self {
        self.limit(MAX_LIMIT)
    }

    /// Take the text that has been collected so far, leaving an empty string in its place.
    ///
    /// If the length limit was hit, this allows the field to continue being read.
    pub fn take_string(&mut self) -> String {
        replace_default(&mut self.accum)
    }

    /// The text that has been collected so far.
    pub fn ref_text(&self) -> &str {
        &self.accum
    }

    /// Destructure this future, taking the internal `FieldData` instance back.
    ///
    /// Will be `None` if the field was read to completion, because the internal `FieldData`
    /// instance is dropped afterwards to allow the parent `Multipart` to immediately start
    /// working on the next field.
    pub fn into_data(self) -> Option<S> {
        self.stream
    }
}

impl<S: Stream> ReadTextField<S> where S::Item: BodyChunk {
    fn next_chunk(&mut self) -> PollOpt<S::Item, S::Error> {
        if let Some(chunk) = self.chunks.pop() {
            return ready(Some(chunk));
        }

        if let Some(ref mut stream) = self.stream {
            stream.poll()
        } else {
            ready(None)
        }
    }

    /// Try to poll for another chunk; if successful, return both of them, otherwise push the first
    /// chunk back.
    fn another_chunk(&mut self, first: S::Item) -> PollOpt<(S::Item, S::Item), S::Error> {
        match self.next_chunk() {
            Ok(Ready(Some(second))) => ready(Some((first, second))),
            Ok(Ready(None)) => ready(None),
            Ok(NotReady) => { self.chunks.push(first); not_ready() }
            Err(e) => { self.chunks.push(first); Err(e) },
        }
    }
}

impl<S: Stream> Future for ReadTextField<S> where S::Item: BodyChunk, S::Error: StreamError {
    type Item = TextField;
    type Error = S::Error;

    fn poll(&mut self) -> Poll<Self::Item, S::Error> {
        loop {
            let chunk = match try_ready!(self.next_chunk()) {
                Some(val) => val,
                _ => break,
            };

            // This also catches capacity overflows
            if self.accum.len().checked_add(chunk.len()).map_or(true, |len| len > self.limit) {
                self.chunks.push(chunk);
                ret_err!("text field {:?} exceeded limit of {} bytes", self.headers, self.limit);
            }

            // Try to convert the chunk to UTF-8 and append it to the accumulator
            let split_idx = match str::from_utf8(chunk.as_slice()) {
                Ok(s) => { self.accum.push_str(s); continue },
                Err(e) => if e.valid_up_to() > chunk.len() - 4 {
                    // this may just be a valid sequence split across two chunks
                    e.valid_up_to()
                } else {
                    // definitely was an invalid byte sequence
                    return utf8_err(e);
                },
            };

            let (valid, invalid) = chunk.split_at(split_idx);

            self.accum.push_str(str::from_utf8(valid.as_slice())
                .expect("a `StreamChunk` was UTF-8 before, now it's not"));

            // Recombine the cutoff UTF-8 sequence
            let char_width = utf8_char_width(invalid.as_slice()[0]);
            let needed_len =  char_width - invalid.len();

            // Get a second chunk or push the first chunk back
            let (first, second) = match try_ready!(self.another_chunk(invalid)) {
                Some(pair) => pair,
                // this also happens if we have some invalid bytes right at the end of the string
                // should be rare and the end result is the same
                None => ret_err!("unexpected end of stream while decoding a UTF-8 sequence"),
            };

            if second.len() < needed_len {
                ret_err!("got a chunk smaller than the {} byte(s) needed to finish \
                          decoding this UTF-8 sequence: {:?}",
                         needed_len, first.as_slice());
            }

            let over_limit = self.accum.len().checked_add(first.len())
                .and_then(|len| len.checked_add(second.len()))
                .map_or(true, |len| len > self.limit);

            if over_limit {
                // push chunks in reverse order
                self.chunks.push(second);
                self.chunks.push(first);
                ret_err!("text field {:?} exceeded limit of {} bytes", self.headers, self.limit);
            }

            let mut buf = [0u8; 4];

            // first.len() will be between 1 and 4 as guaranteed by `Utf8Error::valid_up_to()`
            buf[..first.len()].copy_from_slice(first.as_slice());
            buf[first.len()..].copy_from_slice(&second.as_slice()[..needed_len]);

            // if this fails we definitely got an invalid byte sequence
            str::from_utf8(&buf[..char_width]).map(|s| self.accum.push_str(s))
                .or_else(utf8_err)?;

            let (_, rem) = second.split_at(needed_len);

            if !rem.is_empty() {
                self.chunks.push(rem);
            }
        }

        // Optimization: free the `FieldData` so the parent `Multipart` can yield
        // the next field.
        self.stream = None;

        ready(TextField {
            headers: self.headers.clone(),
            text: self.take_string(),
        })
    }
}

impl<S: Stream> fmt::Debug for ReadTextField<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("ReadFieldText")
            .field("accum", &self.accum)
            .field("headers", &self.headers)
            .field("limit", &self.limit)
            .finish()
    }
}

// Below lifted from https://github.com/rust-lang/rust/blob/1.19.0/src/libcore/str/mod.rs#L1461-L1485
// because they're being selfish with their UTF-8 implementation internals
static UTF8_CHAR_WIDTH: [u8; 256] = [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
    0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
    4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
];

#[inline]
fn utf8_char_width(b: u8) -> usize {
    return UTF8_CHAR_WIDTH[b as usize] as usize;
}
<|endoftext|>


<commit_before>use memory::*;
use ram::*;
use ppu::*;
use std::rc::Rc;
use std::cell::RefCell;

pub struct MemoryBus {
    rom: Rc<RefCell<Box<Memory>>>,
    ram: Box<Memory>,
    ppu: Rc<RefCell<Ppu>>,
    // TODO: APU, controllers
}

impl Memory for MemoryBus {
    fn read(&mut self, address: u16) -> u8 {
        if address < 0x2000 {
            self.ram.read(address)
        } else if (address >= 0x2000 && address <= 0x3FFF) || address == 0x4014 {
            self.ppu.borrow_mut().read(address)
        } else if address >= 0x4020 {
            self.rom.borrow_mut().read(address)
        } else {
            0
        }
    }

    fn write(&mut self, address: u16, value: u8) {
        if address < 0x2000 {
            self.ram.write(address, value);
        } else if address >= 0x2000 && address <= 0x3FFF {
            self.ppu.borrow_mut().write(address, value);
        } else if address == 0x4014 {
            let start = (value as u16) << 8;
            let mut data = vec![];

            for i in start..(start + 0xFF) {
                data.push(self.read(i));
            }

            self.ppu.borrow_mut().oam_dma_write(data);
        }
        else if address >= 0x4020 {
            self.rom.borrow_mut().write(address, value);
        }
    }

}

impl MemoryBus {
    pub fn new(rom: Rc<RefCell<Box<Memory>>>, ppu: Rc<RefCell<Ppu>>) -> MemoryBus  {
        MemoryBus {
            rom: rom,
            ram: Box::new(Ram::new()) as Box<Memory>,
            ppu: ppu,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use memory::*;
    use ppu::*;
    use rom::*;
    use std::cell::RefCell;
    use std::rc::Rc;
    // 64 kilobytes of memory, no mapped addresses

    // TODO: Figure out how to cleanly unit test PPU read\writes

    struct MockMemory {
        memory: Vec<u8>
    }

    impl MockMemory {
        fn new() -> MockMemory {
            MockMemory {
                memory: vec![0;0xFFFF + 1],
            }
        }
    }

    impl Memory for MockMemory {
        fn read(&mut self, address: u16) -> u8 {
            self.memory[address as usize]
        }

        fn write(&mut self, address: u16, value: u8) {
            self.memory[address as usize] = value;
        }
    }

    // few helpers
    impl MemoryBus {
        fn assert_value_present_in_ram_only(&mut self, address: u16, value: u8) {
            assert_eq!(value, self.ram.read(address));
            assert!(self.rom.borrow_mut().read(address) != value);
        }

        fn assert_value_present_in_rom_only(&mut self, address: u16, value: u8) {
            assert_eq!(value, self.rom.borrow_mut().read(address));
            assert!(self.ram.read(address) != value);
        }
    }

    fn create_test_memory_bus() -> MemoryBus {
        let rom = Rc::new(RefCell::new(Box::new(MockMemory::new()) as Box<Memory>));
        MemoryBus {
            rom: rom.clone(),
            ram: Box::new(MockMemory::new()),
            ppu: Rc::new(RefCell::new(Ppu::new(TvSystem::NTSC, Mirroring::VerticalMirroring, rom.clone()))),
        }
    }

    #[test]
    fn write_under_0x2000_is_redirected_to_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x1800, 0x4B);
        mem_bus.assert_value_present_in_ram_only(0x1800, 0x4B);
    }

    #[test]
    fn write_to_0x0000_is_redirected_to_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x0000, 0x4B);
        mem_bus.assert_value_present_in_ram_only(0x0000, 0x4B);
    }

    #[test]
    fn write_to_0x1FFF_is_redirected_to_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x1FFF, 0x4B);
        mem_bus.assert_value_present_in_ram_only(0x1FFF, 0x4B);
    }

    #[test]
    fn read_under_0x2000_is_read_from_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.ram.write(0x456, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x456));
    }

    #[test]
    fn read_at_0x0000_is_read_from_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.ram.write(0x0000, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x0000));
    }

    #[test]
    fn read_at_0x1FFF_is_read_from_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.ram.write(0x1FFF, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x1FFF));
    }

    #[test]
    fn write_above_0x4020_is_redirected_to_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x7090, 0x4B);
        mem_bus.assert_value_present_in_rom_only(0x7090, 0x4B);
    }

    #[test]
    fn write_to_0x4020_is_redirected_to_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x4020, 0x4B);
        mem_bus.assert_value_present_in_rom_only(0x4020, 0x4B);
    }

    #[test]
    fn write_to_0xFFFF_is_redirected_to_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0xFFFF, 0x4B);
        mem_bus.assert_value_present_in_rom_only(0xFFFF, 0x4B);
    }

    #[test]
    fn read_above_0x4020_is_read_from_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.rom.borrow_mut().write(0xEFFF, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0xEFFF));
    }

    #[test]
    fn read_at_0x4020_is_read_from_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.rom.borrow_mut().write(0x4020, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x4020));
    }

    #[test]
    fn read_at_0xFFFF_is_read_from_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.rom.borrow_mut().write(0xFFFF, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0xFFFF));
    }
}
<commit_msg>Fixed oam data transfer (off by one; copied 255 bytes instead of 256<commit_after>use memory::*;
use ram::*;
use ppu::*;
use std::rc::Rc;
use std::cell::RefCell;

pub struct MemoryBus {
    rom: Rc<RefCell<Box<Memory>>>,
    ram: Box<Memory>,
    ppu: Rc<RefCell<Ppu>>,
    // TODO: APU, controllers
}

impl Memory for MemoryBus {
    fn read(&mut self, address: u16) -> u8 {
        if address < 0x2000 {
            self.ram.read(address)
        } else if (address >= 0x2000 && address <= 0x3FFF) || address == 0x4014 {
            self.ppu.borrow_mut().read(address)
        } else if address >= 0x4020 {
            self.rom.borrow_mut().read(address)
        } else {
            0
        }
    }

    fn write(&mut self, address: u16, value: u8) {
        if address < 0x2000 {
            self.ram.write(address, value);
        } else if address >= 0x2000 && address <= 0x3FFF {
            self.ppu.borrow_mut().write(address, value);
        } else if address == 0x4014 {
            let start = (value as u16) << 8;
            let mut data = vec![];

            for i in start..(start + 0x100) {
                data.push(self.read(i));
            }

            self.ppu.borrow_mut().oam_dma_write(data);
        }
        else if address >= 0x4020 {
            self.rom.borrow_mut().write(address, value);
        }
    }

}

impl MemoryBus {
    pub fn new(rom: Rc<RefCell<Box<Memory>>>, ppu: Rc<RefCell<Ppu>>) -> MemoryBus  {
        MemoryBus {
            rom: rom,
            ram: Box::new(Ram::new()) as Box<Memory>,
            ppu: ppu,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use memory::*;
    use ppu::*;
    use rom::*;
    use std::cell::RefCell;
    use std::rc::Rc;
    // 64 kilobytes of memory, no mapped addresses

    // TODO: Figure out how to cleanly unit test PPU read\writes

    struct MockMemory {
        memory: Vec<u8>
    }

    impl MockMemory {
        fn new() -> MockMemory {
            MockMemory {
                memory: vec![0;0xFFFF + 1],
            }
        }
    }

    impl Memory for MockMemory {
        fn read(&mut self, address: u16) -> u8 {
            self.memory[address as usize]
        }

        fn write(&mut self, address: u16, value: u8) {
            self.memory[address as usize] = value;
        }
    }

    // few helpers
    impl MemoryBus {
        fn assert_value_present_in_ram_only(&mut self, address: u16, value: u8) {
            assert_eq!(value, self.ram.read(address));
            assert!(self.rom.borrow_mut().read(address) != value);
        }

        fn assert_value_present_in_rom_only(&mut self, address: u16, value: u8) {
            assert_eq!(value, self.rom.borrow_mut().read(address));
            assert!(self.ram.read(address) != value);
        }
    }

    fn create_test_memory_bus() -> MemoryBus {
        let rom = Rc::new(RefCell::new(Box::new(MockMemory::new()) as Box<Memory>));
        MemoryBus {
            rom: rom.clone(),
            ram: Box::new(MockMemory::new()),
            ppu: Rc::new(RefCell::new(Ppu::new(TvSystem::NTSC, Mirroring::VerticalMirroring, rom.clone()))),
        }
    }

    #[test]
    fn write_under_0x2000_is_redirected_to_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x1800, 0x4B);
        mem_bus.assert_value_present_in_ram_only(0x1800, 0x4B);
    }

    #[test]
    fn write_to_0x0000_is_redirected_to_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x0000, 0x4B);
        mem_bus.assert_value_present_in_ram_only(0x0000, 0x4B);
    }

    #[test]
    fn write_to_0x1FFF_is_redirected_to_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x1FFF, 0x4B);
        mem_bus.assert_value_present_in_ram_only(0x1FFF, 0x4B);
    }

    #[test]
    fn read_under_0x2000_is_read_from_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.ram.write(0x456, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x456));
    }

    #[test]
    fn read_at_0x0000_is_read_from_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.ram.write(0x0000, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x0000));
    }

    #[test]
    fn read_at_0x1FFF_is_read_from_ram() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.ram.write(0x1FFF, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x1FFF));
    }

    #[test]
    fn write_above_0x4020_is_redirected_to_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x7090, 0x4B);
        mem_bus.assert_value_present_in_rom_only(0x7090, 0x4B);
    }

    #[test]
    fn write_to_0x4020_is_redirected_to_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0x4020, 0x4B);
        mem_bus.assert_value_present_in_rom_only(0x4020, 0x4B);
    }

    #[test]
    fn write_to_0xFFFF_is_redirected_to_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.write(0xFFFF, 0x4B);
        mem_bus.assert_value_present_in_rom_only(0xFFFF, 0x4B);
    }

    #[test]
    fn read_above_0x4020_is_read_from_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.rom.borrow_mut().write(0xEFFF, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0xEFFF));
    }

    #[test]
    fn read_at_0x4020_is_read_from_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.rom.borrow_mut().write(0x4020, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0x4020));
    }

    #[test]
    fn read_at_0xFFFF_is_read_from_rom() {
        let mut mem_bus = create_test_memory_bus();
        mem_bus.rom.borrow_mut().write(0xFFFF, 0x4B);
        assert_eq!(0x4B, mem_bus.read(0xFFFF));
    }
}
<|endoftext|>


<commit_before>use crate::cfg::CFG;
use crate::gen::fs;
use std::error::Error as StdError;
use std::ffi::OsString;
use std::fmt::{self, Display};
use std::path::Path;

pub(super) type Result<T, E = Error> = std::result::Result<T, E>;

#[derive(Debug)]
pub(super) enum Error {
    NoEnv(OsString),
    Fs(fs::Error),
    ExportedDirNotAbsolute(&'static Path),
    ExportedEmptyPrefix,
    ExportedDirsWithoutLinks,
    ExportedPrefixesWithoutLinks,
    ExportedLinksWithoutLinks,
    UnusedExportedPrefix(&'static str),
    UnusedExportedLinks(&'static str),
}

macro_rules! expr {
    ($expr:expr) => {{
        let _ = $expr; // ensure it doesn't fall out of sync with CFG definition
        stringify!($expr)
    }};
}

const LINKS_DOCUMENTATION: &str =
    "https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key";

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::NoEnv(var) => {
                write!(f, "missing {} environment variable", var.to_string_lossy())
            }
            Error::Fs(err) => err.fmt(f),
            Error::ExportedDirNotAbsolute(path) => write!(
                f,
                "element of {} must be absolute path, but was: {:?}",
                expr!(CFG.exported_header_dirs),
                path,
            ),
            Error::ExportedEmptyPrefix => write!(
                f,
                "element of {} must not be empty string",
                expr!(CFG.exported_header_prefixes),
            ),
            Error::ExportedDirsWithoutLinks => write!(
                f,
                "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
                expr!(CFG.exported_header_dirs),
                LINKS_DOCUMENTATION,
            ),
            Error::ExportedPrefixesWithoutLinks => write!(
                f,
                "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
                expr!(CFG.exported_header_prefixes),
                LINKS_DOCUMENTATION,
            ),
            Error::ExportedLinksWithoutLinks => write!(
                f,
                "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
                expr!(CFG.exported_header_links),
                LINKS_DOCUMENTATION,
            ),
            Error::UnusedExportedPrefix(unused) => write!(
                f,
                "unused element in {}: {} does not match the include prefix of any direct dependency",
                expr!(CFG.exported_header_prefixes),
                unused,
            ),
            Error::UnusedExportedLinks(unused) => write!(
                f,
                "unused element in {}: {} does not match the `links` attribute any direct dependency",
                expr!(CFG.exported_header_links),
                unused,
            ),
        }
    }
}

impl StdError for Error {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match self {
            Error::Fs(err) => err.source(),
            _ => None,
        }
    }
}

impl From<fs::Error> for Error {
    fn from(err: fs::Error) -> Self {
        Error::Fs(err)
    }
}
<commit_msg>Quote the unrecognized element in "unused element" errors<commit_after>use crate::cfg::CFG;
use crate::gen::fs;
use std::error::Error as StdError;
use std::ffi::OsString;
use std::fmt::{self, Display};
use std::path::Path;

pub(super) type Result<T, E = Error> = std::result::Result<T, E>;

#[derive(Debug)]
pub(super) enum Error {
    NoEnv(OsString),
    Fs(fs::Error),
    ExportedDirNotAbsolute(&'static Path),
    ExportedEmptyPrefix,
    ExportedDirsWithoutLinks,
    ExportedPrefixesWithoutLinks,
    ExportedLinksWithoutLinks,
    UnusedExportedPrefix(&'static str),
    UnusedExportedLinks(&'static str),
}

macro_rules! expr {
    ($expr:expr) => {{
        let _ = $expr; // ensure it doesn't fall out of sync with CFG definition
        stringify!($expr)
    }};
}

const LINKS_DOCUMENTATION: &str =
    "https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key";

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::NoEnv(var) => {
                write!(f, "missing {} environment variable", var.to_string_lossy())
            }
            Error::Fs(err) => err.fmt(f),
            Error::ExportedDirNotAbsolute(path) => write!(
                f,
                "element of {} must be absolute path, but was: {:?}",
                expr!(CFG.exported_header_dirs),
                path,
            ),
            Error::ExportedEmptyPrefix => write!(
                f,
                "element of {} must not be empty string",
                expr!(CFG.exported_header_prefixes),
            ),
            Error::ExportedDirsWithoutLinks => write!(
                f,
                "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
                expr!(CFG.exported_header_dirs),
                LINKS_DOCUMENTATION,
            ),
            Error::ExportedPrefixesWithoutLinks => write!(
                f,
                "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
                expr!(CFG.exported_header_prefixes),
                LINKS_DOCUMENTATION,
            ),
            Error::ExportedLinksWithoutLinks => write!(
                f,
                "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
                expr!(CFG.exported_header_links),
                LINKS_DOCUMENTATION,
            ),
            Error::UnusedExportedPrefix(unused) => write!(
                f,
                "unused element in {}: {:?} does not match the include prefix of any direct dependency",
                expr!(CFG.exported_header_prefixes),
                unused,
            ),
            Error::UnusedExportedLinks(unused) => write!(
                f,
                "unused element in {}: {:?} does not match the `links` attribute any direct dependency",
                expr!(CFG.exported_header_links),
                unused,
            ),
        }
    }
}

impl StdError for Error {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match self {
            Error::Fs(err) => err.source(),
            _ => None,
        }
    }
}

impl From<fs::Error> for Error {
    fn from(err: fs::Error) -> Self {
        Error::Fs(err)
    }
}
<|endoftext|>


<commit_before>use super::Span;

/// An enum representing a diagnostic level.
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub enum Level {
    /// An error.
    Error,
    /// A warning.
    Warning,
    /// A note.
    Note,
    /// A help message.
    Help,
}

/// Trait implemented by types that can be converted into a set of `Span`s.
pub trait MultiSpan {
    /// Converts `self` into a `Vec<Span>`.
    fn into_spans(self) -> Vec<Span>;
}

impl MultiSpan for Span {
    fn into_spans(self) -> Vec<Span> {
        vec![self]
    }
}

impl MultiSpan for Vec<Span> {
    fn into_spans(self) -> Vec<Span> {
        self
    }
}

impl<'a> MultiSpan for &'a [Span] {
    fn into_spans(self) -> Vec<Span> {
        self.to_vec()
    }
}

/// A structure representing a diagnostic message and associated children
/// messages.
#[derive(Clone, Debug)]
pub struct Diagnostic {
    level: Level,
    message: String,
    spans: Vec<Span>,
    children: Vec<Diagnostic>,
}

macro_rules! diagnostic_child_methods {
    ($spanned:ident, $regular:ident, $level:expr) => {
        #[doc = concat!("Adds a new child diagnostics message to `self` with the [`",
                        stringify!($level), "`] level, and the given `spans` and `message`.")]
        pub fn $spanned<S, T>(mut self, spans: S, message: T) -> Diagnostic
        where
            S: MultiSpan,
            T: Into<String>,
        {
            self.children.push(Diagnostic::spanned(spans, $level, message));
            self
        }

        #[doc = concat!("Adds a new child diagnostic message to `self` with the [`",
                        stringify!($level), "`] level, and the given `message`.")]
        pub fn $regular<T: Into<String>>(mut self, message: T) -> Diagnostic {
            self.children.push(Diagnostic::new($level, message));
            self
        }
    };
}

/// Iterator over the children diagnostics of a `Diagnostic`.
#[derive(Debug, Clone)]
pub struct Children<'a>(std::slice::Iter<'a, Diagnostic>);

impl<'a> Iterator for Children<'a> {
    type Item = &'a Diagnostic;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl Diagnostic {
    /// Creates a new diagnostic with the given `level` and `message`.
    pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
        Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
    }

    /// Creates a new diagnostic with the given `level` and `message` pointing to
    /// the given set of `spans`.
    pub fn spanned<S, T>(spans: S, level: Level, message: T) -> Diagnostic
    where
        S: MultiSpan,
        T: Into<String>,
    {
        Diagnostic { level, message: message.into(), spans: spans.into_spans(), children: vec![] }
    }

    diagnostic_child_methods!(span_error, error, Level::Error);
    diagnostic_child_methods!(span_warning, warning, Level::Warning);
    diagnostic_child_methods!(span_note, note, Level::Note);
    diagnostic_child_methods!(span_help, help, Level::Help);

    /// Returns the diagnostic `level` for `self`.
    pub fn level(&self) -> Level {
        self.level
    }

    /// Sets the level in `self` to `level`.
    pub fn set_level(&mut self, level: Level) {
        self.level = level;
    }

    /// Returns the message in `self`.
    pub fn message(&self) -> &str {
        &self.message
    }

    /// Sets the message in `self` to `message`.
    pub fn set_message<T: Into<String>>(&mut self, message: T) {
        self.message = message.into();
    }

    /// Returns the `Span`s in `self`.
    pub fn spans(&self) -> &[Span] {
        &self.spans
    }

    /// Sets the `Span`s in `self` to `spans`.
    pub fn set_spans<S: MultiSpan>(&mut self, spans: S) {
        self.spans = spans.into_spans();
    }

    /// Returns an iterator over the children diagnostics of `self`.
    pub fn children(&self) -> Children<'_> {
        Children(self.children.iter())
    }

    /// Emit the diagnostic.
    pub fn emit(self) {
        fn to_internal(spans: Vec<Span>) -> super::bridge::client::MultiSpan {
            let mut multi_span = super::bridge::client::MultiSpan::new();
            for span in spans {
                multi_span.push(span.0);
            }
            multi_span
        }

        let mut diag = super::bridge::client::Diagnostic::new(
            self.level,
            &self.message[..],
            to_internal(self.spans),
        );
        for c in self.children {
            diag.sub(c.level, &c.message[..], to_internal(c.spans));
        }
        diag.emit();
    }
}
<commit_msg>Add doc comment<commit_after>//! lib-proc-macro diagnostic
//!
//! Copy from <https://github.com/rust-lang/rust/blob/e45d9973b2665897a768312e971b82cc62633103/src/libproc_macro/diagnostic.rs>
//! augmented with removing unstable features

use super::Span;

/// An enum representing a diagnostic level.
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub enum Level {
    /// An error.
    Error,
    /// A warning.
    Warning,
    /// A note.
    Note,
    /// A help message.
    Help,
}

/// Trait implemented by types that can be converted into a set of `Span`s.
pub trait MultiSpan {
    /// Converts `self` into a `Vec<Span>`.
    fn into_spans(self) -> Vec<Span>;
}

impl MultiSpan for Span {
    fn into_spans(self) -> Vec<Span> {
        vec![self]
    }
}

impl MultiSpan for Vec<Span> {
    fn into_spans(self) -> Vec<Span> {
        self
    }
}

impl<'a> MultiSpan for &'a [Span] {
    fn into_spans(self) -> Vec<Span> {
        self.to_vec()
    }
}

/// A structure representing a diagnostic message and associated children
/// messages.
#[derive(Clone, Debug)]
pub struct Diagnostic {
    level: Level,
    message: String,
    spans: Vec<Span>,
    children: Vec<Diagnostic>,
}

macro_rules! diagnostic_child_methods {
    ($spanned:ident, $regular:ident, $level:expr) => {
        #[doc = concat!("Adds a new child diagnostics message to `self` with the [`",
                        stringify!($level), "`] level, and the given `spans` and `message`.")]
        pub fn $spanned<S, T>(mut self, spans: S, message: T) -> Diagnostic
        where
            S: MultiSpan,
            T: Into<String>,
        {
            self.children.push(Diagnostic::spanned(spans, $level, message));
            self
        }

        #[doc = concat!("Adds a new child diagnostic message to `self` with the [`",
                        stringify!($level), "`] level, and the given `message`.")]
        pub fn $regular<T: Into<String>>(mut self, message: T) -> Diagnostic {
            self.children.push(Diagnostic::new($level, message));
            self
        }
    };
}

/// Iterator over the children diagnostics of a `Diagnostic`.
#[derive(Debug, Clone)]
pub struct Children<'a>(std::slice::Iter<'a, Diagnostic>);

impl<'a> Iterator for Children<'a> {
    type Item = &'a Diagnostic;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl Diagnostic {
    /// Creates a new diagnostic with the given `level` and `message`.
    pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
        Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
    }

    /// Creates a new diagnostic with the given `level` and `message` pointing to
    /// the given set of `spans`.
    pub fn spanned<S, T>(spans: S, level: Level, message: T) -> Diagnostic
    where
        S: MultiSpan,
        T: Into<String>,
    {
        Diagnostic { level, message: message.into(), spans: spans.into_spans(), children: vec![] }
    }

    diagnostic_child_methods!(span_error, error, Level::Error);
    diagnostic_child_methods!(span_warning, warning, Level::Warning);
    diagnostic_child_methods!(span_note, note, Level::Note);
    diagnostic_child_methods!(span_help, help, Level::Help);

    /// Returns the diagnostic `level` for `self`.
    pub fn level(&self) -> Level {
        self.level
    }

    /// Sets the level in `self` to `level`.
    pub fn set_level(&mut self, level: Level) {
        self.level = level;
    }

    /// Returns the message in `self`.
    pub fn message(&self) -> &str {
        &self.message
    }

    /// Sets the message in `self` to `message`.
    pub fn set_message<T: Into<String>>(&mut self, message: T) {
        self.message = message.into();
    }

    /// Returns the `Span`s in `self`.
    pub fn spans(&self) -> &[Span] {
        &self.spans
    }

    /// Sets the `Span`s in `self` to `spans`.
    pub fn set_spans<S: MultiSpan>(&mut self, spans: S) {
        self.spans = spans.into_spans();
    }

    /// Returns an iterator over the children diagnostics of `self`.
    pub fn children(&self) -> Children<'_> {
        Children(self.children.iter())
    }

    /// Emit the diagnostic.
    pub fn emit(self) {
        fn to_internal(spans: Vec<Span>) -> super::bridge::client::MultiSpan {
            let mut multi_span = super::bridge::client::MultiSpan::new();
            for span in spans {
                multi_span.push(span.0);
            }
            multi_span
        }

        let mut diag = super::bridge::client::Diagnostic::new(
            self.level,
            &self.message[..],
            to_internal(self.spans),
        );
        for c in self.children {
            diag.sub(c.level, &c.message[..], to_internal(c.spans));
        }
        diag.emit();
    }
}
<|endoftext|>


<commit_before>use std::ops::{Mul};

extern crate nalgebra;
use self::nalgebra::{DMat};

extern crate rand;
use self::rand::{Rand};

extern crate num;
use self::num::{Float, FromPrimitive};

pub struct OrthogonalNMF<FloatT> {
    // TODO add docstrings
    pub hidden: DMat<FloatT>,
    pub weights: DMat<FloatT>,
    pub iteration: usize,
}

impl<FloatT: Rand + Float + FromPrimitive + Mul> OrthogonalNMF<FloatT> {
    /// one observed per column.
    /// one time per row.
    pub fn init_randomly(nhidden: usize, nobserved: usize, nsamples: usize) -> OrthogonalNMF<FloatT> {
        OrthogonalNMF {
            hidden: DMat::new_random(nhidden, nobserved),
            weights: DMat::new_random(nsamples, nhidden),
            iteration: 0,
        }
    }

    // TODO how many iterations ?
    /// it gets better and better with each iteration
    pub fn iterate(&mut self, data: &DMat<FloatT>) {
        let nsamples = self.weights.nrows();
        let nobserved = self.hidden.ncols();
        assert_eq!(nsamples, data.nrows());
        assert_eq!(nobserved, data.ncols());
        let alpha: FloatT =
            FloatT::from_f32(0.1).unwrap() *
            FloatT::from_f32(1.01).unwrap().powi(self.iteration as i32);
    }

    // TODO maybe a function to reuse an existing OrthogonalNMF
    // in order to avoid unnecessary memory allocations

    // TODO initialize with values from last time step t-1 instead of choosing randomly
    // init_manually

    // TODO compare this to the seoung solution
    // #[inline]
    // fn iterate(&mut self, data: &DMat<f64>, alpha: f64) {
    //     let latents_transposed = self.latents.transpose();
    //     let weights_transposed = self.weights.transpose();
    //
    //     // TODO names
    //     let weights_foo = data.mul(latents_transposed);
    //     let weights_bar = self.weights.mul(self.latents).mul(latents_transposed);
    //
    //     let latents_foo = weights_transposed.mul(data);
    //     let size = ?
    //     let gamma = DMat::from_elem(size, size, alpha);
    //     let zeroes = DVec::new_zeros(size);
    //     gamma.set_diag(zeroes);
    //     let latents_bar = weights_transposed
    //         .mul(self.weights)
    //         .mul(self.latents)
    //         // we add the previous latents
    //         // multiplied by alpha except for the diag which is set to zero
    //         .add(gamma.mul(self.latents));
    //
    //     // iterate weights
    //     // TODO correct order ?
    //     for col in 0..self.weights.ncols() {
    //         for row in 0..self.weights.nrows() {
    //             let index = (row, col);
    //             let foo_value = unsafe { weights_foo.unsafe_at(index) }
    //             // these get larger and larger
    //             let bar_value = unsafe { weights_bar.unsafe_at(index) }
    //             let old_value = unsafe { self.weights.unsafe_at(index) }
    //             let new_value = old_value * foo_value / bar_value;
    //             unsafe { self.weights.unsafe_set(index, new_value) }
    //         }
    //     }
    //
    //     // iterate latents
    //     // TODO correct order ?
    //     for col in 0..self.latents.ncols() {
    //         for row in 0..self.latents.nrows() {
    //             let index = (row, col);
    //             let foo_value = latents_foo[index];
    //             let bar_value = latents_bar[index]
    //             let old_value = self.latents[index];
    //             let new_value = old_value * foo_value / bar_value;
    //             self.latents[index] = new_value;
    //         }
    //     }
    // }
}
<commit_msg>ortho nmf: add function to init manually<commit_after>use std::ops::{Mul};

extern crate nalgebra;
use self::nalgebra::{DMat};

extern crate rand;
use self::rand::{Rand};

extern crate num;
use self::num::{Float, FromPrimitive};

pub struct OrthogonalNMF<FloatT> {
    // TODO add docstrings
    pub hidden: DMat<FloatT>,
    pub weights: DMat<FloatT>,
    pub iteration: usize,
}

impl<FloatT: Rand + Float + FromPrimitive + Mul> OrthogonalNMF<FloatT> {
    pub fn init_randomly(nhidden: usize, nobserved: usize, nsamples: usize) -> OrthogonalNMF<FloatT> {
        OrthogonalNMF {
            hidden: DMat::new_random(nhidden, nobserved),
            weights: DMat::new_random(nsamples, nhidden),
            iteration: 0,
        }
    }

    pub fn init(hidden: DMat<FloatT>, weights: DMat<FloatT>) -> OrthogonalNMF<FloatT> {
        OrthogonalNMF {
            hidden: hidden,
            weights: weights,
            iteration: 0,
        }
    }

    // TODO how many iterations ?
    /// it gets better and better with each iteration.
    /// one observed per column.
    /// one sample per row.
    pub fn iterate(&mut self, data: &DMat<FloatT>) {
        let nsamples = self.weights.nrows();
        let nobserved = self.hidden.ncols();
        assert_eq!(nsamples, data.nrows());
        assert_eq!(nobserved, data.ncols());
        let alpha: FloatT =
            FloatT::from_f32(0.1).unwrap() *
            FloatT::from_f32(1.01).unwrap().powi(self.iteration as i32);
    }

    // TODO maybe a function to reuse an existing OrthogonalNMF
    // in order to avoid unnecessary memory allocations

    // TODO initialize with values from last time step t-1 instead of choosing randomly
    // init_manually

    // TODO compare this to the seoung solution
    // #[inline]
    // fn iterate(&mut self, data: &DMat<f64>, alpha: f64) {
    //     let latents_transposed = self.latents.transpose();
    //     let weights_transposed = self.weights.transpose();
    //
    //     // TODO names
    //     let weights_foo = data.mul(latents_transposed);
    //     let weights_bar = self.weights.mul(self.latents).mul(latents_transposed);
    //
    //     let latents_foo = weights_transposed.mul(data);
    //     let size = ?
    //     let gamma = DMat::from_elem(size, size, alpha);
    //     let zeroes = DVec::new_zeros(size);
    //     gamma.set_diag(zeroes);
    //     let latents_bar = weights_transposed
    //         .mul(self.weights)
    //         .mul(self.latents)
    //         // we add the previous latents
    //         // multiplied by alpha except for the diag which is set to zero
    //         .add(gamma.mul(self.latents));
    //
    //     // iterate weights
    //     // TODO correct order ?
    //     for col in 0..self.weights.ncols() {
    //         for row in 0..self.weights.nrows() {
    //             let index = (row, col);
    //             let foo_value = unsafe { weights_foo.unsafe_at(index) }
    //             // these get larger and larger
    //             let bar_value = unsafe { weights_bar.unsafe_at(index) }
    //             let old_value = unsafe { self.weights.unsafe_at(index) }
    //             let new_value = old_value * foo_value / bar_value;
    //             unsafe { self.weights.unsafe_set(index, new_value) }
    //         }
    //     }
    //
    //     // iterate latents
    //     // TODO correct order ?
    //     for col in 0..self.latents.ncols() {
    //         for row in 0..self.latents.nrows() {
    //             let index = (row, col);
    //             let foo_value = latents_foo[index];
    //             let bar_value = latents_bar[index]
    //             let old_value = self.latents[index];
    //             let new_value = old_value * foo_value / bar_value;
    //             self.latents[index] = new_value;
    //         }
    //     }
    // }
}
<|endoftext|>


<commit_before>//!  Decoding of BMP Images
//!
//!  A decoder for BMP (Windows Bitmap) images
//!
//!  # Related Links
//!  * https://msdn.microsoft.com/en-us/library/windows/desktop/dd183375%28v=vs.85%29.aspx
//!  * https://en.wikipedia.org/wiki/BMP_file_format
//!

pub use self::encoder::BMPEncoder;
pub use self::decoder::BMPDecoder;

mod encoder;
mod decoder;
<commit_msg>update doc comments<commit_after>//!  Decoding and Encoding of BMP Images
//!
//!  A decoder and encoder for BMP (Windows Bitmap) images
//!
//!  # Related Links
//!  * https://msdn.microsoft.com/en-us/library/windows/desktop/dd183375%28v=vs.85%29.aspx
//!  * https://en.wikipedia.org/wiki/BMP_file_format
//!

pub use self::encoder::BMPEncoder;
pub use self::decoder::BMPDecoder;

mod encoder;
mod decoder;
<|endoftext|>