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

#[deny(missing_docs)]

extern crate gfx;
extern crate gfx_device_gl;
extern crate glfw;

use gfx::tex::Size;

/// A wrapper around the window that implements `Output`.
pub struct Wrap<R: gfx::Resources> {
    /// Glutin window in the open.
    pub window: glfw::Window,
    frame: gfx::FrameBufferHandle<R>,
    mask: gfx::Mask,
    gamma: gfx::Gamma,
}

impl<R: gfx::Resources> gfx::Output<R> for Wrap<R> {
    fn get_handle(&self) -> Option<&gfx::FrameBufferHandle<R>> {
        Some(&self.frame)
    }

    fn get_size(&self) -> (Size, Size) {
        let (w, h) = self.window.get_framebuffer_size();
        (w as Size, h as Size)
    }

    fn get_mask(&self) -> gfx::Mask {
        self.mask
    }

    fn get_gamma(&self) -> gfx::Gamma {
        self.gamma
    }
}

/// Result of successful context initialization.
pub type Success = (
    Wrap<gfx_device_gl::Resources>,
    gfx_device_gl::Device,
    gfx_device_gl::Factory,
);

/// Initialize with a window.
pub fn init(mut window: glfw::Window) -> Success {
    use gflw::Context;
    window.make_current();
    let (device, factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let wrap = Wrap {
        window: window,
        frame: factory.get_main_frame_buffer(),
        mask: gfx::COLOR | gfx::DEPTH | gfx::STENCIL, //TODO
        gamma: gfx::Gamma::Original, //TODO
    };
    (wrap, device, factory)
}
<commit_msg>Implemented Window<commit_after>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[deny(missing_docs)]

extern crate gfx;
extern crate gfx_device_gl;
extern crate glfw;

use gfx::tex::Size;
use glfw::Context;

/// A wrapper around the window that implements `Output`.
pub struct Wrap<R: gfx::Resources> {
    /// Glutin window in the open.
    pub window: glfw::Window,
    frame: gfx::FrameBufferHandle<R>,
    mask: gfx::Mask,
    gamma: gfx::Gamma,
}

impl<R: gfx::Resources> gfx::Output<R> for Wrap<R> {
    fn get_handle(&self) -> Option<&gfx::FrameBufferHandle<R>> {
        Some(&self.frame)
    }

    fn get_size(&self) -> (Size, Size) {
        let (w, h) = self.window.get_framebuffer_size();
        (w as Size, h as Size)
    }

    fn get_mask(&self) -> gfx::Mask {
        self.mask
    }

    fn get_gamma(&self) -> gfx::Gamma {
        self.gamma
    }
}

impl<R: gfx::Resources> gfx::Window<R> for Wrap<R> {
    fn swap_buffers(&mut self) {
        self.window.swap_buffers();
    }
}

/// Result of successful context initialization.
pub type Success = (
    Wrap<gfx_device_gl::Resources>,
    gfx_device_gl::Device,
    gfx_device_gl::Factory,
);

/// Initialize with a window.
pub fn init(mut window: glfw::Window) -> Success {
    window.make_current();
    let (device, factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let wrap = Wrap {
        window: window,
        frame: factory.get_main_frame_buffer(),
        mask: gfx::COLOR | gfx::DEPTH | gfx::STENCIL, //TODO
        gamma: gfx::Gamma::Original, //TODO
    };
    (wrap, device, factory)
}
<|endoftext|>


<commit_before>use core::prelude::*;

use aspace::mapflag;
use con;
use con::write;
use cpu;
use process;
use process::Handle;
use process::Process;
use start32::kernel_base;
use util::abort;

static log_syscall : bool = false;
static log_transfer_message : bool = false;
static log_portio : bool = false;
static log_hmod : bool = false;

static log_recv : bool = false;

pub mod nr {
    #![allow(dead_code)]
    pub static RECV : uint = 0;
    pub static MAP : uint = 1;
    pub static PFAULT : uint = 2;
    pub static UNMAP : uint = 3;
    pub static HMOD : uint = 4;
    pub static NEWPROC : uint = 5;
    pub static WRITE : uint = 6;
    pub static PORTIO : uint = 7;
    pub static GRANT : uint = 8;
    pub static PULSE : uint = 9;

    pub static USER : uint = 16;

    pub static MSG_MASK : uint = 0xff;
    pub static MSG_KIND_MASK : uint = 0x300;
    pub static MSG_KIND_SEND : uint = 0x000;
    pub static MSG_KIND_CALL : uint = 0x100;
}

// Note: tail-called from the syscall code, "return" by switching to a process.
#[no_mangle]
pub fn syscall(
    arg0: uint,
    arg1: uint,
    arg2: uint,
    arg3: uint,
    arg4: uint,
    arg5: uint,
    nr : uint, // saved_rax
) -> ! {
    use syscall::nr::*;

    let p = unsafe { cpu().get_process() };
    // FIXME cpu.leave_proc?
    p.unset(process::Running);
    p.set(process::FastRet);

    if log_syscall {
        write("syscall! nr=");
        con::writeUInt(nr);
        write(" from process ");
        con::writeMutPtr(p);
        con::newline();
    }

    match nr {
    RECV => ipc_recv(p, arg0),
    MAP => syscall_map(p, arg0, arg1, arg2, arg3, arg4),
    PFAULT => syscall_pfault(p, arg1, arg2), // arg0 is always 0
    HMOD => syscall_hmod(p, arg0, arg1, arg2),
    PORTIO => syscall_portio(p, arg0, arg1, arg2),
    WRITE => {
        con::putc(arg0 as u8 as char);
        cpu().syscall_return(p, 0);
    },
    _ if nr >= USER => {
        match nr & MSG_KIND_MASK {
            MSG_KIND_CALL => ipc_call(p, nr & MSG_MASK, arg0, arg1, arg2, arg3, arg4, arg5),
            MSG_KIND_SEND => ipc_send(p, nr & MSG_MASK, arg0, arg1, arg2, arg3, arg4, arg5),
            _ => abort("Unknown IPC kind")
        }
    },
    _ => abort("Unhandled syscall"),
    }

    if p.is_runnable() {
        abort("process not blocked at return");
    }

    unsafe { cpu().run(); }
}

fn ipc_call(p : &mut Process, msg : uint, to : uint, arg1: uint, arg2: uint,
    arg3: uint, arg4: uint, arg5: uint) {
    write("ipc_call to ");
    con::writeUInt(to);
    con::newline();

    let handle = p.find_handle(to);
    match handle {
    Some(h) => {
        write("==> process ");
        con::writeMutPtr(h.process());
        con::newline();
        p.set(process::InSend);
        p.set(process::InRecv);
        p.regs.rdi = to;
        send_or_block(h, msg, arg1, arg2, arg3, arg4, arg5);
    },
    None => abort("ipc_call: no recipient")
    }
    write("ipc_call: blocked\n");
}

fn transfer_set_handle(target: &mut Process, source: &mut Process) {
    let mut rcpt = target.regs.rdi;
    let from = source.regs.rdi;

    let h = source.find_handle(from).unwrap();
    if rcpt == 0 {
        rcpt = h.other().unwrap().id();
    } else if !target.find_handle(rcpt).is_some() {
        match h.other() {
            // Already associated, "junk" the fresh handle and just update the
            // recipient-side handle.
            Some(g) => rcpt = g.id(),
            // Associate handles now.
            None => {
                let g = target.new_handle(rcpt, source);
                g.associate(h);
            },
        }
    } else {
        // TODO Assert that rcpt <-> from. (But the caller is responsible for
        // checking that first.)
    }
    target.regs.rdi = rcpt;
}

fn transfer_message(target: &mut Process, source: &mut Process) -> ! {
    transfer_set_handle(target, source);

    if log_transfer_message {
        write("transfer_message ");
        con::writeMutPtr(target);
        write(" <- ");
        con::writeMutPtr(source);
        con::newline();
    }

    target.regs.rax = source.regs.rax;
    target.regs.rdi = source.regs.rdi;
    target.regs.rsi = source.regs.rsi;
    target.regs.rdx = source.regs.rdx;
    target.regs.r8 = source.regs.r8;
    target.regs.r9 = source.regs.r9;
    target.regs.r10 = source.regs.r10;

    target.unset(process::InRecv);
    source.unset(process::InSend);

    let c = cpu();
    c.queue(target);
    if source.ipc_state() == 0 {
        c.queue(source);
    }
    unsafe { c.run(); }
}

fn send_or_block(h : &mut Handle, msg: uint, arg1: uint, arg2: uint,
        arg3: uint, arg4: uint, arg5: uint) {
    match h.other() {
        Some(g) => {
            let p = h.process();
            let sender = g.process();

            // Save regs - either we'll copy these in transfer_message or we'll
            // need to store them until later on when the transfer can finish.
            sender.regs.rax = msg;
            sender.regs.rdi = h.id();
            sender.regs.rsi = arg1;
            sender.regs.rdx = arg2;
            sender.regs.r10 = arg3;
            sender.regs.r8 = arg4;
            sender.regs.r9 = arg5;

            // p is the recipient, the sender is in g.process().
            if p.ipc_state() == process::InRecv.mask() {
                let rcpt = h.process().regs.rdi;
                // Check the receiving process' receipt handle
                //   0 ==> transfer
                //   !0, connected to our handle ==> transfer
                //   !0, fresh ==> transfer
                //   !0 otherwise ==> block
                if rcpt == 0
                || rcpt == g.id()
                || !p.find_handle(rcpt).is_some() {
                    transfer_message(p, sender);
                }
            }

            p.add_waiter(sender)
        },
        None => abort("sending to unconnected handle"),
    }
}

fn ipc_send(p : &mut Process, msg : uint, to : uint, arg1: uint, arg2: uint,
        arg3: uint, arg4: uint, arg5: uint) {
    let handle = p.find_handle(to);
    match handle {
    Some(h) => {
        p.set(process::InSend);
        send_or_block(h, msg, arg1, arg2, arg3, arg4, arg5);
    },
    None => abort("ipc_send: no recipient")
    }
}

fn ipc_recv(p : &mut Process, from : uint) {
    let mut handle = None;
    if from != 0 {
        handle = p.find_handle(from);
    }

    if log_recv {
        con::writeMutPtr(p);
        write(" recv from ");
        con::writeUInt(from);
    }

    p.set(process::InRecv);
    p.regs.rdi = from;
    match handle {
        Some(h) => {
            if log_recv {
                write(" ==> process ");
                con::writeMutPtr(h.process());
                con::newline();
            }
            recv(p, h)
        },
        None => {
            if log_recv && from != 0 {
                write(" ==> fresh\n");
            }
            recv_from_any(p, from)
        }
    }
}

fn recv(p: &mut Process, handle: &mut Handle) {
    let rcpt = handle.process();
    if rcpt.is(process::InSend) {
        abort("recv-from-specific not implemented");
    } else {
        rcpt.add_waiter(p);
    }
}

fn recv_from_any(p : &mut Process, _id: uint) {
    let mut sender = None;
    for waiter in p.waiters.iter() {
        if waiter.is(process::InSend) {
            sender = Some(waiter);
            break;
        }
    }
    match sender {
        Some(s) => {
            p.remove_waiter(s);
            transfer_message(p, s);
        },
        None => ()
    }

    if log_recv {
        write("recv: no waiters for ");
        con::writeMutPtr(p);
        con::newline();
    }

    // TODO Look for pending pulse
    // 2. Look for pending pulses
    // 3. Switch next
}

fn syscall_map(p: &mut Process, handle: uint, mut prot: uint, addr: uint, mut offset: uint, size: uint) {
    prot &= mapflag::UserAllowed;
    // TODO Check (and return failure) on:
    // * unaligned addr, offset, size (must be page-aligned)
    if (prot & mapflag::DMA) == mapflag::DMA {
        offset = match cpu().memory.alloc_frame() {
            None => 0,
            Some(p) => p as uint - kernel_base,
        }
    }

    p.aspace().map_range(addr, addr + size, handle, (offset - addr) | prot);

    if (prot & mapflag::Phys) == 0 {
        offset = 0;
    }
    cpu().syscall_return(p, offset);
}

fn syscall_pfault(p : &mut Process, mut vaddr: uint, access: uint) {
    vaddr &= !0xfff;

    // set fault address
    p.fault_addr = vaddr;
    p.regs.rsi = vaddr;
    p.regs.rdx = access & mapflag::RWX;
    // Look up vaddr, get handle, offset and flags
    let card = p.aspace().mapcard_find_def(vaddr);
    p.regs.rsi += card.offset; // proc.rsi is now translated into offset
    p.regs.rdi = card.handle;
    p.set(process::PFault);

    // Now do the equivalent of sendrcv with rdi=handle, rsi=offset, rdx=flags
}

fn syscall_hmod(p : &mut Process, id: uint, rename: uint, copy: uint) {
    let handle = p.find_handle(id);
    if log_hmod {
        con::writeMutPtr(p);
        write(" hmod: id="); con::writeHex(id);
        write(" rename="); con::writeHex(rename);
        write(" copy="); con::writeHex(copy);
        con::newline();
    }
    match handle {
    None => (),
    Some(h) => {
        // Fresh/dissociated handle for the same process as the original
        if copy != 0 {
            p.new_handle(copy, h.process());
        }
        if rename == 0 {
            p.delete_handle(h);
        } else if rename != id {
            p.rename_handle(h, rename);
        }
    }
    }
    cpu().syscall_return(p, 0);
}

fn syscall_portio(p : &mut Process, port : uint, op : uint, data: uint) -> ! {
    let mut res : uint = 0;
    unsafe { match op {
    0x01 => asm!("inb %dx, %al" : "={al}"(res) : "{dx}"(port)),
    0x02 => asm!("inw %dx, %ax" : "={ax}"(res) : "{dx}"(port)),
    0x04 => asm!("inl %dx, %eax" : "={eax}"(res) : "{dx}"(port)),
    0x11 => asm!("outb %al, %dx" :: "{al}"(data), "{dx}"(port)),
    0x12 => asm!("outw %ax, %dx" :: "{ax}"(data), "{dx}"(port)),
    0x14 => asm!("outl %eax, %dx" :: "{eax}"(data), "{dx}"(port)),
    _ => abort("unhandled portio operation")
    } }
    if log_portio {
        write("portio: port="); con::writeHex(port & 0xffff);
        write(" op="); con::writeUInt(op);
        write(" data="); con::writeHex(data);
        write(" res="); con::writeHex(res);
        con::newline();
    }
    cpu().syscall_return(p, res);
}
<commit_msg>IPC logging tweaks<commit_after>use core::prelude::*;

use aspace::mapflag;
use con;
use con::write;
use cpu;
use process;
use process::Handle;
use process::Process;
use start32::kernel_base;
use util::abort;

static log_syscall : bool = false;
static log_transfer_message : bool = false;
static log_portio : bool = false;
static log_hmod : bool = false;

static log_recv : bool = false;
static log_ipc : bool = false;

pub mod nr {
    #![allow(dead_code)]
    pub static RECV : uint = 0;
    pub static MAP : uint = 1;
    pub static PFAULT : uint = 2;
    pub static UNMAP : uint = 3;
    pub static HMOD : uint = 4;
    pub static NEWPROC : uint = 5;
    pub static WRITE : uint = 6;
    pub static PORTIO : uint = 7;
    pub static GRANT : uint = 8;
    pub static PULSE : uint = 9;

    pub static USER : uint = 16;

    pub static MSG_MASK : uint = 0xff;
    pub static MSG_KIND_MASK : uint = 0x300;
    pub static MSG_KIND_SEND : uint = 0x000;
    pub static MSG_KIND_CALL : uint = 0x100;
}

// Note: tail-called from the syscall code, "return" by switching to a process.
#[no_mangle]
pub fn syscall(
    arg0: uint,
    arg1: uint,
    arg2: uint,
    arg3: uint,
    arg4: uint,
    arg5: uint,
    nr : uint, // saved_rax
) -> ! {
    use syscall::nr::*;

    let p = unsafe { cpu().get_process() };
    // FIXME cpu.leave_proc?
    p.unset(process::Running);
    p.set(process::FastRet);

    if log_syscall {
        write("syscall! nr=");
        con::writeUInt(nr);
        write(" from process ");
        con::writeMutPtr(p);
        con::newline();
    }

    match nr {
    RECV => ipc_recv(p, arg0),
    MAP => syscall_map(p, arg0, arg1, arg2, arg3, arg4),
    PFAULT => syscall_pfault(p, arg1, arg2), // arg0 is always 0
    HMOD => syscall_hmod(p, arg0, arg1, arg2),
    PORTIO => syscall_portio(p, arg0, arg1, arg2),
    WRITE => {
        con::putc(arg0 as u8 as char);
        cpu().syscall_return(p, 0);
    },
    _ if nr >= USER => {
        match nr & MSG_KIND_MASK {
            MSG_KIND_CALL => ipc_call(p, nr & MSG_MASK, arg0, arg1, arg2, arg3, arg4, arg5),
            MSG_KIND_SEND => ipc_send(p, nr & MSG_MASK, arg0, arg1, arg2, arg3, arg4, arg5),
            _ => abort("Unknown IPC kind")
        }
    },
    _ => abort("Unhandled syscall"),
    }

    if p.is_runnable() {
        abort("process not blocked at return");
    }

    unsafe { cpu().run(); }
}

fn ipc_call(p : &mut Process, msg : uint, to : uint, arg1: uint, arg2: uint,
    arg3: uint, arg4: uint, arg5: uint) {
    if log_ipc {
        con::writeMutPtr(p);
        write(" ipc_call to ");
        con::writeUInt(to);
    }

    let handle = p.find_handle(to);
    match handle {
    Some(h) => {
        if log_ipc {
            write("==> process ");
            con::writeMutPtr(h.process());
            con::newline();
        }

        p.set(process::InSend);
        p.set(process::InRecv);
        p.regs.rdi = to;
        send_or_block(h, msg, arg1, arg2, arg3, arg4, arg5);
    },
    None => abort("ipc_call: no recipient")
    }
    if log_ipc {
        write("ipc_call: blocked\n");
    }
}

fn transfer_set_handle(target: &mut Process, source: &mut Process) {
    let mut rcpt = target.regs.rdi;
    let from = source.regs.rdi;

    let h = source.find_handle(from).unwrap();
    if rcpt == 0 {
        rcpt = h.other().unwrap().id();
    } else if !target.find_handle(rcpt).is_some() {
        match h.other() {
            // Already associated, "junk" the fresh handle and just update the
            // recipient-side handle.
            Some(g) => rcpt = g.id(),
            // Associate handles now.
            None => {
                let g = target.new_handle(rcpt, source);
                g.associate(h);
            },
        }
    } else {
        // TODO Assert that rcpt <-> from. (But the caller is responsible for
        // checking that first.)
    }
    if log_transfer_message {
        write("transfer_set_handle: rcpt=");
        con::writeHex(rcpt);
        write(" for ");
        con::writeHex(target.regs.rdi);
        con::newline();
    }
    target.regs.rdi = rcpt;
}

fn transfer_message(target: &mut Process, source: &mut Process) -> ! {
    transfer_set_handle(target, source);

    if log_transfer_message {
        write("transfer_message ");
        con::writeMutPtr(target);
        write(" <- ");
        con::writeMutPtr(source);
        con::newline();
    }

    target.regs.rax = source.regs.rax;
    target.regs.rdi = source.regs.rdi;
    target.regs.rsi = source.regs.rsi;
    target.regs.rdx = source.regs.rdx;
    target.regs.r8 = source.regs.r8;
    target.regs.r9 = source.regs.r9;
    target.regs.r10 = source.regs.r10;

    target.unset(process::InRecv);
    source.unset(process::InSend);

    let c = cpu();
    c.queue(target);
    if source.ipc_state() == 0 {
        c.queue(source);
    }
    unsafe { c.run(); }
}

fn send_or_block(h : &mut Handle, msg: uint, arg1: uint, arg2: uint,
        arg3: uint, arg4: uint, arg5: uint) {
    match h.other() {
        Some(g) => {
            let p = h.process();
            let sender = g.process();

            // Save regs - either we'll copy these in transfer_message or we'll
            // need to store them until later on when the transfer can finish.
            sender.regs.rax = msg;
            sender.regs.rdi = h.id();
            sender.regs.rsi = arg1;
            sender.regs.rdx = arg2;
            sender.regs.r10 = arg3;
            sender.regs.r8 = arg4;
            sender.regs.r9 = arg5;

            // p is the recipient, the sender is in g.process().
            if p.ipc_state() == process::InRecv.mask() {
                let rcpt = h.process().regs.rdi;
                // Check the receiving process' receipt handle
                //   0 ==> transfer
                //   !0, connected to our handle ==> transfer
                //   !0, fresh ==> transfer
                //   !0 otherwise ==> block
                if rcpt == 0
                || rcpt == g.id()
                || !p.find_handle(rcpt).is_some() {
                    transfer_message(p, sender);
                }
            }

            p.add_waiter(sender)
        },
        None => abort("sending to unconnected handle"),
    }
}

fn ipc_send(p : &mut Process, msg : uint, to : uint, arg1: uint, arg2: uint,
        arg3: uint, arg4: uint, arg5: uint) {
    if log_ipc {
        con::writeMutPtr(p);
        write(" ipc_send to ");
        con::writeUInt(to);
        con::newline();
    }

    let handle = p.find_handle(to);
    match handle {
    Some(h) => {
        p.set(process::InSend);
        send_or_block(h, msg, arg1, arg2, arg3, arg4, arg5);
    },
    None => abort("ipc_send: no recipient")
    }
}

fn ipc_recv(p : &mut Process, from : uint) {
    let mut handle = None;
    if from != 0 {
        handle = p.find_handle(from);
    }

    if log_recv {
        con::writeMutPtr(p);
        write(" recv from ");
        con::writeUInt(from);
    }

    p.set(process::InRecv);
    p.regs.rdi = from;
    match handle {
        Some(h) => {
            if log_recv {
                write(" ==> process ");
                con::writeMutPtr(h.process());
                con::newline();
            }
            recv(p, h)
        },
        None => {
            if log_recv && from != 0 {
                write(" ==> fresh\n");
            }
            recv_from_any(p, from)
        }
    }
}

fn recv(p: &mut Process, handle: &mut Handle) {
    let rcpt = handle.process();
    if rcpt.is(process::InSend) {
        abort("recv-from-specific not implemented");
    } else {
        rcpt.add_waiter(p);
    }
}

fn recv_from_any(p : &mut Process, _id: uint) {
    let mut sender = None;
    for waiter in p.waiters.iter() {
        if waiter.is(process::InSend) {
            sender = Some(waiter);
            break;
        }
    }
    match sender {
        Some(s) => {
            p.remove_waiter(s);
            transfer_message(p, s);
        },
        None => ()
    }

    if log_recv {
        write("recv: no waiters for ");
        con::writeMutPtr(p);
        con::newline();
    }

    // TODO Look for pending pulse
    // 2. Look for pending pulses
    // 3. Switch next
}

fn syscall_map(p: &mut Process, handle: uint, mut prot: uint, addr: uint, mut offset: uint, size: uint) {
    prot &= mapflag::UserAllowed;
    // TODO Check (and return failure) on:
    // * unaligned addr, offset, size (must be page-aligned)
    if (prot & mapflag::DMA) == mapflag::DMA {
        offset = match cpu().memory.alloc_frame() {
            None => 0,
            Some(p) => p as uint - kernel_base,
        }
    }

    p.aspace().map_range(addr, addr + size, handle, (offset - addr) | prot);

    if (prot & mapflag::Phys) == 0 {
        offset = 0;
    }
    cpu().syscall_return(p, offset);
}

fn syscall_pfault(p : &mut Process, mut vaddr: uint, access: uint) {
    vaddr &= !0xfff;

    // set fault address
    p.fault_addr = vaddr;
    p.regs.rsi = vaddr;
    p.regs.rdx = access & mapflag::RWX;
    // Look up vaddr, get handle, offset and flags
    let card = p.aspace().mapcard_find_def(vaddr);
    p.regs.rsi += card.offset; // proc.rsi is now translated into offset
    p.regs.rdi = card.handle;
    p.set(process::PFault);

    // Now do the equivalent of sendrcv with rdi=handle, rsi=offset, rdx=flags
}

fn syscall_hmod(p : &mut Process, id: uint, rename: uint, copy: uint) {
    let handle = p.find_handle(id);
    if log_hmod {
        con::writeMutPtr(p);
        write(" hmod: id="); con::writeHex(id);
        write(" rename="); con::writeHex(rename);
        write(" copy="); con::writeHex(copy);
        con::newline();
    }
    match handle {
    None => (),
    Some(h) => {
        // Fresh/dissociated handle for the same process as the original
        if copy != 0 {
            p.new_handle(copy, h.process());
        }
        if rename == 0 {
            p.delete_handle(h);
        } else if rename != id {
            p.rename_handle(h, rename);
        }
    }
    }
    cpu().syscall_return(p, 0);
}

fn syscall_portio(p : &mut Process, port : uint, op : uint, data: uint) -> ! {
    let mut res : uint = 0;
    unsafe { match op {
    0x01 => asm!("inb %dx, %al" : "={al}"(res) : "{dx}"(port)),
    0x02 => asm!("inw %dx, %ax" : "={ax}"(res) : "{dx}"(port)),
    0x04 => asm!("inl %dx, %eax" : "={eax}"(res) : "{dx}"(port)),
    0x11 => asm!("outb %al, %dx" :: "{al}"(data), "{dx}"(port)),
    0x12 => asm!("outw %ax, %dx" :: "{ax}"(data), "{dx}"(port)),
    0x14 => asm!("outl %eax, %dx" :: "{eax}"(data), "{dx}"(port)),
    _ => abort("unhandled portio operation")
    } }
    if log_portio {
        write("portio: port="); con::writeHex(port & 0xffff);
        write(" op="); con::writeUInt(op);
        write(" data="); con::writeHex(data);
        write(" res="); con::writeHex(res);
        con::newline();
    }
    cpu().syscall_return(p, res);
}
<|endoftext|>


<commit_before><commit_msg>chore(term): Add example for custom timestamp<commit_after>#[macro_use(o,slog_log,slog_trace,slog_debug,slog_info,slog_warn,slog_error,slog_crit)]
extern crate slog;

extern crate slog_term;

use std::time::{Duration, SystemTime};

use slog::DrainExt;

fn main() {
    let now = SystemTime::now();
    let streamer = slog_term::StreamerBuilder::new()
        .use_custom_timestamp(Box::new(move || {
            let elapsed = now.elapsed().unwrap();
            format!("{:5}.{:06}", elapsed.as_secs(), elapsed.subsec_nanos()/1000)
            }));
    let log = slog::Logger::root(streamer.build().fuse(), o!());

    slog_trace!(log, "logging a trace message");
    std::thread::sleep(Duration::from_millis(250));
    slog_debug!(log, "debug values"; "x" => 1, "y" => -1);
    std::thread::sleep(Duration::from_millis(250));
    slog_info!(log, "some interesting info"; "where" => "right here");
    std::thread::sleep(Duration::from_millis(250));
    slog_warn!(log, "be cautious!"; "why" => "you never know...");
    std::thread::sleep(Duration::from_millis(250));
    slog_error!(log, "type" => "unknown"; "wrong {}", "foobar");
    std::thread::sleep(Duration::from_millis(250));
    slog_crit!(log, "abandoning test");
}
<|endoftext|>


<commit_before><commit_msg>Add problem #81<commit_after>use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 81,
    answer: "427337",
    solver: solve
};

fn solve() -> ~str {
    let result = io::file_reader(&Path("files/matrix.txt")).map(|file| {
        let mut mat = ~[];
        for file.each_line |line| {
            let mut row = ~[];
            for line.each_split_char(',') |n| {
                row.push(uint::from_str(n).get());
            }
            mat.push(row);
            assert_eq!(mat[0].len(), mat.last().len());
        }
        let w = mat[0].len();
        let h = mat.len();
        ((w, h), mat)
    }).map(|&((w, h), mat)| {
        let mut sum = vec::from_fn(h, |_y| vec::from_elem(w, 0));
        sum[0][0] = mat[0][0];
        for uint::range(1, h) |y| {
            sum[y][0] = mat[y][0] + sum[y - 1][0];
        }
        for uint::range(1, w) |x| {
            sum[0][x] = mat[0][x] + sum[0][x - 1];
            for uint::range(1, h) |y| {
                sum[y][x] = mat[y][x] + uint::min(sum[y - 1][x], sum[y][x - 1]);
            }
        }
        sum[h - 1][w - 1]
    });

    match result {
        Err(msg) => fail!(msg),
        Ok(value) => return value.to_str()
    }
}
<|endoftext|>


<commit_before><commit_msg>small doc fix.<commit_after><|endoftext|>


<commit_before><commit_msg>remove arity comments<commit_after><|endoftext|>


<commit_before><commit_msg>それっぽい<commit_after><|endoftext|>


<commit_before><commit_msg>unwrap<commit_after><|endoftext|>


<commit_before><commit_msg>(feat) Added Params object to be stored on Alloy.<commit_after>use regex::Regex;
use std::collections::hashmap::HashMap;

pub struct Params {
    captures: HashMap<String, String>
}

impl Params {
    pub fn new<I: Iterator<String>>(uri: &str, matcher: Regex, params: I) -> Params {
        let captures = matcher.captures(uri).unwrap();
        Params {
            captures: params.map(|p| (p.clone(), captures.name(p.as_slice()).to_string())).collect()
        }
    }

    pub fn get<'a>(&'a self, param: String) -> Option<&'a String> {
        self.captures.find(&param)
    }
}

<|endoftext|>


<commit_before><commit_msg>feat(scores): add PAM200 score matrix<commit_after>// Copyright 2015 M. Rizky Luthfianto.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate lazy_static;

extern crate nalgebra;

use nalgebra::DMat;

lazy_static! {

	// Taken from https://github.com/seqan/seqan/blob/master/include%2Fseqan%2Fscore%2Fscore_matrix_data.h#L710
	// Copyright (c) 2006-2015, Knut Reinert, FU Berlin
	static ref ARRAY: [i32;729]=[
		 3,  0, -3,  0,  0, -4,  1, -2, -1, -2, -2, -2, -2,  0,  0,  1, -1, -2,  1,  1,  0,  0, -7, -4,  0,  0, -9,
		 0,  3, -5,  4,  3, -6,  0,  1, -3, -4,  0, -4, -3,  3, -1, -1,  1, -1,  1,  0, -1, -3, -6, -4,  2, -1, -9,
		-3, -5, 12, -6, -7, -6, -4, -4, -3, -5, -7, -7, -6, -5, -4, -4, -7, -4,  0, -3, -4, -2, -9,  0, -7, -4, -9,
		 0,  4, -6,  5,  4, -7,  0,  0, -3, -4,  0, -5, -4,  3, -1, -2,  2, -2,  0,  0, -1, -3, -8, -5,  3, -1, -9,
		 0,  3, -7,  4,  5, -7,  0,  0, -3, -4,  0, -4, -3,  2, -1, -1,  3, -2,  0, -1, -1, -2, -9, -5,  4, -1, -9,
		-4, -6, -6, -7, -7, 10, -6, -2,  1,  2, -7,  2,  0, -4, -3, -6, -6, -5, -4, -4, -3, -2,  0,  7, -6, -3, -9,
		 1,  0, -4,  0,  0, -6,  6, -3, -3, -4, -2, -5, -4,  0, -1, -1, -2, -4,  1,  0, -1, -2, -8, -6, -1, -1, -9,
		-2,  1, -4,  0,  0, -2, -3,  8, -3, -3, -1, -3, -3,  2, -1, -1,  3,  2, -1, -2, -1, -3, -3,  0,  2, -1, -9,
		-1, -3, -3, -3, -3,  1, -3, -3,  6,  4, -2,  2,  2, -2, -1, -3, -3, -2, -2,  0, -1,  4, -6, -2, -3, -1, -9,
		-2, -4, -5, -4, -4,  2, -4, -3,  4,  5, -3,  5,  3, -3, -2, -3, -3, -3, -3, -1, -2,  3, -4, -2, -3, -2, -9,
		-2,  0, -7,  0,  0, -7, -2, -1, -2, -3,  6, -4,  1,  1, -1, -2,  1,  4,  0,  0, -1, -3, -4, -5,  0, -1, -9,
		-2, -4, -7, -5, -4,  2, -5, -3,  2,  5, -4,  7,  4, -4, -2, -3, -2, -4, -4, -2, -2,  2, -2, -2, -3, -2, -9,
		-2, -3, -6, -4, -3,  0, -4, -3,  2,  3,  1,  4,  8, -2, -1, -3, -1, -1, -2, -1, -1,  2, -5, -3, -2, -1, -9,
		 0,  3, -5,  3,  2, -4,  0,  2, -2, -3,  1, -4, -2,  3,  0, -1,  1,  0,  1,  0,  0, -2, -5, -2,  1,  0, -9,
		 0, -1, -4, -1, -1, -3, -1, -1, -1, -2, -1, -2, -1,  0, -1, -1, -1, -1,  0,  0, -1, -1, -5, -3, -1, -1, -9,
		 1, -1, -4, -2, -1, -6, -1, -1, -3, -3, -2, -3, -3, -1, -1,  7,  0,  0,  1,  0, -1, -2, -7, -6, -1, -1, -9,
		-1,  1, -7,  2,  3, -6, -2,  3, -3, -3,  1, -2, -1,  1, -1,  0,  5,  1, -1, -1, -1, -3, -6, -5,  4, -1, -9,
		-2, -1, -4, -2, -2, -5, -4,  2, -2, -3,  4, -4, -1,  0, -1,  0,  1,  7, -1, -1, -1, -3,  2, -5,  0, -1, -9,
		 1,  1,  0,  0,  0, -4,  1, -1, -2, -3,  0, -4, -2,  1,  0,  1, -1, -1,  2,  2,  0, -1, -3, -3, -1,  0, -9,
		 1,  0, -3,  0, -1, -4,  0, -2,  0, -1,  0, -2, -1,  0,  0,  0, -1, -1,  2,  4,  0,  0, -6, -3, -1,  0, -9,
		 0, -1, -4, -1, -1, -3, -1, -1, -1, -2, -1, -2, -1,  0, -1, -1, -1, -1,  0,  0, -1, -1, -5, -3, -1, -1, -9,
		 0, -3, -2, -3, -2, -2, -2, -3,  4,  3, -3,  2,  2, -2, -1, -2, -3, -3, -1,  0, -1,  5, -8, -3, -2, -1, -9,
		-7, -6, -9, -8, -9,  0, -8, -3, -6, -4, -4, -2, -5, -5, -5, -7, -6,  2, -3, -6, -5, -8, 18, -1, -7, -5, -9,
		-4, -4,  0, -5, -5,  7, -6,  0, -2, -2, -5, -2, -3, -2, -3, -6, -5, -5, -3, -3, -3, -3, -1, 11, -5, -3, -9,
		 0,  2, -7,  3,  4, -6, -1,  2, -3, -3,  0, -3, -2,  1, -1, -1,  4,  0, -1, -1, -1, -2, -7, -5,  4, -1, -9,
		 0, -1, -4, -1, -1, -3, -1, -1, -1, -2, -1, -2, -1,  0, -1, -1, -1, -1,  0,  0, -1, -1, -5, -3, -1, -1, -9,
		-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,  1
	];

	static ref MAT: DMat<i32> = DMat::from_col_vec(27, 27, &*ARRAY);
}

#[inline]
fn lookup(number: u8) -> usize {
	if      number==b'Y' { 23 as usize }
	else if number==b'Z' { 24 as usize }
	else if number==b'X' { 25 as usize }
	else if number==b'*' { 26 as usize }
	else { (number-65) as usize }
}

pub fn pam200(a: u8, b: u8) -> i32 {
	let a = lookup(a);
	let b = lookup(b);

	MAT[(a, b)]
}

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

	#[test]
	fn test_pam200() {
		let score1 = pam200(b'A',b'A');
		assert_eq!(score1, 2);
		let score2 = pam200(b'*',b'*');
		assert_eq!(score2, 1);
		let score3 = pam200(b'A',b'*');
		assert_eq!(score3, -8);
		let score4 = pam200(b'Y',b'Z');
		assert_eq!(score4, -4);
		let score5 = pam200(b'X',b'X');
		assert_eq!(score5, -1);
		let score6 = pam200(b'X',b'Z');
		assert_eq!(score6, -1);
	}
}
<|endoftext|>


<commit_before><commit_msg>Add gtk::Separators to Each Unit<commit_after><|endoftext|>


<commit_before><commit_msg>fix(SubCommands): fixed where subcmds weren't recognized after mult args<commit_after><|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// These 4 `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
// microcontrollers. Namely, all these processors:
//
// - Cortex-M0
// - Cortex-M0+
// - Cortex-M1
// - Cortex-M3
// - Cortex-M4(F)
// - Cortex-M7(F)
//
// We have opted for 4 targets instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
// etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
// non-existent from the POV of codegen so it doesn't make sense to have separate targets for them.
// And if differences exist between two processors under the same target, rustc flags can be used to
// optimize for one processor or the other.
//
// Also, we have not chosen a single target (`arm-none-eabi`) like GCC does because this makes
// difficult to integrate Rust code and C code. Targeting the Cortex-M4 requires different gcc flags
// than the ones you would use for the Cortex-M0 and with a single target it'd be impossible to
// differentiate one processor from the other.
//
// About arm vs thumb in the name. The Cortex-M devices only support the Thumb instruction set,
// which is more compact (higher code density), and not the ARM instruction set. That's why LLVM
// triples use thumb instead of arm. We follow suit because having thumb in the name let us
// differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of
// build scripts / gcc flags.

use target::TargetOptions;
use std::default::Default;

pub fn opts() -> TargetOptions {
    // See rust-lang/rfcs#1645 for a discussion about these defaults
    TargetOptions {
        executables: true,
        // In 99%+ of cases, we want to use the `arm-none-eabi-gcc` compiler (there aren't many
        // options around)
        linker: "arm-none-eabi-gcc".to_string(),
        // Because these devices have very little resources having an unwinder is too onerous so we
        // default to "abort" because the "unwind" strategy is very rare.
        panic_strategy: "abort".to_string(),
        // Similarly, one almost always never wants to use relocatable code because of the extra
        // costs it involves.
        relocation_model: "static".to_string(),
        .. Default::default()
    }
}
<commit_msg>fix: "abort" -> PanicStrategy<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// These 4 `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
// microcontrollers. Namely, all these processors:
//
// - Cortex-M0
// - Cortex-M0+
// - Cortex-M1
// - Cortex-M3
// - Cortex-M4(F)
// - Cortex-M7(F)
//
// We have opted for 4 targets instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
// etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
// non-existent from the POV of codegen so it doesn't make sense to have separate targets for them.
// And if differences exist between two processors under the same target, rustc flags can be used to
// optimize for one processor or the other.
//
// Also, we have not chosen a single target (`arm-none-eabi`) like GCC does because this makes
// difficult to integrate Rust code and C code. Targeting the Cortex-M4 requires different gcc flags
// than the ones you would use for the Cortex-M0 and with a single target it'd be impossible to
// differentiate one processor from the other.
//
// About arm vs thumb in the name. The Cortex-M devices only support the Thumb instruction set,
// which is more compact (higher code density), and not the ARM instruction set. That's why LLVM
// triples use thumb instead of arm. We follow suit because having thumb in the name let us
// differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of
// build scripts / gcc flags.

use PanicStrategy;
use std::default::Default;
use target::TargetOptions;

pub fn opts() -> TargetOptions {
    // See rust-lang/rfcs#1645 for a discussion about these defaults
    TargetOptions {
        executables: true,
        // In 99%+ of cases, we want to use the `arm-none-eabi-gcc` compiler (there aren't many
        // options around)
        linker: "arm-none-eabi-gcc".to_string(),
        // Because these devices have very little resources having an unwinder is too onerous so we
        // default to "abort" because the "unwind" strategy is very rare.
        panic_strategy: PanicStrategy::Abort,
        // Similarly, one almost always never wants to use relocatable code because of the extra
        // costs it involves.
        relocation_model: "static".to_string(),
        .. Default::default()
    }
}
<|endoftext|>


<commit_before><commit_msg>test another version of 'creating a shared ref must not leak the Unique'<commit_after>// Creating a shared reference does not leak the data to raw pointers,
// not even when interior mutability is involved.

use std::cell::Cell;
use std::ptr;

fn main() { unsafe {
    let x = &mut Cell::new(0);
    let raw = x as *mut Cell<i32>;
    let x = &mut *raw;
    let _shr = &*x;
    // The state here is interesting because the top of the stack is [Unique, SharedReadWrite],
    // just like if we had done `x as *mut _`.
    // If we said that reading from a lower item is fine if the top item is `SharedReadWrite`
    // (one way to maybe preserve a stack discipline), then we could now read from `raw`
    // without invalidating `x`.  That would be bad!  It would mean that creating `shr`
    // leaked `x` to `raw`.
    let _val = ptr::read(raw);
    let _val = *x.get_mut(); //~ ERROR borrow stack
} }
<|endoftext|>


<commit_before><commit_msg>Remove commented code 🐽<commit_after><|endoftext|>


<commit_before><commit_msg>Regression test for #20714<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct G;

fn main() {
    let g = G(); //~ ERROR: expected function, found `G`
}
<|endoftext|>


<commit_before><commit_msg>add rustdoc test for `everybody_loops` fix<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//prior to fixing `everybody_loops` to preserve items, rustdoc would crash on this file, as it
//didn't see that `SomeStruct` implemented `Clone`

//FIXME(misdreavus): whenever rustdoc shows traits impl'd inside bodies, make sure this test
//reflects that

pub struct Bounded<T: Clone>(T);

pub struct SomeStruct;

fn asdf() -> Bounded<SomeStruct> {
    impl Clone for SomeStruct {
        fn clone(&self) -> SomeStruct {
            SomeStruct
        }
    }

    Bounded(SomeStruct)
}
<|endoftext|>


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

// Code to handle initial setup steps for a pool.
// Initial setup steps are steps that do not alter the environment.

use std::collections::{HashMap, HashSet};
use std::fs::OpenOptions;
use std::path::PathBuf;

use serde_json;

use devicemapper::{devnode_to_devno, Device};

use stratis::{ErrorEnum, StratisError, StratisResult};

use super::super::super::types::PoolUuid;

use super::super::serde_structs::{BackstoreSave, PoolSave};

use super::blockdev::StratBlockDev;
use super::device::{blkdev_size, is_stratis_device};
use super::metadata::BDA;
use super::util::get_stratis_block_devices;

/// Find all Stratis devices.
///
/// Returns a map of pool uuids to a map of devices to devnodes for each pool.
pub fn find_all() -> StratisResult<HashMap<PoolUuid, HashMap<Device, PathBuf>>> {
    let mut pool_map = HashMap::new();

    for devnode in get_stratis_block_devices()? {
        match devnode_to_devno(&devnode)? {
            None => continue,
            Some(devno) => {
                is_stratis_device(&devnode)?.and_then(|pool_uuid| {
                    pool_map
                        .entry(pool_uuid)
                        .or_insert_with(HashMap::new)
                        .insert(Device::from(devno), devnode)
                });
            }
        }
    }
    Ok(pool_map)
}

/// Get the most recent metadata from a set of Devices for a given pool UUID.
/// Returns None if no metadata found for this pool.
#[allow(implicit_hasher)]
pub fn get_metadata(
    pool_uuid: PoolUuid,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<Option<PoolSave>> {
    // Get pairs of device nodes and matching BDAs
    // If no BDA, or BDA UUID does not match pool UUID, skip.
    // If there is an error reading the BDA, error. There could have been
    // vital information on that BDA, for example, it may have contained
    // the newest metadata.
    let mut bdas = Vec::new();
    for devnode in devnodes.values() {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?;
        if let Some(bda) = bda {
            if bda.pool_uuid() == pool_uuid {
                bdas.push((devnode, bda));
            }
        }
    }

    // Most recent time should never be None if this was a properly
    // created pool; this allows for the method to be called in other
    // circumstances.
    let most_recent_time = {
        match bdas.iter()
            .filter_map(|&(_, ref bda)| bda.last_update_time())
            .max()
        {
            Some(time) => time,
            None => return Ok(None),
        }
    };

    // Try to read from all available devnodes that could contain most
    // recent metadata. In the event of errors, continue to try until all are
    // exhausted.
    for &(devnode, ref bda) in bdas.iter()
        .filter(|&&(_, ref bda)| bda.last_update_time() == Some(most_recent_time))
    {
        let poolsave = OpenOptions::new()
            .read(true)
            .open(devnode)
            .ok()
            .and_then(|mut f| bda.load_state(&mut f).ok())
            .and_then(|opt| opt)
            .and_then(|data| serde_json::from_slice(&data).ok());

        if poolsave.is_some() {
            return Ok(poolsave);
        }
    }

    // If no data has yet returned, we have an error. That is, we should have
    // some metadata, because we have a most recent time, but we failed to
    // get any.
    let err_str = "timestamp indicates data was written, but no data successfully read";
    Err(StratisError::Engine(ErrorEnum::NotFound, err_str.into()))
}

/// Get all the blockdevs corresponding to this pool that can be obtained from
/// the given devices.
/// Returns an error if a BDA can not be read or can not be found on any
/// blockdev in devnodes.
/// Returns an error if the blockdevs obtained do not match the metadata.
/// Returns a tuple, of which the first are the data devs, and the second
/// are the devs that support the cache tier.
/// Precondition: Every device in devnodes has already been determined to
/// belong to the pool with the specified pool uuid.
#[allow(implicit_hasher)]
pub fn get_blockdevs(
    pool_uuid: PoolUuid,
    backstore_save: &BackstoreSave,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<(Vec<StratBlockDev>, Vec<StratBlockDev>)> {
    let recorded_data_map: HashMap<_, _> = backstore_save
        .data_devs
        .iter()
        .map(|bds| (bds.uuid, bds))
        .collect();

    let recorded_cache_map: HashMap<_, _> = match backstore_save.cache_devs {
        Some(ref cache_devs) => cache_devs.iter().map(|bds| (bds.uuid, bds)).collect(),
        None => HashMap::new(),
    };

    let mut segment_table = HashMap::new();
    for seg in &backstore_save.data_segments {
        segment_table
            .entry(seg.0)
            .or_insert_with(Vec::default)
            .push((seg.1, seg.2))
    }
    if let Some(ref segs) = backstore_save.cache_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }
    if let Some(ref segs) = backstore_save.meta_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }

    let (mut datadevs, mut cachedevs) = (vec![], vec![]);
    for (device, devnode) in devnodes {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?.ok_or_else(|| {
            StratisError::Engine(ErrorEnum::NotFound,
                                                 format!("Device {} with devnode {} was previously determined to belong to pool with uuid {} but no BDA was found",
                                                 device,
                                                 devnode.display(),
                                                 pool_uuid))
        })?;

        let actual_size = blkdev_size(&OpenOptions::new().read(true).open(devnode)?)?.sectors();

        if actual_size < bda.dev_size() {
            let err_msg = format!(
                "actual blockdev size ({}) < recorded size ({})",
                actual_size,
                bda.dev_size()
            );

            return Err(StratisError::Engine(ErrorEnum::Error, err_msg));
        }

        let dev_uuid = bda.dev_uuid();

        let (dev_vec, bd_save) = match recorded_data_map.get(&dev_uuid) {
            Some(bd_save) => (&mut datadevs, bd_save),
            None => match recorded_cache_map.get(&dev_uuid) {
                Some(bd_save) => (&mut cachedevs, bd_save),
                None => {
                    let err_msg = format!("Blockdev {} not found in metadata", bda.dev_uuid());
                    return Err(StratisError::Engine(ErrorEnum::NotFound, err_msg));
                }
            },
        };

        // This should always succeed since the actual size is at
        // least the recorded size, so all segments should be
        // available to be allocated. If this fails, the most likely
        // conclusion is metadata corruption.
        let segments = segment_table.get(&dev_uuid);
        dev_vec.push(StratBlockDev::new(
            *device,
            devnode.to_owned(),
            bda,
            segments.unwrap_or(&vec![]),
            bd_save.user_info.clone(),
            bd_save.hardware_info.clone(),
        )?);
    }

    // Verify that datadevs found match datadevs recorded.
    let current_data_uuids: HashSet<_> = datadevs.iter().map(|b| b.uuid()).collect();
    let recorded_data_uuids: HashSet<_> = recorded_data_map.keys().cloned().collect();
    if current_data_uuids != recorded_data_uuids {
        let err_msg = "Recorded data dev UUIDs != discovered datadev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if datadevs.len() != current_data_uuids.len() {
        let err_msg = "Duplicate data devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    // Verify that cachedevs found match cachedevs recorded.
    let current_cache_uuids: HashSet<_> = cachedevs.iter().map(|b| b.uuid()).collect();
    let recorded_cache_uuids: HashSet<_> = recorded_cache_map.keys().cloned().collect();
    if current_cache_uuids != recorded_cache_uuids {
        let err_msg = "Recorded cache dev UUIDs != discovered cachedev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if cachedevs.len() != current_cache_uuids.len() {
        let err_msg = "Duplicate cache devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    Ok((datadevs, cachedevs))
}
<commit_msg>Tidy up the body of the loop<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Code to handle initial setup steps for a pool.
// Initial setup steps are steps that do not alter the environment.

use std::collections::{HashMap, HashSet};
use std::fs::OpenOptions;
use std::path::PathBuf;

use serde_json;

use devicemapper::{devnode_to_devno, Device};

use stratis::{ErrorEnum, StratisError, StratisResult};

use super::super::super::types::{BlockDevTier, PoolUuid};

use super::super::serde_structs::{BackstoreSave, PoolSave};

use super::blockdev::StratBlockDev;
use super::device::{blkdev_size, is_stratis_device};
use super::metadata::BDA;
use super::util::get_stratis_block_devices;

/// Find all Stratis devices.
///
/// Returns a map of pool uuids to a map of devices to devnodes for each pool.
pub fn find_all() -> StratisResult<HashMap<PoolUuid, HashMap<Device, PathBuf>>> {
    let mut pool_map = HashMap::new();

    for devnode in get_stratis_block_devices()? {
        match devnode_to_devno(&devnode)? {
            None => continue,
            Some(devno) => {
                is_stratis_device(&devnode)?.and_then(|pool_uuid| {
                    pool_map
                        .entry(pool_uuid)
                        .or_insert_with(HashMap::new)
                        .insert(Device::from(devno), devnode)
                });
            }
        }
    }
    Ok(pool_map)
}

/// Get the most recent metadata from a set of Devices for a given pool UUID.
/// Returns None if no metadata found for this pool.
#[allow(implicit_hasher)]
pub fn get_metadata(
    pool_uuid: PoolUuid,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<Option<PoolSave>> {
    // Get pairs of device nodes and matching BDAs
    // If no BDA, or BDA UUID does not match pool UUID, skip.
    // If there is an error reading the BDA, error. There could have been
    // vital information on that BDA, for example, it may have contained
    // the newest metadata.
    let mut bdas = Vec::new();
    for devnode in devnodes.values() {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?;
        if let Some(bda) = bda {
            if bda.pool_uuid() == pool_uuid {
                bdas.push((devnode, bda));
            }
        }
    }

    // Most recent time should never be None if this was a properly
    // created pool; this allows for the method to be called in other
    // circumstances.
    let most_recent_time = {
        match bdas.iter()
            .filter_map(|&(_, ref bda)| bda.last_update_time())
            .max()
        {
            Some(time) => time,
            None => return Ok(None),
        }
    };

    // Try to read from all available devnodes that could contain most
    // recent metadata. In the event of errors, continue to try until all are
    // exhausted.
    for &(devnode, ref bda) in bdas.iter()
        .filter(|&&(_, ref bda)| bda.last_update_time() == Some(most_recent_time))
    {
        let poolsave = OpenOptions::new()
            .read(true)
            .open(devnode)
            .ok()
            .and_then(|mut f| bda.load_state(&mut f).ok())
            .and_then(|opt| opt)
            .and_then(|data| serde_json::from_slice(&data).ok());

        if poolsave.is_some() {
            return Ok(poolsave);
        }
    }

    // If no data has yet returned, we have an error. That is, we should have
    // some metadata, because we have a most recent time, but we failed to
    // get any.
    let err_str = "timestamp indicates data was written, but no data successfully read";
    Err(StratisError::Engine(ErrorEnum::NotFound, err_str.into()))
}

/// Get all the blockdevs corresponding to this pool that can be obtained from
/// the given devices.
/// Returns an error if a BDA can not be read or can not be found on any
/// blockdev in devnodes.
/// Returns an error if the blockdevs obtained do not match the metadata.
/// Returns a tuple, of which the first are the data devs, and the second
/// are the devs that support the cache tier.
/// Precondition: Every device in devnodes has already been determined to
/// belong to the pool with the specified pool uuid.
#[allow(implicit_hasher)]
pub fn get_blockdevs(
    pool_uuid: PoolUuid,
    backstore_save: &BackstoreSave,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<(Vec<StratBlockDev>, Vec<StratBlockDev>)> {
    let recorded_data_map: HashMap<_, _> = backstore_save
        .data_devs
        .iter()
        .map(|bds| (bds.uuid, bds))
        .collect();

    let recorded_cache_map: HashMap<_, _> = match backstore_save.cache_devs {
        Some(ref cache_devs) => cache_devs.iter().map(|bds| (bds.uuid, bds)).collect(),
        None => HashMap::new(),
    };

    let mut segment_table = HashMap::new();
    for seg in &backstore_save.data_segments {
        segment_table
            .entry(seg.0)
            .or_insert_with(Vec::default)
            .push((seg.1, seg.2))
    }
    if let Some(ref segs) = backstore_save.cache_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }
    if let Some(ref segs) = backstore_save.meta_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }

    let (mut datadevs, mut cachedevs) = (vec![], vec![]);
    for (device, devnode) in devnodes {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?.ok_or_else(|| {
            StratisError::Engine(ErrorEnum::NotFound,
                                                 format!("Device {} with devnode {} was previously determined to belong to pool with uuid {} but no BDA was found",
                                                 device,
                                                 devnode.display(),
                                                 pool_uuid))
        })?;

        // Return an error if apparent size of Stratis block device appears to
        // have decreased since metadata was recorded or if size of block
        // device could not be obtained.
        blkdev_size(&OpenOptions::new().read(true).open(devnode)?).and_then(|actual_size| {
            let actual_size_sectors = actual_size.sectors();
            let recorded_size = bda.dev_size();
            if actual_size_sectors < recorded_size {
                let err_msg = format!(
                    "Stratis device with device number {}, devnode {}, pool UUID {} and device UUID {} had recorded size ({}), but actual size is less at ({})",
                    device,
                    devnode.display(),
                    bda.pool_uuid(),
                    bda.dev_uuid(),
                    recorded_size,
                    actual_size
                );
                Err(StratisError::Engine(ErrorEnum::Error, err_msg))
            } else {
                Ok(())
            }
        })?;

        let dev_uuid = bda.dev_uuid();

        // Locate the device in the metadata using its uuid. Return the device
        // metadata and whether it was a cache or a datadev.
        let (tier, bd_save) = recorded_data_map
            .get(&dev_uuid)
            .map(|bd_save| (BlockDevTier::Data, bd_save))
            .or_else(|| {
                recorded_cache_map
                    .get(&dev_uuid)
                    .map(|bd_save| (BlockDevTier::Cache, bd_save))
            })
            .ok_or_else(|| {
                let err_msg = format!(
                        "Stratis device with device number {}, devnode {}, pool UUID {} and device UUID {} had no record in pool metadata",
                        device,
                        devnode.display(),
                        bda.pool_uuid(),
                        bda.dev_uuid()
                    );
                StratisError::Engine(ErrorEnum::NotFound, err_msg)
            })?;

        // This should always succeed since the actual size is at
        // least the recorded size, so all segments should be
        // available to be allocated. If this fails, the most likely
        // conclusion is metadata corruption.
        let segments = segment_table.get(&dev_uuid);
        match tier {
            BlockDevTier::Data => &mut datadevs,
            BlockDevTier::Cache => &mut cachedevs,
        }.push(StratBlockDev::new(
            *device,
            devnode.to_owned(),
            bda,
            segments.unwrap_or(&vec![]),
            bd_save.user_info.clone(),
            bd_save.hardware_info.clone(),
        )?);
    }

    // Verify that datadevs found match datadevs recorded.
    let current_data_uuids: HashSet<_> = datadevs.iter().map(|b| b.uuid()).collect();
    let recorded_data_uuids: HashSet<_> = recorded_data_map.keys().cloned().collect();
    if current_data_uuids != recorded_data_uuids {
        let err_msg = "Recorded data dev UUIDs != discovered datadev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if datadevs.len() != current_data_uuids.len() {
        let err_msg = "Duplicate data devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    // Verify that cachedevs found match cachedevs recorded.
    let current_cache_uuids: HashSet<_> = cachedevs.iter().map(|b| b.uuid()).collect();
    let recorded_cache_uuids: HashSet<_> = recorded_cache_map.keys().cloned().collect();
    if current_cache_uuids != recorded_cache_uuids {
        let err_msg = "Recorded cache dev UUIDs != discovered cachedev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if cachedevs.len() != current_cache_uuids.len() {
        let err_msg = "Duplicate cache devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    Ok((datadevs, cachedevs))
}
<|endoftext|>


<commit_before><commit_msg>Make iterator lifetimes less restricting<commit_after><|endoftext|>


<commit_before><commit_msg>add an undef validation test<commit_after>#![allow(unused_variables)]
// error-pattern: attempted to read undefined bytes

mod safe {
    use std::mem;

    pub(crate) fn make_float() -> f32 {
        unsafe { mem::uninitialized() }
    }
}

fn main() {
    let _x = safe::make_float();
}
<|endoftext|>


<commit_before><commit_msg>man or boy implementation<commit_after>// http://rosettacode.org/wiki/Man_or_boy_test
// as originally posted by Kimundi on Reddit
// http://www.reddit.com/r/rust/comments/2t80mw/the_man_or_boy_test_in_rust/
use std::cell::Cell;

fn a(k: i32,
     x1: &Fn() -> i32,
     x2: &Fn() -> i32,
     x3: &Fn() -> i32,
     x4: &Fn() -> i32,
     x5: &Fn() -> i32) -> i32 {
    let k = Cell::new(k);

    let b: Cell<Option<&Fn() -> i32>> = Cell::new(None);
    let tmp = |&:| {
        k.set(k.get() - 1);
        a(k.get(), &*b.get().unwrap(), x1, x2, x3, x4)
    };
    b.set(Some(&tmp));

    if k.get() <= 0 { x4() + x5() } else { b.get().unwrap()() }
}

#[cfg(not(test))]
fn main() {
    println!("%{}", a(10, &|| 1, &|| -1, &|| -1, &|| 1, &|| 0));
}

#[test]
fn result() {
    assert_eq!(a(10, &|| 1, &|| -1, &|| -1, &|| 1, &|| 0), -67)
}
<|endoftext|>


<commit_before><commit_msg>Add error module<commit_after>generate_error_module!(
    generate_error_types!(DiaryError, DiaryErrorKind,
        StoreWriteError     => "Error writing store",
        StoreReadError      => "Error reading store",
        CannotFindDiary     => "Cannot find diary",
        CannotCreateNote    => "Cannot create Note object for diary entry",
        DiaryEditError      => "Cannot edit diary entry",
        PathConversionError => "Error while converting paths internally",
        EntryNotInDiary     => "Entry not in Diary",
        IOError             => "IO Error"
    );
);

pub use self::error::DiaryError;
pub use self::error::DiaryErrorKind;

<|endoftext|>


<commit_before><commit_msg>imag-mv: Move from error-chain to failure<commit_after><|endoftext|>


<commit_before><commit_msg>parser: fix tests<commit_after><|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use LinkerFlavor;
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::android_base::opts();
    base.features = "+v7,+vfp3,+d16".to_string();
    base.max_atomic_width = Some(64);

    Ok(Target {
        llvm_target: "arm-linux-androideabi".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "android".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: TargetOptions {
            abi_blacklist: super::arm_base::abi_blacklist(),
            .. base
        },
    })
}
<commit_msg>Rollup merge of #41656 - malbarbo:android-armeabi, r=alexcrichton<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use LinkerFlavor;
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::android_base::opts();
    // https://developer.android.com/ndk/guides/abis.html#armeabi
    base.features = "+v5te".to_string();
    base.max_atomic_width = Some(64);

    Ok(Target {
        llvm_target: "arm-linux-androideabi".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "android".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: TargetOptions {
            abi_blacklist: super::arm_base::abi_blacklist(),
            .. base
        },
    })
}
<|endoftext|>


<commit_before><commit_msg>Add tests for ChanSelect<commit_after>#[macro_use] extern crate "rust-sessions" as rust_sessions;

use std::thread::spawn;
use std::borrow::ToOwned;
use rust_sessions::*;

// recv and assert a value, then close the channel
macro_rules! recv_assert_eq_close(
    ($e:expr, $rx:ident.recv())
        =>
    ({
        let (c, v) = $rx.recv();
        assert_eq!($e, v);
        c.close();
    })
);

#[test]
fn chan_select_simple() {
    let (tcs, rcs) = session_channel();
    let (tcu, rcu) = session_channel();

    // Spawn threads
    send_str(tcs);

    // The lifetime of `sel` is reduced to the point where we call
    // `wait()`. This ensures we don't hold on to Chan references, but still
    // prevents using the channels the ChanSelect holds references to.
    let index = {
        let mut sel = ChanSelect::new();
        sel.add(&rcs); // Assigned 0
        sel.add(&rcu); // Assigned 1
        sel.wait()     // Destroys the ChanSelect, releases references to
            // rcs and rcu
    };

    assert_eq!(0, index);
    recv_assert_eq_close!("Hello, World!".to_owned(), rcs.recv());

    let (tcs, rcs) = session_channel();

    send_usize(tcu);

    let index = {
        let mut sel = ChanSelect::new();
        sel.add(&rcs);
        sel.add(&rcu);
        sel.wait()
    };

    assert_eq!(1, index);
    recv_assert_eq_close!(42, rcu.recv());

    // Not really necessary for the test, just used to coerce the types of
    // tcs and rcs
    send_str(tcs);
    recv_assert_eq_close!("Hello, World!".to_owned(), rcs.recv());
}

#[test]
fn chan_select_add_ret() {
    enum ChanToRead {
        Str,
        Usize
    }

    let (tcs, rcs) = session_channel();
    let (tcu, rcu) = session_channel();

    // Spawn threads
    spawn(move|| send_str(tcs));

    // The lifetime of `sel` is reduced to the point where we call
    // `wait()`. This ensures we don't hold on to Chan references, but still
    // prevents using the channels the ChanSelect holds references to.
    let chan_to_read = {
        let mut sel = ChanSelect::new();
        sel.add_ret(&rcs, ChanToRead::Str);   // Assigned 0
        sel.add_ret(&rcu, ChanToRead::Usize); // Assigned 1
        sel.wait()     // Destroys the ChanSelect, releases references to
            // rcs and rcu
    };

    send_usize(tcu);

    match chan_to_read {
        ChanToRead::Str => {
            recv_assert_eq_close!("Hello, World!".to_owned(), rcs.recv());
            recv_assert_eq_close!(42, rcu.recv());
        }
        ChanToRead::Usize => {
            panic!("Unexpected read of usize chan before str chan!");
        }
    }
}

// Utility functions

fn send_str(c: Chan<(), Send<String, Eps>>) {
    c.send("Hello, World!".to_string()).close();
}

fn send_usize(c: Chan<(), Send<usize, Eps>>) {
    c.send(42).close();
}
<|endoftext|>


<commit_before><commit_msg>Added ringbuffer<commit_after>//! A generic ringbuffer

#![experimental]

use std::clone::Clone;
use std::vec::Vec;

use core::Time;

pub struct RingBuffer<T: Clone> {
    buf: Vec<T>,
    capacity: uint,
    size: uint,
    start_t: Time,
    end_t: Time,
}

impl<T: Clone> RingBuffer<T> {
    pub fn new(capacity: uint) -> RingBuffer<T> {
        RingBuffer {
            buf: Vec::with_capacity(capacity),
            capacity: capacity,
            size: 0,
            start_t: 0,
            end_t: 0
        }
    }

    pub fn get(&self, t: Time) -> Option<T> {
        if self.start_t <= t && t < self.end_t {
            Some(self.buf[(t % self.capacity as Time) as uint].clone())
        } else {
            None
        }
    }

    pub fn push(&mut self, data: T) {
        if self.size < self.capacity {
            self.buf.push(data);
            self.size += 1;
            self.end_t += 1;
        } else {
            self.buf[(self.end_t % self.capacity as Time) as uint] = data;
            self.start_t += 1;
            self.end_t += 1;
        }
    }
}

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

    #[test]
    fn test_push() {
        let mut rb = RingBuffer::<int>::new(2);

        rb.push(13);
        assert_eq!(rb.size, 1);
        assert_eq!(rb.start_t, 0);
        assert_eq!(rb.end_t, 1);
        assert_eq!(rb.buf[0], 13);

        rb.push(7);
        assert_eq!(rb.size, 2);
        assert_eq!(rb.start_t, 0);
        assert_eq!(rb.end_t, 2);
        assert_eq!(rb.buf[0], 13);
        assert_eq!(rb.buf[1], 7);

        rb.push(3);
        assert_eq!(rb.size, 2);
        assert_eq!(rb.start_t, 1);
        assert_eq!(rb.end_t, 3);
        assert_eq!(rb.buf[0], 3);
        assert_eq!(rb.buf[1], 7);
    }

    #[test]
    fn test_get() {
        let mut rb: RingBuffer<int> = RingBuffer {
            buf: vec![7,13],
            capacity: 2,
            size: 2,
            start_t: 7,
            end_t: 9
        };

        // Test with odd start
        assert_eq!(rb.get(6), None);
        assert_eq!(rb.get(7), Some(13));
        assert_eq!(rb.get(8), Some(7));
        assert_eq!(rb.get(9), None);

        // Test with even start
        rb.start_t = 6; rb.end_t = 8;
        assert_eq!(rb.get(5), None);
        assert_eq!(rb.get(6), Some(7));
        assert_eq!(rb.get(7), Some(13));
        assert_eq!(rb.get(8), None);
    }
}
<|endoftext|>


<commit_before><commit_msg>Improved streak count algo<commit_after><|endoftext|>


<commit_before><commit_msg>Make code more functional by more function chaining.<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary to_string() calls<commit_after><|endoftext|>


<commit_before><commit_msg>Added bar def<commit_after>//! Defines the operations and data definitions for a top bar program.

use std::ops::Drop;
use rustwlc::WlcView;

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct Bar {
    view: WlcView
}

impl Bar {
    pub fn new(view: WlcView) -> Self {
        Bar { view: view }
    }

    /// Gets the view that is associated with the bar.
    pub fn view(&self) -> WlcView {
        self.view
    }
}
<|endoftext|>


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

#![comment = "The Servo Parallel Browser Project"]
#![license = "MPL"]

#![feature(globs, macro_rules, phase, thread_local, unsafe_destructor)]

#![deny(unused_imports, unused_variable)]
#![allow(unrooted_must_root)]

#[phase(plugin, link)]
extern crate log;

extern crate debug;

extern crate geom;
extern crate gfx;
extern crate layout_traits;
extern crate script;
extern crate script_traits;
extern crate serialize;
extern crate style;
#[phase(plugin)]
extern crate "plugins" as servo_plugins;
extern crate "net" as servo_net;
extern crate "msg" as servo_msg;
#[phase(plugin, link)]
extern crate "util" as servo_util;

#[phase(plugin)]
extern crate string_cache_macros;
extern crate string_cache;

extern crate collections;
extern crate encoding;
extern crate green;
extern crate libc;
extern crate sync;
extern crate url;

// Listed first because of macro definitions
pub mod layout_debug;

pub mod block;
pub mod construct;
pub mod context;
pub mod display_list_builder;
pub mod floats;
pub mod flow;
pub mod flow_list;
pub mod flow_ref;
pub mod fragment;
pub mod layout_task;
pub mod inline;
pub mod model;
pub mod parallel;
pub mod sequential;
pub mod table_wrapper;
pub mod table;
pub mod table_caption;
pub mod table_colgroup;
pub mod table_rowgroup;
pub mod table_row;
pub mod table_cell;
pub mod text;
pub mod traversal;
pub mod util;
pub mod incremental;
pub mod wrapper;

pub mod css {
    mod node_util;

    pub mod matching;
    pub mod node_style;
}
<commit_msg>Remove unnecessary import of libgreen<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![comment = "The Servo Parallel Browser Project"]
#![license = "MPL"]

#![feature(globs, macro_rules, phase, thread_local, unsafe_destructor)]

#![deny(unused_imports, unused_variable)]
#![allow(unrooted_must_root)]

#[phase(plugin, link)]
extern crate log;

extern crate debug;

extern crate geom;
extern crate gfx;
extern crate layout_traits;
extern crate script;
extern crate script_traits;
extern crate serialize;
extern crate style;
#[phase(plugin)]
extern crate "plugins" as servo_plugins;
extern crate "net" as servo_net;
extern crate "msg" as servo_msg;
#[phase(plugin, link)]
extern crate "util" as servo_util;

#[phase(plugin)]
extern crate string_cache_macros;
extern crate string_cache;

extern crate collections;
extern crate encoding;
extern crate libc;
extern crate sync;
extern crate url;

// Listed first because of macro definitions
pub mod layout_debug;

pub mod block;
pub mod construct;
pub mod context;
pub mod display_list_builder;
pub mod floats;
pub mod flow;
pub mod flow_list;
pub mod flow_ref;
pub mod fragment;
pub mod layout_task;
pub mod inline;
pub mod model;
pub mod parallel;
pub mod sequential;
pub mod table_wrapper;
pub mod table;
pub mod table_caption;
pub mod table_colgroup;
pub mod table_rowgroup;
pub mod table_row;
pub mod table_cell;
pub mod text;
pub mod traversal;
pub mod util;
pub mod incremental;
pub mod wrapper;

pub mod css {
    mod node_util;

    pub mod matching;
    pub mod node_style;
}
<|endoftext|>


<commit_before><commit_msg>chore: shortcut for propagating errors: ?<commit_after><|endoftext|>


<commit_before><commit_msg>Simplify re-export in library module.<commit_after><|endoftext|>


<commit_before><commit_msg>all references in static variable have 'static lifetime<commit_after><|endoftext|>


<commit_before><commit_msg>Auto merge of #27500 - michaelwoerister:bring-gdb-pp-tests-back, r=alexcrichton<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-windows failing on win32 bot
// ignore-freebsd: output doesn't match
// ignore-tidy-linelength
// ignore-lldb
// ignore-android: FIXME(#10381)
// compile-flags:-g

// This test uses some GDB Python API features (e.g. accessing anonymous fields)
// which are only available in newer GDB version. The following directive will
// case the test runner to ignore this test if an older GDB version is used:
// min-gdb-version 7.7

// gdb-command: run

// gdb-command: print regular_struct
// gdb-check:$1 = RegularStruct = {the_first_field = 101, the_second_field = 102.5, the_third_field = false, the_fourth_field = "I'm so pretty, oh so pretty..."}

// gdb-command: print tuple
// gdb-check:$2 = {true, 103, "blub"}

// gdb-command: print tuple_struct
// gdb-check:$3 = TupleStruct = {-104.5, 105}

// gdb-command: print empty_struct
// gdb-check:$4 = EmptyStruct

// gdb-command: print c_style_enum1
// gdb-check:$5 = CStyleEnumVar1

// gdb-command: print c_style_enum2
// gdb-check:$6 = CStyleEnumVar2

// gdb-command: print c_style_enum3
// gdb-check:$7 = CStyleEnumVar3

// gdb-command: print mixed_enum_c_style_var
// gdb-check:$8 = MixedEnumCStyleVar

// gdb-command: print mixed_enum_tuple_var
// gdb-check:$9 = MixedEnumTupleVar = {106, 107, false}

// gdb-command: print mixed_enum_struct_var
// gdb-check:$10 = MixedEnumStructVar = {field1 = 108.5, field2 = 109}

// gdb-command: print some
// gdb-check:$11 = Some = {110}

// gdb-command: print none
// gdb-check:$12 = None

// gdb-command: print some_fat
// gdb-check:$13 = Some = {"abc"}

// gdb-command: print none_fat
// gdb-check:$14 = None

// gdb-command: print nested_variant1
// gdb-check:$15 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}

// gdb-command: print nested_variant2
// gdb-check:$16 = NestedVariant2 = {abc = NestedStruct = {regular_struct = RegularStruct = {the_first_field = 117, the_second_field = 118.5, the_third_field = false, the_fourth_field = "NestedStructString10"}, tuple_struct = TupleStruct = {119.5, 120}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar3, mixed_enum = MixedEnumStructVar = {field1 = 121.5, field2 = -122}}}

// gdb-command: print none_check1
// gdb-check:$17 = None

// gdb-command: print none_check2
// gdb-check:$18 = None

#![allow(dead_code, unused_variables)]

use self::CStyleEnum::{CStyleEnumVar1, CStyleEnumVar2, CStyleEnumVar3};
use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar};
use self::NestedEnum::{NestedVariant1, NestedVariant2};

struct RegularStruct {
    the_first_field: isize,
    the_second_field: f64,
    the_third_field: bool,
    the_fourth_field: &'static str,
}

struct TupleStruct(f64, i16);

struct EmptyStruct;

enum CStyleEnum {
    CStyleEnumVar1,
    CStyleEnumVar2,
    CStyleEnumVar3,
}

enum MixedEnum {
    MixedEnumCStyleVar,
    MixedEnumTupleVar(u32, u16, bool),
    MixedEnumStructVar { field1: f64, field2: i32 }
}

struct NestedStruct {
    regular_struct: RegularStruct,
    tuple_struct: TupleStruct,
    empty_struct: EmptyStruct,
    c_style_enum: CStyleEnum,
    mixed_enum: MixedEnum,
}

enum NestedEnum {
    NestedVariant1(NestedStruct),
    NestedVariant2 { abc: NestedStruct }
}

fn main() {

    let regular_struct = RegularStruct {
        the_first_field: 101,
        the_second_field: 102.5,
        the_third_field: false,
        the_fourth_field: "I'm so pretty, oh so pretty..."
    };

    let tuple = ( true, 103u32, "blub" );

    let tuple_struct = TupleStruct(-104.5, 105);

    let empty_struct = EmptyStruct;

    let c_style_enum1 = CStyleEnumVar1;
    let c_style_enum2 = CStyleEnumVar2;
    let c_style_enum3 = CStyleEnumVar3;

    let mixed_enum_c_style_var = MixedEnumCStyleVar;
    let mixed_enum_tuple_var = MixedEnumTupleVar(106, 107, false);
    let mixed_enum_struct_var = MixedEnumStructVar { field1: 108.5, field2: 109 };

    let some = Some(110_usize);
    let none: Option<isize> = None;
    let some_fat = Some("abc");
    let none_fat: Option<&'static str> = None;

    let nested_variant1 = NestedVariant1(
        NestedStruct {
            regular_struct: RegularStruct {
                the_first_field: 111,
                the_second_field: 112.5,
                the_third_field: true,
                the_fourth_field: "NestedStructString1",
            },
            tuple_struct: TupleStruct(113.5, 114),
            empty_struct: EmptyStruct,
            c_style_enum: CStyleEnumVar2,
            mixed_enum: MixedEnumTupleVar(115, 116, false)
        }
    );

    let nested_variant2 = NestedVariant2 {
        abc: NestedStruct {
            regular_struct: RegularStruct {
                the_first_field: 117,
                the_second_field: 118.5,
                the_third_field: false,
                the_fourth_field: "NestedStructString10",
            },
            tuple_struct: TupleStruct(119.5, 120),
            empty_struct: EmptyStruct,
            c_style_enum: CStyleEnumVar3,
            mixed_enum: MixedEnumStructVar {
                field1: 121.5,
                field2: -122
            }
        }
    };

    let none_check1: Option<(usize, Vec<usize>)> = None;
    let none_check2: Option<String> = None;

    zzz(); // #break
}

fn zzz() { () }
<|endoftext|>


<commit_before><commit_msg>Remove unused constant<commit_after><|endoftext|>


<commit_before><commit_msg>refactor: Resolve App::usage deprecation<commit_after><|endoftext|>


<commit_before>use std::cmp::max;
use std::collections::VecDeque;
use std::mem::size_of;
use std::{ptr, slice};

use super::{Color, Display, Event, Font, Image, ImageRoi};

use system::error::{Error, Result, EINVAL};

pub struct Window {
    pub x: i32,
    pub y: i32,
    image: Image,
    title: String,
    events: VecDeque<Event>,
}

impl Window {
    pub fn new(x: i32, y: i32, w: i32, h: i32, title: String) -> Window {
        Window {
            x: x,
            y: y,
            image: Image::new(w, h),
            title: title,
            events: VecDeque::new()
        }
    }

    pub fn width(&self) -> i32 {
        self.image.width()
    }

    pub fn height(&self) -> i32 {
        self.image.height()
    }

    pub fn as_roi(&mut self) -> ImageRoi {
        self.image.as_roi()
    }

    pub fn roi(&mut self, x: i32, y: i32, w: i32, h: i32) -> ImageRoi {
        self.image.roi(x, y, w, h)
    }

    pub fn contains(&self, x: i32, y: i32) -> bool {
        x >= self.x && y >= self.y && x < self.x + self.width() && y < self.y + self.height()
    }

    pub fn title_contains(&self, x: i32, y: i32) -> bool {
        ! self.title.is_empty() && x >= self.x && y >= self.y - 18 && x < self.x + self.width() && y < self.y
    }

    pub fn exit_contains(&self, x: i32, y: i32) -> bool {
        ! self.title.is_empty() && x >= max(self.x, self.x + self.width() - 8)  && y >= self.y - 18 && x < self.x + self.width() && y < self.y
    }

    pub fn draw(&mut self, display: &mut Display, focused: bool) {
        if ! self.title.is_empty() {
            if focused {
                display.roi(self.x, self.y - 18, self.width(), 18).set(Color::rgba(192, 192, 192, 224));
            } else {
                display.roi(self.x, self.y - 18, self.width(), 18).set(Color::rgba(64, 64, 64, 224));
            }

            let mut x = self.x + 2;
            for c in self.title.chars() {
                if x + 10 <= self.x + self.width() - 10 {
                    display.roi(x, self.y - 17, 8, 16).blend(&Font::render(c, Color::rgb(255, 255, 255)).as_roi());
                } else {
                    break;
                }
                x += 8;
            }

            x = max(self.x + 2, self.x + self.width() - 10);
            if x + 10 <= self.x + self.width() {
                display.roi(x, self.y - 17, 8, 16).blend(&Font::render('X', Color::rgb(255, 255, 255)).as_roi());
            }
        }
        let mut display_roi = display.roi(self.x, self.y, self.width(), self.height());
        display_roi.blend(&self.as_roi());
    }

    pub fn event(&mut self, event: Event) {
        self.events.push_back(event);
    }

    pub fn read(&mut self, buf: &mut [u8]) -> Result {
        if buf.len() >= size_of::<Event>() {
            let mut i = 0;
            while i <= buf.len() - size_of::<Event>() {
                if let Some(event) = self.events.pop_front() {
                    unsafe { ptr::write(buf.as_mut_ptr().offset(i as isize) as *mut Event, event) };
                    i += size_of::<Event>();
                } else {
                    break;
                }
            }
            Ok(i)
        } else {
            Err(Error::new(EINVAL))
        }
    }

    pub fn write(&mut self, buf: &[u8]) -> Result {
        let old = self.image.data_mut();
        let new = unsafe { slice::from_raw_parts(buf.as_ptr() as *const Color, buf.len() / size_of::<Color>()) };

        let mut i = 0;
        while i < old.len() && i < new.len() {
            old[i] = new[i];
            i += 1;
        }

        Ok(i * size_of::<Color>())
    }
}
<commit_msg>Fix margins<commit_after>use std::cmp::max;
use std::collections::VecDeque;
use std::mem::size_of;
use std::{ptr, slice};

use super::{Color, Display, Event, Font, Image, ImageRoi};

use system::error::{Error, Result, EINVAL};

pub struct Window {
    pub x: i32,
    pub y: i32,
    image: Image,
    title: String,
    events: VecDeque<Event>,
}

impl Window {
    pub fn new(x: i32, y: i32, w: i32, h: i32, title: String) -> Window {
        Window {
            x: x,
            y: y,
            image: Image::new(w, h),
            title: title,
            events: VecDeque::new()
        }
    }

    pub fn width(&self) -> i32 {
        self.image.width()
    }

    pub fn height(&self) -> i32 {
        self.image.height()
    }

    pub fn as_roi(&mut self) -> ImageRoi {
        self.image.as_roi()
    }

    pub fn roi(&mut self, x: i32, y: i32, w: i32, h: i32) -> ImageRoi {
        self.image.roi(x, y, w, h)
    }

    pub fn contains(&self, x: i32, y: i32) -> bool {
        x >= self.x && y >= self.y && x < self.x + self.width() && y < self.y + self.height()
    }

    pub fn title_contains(&self, x: i32, y: i32) -> bool {
        ! self.title.is_empty() && x >= self.x && y >= self.y - 18 && x < self.x + self.width() && y < self.y
    }

    pub fn exit_contains(&self, x: i32, y: i32) -> bool {
        ! self.title.is_empty() && x >= max(self.x, self.x + self.width() - 10)  && y >= self.y - 18 && x < self.x + self.width() && y < self.y
    }

    pub fn draw(&mut self, display: &mut Display, focused: bool) {
        if ! self.title.is_empty() {
            if focused {
                display.roi(self.x, self.y - 18, self.width(), 18).set(Color::rgba(192, 192, 192, 224));
            } else {
                display.roi(self.x, self.y - 18, self.width(), 18).set(Color::rgba(64, 64, 64, 224));
            }

            let mut x = self.x + 2;
            for c in self.title.chars() {
                if x + 8 <= self.x + self.width() - 10 {
                    display.roi(x, self.y - 17, 8, 16).blend(&Font::render(c, Color::rgb(255, 255, 255)).as_roi());
                } else {
                    break;
                }
                x += 8;
            }

            x = max(self.x + 2, self.x + self.width() - 10);
            if x + 10 <= self.x + self.width() {
                display.roi(x, self.y - 17, 8, 16).blend(&Font::render('X', Color::rgb(255, 255, 255)).as_roi());
            }
        }
        let mut display_roi = display.roi(self.x, self.y, self.width(), self.height());
        display_roi.blend(&self.as_roi());
    }

    pub fn event(&mut self, event: Event) {
        self.events.push_back(event);
    }

    pub fn read(&mut self, buf: &mut [u8]) -> Result {
        if buf.len() >= size_of::<Event>() {
            let mut i = 0;
            while i <= buf.len() - size_of::<Event>() {
                if let Some(event) = self.events.pop_front() {
                    unsafe { ptr::write(buf.as_mut_ptr().offset(i as isize) as *mut Event, event) };
                    i += size_of::<Event>();
                } else {
                    break;
                }
            }
            Ok(i)
        } else {
            Err(Error::new(EINVAL))
        }
    }

    pub fn write(&mut self, buf: &[u8]) -> Result {
        let old = self.image.data_mut();
        let new = unsafe { slice::from_raw_parts(buf.as_ptr() as *const Color, buf.len() / size_of::<Color>()) };

        let mut i = 0;
        while i < old.len() && i < new.len() {
            old[i] = new[i];
            i += 1;
        }

        Ok(i * size_of::<Color>())
    }
}
<|endoftext|>


<commit_before><commit_msg>CIFF: implement basic parser same as TIFF<commit_after>use std::collections::HashMap;
use decoders::basics::*;
use decoders::Buffer;
use std::str;

enum_from_primitive! {
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum CiffTag {
  Null         = 0x0000,
  MakeModel    = 0x080a,
  ShotInfo     = 0x102a,
  WhiteBalance = 0x10a9,
  SensorInfo   = 0x1031,
  ImageInfo    = 0x1810,
  DecoderTable = 0x1835,
  RawData      = 0x2005,
  SubIFD       = 0x300a,
  Exif         = 0x300b,
}
}

fn ct (tag: CiffTag) -> u16 {
  tag as u16
}

#[derive(Debug, Copy, Clone)]
pub struct CiffEntry<'a> {
  pub tag: u16,
  pub typ: u16,
  pub count: usize,
  pub bytesize: usize,
  pub data_offset: usize,
  pub data: &'a [u8],
}

#[derive(Debug, Clone)]
pub struct CiffIFD<'a> {
  entries: HashMap<u16,CiffEntry<'a>>,
  subifds: Vec<CiffIFD<'a>>,
}

pub fn is_ciff(buf: &[u8]) -> bool {
  buf[6..14] == b"HEAPCCDR"[..]
}

impl<'a> CiffIFD<'a> {
  pub fn new_file(buf: &'a Buffer) -> Result<CiffIFD<'a>,String> {
    let data = &buf.buf;
    CiffIFD::new(data, data[2] as usize, buf.size, 1)
  }

  pub fn new(buf: &'a[u8], start: usize, end: usize, depth: u32) -> Result<CiffIFD<'a>, String> {
    let mut entries = HashMap::new();
    let mut subifds = Vec::new();

    let valuedata_size = LEu32(buf, end-4) as usize;
    let dircount = LEu16(buf, start+valuedata_size) as usize;

    for i in 0..dircount {
      let entry_offset: usize = start+valuedata_size+2+i*10;
      let e = try!(CiffEntry::new(buf, start, entry_offset));
      if e.typ == 0x2800 || e.typ == 0x3000 { // SubIFDs
        if depth < 10 { // Avoid infinite looping IFDs
          let ifd = CiffIFD::new(buf, e.data_offset, e.data_offset+e.bytesize, depth+1);
          match ifd {
            Ok(val) => {subifds.push(val);},
            Err(_) => {entries.insert(e.tag, e);}, // Ignore unparsable IFDs
          }
        }
      } else {
        entries.insert(e.tag, e);
      }
    }

    Ok(CiffIFD {
      entries: entries,
      subifds: subifds,
    })
  }

  pub fn find_entry(&self, tag: CiffTag) -> Option<&CiffEntry> {
    if self.entries.contains_key(&ct(tag)) {
      self.entries.get(&ct(tag))
    } else {
      for ifd in &self.subifds {
        match ifd.find_entry(tag) {
          Some(x) => return Some(x),
          None => {},
        }
      }
      None
    }
  }
}

impl<'a> CiffEntry<'a> {
  pub fn new(buf: &'a[u8], value_data: usize, offset: usize) -> Result<CiffEntry<'a>, String> {
    let p = LEu16(buf, offset);
    let tag = p & 0x3fff;
    let datalocation = (p & 0xc000) as usize;
    let typ = p & 0x3800;

    let (bytesize, data_offset) = match datalocation {
      // Data is offset in value_data
      0x0000 => (LEu32(buf, offset+2) as usize, LEu32(buf, offset+6) as usize + value_data),
      // Data is stored directly in entry
      0x4000 => (8, offset+2),
      val => return Err(format!("CIFF: Don't know about data location {:x}", val).to_string()),
    };
    let data = &buf[data_offset..data_offset+bytesize];
    let count = bytesize >> CiffEntry::element_shift(typ);

    Ok(CiffEntry {
      tag: tag,
      typ: typ,
      count: count,
      bytesize: bytesize,
      data_offset: data_offset,
      data: data,
    })
  }

  pub fn element_shift(typ: u16) -> usize {
    match typ {
      // Byte and ASCII
      0x0000 | 0x8000                   => 0,
      // Short
      0x1000                            => 1,
      // Long, Mix, Sub1 and Sub2
      0x1800 | 0x2000 | 0x2800 | 0x3000 => 2,
      // Default to 0
      _                                 => 0,
    }
  }

  pub fn get_strings(&self) -> Vec<String> {
    String::from_utf8_lossy(self.data).split_terminator("\0").map(|x| x.to_string()).collect()
  }
}
<|endoftext|>


<commit_before><commit_msg>Add refine.rs<commit_after>
use rand;
use generate::Generator;
use truth_value::TruthValue;
use program::Program;
use fact_table::FactTable;
use optimize::compute_adjustments;
use bottom_up::evaluate_bottom_up;
use name_table::NameTable;
use std::mem::swap;

pub struct Refiner<R, T> where R: rand::Rng, T: TruthValue {
    generator: Generator<R>,
    base_facts: FactTable<T>,
    program: Program<T>,
    samples: Vec<(FactTable<T>, FactTable<T>)>,
    gradient_iterations: usize,
    learning_rate: f64,
    max_new_body_len: usize,
    max_new_predicate_terms: usize,
    step_iterations: usize,
    clause_weight_cutoff_coeff: f64,
    num_clauses_to_add: usize,
    default_clause_weight: T::Dual,
}

impl<R, T> Refiner<R, T> where R: rand::Rng, T: TruthValue {
    pub fn new(rng: R, facts: FactTable<T>, program: Program<T>, samples: Vec<(FactTable<T>, FactTable<T>)>) -> Self {
        let mut default_clause_weight = T::dual_zero();
        T::dual_adjust(&mut default_clause_weight, &T::dual_default(), 0.5);
        Refiner {
            generator: Generator::new(rng, &facts, &program),
            base_facts: facts,
            program: program,
            samples: samples,
            gradient_iterations: 10,
            learning_rate: 0.5,
            max_new_body_len: 8,
            max_new_predicate_terms: 8,
            step_iterations: 100,
            clause_weight_cutoff_coeff: 1.0,
            num_clauses_to_add: 5,
            default_clause_weight: default_clause_weight,
        }
    }

    pub fn fit_weights(&mut self) {
        for _ in 0..self.gradient_iterations {
            let res = compute_adjustments(&self.program, &self.base_facts, &self.samples, self.step_iterations);
            for (clause_idx, adjustment) in res.clause_adjustments.iter().enumerate() {
                T::dual_adjust(&mut self.program.clause_weights[clause_idx], adjustment, self.learning_rate);
            }
        }
    }

    pub fn add_clauses(&mut self) {
        let mut result_facts = self.base_facts.clone();
        evaluate_bottom_up(&mut result_facts, &self.program);
        self.generator.update_max_constant(&result_facts);
        self.generator.update_num_terms(&self.program);
        for _ in 0..self.num_clauses_to_add {
            self.program.push_clause(self.generator.gen_clause(self.max_new_body_len,
                                                               self.max_new_predicate_terms),
                                                               self.default_clause_weight.clone(),
                                                               NameTable::new()).unwrap();
        }
    }

    pub fn reduce_clauses(&mut self) {
        let num_weights = self.program.clause_weights.len();
        let amount_per_weight = 1f64 / num_weights as f64;
        let mut mean_weight = T::dual_zero();
        for weight in self.program.clause_weights.iter() {
            T::dual_adjust(&mut mean_weight, weight, amount_per_weight);
        }
        let mut program = Program::new();
        swap(&mut program, &mut self.program);
        self.program.predicate_names = program.predicate_names.clone();
        let clauses = program.clauses;
        let weights = program.clause_weights;
        for (clause_idx, (clause, weight)) in clauses.into_iter().zip(weights).enumerate() {
            if T::dual_less(&mean_weight, &weight, self.clause_weight_cutoff_coeff) {
                let clause_var_names = program.clause_variable_names.remove(&clause_idx).unwrap_or_else(|| NameTable::new());
                self.program.push_clause(clause, weight, clause_var_names).unwrap();
            }
        }
        for &(ref input, ref output) in &self.samples {
            self.program.check_num_fact_terms(input).unwrap();
            self.program.check_num_fact_terms(output).unwrap();
        }
        self.program.check_num_fact_terms(&self.base_facts).unwrap();
    }

    pub fn iterate(&mut self, iterations: usize) {
        for _ in 0..iterations {
            self.add_clauses();
            self.fit_weights();
            self.reduce_clauses();
        }
    }

    #[cfg(test)]
    pub fn get_program(&self) -> &Program<T> {
        &self.program
    }

    pub fn to_program(self) -> Program<T> {
        self.program
    }
}

#[cfg(test)]
mod tests {
    use super::{Refiner};
    use parser::{program};
    use rand::XorShiftRng;
    use rand::SeedableRng;
    use truth_value::MaxFloat64;

    #[test]
    fn can_refine_single_clause() {
        let rng = XorShiftRng::from_seed([0xde, 0xad, 0xbe, 0xef]);
        let (facts, program, samples) = program::<MaxFloat64>(r#"
        types(0) :- a(0), b(0)
        sample
            b(1)
        output
            a(1).
        "#).unwrap().0;
        let mut refiner = Refiner::new(rng, facts, program, samples);
        refiner.iterate(10);
        println!("program = {}", refiner.get_program());
    }

    #[test]
    fn can_refine_conjunction() {
        let rng = XorShiftRng::from_seed([0xde, 0xad, 0xbe, 0xef]);
        let (facts, program, samples) = program::<MaxFloat64>(r#"
        types(0) :- a(0), b(0), c(0)
        sample
            b(1),
            c(1)
        output
            a(1).
        sample
            b(2),
            c(2)
        output
            a(2).
        sample
            b(3),
            c(3)
        output
            a(3).
        sample
            b(2),
            c(3)
        output
            types(0).
        "#).unwrap().0;
        let mut refiner = Refiner::new(rng, facts, program, samples);
        refiner.iterate(1);
        println!("program = {}", refiner.get_program());
    }
}
<|endoftext|>


<commit_before><commit_msg>style<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #30465 - androm3da:master, r=alexcrichton<commit_after><|endoftext|>


<commit_before><commit_msg>Don't draw title in new tabbed/stacked containers<commit_after><|endoftext|>


<commit_before><commit_msg>[No-auto] lib/entry/category: Fix Clippy warnings<commit_after><|endoftext|>