<commit_before>const DOUBLE: u8 = 1;
const COMM_1: u8 = 2;
const COMM_2: u8 = 4;
const VARIAB: u8 = 8;
const ARRAY: u8 = 16;
const METHOD: u8 = 32;

bitflags! {
    struct ArgumentFlags: u8 {
        /// Double quotes
        const DOUBLE = 0b00000001;
        /// Command flags
        const COMM_1 = 0b00000010; // found $
        const COMM_2 = 0b00000100; // found ( after $
        /// String variable
        const VARIAB = 0b00001000;
        /// Array variable
        const ARRAY  = 0b00010000;
        const METHOD = 0b00100000;
    }
}

/// An efficient `Iterator` structure for splitting arguments
pub struct ArgumentSplitter<'a> {
    data:  &'a str,
    /// Number of bytes read
    read:  usize,
    flags: u8,
    bitflags: ArgumentFlags,
}

impl<'a> ArgumentSplitter<'a> {
    pub fn new(data: &'a str) -> ArgumentSplitter<'a> {
        ArgumentSplitter {
            data:  data,
            read:  0,
            flags: 0,
            bitflags: ArgumentFlags::empty(),
        }
    }
}

impl<'a> ArgumentSplitter<'a> {
    fn scan_singlequotes<B: Iterator<Item = u8>>(&mut self, bytes: &mut B) {
        while let Some(character) = bytes.next() {
            match character {
                b'\\' => {
                    self.read += 2;
                    let _ = bytes.next();
                    continue;
                }
                b'\'' => break,
                _ => (),
            }
            self.read += 1;
        }
    }
}

impl<'a> Iterator for ArgumentSplitter<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        let data = self.data.as_bytes();
        while let Some(&b' ') = data.get(self.read) {
            self.read += 1;
        }
        let start = self.read;

        // parenthesis level and array bracket level
        let (mut level, mut alevel) = (0, 0);
        let mut bytes = data.iter().cloned().skip(self.read);
        while let Some(character) = bytes.next() {
            match character {
                // Skip the next byte.
                b'\\' => {
                    self.read += 2;
                    let _ = bytes.next();
                    continue;
                }
                // Disable COMM_1 and enable COMM_2 + ARRAY.
                b'@' => {
                    self.flags = (self.flags & (255 ^ COMM_1)) | (COMM_2 + ARRAY);
                    self.bitflags.remove(ArgumentFlags::COMM_1);
                    self.bitflags.insert(
                        ArgumentFlags::COMM_2 | ArgumentFlags::ARRAY
                    );
                    self.read += 1;
                    continue;
                }
                // Disable COMM_2 and enable COMM_1 + VARIAB.
                b'$' => {
                    self.flags = (self.flags & (255 ^ COMM_2)) | (COMM_1 + VARIAB);
                    self.bitflags.remove(ArgumentFlags::COMM_2);
                    self.bitflags.insert(
                        ArgumentFlags::COMM_1 | ArgumentFlags::VARIAB
                    );
                    self.read += 1;
                    continue;
                }
                // Increment the array level
                b'[' => alevel += 1,
                // Decrement the array level
                b']' => alevel -= 1,
                b'(' => {
                    // if VARIAB or ARRAY are set
                    // Disable VARIAB + ARRAY and enable METHOD.
                    if self.bitflags.intersects(
                        ArgumentFlags::VARIAB | ArgumentFlags::ARRAY
                    ) {
                        self.flags = (self.flags & (255 ^ (VARIAB + ARRAY))) | METHOD;
                        self.bitflags.remove(
                            ArgumentFlags::VARIAB | ArgumentFlags::ARRAY
                        );
                        self.bitflags.insert(ArgumentFlags::METHOD);
                    }
                    level += 1;
                }
                // Toggle double quote rules.
                b'"' => {
                    self.flags ^= DOUBLE;
                    self.bitflags.toggle(ArgumentFlags::DOUBLE);
                }
                // Loop through characters until single quote rules are completed.
                b'\'' if self.flags & DOUBLE == 0 => {
                    self.scan_singlequotes(&mut bytes);
                    self.read += 2;
                    continue;
                }
                // Break from the loop once a root-level space is found.
                b' ' if (self.flags & (DOUBLE + METHOD)) + level + alevel == 0 => break,
                _ => (),
            }
            self.read += 1;
            // disable COMM_1 and COMM_2
            self.flags &= 255 ^ (COMM_1 + COMM_2);
            self.bitflags.remove(
                ArgumentFlags::COMM_1 | ArgumentFlags::COMM_2
            );
        }

        if start == self.read {
            None
        } else {
            Some(&self.data[start..self.read])
        }
    }
}

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

    fn compare(input: &str, expected: Vec<&str>) {
        let arguments = ArgumentSplitter::new(input).collect::<Vec<&str>>();
        for (left, right) in expected.iter().zip(arguments.iter()) {
            assert_eq!(left, right);
        }
        assert_eq!(expected.len(), arguments.len());
    }

    #[test]
    fn methods() {
        let input = "echo $join(array, ', ') @split(var, ', ')";
        let expected = vec!["echo", "$join(array, ', ')", "@split(var, ', ')"];
        compare(input, expected);
    }

    #[test]
    fn processes() {
        let input = "echo $(echo one $(echo two)) @[echo one @[echo two]]";
        let expected = vec!["echo", "$(echo one $(echo two))", "@[echo one @[echo two]]"];
        compare(input, expected);
    }

    #[test]
    fn arrays() {
        let input = "echo [ one two @[echo three four] five ] [ six seven ]";
        let expected = vec![
            "echo",
            "[ one two @[echo three four] five ]",
            "[ six seven ]",
        ];
        compare(input, expected);
    }

    #[test]
    fn quotes() {
        let input = "echo 'one two \"three four\"' \"five six 'seven eight'\"";
        let expected = vec![
            "echo",
            "'one two \"three four\"'",
            "\"five six 'seven eight'\"",
        ];
        compare(input, expected);
    }
}
<commit_msg>factored out flags in favor of bitflags<commit_after>bitflags! {
    struct ArgumentFlags: u8 {
        /// Double quotes
        const DOUBLE = 0b00000001;
        /// Command flags
        const COMM_1 = 0b00000010; // found $
        const COMM_2 = 0b00000100; // found ( after $
        /// String variable
        const VARIAB = 0b00001000;
        /// Array variable
        const ARRAY  = 0b00010000;
        const METHOD = 0b00100000;
    }
}

/// An efficient `Iterator` structure for splitting arguments
pub struct ArgumentSplitter<'a> {
    data:  &'a str,
    /// Number of bytes read
    read:  usize,
    bitflags: ArgumentFlags,
}

impl<'a> ArgumentSplitter<'a> {
    pub fn new(data: &'a str) -> ArgumentSplitter<'a> {
        ArgumentSplitter {
            data:  data,
            read:  0,
            bitflags: ArgumentFlags::empty(),
        }
    }
}

impl<'a> ArgumentSplitter<'a> {
    fn scan_singlequotes<B: Iterator<Item = u8>>(&mut self, bytes: &mut B) {
        while let Some(character) = bytes.next() {
            match character {
                b'\\' => {
                    self.read += 2;
                    let _ = bytes.next();
                    continue;
                }
                b'\'' => break,
                _ => (),
            }
            self.read += 1;
        }
    }
}

impl<'a> Iterator for ArgumentSplitter<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        let data = self.data.as_bytes();
        while let Some(&b' ') = data.get(self.read) {
            self.read += 1;
        }
        let start = self.read;

        let (mut level, mut alevel) = (0, 0);
        let mut bytes = data.iter().cloned().skip(self.read);
        while let Some(character) = bytes.next() {

            match character {
                // Skip the next byte.
                b'\\' => {
                    self.read += 2;
                    let _ = bytes.next();
                    continue;
                }
                // Disable COMM_1 and enable COMM_2 + ARRAY.
                b'@' => {
                    self.bitflags.remove(ArgumentFlags::COMM_1);
                    self.bitflags.insert(
                        ArgumentFlags::COMM_2 | ArgumentFlags::ARRAY
                    );
                    self.read += 1;
                    continue;
                }
                // Disable COMM_2 and enable COMM_1 + VARIAB.
                b'$' => {
                    self.bitflags.remove(ArgumentFlags::COMM_2);
                    self.bitflags.insert(
                        ArgumentFlags::COMM_1 | ArgumentFlags::VARIAB
                    );
                    self.read += 1;
                    continue;
                }
                // Increment the array level
                b'[' => alevel += 1,
                // Decrement the array level
                b']' => alevel -= 1,

                b'(' => {
                    // Disable VARIAB + ARRAY and enable METHOD.
                    // if variab or array are set
                    if self.bitflags.intersects(
                        ArgumentFlags::VARIAB | ArgumentFlags::ARRAY
                    ) {
                        self.bitflags.remove(
                            ArgumentFlags::VARIAB | ArgumentFlags::ARRAY
                        );
                        self.bitflags.insert(ArgumentFlags::METHOD);
                    }
                    level += 1
                }
                b')' => {
                    if self.bitflags.contains(ArgumentFlags::METHOD) {
                        self.bitflags.remove(ArgumentFlags::METHOD);
                    }
                    level -= 1;
                }

                // Toggle double quote rules.
                b'"' => {
                    self.bitflags.toggle(ArgumentFlags::DOUBLE);
                }
                // Loop through characters until single quote rules are completed.
                b'\'' if !self.bitflags.contains(ArgumentFlags::DOUBLE) => {
                    self.scan_singlequotes(&mut bytes);
                    self.read += 2;
                    continue;
                }
                // b' ' if (!self.bitflags.contains(
                //     ArgumentFlags::DOUBLE | ArgumentFlags::METHOD
                // ) && level + alevel == 0) => break,
                // Break from the loop once a root-level space is found.
                b' ' => {
                    if !self.bitflags.intersects(
                        ArgumentFlags::DOUBLE | ArgumentFlags::METHOD
                    ) && level == 0 && alevel == 0 {
                        break;
                    }
                }
                _ => (),
            }

            self.read += 1;
            // disable COMM_1 and COMM_2
            self.bitflags.remove(
                ArgumentFlags::COMM_1 | ArgumentFlags::COMM_2
            );
        }

        if start == self.read {
            None
        } else {
            Some(&self.data[start..self.read])
        }
    }
}

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

    fn compare(input: &str, expected: Vec<&str>) {
        let arguments = ArgumentSplitter::new(input).collect::<Vec<&str>>();
        for (left, right) in expected.iter().zip(arguments.iter()) {
            assert_eq!(left, right);
        }
        assert_eq!(expected.len(), arguments.len());
    }

    #[test]
    fn methods() {
        let input = "echo $join(array, ', ') @split(var, ', ')";
        let expected = vec!["echo", "$join(array, ', ')", "@split(var, ', ')"];
        compare(input, expected);
    }

    #[test]
    fn processes() {
        let input = "echo $(echo one $(echo two)) @[echo one @[echo two]]";
        let expected = vec!["echo", "$(echo one $(echo two))", "@[echo one @[echo two]]"];
        compare(input, expected);
    }

    #[test]
    fn arrays() {
        let input = "echo [ one two @[echo three four] five ] [ six seven ]";
        let expected = vec![
            "echo",
            "[ one two @[echo three four] five ]",
            "[ six seven ]",
        ];
        compare(input, expected);
    }

    #[test]
    fn quotes() {
        let input = "echo 'one two \"three four\"' \"five six 'seven eight'\"";
        let expected = vec![
            "echo",
            "'one two \"three four\"'",
            "\"five six 'seven eight'\"",
        ];
        compare(input, expected);
    }
}
<|endoftext|>


<commit_before>use std::os::getenv;
use std::io::{stdout, stderr};
use std::collections::HashSet;

use argparse::{ArgumentParser, List};

use config::Config;
use config::command::{Networking};
use config::command::{main};

pub struct Graph {
    pub drop_pairs: Vec<(String, String)>,
    pub isolate: Vec<String>,
}

pub fn full_mesh_cmd(_config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Returns network back to full connectivity");
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    return Ok(Graph { drop_pairs: vec!(), isolate: vec!() });
}

pub fn disjoint_graph_cmd(config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    let mut nodes: Vec<String> = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Splits graph into few disjoint clusters. Each node must be
            specified exactly once. Clusters are separated by double-dash.
            ");
        ap.refer(&mut nodes)
            .add_argument("node", box List::<String>, r#"
                List of nodes separated in clusters by "--"
                "#);
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    let cmd = try!(getenv("VAGGA_COMMAND")
        .and_then(|cmd| config.commands.find(&cmd))
        .ok_or(Err(format!("This command is supposed to be run inside \
                        container started by vagga !Supervise command"))));
    let sup = match cmd {
        &main::Supervise(ref sup) => sup,
        _ => return Err(Err(format!("This command is supposed to be run \
                inside container started by vagga !Supervise command"))),
    };
    let mut visited = HashSet::new();
    let mut clusters = vec!();
    let mut cluster: Vec<String> = vec!();
    for v in nodes.iter() {
        if v.as_slice() == "--" {
            if cluster.len() > 0 {
                clusters.push(cluster);
                cluster = vec!();
            }
            continue;
        }
        let node = try!(sup.children.find(v)
            .ok_or(Err(format!("Node {} does not exists", v))));
        if let Some(netw) = node.network() {
            let ref ip = netw.ip;
            if ip.as_slice() == "172.18.0.254" {
                return Err(Err(format!(
                    "Node {} is bridge and must not be used", v)));
            }
            cluster.push(ip.to_string());
            if !visited.insert(ip.to_string()) {
                return Err(Err(format!("Duplicate node {} (or it's IP)", v)));
            }
        } else {
            return Err(Err(format!("Node {} has no network", v)));
        }
    }
    if cluster.len() > 0 {
        clusters.push(cluster);
    }

    let mut pairs = HashSet::new();
    for i in visited.iter() {
        for j in visited.iter() {
            pairs.insert((i.clone(), j.clone()));
        }
    }
    for cluster in clusters.iter() {
        for i in cluster.iter() {
            for j in cluster.iter() {
                pairs.remove(&(i.to_string(), j.to_string()));
            }
        }
    }
    return Ok(Graph {
        drop_pairs: pairs.into_iter().collect(),
        isolate: vec!(),
        });
}

pub fn split_graph_cmd(config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    let mut nodes: Vec<String> = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Splits graph into few clusters. Each node might participate in
            multiple clusters. Nodes which are not specified are isolated
            from all others.
            ");
        ap.refer(&mut nodes)
            .add_argument("node", box List::<String>, r#"
                List of nodes separated in clusters by "--"
                "#);
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    let cmd = try!(getenv("VAGGA_COMMAND")
        .and_then(|cmd| config.commands.find(&cmd))
        .ok_or(Err(format!("This command is supposed to be run inside \
                        container started by vagga !Supervise command"))));
    let sup = match cmd {
        &main::Supervise(ref sup) => sup,
        _ => return Err(Err(format!("This command is supposed to be run \
                inside container started by vagga !Supervise command"))),
    };
    let mut isolate: HashSet<String> = sup.children.iter()
        .filter(|&(_, cfg)| cfg.network().is_some())
        .map(|(_, cfg)| cfg.network().unwrap().ip.clone())
        .collect();
    let mut visited = HashSet::new();
    let mut clusters = vec!();
    let mut cluster: Vec<String> = vec!();
    for v in nodes.iter() {
        if v.as_slice() == "--" {
            if cluster.len() > 0 {
                clusters.push(cluster);
                cluster = vec!();
            }
            continue;
        }
        let node = try!(sup.children.find(v)
            .ok_or(Err(format!("Node {} does not exists", v))));
        if let Some(netw) = node.network() {
            let ref ip = netw.ip;
            if ip.as_slice() == "172.18.0.254" {
                return Err(Err(format!(
                    "Node {} is bridge and must not be used", v)));
            }
            cluster.push(ip.to_string());
            visited.insert(ip.to_string());
            isolate.remove(ip);
        } else {
            return Err(Err(format!("Node {} has no network", v)));
        }
    }
    if cluster.len() > 0 {
        clusters.push(cluster);
    }

    let mut pairs = HashSet::new();
    for i in visited.iter() {
        for j in visited.iter() {
            pairs.insert((i.clone(), j.clone()));
        }
    }
    for cluster in clusters.iter() {
        for i in cluster.iter() {
            for j in cluster.iter() {
                pairs.remove(&(i.to_string(), j.to_string()));
            }
        }
    }
    return Ok(Graph {
        drop_pairs: pairs.into_iter().collect(),
        isolate: isolate.into_iter().collect(),
        });
}

pub fn isolate_graph_cmd(config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    let mut nodes: Vec<String> = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Splits graph into few clusters. Each node might participate in
            multiple clusters. Nodes which are not specified are isolated
            from all others.
            ");
        ap.refer(&mut nodes)
            .add_argument("node", box List::<String>, r#"
                List of nodes separated in clusters by "--"
                "#);
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    let cmd = try!(getenv("VAGGA_COMMAND")
        .and_then(|cmd| config.commands.find(&cmd))
        .ok_or(Err(format!("This command is supposed to be run inside \
                        container started by vagga !Supervise command"))));
    let sup = match cmd {
        &main::Supervise(ref sup) => sup,
        _ => return Err(Err(format!("This command is supposed to be run \
                inside container started by vagga !Supervise command"))),
    };
    let mut isolate = HashSet::new();
    for v in nodes.iter() {
        let node = try!(sup.children.find(v)
            .ok_or(Err(format!("Node {} does not exists", v))));
        if let Some(netw) = node.network() {
            let ref ip = netw.ip;
            if ip.as_slice() == "172.18.0.254" {
                return Err(Err(format!(
                    "Node {} is bridge and must not be used", v)));
            }
            isolate.insert(ip.to_string());
        } else {
            return Err(Err(format!("Node {} has no network", v)));
        }
    }
    return Ok(Graph {
        drop_pairs: vec!(),
        isolate: isolate.into_iter().collect(),
        });
}
<commit_msg>vagga_partition: Fix graph generation and checking<commit_after>use std::os::getenv;
use std::io::{stdout, stderr};
use std::collections::HashSet;

use argparse::{ArgumentParser, List};

use config::Config;
use config::command::{Networking};
use config::command::{main};

pub struct Graph {
    pub drop_pairs: Vec<(String, String)>,
    pub isolate: Vec<String>,
}

pub fn full_mesh_cmd(_config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Returns network back to full connectivity");
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    return Ok(Graph { drop_pairs: vec!(), isolate: vec!() });
}

pub fn disjoint_graph_cmd(config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    let mut nodes: Vec<String> = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Splits graph into few disjoint clusters. Each node must be
            specified exactly once. Clusters are separated by double-dash.
            ");
        ap.refer(&mut nodes)
            .add_argument("node", box List::<String>, r#"
                List of nodes separated in clusters by "--"
                "#);
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    let cmd = try!(getenv("VAGGA_COMMAND")
        .and_then(|cmd| config.commands.find(&cmd))
        .ok_or(Err(format!("This command is supposed to be run inside \
                        container started by vagga !Supervise command"))));
    let sup = match cmd {
        &main::Supervise(ref sup) => sup,
        _ => return Err(Err(format!("This command is supposed to be run \
                inside container started by vagga !Supervise command"))),
    };
    let mut visited = HashSet::new();
    let mut clusters = vec!();
    let mut cluster: Vec<String> = vec!();
    for v in nodes.iter() {
        if v.as_slice() == "--" {
            if cluster.len() > 0 {
                clusters.push(cluster);
                cluster = vec!();
            }
            continue;
        }
        let node = try!(sup.children.find(v)
            .ok_or(Err(format!("Node {} does not exists", v))));
        if let Some(netw) = node.network() {
            let ref ip = netw.ip;
            if ip.as_slice() == "172.18.0.254" {
                return Err(Err(format!(
                    "Node {} is bridge and must not be used", v)));
            }
            cluster.push(ip.to_string());
            if !visited.insert(ip.to_string()) {
                return Err(Err(format!("Duplicate node {} (or it's IP)", v)));
            }
        } else {
            return Err(Err(format!("Node {} has no network", v)));
        }
    }
    for (name, child) in sup.children.iter() {
        if let Some(netw) = child.network() {
            if !visited.contains(&netw.ip) {
                return Err(Err(format!("Node {} is missing. \
                    You may use 'split' command if you want to skip some nodes\
                    ", name)));
            }
        }
    }
    if cluster.len() > 0 {
        clusters.push(cluster);
    }

    let mut pairs = HashSet::new();
    for i in visited.iter() {
        for j in visited.iter() {
            if i != j {
                pairs.insert((i.clone(), j.clone()));
            }
        }
    }
    for cluster in clusters.iter() {
        for i in cluster.iter() {
            for j in cluster.iter() {
                if i != j {
                    pairs.remove(&(i.to_string(), j.to_string()));
                }
            }
        }
    }
    return Ok(Graph {
        drop_pairs: pairs.into_iter().collect(),
        isolate: vec!(),
        });
}

pub fn split_graph_cmd(config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    let mut nodes: Vec<String> = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Splits graph into few clusters. Each node might participate in
            multiple clusters. Nodes which are not specified are isolated
            from all others.
            ");
        ap.refer(&mut nodes)
            .add_argument("node", box List::<String>, r#"
                List of nodes separated in clusters by "--"
                "#);
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    let cmd = try!(getenv("VAGGA_COMMAND")
        .and_then(|cmd| config.commands.find(&cmd))
        .ok_or(Err(format!("This command is supposed to be run inside \
                        container started by vagga !Supervise command"))));
    let sup = match cmd {
        &main::Supervise(ref sup) => sup,
        _ => return Err(Err(format!("This command is supposed to be run \
                inside container started by vagga !Supervise command"))),
    };
    let mut isolate: HashSet<String> = sup.children.iter()
        .filter(|&(_, cfg)| cfg.network().is_some())
        .map(|(_, cfg)| cfg.network().unwrap().ip.clone())
        .collect();
    let mut visited = HashSet::new();
    let mut clusters = vec!();
    let mut cluster: Vec<String> = vec!();
    for v in nodes.iter() {
        if v.as_slice() == "--" {
            if cluster.len() > 0 {
                clusters.push(cluster);
                cluster = vec!();
            }
            continue;
        }
        let node = try!(sup.children.find(v)
            .ok_or(Err(format!("Node {} does not exists", v))));
        if let Some(netw) = node.network() {
            let ref ip = netw.ip;
            if ip.as_slice() == "172.18.0.254" {
                return Err(Err(format!(
                    "Node {} is bridge and must not be used", v)));
            }
            cluster.push(ip.to_string());
            visited.insert(ip.to_string());
            isolate.remove(ip);
        } else {
            return Err(Err(format!("Node {} has no network", v)));
        }
    }
    if cluster.len() > 0 {
        clusters.push(cluster);
    }

    let mut pairs = HashSet::new();
    for i in visited.iter() {
        for j in visited.iter() {
            if i != j {
                pairs.insert((i.clone(), j.clone()));
            }
        }
    }
    for cluster in clusters.iter() {
        for i in cluster.iter() {
            for j in cluster.iter() {
                if i != j {
                    pairs.remove(&(i.to_string(), j.to_string()));
                }
            }
        }
    }
    return Ok(Graph {
        drop_pairs: pairs.into_iter().collect(),
        isolate: isolate.into_iter().collect(),
        });
}

pub fn isolate_graph_cmd(config: &Config, args: Vec<String>)
    -> Result<Graph, Result<int, String>>
{
    let mut nodes: Vec<String> = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Splits graph into few clusters. Each node might participate in
            multiple clusters. Nodes which are not specified are isolated
            from all others.
            ");
        ap.refer(&mut nodes)
            .add_argument("node", box List::<String>, r#"
                List of nodes separated in clusters by "--"
                "#);
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Err(Ok(0)),
            Err(x) => {
                return Err(Ok(x));
            }
        }
    }
    let cmd = try!(getenv("VAGGA_COMMAND")
        .and_then(|cmd| config.commands.find(&cmd))
        .ok_or(Err(format!("This command is supposed to be run inside \
                        container started by vagga !Supervise command"))));
    let sup = match cmd {
        &main::Supervise(ref sup) => sup,
        _ => return Err(Err(format!("This command is supposed to be run \
                inside container started by vagga !Supervise command"))),
    };
    let mut isolate = HashSet::new();
    for v in nodes.iter() {
        let node = try!(sup.children.find(v)
            .ok_or(Err(format!("Node {} does not exists", v))));
        if let Some(netw) = node.network() {
            let ref ip = netw.ip;
            if ip.as_slice() == "172.18.0.254" {
                return Err(Err(format!(
                    "Node {} is bridge and must not be used", v)));
            }
            isolate.insert(ip.to_string());
        } else {
            return Err(Err(format!("Node {} has no network", v)));
        }
    }
    return Ok(Graph {
        drop_pairs: vec!(),
        isolate: isolate.into_iter().collect(),
        });
}
<|endoftext|>


<commit_before>//! Pattern-sequence data structures and implementations.

use std::ops::Index;
use std::iter::FromIterator;

use util::set::{self, Contains};
use super::{Atom, Class, Element, Repetition, Union, flatten_vec};

// To hide the implementation details, we wrap the type alias in
// a private submodule.
mod seq_impl {
    use std::slice;
    use ::pattern::Element;
    pub type Inner<T> = Vec<Element<T>>;
    pub type Iter<'a,T> = slice::Iter<'a,Element<T>>;
}

/// Sequence of patterns.
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub struct Sequence<T: Atom>(seq_impl::Inner<T>);

impl<T: Atom> Sequence<T> {
    /// Create a new sequence from the given vector.
    pub fn new(v: Vec<Element<T>>) -> Self {
        if v.len() < 2 {
            panic!("Sequences must have at least two elements");
        }
        Sequence(v)
    }

    /// Get the number of elements in the sequence.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Fetch an iterator over the elements in the sequence
    pub fn iter<'a>(&'a self) -> SequenceIterator<'a,T> {
        SequenceIterator(self.0.iter())
    }

    fn into_inner(self) -> seq_impl::Inner<T> {
        self.0
    }

    /// Transforms each contained atom using the supplied function or closure
    /// to produce a new sequence.
    pub fn map_atoms<U, F>(self, f: F) -> Sequence<U>
        where F: Fn(T) -> U,
              U: Atom
    {
        self.0.into_iter().map(|elt| elt.map_atoms(&f)).collect()
    }

    /// Flatten the sequence and apply implementation-defined optimizations.
    pub fn reduce(&mut self) {
        for elt in self.0.iter_mut() {
            elt.reduce();
        }

        flatten_vec(&mut self.0,
                    |elt| match elt { &Element::Sequence(ref s) => Some(s.len()), _ => None },
                    |elt| match elt { Element::Sequence(s) => s.into_inner(), _ => unreachable!() });
    }
}

impl<T: Atom> Index<usize> for Sequence<T> {
    type Output = Element<T>;
    fn index(&self, index: usize) -> &Self::Output {
        &self.0[index]
    }

}

impl<T: Atom> FromIterator<Element<T>> for Sequence<T> {
    fn from_iter<I>(iter: I) -> Self
        where I: IntoIterator<Item=Element<T>>
    {
        Sequence::new(iter.into_iter().collect())
    }
}

impl<T: Atom> set::Contains<T> for Sequence<T> {
    /// A sequence always contains at least two elements, and thus will never
    /// match a single atom.
    #[inline(always)]
    fn contains(&self, _: T) -> bool {
        false
    }
}

// A sequence `A` can be a subset of another sequence `B` *if* both have the
// same length and each element in `A` is a subset of the corresponding element
// in `B`:
//
// A ⊂ B ⇔ |A|=|B|=n ∧ Aᵢ ⊂ Bᵢ ∀ i∈[0,n]
impl<T: Atom> set::IsSubsetOf<Sequence<T>> for Sequence<T> {
    fn is_subset_of(&self, other: &Sequence<T>) -> bool {
        other.len() == self.len() &&
            self.iter().zip(other.iter()).all(|(u, v)| u.is_subset_of(v))
    }
}

impl<T: Atom> set::IsSubsetOf<Class<T>> for Sequence<T> {
    /// A sequence is never a subset of an atom class because sequences are
    /// guaranteed to contain at least two elements.
    #[inline(always)]
    fn is_subset_of(&self, _: &Class<T>) -> bool {
        false
    }
}

impl<T: Atom> set::IsSubsetOf<Union<T>> for Sequence<T> {
    /// A sequence is a subset of a union whenever it is a subset of one of the
    /// union's members.
    fn is_subset_of(&self, union: &Union<T>) -> bool {
        union.iter().any(|m| self.is_subset_of(m))
    }
}

impl<T: Atom> set::IsSubsetOf<Repetition<T>> for Sequence<T> {
    /// A sequence is a subset of a repetition if the sequence's length is
    /// contained by the repetition's count and all members of the sequence are
    /// subsets of the repeated element.
    fn is_subset_of(&self, rep: &Repetition<T>) -> bool {
        rep.count().contains(self.len()) && self.iter().all(|elt| elt.is_subset_of(rep.element()))
    }
}

impl<T: Atom> set::IsSubsetOf<Element<T>> for Sequence<T> {
    fn is_subset_of(&self, elt: &Element<T>) -> bool {
        match elt {
            &Element::Tagged{ref element, ..} => self.is_subset_of(&**element),
            &Element::Sequence(ref s) => self.is_subset_of(s),
            &Element::Union(ref u) => self.is_subset_of(u),
            &Element::Repeat(ref r) => self.is_subset_of(r),

            &Element::Anchor(_) => false,
            &Element::Atom(_) => false,
            &Element::Class(_) => false,
            &Element::Wildcard => false,
        }
    }
}

// ----------------------------------------------------------------

/// Iterator over the patterns within a sequence.
pub struct SequenceIterator<'a,T: 'a + Atom>(seq_impl::Iter<'a,T>);

impl<'a,T: 'a + Atom> Iterator for SequenceIterator<'a,T> {
    type Item = &'a Element<T>;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

<commit_msg>pattern/sequence: switch to `impl Iterator<...>`<commit_after>//! Pattern-sequence data structures and implementations.

use std::ops::Index;
use std::iter::FromIterator;

use util::set::{self, Contains};
use super::{Atom, Class, Element, Repetition, Union, flatten_vec};

// To hide the implementation details, we wrap the type alias in
// a private submodule.
mod seq_impl {
    use ::pattern::Element;
    pub type Inner<T> = Vec<Element<T>>;
}

/// Sequence of patterns.
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub struct Sequence<T: Atom>(seq_impl::Inner<T>);

impl<T: Atom> Sequence<T> {
    /// Create a new sequence from the given vector.
    pub fn new(v: Vec<Element<T>>) -> Self {
        if v.len() < 2 {
            panic!("Sequences must have at least two elements");
        }
        Sequence(v)
    }

    /// Get the number of elements in the sequence.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Fetch an iterator over the elements in the sequence
    pub fn iter<'a>(&'a self) -> impl Iterator<Item=&'a Element<T>> {
        self.0.iter()
    }

    fn into_inner(self) -> seq_impl::Inner<T> {
        self.0
    }

    /// Transforms each contained atom using the supplied function or closure
    /// to produce a new sequence.
    pub fn map_atoms<U, F>(self, f: F) -> Sequence<U>
        where F: Fn(T) -> U,
              U: Atom
    {
        self.0.into_iter().map(|elt| elt.map_atoms(&f)).collect()
    }

    /// Flatten the sequence and apply implementation-defined optimizations.
    pub fn reduce(&mut self) {
        for elt in self.0.iter_mut() {
            elt.reduce();
        }

        flatten_vec(&mut self.0,
                    |elt| match elt { &Element::Sequence(ref s) => Some(s.len()), _ => None },
                    |elt| match elt { Element::Sequence(s) => s.into_inner(), _ => unreachable!() });
    }
}

impl<T: Atom> Index<usize> for Sequence<T> {
    type Output = Element<T>;
    fn index(&self, index: usize) -> &Self::Output {
        &self.0[index]
    }

}

impl<T: Atom> FromIterator<Element<T>> for Sequence<T> {
    fn from_iter<I>(iter: I) -> Self
        where I: IntoIterator<Item=Element<T>>
    {
        Sequence::new(iter.into_iter().collect())
    }
}

impl<T: Atom> set::Contains<T> for Sequence<T> {
    /// A sequence always contains at least two elements, and thus will never
    /// match a single atom.
    #[inline(always)]
    fn contains(&self, _: T) -> bool {
        false
    }
}

// A sequence `A` can be a subset of another sequence `B` *if* both have the
// same length and each element in `A` is a subset of the corresponding element
// in `B`:
//
// A ⊂ B ⇔ |A|=|B|=n ∧ Aᵢ ⊂ Bᵢ ∀ i∈[0,n]
impl<T: Atom> set::IsSubsetOf<Sequence<T>> for Sequence<T> {
    fn is_subset_of(&self, other: &Sequence<T>) -> bool {
        other.len() == self.len() &&
            self.iter().zip(other.iter()).all(|(u, v)| u.is_subset_of(v))
    }
}

impl<T: Atom> set::IsSubsetOf<Class<T>> for Sequence<T> {
    /// A sequence is never a subset of an atom class because sequences are
    /// guaranteed to contain at least two elements.
    #[inline(always)]
    fn is_subset_of(&self, _: &Class<T>) -> bool {
        false
    }
}

impl<T: Atom> set::IsSubsetOf<Union<T>> for Sequence<T> {
    /// A sequence is a subset of a union whenever it is a subset of one of the
    /// union's members.
    fn is_subset_of(&self, union: &Union<T>) -> bool {
        union.iter().any(|m| self.is_subset_of(m))
    }
}

impl<T: Atom> set::IsSubsetOf<Repetition<T>> for Sequence<T> {
    /// A sequence is a subset of a repetition if the sequence's length is
    /// contained by the repetition's count and all members of the sequence are
    /// subsets of the repeated element.
    fn is_subset_of(&self, rep: &Repetition<T>) -> bool {
        rep.count().contains(self.len()) && self.iter().all(|elt| elt.is_subset_of(rep.element()))
    }
}

impl<T: Atom> set::IsSubsetOf<Element<T>> for Sequence<T> {
    fn is_subset_of(&self, elt: &Element<T>) -> bool {
        match elt {
            &Element::Tagged{ref element, ..} => self.is_subset_of(&**element),
            &Element::Sequence(ref s) => self.is_subset_of(s),
            &Element::Union(ref u) => self.is_subset_of(u),
            &Element::Repeat(ref r) => self.is_subset_of(r),

            &Element::Anchor(_) => false,
            &Element::Atom(_) => false,
            &Element::Class(_) => false,
            &Element::Wildcard => false,
        }
    }
}
<|endoftext|>


<commit_before>

// -*- rust -*-
import core::sys;

enum t { make_t(@int), clam, }

fn foo(s: @int) {
    let count = sys::refcount(s);
    let x: t = make_t(s); // ref up

    alt x {
      make_t(y) {
        log(debug, y); // ref up then down

      }
      _ { #debug("?"); fail; }
    }
    log(debug, sys::refcount(s));
    assert (sys::refcount(s) == count + 1u);
}

fn main() {
    let s: @int = @0; // ref up

    let count = sys::refcount(s);

    foo(s); // ref up then down

    log(debug, sys::refcount(s));
    assert (sys::refcount(s) == count);
}
<commit_msg>Fix alt-pattern-drop's breakage from af2d01e<commit_after>

// -*- rust -*-
import core::sys;

enum t { make_t(@int), clam, }

fn foo(s: @int) {
    let count = sys::refcount(s);
    let x: t = make_t(s); // ref up

    alt x {
      make_t(y) {
        log(debug, y); // ref up then down

      }
      _ { #debug("?"); fail; }
    }
    log(debug, sys::refcount(s));
    assert (sys::refcount(s) == count + 1u);
}

fn main() {
    let s: @int = @0; // ref up

    let count = sys::refcount(s);

    foo(s); // ref up then down

    log(debug, sys::refcount(s));
    let count2 = sys::refcount(s);
    let _ = sys::refcount(s); // don't get bitten by last-use.
    assert count == count2;
}
<|endoftext|>


<commit_before>fn id(x: bool) -> bool { x }

fn call_id() {
    let c <- fail;
    id(c);
}

fn call_id_2() { id(true) && id(ret); }

fn call_id_3() { id(ret) && id(ret); }

fn call_id_4() { while id(break) { } }

iter put_break() -> int {
    while true { put break; }
}

fn log_fail() { log_err fail; }

fn ret_ret() -> int { ret (ret 2) + 3; }

fn ret_guard() {
    alt 2 {
      x when (ret) { x; }
    }
}

fn fail_then_concat() {
    let x = [], y = [3];
    fail;
    x += y;
    "good" + "bye";
}

fn main() {}
<commit_msg>xfail-pretty unreachable-code.rs<commit_after>// xfail-pretty

fn id(x: bool) -> bool { x }

fn call_id() {
    let c <- fail;
    id(c);
}

fn call_id_2() { id(true) && id(ret); }

fn call_id_3() { id(ret) && id(ret); }

fn call_id_4() { while id(break) { } }

iter put_break() -> int {
    while true { put break; }
}

fn log_fail() { log_err fail; }

fn ret_ret() -> int { ret (ret 2) + 3; }

fn ret_guard() {
    alt 2 {
      x when (ret) { x; }
    }
}

fn fail_then_concat() {
    let x = [], y = [3];
    fail;
    x += y;
    "good" + "bye";
}

fn main() {}
<|endoftext|>


<commit_before>use subframe;
use subframe::{Subframe, MAX_FIXED_ORDER, MAX_LPC_ORDER};

pub fn fixed_restore_signal(order: usize,
                            residual: &[i32],
                            output: &mut [i32]) {
  debug_assert!(order <= MAX_FIXED_ORDER);

  let polynomial = [ &[][..]
                   , &[1][..]
                   , &[-1, 2][..]
                   , &[1, -3, 3][..]
                   , &[-1, 4, -6, 4][..]
                   ];

  let coefficients = polynomial[order];

  for i in 0..residual.len() {
    let offset     = i + order;
    let prediction = coefficients.iter()
                      .zip(&output[i..offset])
                      .fold(0, |result, (coefficient, signal)|
                            result + coefficient * signal);

    output[offset] = residual[i] + prediction;
  }
}

pub fn lpc_restore_signal(quantization_level: i8,
                          coefficients: &[i32],
                          residual: &[i32],
                          output: &mut [i32]) {
  let order = coefficients.len();

  debug_assert!(order <= MAX_LPC_ORDER);

  for i in 0..residual.len() {
    let offset     = i + order;
    let prediction = coefficients.iter().rev()
                       .zip(&output[i..offset])
                       .fold(0, |result, (coefficient, signal)|
                             result + coefficient * signal);

    output[offset] = residual[i] + (prediction >> quantization_level);
  }
}

pub fn decode(subframe: &Subframe, output: &mut [i32]) {
  match subframe.data {
    subframe::Data::Constant(constant) => {
      for i in 0..output.len() {
        output[i] = constant
      }
    }
    subframe::Data::Verbatim(_)        => unimplemented!(),
    subframe::Data::Fixed(ref fixed)   => {
      let order = fixed.order as usize;

      for i in 0..order {
        output[i] = fixed.warmup[i];
      }

      fixed_restore_signal(order, &fixed.residual, output);
    }
    subframe::Data::LPC(ref lpc)       => {
      let order        = lpc.order as usize;
      let coefficients = &lpc.qlp_coefficients[0..order];

      for i in 0..order {
        output[i] = lpc.warmup[i];
      }

      lpc_restore_signal(lpc.quantization_level, coefficients, &lpc.residual,
                         output);
    }
  }

  if subframe.wasted_bits > 0 {
    for value in output {
      *value <<= subframe.wasted_bits;
    }
  }
}
<commit_msg>Add functionality for `Verbatim` subframe decoding<commit_after>use subframe;
use subframe::{Subframe, MAX_FIXED_ORDER, MAX_LPC_ORDER};

use std::ptr;

pub fn fixed_restore_signal(order: usize,
                            residual: &[i32],
                            output: &mut [i32]) {
  debug_assert!(order <= MAX_FIXED_ORDER);

  let polynomial = [ &[][..]
                   , &[1][..]
                   , &[-1, 2][..]
                   , &[1, -3, 3][..]
                   , &[-1, 4, -6, 4][..]
                   ];

  let coefficients = polynomial[order];

  for i in 0..residual.len() {
    let offset     = i + order;
    let prediction = coefficients.iter()
                      .zip(&output[i..offset])
                      .fold(0, |result, (coefficient, signal)|
                            result + coefficient * signal);

    output[offset] = residual[i] + prediction;
  }
}

pub fn lpc_restore_signal(quantization_level: i8,
                          coefficients: &[i32],
                          residual: &[i32],
                          output: &mut [i32]) {
  let order = coefficients.len();

  debug_assert!(order <= MAX_LPC_ORDER);

  for i in 0..residual.len() {
    let offset     = i + order;
    let prediction = coefficients.iter().rev()
                       .zip(&output[i..offset])
                       .fold(0, |result, (coefficient, signal)|
                             result + coefficient * signal);

    output[offset] = residual[i] + (prediction >> quantization_level);
  }
}

pub fn decode(subframe: &Subframe, output: &mut [i32]) {
  match subframe.data {
    subframe::Data::Constant(constant)     => {
      for i in 0..output.len() {
        output[i] = constant
      }
    }
    subframe::Data::Verbatim(ref verbatim) => {
      let length = verbatim.len();

      unsafe {
        ptr::copy(verbatim.as_ptr(), output.as_mut_ptr(), length)
      }
    }
    subframe::Data::Fixed(ref fixed)       => {
      let order = fixed.order as usize;

      for i in 0..order {
        output[i] = fixed.warmup[i];
      }

      fixed_restore_signal(order, &fixed.residual, output);
    }
    subframe::Data::LPC(ref lpc)           => {
      let order        = lpc.order as usize;
      let coefficients = &lpc.qlp_coefficients[0..order];

      for i in 0..order {
        output[i] = lpc.warmup[i];
      }

      lpc_restore_signal(lpc.quantization_level, coefficients, &lpc.residual,
                         output);
    }
  }

  if subframe.wasted_bits > 0 {
    for value in output {
      *value <<= subframe.wasted_bits;
    }
  }
}
<|endoftext|>


<commit_before>//! Visitation patterns for graphs.
//!
//! As a simple example, the following creates two subgraphs and verifies that
//! iterators over each, using both depth- and breadth-first algorithms, visit
//! each node in the expected order.
//!
//! ```rust
//! use cripes::util::graph::*;
//!
//! let mut g = BasicGraph::<u8>::new();
//!
//! // Add some nodes to the graph so we can add edges between them.
//! for _ in 0..14 {
//!     g.add_node(());
//! }
//!
//! // Build a few sub-graphs to play with; we'll refer to each using the ID of
//! // the root node.
//! //
//! //       (0)            __(7)__
//! //       / \           /       \
//! //     (1) (2)       (8)       (9)
//! //     / \           / \       / \
//! //   (3) (4)      (10) (11) (12) (13)
//! //       / \
//! //     (5) (6)
//! g.add_edges(&[(0, 1), (1, 3), (1, 4), (4, 5), (4, 6), (0, 2),
//!               (7, 8), (8, 10), (8, 11), (7, 9), (9, 12), (9, 13)]);
//!
//! // Define a convenience function to determine the order in which nodes are
//! // walked.
//! fn walk_order<G, A>(g: &G, entry: <G as Graph>::NodeId) -> Vec<usize>
//!     where G: Graph, A: visit::RootedAlgorithm<G> {
//!     g.iter::<A>(entry).map(|id| id.index()).collect::<Vec<_>>()
//! }
//!
//!
//! //                         TREE (0)
//! // Walk the tree using depth-first search:
//! assert_eq!(walk_order::<_, visit::DepthFirst<_>>(&g, 0.into()),
//!            vec![0, 1, 3, 4, 5, 6, 2]);
//!
//!
//! // Breadth-first search:
//! assert_eq!(walk_order::<_, visit::BreadthFirst<_>>(&g, 0.into()),
//!           vec![0, 1, 2, 3, 4, 5, 6]);
//!
//! //                         TREE (7)
//! // Walk the second tree using depth- and breadth-first search.
//! assert_eq!(walk_order::<_, visit::DepthFirst<_>>(&g, 7.into()),
//!            vec![7, 8, 10, 11, 9, 12, 13]);
//! assert_eq!(walk_order::<_, visit::BreadthFirst<_>>(&g, 7.into()),
//!           vec![7, 8, 9, 10, 11, 12, 13]);
//!
//! ```
//!
//!
//!

use std::fmt::Debug;
use std::collections::VecDeque;
use smallvec::SmallVec;

use bit_vec::BitVec;

use super::interface::{DirectedGraph, Graph, Id};

// ================================================================
// Algorithm

/// Visitation-order selection helper.
pub trait Algorithm<G: Graph>: Debug {
    /// Select the next node to visit.
    fn next(&mut self, v: &VisitorState<G>, g: &G) -> Option<<G as Graph>::NodeId>;
}

/// Interface required for "rooted" algorithms.
///
/// Rooted algorithms are those that require a pre-defined entry point on
/// the graph.
pub trait RootedAlgorithm<G: Graph>: Algorithm<G> {
    /// Instantiate and initialize the algorithm object.
    fn new(g: &G, entry: <G as Graph>::NodeId) -> Self;
}

// ================================================================
// Visitor

/// Mutable common state for visitors.
pub struct VisitorState<G: Graph> {
    /// Node most recently visited.
    pub current_node: <G as Graph>::NodeId,
    /// Map of visited nodes.
    visited: BitVec<u32>
}

impl<G: Graph> VisitorState<G> {
    /// Crate a new state object for the specified graph and entry node.
    pub fn new(g: &G, entry: <G as Graph>::NodeId) -> VisitorState<G> {
        VisitorState{current_node: entry, visited: BitVec::from_elem(g.node_count(), false)}
    }

    /// Check if a particular node has been visited.
    pub fn visited(&self, node: <G as Graph>::NodeId) -> bool {
        self.visited.get(node.index()).unwrap_or_else(|| false)
    }

    /// Move to the specified node and mark it as visited.
    fn move_to(&mut self, n: <G as Graph>::NodeId) {
        self.visited.set(n.index(), true);
        self.current_node = n;
    }
}

// ----------------------------------------------------------------

/// Iterator adaptor for Visitor.
///
/// `VisitorIter`s are produced by calling a Visitor's `into_iterator` method
/// with a graph reference as the argument.
pub struct VisitorIter<'a,G: 'a + Graph, V: Visit<G>> {
    graph: &'a G,
    visitor: V
}

impl<'a, G: 'a + Graph, V: Visit<G>> Iterator for VisitorIter<'a, G, V> {
    type Item = <G as Graph>::NodeId;
    fn next(&mut self) -> Option<Self::Item> {
        self.visitor.next(self.graph)
    }
}

// ----------------------------------------------------------------

/// Tracks required state when traversing a graph.
pub struct Visitor<G: Graph, A: Algorithm<G>> where A: Sized {
    state: VisitorState<G>,
    algo: A
}

/// Visitor methods that operate the same regardless of the kind of search
/// algorithm used.
pub trait Visit<G: Graph> {
    /// Determine the next node to inspect.
    fn next(&mut self, g: &G) -> Option<<G as Graph>::NodeId>;

    /*/// Fetch a const reference to the visitor's state data.
    fn state(&self) -> &VisitorState<G>;

    /// Fetch a mutable reference to the visitor's state data.
    fn state_mut(&mut self) -> &mut VisitorState<G>;*/

    /// Transform the visitor into an iterator.
    fn into_iter<'a>(self, g: &'a G) -> VisitorIter<'a, G, Self>
        where Self: Sized {
        VisitorIter{graph: g, visitor: self}
    }
}

impl<G, A> Visitor<G, A>
    where G: Graph, A: Sized + Algorithm<G> + RootedAlgorithm<G> {
    /// Create a Visitor instance for the given entry point.
    pub fn new(g: &G, entry: <G as Graph>::NodeId) -> Self {
        Visitor{state: VisitorState::new(g, entry), algo: A::new(g, entry)}
    }
}

impl<G: Graph, A: Sized + Algorithm<G>> Visit<G> for Visitor<G, A> {
    fn next(&mut self, g: &G) -> Option<<G as Graph>::NodeId> {
        if let Some(node) = self.algo.next(&self.state, g) {
            panic_unless!(g.contains_node(node), "Invalid node ID {:?} produced by algorithm {:?}", node, self.algo);
            self.state.move_to(node);
            Some(node)
        }
        else { None }
    }
}

// ================================================================
// Algorithm implementations

/// Initial capacity for the queues of DepthFirst instances.
const DEPTH_FIRST_INITIAL_STACK_CAPACITY: usize = 8;

/// Initial capacity for the queues of BreadthFirst instances.
const BREADTH_FIRST_INITIAL_QUEUE_CAPACITY: usize = 8;

/// Depth-first traversal algorithm.
///
/// Memory: allocates on the heap.
#[derive(Debug)]
pub struct DepthFirst<G: Graph> {
    stack: SmallVec<[<G as Graph>::NodeId; DEPTH_FIRST_INITIAL_STACK_CAPACITY]>
}

impl<G: Graph + Debug> RootedAlgorithm<G> for DepthFirst<G> {
    /// Create a depth-first search object starting at the specified node.
    fn new(_: &G, entry: <G as Graph>::NodeId) -> Self {
        let mut stack = SmallVec::new(); stack.push(entry);
        DepthFirst{stack: stack}
    }
}

impl<G> Algorithm<G> for DepthFirst<G>
    where G: Debug + DirectedGraph
{
    fn next(&mut self, _: &VisitorState<G>, g: &G) -> Option<G::NodeId> {
        if let Some(next) = self.stack.pop() {
            self.stack.extend(g.direct_successors(next).rev());
            Some(next)
        } else {
            None
        }
    }
}

/// Breadth-first traversal algorithm.
///
/// Memory:   allocates on the heap.

#[derive(Debug)]
pub struct BreadthFirst<G: Graph> {
    queue: VecDeque<<G as Graph>::NodeId>
}

impl<G> RootedAlgorithm<G> for BreadthFirst<G>
    where G: Debug + DirectedGraph
{
    /// Create a breadth-first search object starting at the specified node.
    fn new(_: &G, entry: <G as Graph>::NodeId) -> Self {
        let mut queue = VecDeque::with_capacity(BREADTH_FIRST_INITIAL_QUEUE_CAPACITY);
        queue.push_back(entry);
        BreadthFirst{queue: queue}
    }
}

impl<G> Algorithm<G> for BreadthFirst<G>
    where G: Debug + DirectedGraph
{
    fn next(&mut self, _: &VisitorState<G>, g: &G) -> Option<<G as Graph>::NodeId> {
        if let Some(next) = self.queue.pop_front() {
            self.queue.extend(g.direct_successors(next));
            Some(next)
        } else {
            None
        }
    }
}
<commit_msg>util/graph/visit: some readability/doc improvements<commit_after>//! Visitation patterns for graphs.
//!
//! As a simple example, the following creates two subgraphs and verifies that
//! iterators over each, using both depth- and breadth-first algorithms, visit
//! each node in the expected order.
//!
//! ```rust
//! use cripes::util::graph::*;
//!
//! let mut g = BasicGraph::<u8>::new();
//!
//! // Add some nodes to the graph so we can add edges between them.
//! for _ in 0..14 {
//!     g.add_node(());
//! }
//!
//! // Build a few sub-graphs to play with; we'll refer to each using the ID of
//! // the root node.
//! //
//! //       (0)            __(7)__
//! //       / \           /       \
//! //     (1) (2)       (8)       (9)
//! //     / \           / \       / \
//! //   (3) (4)      (10) (11) (12) (13)
//! //       / \
//! //     (5) (6)
//! g.add_edges(&[(0, 1), (1, 3), (1, 4), (4, 5), (4, 6), (0, 2),
//!               (7, 8), (8, 10), (8, 11), (7, 9), (9, 12), (9, 13)]);
//!
//! // Define a convenience function to determine the order in which nodes are
//! // walked.
//! fn walk_order<G, A>(g: &G, entry: G::NodeId) -> Vec<usize>
//!     where G: Graph, A: visit::RootedAlgorithm<G> {
//!     g.iter::<A>(entry).map(|id| id.index()).collect::<Vec<_>>()
//! }
//!
//!
//! //                         TREE (0)
//! // Walk the tree using depth-first search:
//! assert_eq!(walk_order::<_, visit::DepthFirst<_>>(&g, 0.into()),
//!            vec![0, 1, 3, 4, 5, 6, 2]);
//!
//!
//! // Breadth-first search:
//! assert_eq!(walk_order::<_, visit::BreadthFirst<_>>(&g, 0.into()),
//!           vec![0, 1, 2, 3, 4, 5, 6]);
//!
//! //                         TREE (7)
//! // Walk the second tree using depth- and breadth-first search.
//! assert_eq!(walk_order::<_, visit::DepthFirst<_>>(&g, 7.into()),
//!            vec![7, 8, 10, 11, 9, 12, 13]);
//! assert_eq!(walk_order::<_, visit::BreadthFirst<_>>(&g, 7.into()),
//!           vec![7, 8, 9, 10, 11, 12, 13]);
//!
//! ```
//!
//!
//!

use std::fmt::Debug;
use std::collections::VecDeque;
use smallvec::SmallVec;

use bit_vec::BitVec;

use super::interface::{DirectedGraph, Graph, Id};

// ================================================================
// Algorithm

/// Visitation-order selection helper.
pub trait Algorithm<G: Graph>: Debug {
    /// Select the next node to visit.
    fn next(&mut self, v: &VisitorState<G>, g: &G) -> Option<G::NodeId>;
}

/// Interface required for "rooted" algorithms.
///
/// Rooted algorithms are those that require a pre-defined entry point on
/// the graph.
pub trait RootedAlgorithm<G: Graph>: Algorithm<G> {
    /// Instantiate and initialize the algorithm object.
    fn new(g: &G, entry: G::NodeId) -> Self;
}

// ================================================================
// Visitor

/// Mutable common state for visitors.
///
/// VisitorState tracks which nodes in a graph have been visited by
/// a traversal algorithm.
pub struct VisitorState<G: Graph> {
    /// Node most recently visited.
    pub current_node: G::NodeId,
    /// Map of visited nodes.
    visited: BitVec<u32>
}

impl<G: Graph> VisitorState<G> {
    /// Crate a new state object for the specified graph and entry node.
    pub fn new(g: &G, entry: G::NodeId) -> VisitorState<G> {
        VisitorState{current_node: entry, visited: BitVec::from_elem(g.node_count(), false)}
    }

    /// Check if a particular node has been visited.
    pub fn visited(&self, node: G::NodeId) -> bool {
        self.visited.get(node.index()).unwrap_or_else(|| false)
    }

    /// Move to the specified node and mark it as visited.
    fn move_to(&mut self, n: G::NodeId) {
        self.visited.set(n.index(), true);
        self.current_node = n;
    }
}

// ----------------------------------------------------------------

/// Iterator adaptor for Visitor.
///
/// `VisitorIter`s are produced by calling a Visitor's `into_iterator` method
/// with a graph reference as the argument.
pub struct VisitorIter<'a,G: 'a + Graph, V: Visit<G>> {
    graph: &'a G,
    visitor: V
}

impl<'a, G: 'a + Graph, V: Visit<G>> Iterator for VisitorIter<'a, G, V> {
    type Item = G::NodeId;
    fn next(&mut self) -> Option<Self::Item> {
        self.visitor.next(self.graph)
    }
}

// ----------------------------------------------------------------

/// Tracks required state when traversing a graph.
pub struct Visitor<G: Graph, A: Algorithm<G>> where A: Sized {
    state: VisitorState<G>,
    algo: A
}

/// Visitor methods that operate the same regardless of the kind of search
/// algorithm used.
pub trait Visit<G: Graph> {
    /// Determine the next node to inspect.
    fn next(&mut self, g: &G) -> Option<G::NodeId>;

    /*/// Fetch a const reference to the visitor's state data.
    fn state(&self) -> &VisitorState<G>;

    /// Fetch a mutable reference to the visitor's state data.
    fn state_mut(&mut self) -> &mut VisitorState<G>;*/

    /// Transform the visitor into an iterator.
    fn into_iter<'a>(self, g: &'a G) -> VisitorIter<'a, G, Self>
        where Self: Sized {
        VisitorIter{graph: g, visitor: self}
    }
}

impl<G, A> Visitor<G, A>
    where G: Graph, A: Sized + Algorithm<G> + RootedAlgorithm<G> {
    /// Create a Visitor instance for the given entry point.
    pub fn new(g: &G, entry: G::NodeId) -> Self {
        Visitor{state: VisitorState::new(g, entry), algo: A::new(g, entry)}
    }
}

impl<G: Graph, A: Sized + Algorithm<G>> Visit<G> for Visitor<G, A> {
    fn next(&mut self, g: &G) -> Option<G::NodeId> {
        if let Some(node) = self.algo.next(&self.state, g) {
            panic_unless!(g.contains_node(node), "Invalid node ID {:?} produced by algorithm {:?}", node, self.algo);
            self.state.move_to(node);
            Some(node)
        }
        else { None }
    }
}

// ================================================================
// Algorithm implementations

/// Initial capacity for the queues of DepthFirst instances.
const DEPTH_FIRST_INITIAL_STACK_CAPACITY: usize = 8;

/// Initial capacity for the queues of BreadthFirst instances.
const BREADTH_FIRST_INITIAL_QUEUE_CAPACITY: usize = 8;

/// Depth-first traversal algorithm.
///
/// Memory: allocates on the heap.
#[derive(Debug)]
pub struct DepthFirst<G: Graph> {
    stack: SmallVec<[G::NodeId; DEPTH_FIRST_INITIAL_STACK_CAPACITY]>
}

impl<G> RootedAlgorithm<G> for DepthFirst<G>
    where G: Debug + DirectedGraph
{
    /// Create a depth-first search object starting at the specified node.
    fn new(_: &G, entry: G::NodeId) -> Self {
        let mut stack = SmallVec::new(); stack.push(entry);
        DepthFirst{stack: stack}
    }
}

impl<G> Algorithm<G> for DepthFirst<G>
    where G: Debug + DirectedGraph
{
    fn next(&mut self, _: &VisitorState<G>, g: &G) -> Option<G::NodeId> {
        if let Some(next) = self.stack.pop() {
            self.stack.extend(g.direct_successors(next).rev());
            Some(next)
        } else {
            None
        }
    }
}

/// Breadth-first traversal algorithm.
///
/// Memory:   allocates on the heap.

#[derive(Debug)]
pub struct BreadthFirst<G: Graph> {
    queue: VecDeque<G::NodeId>
}

impl<G> RootedAlgorithm<G> for BreadthFirst<G>
    where G: Debug + DirectedGraph
{
    /// Create a breadth-first search object starting at the specified node.
    fn new(_: &G, entry: G::NodeId) -> Self {
        let mut queue = VecDeque::with_capacity(BREADTH_FIRST_INITIAL_QUEUE_CAPACITY);
        queue.push_back(entry);
        BreadthFirst{queue: queue}
    }
}

impl<G> Algorithm<G> for BreadthFirst<G>
    where G: Debug + DirectedGraph
{
    fn next(&mut self, _: &VisitorState<G>, g: &G) -> Option<G::NodeId> {
        if let Some(next) = self.queue.pop_front() {
            self.queue.extend(g.direct_successors(next));
            Some(next)
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>use clap::builder::ValueParser;
//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Michael Gehring <mg@ebfe.org>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.
use clap::{crate_version, Arg, Command};
use std::ffi::OsString;
use std::fs::hard_link;
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
use uucore::format_usage;

static ABOUT: &str = "Call the link function to create a link named FILE2 to an existing FILE1.";
const USAGE: &str = "{} FILE1 FILE2";

pub mod options {
    pub static FILES: &str = "FILES";
}

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let matches = uu_app().get_matches_from(args);

    let files: Vec<_> = matches
        .get_many::<OsString>(options::FILES)
        .unwrap_or_default()
        .collect();
    let old = Path::new(files[0]);
    let new = Path::new(files[1]);

    hard_link(old, new)
        .map_err_context(|| format!("cannot create link {} to {}", new.quote(), old.quote()))
}

pub fn uu_app<'a>() -> Command<'a> {
    Command::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .override_usage(format_usage(USAGE))
        .infer_long_args(true)
        .arg(
            Arg::new(options::FILES)
                .hide(true)
                .required(true)
                .min_values(2)
                .max_values(2)
                .takes_value(true)
                .value_hint(clap::ValueHint::AnyPath)
                .value_parser(ValueParser::os_string()),
        )
}
<commit_msg>link: move use statement after copyright<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Michael Gehring <mg@ebfe.org>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.
use clap::builder::ValueParser;
use clap::{crate_version, Arg, Command};
use std::ffi::OsString;
use std::fs::hard_link;
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
use uucore::format_usage;

static ABOUT: &str = "Call the link function to create a link named FILE2 to an existing FILE1.";
const USAGE: &str = "{} FILE1 FILE2";

pub mod options {
    pub static FILES: &str = "FILES";
}

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let matches = uu_app().get_matches_from(args);

    let files: Vec<_> = matches
        .get_many::<OsString>(options::FILES)
        .unwrap_or_default()
        .collect();
    let old = Path::new(files[0]);
    let new = Path::new(files[1]);

    hard_link(old, new)
        .map_err_context(|| format!("cannot create link {} to {}", new.quote(), old.quote()))
}

pub fn uu_app<'a>() -> Command<'a> {
    Command::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .override_usage(format_usage(USAGE))
        .infer_long_args(true)
        .arg(
            Arg::new(options::FILES)
                .hide(true)
                .required(true)
                .min_values(2)
                .max_values(2)
                .takes_value(true)
                .value_hint(clap::ValueHint::AnyPath)
                .value_parser(ValueParser::os_string()),
        )
}
<|endoftext|>


<commit_before>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, EnergyCache};

/// Monte-Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// System after applying changes to the simulation cell
    new_system: System,
    /// target pressure
    pressure: f64,
    /// largest cut off diameter of `PairPotentials`
    rc_max: f64,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            new_system: System::new(),
            pressure: pressure,
            rc_max: 0.0,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // get the largest cutoff of all intermolecular interactions in the
        // system.
        // TODO: include electrostatic interactions
        self.rc_max = system.interactions()
                            .all_pairs()
                            .iter()
                            .map(|i| i.get_cutoff())
                            .fold(f64::NAN, f64::max)
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // copy the system: the proposed state will be stored here
        // TODO: we only need to store positions and the cell; all
        // other information stays the same.
        self.new_system = system.clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // change the simulation cell
        self.new_system.cell_mut().scale_mut(Matrix3::one() * scaling_factor);
        // check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // abort simulation when box gets smaller than twice the cutoff radius
        if self.new_system.cell()
            .lengths()
            .iter()
            .any(|&d| 0.5 * d <= self.rc_max) {
            fatal_error!("Tried to decrease the cell size but new size
                conflicts with the cut off radius. \
                Increase the number of particles to get rid of this problem.")
        }
        // loop over all molecules in the system
        // we don't want to change the intramolecular distances
        // so we compute the translation vector of the center of mass
        // of a molecule and apply it to all its particles

        // TODO: check if system.size == system.molecules().len
        // if that is the case, skip com computation since it is a
        // system without molecules
        for (mi, molecule) in system
            .molecules()
            .iter()
            .enumerate() {
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell().fractional(&old_com);
            // compute translation vector
            let delta_com = self.new_system.cell().cartesian(&frac_com) - old_com;
            // loop over all particles (indices) in the molecule
            for pi in molecule.iter() {
                self.new_system[pi].position += delta_com
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_rigid_molecules_cost(&self.new_system);
        let new_volume = self.new_system.volume();
        let old_volume = system.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, system: &mut System) {
        // Exchange systems.
        mem::swap(system, &mut self.new_system)
    }

    fn restore(&mut self, _: &mut System) {
        // Do nothing.
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<commit_msg>Add check in setup to abort simulation when system CellShape is Infinite.<commit_after>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, EnergyCache, CellShape};

/// Monte-Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// System after applying changes to the simulation cell
    new_system: System,
    /// target pressure
    pressure: f64,
    /// largest cut off diameter of `PairPotentials`
    rc_max: f64,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            new_system: System::new(),
            pressure: pressure,
            rc_max: 0.0,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // check if the cell is infinite
        if system.cell().shape() == CellShape::Infinite {
            fatal_error!("Cannot use `Resize` move with infinite simulation cell.")
        }

        // get the largest cutoff of all intermolecular interactions in the
        // system.
        // TODO: include electrostatic interactions
        self.rc_max = system.interactions()
                            .all_pairs()
                            .iter()
                            .map(|i| i.get_cutoff())
                            .fold(f64::NAN, f64::max)
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // copy the system: the proposed state will be stored here
        // TODO: we only need to store positions and the cell; all
        // other information stays the same.
        self.new_system = system.clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // change the simulation cell
        self.new_system.cell_mut().scale_mut(Matrix3::one() * scaling_factor);
        // check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // abort simulation when box gets smaller than twice the cutoff radius
        if self.new_system.cell()
            .lengths()
            .iter()
            .any(|&d| 0.5 * d <= self.rc_max) {
            fatal_error!("Tried to decrease the cell size but new size
                conflicts with the cut off radius. \
                Increase the number of particles to get rid of this problem.")
        }
        // loop over all molecules in the system
        // we don't want to change the intramolecular distances
        // so we compute the translation vector of the center of mass
        // of a molecule and apply it to all its particles

        // TODO: check if system.size == system.molecules().len
        // if that is the case, skip com computation since it is a
        // system without molecules
        for (mi, molecule) in system
            .molecules()
            .iter()
            .enumerate() {
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell().fractional(&old_com);
            // compute translation vector
            let delta_com = self.new_system.cell().cartesian(&frac_com) - old_com;
            // loop over all particles (indices) in the molecule
            for pi in molecule.iter() {
                self.new_system[pi].position += delta_com
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_rigid_molecules_cost(&self.new_system);
        let new_volume = self.new_system.volume();
        let old_volume = system.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, system: &mut System) {
        // Exchange systems.
        mem::swap(system, &mut self.new_system)
    }

    fn restore(&mut self, _: &mut System) {
        // Do nothing.
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<|endoftext|>


<commit_before>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, Configuration, EnergyCache};

/// Monte Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// Configuration before applying changes to the simulation cell
    previous: Configuration,
    /// target pressure
    pressure: f64,
    /// largest cutoff diameter of potentials in `Interactions`
    maximum_cutoff: Option<f64>,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            previous: Configuration::new(),
            pressure: pressure,
            maximum_cutoff: None,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // check if the cell is infinite
        if system.cell.is_infinite() {
            fatal_error!("Cannot use `Resize` move with infinite simulation cell.")
        }

        // Get the largest cutoff of all intermolecular interactions in the
        // system.
        self.maximum_cutoff = system.maximum_cutoff()
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // Store the previous configuration
        self.previous = (**system).clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // Change the simulation cell
        system.cell.scale_mut(Matrix3::one() * scaling_factor);
        // Check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // Abort simulation when box gets smaller than twice the cutoff radius.
        if let Some(maximum_cutoff) = self.maximum_cutoff {
            if system.cell.lengths().iter().any(|&d| 0.5 * d <= maximum_cutoff) {
                fatal_error!(
                    "Tried to decrease the cell size but new size
                    conflicts with the cut off radius. \
                    Increase the number of particles to get rid of this problem."
                );
            }
        };

        // Loop over all molecules in the system.
        // We don't want to change the intramolecular distances
        // so we compute the translation vector of the center-of-mass
        // (com) of a molecule and apply it to all its particles.
        // Note that to do this, the com of a molecule *always* has
        // to reside inside the simulation cell.

        // TODO: Check if system.size == system.molecules().len
        // if that is the case, skip com computation since it is a
        // system without molecules.
        for (mi, molecule) in self.previous.molecules().iter().enumerate() {
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell.fractional(&old_com);
            // compute translation vector
            let delta_com = system.cell.cartesian(&frac_com) - old_com;
            // loop over all particles (indices) in the molecule
            for pi in molecule.iter() {
                system.particle_mut(pi).position += delta_com;
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_all_rigid_molecules_cost(system);
        let new_volume = system.volume();
        let old_volume = self.previous.cell.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function.
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, _: &mut System) {
        // Nothing to do.
    }

    fn restore(&mut self, system: &mut System) {
        // Exchange configurations
        mem::swap(&mut **system, &mut self.previous)
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<commit_msg>Remove a TODO in Resize<commit_after>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, Configuration, EnergyCache};

/// Monte Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// Configuration before applying changes to the simulation cell
    previous: Configuration,
    /// target pressure
    pressure: f64,
    /// largest cutoff diameter of potentials in `Interactions`
    maximum_cutoff: Option<f64>,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            previous: Configuration::new(),
            pressure: pressure,
            maximum_cutoff: None,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // check if the cell is infinite
        if system.cell.is_infinite() {
            fatal_error!("Cannot use `Resize` move with infinite simulation cell.")
        }

        // Get the largest cutoff of all intermolecular interactions in the
        // system.
        self.maximum_cutoff = system.maximum_cutoff()
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // Store the previous configuration
        self.previous = (**system).clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // Change the simulation cell
        system.cell.scale_mut(Matrix3::one() * scaling_factor);
        // Check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // Abort simulation when box gets smaller than twice the cutoff radius.
        if let Some(maximum_cutoff) = self.maximum_cutoff {
            if system.cell.lengths().iter().any(|&d| 0.5 * d <= maximum_cutoff) {
                fatal_error!(
                    "Tried to decrease the cell size but new size
                    conflicts with the cut off radius. \
                    Increase the number of particles to get rid of this problem."
                );
            }
        };

        for (mi, molecule) in self.previous.molecules().iter().enumerate() {
            // We don't want to change the intramolecular distances
            // so we compute the translation vector of the center-of-mass
            // (com) of a molecule and apply it to all its particles.
            // Note that to do this, the com of a molecule *always* has
            // to reside inside the simulation cell.
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell.fractional(&old_com);
            let delta_com = system.cell.cartesian(&frac_com) - old_com;
            for pi in molecule.iter() {
                system.particle_mut(pi).position += delta_com;
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_all_rigid_molecules_cost(system);
        let new_volume = system.volume();
        let old_volume = self.previous.cell.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function.
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, _: &mut System) {
        // Nothing to do.
    }

    fn restore(&mut self, system: &mut System) {
        // Exchange configurations
        mem::swap(&mut **system, &mut self.previous)
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<|endoftext|>


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

//! Various data structures used by the Rust compiler. The intention
//! is that code in here should be not be *specific* to rustc, so that
//! it can be easily unit tested and so forth.
//!
//! # Note
//!
//! This API is completely unstable and subject to change.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_data_structures"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![staged_api]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://www.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(rustc_private, staged_api)]
#![cfg_attr(test, feature(test))]

#[macro_use] extern crate log;
extern crate serialize as rustc_serialize; // used by deriving

pub mod snapshot_vec;
pub mod graph;
pub mod bitvec;
pub mod ivar;
pub mod unify;

// See comments in src/librustc/lib.rs
#[doc(hidden)]
pub fn __noop_fix_for_27438() {}
<commit_msg>reorder imports to respect the alphabet, only one of the single most important inventions of all time<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Various data structures used by the Rust compiler. The intention
//! is that code in here should be not be *specific* to rustc, so that
//! it can be easily unit tested and so forth.
//!
//! # Note
//!
//! This API is completely unstable and subject to change.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_data_structures"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![staged_api]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://www.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(rustc_private, staged_api)]
#![cfg_attr(test, feature(test))]

#[macro_use] extern crate log;
extern crate serialize as rustc_serialize; // used by deriving

pub mod bitvec;
pub mod graph;
pub mod ivar;
pub mod snapshot_vec;
pub mod unify;

// See comments in src/librustc/lib.rs
#[doc(hidden)]
pub fn __noop_fix_for_27438() {}
<|endoftext|>