<commit_before>//use std::io::prelude::*;
use std::path::Path;
use std::time::Duration;
use std::thread;
use std::thread::sleep;
use std::thread::JoinHandle;
use std::fs::remove_file;
use std::os::unix::net::{UnixListener, UnixStream};
use std::sync::mpsc::channel;
use std::sync::mpsc::{Sender, Receiver};
use std::sync::Arc;

pub struct Server {
    listener : UnixListener,
}

impl Server {
    pub fn create_server_thread(socket_path : &str) -> (JoinHandle<()>, Receiver<UnixStream>) {
        // Because it is not a static str, we have to use Arc (A thread-safe reference-counting pointer)
        let socket_path_share = Arc::new(socket_path.to_string());
        let socket_path_copy = Arc::clone(&socket_path_share);
        let (tx, rx) = channel::<UnixStream>();
        (thread::spawn(move || {
            let mut serv = Server::new(socket_path_copy.as_str());
            serv.receive(tx);
        }), rx)
    }

    fn new(socket_path : &str) -> Server {
        let socket = Path::new(socket_path);

        // Delete old socket if necessary
        if socket.exists() {
            let _ = remove_file(socket);
        }

        // Bind to socket
        match UnixListener::bind(&socket) {
            Err(_) => panic!("failed to bind socket"),
            Ok(listener) => {
                //listener.set_nonblocking(true).expect("Couldn't set non blocking");
                Server {
                    listener
                }
            },
        }
    }

    fn receive(& mut self, tx_channel : Sender<UnixStream>) {
        println!("Server started, waiting for clients");

        // accept connections and process them
        for stream in self.listener.incoming() {
            match stream {
                Ok(stream) => {
                    /* connection succeeded */
                    println!("Connection succeeded {:?}", stream);
                    tx_channel.send(stream).unwrap();
                    //stream.write_all(b"hello world\n").unwrap();
                }
                Err(err) => {
                    /* connection failed */
                    println!("Connection failed : {}", err);
                    sleep(Duration::from_secs(5));
                }
            }
        }
    }
}
<commit_msg>Remive useless use of Arc. Just copy str as string and use it in the other thread<commit_after>use std::path::Path;
use std::time::Duration;
use std::thread;
use std::thread::sleep;
use std::thread::JoinHandle;
use std::fs::remove_file;
use std::os::unix::net::{UnixListener, UnixStream};
use std::sync::mpsc::channel;
use std::sync::mpsc::{Sender, Receiver};

pub struct Server {
    listener : UnixListener,
}

impl Server {
    pub fn create_server_thread(socket_path : &str) -> (JoinHandle<()>, Receiver<UnixStream>) {
        let socket_path_copy = socket_path.to_string();
        let (tx, rx) = channel::<UnixStream>();
        (thread::spawn(move || {
            let mut serv = Server::new(socket_path_copy.as_str());
            serv.receive(tx);
        }), rx)
    }

    fn new(socket_path : &str) -> Server {
        let socket = Path::new(socket_path);

        // Delete old socket if necessary
        if socket.exists() {
            let _ = remove_file(socket);
        }

        // Bind to socket
        match UnixListener::bind(&socket) {
            Err(_) => panic!("failed to bind socket"),
            Ok(listener) => {
                //listener.set_nonblocking(true).expect("Couldn't set non blocking");
                Server {
                    listener
                }
            },
        }
    }

    fn receive(& mut self, tx_channel : Sender<UnixStream>) {
        println!("Server started, waiting for clients");

        // accept connections and process them
        for stream in self.listener.incoming() {
            match stream {
                Ok(stream) => {
                    /* connection succeeded */
                    println!("Connection succeeded {:?}", stream);
                    tx_channel.send(stream).unwrap();
                    //stream.write_all(b"hello world\n").unwrap();
                }
                Err(err) => {
                    /* connection failed */
                    println!("Connection failed : {}", err);
                    sleep(Duration::from_secs(5));
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, StreamProducer, many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
  output: Vec<i32>,
}

/// Alias for a FLAC stream produced from `Read`.
pub type StreamReader<R>  = Stream<ReadStream<R>>;

/// Alias for a FLAC stream produced from a byte stream buffer.
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> Result<StreamReader<R>, ErrorKind> {
    let producer = ReadStream::new(reader);

    Stream::from_stream_producer(producer)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::NotFound)` is returned when the given
  ///   filename isn't found.
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_file(filename: &str) -> Result<StreamReader<File>, ErrorKind> {
    File::open(filename).map_err(|e| ErrorKind::IO(e.kind()))
                        .and_then(|file| {
      let producer = ReadStream::new(file);

      Stream::from_stream_producer(producer)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> Result<StreamBuffer, ErrorKind> {
    let producer = ByteStream::new(buffer);

    Stream::from_stream_producer(producer)
  }

  fn from_stream_producer(mut producer: P) -> Result<Self, ErrorKind> {
    let mut stream_info = StreamInfo::new();
    let mut metadata    = Vec::new();

    many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    }).map(|_| {
      Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
        output: Vec::new(),
      }
    })
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;

    if self.output.is_empty() {
      let channels    = self.info.channels as usize;
      let block_size  = self.info.max_block_size as usize;
      let output_size = block_size * channels;

      self.output.reserve_exact(output_size);

      unsafe { self.output.set_len(output_size) }
    }

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }

  fn next_frame(&mut self) -> Option<usize> {
    let stream_info = &self.info;
    let buffer      = &mut self.output;

    loop {
      match self.producer.parse(|i| frame_parser(i, stream_info, buffer)) {
        Ok(frame)                  => {
          let channels    = frame.header.channels as usize;
          let block_size  = frame.header.block_size as usize;
          let mut channel = 0;

          for subframe in &frame.subframes[0..channels] {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut buffer[start..end];

            subframe::decode(&subframe, block_size, output);

            channel += 1;
          }

          frame::decode(frame.header.channel_assignment, buffer);

          return Some(block_size);
        }
        Err(ErrorKind::EndOfInput) => return None,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P> where P: 'a + StreamProducer {
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a, P> Iterator for Iter<'a, P> where P: StreamProducer {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      if let Some(block_size) = self.stream.next_frame() {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

impl<'a, P> IntoIterator for &'a mut Stream

 where P: StreamProducer {
  type Item     = i32;
  type IntoIter = Iter<'a, P>;

  #[inline]
  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}
<commit_msg>Remove buffer from `Stream`<commit_after>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, StreamProducer, many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
}

/// Alias for a FLAC stream produced from `Read`.
pub type StreamReader<R>  = Stream<ReadStream<R>>;

/// Alias for a FLAC stream produced from a byte stream buffer.
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> Result<StreamReader<R>, ErrorKind> {
    let producer = ReadStream::new(reader);

    Stream::from_stream_producer(producer)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::NotFound)` is returned when the given
  ///   filename isn't found.
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_file(filename: &str) -> Result<StreamReader<File>, ErrorKind> {
    File::open(filename).map_err(|e| ErrorKind::IO(e.kind()))
                        .and_then(|file| {
      let producer = ReadStream::new(file);

      Stream::from_stream_producer(producer)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> Result<StreamBuffer, ErrorKind> {
    let producer = ByteStream::new(buffer);

    Stream::from_stream_producer(producer)
  }

  fn from_stream_producer(mut producer: P) -> Result<Self, ErrorKind> {
    let mut stream_info = StreamInfo::new();
    let mut metadata    = Vec::new();

    many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    }).map(|_| {
      Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
      }
    })
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;
    let channels     = self.info.channels as usize;
    let block_size   = self.info.max_block_size as usize;
    let buffer_size  = block_size * channels;

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }

  fn next_frame(&mut self) -> Option<usize> {
    let stream_info = &self.info;
    let buffer      = &mut self.output;

    loop {
      match self.producer.parse(|i| frame_parser(i, stream_info, buffer)) {
        Ok(frame)                  => {
          let channels    = frame.header.channels as usize;
          let block_size  = frame.header.block_size as usize;
          let mut channel = 0;

          for subframe in &frame.subframes[0..channels] {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut buffer[start..end];

            subframe::decode(&subframe, block_size, output);

            channel += 1;
          }

          frame::decode(frame.header.channel_assignment, buffer);

          return Some(block_size);
        }
        Err(ErrorKind::EndOfInput) => return None,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P> where P: 'a + StreamProducer {
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a, P> Iterator for Iter<'a, P> where P: StreamProducer {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      if let Some(block_size) = self.stream.next_frame() {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

impl<'a, P> IntoIterator for &'a mut Stream

 where P: StreamProducer {
  type Item     = i32;
  type IntoIter = Iter<'a, P>;

  #[inline]
  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::rc::Rc;

lazy_static! {
    static ref SYMBOLS: HashSet<Rc<String>> = {
        HashSet::new()
    };
}

pub fn contains(n: &str) -> bool {
    SYMBOLS.contains(n)
}

pub fn fetch(n: &str) -> Rc<String> {
    if !SYMBOLS.contains(n) {
        SYMBOLS.insert(n.to_owned());
    }

    &SYMBOLS.get(n).unwrap()
}
<commit_msg>interner?<commit_after>use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
use std::ops::Deref;

#[derive (Eq, PartialEq, Clone, Copy, Default, Hash, Debug)]
pub struct InternedStr(usize);

#[derive (Debug)]
pub struct Interner {
    indices: HashMap<String, usize>,
    strings: Vec<String>
}

impl Interner {
    pub fn new() -> Interner {
        Interner { indices: HashMap::new(), strings: vec![] }
    }

    pub fn intern(&mut self, s: &str) -> InternedStr {
        match self.indices.get(s).map(|x| *x) {
            Some(index) => InternedStr(index),
            None => {
                let index = self.strings.len();
                self.indices.insert(s.to_string(), index);
                self.strings.push(s.to_string());
                InternedStr(index)
            }
        }
    }

    pub fn get_str(&self, InternedStr(i): InternedStr) -> &str {
        if i < self.strings.len() {
            &*self.strings[i]
        } else {
            panic!("argh!");
        }
    }
}

pub fn get_local_interner() -> Rc<RefCell<Interner>> {
    thread_local!( static INTERNER: Rc<RefCell<Interner>> = Rc::new(RefCell::new(Interner::new())));
    INTERNER.with(|interner| interner.clone())
}

pub fn intern(s: &str) -> InternedStr {
    let interner = get_local_interner();
    let mut i = interner.borrow_mut();
    i.intern(s)
}

impl Deref for InternedStr {
    type Target = str;
    fn deref(&self) -> &str {
        self.as_ref()
    }
}

impl AsRef<str> for InternedStr {
    fn as_ref(&self) -> &str {
        let interner = get_local_interner();
        let x = (*interner).borrow_mut();
        let r: &str = x.get_str(*self);
        unsafe { ::std::mem::transmute(r) }
    }
}
<|endoftext|>


<commit_before>use super::ToTokens;
use std::fmt::{self, Display};

#[derive(Debug, Clone)]
pub struct Tokens(String);

impl Tokens {
    pub fn new() -> Self {
        Tokens(String::new())
    }

    pub fn append(&mut self, token: &str) {
        if !self.0.is_empty() {
            self.0.push(' ');
        }
        self.0.push_str(token);
    }

    pub fn append_all<T, I>(&mut self, iter: I)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
        }
    }

    pub fn append_separated<T, I>(&mut self, iter: I, sep: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for (i, token) in iter.into_iter().enumerate() {
            if i > 0 {
                self.append(sep);
            }
            token.to_tokens(self);
        }
    }

    pub fn append_terminated<T, I>(&mut self, iter: I, term: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
            self.append(term);
        }
    }
}

impl Default for Tokens {
    fn default() -> Self {
        Tokens::new()
    }
}

impl Display for Tokens {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(formatter)
    }
}
<commit_msg>Avoid appending empty tokens<commit_after>use super::ToTokens;
use std::fmt::{self, Display};

#[derive(Debug, Clone)]
pub struct Tokens(String);

impl Tokens {
    pub fn new() -> Self {
        Tokens(String::new())
    }

    pub fn append(&mut self, token: &str) {
        if !self.0.is_empty() && !token.is_empty() {
            self.0.push(' ');
        }
        self.0.push_str(token);
    }

    pub fn append_all<T, I>(&mut self, iter: I)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
        }
    }

    pub fn append_separated<T, I>(&mut self, iter: I, sep: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for (i, token) in iter.into_iter().enumerate() {
            if i > 0 {
                self.append(sep);
            }
            token.to_tokens(self);
        }
    }

    pub fn append_terminated<T, I>(&mut self, iter: I, term: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
            self.append(term);
        }
    }
}

impl Default for Tokens {
    fn default() -> Self {
        Tokens::new()
    }
}

impl Display for Tokens {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(formatter)
    }
}
<|endoftext|>


<commit_before>//! Traits input types have to implement to work with nom combinators
//!
use std::ops::{Range,RangeTo,RangeFrom,RangeFull};

#[cfg(not(feature = "core"))]
use std::str::Chars;

pub trait InputLength {
  #[inline]
  fn input_len(&self) -> usize;
}

impl<'a, T> InputLength for &'a[T] {
  #[inline]
  fn input_len(&self) -> usize {
    self.len()
  }
}

#[cfg(not(feature = "core"))]
impl<'a> InputLength for &'a str {
  #[inline]
  fn input_len(&self) -> usize {
    self.len()
  }
}

impl<'a> InputLength for (&'a [u8], usize) {
  #[inline]
  fn input_len(&self) -> usize {
    //println!("bit input length for ({:?}, {}):", self.0, self.1);
    let res = self.0.len() * 8 - self.1;
    //println!("-> {}", res);
    res
  }
}

use std::iter::Enumerate;
#[cfg(not(feature = "core"))]
use std::str::CharIndices;

pub trait AsChar {
    #[inline]
    fn as_char(self)      -> char;
    #[inline]
    fn is_alpha(self)     -> bool;
    #[inline]
    fn is_alphanum(self)  -> bool;
    #[inline]
    fn is_dec_digit(self) -> bool;
    #[inline]
    fn is_hex_digit(self) -> bool;
    #[inline]
    fn is_oct_digit(self) -> bool;
}

impl AsChar for u8 {
    #[inline]
    fn as_char(self)      -> char { self as char }
    #[inline]
    fn is_alpha(self)     -> bool {
      (self >= 0x41 && self <= 0x5A) || (self >= 0x61 && self <= 0x7A)
    }
    #[inline]
    fn is_alphanum(self)  -> bool { self.is_alpha() || self.is_dec_digit() }
    #[inline]
    fn is_dec_digit(self) -> bool {
      self >= 0x30 && self <= 0x39
    }
    #[inline]
    fn is_hex_digit(self) -> bool {
      (self >= 0x30 && self <= 0x39) ||
      (self >= 0x41 && self <= 0x46) ||
      (self >= 0x61 && self <= 0x66)
    }
    #[inline]
    fn is_oct_digit(self) -> bool {
      self >= 0x30 && self <= 0x37
    }
}
impl<'a> AsChar for &'a u8 {
    #[inline]
    fn as_char(self)      -> char { *self as char }
    #[inline]
    fn is_alpha(self)     -> bool {
      (*self >= 0x41 && *self <= 0x5A) || (*self >= 0x61 && *self <= 0x7A)
    }
    #[inline]
    fn is_alphanum(self)  -> bool { self.is_alpha() || self.is_dec_digit() }
    #[inline]
    fn is_dec_digit(self) -> bool {
      *self >= 0x30 && *self <= 0x39
    }
    #[inline]
    fn is_hex_digit(self) -> bool {
      (*self >= 0x30 && *self <= 0x39) ||
      (*self >= 0x41 && *self <= 0x46) ||
      (*self >= 0x61 && *self <= 0x66)
    }
    #[inline]
    fn is_oct_digit(self)   -> bool {
      *self >= 0x30 && *self <= 0x37
    }
}

impl AsChar for char {
    #[inline]
    fn as_char(self)      -> char { self }
    #[inline]
    fn is_alpha(self)     -> bool { self.is_alphabetic() }
    #[inline]
    fn is_alphanum(self)  -> bool { self.is_alpha() || self.is_dec_digit() }
    #[inline]
    fn is_dec_digit(self) -> bool { self.is_digit(10) }
    #[inline]
    fn is_hex_digit(self) -> bool { self.is_digit(16) }
    #[inline]
    fn is_oct_digit(self) -> bool { self.is_digit(8) }
}

pub trait InputIter {
    type Item     : AsChar;
    type RawItem  : AsChar;
    type Iter     : Iterator<Item=(usize, Self::Item)>;
    type IterElem : Iterator<Item=Self::Item>;

    fn iter_indices(&self)  -> Self::Iter;
    fn iter_elements(&self) -> Self::IterElem;
    fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool;
    fn index(&self, count:usize) -> Option<usize>;
}

pub trait InputTake {
    fn take<P>(&self, count: usize)  -> Option<&Self>;
    fn take_split<P>(&self, count: usize) -> Option<(&Self,&Self)>;
}

impl<'a> InputIter for &'a [u8] {
    type Item     = &'a u8;
    type RawItem  = u8;
    type Iter     = Enumerate<::std::slice::Iter<'a, u8>>;
    type IterElem = ::std::slice::Iter<'a, u8>;

    #[inline]
    fn iter_indices(&self) -> Enumerate<::std::slice::Iter<'a, u8>> {
        self.iter().enumerate()
    }
    #[inline]
    fn iter_elements(&self) -> ::std::slice::Iter<'a,u8> {
      self.iter()
    }
    #[inline]
    fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
      self.iter().position(|b| predicate(*b))
    }
    #[inline]
    fn index(&self, count:usize) -> Option<usize> {
      if self.len() >= count {
        Some(count)
      } else {
        None
      }
    }
}

impl InputTake for [u8] {
    #[inline]
    fn take<P>(&self, count: usize) -> Option<&Self> {
      if self.len() >= count {
        Some(&self[0..count])
      } else {
        None
      }
    }
    #[inline]
    fn take_split<P>(&self, count: usize) -> Option<(&Self,&Self)> {
      if self.len() >= count {
        Some((&self[count..],&self[..count]))
      } else {
        None
      }
    }
}

#[cfg(not(feature = "core"))]
impl<'a> InputIter for &'a str {
    type Item     = char;
    type RawItem  = char;
    type Iter     = CharIndices<'a>;
    type IterElem = Chars<'a>;
    #[inline]
    fn iter_indices(&self) -> CharIndices<'a> {
        self.char_indices()
    }
    #[inline]
    fn iter_elements(&self) -> Chars<'a> {
      self.chars()
    }
    fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
      for (o,c) in self.char_indices() {
        if predicate(c) {
          return Some(o)
        }
      }
      None
    }
    #[inline]
    fn index(&self, count:usize) -> Option<usize> {
      let mut cnt    = 0;
      for (index, _) in self.char_indices() {
        if cnt == count {
          return Some(index)
        }
        cnt += 1;
      }
      if cnt == count {
        return Some(self.len())
      }
      None
    }
}

#[cfg(not(feature = "core"))]
impl InputTake for str {
    #[inline]
    fn take<P>(&self, count: usize) -> Option<&Self> {
      let mut cnt    = 0;
      for (index, _) in self.char_indices() {
        if cnt == count {
          return Some(&self[..index])
        }
        cnt += 1;
      }
      None
    }

    // return byte index
    #[inline]
    fn take_split<P>(&self, count: usize) -> Option<(&Self,&Self)> {
      let mut cnt    = 0;
      for (index, _) in self.char_indices() {
        if cnt == count {
          return Some((&self[index..],&self[..index]))
        }
        cnt += 1;
      }
      None
    }
}

#[derive(Debug,PartialEq)]
pub enum CompareResult {
  Ok,
  Incomplete,
  Error
}

pub trait Compare<T> {
  fn compare(&self, t:T)         -> CompareResult;
  fn compare_no_case(&self, t:T) -> CompareResult;
}

impl<'a,'b> Compare<&'b[u8]> for &'a [u8] {
  #[inline(always)]
  fn compare(&self, t: &'b[u8]) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = &self[..m];
    let b       = &t[..m];

    if reduced != b {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }

  #[inline(always)]
  fn compare_no_case(&self, t: &'b[u8]) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = &self[..m];
    let other   = &t[..m];

    if !reduced.iter().zip(other).all(|(a, b)| {
      match (*a,*b) {
        (0...64, 0...64) | (91...96, 91...96) | (123...255, 123...255) => a == b,
        (65...90, 65...90) | (97...122, 97...122) | (65...90, 97...122 ) |(97...122, 65...90) => {
          *a & 0b01000000 == *b & 0b01000000
        }
        _ => false
      }
    }) {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> Compare<&'b str> for &'a [u8] {
  #[inline(always)]
  fn compare(&self, t: &'b str) -> CompareResult {
    self.compare(str::as_bytes(t))
  }
  #[inline(always)]
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.compare_no_case(str::as_bytes(t))
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> Compare<&'b str> for &'a str {
  #[inline(always)]
  fn compare(&self, t: &'b str) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = &self[..m];
    let b       = &t[..m];

    if reduced != b {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }

  //FIXME: this version is too simple and does not use the current locale
  #[inline(always)]
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = &self[..m];
    let b       = &t[..m];

    //println!("compare_no_case({}, {}) => {} / {}", self, t, reduced.to_lowercase(), b.to_lowercase());
    if !(reduced.to_lowercase() == b.to_lowercase()) {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }
}

pub trait FindToken<T> {
  fn find_token(&self, list: T) -> bool;
}

impl<'a> FindToken<&'a[u8]> for u8 {
  fn find_token(&self, list: &[u8]) -> bool {
    for &i in list.iter() {
      if *self == i { return true }
    }
    false
  }
}

#[cfg(not(feature = "core"))]
impl<'a> FindToken<&'a str> for u8 {
  fn find_token(&self, list: &str) -> bool {
    self.find_token(str::as_bytes(list))
  }
}

#[cfg(not(feature = "core"))]
impl<'a> FindToken<&'a str> for char {
  fn find_token(&self, list: &str) -> bool {
    for i in list.chars() {
      if *self == i { return true }
    }
    false
  }
}

pub trait FindSubstring<T> {
  fn find_substring(&self, substr: T) -> Option<usize>;
}

impl<'a,'b> FindSubstring<&'b [u8]> for &'a[u8] {
  fn find_substring(&self, substr: &'b[u8]) -> Option<usize> {
    for (index,win) in self.windows(substr.len()).enumerate() {
      if win == substr {
        return Some(index)
      }
    }
    None
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> FindSubstring<&'b str> for &'a[u8] {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.find_substring(str::as_bytes(substr))
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> FindSubstring<&'b str> for &'a str {
  //returns byte index
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.find(substr)
  }
}

pub trait Slice<R> {
  #[inline(always)]
  fn slice(&self, range: R) -> Self;
}

impl<'a,T> Slice<Range<usize>> for &'a [T] {
  fn slice(&self, range:Range<usize>) -> Self {
    &self[range]
  }
}

impl<'a,T> Slice<RangeTo<usize>> for &'a [T] {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    &self[range]
  }
}

impl<'a,T> Slice<RangeFrom<usize>> for &'a [T] {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    &self[range]
  }
}

impl<'a,T> Slice<RangeFull> for &'a [T] {
  fn slice(&self, range:RangeFull) -> Self {
    &self[range]
  }
}

impl<'a> Slice<Range<usize>> for &'a str {
  fn slice(&self, range:Range<usize>) -> Self {
    &self[range]
  }
}

impl<'a> Slice<RangeTo<usize>> for &'a str {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    &self[range]
  }
}

impl<'a> Slice<RangeFrom<usize>> for &'a str {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    &self[range]
  }
}

impl<'a> Slice<RangeFull> for &'a str {
  fn slice(&self, range:RangeFull) -> Self {
    &self[range]
  }
}
<commit_msg>Fix indexing of &str containing Unicode.<commit_after>//! Traits input types have to implement to work with nom combinators
//!
use std::ops::{Range,RangeTo,RangeFrom,RangeFull};

#[cfg(not(feature = "core"))]
use std::str::Chars;

pub trait InputLength {
  #[inline]
  fn input_len(&self) -> usize;
}

impl<'a, T> InputLength for &'a[T] {
  #[inline]
  fn input_len(&self) -> usize {
    self.len()
  }
}

#[cfg(not(feature = "core"))]
impl<'a> InputLength for &'a str {
  #[inline]
  fn input_len(&self) -> usize {
    self.len()
  }
}

impl<'a> InputLength for (&'a [u8], usize) {
  #[inline]
  fn input_len(&self) -> usize {
    //println!("bit input length for ({:?}, {}):", self.0, self.1);
    let res = self.0.len() * 8 - self.1;
    //println!("-> {}", res);
    res
  }
}

use std::iter::Enumerate;
#[cfg(not(feature = "core"))]
use std::str::CharIndices;

pub trait AsChar {
    #[inline]
    fn as_char(self)      -> char;
    #[inline]
    fn is_alpha(self)     -> bool;
    #[inline]
    fn is_alphanum(self)  -> bool;
    #[inline]
    fn is_dec_digit(self) -> bool;
    #[inline]
    fn is_hex_digit(self) -> bool;
    #[inline]
    fn is_oct_digit(self) -> bool;
}

impl AsChar for u8 {
    #[inline]
    fn as_char(self)      -> char { self as char }
    #[inline]
    fn is_alpha(self)     -> bool {
      (self >= 0x41 && self <= 0x5A) || (self >= 0x61 && self <= 0x7A)
    }
    #[inline]
    fn is_alphanum(self)  -> bool { self.is_alpha() || self.is_dec_digit() }
    #[inline]
    fn is_dec_digit(self) -> bool {
      self >= 0x30 && self <= 0x39
    }
    #[inline]
    fn is_hex_digit(self) -> bool {
      (self >= 0x30 && self <= 0x39) ||
      (self >= 0x41 && self <= 0x46) ||
      (self >= 0x61 && self <= 0x66)
    }
    #[inline]
    fn is_oct_digit(self) -> bool {
      self >= 0x30 && self <= 0x37
    }
}
impl<'a> AsChar for &'a u8 {
    #[inline]
    fn as_char(self)      -> char { *self as char }
    #[inline]
    fn is_alpha(self)     -> bool {
      (*self >= 0x41 && *self <= 0x5A) || (*self >= 0x61 && *self <= 0x7A)
    }
    #[inline]
    fn is_alphanum(self)  -> bool { self.is_alpha() || self.is_dec_digit() }
    #[inline]
    fn is_dec_digit(self) -> bool {
      *self >= 0x30 && *self <= 0x39
    }
    #[inline]
    fn is_hex_digit(self) -> bool {
      (*self >= 0x30 && *self <= 0x39) ||
      (*self >= 0x41 && *self <= 0x46) ||
      (*self >= 0x61 && *self <= 0x66)
    }
    #[inline]
    fn is_oct_digit(self)   -> bool {
      *self >= 0x30 && *self <= 0x37
    }
}

impl AsChar for char {
    #[inline]
    fn as_char(self)      -> char { self }
    #[inline]
    fn is_alpha(self)     -> bool { self.is_alphabetic() }
    #[inline]
    fn is_alphanum(self)  -> bool { self.is_alpha() || self.is_dec_digit() }
    #[inline]
    fn is_dec_digit(self) -> bool { self.is_digit(10) }
    #[inline]
    fn is_hex_digit(self) -> bool { self.is_digit(16) }
    #[inline]
    fn is_oct_digit(self) -> bool { self.is_digit(8) }
}

pub trait InputIter {
    type Item     : AsChar;
    type RawItem  : AsChar;
    type Iter     : Iterator<Item=(usize, Self::Item)>;
    type IterElem : Iterator<Item=Self::Item>;

    fn iter_indices(&self)  -> Self::Iter;
    fn iter_elements(&self) -> Self::IterElem;
    fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool;
    fn index(&self, count:usize) -> Option<usize>;
}

pub trait InputTake {
    fn take<P>(&self, count: usize)  -> Option<&Self>;
    fn take_split<P>(&self, count: usize) -> Option<(&Self,&Self)>;
}

impl<'a> InputIter for &'a [u8] {
    type Item     = &'a u8;
    type RawItem  = u8;
    type Iter     = Enumerate<::std::slice::Iter<'a, u8>>;
    type IterElem = ::std::slice::Iter<'a, u8>;

    #[inline]
    fn iter_indices(&self) -> Enumerate<::std::slice::Iter<'a, u8>> {
        self.iter().enumerate()
    }
    #[inline]
    fn iter_elements(&self) -> ::std::slice::Iter<'a,u8> {
      self.iter()
    }
    #[inline]
    fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
      self.iter().position(|b| predicate(*b))
    }
    #[inline]
    fn index(&self, count:usize) -> Option<usize> {
      if self.len() >= count {
        Some(count)
      } else {
        None
      }
    }
}

impl InputTake for [u8] {
    #[inline]
    fn take<P>(&self, count: usize) -> Option<&Self> {
      if self.len() >= count {
        Some(&self[0..count])
      } else {
        None
      }
    }
    #[inline]
    fn take_split<P>(&self, count: usize) -> Option<(&Self,&Self)> {
      if self.len() >= count {
        Some((&self[count..],&self[..count]))
      } else {
        None
      }
    }
}

#[cfg(not(feature = "core"))]
impl<'a> InputIter for &'a str {
    type Item     = char;
    type RawItem  = char;
    type Iter     = CharIndices<'a>;
    type IterElem = Chars<'a>;
    #[inline]
    fn iter_indices(&self) -> CharIndices<'a> {
        self.char_indices()
    }
    #[inline]
    fn iter_elements(&self) -> Chars<'a> {
      self.chars()
    }
    fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
      for (o,c) in self.char_indices() {
        if predicate(c) {
          return Some(o)
        }
      }
      None
    }
    #[inline]
    fn index(&self, count:usize) -> Option<usize> {
      let mut cnt    = 0;
      for (index, _) in self.char_indices() {
        if cnt == count {
          return Some(index)
        }
        cnt += 1;
      }
      if cnt == count {
        return Some(self.len())
      }
      None
    }
}

#[cfg(not(feature = "core"))]
impl InputTake for str {
    #[inline]
    fn take<P>(&self, count: usize) -> Option<&Self> {
      let mut cnt    = 0;
      for (index, _) in self.char_indices() {
        if cnt == count {
          return Some(&self[..index])
        }
        cnt += 1;
      }
      None
    }

    // return byte index
    #[inline]
    fn take_split<P>(&self, count: usize) -> Option<(&Self,&Self)> {
      let mut cnt    = 0;
      for (index, _) in self.char_indices() {
        if cnt == count {
          return Some((&self[index..],&self[..index]))
        }
        cnt += 1;
      }
      None
    }
}

#[derive(Debug,PartialEq)]
pub enum CompareResult {
  Ok,
  Incomplete,
  Error
}

pub trait Compare<T> {
  fn compare(&self, t:T)         -> CompareResult;
  fn compare_no_case(&self, t:T) -> CompareResult;
}

impl<'a,'b> Compare<&'b[u8]> for &'a [u8] {
  #[inline(always)]
  fn compare(&self, t: &'b[u8]) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = &self[..m];
    let b       = &t[..m];

    if reduced != b {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }

  #[inline(always)]
  fn compare_no_case(&self, t: &'b[u8]) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = &self[..m];
    let other   = &t[..m];

    if !reduced.iter().zip(other).all(|(a, b)| {
      match (*a,*b) {
        (0...64, 0...64) | (91...96, 91...96) | (123...255, 123...255) => a == b,
        (65...90, 65...90) | (97...122, 97...122) | (65...90, 97...122 ) |(97...122, 65...90) => {
          *a & 0b01000000 == *b & 0b01000000
        }
        _ => false
      }
    }) {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> Compare<&'b str> for &'a [u8] {
  #[inline(always)]
  fn compare(&self, t: &'b str) -> CompareResult {
    self.compare(str::as_bytes(t))
  }
  #[inline(always)]
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.compare_no_case(str::as_bytes(t))
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> Compare<&'b str> for &'a str {
  #[inline(always)]
  fn compare(&self, t: &'b str) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = unsafe { self.slice_unchecked(0, m) };
    let b       = &t[..m];

    if reduced != b {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }

  //FIXME: this version is too simple and does not use the current locale
  #[inline(always)]
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    let len     = self.len();
    let blen    = t.len();
    let m       = if len < blen { len } else { blen };
    let reduced = unsafe { self.slice_unchecked(0, m) };
    let b       = &t[..m];

    //println!("compare_no_case({}, {}) => {} / {}", self, t, reduced.to_lowercase(), b.to_lowercase());
    if !(reduced.to_lowercase() == b.to_lowercase()) {
      CompareResult::Error
    } else if m < blen {
      CompareResult::Incomplete
    } else {
      CompareResult::Ok
    }
  }
}

pub trait FindToken<T> {
  fn find_token(&self, list: T) -> bool;
}

impl<'a> FindToken<&'a[u8]> for u8 {
  fn find_token(&self, list: &[u8]) -> bool {
    for &i in list.iter() {
      if *self == i { return true }
    }
    false
  }
}

#[cfg(not(feature = "core"))]
impl<'a> FindToken<&'a str> for u8 {
  fn find_token(&self, list: &str) -> bool {
    self.find_token(str::as_bytes(list))
  }
}

#[cfg(not(feature = "core"))]
impl<'a> FindToken<&'a str> for char {
  fn find_token(&self, list: &str) -> bool {
    for i in list.chars() {
      if *self == i { return true }
    }
    false
  }
}

pub trait FindSubstring<T> {
  fn find_substring(&self, substr: T) -> Option<usize>;
}

impl<'a,'b> FindSubstring<&'b [u8]> for &'a[u8] {
  fn find_substring(&self, substr: &'b[u8]) -> Option<usize> {
    for (index,win) in self.windows(substr.len()).enumerate() {
      if win == substr {
        return Some(index)
      }
    }
    None
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> FindSubstring<&'b str> for &'a[u8] {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.find_substring(str::as_bytes(substr))
  }
}

#[cfg(not(feature = "core"))]
impl<'a,'b> FindSubstring<&'b str> for &'a str {
  //returns byte index
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.find(substr)
  }
}

pub trait Slice<R> {
  #[inline(always)]
  fn slice(&self, range: R) -> Self;
}

impl<'a,T> Slice<Range<usize>> for &'a [T] {
  fn slice(&self, range:Range<usize>) -> Self {
    &self[range]
  }
}

impl<'a,T> Slice<RangeTo<usize>> for &'a [T] {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    &self[range]
  }
}

impl<'a,T> Slice<RangeFrom<usize>> for &'a [T] {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    &self[range]
  }
}

impl<'a,T> Slice<RangeFull> for &'a [T] {
  fn slice(&self, range:RangeFull) -> Self {
    &self[range]
  }
}

impl<'a> Slice<Range<usize>> for &'a str {
  fn slice(&self, range:Range<usize>) -> Self {
    &self[range]
  }
}

impl<'a> Slice<RangeTo<usize>> for &'a str {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    &self[range]
  }
}

impl<'a> Slice<RangeFrom<usize>> for &'a str {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    &self[range]
  }
}

impl<'a> Slice<RangeFull> for &'a str {
  fn slice(&self, range:RangeFull) -> Self {
    &self[range]
  }
}
<|endoftext|>


<commit_before>use common::*;
use std::io::{Read, Write};

mod memory;
mod registers;
mod opcodes;
mod modes;

use self::memory::*;

pub struct VM<'a, R: Read, W: Write> {
    input: R,
    output: W,

    registers: Registers,
    memory: Memory<'a>,
}

impl<'a, R: Read, W: Write> VM<'a, R, W> {
    pub fn new(input: R, output: W) -> Self {
        unimplemented!()
    }

    pub fn run(&mut self, executable: Data) {
        unimplemented!()
    }

    fn parse_executable(executable: Data) -> Memory<'a> {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    use self::modes::*;
    use self::opcodes::*;
    use self::registers::*;
    use std::io::{BufReader, BufWriter};
    use super::*;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    #[test]
    fn simple() {
        assert!(run(&[], vec![]).0.is_empty());

        {
            let mut executable = vec![0,
                MOV, REG, A, VALUE, 123, 0,
                ADD, REG, B, REG, A, REG, A];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[], executable);

            assert_eq!(123, registers[A as usize]);
            assert_eq!(246, registers[B as usize]);
            assert!(output.is_empty());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                SUB, REG, SP, 4, 0,  // stack allocation for 2 words
                PUSH, VALUE, 5, 0,
                PUSH, VALUE, 6, 0,
                ADD,   REG, A,   PTR, REG, SP,   PTR_WITH_OFFSET, REG, SP, 2, 0,
                // add a, [sp], [sp+2]
                POP, B,
                POP, C,
                ADD, 4, 0];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory)  = run(&[], executable);

            assert_eq!(11, registers[A as usize]);
            assert_eq!(6, registers[B as usize]);
            assert_eq!(5, registers[C as usize]);
            assert!(output.is_empty());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                MOV, REG, A, VALUE, 10, 0,
                DEC, REG, A,
                WRITE, REG, A,
                JNZ, 0];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[], executable);

            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[10, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5, 0,
                         4, 0, 3, 0, 2, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                MOV, REG, B, VALUE, 20, 0,       // data address
                MOV, REG, A, PTR, REG, B,        // dereference B
                WRITE, REG, A,
                INC, REG, B,
                INC, REG, B,
                JNZ, 0,

                3, 0,                            // data with address 23
                2, 0,                            // data with address 25
                1, 0,
                0, 0];
            let data_length = 8;
            let code_length = executable.len() as u8 - data_length;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[], executable);

            assert_eq!(8, memory.data.len());
            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[3, 0, 2, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                READ, REG, A,
                WRITE, REG, A,
                JNZ, 0];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[3, 0, 2, 0, 1, 0, 0, 0], executable);
            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[3, 0, 2, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                                                   // do
                READ, REG, A,                      //   a = read
                SUB, REG, SP, 2, 0,                //   (stack allocation)
                PUSH, REG, A,
                CALL, VALUE, 28, 0,                //   a = f(a)
                WRITE, REG, A,                     //   print a
                ADD,  REG, SP,  VALUE,  2, 0,      //   (stack deallocation)
                JNZ, 0,                            // while a != 0 goto addr 0
                JMP, 39,                           // exit

                // label f
                PUSH, REG, BP,
                MOV, REG, BP, REG, SP,

                POP, REG, A,
                MUL, REG, A, REG, A, VALUE, 2, 0,  // a = a * 2

                MOV, REG, SP, REG, BP,
                POP, REG, BP,
                RET,

                NOP                                // optional
            ];

            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[3, 0, 2, 0, 1, 0, 0, 0],
                                                  executable);

            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[6, 0, 4, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }
    }

    fn run<'a>(input: &[u8], executable: Data) -> (Data, Registers, Memory<'a>) {
        let input = BufReader::new(input);

        let output: Data = vec![];
        let output = BufWriter::new(output);

        let mut vm = VM::new(input, output);
        vm.run(executable);

        let output = vm.output
            .get_mut()
            .by_ref()
            .iter()
            .map(|x| *x)
            .collect::<Data>();

        (output, vm.registers, vm.memory)
    }
}
<commit_msg>bugfixes<commit_after>use common::*;
use std::io::{Read, Write};

mod memory;
mod registers;
mod opcodes;
mod modes;

use self::memory::*;

pub struct VM<'a, R: Read, W: Write> {
    input: R,
    output: W,

    registers: Registers,
    memory: Memory<'a>,
}

impl<'a, R: Read, W: Write> VM<'a, R, W> {
    pub fn new(input: R, output: W) -> Self {
        unimplemented!()
    }

    pub fn run(&mut self, executable: Data) {
        unimplemented!()
    }

    fn parse_executable(executable: Data) -> Memory<'a> {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    use self::modes::*;
    use self::opcodes::*;
    use self::registers::*;
    use std::io::{BufReader, BufWriter};
    use super::*;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    #[test]
    fn simple() {
        assert!(run(&[], vec![]).0.is_empty());

        {
            let mut executable = vec![0,
                MOV, REG, A, VALUE, 123, 0,
                ADD, REG, B, REG, A, REG, A];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[], executable);

            assert_eq!(123, registers[A as usize]);
            assert_eq!(246, registers[B as usize]);
            assert!(output.is_empty());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                // stack allocation for 2 words
                SUB, REG, SP,  REG, SP,  VALUE, 4, 0,

                PUSH, VALUE, 5, 0,
                PUSH, VALUE, 6, 0,
                ADD,  REG, A,  PTR, REG, SP,  PTR_WITH_OFFSET, REG, SP, 2, 0,
                // add a, [sp], [sp+2]
                POP, B,
                POP, C,
                ADD, REG, SP,  REG, SP,  4, 0];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory)  = run(&[], executable);

            assert_eq!(11, registers[A as usize]);
            assert_eq!(6, registers[B as usize]);
            assert_eq!(5, registers[C as usize]);
            assert!(output.is_empty());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                MOV, REG, A, VALUE, 10, 0,
                DEC, REG, A,
                WRITE, REG, A,
                JNZ, 0, 0];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[], executable);

            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[10, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5, 0,
                         4, 0, 3, 0, 2, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                MOV, REG, B, VALUE, 24, 0,       // data address
                MOV, REG, A, PTR, REG, B,        // dereference B
                WRITE, REG, A,
                INC, REG, B,
                INC, REG, B,
                JNZ, 0, 0,

                3, 0,                            // data with address 24
                2, 0,                            // data with address 26
                1, 0,
                0, 0];
            let data_length = 8;
            let code_length = executable.len() as u8 - data_length;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[], executable);

            assert_eq!(8, memory.data.len());
            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[3, 0, 2, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                READ, REG, A,
                WRITE, REG, A,
                JNZ, 0, 0];
            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[3, 0, 2, 0, 1, 0, 0, 0], executable);
            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[3, 0, 2, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }

        {
            let mut executable = vec![0,
                                                      // do
                READ, REG, A,                         //   a = read
                SUB, REG, SP,  REG, SP,  VALUE, 2, 0, //   (stack allocation)
                PUSH, REG, A,
                CALL, VALUE, 35, 0,                   //   a = f(a)
                WRITE, REG, A,                        //   print a
                ADD, REG, SP,  REG, SP,  VALUE, 2, 0, //   (stack deallocation)
                JNZ, 0, 0,                            // while a != 0 jmp addr 0
                JMP, 63, 0,                           // exit

                // label f
                PUSH, REG, BP,
                MOV, REG, BP, REG, SP,

                POP, REG, A,
                MUL, REG, A, REG, A, VALUE, 2, 0,    // a = a * 2

                MOV, REG, SP, REG, BP,
                POP, REG, BP,
                RET,

                NOP                                  // optional
            ];

            let code_length = executable.len() as u8;
            executable[0] = code_length;

            let (output, registers, memory) = run(&[3, 0, 2, 0, 1, 0, 0, 0],
                                                  executable);

            assert_eq!(0, registers[A as usize]);
            assert_eq!(&[6, 0, 4, 0, 1, 0, 0, 0], output.as_slice());
            assert!(memory.stack_is_empty(registers[SP as usize]));
        }
    }

    fn run<'a>(input: &[u8], executable: Data) -> (Data, Registers, Memory<'a>) {
        let input = BufReader::new(input);

        let output: Data = vec![];
        let output = BufWriter::new(output);

        let mut vm = VM::new(input, output);
        vm.run(executable);

        let output = vm.output
            .get_mut()
            .by_ref()
            .iter()
            .map(|x| *x)
            .collect::<Data>();

        (output, vm.registers, vm.memory)
    }
}
<|endoftext|>


<commit_before>//! The root of each single-threaded worker.

use std::rc::Rc;
use std::cell::{RefCell, RefMut};
use std::any::Any;
use std::time::Instant;
use std::collections::HashMap;
use std::collections::hash_map::Entry;

use communication::{Allocate, Data, Push, Pull};
use communication::allocator::thread::{ThreadPusher, ThreadPuller};
use scheduling::{Schedule, Scheduler, Activations};
use progress::timestamp::{Refines};
use progress::SubgraphBuilder;
use progress::operate::Operate;
use dataflow::scopes::Child;

/// Methods provided by the root Worker.
///
/// These methods are often proxied by child scopes, and this trait provides access.
pub trait AsWorker : Scheduler {

    /// Index of the worker among its peers.
    fn index(&self) -> usize;
    /// Number of peer workers.
    fn peers(&self) -> usize;
    /// Allocates a new channel from a supplied identifier and address.
    ///
    /// The identifier is used to identify the underlying channel and route
    /// its data. It should be distinct from other identifiers passed used
    /// for allocation, but can otherwise be arbitrary.
    ///
    /// The address should specify a path to an operator that should be
    /// scheduled in response to the receipt of records on the channel.
    /// Most commonly, this would be the address of the *target* of the
    /// channel.
    fn allocate<T: Data>(&mut self, identifier: usize, address: &[usize]) -> (Vec<Box<Push<Message<T>>>>, Box<Pull<Message<T>>>);
    /// Constructs a pipeline channel from the worker to itself.
    ///
    /// By default this method uses the native channel allocation mechanism, but the expectation is
    /// that this behavior will be overriden to be more efficient.
    fn pipeline<T: 'static>(&mut self, identifier: usize, address: &[usize]) -> (ThreadPusher<Message<T>>, ThreadPuller<Message<T>>);

    /// Allocates a new worker-unique identifier.
    fn new_identifier(&mut self) -> usize;
    /// Provides access to named logging streams.
    fn log_register(&self) -> ::std::cell::RefMut<::logging_core::Registry<::logging::WorkerIdentifier>>;
    /// Provides access to the timely logging stream.
    fn logging(&self) -> Option<::logging::TimelyLogger> { self.log_register().get("timely") }
}

/// A `Worker` is the entry point to a timely dataflow computation. It wraps a `Allocate`,
/// and has a list of dataflows that it manages.
pub struct Worker<A: Allocate> {
    timer: Instant,
    paths: Rc<RefCell<Vec<Vec<usize>>>>,
    allocator: Rc<RefCell<A>>,
    identifiers: Rc<RefCell<usize>>,
    // dataflows: Rc<RefCell<Vec<Wrapper>>>,
    dataflows: Rc<RefCell<HashMap<usize, Wrapper>>>,
    dataflow_counter: Rc<RefCell<usize>>,
    logging: Rc<RefCell<::logging_core::Registry<::logging::WorkerIdentifier>>>,

    activations: Rc<RefCell<Activations>>,
    active_dataflows: Vec<usize>,
}

impl<A: Allocate> AsWorker for Worker<A> {
    fn index(&self) -> usize { self.allocator.borrow().index() }
    fn peers(&self) -> usize { self.allocator.borrow().peers() }
    fn allocate<D: Data>(&mut self, identifier: usize, address: &[usize]) -> (Vec<Box<Push<Message<D>>>>, Box<Pull<Message<D>>>) {
        if address.len() == 0 { panic!("Unacceptable address: Length zero"); }
        // println!("Exchange allocation; path: {:?}, identifier: {:?}", address, identifier);
        let mut paths = self.paths.borrow_mut();
        while paths.len() <= identifier {
            paths.push(Vec::new());
        }
        paths[identifier] = address.to_vec();
        self.allocator.borrow_mut().allocate(identifier)
    }
    fn pipeline<T: 'static>(&mut self, identifier: usize, address: &[usize]) -> (ThreadPusher<Message<T>>, ThreadPuller<Message<T>>) {
        if address.len() == 0 { panic!("Unacceptable address: Length zero"); }
        // println!("Pipeline allocation; path: {:?}, identifier: {:?}", address, identifier);
        let mut paths = self.paths.borrow_mut();
        while paths.len() <= identifier {
            paths.push(Vec::new());
        }
        paths[identifier] = address.to_vec();
        self.allocator.borrow_mut().pipeline(identifier)
    }

    fn new_identifier(&mut self) -> usize { self.new_identifier() }
    fn log_register(&self) -> RefMut<::logging_core::Registry<::logging::WorkerIdentifier>> {
        self.log_register()
    }
}

impl<A: Allocate> Scheduler for Worker<A> {
    fn activations(&self) -> Rc<RefCell<Activations>> {
        self.activations.clone()
    }
}

impl<A: Allocate> Worker<A> {
    /// Allocates a new `Worker` bound to a channel allocator.
    pub fn new(c: A) -> Worker<A> {
        let now = Instant::now();
        let index = c.index();
        Worker {
            timer: now.clone(),
            paths: Rc::new(RefCell::new(Vec::new())),
            allocator: Rc::new(RefCell::new(c)),
            identifiers: Rc::new(RefCell::new(0)),
            dataflows: Rc::new(RefCell::new(HashMap::new())),
            dataflow_counter: Rc::new(RefCell::new(0)),
            logging: Rc::new(RefCell::new(::logging_core::Registry::new(now, index))),
            activations: Rc::new(RefCell::new(Activations::new())),
            active_dataflows: Vec::new(),
        }
    }

    /// Performs one step of the computation.
    ///
    /// A step gives each dataflow operator a chance to run, and is the
    /// main way to ensure that a computation proceeds.
    pub fn step(&mut self) -> bool {

        {   // Process channel events. Activate responders.
            let mut allocator = self.allocator.borrow_mut();
            allocator.receive();
            let events = allocator.events().clone();
            let mut borrow = events.borrow_mut();
            let paths = self.paths.borrow();
            for (channel, _event) in borrow.drain(..) {
                // TODO: Pay more attent to `_event`.
                // Consider tracking whether a channel
                // in non-empty, and only activating
                // on the basis of non-empty channels.
                // TODO: This is a sloppy way to deal
                // with channels that may not be alloc'd.
                if let Some(path) = paths.get(channel) {
                    // println!("Message for {:?}", path);
                    self.activations
                        .borrow_mut()
                        .activate(&path[..]);
                }
            }
        }

        // Organize activations.
        self.activations
            .borrow_mut()
            .advance();

        // self.activations.borrow().map_active(|path| println!("active path: {:?}", path));

        {   // Schedule active dataflows.

            let active_dataflows = &mut self.active_dataflows;
            self.activations
                .borrow_mut()
                .for_extensions(&[], |index| active_dataflows.push(index));

            // println!("scheduling {} dataflows", active_dataflows.len());

            let mut dataflows = self.dataflows.borrow_mut();
            for index in active_dataflows.drain(..) {
                // Step dataflow if it exists, remove if not incomplete.
                if let Entry::Occupied(mut entry) = dataflows.entry(index) {
                    // println!("Scheduling dataflow {}", index);
                    let incomplete = entry.get_mut().step();
                    if !incomplete {
                        entry.remove_entry();
                    }
                }
            }
        }

        // Clean up, indicate if dataflows remain.
        self.logging.borrow_mut().flush();
        self.allocator.borrow_mut().release();
        !self.dataflows.borrow().is_empty()
    }

    /// Calls `self.step()` as long as `func` evaluates to true.
    pub fn step_while<F: FnMut()->bool>(&mut self, mut func: F) {
        while func() { self.step(); }
    }

    /// The index of the worker out of its peers.
    pub fn index(&self) -> usize { self.allocator.borrow().index() }
    /// The total number of peer workers.
    pub fn peers(&self) -> usize { self.allocator.borrow().peers() }

    /// A timer started at the initiation of the timely computation.
    pub fn timer(&self) -> Instant { self.timer }

    /// Allocate a new worker-unique identifier.
    pub fn new_identifier(&mut self) -> usize {
        *self.identifiers.borrow_mut() += 1;
        *self.identifiers.borrow() - 1
    }

    /// Access to named loggers.
    pub fn log_register(&self) -> ::std::cell::RefMut<::logging_core::Registry<::logging::WorkerIdentifier>> {
        self.logging.borrow_mut()
    }

    /// Construct a new dataflow.
    pub fn dataflow<T, R, F>(&mut self, func: F) -> R
    where
        T: Refines<()>,
        F: FnOnce(&mut Child<Self, T>)->R,
    {
        self.dataflow_using(Box::new(()), |_, child| func(child))
    }

    /// Construct a new dataflow binding resources that are released only after the dataflow is dropped.
    ///
    /// This method is designed to allow the dataflow builder to use certain resources that are then stashed
    /// with the dataflow until it has completed running. Once complete, the resources are dropped. The most
    /// common use of this method at present is with loading shared libraries, where the library is important
    /// for building the dataflow, and must be kept around until after the dataflow has completed operation.
    pub fn dataflow_using<T, R, F, V>(&mut self, mut resources: V, func: F) -> R
    where
        T: Refines<()>,
        F: FnOnce(&mut V, &mut Child<Self, T>)->R,
        V: Any+'static,
    {

        // let addr = vec![self.allocator.borrow().index()];
        let addr = vec![];
        let dataflow_index = self.allocate_dataflow_index();

        let mut logging = self.logging.borrow_mut().get("timely");
        let subscope = SubgraphBuilder::new_from(dataflow_index, addr, logging.clone(), "Dataflow");
        let subscope = RefCell::new(subscope);

        let result = {
            let mut builder = Child {
                subgraph: &subscope,
                parent: self.clone(),
                logging: logging.clone(),
            };
            func(&mut resources, &mut builder)
        };

        logging.as_mut().map(|l| l.flush());

        let mut operator = subscope.into_inner().build(self);

        operator.get_internal_summary();
        operator.set_external_summary();

        let wrapper = Wrapper {
            operate: Some(Box::new(operator)),
            resources: Some(Box::new(resources)),
        };
        self.dataflows.borrow_mut().insert(dataflow_index, wrapper);

        result

    }

    // Acquire a new distinct dataflow identifier.
    fn allocate_dataflow_index(&mut self) -> usize {
        *self.dataflow_counter.borrow_mut() += 1;
        *self.dataflow_counter.borrow() - 1
    }
}

use communication::Message;

impl<A: Allocate> Clone for Worker<A> {
    fn clone(&self) -> Self {
        Worker {
            timer: self.timer,
            paths: self.paths.clone(),
            allocator: self.allocator.clone(),
            identifiers: self.identifiers.clone(),
            dataflows: self.dataflows.clone(),
            dataflow_counter: self.dataflow_counter.clone(),
            logging: self.logging.clone(),
            activations: self.activations.clone(),
            active_dataflows: Vec::new(),
        }
    }
}

struct Wrapper {
    operate: Option<Box<Schedule>>,
    resources: Option<Box<Any>>,
}

impl Wrapper {
    /// Steps the dataflow, indicates if it remains incomplete.
    ///
    /// If the dataflow is incomplete, this call will drop it and its resources,
    /// dropping the dataflow first and then the resources (so that, e.g., shared
    /// library bindings will outlive the dataflow).
    fn step(&mut self) -> bool {
        let incomplete = self.operate.as_mut().map(|op| op.schedule()).unwrap_or(false);
        if !incomplete {
            self.operate = None;
            self.resources = None;
        }
        incomplete
    }
}

impl Drop for Wrapper {
    fn drop(&mut self) {
        // ensure drop order
        self.operate = None;
        self.resources = None;
    }
}
<commit_msg>log dataflow scheduling<commit_after>//! The root of each single-threaded worker.

use std::rc::Rc;
use std::cell::{RefCell, RefMut};
use std::any::Any;
use std::time::Instant;
use std::collections::HashMap;
use std::collections::hash_map::Entry;

use communication::{Allocate, Data, Push, Pull};
use communication::allocator::thread::{ThreadPusher, ThreadPuller};
use scheduling::{Schedule, Scheduler, Activations};
use progress::timestamp::{Refines};
use progress::SubgraphBuilder;
use progress::operate::Operate;
use dataflow::scopes::Child;
use logging::TimelyLogger;

/// Methods provided by the root Worker.
///
/// These methods are often proxied by child scopes, and this trait provides access.
pub trait AsWorker : Scheduler {

    /// Index of the worker among its peers.
    fn index(&self) -> usize;
    /// Number of peer workers.
    fn peers(&self) -> usize;
    /// Allocates a new channel from a supplied identifier and address.
    ///
    /// The identifier is used to identify the underlying channel and route
    /// its data. It should be distinct from other identifiers passed used
    /// for allocation, but can otherwise be arbitrary.
    ///
    /// The address should specify a path to an operator that should be
    /// scheduled in response to the receipt of records on the channel.
    /// Most commonly, this would be the address of the *target* of the
    /// channel.
    fn allocate<T: Data>(&mut self, identifier: usize, address: &[usize]) -> (Vec<Box<Push<Message<T>>>>, Box<Pull<Message<T>>>);
    /// Constructs a pipeline channel from the worker to itself.
    ///
    /// By default this method uses the native channel allocation mechanism, but the expectation is
    /// that this behavior will be overriden to be more efficient.
    fn pipeline<T: 'static>(&mut self, identifier: usize, address: &[usize]) -> (ThreadPusher<Message<T>>, ThreadPuller<Message<T>>);

    /// Allocates a new worker-unique identifier.
    fn new_identifier(&mut self) -> usize;
    /// Provides access to named logging streams.
    fn log_register(&self) -> ::std::cell::RefMut<::logging_core::Registry<::logging::WorkerIdentifier>>;
    /// Provides access to the timely logging stream.
    fn logging(&self) -> Option<::logging::TimelyLogger> { self.log_register().get("timely") }
}

/// A `Worker` is the entry point to a timely dataflow computation. It wraps a `Allocate`,
/// and has a list of dataflows that it manages.
pub struct Worker<A: Allocate> {
    timer: Instant,
    paths: Rc<RefCell<Vec<Vec<usize>>>>,
    allocator: Rc<RefCell<A>>,
    identifiers: Rc<RefCell<usize>>,
    // dataflows: Rc<RefCell<Vec<Wrapper>>>,
    dataflows: Rc<RefCell<HashMap<usize, Wrapper>>>,
    dataflow_counter: Rc<RefCell<usize>>,
    logging: Rc<RefCell<::logging_core::Registry<::logging::WorkerIdentifier>>>,

    activations: Rc<RefCell<Activations>>,
    active_dataflows: Vec<usize>,
}

impl<A: Allocate> AsWorker for Worker<A> {
    fn index(&self) -> usize { self.allocator.borrow().index() }
    fn peers(&self) -> usize { self.allocator.borrow().peers() }
    fn allocate<D: Data>(&mut self, identifier: usize, address: &[usize]) -> (Vec<Box<Push<Message<D>>>>, Box<Pull<Message<D>>>) {
        if address.len() == 0 { panic!("Unacceptable address: Length zero"); }
        // println!("Exchange allocation; path: {:?}, identifier: {:?}", address, identifier);
        let mut paths = self.paths.borrow_mut();
        while paths.len() <= identifier {
            paths.push(Vec::new());
        }
        paths[identifier] = address.to_vec();
        self.allocator.borrow_mut().allocate(identifier)
    }
    fn pipeline<T: 'static>(&mut self, identifier: usize, address: &[usize]) -> (ThreadPusher<Message<T>>, ThreadPuller<Message<T>>) {
        if address.len() == 0 { panic!("Unacceptable address: Length zero"); }
        // println!("Pipeline allocation; path: {:?}, identifier: {:?}", address, identifier);
        let mut paths = self.paths.borrow_mut();
        while paths.len() <= identifier {
            paths.push(Vec::new());
        }
        paths[identifier] = address.to_vec();
        self.allocator.borrow_mut().pipeline(identifier)
    }

    fn new_identifier(&mut self) -> usize { self.new_identifier() }
    fn log_register(&self) -> RefMut<::logging_core::Registry<::logging::WorkerIdentifier>> {
        self.log_register()
    }
}

impl<A: Allocate> Scheduler for Worker<A> {
    fn activations(&self) -> Rc<RefCell<Activations>> {
        self.activations.clone()
    }
}

impl<A: Allocate> Worker<A> {
    /// Allocates a new `Worker` bound to a channel allocator.
    pub fn new(c: A) -> Worker<A> {
        let now = Instant::now();
        let index = c.index();
        Worker {
            timer: now.clone(),
            paths: Rc::new(RefCell::new(Vec::new())),
            allocator: Rc::new(RefCell::new(c)),
            identifiers: Rc::new(RefCell::new(0)),
            dataflows: Rc::new(RefCell::new(HashMap::new())),
            dataflow_counter: Rc::new(RefCell::new(0)),
            logging: Rc::new(RefCell::new(::logging_core::Registry::new(now, index))),
            activations: Rc::new(RefCell::new(Activations::new())),
            active_dataflows: Vec::new(),
        }
    }

    /// Performs one step of the computation.
    ///
    /// A step gives each dataflow operator a chance to run, and is the
    /// main way to ensure that a computation proceeds.
    pub fn step(&mut self) -> bool {

        {   // Process channel events. Activate responders.
            let mut allocator = self.allocator.borrow_mut();
            allocator.receive();
            let events = allocator.events().clone();
            let mut borrow = events.borrow_mut();
            let paths = self.paths.borrow();
            for (channel, _event) in borrow.drain(..) {
                // TODO: Pay more attent to `_event`.
                // Consider tracking whether a channel
                // in non-empty, and only activating
                // on the basis of non-empty channels.
                // TODO: This is a sloppy way to deal
                // with channels that may not be alloc'd.
                if let Some(path) = paths.get(channel) {
                    // println!("Message for {:?}", path);
                    self.activations
                        .borrow_mut()
                        .activate(&path[..]);
                }
            }
        }

        // Organize activations.
        self.activations
            .borrow_mut()
            .advance();

        // self.activations.borrow().map_active(|path| println!("active path: {:?}", path));

        {   // Schedule active dataflows.

            let active_dataflows = &mut self.active_dataflows;
            self.activations
                .borrow_mut()
                .for_extensions(&[], |index| active_dataflows.push(index));

            // println!("scheduling {} dataflows", active_dataflows.len());

            let mut dataflows = self.dataflows.borrow_mut();
            for index in active_dataflows.drain(..) {
                // Step dataflow if it exists, remove if not incomplete.
                if let Entry::Occupied(mut entry) = dataflows.entry(index) {
                    // println!("Scheduling dataflow {}", index);
                    let incomplete = entry.get_mut().step();
                    if !incomplete {
                        entry.remove_entry();
                    }
                }
            }
        }

        // Clean up, indicate if dataflows remain.
        self.logging.borrow_mut().flush();
        self.allocator.borrow_mut().release();
        !self.dataflows.borrow().is_empty()
    }

    /// Calls `self.step()` as long as `func` evaluates to true.
    pub fn step_while<F: FnMut()->bool>(&mut self, mut func: F) {
        while func() { self.step(); }
    }

    /// The index of the worker out of its peers.
    pub fn index(&self) -> usize { self.allocator.borrow().index() }
    /// The total number of peer workers.
    pub fn peers(&self) -> usize { self.allocator.borrow().peers() }

    /// A timer started at the initiation of the timely computation.
    pub fn timer(&self) -> Instant { self.timer }

    /// Allocate a new worker-unique identifier.
    pub fn new_identifier(&mut self) -> usize {
        *self.identifiers.borrow_mut() += 1;
        *self.identifiers.borrow() - 1
    }

    /// Access to named loggers.
    pub fn log_register(&self) -> ::std::cell::RefMut<::logging_core::Registry<::logging::WorkerIdentifier>> {
        self.logging.borrow_mut()
    }

    /// Construct a new dataflow.
    pub fn dataflow<T, R, F>(&mut self, func: F) -> R
    where
        T: Refines<()>,
        F: FnOnce(&mut Child<Self, T>)->R,
    {
        self.dataflow_using(Box::new(()), |_, child| func(child))
    }

    /// Construct a new dataflow binding resources that are released only after the dataflow is dropped.
    ///
    /// This method is designed to allow the dataflow builder to use certain resources that are then stashed
    /// with the dataflow until it has completed running. Once complete, the resources are dropped. The most
    /// common use of this method at present is with loading shared libraries, where the library is important
    /// for building the dataflow, and must be kept around until after the dataflow has completed operation.
    pub fn dataflow_using<T, R, F, V>(&mut self, mut resources: V, func: F) -> R
    where
        T: Refines<()>,
        F: FnOnce(&mut V, &mut Child<Self, T>)->R,
        V: Any+'static,
    {

        // let addr = vec![self.allocator.borrow().index()];
        let addr = vec![];
        let dataflow_index = self.allocate_dataflow_index();
        let identifier = self.new_identifier();

        let mut logging = self.logging.borrow_mut().get("timely");

        let subscope = SubgraphBuilder::new_from(dataflow_index, addr, logging.clone(), "Dataflow");
        let subscope = RefCell::new(subscope);

        let result = {
            let mut builder = Child {
                subgraph: &subscope,
                parent: self.clone(),
                logging: logging.clone(),
            };
            func(&mut resources, &mut builder)
        };

        let mut operator = subscope.into_inner().build(self);

        logging.as_mut().map(|l| l.log(::logging::OperatesEvent {
            id: identifier,
            addr: operator.path().to_vec(),
            name: operator.name().to_string(),
        }));

        logging.as_mut().map(|l| l.flush());

        operator.get_internal_summary();
        operator.set_external_summary();

        let wrapper = Wrapper {
            logging,
            identifier,
            operate: Some(Box::new(operator)),
            resources: Some(Box::new(resources)),
        };
        self.dataflows.borrow_mut().insert(dataflow_index, wrapper);

        result

    }

    // Acquire a new distinct dataflow identifier.
    fn allocate_dataflow_index(&mut self) -> usize {
        *self.dataflow_counter.borrow_mut() += 1;
        *self.dataflow_counter.borrow() - 1
    }
}

use communication::Message;

impl<A: Allocate> Clone for Worker<A> {
    fn clone(&self) -> Self {
        Worker {
            timer: self.timer,
            paths: self.paths.clone(),
            allocator: self.allocator.clone(),
            identifiers: self.identifiers.clone(),
            dataflows: self.dataflows.clone(),
            dataflow_counter: self.dataflow_counter.clone(),
            logging: self.logging.clone(),
            activations: self.activations.clone(),
            active_dataflows: Vec::new(),
        }
    }
}

struct Wrapper {
    logging: Option<TimelyLogger>,
    identifier: usize,
    operate: Option<Box<Schedule>>,
    resources: Option<Box<Any>>,
}

impl Wrapper {
    /// Steps the dataflow, indicates if it remains incomplete.
    ///
    /// If the dataflow is incomplete, this call will drop it and its resources,
    /// dropping the dataflow first and then the resources (so that, e.g., shared
    /// library bindings will outlive the dataflow).
    fn step(&mut self) -> bool {

        // Perhaps log information about the start of the schedule call.
        if let Some(l) = self.logging.as_mut() {
            l.log(::logging::ScheduleEvent::start(self.identifier));
        }

        let incomplete = self.operate.as_mut().map(|op| op.schedule()).unwrap_or(false);
        if !incomplete {
            self.operate = None;
            self.resources = None;
        }

        // Perhaps log information about the stop of the schedule call.
        if let Some(l) = self.logging.as_mut() {
            l.log(::logging::ScheduleEvent::stop(self.identifier));
        }

        incomplete
    }
}

impl Drop for Wrapper {
    fn drop(&mut self) {
        // ensure drop order
        self.operate = None;
        self.resources = None;
    }
}
<|endoftext|>


<commit_before>use std::io;

use crate::error::*;
use crate::types::*;
use std::fmt;

pub struct Writer<R> {
    buffer: R,
}

impl<R: io::Write> Writer<R> {
    pub fn new(inner: R) -> Self {
        Writer { buffer: inner }
    }

    pub fn write_snapshot<T: fmt::Display>(&mut self, snapshot: &Snapshot<T>) -> Result<()> {
        self.buffer.write(snapshot.size().to_string().as_bytes())?;
        self.buffer.write(b"\n")?;
        self.buffer.write(snapshot.comment.as_bytes())?;
        self.buffer.write(b"\n")?;
        for atom in &snapshot.atoms {
            self.buffer.write(format!("{}", atom).as_bytes())?;
            self.buffer.write(b"\n")?;
        }
        self.buffer.flush()?;
        Ok(())
    }
}

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

    #[test]
    fn test_write() {
        let mut buffer: Vec<u8> = vec![];
        {
            let mut writer = Writer::new(&mut buffer);
            let result = writer.write_snapshot(&Snapshot {
                comment: "comment".to_string(),
                atoms: vec![
                    Atom::new("C", 10.2, 13.4, 8.9),
                    Atom::new("N", 3.1, 10.8, 13.6),
                    Atom::new("H", 5.7, 13.4, 4.6),
                ],
            });
            assert!(result.is_ok());
        }
        let string = String::from_utf8(buffer);
        assert!(string.is_ok());
        assert_eq!(
            "3\n\
             comment\n\
             C 10.2 13.4 8.9\n\
             N 3.1 10.8 13.6\n\
             H 5.7 13.4 4.6\n",
            string.unwrap()
        );
    }
}
<commit_msg>:recycle: Use writeln! format for Writer<commit_after>use std::io;

use crate::error::*;
use crate::types::*;
use std::fmt;

pub struct Writer<R> {
    buffer: R,
}

impl<R: io::Write> Writer<R> {
    pub fn new(inner: R) -> Self {
        Writer { buffer: inner }
    }

    pub fn write_snapshot<T>(&mut self, snapshot: &Snapshot<T>) -> Result<()>
    where
        T: fmt::Display,
    {
        writeln!(self.buffer, "{}", snapshot.size())?;
        writeln!(self.buffer, "{}", snapshot.comment)?;
        for atom in &snapshot.atoms {
            writeln!(self.buffer, "{}", atom)?;
        }
        self.buffer.flush()?;
        Ok(())
    }
}

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

    #[test]
    fn test_write() {
        let mut buffer: Vec<u8> = vec![];
        {
            let mut writer = Writer::new(&mut buffer);
            let result = writer.write_snapshot(&Snapshot {
                comment: "comment".to_string(),
                atoms: vec![
                    Atom::new("C", 10.2, 13.4, 8.9),
                    Atom::new("N", 3.1, 10.8, 13.6),
                    Atom::new("H", 5.7, 13.4, 4.6),
                ],
            });
            assert!(result.is_ok());
        }
        let string = String::from_utf8(buffer);
        assert!(string.is_ok());
        assert_eq!(
            "3\n\
             comment\n\
             C 10.2 13.4 8.9\n\
             N 3.1 10.8 13.6\n\
             H 5.7 13.4 4.6\n",
            string.unwrap()
        );
    }
}
<|endoftext|>