<commit_before>use std::io::Read;
use std::sync::{Once, ONCE_INIT};

use failure::Error;
use serde_json::{Map, Value};

/// Maximum number of bytes that can be allocated when decoding
/// Avro-encoded values. This is a protection against ill-formed
/// data, whose length field might be interpreted as enourmous.
/// See max_allocation_bytes to change this limit.
pub static mut MAX_ALLOCATION_BYTES: usize = 512 * 1024 * 1024;
static MAX_ALLOCATION_BYTES_ONCE: Once = ONCE_INIT;

/// Describes errors happened trying to allocate too many bytes
#[derive(Fail, Debug)]
#[fail(display = "Allocation error: {}", _0)]
pub struct AllocationError(String);

impl AllocationError {
    pub fn new<S>(msg: S) -> AllocationError
    where
        S: Into<String>,
    {
        AllocationError(msg.into())
    }
}

/// Describes errors happened while decoding Avro data.
#[derive(Fail, Debug)]
#[fail(display = "Decoding error: {}", _0)]
pub struct DecodeError(String);

impl DecodeError {
    pub fn new<S>(msg: S) -> DecodeError
    where
        S: Into<String>,
    {
        DecodeError(msg.into())
    }
}

pub trait MapHelper {
    fn string(&self, key: &str) -> Option<String>;

    fn name(&self) -> Option<String> {
        self.string("name")
    }

    fn doc(&self) -> Option<String> {
        self.string("doc")
    }
}

impl MapHelper for Map<String, Value> {
    fn string(&self, key: &str) -> Option<String> {
        self.get(key)
            .and_then(|v| v.as_str())
            .map(|v| v.to_string())
    }
}

pub fn read_long<R: Read>(reader: &mut R) -> Result<i64, Error> {
    zag_i64(reader)
}

pub fn zig_i32(n: i32, buffer: &mut Vec<u8>) {
    zig_i64(n as i64, buffer)
}

pub fn zig_i64(n: i64, buffer: &mut Vec<u8>) {
    encode_variable((n << 1) ^ (n >> 63), buffer)
}

pub fn zag_i32<R: Read>(reader: &mut R) -> Result<i32, Error> {
    let i = zag_i64(reader)?;
    if i < i64::from(i32::min_value()) || i > i64::from(i32::max_value()) {
        Err(DecodeError::new("int out of range").into())
    } else {
        Ok(i as i32)
    }
}

pub fn zag_i64<R: Read>(reader: &mut R) -> Result<i64, Error> {
    let z = decode_variable(reader)?;
    Ok(if z & 0x1 == 0 {
        (z >> 1) as i64
    } else {
        !(z >> 1) as i64
    })
}

fn encode_variable(mut z: i64, buffer: &mut Vec<u8>) {
    loop {
        if z <= 0x7F {
            buffer.push((z & 0x7F) as u8);
            break
        } else {
            buffer.push((0x80 | (z & 0x7F)) as u8);
            z >>= 7;
        }
    }
}

fn decode_variable<R: Read>(reader: &mut R) -> Result<u64, Error> {
    let mut i = 0u64;
    let mut buf = [0u8; 1];

    let mut j = 0;
    loop {
        if j > 9 {
            // if j * 7 > 64
            return Err(DecodeError::new("Overflow when decoding integer value").into())
        }
        reader.read_exact(&mut buf[..])?;
        i |= (u64::from(buf[0] & 0x7F)) << (j * 7);
        if (buf[0] >> 7) == 0 {
            break
        } else {
            j += 1;
        }
    }

    Ok(i)
}

/// Set a new maximum number of bytes that can be allocated when decoding data.
/// Once called, the limit cannot be changed.
///
/// **NOTE** This function must be called before decoding **any** data. The
/// library leverages [`std::sync::Once`](https://doc.rust-lang.org/std/sync/struct.Once.html)
/// to set the limit either when calling this method, or when decoding for
/// the first time.
pub fn max_allocation_bytes(num_bytes: usize) -> usize {
    unsafe {
        MAX_ALLOCATION_BYTES_ONCE.call_once(|| {
            MAX_ALLOCATION_BYTES = num_bytes;
        });
        MAX_ALLOCATION_BYTES
    }
}

pub fn safe_len(len: usize) -> Result<usize, Error> {
    let max_bytes = max_allocation_bytes(512 * 1024 * 1024);

    if len <= max_bytes {
        Ok(len)
    } else {
        Err(AllocationError::new(format!(
            "Unable to allocate {} bytes (Maximum allowed: {})",
            len, max_bytes
        )).into())
    }
}

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

    #[test]
    fn test_zigzag() {
        let mut a = Vec::new();
        let mut b = Vec::new();
        zig_i32(42i32, &mut a);
        zig_i64(42i64, &mut b);
        assert_eq!(a, b);
    }

    #[test]
    fn test_zig_i64() {
        let mut s = Vec::new();
        zig_i64(2147483647i64, &mut s);
        assert_eq!(s, [254, 255, 255, 255, 15]);

        s.clear();
        zig_i64(2147483648i64, &mut s);
        assert_eq!(s, [128, 128, 128, 128, 16]);

        s.clear();
        zig_i64(-2147483648i64, &mut s);
        assert_eq!(s, [255, 255, 255, 255, 15]);

        s.clear();
        zig_i64(-2147483649i64, &mut s);
        assert_eq!(s, [129, 128, 128, 128, 16]);
    }

    #[test]
    fn test_zig_i32() {
        let mut s = Vec::new();
        zig_i32(1073741823i32, &mut s);
        assert_eq!(s, [254, 255, 255, 255, 7]);

        s.clear();
        zig_i32(-1073741824i32, &mut s);
        assert_eq!(s, [255, 255, 255, 255, 7]);

        s.clear();
        zig_i32(1073741824i32, &mut s);
        assert_eq!(s, [128, 128, 128, 128, 8]);

        s.clear();
        zig_i32(-1073741825i32, &mut s);
        assert_eq!(s, [129, 128, 128, 128, 8]);

        s.clear();
        zig_i32(2147483647i32, &mut s);
        assert_eq!(s, [254, 255, 255, 255, 15]);

        s.clear();
        zig_i32(-2147483648i32, &mut s);
        assert_eq!(s, [255, 255, 255, 255, 15]);
    }

    #[test]
    fn test_overflow() {
        let causes_left_shift_overflow: &[u8] = &[0xe1, 0xe1, 0xe1, 0xe1, 0xe1];
        assert!(decode_variable(&mut &causes_left_shift_overflow[..]).is_err());
    }

    #[test]
    fn test_safe_len() {
        assert_eq!(42usize, safe_len(42usize).unwrap());
        assert!(safe_len(1024 * 1024 * 1024).is_err());
    }
}
<commit_msg>Fix variable-length encoding for big i64 numbers<commit_after>use std::io::Read;
use std::sync::{Once, ONCE_INIT};
use std::i64;

use failure::Error;
use serde_json::{Map, Value};

/// Maximum number of bytes that can be allocated when decoding
/// Avro-encoded values. This is a protection against ill-formed
/// data, whose length field might be interpreted as enourmous.
/// See max_allocation_bytes to change this limit.
pub static mut MAX_ALLOCATION_BYTES: usize = 512 * 1024 * 1024;
static MAX_ALLOCATION_BYTES_ONCE: Once = ONCE_INIT;

/// Describes errors happened trying to allocate too many bytes
#[derive(Fail, Debug)]
#[fail(display = "Allocation error: {}", _0)]
pub struct AllocationError(String);

impl AllocationError {
    pub fn new<S>(msg: S) -> AllocationError
    where
        S: Into<String>,
    {
        AllocationError(msg.into())
    }
}

/// Describes errors happened while decoding Avro data.
#[derive(Fail, Debug)]
#[fail(display = "Decoding error: {}", _0)]
pub struct DecodeError(String);

impl DecodeError {
    pub fn new<S>(msg: S) -> DecodeError
    where
        S: Into<String>,
    {
        DecodeError(msg.into())
    }
}

pub trait MapHelper {
    fn string(&self, key: &str) -> Option<String>;

    fn name(&self) -> Option<String> {
        self.string("name")
    }

    fn doc(&self) -> Option<String> {
        self.string("doc")
    }
}

impl MapHelper for Map<String, Value> {
    fn string(&self, key: &str) -> Option<String> {
        self.get(key)
            .and_then(|v| v.as_str())
            .map(|v| v.to_string())
    }
}

pub fn read_long<R: Read>(reader: &mut R) -> Result<i64, Error> {
    zag_i64(reader)
}

pub fn zig_i32(n: i32, buffer: &mut Vec<u8>) {
    zig_i64(n as i64, buffer)
}

pub fn zig_i64(n: i64, buffer: &mut Vec<u8>) {
    encode_variable(((n << 1) ^ (n >> 63)) as u64, buffer)
}

pub fn zag_i32<R: Read>(reader: &mut R) -> Result<i32, Error> {
    let i = zag_i64(reader)?;
    if i < i64::from(i32::min_value()) || i > i64::from(i32::max_value()) {
        Err(DecodeError::new("int out of range").into())
    } else {
        Ok(i as i32)
    }
}

pub fn zag_i64<R: Read>(reader: &mut R) -> Result<i64, Error> {
    let z = decode_variable(reader)?;
    Ok(if z & 0x1 == 0 {
        (z >> 1) as i64
    } else {
        !(z >> 1) as i64
    })
}

fn encode_variable(mut z: u64, buffer: &mut Vec<u8>) {
    loop {
        if z <= 0x7F {
            buffer.push((z & 0x7F) as u8);
            break
        } else {
            buffer.push((0x80 | (z & 0x7F)) as u8);
            z >>= 7;
        }
    }
}

fn decode_variable<R: Read>(reader: &mut R) -> Result<u64, Error> {
    let mut i = 0u64;
    let mut buf = [0u8; 1];

    let mut j = 0;
    loop {
        if j > 9 {
            // if j * 7 > 64
            return Err(DecodeError::new("Overflow when decoding integer value").into())
        }
        reader.read_exact(&mut buf[..])?;
        i |= (u64::from(buf[0] & 0x7F)) << (j * 7);
        if (buf[0] >> 7) == 0 {
            break
        } else {
            j += 1;
        }
    }

    Ok(i)
}

/// Set a new maximum number of bytes that can be allocated when decoding data.
/// Once called, the limit cannot be changed.
///
/// **NOTE** This function must be called before decoding **any** data. The
/// library leverages [`std::sync::Once`](https://doc.rust-lang.org/std/sync/struct.Once.html)
/// to set the limit either when calling this method, or when decoding for
/// the first time.
pub fn max_allocation_bytes(num_bytes: usize) -> usize {
    unsafe {
        MAX_ALLOCATION_BYTES_ONCE.call_once(|| {
            MAX_ALLOCATION_BYTES = num_bytes;
        });
        MAX_ALLOCATION_BYTES
    }
}

pub fn safe_len(len: usize) -> Result<usize, Error> {
    let max_bytes = max_allocation_bytes(512 * 1024 * 1024);

    if len <= max_bytes {
        Ok(len)
    } else {
        Err(AllocationError::new(format!(
            "Unable to allocate {} bytes (Maximum allowed: {})",
            len, max_bytes
        )).into())
    }
}

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

    #[test]
    fn test_zigzag() {
        let mut a = Vec::new();
        let mut b = Vec::new();
        zig_i32(42i32, &mut a);
        zig_i64(42i64, &mut b);
        assert_eq!(a, b);
    }

    #[test]
    fn test_zig_i64() {
        let mut s = Vec::new();
        zig_i64(2147483647i64, &mut s);
        assert_eq!(s, [254, 255, 255, 255, 15]);

        s.clear();
        zig_i64(2147483648i64, &mut s);
        assert_eq!(s, [128, 128, 128, 128, 16]);

        s.clear();
        zig_i64(-2147483648i64, &mut s);
        assert_eq!(s, [255, 255, 255, 255, 15]);

        s.clear();
        zig_i64(-2147483649i64, &mut s);
        assert_eq!(s, [129, 128, 128, 128, 16]);

        s.clear();
        zig_i64(i64::MAX, &mut s);
        assert_eq!(s, [254, 255, 255, 255, 255, 255, 255, 255, 255, 1]);

        s.clear();
        zig_i64(i64::MIN, &mut s);
        assert_eq!(s, [255, 255, 255, 255, 255, 255, 255, 255, 255, 1]);
    }

    #[test]
    fn test_zig_i32() {
        let mut s = Vec::new();
        zig_i32(1073741823i32, &mut s);
        assert_eq!(s, [254, 255, 255, 255, 7]);

        s.clear();
        zig_i32(-1073741824i32, &mut s);
        assert_eq!(s, [255, 255, 255, 255, 7]);

        s.clear();
        zig_i32(1073741824i32, &mut s);
        assert_eq!(s, [128, 128, 128, 128, 8]);

        s.clear();
        zig_i32(-1073741825i32, &mut s);
        assert_eq!(s, [129, 128, 128, 128, 8]);

        s.clear();
        zig_i32(2147483647i32, &mut s);
        assert_eq!(s, [254, 255, 255, 255, 15]);

        s.clear();
        zig_i32(-2147483648i32, &mut s);
        assert_eq!(s, [255, 255, 255, 255, 15]);
    }

    #[test]
    fn test_overflow() {
        let causes_left_shift_overflow: &[u8] = &[0xe1, 0xe1, 0xe1, 0xe1, 0xe1];
        assert!(decode_variable(&mut &causes_left_shift_overflow[..]).is_err());
    }

    #[test]
    fn test_safe_len() {
        assert_eq!(42usize, safe_len(42usize).unwrap());
        assert!(safe_len(1024 * 1024 * 1024).is_err());
    }
}
<|endoftext|>


<commit_before>extern crate glm;

use sdl2::EventPump as SdlEventPump;
use sdl2::mouse::MouseButton;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use std::collections::HashSet;

pub trait EventPump {
    fn poll_event(&mut self) -> Option<Event>;
}

impl EventPump for SdlEventPump {
    fn poll_event(&mut self) -> Option<Event> {
        self.poll_event()
    }
}

pub struct InputManager<P> {
    pressed_keys: HashSet<Keycode>,
    pressed_buttons: HashSet<MouseButton>,
    prev_pressed_keys: HashSet<Keycode>,
    prev_pressed_buttons: HashSet<MouseButton>,
    mouse_coords: glm::IVec2,
    event_pump: P,
}

impl<P: EventPump> InputManager<P> {
    pub fn new(events_generator: P) -> InputManager<P> {
        InputManager {
            pressed_keys: HashSet::new(),
            pressed_buttons: HashSet::new(),
            prev_pressed_keys: HashSet::new(),
            prev_pressed_buttons: HashSet::new(),
            mouse_coords: glm::ivec2(0, 0),
            event_pump: events_generator,
        }
    }

    pub fn update(&mut self) -> bool {
        self.prev_pressed_keys = self.pressed_keys.clone();
        self.prev_pressed_buttons = self.pressed_buttons.clone();

        while let Some(event) = self.event_pump.poll_event() {
            if let Event::Quit { .. } = event {
                return false;
            }
            self.process_event(event)
        }
        true
    }

    pub fn is_key_down(&self, keycode: Keycode) -> bool {
        self.pressed_keys.contains(&keycode)
    }

    pub fn did_press_key(&self, keycode: Keycode) -> bool {
        self.pressed_keys.contains(&keycode) && !self.prev_pressed_keys.contains(&keycode)
    }

    pub fn did_click_mouse(&self, mouse_button: MouseButton) -> bool {
        self.pressed_buttons.contains(&mouse_button) &&
        !self.prev_pressed_buttons.contains(&mouse_button)
    }

    pub fn did_release_mouse(&self, mouse_button: MouseButton) -> bool {
        !self.pressed_buttons.contains(&mouse_button) &&
        self.prev_pressed_buttons.contains(&mouse_button)
    }

    pub fn is_mouse_down(&self, mouse_button: MouseButton) -> bool {
        self.pressed_buttons.contains(&mouse_button)
    }

    pub fn mouse_coords(&self) -> glm::IVec2 {
        self.mouse_coords
    }

    fn process_event(&mut self, event: Event) {
        match event {
            Event::KeyDown { keycode: Some(keycode), .. } => {
                self.pressed_keys.insert(keycode);
            }
            Event::KeyUp { keycode: Some(keycode), .. } => {
                self.pressed_keys.remove(&keycode);
            }
            Event::MouseMotion { x, y, .. } => {
                self.mouse_coords = glm::ivec2(x, y);
            }
            Event::MouseButtonDown { mouse_btn, .. } => {
                self.pressed_buttons.insert(mouse_btn);
            }
            Event::MouseButtonUp { mouse_btn, .. } => {
                self.pressed_buttons.remove(&mouse_btn);
            }
            _ => {}
        }
    }
}
<commit_msg>convert event pump to iterator<commit_after>extern crate glm;

use sdl2::EventPump as SdlEventPump;
use sdl2::mouse::MouseButton;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use std::collections::HashSet;

struct EventGenerator<E: EventPump> {
    event_pump: E,
}

impl<E: EventPump> EventGenerator<E> {
    fn new(event_pump: E) -> Self {
        EventGenerator { event_pump: event_pump }
    }

    fn iter(&mut self) -> EventIterator<E> {
        EventIterator { event_pump: &mut self.event_pump }
    }
}

struct EventIterator<'a, E: EventPump + 'a> {
    event_pump: &'a mut E,
}

impl<'a, E: EventPump> Iterator for EventIterator<'a, E> {
    type Item = Event;

    fn next(&mut self) -> Option<Event> {
        self.event_pump.poll_event()
    }
}

pub trait EventPump {
    fn poll_event(&mut self) -> Option<Event>;
}

impl EventPump for SdlEventPump {
    fn poll_event(&mut self) -> Option<Event> {
        self.poll_event()
    }
}

pub struct InputManager<P: EventPump> {
    pressed_keys: HashSet<Keycode>,
    pressed_buttons: HashSet<MouseButton>,
    prev_pressed_keys: HashSet<Keycode>,
    prev_pressed_buttons: HashSet<MouseButton>,
    mouse_coords: glm::IVec2,
    event_generator: EventGenerator<P>,
}

impl<P: EventPump> InputManager<P> {
    pub fn new(event_pump: P) -> InputManager<P> {
        InputManager {
            pressed_keys: HashSet::new(),
            pressed_buttons: HashSet::new(),
            prev_pressed_keys: HashSet::new(),
            prev_pressed_buttons: HashSet::new(),
            mouse_coords: glm::ivec2(0, 0),
            event_generator: EventGenerator::new(event_pump),
        }
    }

    pub fn update(&mut self) -> bool {
        self.prev_pressed_keys = self.pressed_keys.clone();
        self.prev_pressed_buttons = self.pressed_buttons.clone();

        for event in self.event_generator.iter() {
            match event {
                Event::Quit { .. } => return false,
                Event::KeyDown { keycode: Some(keycode), .. } => {
                    self.pressed_keys.insert(keycode);
                }
                Event::KeyUp { keycode: Some(keycode), .. } => {
                    self.pressed_keys.remove(&keycode);
                }
                Event::MouseMotion { x, y, .. } => {
                    self.mouse_coords = glm::ivec2(x, y);
                }
                Event::MouseButtonDown { mouse_btn, .. } => {
                    self.pressed_buttons.insert(mouse_btn);
                }
                Event::MouseButtonUp { mouse_btn, .. } => {
                    self.pressed_buttons.remove(&mouse_btn);
                }
                _ => {}
            }
        }

        true
    }

    pub fn is_key_down(&self, keycode: Keycode) -> bool {
        self.pressed_keys.contains(&keycode)
    }

    pub fn did_press_key(&self, keycode: Keycode) -> bool {
        self.pressed_keys.contains(&keycode) && !self.prev_pressed_keys.contains(&keycode)
    }

    pub fn did_click_mouse(&self, mouse_button: MouseButton) -> bool {
        self.pressed_buttons.contains(&mouse_button) &&
        !self.prev_pressed_buttons.contains(&mouse_button)
    }

    pub fn did_release_mouse(&self, mouse_button: MouseButton) -> bool {
        !self.pressed_buttons.contains(&mouse_button) &&
        self.prev_pressed_buttons.contains(&mouse_button)
    }

    pub fn is_mouse_down(&self, mouse_button: MouseButton) -> bool {
        self.pressed_buttons.contains(&mouse_button)
    }

    pub fn mouse_coords(&self) -> glm::IVec2 {
        self.mouse_coords
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Mathias Hällman
 *
 * 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/.
 */

extern crate unicode_width;

use self::unicode_width::UnicodeWidthChar as CharWidth;

use buffer;
use caret;
use screen;

const MIN_VIEW_SIZE: u16 = 1;

/*
 * View handles the presentation of a buffer.
 * Everything is measured in screen cell coordinates.
 */
#[derive(Clone, Copy)]
pub struct View {
  scroll_line: usize,
  scroll_column: usize,
  size: screen::Size,
}

impl View {
  pub fn new() -> View {
    View {
      scroll_line: 0,
      scroll_column: 0,
      size: screen::Size(MIN_VIEW_SIZE, MIN_VIEW_SIZE),
    }
  }

  pub fn scroll_line(&self) -> usize {
    self.scroll_line
  }

  pub fn scroll_column(&self) -> usize {
    self.scroll_column
  }

  // assumes caret is in view
  pub fn caret_position(&self, caret: caret::Caret, buffer: &buffer::Buffer)
      -> screen::Cell {
    let caret_row = (caret.line() - self.scroll_line) as u16;
    let caret_column = caret::buffer_to_screen_column(
      caret.line(), caret.column(), buffer) - self.scroll_column;
    screen::Cell(caret_row, caret_column as u16)
  }

  pub fn set_scroll(&mut self, line: usize, column: usize) {
    self.scroll_line = line;
    self.scroll_column = column;
  }

  pub fn scroll_into_view(&mut self, caret: caret::Caret,
                          buffer: &buffer::Buffer) {
    let (line, column) = (caret.line(), caret.column());
    let screen::Size(rows, cols) = self.size;
    let rows = rows as usize;
    let cols = cols as usize;

    self.scroll_line =
      if line < self.scroll_line { line }
      else if line >= self.scroll_line + rows { line - rows + 1 }
      else { self.scroll_line };

    // make sure wider characters are scrolled in entirely as well
    let character = buffer.get_char_by_line_column(line, column).unwrap();
    let start = caret::buffer_to_screen_column(line, column, buffer);
    let end = start + CharWidth::width(character).unwrap_or(1) - 1;
    self.scroll_column =
      if start < self.scroll_column { start }
      else if end >= self.scroll_column + cols { end - cols + 1 }
      else { self.scroll_column };
  }

  pub fn set_size(&mut self, size: screen::Size) {
    let screen::Size(rows, cols) = size;
    assert!(rows >= MIN_VIEW_SIZE && cols >= MIN_VIEW_SIZE);
    self.size = size;
  }

  #[cfg(not(test))]
  pub fn draw(&self, buffer: &buffer::Buffer, caret: caret::Caret,
              focused: bool, position: screen::Cell,
              screen: &mut screen::Screen) {
    use std::cmp;
    // calculate caret screen position if focused
    let caret_cell =
      if focused { Some(position + self.caret_position(caret, buffer)) }
      else       { None };

    // helper to put a character on the screen
    let put = |character, cell: screen::Cell, screen: &mut screen::Screen| {
      use screen::Color::*;
      let highlight = caret_cell.map(|c| c != cell).unwrap_or(false);
      let (fg, bg) = if highlight { (Black, White) } else { (White, Black) };
      screen.put(cell, character, fg, bg);
    };

    let screen::Size(rows, cols) = self.size;
    // draw line by line
    let mut row: u16 = 0;
    for chars in buffer.line_iter().from(self.scroll_line).take(rows as usize) {
      let line_offset = screen::Cell(row, 0) + position;
      // draw character by character
      let mut col = -(self.scroll_column as isize);
      for character in chars {
        if col >= cols as isize || character == '\n' { break }
        let char_width = CharWidth::width(character).unwrap_or(0) as isize;
        let end_col = col + char_width;
        if (col < 0 && end_col >= 0) || end_col > cols as isize {
          // blank out partially visible characters
          for col in cmp::max(0, col)..cmp::min(end_col, cols as isize) {
            put(' ', line_offset + screen::Cell(0, col as u16), screen);
          }
        }
        else if col >= 0 {
          put(character, line_offset + screen::Cell(0, col as u16), screen);
        }
        col += char_width;
      }
      // blank out the rest of the row if the line didn't fill it
      for col in cmp::max(0, col) as u16..cols {
        put(' ', line_offset + screen::Cell(0, col), screen);
      }
      row += 1;
    }
    // fill in the rest of the view below the buffer content
    for row in row..rows {
      let line_offset = screen::Cell(row, 0) + position;
      put(if self.scroll_column == 0 { '~' } else { ' ' }, line_offset, screen);
      for col in 1..cols {
        put(' ', line_offset + screen::Cell(0, col), screen);
      }
    }
  }
}

#[cfg(test)]
mod test {
  use std::path::Path;

  use buffer;
  use caret;
  use screen;

  #[test]
  fn scroll_into_view_double_width() {
    let mut caret = caret::Caret::new();
    let buffer = buffer::Buffer::open(
      &Path::new("tests/view/scroll_into_view_double_width.txt")).unwrap();
    let mut view = super::View::new();
    view.set_size(screen::Size(1, 15));
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 0);
    caret.adjust(caret::Adjustment::Set(0, 12), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 3);
    caret.adjust(caret::Adjustment::Set(0, 16), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 9);
    caret.adjust(caret::Adjustment::Set(0, 3), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 6);
    caret.adjust(caret::Adjustment::Set(3, 10), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 3); assert_eq!(view.scroll_column(), 6);
  }

  #[test]
  fn caret_position() {
    let mut caret = caret::Caret::new();
    let buffer = buffer::Buffer::open(
      &Path::new("tests/view/caret_position.txt")).unwrap();
    let mut view = super::View::new();
    view.set_scroll(1, 1);
    caret.adjust(caret::Adjustment::Set(1, 1), &buffer);
    assert_eq!(view.caret_position(caret, &buffer), screen::Cell(0, 1));
    caret.adjust(caret::Adjustment::Set(2, 1), &buffer);
    assert_eq!(view.caret_position(caret, &buffer), screen::Cell(1, 0));
  }
}
<commit_msg>Don't expect the caret to be valid when scrolling it into view<commit_after>/*
 * Copyright (c) 2015 Mathias Hällman
 *
 * 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/.
 */

extern crate unicode_width;

use self::unicode_width::UnicodeWidthChar as CharWidth;

use buffer;
use caret;
use screen;

const MIN_VIEW_SIZE: u16 = 1;

/*
 * View handles the presentation of a buffer.
 * Everything is measured in screen cell coordinates.
 */
#[derive(Clone, Copy)]
pub struct View {
  scroll_line: usize,
  scroll_column: usize,
  size: screen::Size,
}

impl View {
  pub fn new() -> View {
    View {
      scroll_line: 0,
      scroll_column: 0,
      size: screen::Size(MIN_VIEW_SIZE, MIN_VIEW_SIZE),
    }
  }

  pub fn scroll_line(&self) -> usize {
    self.scroll_line
  }

  pub fn scroll_column(&self) -> usize {
    self.scroll_column
  }

  // assumes caret is in view
  pub fn caret_position(&self, caret: caret::Caret, buffer: &buffer::Buffer)
      -> screen::Cell {
    let caret_row = (caret.line() - self.scroll_line) as u16;
    let caret_column = caret::buffer_to_screen_column(
      caret.line(), caret.column(), buffer) - self.scroll_column;
    screen::Cell(caret_row, caret_column as u16)
  }

  pub fn set_scroll(&mut self, line: usize, column: usize) {
    self.scroll_line = line;
    self.scroll_column = column;
  }

  pub fn scroll_into_view(&mut self, caret: caret::Caret,
                          buffer: &buffer::Buffer) {
    let (line, column) = (caret.line(), caret.column());
    let screen::Size(rows, cols) = self.size;
    let rows = rows as usize;
    let cols = cols as usize;

    self.scroll_line =
      if line < self.scroll_line { line }
      else if line >= self.scroll_line + rows { line - rows + 1 }
      else { self.scroll_line };

    // make sure wider characters are scrolled in entirely as well
    let start = caret::buffer_to_screen_column(line, column, buffer);
    let end = start + buffer.get_char_by_line_column(line, column).and_then(|c|
      CharWidth::width(c)).unwrap_or(1) - 1;
    self.scroll_column =
      if start < self.scroll_column { start }
      else if end >= self.scroll_column + cols { end - cols + 1 }
      else { self.scroll_column };
  }

  pub fn set_size(&mut self, size: screen::Size) {
    let screen::Size(rows, cols) = size;
    assert!(rows >= MIN_VIEW_SIZE && cols >= MIN_VIEW_SIZE);
    self.size = size;
  }

  #[cfg(not(test))]
  pub fn draw(&self, buffer: &buffer::Buffer, caret: caret::Caret,
              focused: bool, position: screen::Cell,
              screen: &mut screen::Screen) {
    use std::cmp;
    // calculate caret screen position if focused
    let caret_cell =
      if focused { Some(position + self.caret_position(caret, buffer)) }
      else       { None };

    // helper to put a character on the screen
    let put = |character, cell: screen::Cell, screen: &mut screen::Screen| {
      use screen::Color::*;
      let highlight = caret_cell.map(|c| c != cell).unwrap_or(false);
      let (fg, bg) = if highlight { (Black, White) } else { (White, Black) };
      screen.put(cell, character, fg, bg);
    };

    let screen::Size(rows, cols) = self.size;
    // draw line by line
    let mut row: u16 = 0;
    for chars in buffer.line_iter().from(self.scroll_line).take(rows as usize) {
      let line_offset = screen::Cell(row, 0) + position;
      // draw character by character
      let mut col = -(self.scroll_column as isize);
      for character in chars {
        if col >= cols as isize || character == '\n' { break }
        let char_width = CharWidth::width(character).unwrap_or(0) as isize;
        let end_col = col + char_width;
        if (col < 0 && end_col >= 0) || end_col > cols as isize {
          // blank out partially visible characters
          for col in cmp::max(0, col)..cmp::min(end_col, cols as isize) {
            put(' ', line_offset + screen::Cell(0, col as u16), screen);
          }
        }
        else if col >= 0 {
          put(character, line_offset + screen::Cell(0, col as u16), screen);
        }
        col += char_width;
      }
      // blank out the rest of the row if the line didn't fill it
      for col in cmp::max(0, col) as u16..cols {
        put(' ', line_offset + screen::Cell(0, col), screen);
      }
      row += 1;
    }
    // fill in the rest of the view below the buffer content
    for row in row..rows {
      let line_offset = screen::Cell(row, 0) + position;
      put(if self.scroll_column == 0 { '~' } else { ' ' }, line_offset, screen);
      for col in 1..cols {
        put(' ', line_offset + screen::Cell(0, col), screen);
      }
    }
  }
}

#[cfg(test)]
mod test {
  use std::path::Path;

  use buffer;
  use caret;
  use screen;

  #[test]
  fn scroll_into_view_double_width() {
    let mut caret = caret::Caret::new();
    let buffer = buffer::Buffer::open(
      &Path::new("tests/view/scroll_into_view_double_width.txt")).unwrap();
    let mut view = super::View::new();
    view.set_size(screen::Size(1, 15));
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 0);
    caret.adjust(caret::Adjustment::Set(0, 12), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 3);
    caret.adjust(caret::Adjustment::Set(0, 16), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 9);
    caret.adjust(caret::Adjustment::Set(0, 3), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 0); assert_eq!(view.scroll_column(), 6);
    caret.adjust(caret::Adjustment::Set(3, 10), &buffer);
    view.scroll_into_view(caret, &buffer);
    assert_eq!(view.scroll_line(), 3); assert_eq!(view.scroll_column(), 6);
  }

  #[test]
  fn caret_position() {
    let mut caret = caret::Caret::new();
    let buffer = buffer::Buffer::open(
      &Path::new("tests/view/caret_position.txt")).unwrap();
    let mut view = super::View::new();
    view.set_scroll(1, 1);
    caret.adjust(caret::Adjustment::Set(1, 1), &buffer);
    assert_eq!(view.caret_position(caret, &buffer), screen::Cell(0, 1));
    caret.adjust(caret::Adjustment::Set(2, 1), &buffer);
    assert_eq!(view.caret_position(caret, &buffer), screen::Cell(1, 0));
  }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate time;
extern crate timely;
extern crate differential_dataflow;

use timely::dataflow::*;
use timely::dataflow::operators::*;
use timely::progress::timestamp::RootTimestamp;

use rand::{Rng, SeedableRng, StdRng};

use differential_dataflow::operators::*;
use differential_dataflow::collection::LeastUpperBound;

type Node = u32;
type Edge = (Node, Node);

fn main() {

    let nodes: u32 = std::env::args().nth(1).unwrap().parse().unwrap();
    let edges: u32 = std::env::args().nth(2).unwrap().parse().unwrap();
    let batch: u32 = std::env::args().nth(3).unwrap().parse().unwrap();

    // define a new computational scope, in which to run BFS
    timely::execute_from_args(std::env::args().skip(4), move |computation| {
        let start = time::precise_time_s();

        // define BFS dataflow; return handles to roots and edges inputs
        let (mut graph, probe) = computation.scoped(|scope| {

            let roots = vec![(0,1)].into_iter().to_stream(scope);
            let (edge_input, graph) = scope.new_input();
            let probe = bfs(&graph, &roots).probe().0;

            (edge_input, probe)
        });

        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge deletions

        println!("performing BFS on {} nodes, {} edges:", nodes, edges);

        if computation.index() == 0 {
            // trickle edges in to dataflow
            for _ in 0..(edges/1000) {
                for _ in 0..1000 {
                    graph.send(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), 1));
                }
                computation.step();
            }
        }

        println!("loaded; elapsed: {}s", time::precise_time_s() - start);

        graph.advance_to(1);
        while probe.le(&RootTimestamp::new(0)) { computation.step(); }

        println!("stable; elapsed: {}s", time::precise_time_s() - start);

        let mut changes = Vec::new();
        for wave in 0.. {
            for _ in 0..batch {
                changes.push(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), 1));
                changes.push(((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)),-1));
            }

            let start = time::precise_time_s();
            let round = *graph.epoch();
            if computation.index() == 0 {
                while let Some(change) = changes.pop() {
                    graph.send(change);
                }
            }
            graph.advance_to(round + 1);

            while probe.le(&RootTimestamp::new(round)) { computation.step(); }

            if computation.index() == 0 {
                println!("wave {}: avg {}", wave, (time::precise_time_s() - start) / (batch as f64));
            }
        }
    });
}

// returns pairs (n, s) indicating node n can be reached from a root in s steps.
fn bfs<G: Scope>(edges: &Stream<G, (Edge, i32)>, roots: &Stream<G, (Node, i32)>) -> Stream<G, ((Node, u32), i32)>
where G::Timestamp: LeastUpperBound {

    // initialize roots as reaching themselves at distance 0
    let nodes = roots.map(|(x,w)| ((x, 0), w));
    // let edges = edges.map_in_place(|x| x.0 = ((x.0).1, (x.0).0))
    //                  .concat(&edges);

    // repeatedly update minimal distances each node can be reached from each root
    nodes.iterate(|inner| {

        let edges = inner.scope().enter(&edges);
        let nodes = inner.scope().enter(&nodes);

        inner.join_map_u(&edges, |_k,l,d| (*d, l+1))
             .concat(&nodes)
             .group_u(|_, s, t| t.push((*s.peek().unwrap().0, 1)))
     })
}
<commit_msg>tidying<commit_after>extern crate rand;
extern crate time;
extern crate timely;
extern crate differential_dataflow;

use timely::dataflow::*;
use timely::dataflow::operators::*;
use timely::progress::timestamp::RootTimestamp;

use rand::{Rng, SeedableRng, StdRng};

use differential_dataflow::operators::*;
use differential_dataflow::collection::LeastUpperBound;

type Node = u32;
type Edge = (Node, Node);

fn main() {

    let nodes: u32 = std::env::args().nth(1).unwrap().parse().unwrap();
    let edges: u32 = std::env::args().nth(2).unwrap().parse().unwrap();
    let batch: u32 = std::env::args().nth(3).unwrap().parse().unwrap();

    // define a new computational scope, in which to run BFS
    timely::execute_from_args(std::env::args().skip(4), move |computation| {
        let start = time::precise_time_s();

        // define BFS dataflow; return handles to roots and edges inputs
        let (mut graph, probe) = computation.scoped(|scope| {

            let roots = vec![(0,1)].into_iter().to_stream(scope);
            let (edge_input, graph) = scope.new_input();
            let probe = bfs(&graph, &roots).probe().0;

            (edge_input, probe)
        });

        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge deletions

        println!("performing BFS on {} nodes, {} edges:", nodes, edges);

        if computation.index() == 0 {
            // trickle edges in to dataflow
            for _ in 0..(edges/1000) {
                for _ in 0..1000 {
                    graph.send(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), 1));
                }
                computation.step();
            }
        }

        println!("loaded; elapsed: {}s", time::precise_time_s() - start);

        graph.advance_to(1);
        while probe.le(&RootTimestamp::new(0)) { computation.step(); }

        println!("stable; elapsed: {}s", time::precise_time_s() - start);

        let mut changes = Vec::new();
        for wave in 0.. {
            for _ in 0..batch {
                changes.push(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), 1));
                changes.push(((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)),-1));
            }

            let start = time::precise_time_s();
            let round = *graph.epoch();
            if computation.index() == 0 {
                while let Some(change) = changes.pop() {
                    graph.send(change);
                }
            }
            graph.advance_to(round + 1);

            while probe.le(&RootTimestamp::new(round)) { computation.step(); }

            if computation.index() == 0 {
                println!("wave {}: avg {}", wave, (time::precise_time_s() - start) / (batch as f64));
            }
        }
    });
}

// returns pairs (n, s) indicating node n can be reached from a root in s steps.
fn bfs<G: Scope>(edges: &Stream<G, (Edge, i32)>, roots: &Stream<G, (Node, i32)>) -> Stream<G, ((Node, u32), i32)>
where G::Timestamp: LeastUpperBound {

    // initialize roots as reaching themselves at distance 0
    let nodes = roots.map(|(x,w)| ((x, 0), w));

    // repeatedly update minimal distances each node can be reached from each root
    nodes.iterate(|inner| {

        let edges = inner.scope().enter(&edges);
        let nodes = inner.scope().enter(&nodes);

        inner.join_map(&edges, |_k,l,d| (*d, l+1))
             .concat(&nodes)
             .group(|_, s, t| t.push((*s.peek().unwrap().0, 1)))
     })
}
<|endoftext|>


<commit_before>// Translation of the following Go program into Rust:
//
// ```
// func main() {
//     people := []string{"Anna", "Bob", "Cody", "Dave", "Eva"}
//     match := make(chan string, 1) // Make room for one unmatched send.
//     wg := new(sync.WaitGroup)
//     for _, name := range people {
//         wg.Add(1)
//         go Seek(name, match, wg)
//     }
//     wg.Wait()
//     select {
//     case name := <-match:
//         fmt.Printf("No one received %s’s message.\n", name)
//     default:
//         // There was no pending send operation.
//     }
// }
//
// // Seek either sends or receives, whichever possible, a name on the match
// // channel and notifies the wait group when done.
// func Seek(name string, match chan string, wg *sync.WaitGroup) {
//     select {
//     case peer := <-match:
//         fmt.Printf("%s received a message from %s.\n", name, peer)
//     case match <- name:
//         // Wait for someone to receive my message.
//     }
//     wg.Done()
// }
// ```
//
// Source: https://www.nada.kth.se/~snilsson/concurrency/#Match

extern crate crossbeam;
extern crate channel;

use channel::{select, Receiver, Sender};

fn main() {
    let people = vec!["Anna", "Bob", "Cody", "Dave", "Eva"];
    let (tx, rx) = channel::bounded(1); // Make room for one unmatched send.
    let (tx, rx) = (&tx, &rx);

    crossbeam::scope(|s| for name in people {
        s.spawn(move || seek(name, tx, rx));
    });

    loop {
        if let Ok(peer) = rx.select() {
            println!("No one received {}’s message.", peer);
            break;
        }
        if select::blocked() {
            // There was no pending send operation.
            break;
        }
    }
}

// Either sends or receives, whichever possible, a name on the channel.
fn seek<'a>(name: &'a str, tx: &Sender<&'a str>, rx: &Receiver<&'a str>) {
    loop {
        if let Ok(peer) = rx.select() {
            println!("{} received a message from {}.", name, peer);
            break;
        }
        if let Ok(_) = tx.select(name) {
            // Wait for someone to receive my message.
            break;
        }
    }
}
<commit_msg>Use try_recv instead of select<commit_after>// Translation of the following Go program into Rust:
//
// ```
// func main() {
//     people := []string{"Anna", "Bob", "Cody", "Dave", "Eva"}
//     match := make(chan string, 1) // Make room for one unmatched send.
//     wg := new(sync.WaitGroup)
//     for _, name := range people {
//         wg.Add(1)
//         go Seek(name, match, wg)
//     }
//     wg.Wait()
//     select {
//     case name := <-match:
//         fmt.Printf("No one received %s’s message.\n", name)
//     default:
//         // There was no pending send operation.
//     }
// }
//
// // Seek either sends or receives, whichever possible, a name on the match
// // channel and notifies the wait group when done.
// func Seek(name string, match chan string, wg *sync.WaitGroup) {
//     select {
//     case peer := <-match:
//         fmt.Printf("%s received a message from %s.\n", name, peer)
//     case match <- name:
//         // Wait for someone to receive my message.
//     }
//     wg.Done()
// }
// ```
//
// Source: https://www.nada.kth.se/~snilsson/concurrency/#Match

extern crate crossbeam;
extern crate channel;

use channel::{select, Receiver, Sender};

fn main() {
    let people = vec!["Anna", "Bob", "Cody", "Dave", "Eva"];
    let (tx, rx) = channel::bounded(1); // Make room for one unmatched send.
    let (tx, rx) = (&tx, &rx);

    crossbeam::scope(|s| for name in people {
        s.spawn(move || seek(name, tx, rx));
    });

    if let Ok(peer) = rx.try_recv() {
        println!("No one received {}’s message.", peer);
    }
}

// Either sends or receives, whichever possible, a name on the channel.
fn seek<'a>(name: &'a str, tx: &Sender<&'a str>, rx: &Receiver<&'a str>) {
    loop {
        if let Ok(peer) = rx.select() {
            println!("{} received a message from {}.", name, peer);
            break;
        }
        if let Ok(_) = tx.select(name) {
            // Wait for someone to receive my message.
            break;
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::fmt::Write;

/// Defines whether a term in a query must be present,
/// should be present or must be not present.
#[derive(Debug, Clone, Hash, Copy, Eq, PartialEq)]
pub enum Occur {
    /// For a given document to be considered for scoring,
    /// at least one of the document with the Should or the Must
    /// Occur constraint must be within the document.
    Should,
    /// Document without the term are excluded from the search.
    Must,
    /// Document that contain the term are excluded from the
    /// search.
    MustNot,
}

impl Occur {
    /// Returns the one-char prefix symbol for this `Occur`.
    /// - `Should` => '?',
    /// - `Must` => '+'
    /// - `Not` => '-'
    fn to_char(self) -> char {
        match self {
            Occur::Should => '?',
            Occur::Must => '+',
            Occur::MustNot => '-',
        }
    }

    /// Compose two occur values.
    pub fn compose(left: Occur, right: Occur) -> Occur {
        match left {
            Occur::Should => right,
            Occur::Must => {
                if right == Occur::MustNot {
                    Occur::MustNot
                } else {
                    Occur::Must
                }
            }
            Occur::MustNot => {
                if right == Occur::MustNot {
                    Occur::Must
                } else {
                    Occur::MustNot
                }
            }
        }
    }
}

impl fmt::Display for Occur {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_char(self.to_char())
    }
}
<commit_msg>Update occur.rs (#862)<commit_after>use std::fmt;
use std::fmt::Write;

/// Defines whether a term in a query must be present,
/// should be present or must be not present.
#[derive(Debug, Clone, Hash, Copy, Eq, PartialEq)]
pub enum Occur {
    /// For a given document to be considered for scoring,
    /// at least one of the document with the Should or the Must
    /// Occur constraint must be within the document.
    Should,
    /// Document without the term are excluded from the search.
    Must,
    /// Document that contain the term are excluded from the
    /// search.
    MustNot,
}

impl Occur {
    /// Returns the one-char prefix symbol for this `Occur`.
    /// - `Should` => '?',
    /// - `Must` => '+'
    /// - `Not` => '-'
    fn to_char(self) -> char {
        match self {
            Occur::Should => '?',
            Occur::Must => '+',
            Occur::MustNot => '-',
        }
    }

    /// Compose two occur values.
    pub fn compose(left: Occur, right: Occur) -> Occur {
        match (left, right) {
            (Occur::Should, _) => { right }
            (Occur::Must, Occur::MustNot) => { Occur::MustNot }
            (Occur::Must, _) => { Occur::Must }
            (Occur::MustNot, Occur::MustNot) => { Occur::Must }
            (Occur::MustNot, _) => { Occur::MustNot }
        }
    }
}

impl fmt::Display for Occur {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_char(self.to_char())
    }
}

#[cfg(test)]
mod test {
    use crate::Occur;

    #[test]
    fn test_Occur_compose() {
        assert_eq!(Occur::compose(Occur::Should, Occur::Should), Occur::Should);
        assert_eq!(Occur::compose(Occur::Should, Occur::Must), Occur::Must);
        assert_eq!(Occur::compose(Occur::Should, Occur::MustNot), Occur::MustNot);
        assert_eq!(Occur::compose(Occur::Must, Occur::Should), Occur::Must);
        assert_eq!(Occur::compose(Occur::Must, Occur::Must), Occur::Must);
        assert_eq!(Occur::compose(Occur::Must, Occur::MustNot), Occur::MustNot);
        assert_eq!(Occur::compose(Occur::MustNot, Occur::Should), Occur::MustNot);
        assert_eq!(Occur::compose(Occur::MustNot, Occur::Must), Occur::MustNot);
        assert_eq!(Occur::compose(Occur::MustNot, Occur::MustNot), Occur::Must);
    }
}
<|endoftext|>


<commit_before>//! Scheduling primitives for Uni.rs.

use alloc::boxed::{Box, FnBox};

use intrusive::link::Link;
use intrusive::list::{Node, Owner};

use self::stack::Stack;
use self::context::Context;

mod stack;
mod context;
mod scheduler;

const DEFAULT_STACK_SIZE: usize = 8192;

pub struct Thread {
    t_impl: Box<ThreadImpl>,
}

impl Thread {
    pub fn spawn<F>(fun: F) -> Thread where F: Fn() -> () {
        Builder::new().spawn(fun)
    }
}

pub struct Builder {
    stack_size: usize,
}

impl Builder {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn stack_size(mut self, stack_size: usize) -> Builder {
        self.stack_size = stack_size;
        self
    }

    pub fn spawn<F>(self, fun: F) -> Thread where F: Fn() -> () {
        let thread_impl = Box::new(ThreadImpl::new(fun, self.stack_size));

        Thread {
            t_impl: thread_impl,
        }
    }
}

impl Default for Builder {
    fn default() -> Self {
        Builder {
            stack_size: DEFAULT_STACK_SIZE,
        }
    }
}

#[derive(PartialEq)]
enum State {
    Empty,
    Ready,
    Running,
    Blocked,
    Terminated,
}

struct ThreadImpl {
    context: Context,
    state: State,
    // On Drop stack is released
    #[allow(dead_code)]
    stack: Stack,
    prev: Link<ThreadImpl>,
    next: Link<ThreadImpl>,
}

impl ThreadImpl {
    pub unsafe fn empty() -> Self {
        ThreadImpl {
            context: Context::empty(),
            state: State::Empty,
            stack: Stack::null(),
            prev: Link::none(),
            next: Link::none(),
        }
    }

    pub fn new<F>(fun: F, stack_size: usize) -> Self where F: Fn() -> () {
        let mut stack = unsafe { Stack::new(stack_size) };

        if stack.is_null() {
            panic!("Cannot allocate a stack (size: {}) for a new thread",
                   stack_size);
        }

        ThreadImpl {
            context: unsafe { Context::new(thread_wrapper, fun, &mut stack) },
            state: State::Ready,
            stack: stack,
            prev: Link::none(),
            next: Link::none(),
        }
    }
}

extern "C" fn thread_wrapper(f: *mut u8) -> ! {
    {
        let boxed_fn: Box<Box<FnBox()>> = unsafe {
            Box::from_raw(f as *mut Box<FnBox()>)
        };

        boxed_fn();
    }

    unimplemented!();
}

impl Node for ThreadImpl {
    #[inline]
    fn prev(&self) -> &Link<Self> {
        &self.prev
    }

    #[inline]
    fn next(&self) -> &Link<Self> {
        &self.next
    }

    #[inline]
    fn prev_mut(&mut self) -> &mut Link<Self> {
        &mut self.prev
    }

    #[inline]
    fn next_mut(&mut self) -> &mut Link<Self> {
        &mut self.prev
    }
}

// This trait cannot be implemented for Box in libintrusive as it must not
// depend on rust's liballoc
type ThreadImplBox = Box<ThreadImpl>;

impl Owner<ThreadImpl> for ThreadImplBox {
    #[inline]
    fn get(&self) -> &ThreadImpl {
        &**self
    }

    #[inline]
    fn get_mut(&mut self) -> &mut ThreadImpl {
        &mut **self
    }

    #[inline]
    fn take(self) {
        Box::into_raw(self);
    }

    unsafe fn from_raw_ptr(ptr: *mut ThreadImpl) -> Self {
        Box::from_raw(ptr)
    }
}
<commit_msg>thread: Add ThreadImpl::yield_to()<commit_after>//! Scheduling primitives for Uni.rs.

use alloc::boxed::{Box, FnBox};

use intrusive::link::Link;
use intrusive::list::{Node, Owner};

use self::stack::Stack;
use self::context::Context;

mod stack;
mod context;
mod scheduler;

const DEFAULT_STACK_SIZE: usize = 8192;

pub struct Thread {
    t_impl: Box<ThreadImpl>,
}

impl Thread {
    pub fn spawn<F>(fun: F) -> Thread where F: Fn() -> () {
        Builder::new().spawn(fun)
    }
}

pub struct Builder {
    stack_size: usize,
}

impl Builder {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn stack_size(mut self, stack_size: usize) -> Builder {
        self.stack_size = stack_size;
        self
    }

    pub fn spawn<F>(self, fun: F) -> Thread where F: Fn() -> () {
        let thread_impl = Box::new(ThreadImpl::new(fun, self.stack_size));

        Thread {
            t_impl: thread_impl,
        }
    }
}

impl Default for Builder {
    fn default() -> Self {
        Builder {
            stack_size: DEFAULT_STACK_SIZE,
        }
    }
}

#[derive(PartialEq)]
enum State {
    Empty,
    Ready,
    Running,
    Blocked,
    Terminated,
}

struct ThreadImpl {
    context: Context,
    state: State,
    // On Drop stack is released
    #[allow(dead_code)]
    stack: Stack,
    prev: Link<ThreadImpl>,
    next: Link<ThreadImpl>,
}

impl ThreadImpl {
    pub unsafe fn empty() -> Self {
        ThreadImpl {
            context: Context::empty(),
            state: State::Empty,
            stack: Stack::null(),
            prev: Link::none(),
            next: Link::none(),
        }
    }

    pub fn new<F>(fun: F, stack_size: usize) -> Self where F: Fn() -> () {
        let mut stack = unsafe { Stack::new(stack_size) };

        if stack.is_null() {
            panic!("Cannot allocate a stack (size: {}) for a new thread",
                   stack_size);
        }

        ThreadImpl {
            context: unsafe { Context::new(thread_wrapper, fun, &mut stack) },
            state: State::Ready,
            stack: stack,
            prev: Link::none(),
            next: Link::none(),
        }
    }

    pub unsafe fn yield_to(&mut self, thread: &ThreadImpl) {
        thread.context.switch_with(&mut self.context);
    }
}

extern "C" fn thread_wrapper(f: *mut u8) -> ! {
    {
        let boxed_fn: Box<Box<FnBox()>> = unsafe {
            Box::from_raw(f as *mut Box<FnBox()>)
        };

        boxed_fn();
    }

    unimplemented!();
}

impl Node for ThreadImpl {
    #[inline]
    fn prev(&self) -> &Link<Self> {
        &self.prev
    }

    #[inline]
    fn next(&self) -> &Link<Self> {
        &self.next
    }

    #[inline]
    fn prev_mut(&mut self) -> &mut Link<Self> {
        &mut self.prev
    }

    #[inline]
    fn next_mut(&mut self) -> &mut Link<Self> {
        &mut self.prev
    }
}

// This trait cannot be implemented for Box in libintrusive as it must not
// depend on rust's liballoc
type ThreadImplBox = Box<ThreadImpl>;

impl Owner<ThreadImpl> for ThreadImplBox {
    #[inline]
    fn get(&self) -> &ThreadImpl {
        &**self
    }

    #[inline]
    fn get_mut(&mut self) -> &mut ThreadImpl {
        &mut **self
    }

    #[inline]
    fn take(self) {
        Box::into_raw(self);
    }

    unsafe fn from_raw_ptr(ptr: *mut ThreadImpl) -> Self {
        Box::from_raw(ptr)
    }
}
<|endoftext|>


<commit_before>
/// Should be implemented by contexts that have rectangle information.
pub trait RelativeRectangle<'a> {
    /// Shrinks the current rectangle equally by all sides.
    fn margin(&'a self, m: f64) -> Self;

    /// Expands the current rectangle equally by all sides.
    #[inline(always)]
    fn expand(&'a self, m: f64) -> Self {
        self.margin(-m)
    }

    /// Moves to a relative rectangle using the current rectangle as tile.
    fn rel(&'a self, x: f64, y: f64) -> Self;
}

<commit_msg>Added `up`<commit_after>
/// Should be implemented by contexts that have rectangle information.
pub trait RelativeRectangle<'a> {
    /// Shrinks the current rectangle equally by all sides.
    fn margin(&'a self, m: f64) -> Self;

    /// Expands the current rectangle equally by all sides.
    #[inline(always)]
    fn expand(&'a self, m: f64) -> Self {
        self.margin(-m)
    }

    /// Moves to a relative rectangle using the current rectangle as tile.
    fn rel(&'a self, x: f64, y: f64) -> Self;

    /// Moves to the above rectangle using the current rectangle as tile.
    #[inline(always)]
    fn up(&'a self) -> Self {
        self.rel(0.0, 1.0)
    }
}

<|endoftext|>


<commit_before>// xfail-test

fn foo(cond: bool) {
    // Here we will infer a type that uses the
    // region of the if stmt then block:
    let mut x; //~ ERROR foo

    if cond {
        x = &3;
    }
}

fn main() {}<commit_msg>Update error message and un-xfail test<commit_after>fn foo(cond: bool) {
    // Here we will infer a type that uses the
    // region of the if stmt then block:
    let mut x;

    if cond {
        x = &3; //~ ERROR illegal borrow: borrowed value does not live long enough
        assert (*x == 3);
    }
}

fn main() {}<|endoftext|>


<commit_before>// Copyright 2012-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.

//! Manages the communication between the compiler's main thread and
//! the thread that constructs the dependency graph. The basic idea is
//! to use double buffering to lower the cost of producing a message.
//! In the compiler thread, we accumulate messages in a vector until
//! the vector is full, or until we want to query the graph, and then
//! we send that vector over to the depgraph thread. At the same time,
//! we receive an empty vector from the depgraph thread that we can use
//! to accumulate more messages. This way we only ever have two vectors
//! allocated (and both have a fairly large capacity).

use hir::def_id::DefId;
use rustc_data_structures::veccell::VecCell;
use std::cell::Cell;
use std::sync::mpsc::{self, Sender, Receiver};
use std::thread;

use super::DepGraphQuery;
use super::DepNode;
use super::edges::DepGraphEdges;

pub enum DepMessage {
    Read(DepNode<DefId>),
    Write(DepNode<DefId>),
    PushTask(DepNode<DefId>),
    PopTask(DepNode<DefId>),
    PushIgnore,
    PopIgnore,
    Query,
}

pub struct DepGraphThreadData {
    enabled: bool,

    // Local counter that just tracks how many tasks are pushed onto the
    // stack, so that we still get an error in the case where one is
    // missing. If dep-graph construction is enabled, we'd get the same
    // error when processing tasks later on, but that's annoying because
    // it lacks precision about the source of the error.
    tasks_pushed: Cell<usize>,

    // current buffer, where we accumulate messages
    messages: VecCell<DepMessage>,

    // whence to receive new buffer when full
    swap_in: Receiver<Vec<DepMessage>>,

    // where to send buffer when full
    swap_out: Sender<Vec<DepMessage>>,

    // where to receive query results
    query_in: Receiver<DepGraphQuery<DefId>>,
}

const INITIAL_CAPACITY: usize = 2048;

impl DepGraphThreadData {
    pub fn new(enabled: bool) -> DepGraphThreadData {
        let (tx1, rx1) = mpsc::channel();
        let (tx2, rx2) = mpsc::channel();
        let (txq, rxq) = mpsc::channel();

        if enabled {
            thread::spawn(move || main(rx1, tx2, txq));
        }

        DepGraphThreadData {
            enabled: enabled,
            tasks_pushed: Cell::new(0),
            messages: VecCell::with_capacity(INITIAL_CAPACITY),
            swap_in: rx2,
            swap_out: tx1,
            query_in: rxq,
        }
    }

    #[inline]
    pub fn enabled(&self) -> bool {
        self.enabled
    }

    /// Sends the current batch of messages to the thread. Installs a
    /// new vector of messages.
    fn swap(&self) {
        assert!(self.enabled, "should never swap if not enabled");

        // should be a buffer waiting for us (though of course we may
        // have to wait for depgraph thread to finish processing the
        // old messages)
        let new_messages = self.swap_in.recv().unwrap();
        assert!(new_messages.is_empty());

        // swap in the empty buffer and extract the full one
        let old_messages = self.messages.swap(new_messages);

        // send full buffer to depgraph thread to be processed
        self.swap_out.send(old_messages).unwrap();
    }

    pub fn query(&self) -> DepGraphQuery<DefId> {
        assert!(self.enabled, "cannot query if dep graph construction not enabled");
        self.enqueue(DepMessage::Query);
        self.swap();
        self.query_in.recv().unwrap()
    }

    /// Enqueue a message to be sent when things are next swapped. (If
    /// the buffer is full, this may swap.)
    #[inline]
    pub fn enqueue(&self, message: DepMessage) {
        // Regardless of whether dep graph construction is enabled, we
        // still want to check that we always have a valid task on the
        // stack when a read/write/etc event occurs.
        match message {
            DepMessage::Read(_) | DepMessage::Write(_) =>
                if self.tasks_pushed.get() == 0 {
                    self.invalid_message("read/write but no current task")
                },
            DepMessage::PushTask(_) | DepMessage::PushIgnore =>
                self.tasks_pushed.set(self.tasks_pushed.get() + 1),
            DepMessage::PopTask(_) | DepMessage::PopIgnore =>
                self.tasks_pushed.set(self.tasks_pushed.get() - 1),
            DepMessage::Query =>
                (),
        }

        if self.enabled {
            self.enqueue_enabled(message);
        }
    }

    // Outline this fn since I expect it may want to be inlined
    // separately.
    fn enqueue_enabled(&self, message: DepMessage) {
        let len = self.messages.push(message);
        if len == INITIAL_CAPACITY {
            self.swap();
        }
    }

    // Outline this too.
    fn invalid_message(&self, string: &str) {
        bug!("{}; see src/librustc/dep_graph/README.md for more information", string)
    }
}

/// Definition of the depgraph thread.
pub fn main(swap_in: Receiver<Vec<DepMessage>>,
            swap_out: Sender<Vec<DepMessage>>,
            query_out: Sender<DepGraphQuery<DefId>>) {
    let mut edges = DepGraphEdges::new();

    // the compiler thread always expects a fresh buffer to be
    // waiting, so queue one up
    swap_out.send(Vec::with_capacity(INITIAL_CAPACITY)).unwrap();

    // process the buffers from compiler thread as we receive them
    for mut messages in swap_in {
        for msg in messages.drain(..) {
            match msg {
                DepMessage::Read(node) => edges.read(node),
                DepMessage::Write(node) => edges.write(node),
                DepMessage::PushTask(node) => edges.push_task(node),
                DepMessage::PopTask(node) => edges.pop_task(node),
                DepMessage::PushIgnore => edges.push_ignore(),
                DepMessage::PopIgnore => edges.pop_ignore(),
                DepMessage::Query => query_out.send(edges.query()).unwrap(),
            }
        }
        swap_out.send(messages).unwrap();
    }
}
<commit_msg>dep_graph: avoid panicking in thread when channel closed<commit_after>// Copyright 2012-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.

//! Manages the communication between the compiler's main thread and
//! the thread that constructs the dependency graph. The basic idea is
//! to use double buffering to lower the cost of producing a message.
//! In the compiler thread, we accumulate messages in a vector until
//! the vector is full, or until we want to query the graph, and then
//! we send that vector over to the depgraph thread. At the same time,
//! we receive an empty vector from the depgraph thread that we can use
//! to accumulate more messages. This way we only ever have two vectors
//! allocated (and both have a fairly large capacity).

use hir::def_id::DefId;
use rustc_data_structures::veccell::VecCell;
use std::cell::Cell;
use std::sync::mpsc::{self, Sender, Receiver};
use std::thread;

use super::DepGraphQuery;
use super::DepNode;
use super::edges::DepGraphEdges;

pub enum DepMessage {
    Read(DepNode<DefId>),
    Write(DepNode<DefId>),
    PushTask(DepNode<DefId>),
    PopTask(DepNode<DefId>),
    PushIgnore,
    PopIgnore,
    Query,
}

pub struct DepGraphThreadData {
    enabled: bool,

    // Local counter that just tracks how many tasks are pushed onto the
    // stack, so that we still get an error in the case where one is
    // missing. If dep-graph construction is enabled, we'd get the same
    // error when processing tasks later on, but that's annoying because
    // it lacks precision about the source of the error.
    tasks_pushed: Cell<usize>,

    // current buffer, where we accumulate messages
    messages: VecCell<DepMessage>,

    // whence to receive new buffer when full
    swap_in: Receiver<Vec<DepMessage>>,

    // where to send buffer when full
    swap_out: Sender<Vec<DepMessage>>,

    // where to receive query results
    query_in: Receiver<DepGraphQuery<DefId>>,
}

const INITIAL_CAPACITY: usize = 2048;

impl DepGraphThreadData {
    pub fn new(enabled: bool) -> DepGraphThreadData {
        let (tx1, rx1) = mpsc::channel();
        let (tx2, rx2) = mpsc::channel();
        let (txq, rxq) = mpsc::channel();

        if enabled {
            thread::spawn(move || main(rx1, tx2, txq));
        }

        DepGraphThreadData {
            enabled: enabled,
            tasks_pushed: Cell::new(0),
            messages: VecCell::with_capacity(INITIAL_CAPACITY),
            swap_in: rx2,
            swap_out: tx1,
            query_in: rxq,
        }
    }

    #[inline]
    pub fn enabled(&self) -> bool {
        self.enabled
    }

    /// Sends the current batch of messages to the thread. Installs a
    /// new vector of messages.
    fn swap(&self) {
        assert!(self.enabled, "should never swap if not enabled");

        // should be a buffer waiting for us (though of course we may
        // have to wait for depgraph thread to finish processing the
        // old messages)
        let new_messages = self.swap_in.recv().unwrap();
        assert!(new_messages.is_empty());

        // swap in the empty buffer and extract the full one
        let old_messages = self.messages.swap(new_messages);

        // send full buffer to depgraph thread to be processed
        self.swap_out.send(old_messages).unwrap();
    }

    pub fn query(&self) -> DepGraphQuery<DefId> {
        assert!(self.enabled, "cannot query if dep graph construction not enabled");
        self.enqueue(DepMessage::Query);
        self.swap();
        self.query_in.recv().unwrap()
    }

    /// Enqueue a message to be sent when things are next swapped. (If
    /// the buffer is full, this may swap.)
    #[inline]
    pub fn enqueue(&self, message: DepMessage) {
        // Regardless of whether dep graph construction is enabled, we
        // still want to check that we always have a valid task on the
        // stack when a read/write/etc event occurs.
        match message {
            DepMessage::Read(_) | DepMessage::Write(_) =>
                if self.tasks_pushed.get() == 0 {
                    self.invalid_message("read/write but no current task")
                },
            DepMessage::PushTask(_) | DepMessage::PushIgnore =>
                self.tasks_pushed.set(self.tasks_pushed.get() + 1),
            DepMessage::PopTask(_) | DepMessage::PopIgnore =>
                self.tasks_pushed.set(self.tasks_pushed.get() - 1),
            DepMessage::Query =>
                (),
        }

        if self.enabled {
            self.enqueue_enabled(message);
        }
    }

    // Outline this fn since I expect it may want to be inlined
    // separately.
    fn enqueue_enabled(&self, message: DepMessage) {
        let len = self.messages.push(message);
        if len == INITIAL_CAPACITY {
            self.swap();
        }
    }

    // Outline this too.
    fn invalid_message(&self, string: &str) {
        bug!("{}; see src/librustc/dep_graph/README.md for more information", string)
    }
}

/// Definition of the depgraph thread.
pub fn main(swap_in: Receiver<Vec<DepMessage>>,
            swap_out: Sender<Vec<DepMessage>>,
            query_out: Sender<DepGraphQuery<DefId>>) {
    let mut edges = DepGraphEdges::new();

    // the compiler thread always expects a fresh buffer to be
    // waiting, so queue one up
    swap_out.send(Vec::with_capacity(INITIAL_CAPACITY)).unwrap();

    // process the buffers from compiler thread as we receive them
    for mut messages in swap_in {
        for msg in messages.drain(..) {
            match msg {
                DepMessage::Read(node) => edges.read(node),
                DepMessage::Write(node) => edges.write(node),
                DepMessage::PushTask(node) => edges.push_task(node),
                DepMessage::PopTask(node) => edges.pop_task(node),
                DepMessage::PushIgnore => edges.push_ignore(),
                DepMessage::PopIgnore => edges.pop_ignore(),
                DepMessage::Query => query_out.send(edges.query()).unwrap(),
            }
        }
        if let Err(_) = swap_out.send(messages) {
            // the receiver must have been dropped already
            break;
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

//! Sampling from random distributions

// Some implementations use the Ziggurat method
// https://en.wikipedia.org/wiki/Ziggurat_algorithm
//
// The version used here is ZIGNOR [Doornik 2005, "An Improved
// Ziggurat Method to Generate Normal Random Samples"] which is slower
// (about double, it generates an extra random number) than the
// canonical version [Marsaglia & Tsang 2000, "The Ziggurat Method for
// Generating Random Variables"], but more robust. If one wanted, one
// could implement VIZIGNOR the ZIGNOR paper for more speed.

use num;
use rand::{Rng,Rand};

/// Things that can be used to create a random instance of `Support`.
pub trait Sample<Support> {
    /// Generate a random value of `Support`, using `rng` as the
    /// source of randomness.
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
}

/// `Sample`s that do not require keeping track of state, so each
/// sample is (statistically) independent of all others, assuming the
/// `Rng` used has this property.
// XXX maybe having this separate is overkill (the only reason is to
// take &self rather than &mut self)? or maybe this should be the
// trait called `Sample` and the other should be `DependentSample`.
pub trait IndependentSample<Support>: Sample<Support> {
    /// Generate a random value.
    fn ind_sample<R: Rng>(&self, &mut R) -> Support;
}

mod ziggurat_tables;

// inlining should mean there is no performance penalty for this
#[inline]
fn ziggurat<R:Rng>(rng: &mut R,
                   center_u: bool,
                   X: ziggurat_tables::ZigTable,
                   F: ziggurat_tables::ZigTable,
                   F_DIFF: ziggurat_tables::ZigTable,
                   pdf: &'static fn(f64) -> f64, // probability density function
                   zero_case: &'static fn(&mut R, f64) -> f64) -> f64 {
    loop {
        let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()};
        let i: uint = rng.gen::<uint>() & 0xff;
        let x = u * X[i];

        let test_x = if center_u {num::abs(x)} else {x};

        // algebraically equivalent to |u| < X[i+1]/X[i] (or u < X[i+1]/X[i])
        if test_x < X[i + 1] {
            return x;
        }
        if i == 0 {
            return zero_case(rng, u);
        }
        // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
        if F[i+1] + F_DIFF[i+1] * rng.gen() < pdf(x) {
            return x;
        }
    }
}

/// A wrapper around an `f64` to generate N(0, 1) random numbers (a.k.a.  a
/// standard normal, or Gaussian). Multiplying the generated values by the
/// desired standard deviation `sigma` then adding the desired mean `mu` will
/// give N(mu, sigma^2) distributed random numbers.
///
/// Note that this has to be unwrapped before use as an `f64` (using either
/// `*` or `cast::transmute` is safe).
///
/// # Example
///
/// ```
/// use std::rand::distributions::StandardNormal;
///
/// fn main() {
///     let normal = 2.0 + (*rand::random::<StandardNormal>()) * 3.0;
///     println!("{} is from a N(2, 9) distribution", normal)
/// }
/// ```
pub struct StandardNormal(f64);

impl Rand for StandardNormal {
    fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
        #[inline]
        fn pdf(x: f64) -> f64 {
            ((-x*x/2.0) as f64).exp()
        }
        #[inline]
        fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
            // compute a random number in the tail by hand

            // strange initial conditions, because the loop is not
            // do-while, so the condition should be true on the first
            // run, they get overwritten anyway (0 < 1, so these are
            // good).
            let mut x = 1.0f64;
            let mut y = 0.0f64;

            // FIXME #7755: infinities?
            while -2.0 * y < x * x {
                x = rng.gen::<f64>().ln() / ziggurat_tables::ZIG_NORM_R;
                y = rng.gen::<f64>().ln();
            }

            if u < 0.0 { x - ziggurat_tables::ZIG_NORM_R } else { ziggurat_tables::ZIG_NORM_R - x }
        }

        StandardNormal(ziggurat(
            rng,
            true, // this is symmetric
            &ziggurat_tables::ZIG_NORM_X,
            &ziggurat_tables::ZIG_NORM_F, &ziggurat_tables::ZIG_NORM_F_DIFF,
            pdf, zero_case))
    }
}

/// A wrapper around an `f64` to generate Exp(1) random numbers. Dividing by
/// the desired rate `lambda` will give Exp(lambda) distributed random
/// numbers.
///
/// Note that this has to be unwrapped before use as an `f64` (using either
/// `*` or `cast::transmute` is safe).
///
/// # Example
///
/// ```
/// use std::rand::distributions::Exp1;
///
/// fn main() {
///     let exp2 = (*rand::random::<Exp1>()) * 0.5;
///     println!("{} is from a Exp(2) distribution", exp2);
/// }
/// ```
pub struct Exp1(f64);

// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
impl Rand for Exp1 {
    #[inline]
    fn rand<R:Rng>(rng: &mut R) -> Exp1 {
        #[inline]
        fn pdf(x: f64) -> f64 {
            (-x).exp()
        }
        #[inline]
        fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
            ziggurat_tables::ZIG_EXP_R - rng.gen::<f64>().ln()
        }

        Exp1(ziggurat(rng, false,
                      &ziggurat_tables::ZIG_EXP_X,
                      &ziggurat_tables::ZIG_EXP_F, &ziggurat_tables::ZIG_EXP_F_DIFF,
                      pdf, zero_case))
    }
}
<commit_msg>std::rand: Add RandSample for Sample-ing Rand types directly.<commit_after>// Copyright 2013 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.

//! Sampling from random distributions

// Some implementations use the Ziggurat method
// https://en.wikipedia.org/wiki/Ziggurat_algorithm
//
// The version used here is ZIGNOR [Doornik 2005, "An Improved
// Ziggurat Method to Generate Normal Random Samples"] which is slower
// (about double, it generates an extra random number) than the
// canonical version [Marsaglia & Tsang 2000, "The Ziggurat Method for
// Generating Random Variables"], but more robust. If one wanted, one
// could implement VIZIGNOR the ZIGNOR paper for more speed.

use num;
use rand::{Rng,Rand};

/// Things that can be used to create a random instance of `Support`.
pub trait Sample<Support> {
    /// Generate a random value of `Support`, using `rng` as the
    /// source of randomness.
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
}

/// `Sample`s that do not require keeping track of state, so each
/// sample is (statistically) independent of all others, assuming the
/// `Rng` used has this property.
// XXX maybe having this separate is overkill (the only reason is to
// take &self rather than &mut self)? or maybe this should be the
// trait called `Sample` and the other should be `DependentSample`.
pub trait IndependentSample<Support>: Sample<Support> {
    /// Generate a random value.
    fn ind_sample<R: Rng>(&self, &mut R) -> Support;
}

/// A wrapper for generating types that implement `Rand` via the
/// `Sample` & `IndependentSample` traits.
pub struct RandSample<Sup>;

impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
}

impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
        rng.gen()
    }
}

mod ziggurat_tables;

// inlining should mean there is no performance penalty for this
#[inline]
fn ziggurat<R:Rng>(rng: &mut R,
                   center_u: bool,
                   X: ziggurat_tables::ZigTable,
                   F: ziggurat_tables::ZigTable,
                   F_DIFF: ziggurat_tables::ZigTable,
                   pdf: &'static fn(f64) -> f64, // probability density function
                   zero_case: &'static fn(&mut R, f64) -> f64) -> f64 {
    loop {
        let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()};
        let i: uint = rng.gen::<uint>() & 0xff;
        let x = u * X[i];

        let test_x = if center_u {num::abs(x)} else {x};

        // algebraically equivalent to |u| < X[i+1]/X[i] (or u < X[i+1]/X[i])
        if test_x < X[i + 1] {
            return x;
        }
        if i == 0 {
            return zero_case(rng, u);
        }
        // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
        if F[i+1] + F_DIFF[i+1] * rng.gen() < pdf(x) {
            return x;
        }
    }
}

/// A wrapper around an `f64` to generate N(0, 1) random numbers (a.k.a.  a
/// standard normal, or Gaussian). Multiplying the generated values by the
/// desired standard deviation `sigma` then adding the desired mean `mu` will
/// give N(mu, sigma^2) distributed random numbers.
///
/// Note that this has to be unwrapped before use as an `f64` (using either
/// `*` or `cast::transmute` is safe).
///
/// # Example
///
/// ```
/// use std::rand::distributions::StandardNormal;
///
/// fn main() {
///     let normal = 2.0 + (*rand::random::<StandardNormal>()) * 3.0;
///     println!("{} is from a N(2, 9) distribution", normal)
/// }
/// ```
pub struct StandardNormal(f64);

impl Rand for StandardNormal {
    fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
        #[inline]
        fn pdf(x: f64) -> f64 {
            ((-x*x/2.0) as f64).exp()
        }
        #[inline]
        fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
            // compute a random number in the tail by hand

            // strange initial conditions, because the loop is not
            // do-while, so the condition should be true on the first
            // run, they get overwritten anyway (0 < 1, so these are
            // good).
            let mut x = 1.0f64;
            let mut y = 0.0f64;

            // FIXME #7755: infinities?
            while -2.0 * y < x * x {
                x = rng.gen::<f64>().ln() / ziggurat_tables::ZIG_NORM_R;
                y = rng.gen::<f64>().ln();
            }

            if u < 0.0 { x - ziggurat_tables::ZIG_NORM_R } else { ziggurat_tables::ZIG_NORM_R - x }
        }

        StandardNormal(ziggurat(
            rng,
            true, // this is symmetric
            &ziggurat_tables::ZIG_NORM_X,
            &ziggurat_tables::ZIG_NORM_F, &ziggurat_tables::ZIG_NORM_F_DIFF,
            pdf, zero_case))
    }
}

/// A wrapper around an `f64` to generate Exp(1) random numbers. Dividing by
/// the desired rate `lambda` will give Exp(lambda) distributed random
/// numbers.
///
/// Note that this has to be unwrapped before use as an `f64` (using either
/// `*` or `cast::transmute` is safe).
///
/// # Example
///
/// ```
/// use std::rand::distributions::Exp1;
///
/// fn main() {
///     let exp2 = (*rand::random::<Exp1>()) * 0.5;
///     println!("{} is from a Exp(2) distribution", exp2);
/// }
/// ```
pub struct Exp1(f64);

// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
impl Rand for Exp1 {
    #[inline]
    fn rand<R:Rng>(rng: &mut R) -> Exp1 {
        #[inline]
        fn pdf(x: f64) -> f64 {
            (-x).exp()
        }
        #[inline]
        fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
            ziggurat_tables::ZIG_EXP_R - rng.gen::<f64>().ln()
        }

        Exp1(ziggurat(rng, false,
                      &ziggurat_tables::ZIG_EXP_X,
                      &ziggurat_tables::ZIG_EXP_F, &ziggurat_tables::ZIG_EXP_F_DIFF,
                      pdf, zero_case))
    }
}

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

    struct ConstRand(uint);
    impl Rand for ConstRand {
        fn rand<R: Rng>(_: &mut R) -> ConstRand {
            ConstRand(0)
        }
    }

    #[test]
    fn test_rand_sample() {
        let mut rand_sample = RandSample::<ConstRand>;

        assert_eq!(*rand_sample.sample(task_rng()), 0);
        assert_eq!(*rand_sample.ind_sample(task_rng()), 0);
    }
}
<|endoftext|>


<commit_before>//! Provides an animated transformation that moves an object between a
//! set of specified keyframes.

use std::ops::Mul;

use bspline::BSpline;

use linalg::{self, quaternion, Keyframe, Transform};
use geometry::BBox;

/// An animated transform that blends between the keyframes in its transformation
/// list over time.
#[derive(Clone, Debug)]
pub struct AnimatedTransform {
    /// List of animated transforms in hierarchical order, e.g. the lowest
    /// index is the object's, index 1 holds its direct parent's transform, etc.
    keyframes: Vec<BSpline<Keyframe>>,
}

impl AnimatedTransform {
    /// Create an animated transformation blending between the passed keyframes
    pub fn with_keyframes(mut keyframes: Vec<Keyframe>, knots: Vec<f32>, degree: usize) -> AnimatedTransform {
        // so we know what degree and so on.
        // Step through and make sure all rotations take the shortest path
        for i in 1..keyframes.len() {
            // If the dot product is negative flip the current quaternion to
            // take the shortest path through the rotation
            if quaternion::dot(&keyframes[i - 1].rotation, &keyframes[i].rotation) < 0.0 {
                keyframes[i].rotation = -keyframes[i].rotation;
            }
        }
        AnimatedTransform { keyframes: vec![BSpline::new(degree, keyframes, knots)] }
    }
    pub fn unanimated(transform: &Transform) -> AnimatedTransform {
        let key = Keyframe::new(&transform);
        AnimatedTransform { keyframes: vec![BSpline::new(0, vec![key], vec![0.0, 1.0])] }
    }
    /// Compute the transformation matrix for the animation at some time point using B-Spline
    /// interpolation.
    pub fn transform(&self, time: f32) -> Transform {
        let mut transform = Transform::identity();
        // Step through the transform stack, applying each animation transform at this
        // time as we move up
        for spline in &self.keyframes {
            let domain = spline.knot_domain();
            let t =
                if spline.control_points().count() == 1 {
                    spline.control_points().next().unwrap().transform()
                } else if time < domain.0 {
                    spline.point(domain.0).transform()
                } else if time > domain.1 {
                    spline.point(domain.1).transform()
                } else {
                    spline.point(time).transform()
                };
            transform = t * transform;
        }
        transform
    }
    /// Compute the bounds of the box moving through the animation sequence by sampling time
    pub fn animation_bounds(&self, b: &BBox, start: f32, end: f32) -> BBox {
        if !self.is_animated() {
            let t = self.transform(start);
            t * *b
        } else {
            let mut ret = BBox::new();
            for i in 0..128 {
                let time = linalg::lerp((i as f32) / 127.0, &start, &end);
                let t = self.transform(time);
                ret = ret.box_union(&(t * *b));
            }
            ret
        }
    }
    /// Check if the transform is actually animated
    pub fn is_animated(&self) -> bool {
        self.keyframes.is_empty() || self.keyframes.iter().fold(true, |b, spline| b && spline.control_points().count() > 1)
    }
}

impl Mul for AnimatedTransform {
    type Output = AnimatedTransform;
    /// Compose the animated transformations
    fn mul(self, mut rhs: AnimatedTransform) -> AnimatedTransform {
        for l in &self.keyframes[..] {
            rhs.keyframes.push(l.clone());
        }
        rhs
    }
}

<commit_msg>Also just clamp the t value to the knot domain in animated transform<commit_after>//! Provides an animated transformation that moves an object between a
//! set of specified keyframes.

use std::ops::Mul;

use bspline::BSpline;

use linalg::{self, quaternion, Keyframe, Transform};
use geometry::BBox;

/// An animated transform that blends between the keyframes in its transformation
/// list over time.
#[derive(Clone, Debug)]
pub struct AnimatedTransform {
    /// List of animated transforms in hierarchical order, e.g. the lowest
    /// index is the object's, index 1 holds its direct parent's transform, etc.
    keyframes: Vec<BSpline<Keyframe>>,
}

impl AnimatedTransform {
    /// Create an animated transformation blending between the passed keyframes
    pub fn with_keyframes(mut keyframes: Vec<Keyframe>, knots: Vec<f32>, degree: usize) -> AnimatedTransform {
        // so we know what degree and so on.
        // Step through and make sure all rotations take the shortest path
        for i in 1..keyframes.len() {
            // If the dot product is negative flip the current quaternion to
            // take the shortest path through the rotation
            if quaternion::dot(&keyframes[i - 1].rotation, &keyframes[i].rotation) < 0.0 {
                keyframes[i].rotation = -keyframes[i].rotation;
            }
        }
        AnimatedTransform { keyframes: vec![BSpline::new(degree, keyframes, knots)] }
    }
    pub fn unanimated(transform: &Transform) -> AnimatedTransform {
        let key = Keyframe::new(&transform);
        AnimatedTransform { keyframes: vec![BSpline::new(0, vec![key], vec![0.0, 1.0])] }
    }
    /// Compute the transformation matrix for the animation at some time point using B-Spline
    /// interpolation.
    pub fn transform(&self, time: f32) -> Transform {
        let mut transform = Transform::identity();
        // Step through the transform stack, applying each animation transform at this
        // time as we move up
        for spline in &self.keyframes {
            let domain = spline.knot_domain();
            let t =
                if spline.control_points().count() == 1 {
                    spline.control_points().next().unwrap().transform()
                } else {
                    let t_val = linalg::clamp(time, domain.0, domain.1);
                    spline.point(t_val).transform()
                };
            transform = t * transform;
        }
        transform
    }
    /// Compute the bounds of the box moving through the animation sequence by sampling time
    pub fn animation_bounds(&self, b: &BBox, start: f32, end: f32) -> BBox {
        if !self.is_animated() {
            let t = self.transform(start);
            t * *b
        } else {
            let mut ret = BBox::new();
            for i in 0..128 {
                let time = linalg::lerp((i as f32) / 127.0, &start, &end);
                let t = self.transform(time);
                ret = ret.box_union(&(t * *b));
            }
            ret
        }
    }
    /// Check if the transform is actually animated
    pub fn is_animated(&self) -> bool {
        self.keyframes.is_empty() || self.keyframes.iter().fold(true, |b, spline| b && spline.control_points().count() > 1)
    }
}

impl Mul for AnimatedTransform {
    type Output = AnimatedTransform;
    /// Compose the animated transformations
    fn mul(self, mut rhs: AnimatedTransform) -> AnimatedTransform {
        for l in &self.keyframes[..] {
            rhs.keyframes.push(l.clone());
        }
        rhs
    }
}

<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;

use vobject::parse_component;
use toml::Value;
use toml_query::insert::TomlValueInsertExt;

use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagentryref::refstore::RefStore;
use libimagentryref::flags::RefFlags;

use error::Result;
use util;

pub trait ContactStore<'a> : RefStore {

    // creating

    fn create_from_path(&'a self, p: &PathBuf) -> Result<FileLockEntry<'a>>;

    /// Create contact ref from buffer
    ///
    /// Needs the `p` argument as we're finally creating a reference by path, the buffer is only for
    /// collecting metadata.
    fn create_from_buf(&'a self, p: &PathBuf, buf: &String) -> Result<FileLockEntry<'a>>;

    // getting

    fn search_contact(&'a self /* later more params */) -> Result<FileLockEntry<'a>>;
}

impl<'a> ContactStore<'a> for Store {

    fn create_from_path(&'a self, p: &PathBuf) -> Result<FileLockEntry<'a>> {
        util::read_to_string(p).and_then(|buf| self.create_from_buf(p, &buf))
    }

    /// Create contact ref from buffer
    fn create_from_buf(&'a self, p: &PathBuf, buf: &String) -> Result<FileLockEntry<'a>> {
        let component = parse_component(&buf)?;
        debug!("Parsed: {:?}", component);

        let flags = RefFlags::default().with_content_hashing(true).with_permission_tracking(false);
        RefStore::create(self, p.clone(), flags)
            .map_err(From::from)
            .and_then(|mut entry| {
                entry.get_header_mut()
                    .insert("contact.marker", Value::Boolean(true))
                    .map_err(From::from)
                    .map(|_| entry)
            })
    }

    fn search_contact(&'a self /* later more params */) -> Result<FileLockEntry<'a>> {
        unimplemented!()
    }

}
<commit_msg>Replace search_contact() with all_contacts()<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;

use vobject::parse_component;
use toml::Value;
use toml_query::insert::TomlValueInsertExt;

use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreIdIterator;
use libimagentryref::refstore::RefStore;
use libimagentryref::flags::RefFlags;

use error::Result;
use util;

pub trait ContactStore<'a> : RefStore {

    // creating

    fn create_from_path(&'a self, p: &PathBuf) -> Result<FileLockEntry<'a>>;

    /// Create contact ref from buffer
    ///
    /// Needs the `p` argument as we're finally creating a reference by path, the buffer is only for
    /// collecting metadata.
    fn create_from_buf(&'a self, p: &PathBuf, buf: &String) -> Result<FileLockEntry<'a>>;

    // getting

    fn all_contacts(&'a self) -> Result<StoreIdIterator>;
}

/// The extension for the Store to work with contacts
///
/// The contact functionality is implemented by using the `libimagentryref` library, so basically
/// we only reference vcard files from outside the store.
///
/// Because of this, we do not have an own store collection `/contacts` or something like that, but
/// must stress the `libimagentryref` API for everything.
impl<'a> ContactStore<'a> for Store {

    fn create_from_path(&'a self, p: &PathBuf) -> Result<FileLockEntry<'a>> {
        util::read_to_string(p).and_then(|buf| self.create_from_buf(p, &buf))
    }

    /// Create contact ref from buffer
    fn create_from_buf(&'a self, p: &PathBuf, buf: &String) -> Result<FileLockEntry<'a>> {
        let component = parse_component(&buf)?;
        debug!("Parsed: {:?}", component);

        let flags = RefFlags::default().with_content_hashing(true).with_permission_tracking(false);
        RefStore::create(self, p.clone(), flags)
            .map_err(From::from)
            .and_then(|mut entry| {
                entry.get_header_mut()
                    .insert("contact.marker", Value::Boolean(true))
                    .map_err(From::from)
                    .map(|_| entry)
            })
    }

    fn all_contacts(&'a self) -> Result<StoreIdIterator> {
        self.all_references().map_err(From::from)
    }

}

<|endoftext|>