<commit_before>use std::fs;
use std::env;
use std::fs::File;
use std::io::Read;
use std::hash::Hasher;
use std::path::PathBuf;
use std::collections::HashMap;
use std::collections::BTreeSet;
use std::os::unix::fs::MetadataExt;
use std::collections::hash_map::DefaultHasher;

#[macro_use]
extern crate log;
extern crate env_logger;

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)]
struct FileEntry {
    size : u64,
    hash : u64,
    files : Vec<String>,
}

fn collect_files(dir: &String, h: &mut HashMap<u64, Vec<String>>,
                 b: &mut BTreeSet<(u64, u64)>) {

    let entries = match fs::read_dir(dir) {
        Ok(x) => x,
        _ => {
            warn!("{}: invalid directory", dir);
            return
        },
    };

    for path in  entries.filter( |x| x.is_ok() ).map( |x| x.unwrap().path() )
                .collect::<Vec<PathBuf>>() {
        if let (Some(path_str), Ok(metadata)) =
                (path.to_str(), path.symlink_metadata()) {
            let ft = metadata.file_type();
            if ft.is_symlink() {
                continue;
            } else if ft.is_file() {
                let file_ino = metadata.ino();
                let file_dev = metadata.dev();
                if b.contains(&(file_ino, file_dev)) {
                    continue;
                }
                b.insert((file_ino, file_dev));
                match metadata.len() {
                    0 => continue, //Ignore empty files.
                    i => h.entry(i).or_insert_with(Vec::new)
                          .push(String::from(path_str)),
                };
            } else if ft.is_dir() {
                collect_files(&(String::from(path_str)), h, b);
            }
        } else {
            warn!("Failed to retrieve metadata for {}", path.to_str().unwrap());
        }
    }
}

fn find_duplicates(duplicates: &mut HashMap<u64, Vec<String>>,
                   vec: &Vec<String>, thorough: bool ) {
    for file_entry in vec {
        if let Ok(mut file) = File::open(file_entry) {
            let mut hash: u64 = 0;
            let mut hasher = DefaultHasher::new();
            if thorough {
                let mut contents: Vec<u8> = Vec::new();
                if let Ok(_) = file.read_to_end(&mut contents) {
                    hasher.write(&contents[..]);
                    hash = hasher.finish();
                } else {
                    warn!("Failed to read {}", file_entry);
                }
            } else {
                let mut buf: [u8; 1024] = [0; 1024];
                if let Ok(nbytes) = file.read(&mut buf) {
                    hasher.write(&buf[..nbytes as usize]);
                    hash = hasher.finish();
                } else {
                    warn!("Failed to read {} chunk", file_entry);
                }
            }
            if hash != 0 {
                duplicates.entry(hash).or_insert_with(Vec::new)
                    .push(file_entry.to_string());
            }
        } else {
            warn!("Failed to open file {}", file_entry);
        }
    }
}

fn print_duplicates(vec: &Vec<String>, cluster: i32, key: u64, hash: u64,
                    json_list: &mut Vec<FileEntry>, json_output: bool) {
    if json_output {
        json_list.push( FileEntry {
            size  : key,
            hash  : hash,
            files : vec.to_vec(),
        });
    } else {
        println!("{} files in cluster {} (size: {}, digest: {})",
                 vec.len(), cluster, key, hash);
        // for_each becomes stable v1.22.0 onwards. Should uncomment then.
        //vec.iter().for_each(|f| println!("{}", f.path));
        for file_entry in vec {
            println!("{}", file_entry);
        }
    }
}

fn exhaustive_search(emap: &mut HashMap<Vec<u8>, Vec<String>>,
                     vec: &Vec<String>) {
    for file_entry in vec {
        if let Ok(mut file) = File::open(file_entry) {
            let mut contents: Vec<u8> = Vec::new();
            if let Ok(_) = file.read_to_end(&mut contents) {
                emap.entry(contents).or_insert_with(Vec::new)
                    .push(file_entry.to_string());
            } else {
                warn!("Failed to read {}", file_entry);
            }
        } else {
            warn!("Failed to open {}", file_entry);
        }
    }
}

fn main() {
    env_logger::init().unwrap();

    let mut args: Vec<String> = env::args().collect();

    let binary_name = args.remove(0);

    let mut hmap: HashMap<u64, Vec<String> > = HashMap::new();
    let mut bset: BTreeSet<(u64, u64)> = BTreeSet::new();

    let mut thorough = false;
    let mut exhaustive = false;
    let mut json_output = false;
    let mut print_usage = true;

    for dir in &args[..] {
        match dir.as_ref() {
            "-t" => {
                thorough = true;
                continue;
            },
            "-e" => {
                thorough = false;
                exhaustive = false;
                continue;
            },
            "-j" => {
                json_output = true;
                continue;
            },
            _ => {
                print_usage = false;
                collect_files(dir, &mut hmap, &mut bset);
            },
        }
    }

    if print_usage {
        println!("Usage: {} [-t] [-e] [-j] <dir1> [dir2 [dir3 ...]]",
                 binary_name);
        ::std::process::exit(0);
    }

    // Get rid of all the single entries.
    hmap.retain(|_, v| v.len() >= 2);

    let mut cluster = 1;

    let mut json_list : Vec<FileEntry> = Vec::new();
    for (key, val) in hmap {
        let mut duplicates: HashMap<u64, Vec<String> > = HashMap::new();
        find_duplicates(&mut duplicates, &val, thorough);

        for (hash, vec) in duplicates {
            if vec.len() >= 2 {
                if exhaustive {
                    let mut emap: HashMap<Vec<u8>, Vec<String>> = HashMap::new();
                    exhaustive_search(&mut emap, &vec);
                    for (_, v) in emap {
                        if v.len() >= 2 {
                            print_duplicates(&v, cluster, key, hash,
                                             &mut json_list, json_output);
                            cluster += 1;
                        }
                    }
                } else {
                    print_duplicates(&vec, cluster, key, hash, &mut json_list,
                                     json_output);
                    cluster += 1;
                }
            }
        }
    }
    if json_output {
        println!("{}", serde_json::to_string_pretty(&json_list).unwrap());
    }
}
<commit_msg>Refactor 'collect_files'<commit_after>use std::fs;
use std::env;
use std::fs::File;
use std::io::Read;
use std::hash::Hasher;
use std::path::PathBuf;
use std::collections::HashMap;
use std::collections::BTreeSet;
use std::os::unix::fs::MetadataExt;
use std::collections::hash_map::DefaultHasher;

#[macro_use]
extern crate log;
extern crate env_logger;

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)]
struct FileEntry {
    size : u64,
    hash : u64,
    files : Vec<String>,
}

fn collect_files(dir: &String, files: &mut HashMap<u64, Vec<String>>,
                 inodes: &mut BTreeSet<(u64, u64)>) {

    let entries = match fs::read_dir(dir) {
        Ok(x) => x,
        _ => {
            warn!("{}: invalid directory", dir);
            return
        },
    };

    for path in  entries.filter( |x| x.is_ok() )
                        .map( |x| x.unwrap().path() )
                        .collect::<Vec<PathBuf>>() {
        if let (Some(path_str), Ok(metadata)) =
                (path.to_str(), path.symlink_metadata()) {
            let ft = metadata.file_type();
            if ft.is_symlink() {
                continue;
            } else if ft.is_file() {
                let inode = metadata.ino();
                let device = metadata.dev();
                if inodes.contains(&(inode, device)) {
                    continue;
                }
                inodes.insert((inode, device));
                match metadata.len() {
                    0 => continue, //Ignore empty files.
                    i => files.entry(i).or_insert_with(Vec::new)
                          .push(String::from(path_str)),
                };
            } else if ft.is_dir() {
                collect_files(&(String::from(path_str)), files, inodes);
            }
        } else {
            warn!("Failed to retrieve metadata for {}", path.to_str().unwrap());
        }
    }
}

fn find_duplicates(duplicates: &mut HashMap<u64, Vec<String>>,
                   vec: &Vec<String>, thorough: bool ) {
    for file_entry in vec {
        if let Ok(mut file) = File::open(file_entry) {
            let mut hash: u64 = 0;
            let mut hasher = DefaultHasher::new();
            if thorough {
                let mut contents: Vec<u8> = Vec::new();
                if let Ok(_) = file.read_to_end(&mut contents) {
                    hasher.write(&contents[..]);
                    hash = hasher.finish();
                } else {
                    warn!("Failed to read {}", file_entry);
                }
            } else {
                let mut buf: [u8; 1024] = [0; 1024];
                if let Ok(nbytes) = file.read(&mut buf) {
                    hasher.write(&buf[..nbytes as usize]);
                    hash = hasher.finish();
                } else {
                    warn!("Failed to read {} chunk", file_entry);
                }
            }
            if hash != 0 {
                duplicates.entry(hash).or_insert_with(Vec::new)
                    .push(file_entry.to_string());
            }
        } else {
            warn!("Failed to open file {}", file_entry);
        }
    }
}

fn print_duplicates(vec: &Vec<String>, cluster: i32, key: u64, hash: u64,
                    json_list: &mut Vec<FileEntry>, json_output: bool) {
    if json_output {
        json_list.push( FileEntry {
            size  : key,
            hash  : hash,
            files : vec.to_vec(),
        });
    } else {
        println!("{} files in cluster {} (size: {}, digest: {})",
                 vec.len(), cluster, key, hash);
        // for_each becomes stable v1.22.0 onwards. Should uncomment then.
        //vec.iter().for_each(|f| println!("{}", f.path));
        for file_entry in vec {
            println!("{}", file_entry);
        }
    }
}

fn exhaustive_search(emap: &mut HashMap<Vec<u8>, Vec<String>>,
                     vec: &Vec<String>) {
    for file_entry in vec {
        if let Ok(mut file) = File::open(file_entry) {
            let mut contents: Vec<u8> = Vec::new();
            if let Ok(_) = file.read_to_end(&mut contents) {
                emap.entry(contents).or_insert_with(Vec::new)
                    .push(file_entry.to_string());
            } else {
                warn!("Failed to read {}", file_entry);
            }
        } else {
            warn!("Failed to open {}", file_entry);
        }
    }
}

fn main() {
    env_logger::init().unwrap();

    let mut args: Vec<String> = env::args().collect();

    let binary_name = args.remove(0);

    let mut hmap: HashMap<u64, Vec<String> > = HashMap::new();
    let mut bset: BTreeSet<(u64, u64)> = BTreeSet::new();

    let mut thorough = false;
    let mut exhaustive = false;
    let mut json_output = false;
    let mut print_usage = true;

    for dir in &args[..] {
        match dir.as_ref() {
            "-t" => {
                thorough = true;
                continue;
            },
            "-e" => {
                thorough = false;
                exhaustive = false;
                continue;
            },
            "-j" => {
                json_output = true;
                continue;
            },
            _ => {
                print_usage = false;
                collect_files(dir, &mut hmap, &mut bset);
            },
        }
    }

    if print_usage {
        println!("Usage: {} [-t] [-e] [-j] <dir1> [dir2 [dir3 ...]]",
                 binary_name);
        ::std::process::exit(0);
    }

    // Get rid of all the single entries.
    hmap.retain(|_, v| v.len() >= 2);

    let mut cluster = 1;

    let mut json_list : Vec<FileEntry> = Vec::new();
    for (key, val) in hmap {
        let mut duplicates: HashMap<u64, Vec<String> > = HashMap::new();
        find_duplicates(&mut duplicates, &val, thorough);

        for (hash, vec) in duplicates {
            if vec.len() >= 2 {
                if exhaustive {
                    let mut emap: HashMap<Vec<u8>, Vec<String>> = HashMap::new();
                    exhaustive_search(&mut emap, &vec);
                    for (_, v) in emap {
                        if v.len() >= 2 {
                            print_duplicates(&v, cluster, key, hash,
                                             &mut json_list, json_output);
                            cluster += 1;
                        }
                    }
                } else {
                    print_duplicates(&vec, cluster, key, hash, &mut json_list,
                                     json_output);
                    cluster += 1;
                }
            }
        }
    }
    if json_output {
        println!("{}", serde_json::to_string_pretty(&json_list).unwrap());
    }
}
<|endoftext|>


<commit_before>extern crate bs58;
extern crate byteorder;
extern crate clap;
extern crate crypto;
extern crate curve25519_dalek;
extern crate ocl_core as core;
extern crate ring;

mod address;
mod device;
mod pattern;
mod sha256;
mod util;

use clap::{App, Arg};
use core::{PlatformInfo, DeviceInfo, DeviceId, PlatformId};
use pattern::Pattern;
use ring::rand::SystemRandom;
use std::{str, thread, time};
use std::fs::File;
use std::io::{self, Read, Write};
use std::sync::Arc;
use std::sync::atomic;
use std::sync::mpsc::{self, Sender, Receiver};

fn main() {
    let matches = App::new("Zcash Vanity Address Generator")
        .version("0.0.1")
        .about("Generates Zcash shielded addresses (\"z-addrs\") that match given prefixes.")
        .arg(Arg::with_name("device")
             .short("d")
             .takes_value(true)
             .number_of_values(1)
             .multiple(true)
             .help("OpenCL device string: <platform>:<device>.\n\
                    Specify multiple times for multiple devices, e.g. -d 0:0 -d 0:1.\n\
                    If not specified, uses all available platforms and devices."))
        .arg(Arg::with_name("file")
             .short("f")
             .takes_value(true)
             .help("Load prefixes from file, one per line.\nCan be combined with --insensitive."))
        .arg(Arg::with_name("insensitive")
             .short("i")
             .help("Case-insensitive prefix search."))
        .arg(Arg::with_name("continue")
             .short("c")
             .help("Continue searching after a match is found."))
        .arg(Arg::with_name("pattern")
             .index(1)
             .help("Zcash address prefix to be matched."))
        .after_help("Matches will be printed to stdout; each z-addr on its own line followed by its spending key on the next line.\n\
                     You can import the spending key to your Zcash client using `zcash-cli z_importkey <key> <rescan>`.")
        .get_matches();

    let mut device_values = if matches.is_present("device") {
        matches.values_of("device").unwrap().collect::<Vec<&str>>()
    } else {
        vec![]
    };
    device_values.sort();
    let mut device_specifiers = device_values.iter().map(|s| {
        let mut values = s.split(':');
        (values.next().unwrap().parse::<usize>().unwrap(), values.next().unwrap().parse::<usize>().unwrap())
    });

    let mut stderr = io::stderr();
    let mut devices = vec![];
    let mut device_specifier = device_specifiers.next();
    let all_devices = device_specifier.is_none();
    for (i, &platform) in core::get_platform_ids().unwrap().iter().enumerate() {
        writeln!(&mut stderr, "Available devices on platform {}:", core::get_platform_info(&platform, PlatformInfo::Name)).unwrap();
        for (j, &device) in core::get_device_ids(&platform, None, None).unwrap().iter().enumerate() {
            writeln!(&mut stderr, "  {}:{} {}", i, j, core::get_device_info(device, DeviceInfo::Name)).unwrap();
            if all_devices || Some((i, j)) == device_specifier {
                devices.push((platform, device));
                device_specifier = device_specifiers.next();
            }
        }
    }
    stderr.flush().unwrap();

    let mut patterns = if let Some(filename) = matches.value_of("file") {
        let mut file = File::open(&filename).unwrap();
        let mut contents = String::new();
        file.read_to_string(&mut contents).unwrap();
        contents.lines().map(|s| Pattern::new(s.to_string()).unwrap()).collect()
    } else {
        vec![Pattern::new(matches.value_of("pattern").unwrap_or("").to_string()).unwrap()]
    };

    if matches.is_present("insensitive") {
        patterns = patterns.iter().flat_map(|p| p.case_insensitive()).collect()
    }

    vanity(&devices, &patterns, !matches.is_present("continue"));
}

fn vanity(devices: &[(PlatformId, DeviceId)], patterns: &[Pattern], single_match: bool) {
    let mut pattern_prefixes: Vec<String> = patterns.into_iter().map(|p| p.prefix.to_owned()).collect();
    pattern_prefixes.sort();

    let mut pattern_ranges: Vec<(u64, u64)> = patterns.iter().map(|p| p.range).collect();
    pattern_ranges.sort_by_key(|r| r.0);

    // TODO: the pairs in pattern_words are guaranteed to be sorted, but only by virtue of
    // lexicographic ordering of the default base58 alphabet being equivalent to ordering of the
    // big-endian data.
    let mut pattern_words = vec![];
    let mut search_size = 0;
    for (from, to) in pattern_ranges {
        pattern_words.push(from);
        pattern_words.push(to);
        search_size += to - from;
    }

    let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
    let pattern_prefixes = Arc::new(pattern_prefixes);
    let pattern_words = Arc::new(pattern_words);
    let rng = Arc::new(SystemRandom::new());
    let finished = Arc::new(atomic::AtomicBool::new(false));

    for &device_specifier in devices {
        let tx = tx.clone();
        let pattern_prefixes = pattern_prefixes.clone();
        let pattern_words = pattern_words.clone();
        let rng = rng.clone();
        let finished = finished.clone();
        thread::spawn(move || {
            device::vanity_device(&*finished, &*rng, &tx, device_specifier.0, device_specifier.1, &*pattern_prefixes, &*pattern_words, single_match);
            finished.store(true, atomic::Ordering::Relaxed);
        });
    }
    drop(tx);

    let difficulty = (!0u64 as f64) / (search_size as f64);
    let start = time::Instant::now();
    let mut cumulative_work = 0u64;
    let mut now = start;
    let mut stderr = io::stderr();

    while let Ok(work) = rx.recv() {
        cumulative_work += work;
        let now_elapsed = now.elapsed();

        if now_elapsed.as_secs() > 0 {
            let start_elapsed = start.elapsed();
            let start_elapsed_secs = (start_elapsed.as_secs() as f64) + (start_elapsed.subsec_nanos() as f64 / 1_000_000_000.0);

            let rate = cumulative_work as f64 / (now_elapsed.as_secs() as f64) + (now_elapsed.subsec_nanos() as f64 / 1_000_000_000.0);
            let lambda = rate / difficulty;
            let probability = 1. - (-start_elapsed_secs * lambda).exp();

            write!(&mut stderr, "\rElapsed: {:.0}/{:.0}s Rate: {:.0}/s Prob: {:.2}%", start_elapsed_secs, 1. / lambda, rate, 100. * probability).unwrap();
            stderr.flush().unwrap();

            cumulative_work = 0;
            now += now_elapsed;
        }
    }
}
<commit_msg>Simplify.<commit_after>extern crate bs58;
extern crate byteorder;
extern crate clap;
extern crate crypto;
extern crate curve25519_dalek;
extern crate ocl_core as core;
extern crate ring;

mod address;
mod device;
mod pattern;
mod sha256;
mod util;

use clap::{App, Arg};
use core::{PlatformInfo, DeviceInfo, DeviceId, PlatformId};
use pattern::Pattern;
use ring::rand::SystemRandom;
use std::{str, thread, time};
use std::fs::File;
use std::io::{self, Read, Write};
use std::sync::Arc;
use std::sync::atomic;
use std::sync::mpsc::{self, Sender, Receiver};

fn main() {
    let matches = App::new("Zcash Vanity Address Generator")
        .version("0.0.1")
        .about("Generates Zcash shielded addresses (\"z-addrs\") that match given prefixes.")
        .arg(Arg::with_name("device")
             .short("d")
             .takes_value(true)
             .number_of_values(1)
             .multiple(true)
             .help("OpenCL device string: <platform>:<device>.\n\
                    Specify multiple times for multiple devices, e.g. -d 0:0 -d 0:1.\n\
                    If not specified, uses all available platforms and devices."))
        .arg(Arg::with_name("file")
             .short("f")
             .takes_value(true)
             .help("Load prefixes from file, one per line.\nCan be combined with --insensitive."))
        .arg(Arg::with_name("insensitive")
             .short("i")
             .help("Case-insensitive prefix search."))
        .arg(Arg::with_name("continue")
             .short("c")
             .help("Continue searching after a match is found."))
        .arg(Arg::with_name("pattern")
             .index(1)
             .help("Zcash address prefix to be matched."))
        .after_help("Matches will be printed to stdout; each z-addr on its own line followed by its spending key on the next line.\n\
                     You can import the spending key to your Zcash client using `zcash-cli z_importkey <key> <rescan>`.")
        .get_matches();

    let mut device_specifiers = if matches.is_present("device") {
        matches.values_of("device").unwrap().map(|s| {
            let mut values = s.split(':');
            (values.next().unwrap().parse::<usize>().unwrap(), values.next().unwrap().parse::<usize>().unwrap())
        }).collect()
    } else {
        vec![]
    };
    device_specifiers.sort();
    let mut device_specifiers_iter = device_specifiers.into_iter();

    let mut stderr = io::stderr();
    let mut devices = vec![];
    let mut device_specifier = device_specifiers_iter.next();
    let all_devices = device_specifier.is_none();
    for (i, &platform) in core::get_platform_ids().unwrap().iter().enumerate() {
        writeln!(&mut stderr, "Available devices on platform {}:", core::get_platform_info(&platform, PlatformInfo::Name)).unwrap();
        for (j, &device) in core::get_device_ids(&platform, None, None).unwrap().iter().enumerate() {
            writeln!(&mut stderr, "  {}:{} {}", i, j, core::get_device_info(device, DeviceInfo::Name)).unwrap();
            if all_devices || Some((i, j)) == device_specifier {
                devices.push((platform, device));
                device_specifier = device_specifiers_iter.next();
            }
        }
    }
    stderr.flush().unwrap();

    let mut patterns = if let Some(filename) = matches.value_of("file") {
        let mut file = File::open(&filename).unwrap();
        let mut contents = String::new();
        file.read_to_string(&mut contents).unwrap();
        contents.lines().map(|s| Pattern::new(s.to_string()).unwrap()).collect()
    } else {
        vec![Pattern::new(matches.value_of("pattern").unwrap_or("").to_string()).unwrap()]
    };

    if matches.is_present("insensitive") {
        patterns = patterns.iter().flat_map(|p| p.case_insensitive()).collect()
    }

    vanity(&devices, &patterns, !matches.is_present("continue"));
}

fn vanity(devices: &[(PlatformId, DeviceId)], patterns: &[Pattern], single_match: bool) {
    let mut pattern_prefixes: Vec<String> = patterns.into_iter().map(|p| p.prefix.to_owned()).collect();
    pattern_prefixes.sort();

    let mut pattern_ranges: Vec<(u64, u64)> = patterns.iter().map(|p| p.range).collect();
    pattern_ranges.sort_by_key(|r| r.0);

    // TODO: the pairs in pattern_words are guaranteed to be sorted, but only by virtue of
    // lexicographic ordering of the default base58 alphabet being equivalent to ordering of the
    // big-endian data.
    let mut pattern_words = vec![];
    let mut search_size = 0;
    for (from, to) in pattern_ranges {
        pattern_words.push(from);
        pattern_words.push(to);
        search_size += to - from;
    }

    let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
    let pattern_prefixes = Arc::new(pattern_prefixes);
    let pattern_words = Arc::new(pattern_words);
    let rng = Arc::new(SystemRandom::new());
    let finished = Arc::new(atomic::AtomicBool::new(false));

    for &device_specifier in devices {
        let tx = tx.clone();
        let pattern_prefixes = pattern_prefixes.clone();
        let pattern_words = pattern_words.clone();
        let rng = rng.clone();
        let finished = finished.clone();
        thread::spawn(move || {
            device::vanity_device(&*finished, &*rng, &tx, device_specifier.0, device_specifier.1, &*pattern_prefixes, &*pattern_words, single_match);
            finished.store(true, atomic::Ordering::Relaxed);
        });
    }
    drop(tx);

    let difficulty = (!0u64 as f64) / (search_size as f64);
    let start = time::Instant::now();
    let mut cumulative_work = 0u64;
    let mut now = start;
    let mut stderr = io::stderr();

    while let Ok(work) = rx.recv() {
        cumulative_work += work;
        let now_elapsed = now.elapsed();

        if now_elapsed.as_secs() > 0 {
            let start_elapsed = start.elapsed();
            let start_elapsed_secs = (start_elapsed.as_secs() as f64) + (start_elapsed.subsec_nanos() as f64 / 1_000_000_000.0);

            let rate = cumulative_work as f64 / (now_elapsed.as_secs() as f64) + (now_elapsed.subsec_nanos() as f64 / 1_000_000_000.0);
            let lambda = rate / difficulty;
            let probability = 1. - (-start_elapsed_secs * lambda).exp();

            write!(&mut stderr, "\rElapsed: {:.0}/{:.0}s Rate: {:.0}/s Prob: {:.2}%", start_elapsed_secs, 1. / lambda, rate, 100. * probability).unwrap();
            stderr.flush().unwrap();

            cumulative_work = 0;
            now += now_elapsed;
        }
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate docopt;
extern crate rand;
extern crate libc;

mod PerfCounters;
mod Parameters;
mod SimulatedAnnealing;
mod ThreadExecutor;
mod MeterProxy;

use std::sync::{Arc, Mutex, Condvar};
use std::sync::RwLock;

use docopt::Docopt;
use std::process::Command;
use PerfCounters::PerfMetrics;
use std::thread;

// The Docopt usage string.
const USAGE: &'static str =
    "
Usage:   sgxmusl-autotuner [-t] --targ=<targetPath> [--args2targ=<args>] [-b] \
     --bench=<benchmarkPath> [--args2bench=<args>] [-ms] --maxSteps=<maxSteps> [-tp] \
     --temp=<initialTemp> [-rf] --redFact=<tempReductionFactor> [-at] --maxAtt=<maxAttempts> \
     [-ac] --maxAcc=<maxAccepts> [-rj] --maxRej=<maxRejects>
Options:
    -t,    \
     --targ=<args>     	someoption.
    --args2targ=<args>   		arguments for target.
    -b,    \
     --bench=<args>     	someoption.
    --args2bench=<args>  		arguments for benchmark.
    -ms,   \
     --maxSteps=<args>    someoption.
    -tp,   --temp=<args>     	someoption.
    -rf,   \
     --redFact=<args>     someoption.
    -at,   --maxAtt=<args>     	someoption.
    -ac,   \
     --maxAcc=<args>     	someoption.
    -rj,   --maxRej=<args>     	someoption.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_targ: String,
    flag_bench: String,
    flag_maxSteps: u64,
    flag_temp: f64,
    flag_redFact: f64,
    flag_maxAtt: u64,
    flag_maxAcc: u64,
    flag_maxRej: u64,
    flag_args2targ: String,
    flag_args2bench: String,
}

/**
The Sgx-Musl Auto Tuner is a tool able to needs in input:

	- The target app
	- The benchmark app
	- An initial default parameter configuration
	- The possible categorical levels that each parameter can assume
	- The cutoff time k after which terminate the target algorithm execution
	- The iteration number r for random selection of initial parameter configuration
	- Probability p_restart with which re-initialize the search at random
	- Fixed number s of random moves for perturbation
**/
/**
Sgx-Musl Auto Tuner Entry Point
**/
fn main() {

    /// Collect command line arguments
    ///
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    println!("{:?}", args);

    /// Create ParamsConfigurator useful to manage the parameters (or states)
    /// that the simulated annealing algorithm will explore. ParamsConfigurator set initial default parameters
    /// defined in the initial-params.txt input file
    ///
    let params_config = Parameters::ParamsConfigurator {
        param_file_path: "../initial-params.txt".to_string(),
        ..Parameters::ParamsConfigurator::default()
    };

    /// Instantiate the AppsManager struct needed for start/stop the Target and the Benchmark applications
    ///
    let executor = ThreadExecutor::ThreadExecutor {
        target_path: args.flag_targ,
        bench_path: args.flag_bench,
        target_args: args.flag_args2targ,
        bench_args: args.flag_args2bench.split_whitespace().map(String::from).collect(),
        ..ThreadExecutor::ThreadExecutor::default()
    };
    // executor.start_meter_proxy();

    /// Configure the Simulated Annealing problem with the ParamsConfigurator and AppsManager instances.
    /// Finally,the solver is started
    ///
    let mut problem = SimulatedAnnealing::Problem::ProblemInputs {
        params_configurator: params_config,
        thread_executor: executor,
    };
    let annealing_solver = SimulatedAnnealing::Solver::Solver {
        steps: args.flag_maxSteps,
        initial_temperature: args.flag_temp,
        temperature_reduction: args.flag_redFact,
        max_attempts: args.flag_maxAtt,
        max_accepts: args.flag_maxAcc,
        max_rejects: args.flag_maxRej,
    };

    annealing_solver.solve(&mut problem);

}
<commit_msg>Changed main<commit_after>extern crate rustc_serialize;
extern crate docopt;
extern crate rand;
extern crate libc;

mod PerfCounters;
mod Parameters;
mod SimulatedAnnealing;
mod ThreadExecutor;
mod MeterProxy;

use std::sync::{Arc, Mutex, Condvar};
use std::sync::RwLock;

use docopt::Docopt;
use std::process::Command;
use PerfCounters::PerfMetrics;
use std::thread;

//The Docopt usage string.
const USAGE: &'static str = "
Usage:   sgxmusl-autotuner [-t] --targ=<targetPath> [--args2targ=<args>] [-b] --bench=<benchmarkPath> [--args2bench=<args>] [-ms] --maxSteps=<maxSteps> [-tp] --temp=<initialTemp> [-rf] --redFact=<tempReductionFactor> [-at] --maxAtt=<maxAttempts> [-ac] --maxAcc=<maxAccepts> [-rj] --maxRej=<maxRejects>
Options:
    -t,    --targ=<args>     	someoption.
    --args2targ=<args>   		arguments for target.
    -b,    --bench=<args>     	someoption.
    --args2bench=<args>  		arguments for benchmark.
    -ms,   --maxSteps=<args>    someoption.
    -tp,   --temp=<args>     	someoption.
    -rf,   --redFact=<args>     someoption.
    -at,   --maxAtt=<args>     	someoption.
    -ac,   --maxAcc=<args>     	someoption.
    -rj,   --maxRej=<args>     	someoption.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_targ: String,
    flag_bench: String,
    flag_maxSteps: u64,
    flag_temp: f64,
    flag_redFact: f64,
    flag_maxAtt: u64,
    flag_maxAcc: u64,
    flag_maxRej: u64,
    flag_args2targ: String,
    flag_args2bench: String,
}

/**
The Sgx-Musl Auto Tuner is a tool able to needs in input:

	- The target app
	- The benchmark app
	- An initial default parameter configuration
	- The possible categorical levels that each parameter can assume
	- The cutoff time k after which terminate the target algorithm execution
	- The iteration number r for random selection of initial parameter configuration
	- Probability p_restart with which re-initialize the search at random
	- Fixed number s of random moves for perturbation
**/
/**
Sgx-Musl Auto Tuner Entry Point
**/
fn main() {

    /// Collect command line arguments
    ///
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    println!("{:?}", args);

    /// Create ParamsConfigurator useful to manage the parameters (or states)
    /// that the simulated annealing algorithm will explore. ParamsConfigurator set initial default parameters
    /// defined in the initial-params.txt input file
    ///
    let params_config = Parameters::ParamsConfigurator {
        param_file_path: "../initial-params.txt".to_string(),
        ..Parameters::ParamsConfigurator::default()
    };

    /// Instantiate the AppsManager struct needed for start/stop the Target and the Benchmark applications
    ///
    let executor = ThreadExecutor::ThreadExecutor {
        target_path: args.flag_targ,
        bench_path: args.flag_bench,
        target_args: args.flag_args2targ,
        bench_args: args.flag_args2bench.split_whitespace().map(String::from).collect(),
        ..ThreadExecutor::ThreadExecutor::default()
    };
    // executor.start_meter_proxy();

    /// Configure the Simulated Annealing problem with the ParamsConfigurator and AppsManager instances.
    /// Finally,the solver is started
    ///
    let mut problem = SimulatedAnnealing::Problem::ProblemInputs {
        params_configurator: params_config,
        thread_executor: executor,
    };
    let annealing_solver = SimulatedAnnealing::Solver::Solver {
        steps: args.flag_maxSteps,
        initial_temperature: args.flag_temp,
        temperature_reduction: args.flag_redFact,
        max_attempts: args.flag_maxAtt,
        max_accepts: args.flag_maxAcc,
        max_rejects: args.flag_maxRej,
    };

    annealing_solver.solve(&mut problem);

}
<|endoftext|>


<commit_before>#[ macro_use ]
extern crate clap;

extern crate btrfs;
extern crate sha2;
extern crate termion;

#[ doc (hidden) ]
#[ macro_use ]
mod misc;

mod examine;
mod output;
mod scan;
mod types;

use std::path::PathBuf;
use std::process;

use types::*;
use output::Output;

fn main () {

	let arguments =
		parse_arguments ();

	let mut output =
		Output::new ();

	match main_real (
		& arguments,
		& mut output,
	) {

		Ok (_) => (),

		Err (error_message) => {

			output.clear_status ();

			output.message (
				& format! (
					"Error: {}",
					error_message));

			process::exit (1);

		},

	}

}

fn parse_arguments (
) -> Arguments {

	let argument_matches = (
		clap::App::new ("Btrfs Dedupe")

		.arg (
			clap::Arg::with_name ("match-filename")
				.long ("match-filename")
				.help ("Match filename as well as checksum")
		)

		.arg (
			clap::Arg::with_name ("root-path")
				.multiple (true)
				.help ("Root path to scan for files")
		)

	).get_matches ();

	let match_filename =
		argument_matches.is_present (
			"match-filename",
		);

	let root_paths = (
		argument_matches.values_of_os (
			"root-path",
		)
	).map (
		|os_values|

		os_values.map (
			|os_value|

			PathBuf::from (os_value)

		).collect ()

	).unwrap_or (
		Vec::new (),
	);

	Arguments {
		match_filename: match_filename,
		root_paths: root_paths,
	}

}

fn main_real (
	arguments: & Arguments,
	output: & mut Output,
) -> Result <(), String> {

	// create a list of all files with the same name and size

	let file_metadata_lists: FileMetadataLists = try! (
		scan::scan_directories (
			& arguments,
			output)
	);

	// discard any with only a single coincidence

	let file_metadata_lists: FileMetadataLists =
		file_metadata_lists.into_iter ().filter (
			|& (_, ref value)|

		value.len () > 1

	).collect ();

	output.message (
		& format! (
			"Found {} {} that coincide",
			file_metadata_lists.len (),
			if arguments.match_filename {
				"filenames and sizes"
			} else {
				"sizes"
			}));

	// perform a checksum on each one

	let (filename_and_checksum_lists, checksum_error_count) =
		examine::split_by_hash (
			output,
			file_metadata_lists);

	output.message (
		& format! (
			"Found {} filenames and checksums that coincide",
			filename_and_checksum_lists.len ()));

	if checksum_error_count > 0 {

		output.message (
			& format! (
				"Encountered {} errors while calculating checksums",
				checksum_error_count));

	}

	if filename_and_checksum_lists.is_empty () {
		return Ok (());
	}

	// deduplicate the matches

	let mut progress: usize = 0;
	let target = filename_and_checksum_lists.len ();

	let mut error_count: u64 = 0;

	output.status (
		"Deduplication progress: 0%");

	for (_, paths)
	in filename_and_checksum_lists.into_iter () {

		let (first_path_slice, other_paths) =
			paths.split_at (1);

		let first_path =
			first_path_slice.into_iter ().next ().unwrap ();

		for paths_chunk in other_paths.chunks (512) {

			match btrfs::deduplicate_files_with_source (
				first_path,
				paths_chunk,
			) {

				Ok (_) => (),
				Err (_) => error_count += 1,

			}

		}

		progress += 1;

		if progress % 256 == 0 {

			output.status (
				& format! (
					"Deduplication progress: {}%",
					progress * 100 / target));

		}

	};

	output.clear_status ();

	if error_count > 0 {

		output.message (
			& format! (
				"Encountered {} errors during deduplication",
				error_count));

	} else {

		output.message (
			& format! (
				"Deduplicated all files successfully"));

	}

	// return

	Ok (())

}

// ex: noet ts=4 filetype=rust
<commit_msg>improve some messages and variable names<commit_after>#[ macro_use ]
extern crate clap;

extern crate btrfs;
extern crate sha2;
extern crate termion;

#[ doc (hidden) ]
#[ macro_use ]
mod misc;

mod examine;
mod output;
mod scan;
mod types;

use std::path::PathBuf;
use std::process;

use types::*;
use output::Output;

fn main () {

	let arguments =
		parse_arguments ();

	let mut output =
		Output::new ();

	match main_real (
		& arguments,
		& mut output,
	) {

		Ok (_) => (),

		Err (error_message) => {

			output.clear_status ();

			output.message (
				& format! (
					"Error: {}",
					error_message));

			process::exit (1);

		},

	}

}

fn parse_arguments (
) -> Arguments {

	let argument_matches = (
		clap::App::new ("Btrfs Dedupe")

		.arg (
			clap::Arg::with_name ("match-filename")
				.long ("match-filename")
				.help ("Match filename as well as checksum")
		)

		.arg (
			clap::Arg::with_name ("root-path")
				.multiple (true)
				.help ("Root path to scan for files")
		)

	).get_matches ();

	let match_filename =
		argument_matches.is_present (
			"match-filename",
		);

	let root_paths = (
		argument_matches.values_of_os (
			"root-path",
		)
	).map (
		|os_values|

		os_values.map (
			|os_value|

			PathBuf::from (os_value)

		).collect ()

	).unwrap_or (
		Vec::new (),
	);

	Arguments {
		match_filename: match_filename,
		root_paths: root_paths,
	}

}

fn main_real (
	arguments: & Arguments,
	output: & mut Output,
) -> Result <(), String> {

	// create a list of all files with the same name and size

	let file_metadata_lists: FileMetadataLists = try! (
		scan::scan_directories (
			& arguments,
			output)
	);

	// discard any with only a single coincidence

	let file_metadata_lists: FileMetadataLists =
		file_metadata_lists.into_iter ().filter (
			|& (_, ref value)|

		value.len () > 1

	).collect ();

	output.message (
		& format! (
			"Found {} {} that coincide",
			file_metadata_lists.len (),
			if arguments.match_filename {
				"filenames and sizes"
			} else {
				"sizes"
			}));

	// perform a checksum on each one

	let (hash_lists, checksum_error_count) =
		examine::split_by_hash (
			output,
			file_metadata_lists);

	output.message (
		& format! (
			"Found {} {} that coincide",
			hash_lists.len (),
			if arguments.match_filename {
				"filenames and hashes"
			} else {
				"checksums"
			}));

	if checksum_error_count > 0 {

		output.message (
			& format! (
				"Encountered {} errors while calculating checksums",
				checksum_error_count));

	}

	if hash_lists.is_empty () {
		return Ok (());
	}

	// deduplicate the matches

	let mut progress: usize = 0;
	let target = hash_lists.len ();

	let mut error_count: u64 = 0;

	output.status (
		"Deduplication progress: 0%");

	for (_, paths)
	in hash_lists.into_iter () {

		let (first_path_slice, other_paths) =
			paths.split_at (1);

		let first_path =
			first_path_slice.into_iter ().next ().unwrap ();

		for paths_chunk in other_paths.chunks (512) {

			match btrfs::deduplicate_files_with_source (
				first_path,
				paths_chunk,
			) {

				Ok (_) => (),
				Err (_) => error_count += 1,

			}

		}

		progress += 1;

		if progress % 256 == 0 {

			output.status (
				& format! (
					"Deduplication progress: {}%",
					progress * 100 / target));

		}

	};

	output.clear_status ();

	if error_count > 0 {

		output.message (
			& format! (
				"Encountered {} errors during deduplication",
				error_count));

	} else {

		output.message (
			& format! (
				"Deduplicated all files successfully"));

	}

	// return

	Ok (())

}

// ex: noet ts=4 filetype=rust
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate rsstreem;
extern crate rsstreem_parser as parser;

use clap::{App, Arg};
use parser::parse;

use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

fn main() {
    let matches = App::new("rsstreem-language")
        .version(crate_version!())
        .author("everysick <s.wakeup31@gmail.com>")
        .about("Implementation of streem by Rust.")
        .arg(Arg::with_name("file")
                 .short("f")
                 .long("file")
                 .help("Target file for execute"))
        .get_matches();

    // Some code is not verified yet.
    // TODO: parse from FILE
    if let Some(f) = matches.value_of("file") {
        let path = PathBuf::from(f);

        let code = File::open(&path)
            .map_err(|error| String::from(error.description()))
            .and_then(|mut file| {
                          let mut s = String::new();
                          file.read_to_string(&mut s)
                              .map_err(|error| String::from(error.description()))
                              .map(|_| s)
                      })
            .unwrap();

        let ast = parse::parse_code(code.as_ref()).unwrap();
    }
}
<commit_msg>Use rustfmt v0.9.0 && format files<commit_after>#[macro_use]
extern crate clap;
extern crate rsstreem;
extern crate rsstreem_parser as parser;

use clap::{App, Arg};
use parser::parse;

use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

fn main() {
    let matches = App::new("rsstreem-language")
        .version(crate_version!())
        .author("everysick <s.wakeup31@gmail.com>")
        .about("Implementation of streem by Rust.")
        .arg(Arg::with_name("file").short("f").long("file").help(
            "Target file for execute",
        ))
        .get_matches();

    // Some code is not verified yet.
    // TODO: parse from FILE
    if let Some(f) = matches.value_of("file") {
        let path = PathBuf::from(f);

        let code = File::open(&path)
            .map_err(|error| String::from(error.description()))
            .and_then(|mut file| {
                let mut s = String::new();
                file.read_to_string(&mut s)
                    .map_err(|error| String::from(error.description()))
                    .map(|_| s)
            })
            .unwrap();

        let ast = parse::parse_code(code.as_ref()).unwrap();
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate lazy_static;
#[macro_use] extern crate image;
#[macro_use] extern crate clap;

mod modes;
mod pixel;
mod loader;

use clap::App;

fn main() {
  let yaml = load_yaml!("../cli.yml");
  let app = App::from_yaml(yaml);
  let matches = app.get_matches();

  let printer = match matches.value_of("mode").unwrap() {
    "ansi"       => modes::ansi::print_pixel,
    "grayscale"  => modes::grayscale::print_pixel,
    "true_color" => modes::true_color::print_pixel,
    _            => modes::text::print_pixel
  };

  let mut l = loader::ImageLoader { filename: matches.value_of("FILE").unwrap(),
                                    cols:     matches.value_of("width").unwrap().parse::<u32>().unwrap(),
                                    filter:   matches.value_of("filter").unwrap(),
                                    ..Default::default() };
  l.load();
  l.paint(printer);
}
<commit_msg>Refactor main code.<commit_after>#[macro_use] extern crate lazy_static;
#[macro_use] extern crate image;
#[macro_use] extern crate clap;

mod modes;
mod pixel;
mod loader;

use clap::App;

fn main() {
  let yaml = load_yaml!("../cli.yml");
  let matches = App::from_yaml(yaml).get_matches();

  let printer = match matches.value_of("mode").unwrap() {
    "ansi"       => modes::ansi::print_pixel,
    "grayscale"  => modes::grayscale::print_pixel,
    "true_color" => modes::true_color::print_pixel,
    _            => modes::text::print_pixel
  };

  let mut l = loader::ImageLoader { filename: matches.value_of("FILE").unwrap(),
                                    cols:     matches.value_of("width").unwrap().parse::<u32>().unwrap(),
                                    filter:   matches.value_of("filter").unwrap(),
                                    ..Default::default() };
  l.load();
  l.paint(printer);
}
<|endoftext|>


<commit_before>#[macro_use(shared_ntfy)]
extern crate rust_install;

extern crate clap;
extern crate multirust;

use std::ffi::OsStr;
use std::error::Error;

use clap::{App, AppSettings, Arg};

use multirust::{Cfg, Notification, Toolchain};

type Result<T> = std::result::Result<T, Box<Error>>;

// Copied from multirust-rs.
fn set_globals() -> multirust::Result<Cfg> {
    // Base config
    let verbose = false;
    Cfg::from_env(shared_ntfy!(move |n: Notification| {
        use multirust::notify::NotificationLevel::*;
        match n.level() {
            Verbose => {
                if verbose {
                    println!("{}", n);
                }
            }
            _ => {
                println!("{}", n);
            }
        }
    }))
}

struct Cmd<'a> {
    program: &'a OsStr,
    args: &'a [&'a OsStr],
}

impl<'a> Cmd<'a> {
    fn from(command: &'a [&'a OsStr]) -> Cmd<'a> {
        let program = command[0];
        let args = &command[1..];

        Cmd {
            program: program,
            args: args,
        }
    }

    fn succeeds_with<'b>(&self, toolchain: &Toolchain<'b>) -> Result<bool> {
        let mut cmd = try!(toolchain.create_command(self.program));
        cmd.args(self.args);
        let status = try!(cmd.status());
        Ok(status.success())
    }
}

fn run_rust_bisect() -> Result<()> {
    let matches = App::new("rustc-bisect")
                      .author("Kamal Marhubi <kamal@marhubi.com>")
                      .setting(AppSettings::TrailingVarArg)
                      .arg(Arg::with_name("toolchain")
                               .long("tmp-toolchain")
                               .takes_value(true)
                               .value_name("TOOLCHAIN")
                               .required(true))
                      .arg(Arg::with_name("good")
                               .long("good")
                               .takes_value(true)
                               .value_name("TOOLCHAIN"))
                      .arg(Arg::with_name("bad")
                               .long("bad")
                               .takes_value(true)
                               .value_name("TOOLCHAIN"))
                      .arg(Arg::with_name("COMMAND")
                               .multiple(true)
                               .required(true))
                      .get_matches();

    let cfg = try!(set_globals());

    let cmd: Vec<_> = matches.values_of_os("COMMAND").expect("COMMAND").collect();
    let cmd = Cmd::from(&cmd[..]);

    let toolchain = try!(cfg.get_toolchain(matches.value_of("toolchain").expect("toolchain"),
                                           false));
    try!(toolchain.install_from_dist_if_not_installed());

    println!("{}", try!(cmd.succeeds_with(&toolchain)));

    Ok(())
}

fn main() {
    run_rust_bisect().expect("something went wrong");
}
<commit_msg>Fix missing reference<commit_after>#[macro_use(shared_ntfy)]
extern crate rust_install;

extern crate clap;
extern crate multirust;

use std::ffi::OsStr;
use std::error::Error;

use clap::{App, AppSettings, Arg};

use multirust::{Cfg, Notification, Toolchain};

type Result<T> = std::result::Result<T, Box<Error>>;

// Copied from multirust-rs.
fn set_globals() -> multirust::Result<Cfg> {
    // Base config
    let verbose = false;
    Cfg::from_env(shared_ntfy!(move |n: Notification| {
        use multirust::notify::NotificationLevel::*;
        match n.level() {
            Verbose => {
                if verbose {
                    println!("{}", n);
                }
            }
            _ => {
                println!("{}", n);
            }
        }
    }))
}

struct Cmd<'a> {
    program: &'a OsStr,
    args: &'a [&'a OsStr],
}

impl<'a> Cmd<'a> {
    fn from(command: &'a [&'a OsStr]) -> Cmd<'a> {
        let program = command[0];
        let args = &command[1..];

        Cmd {
            program: program,
            args: args,
        }
    }

    fn succeeds_with<'b>(&self, toolchain: &Toolchain<'b>) -> Result<bool> {
        let mut cmd = try!(toolchain.create_command(&self.program));
        cmd.args(self.args);
        let status = try!(cmd.status());
        Ok(status.success())
    }
}

fn run_rust_bisect() -> Result<()> {
    let matches = App::new("rustc-bisect")
                      .author("Kamal Marhubi <kamal@marhubi.com>")
                      .setting(AppSettings::TrailingVarArg)
                      .arg(Arg::with_name("toolchain")
                               .long("tmp-toolchain")
                               .takes_value(true)
                               .value_name("TOOLCHAIN")
                               .required(true))
                      .arg(Arg::with_name("good")
                               .long("good")
                               .takes_value(true)
                               .value_name("TOOLCHAIN"))
                      .arg(Arg::with_name("bad")
                               .long("bad")
                               .takes_value(true)
                               .value_name("TOOLCHAIN"))
                      .arg(Arg::with_name("COMMAND")
                               .multiple(true)
                               .required(true))
                      .get_matches();

    let cfg = try!(set_globals());

    let cmd: Vec<_> = matches.values_of_os("COMMAND").expect("COMMAND").collect();
    let cmd = Cmd::from(&cmd[..]);

    let toolchain = try!(cfg.get_toolchain(matches.value_of("toolchain").expect("toolchain"),
                                           false));
    try!(toolchain.install_from_dist_if_not_installed());

    println!("{}", try!(cmd.succeeds_with(&toolchain)));

    Ok(())
}

fn main() {
    run_rust_bisect().expect("something went wrong");
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate error_chain;

extern crate clap;
extern crate serde;
extern crate rmp_serde;
extern crate sodiumoxide;
extern crate xdg;

extern crate mine;

mod init;
mod insert;
mod show;
mod set_tag;

use clap::{Arg, App, AppSettings, SubCommand};

use mine::Mine;

mod errors {
    extern crate mine;
    // Create the Error, ErrorKind, ResultExt, and Result types
    error_chain! {
        links {
            MineLib(mine::errors::Error, mine::errors::ErrorKind);
        }
    }
}

use errors::*;

quick_main!(run);

fn run() -> Result<()> {
    sodiumoxide::init();

    let matches = App::new("mine")
                    .version("0.0.0")
                    .author("Johannes Löthberg <johannes@kyriasis.com>")
                    .about("NaCL based password manager in Rust")
                    .global_settings(&[AppSettings::ColoredHelp])
                    .setting(AppSettings::SubcommandRequired)
                    .subcommand(SubCommand::with_name("init")
                                .about("initialize password store"))
                    .subcommand(SubCommand::with_name("insert")
                                .about("insert a password")
                                .arg(Arg::with_name("NAME")
                                     .required(true)
                                     .index(1))
                                .arg(Arg::with_name("PASSWORD")
                                     .required(true)
                                     .index(2)))
                    .subcommand(SubCommand::with_name("show")
                                .about("show a password")
                                .arg(Arg::with_name("NAME")
                                     .help("Password name")
                                     .required(true)
                                     .index(1)))
                    .subcommand(SubCommand::with_name("set-tag")
                                .about("set a tag on a password")
                                .arg(Arg::with_name("PASSWORD")
                                     .required(true)
                                     .index(1))
                                .arg(Arg::with_name("TAG")
                                     .required(true)
                                     .index(2))
                                .arg(Arg::with_name("VALUE")
                                     .required(true)
                                     .index(3)))
                    .get_matches();

    let mine = Mine::new("mine")
        .chain_err(|| "failed to initialize mine")?;

    let subcommand = matches.subcommand_name().unwrap();
    let sub_matches = matches.subcommand_matches(subcommand).unwrap();

    match subcommand {
        "init" => init::init_run(mine)?,
        "insert" => insert::insert_run(mine, sub_matches)?,
        "show" => show::show_run(mine, sub_matches)?,
        "set-tag" => set_tag::set_tag_run(mine, sub_matches)?,
        _ => unreachable!(),
    }

    Ok(())
}

<commit_msg>main: Reindent clap lines<commit_after>#[macro_use]
extern crate error_chain;

extern crate clap;
extern crate serde;
extern crate rmp_serde;
extern crate sodiumoxide;
extern crate xdg;

extern crate mine;

mod init;
mod insert;
mod show;
mod set_tag;

use clap::{Arg, App, AppSettings, SubCommand};

use mine::Mine;

mod errors {
    extern crate mine;
    // Create the Error, ErrorKind, ResultExt, and Result types
    error_chain! {
        links {
            MineLib(mine::errors::Error, mine::errors::ErrorKind);
        }
    }
}

use errors::*;

quick_main!(run);

fn run() -> Result<()> {
    sodiumoxide::init();

    let matches = App::new("mine")
        .version("0.0.0")
        .author("Johannes Löthberg <johannes@kyriasis.com>")
        .about("NaCL based password manager in Rust")
        .global_settings(&[AppSettings::ColoredHelp])
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("init")
                    .about("initialize password store"))
        .subcommand(SubCommand::with_name("insert")
                    .about("insert a password")
                    .arg(Arg::with_name("NAME")
                         .required(true)
                         .index(1))
                    .arg(Arg::with_name("PASSWORD")
                         .required(true)
                         .index(2)))
        .subcommand(SubCommand::with_name("show")
                    .about("show a password")
                    .arg(Arg::with_name("NAME")
                         .help("Password name")
                         .required(true)
                         .index(1)))
        .subcommand(SubCommand::with_name("set-tag")
                    .about("set a tag on a password")
                    .arg(Arg::with_name("PASSWORD")
                         .required(true)
                         .index(1))
                    .arg(Arg::with_name("TAG")
                         .required(true)
                         .index(2))
                    .arg(Arg::with_name("VALUE")
                         .required(true)
                         .index(3)))
        .get_matches();

    let mine = Mine::new("mine")
        .chain_err(|| "failed to initialize mine")?;

    let subcommand = matches.subcommand_name().unwrap();
    let sub_matches = matches.subcommand_matches(subcommand).unwrap();

    match subcommand {
        "init" => init::init_run(mine)?,
        "insert" => insert::insert_run(mine, sub_matches)?,
        "show" => show::show_run(mine, sub_matches)?,
        "set-tag" => set_tag::set_tag_run(mine, sub_matches)?,
        _ => unreachable!(),
    }

    Ok(())
}

<|endoftext|>


<commit_before>extern crate mysql;

extern crate toml;
#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate log;
extern crate log4rs;

#[macro_use]
extern crate lazy_static;
extern crate timer;
extern crate chrono;
extern crate hyper;
extern crate hyper_native_tls;
extern crate json;
extern crate flate2;
extern crate sha2;

mod lib;
mod handler;

use lib::downloader::Downloader;
use lib::converter::Converter;
use handler::init_handlers;
use handler::Registry;
use timer::{Timer};
use std::sync::Arc;
use lib::config;
use lib::db;
use lib::logger;
use lib::Error;

const VERSION: &'static str = "0.6.3";
const CONFIG_PATH: &'static str = "config.cfg";
const USER_AGENT: &'static str = "hyper/yayd (github.com/0xpr03/yayd)";
const LOG_CONFIG: &'static str = "logger.yaml";
const LOG_PATTERN: &'static str = "{d(%d-%m-%Y %H:%M:%S)}\t{l}\t{f}:{L} \t{m:>10}{n}";
const CODE_WAITING: i8 = -1;
const CODE_STARTED: i8 = 0;
const CODE_IN_PROGRESS: i8 = 1;
const CODE_SUCCESS: i8 = 2;
const CODE_SUCCESS_WARNINGS: i8 = 3; // finished with warnings
const CODE_FAILED_INTERNAL: i8 = 10; // internal error
const CODE_FAILED_QUALITY: i8 = 11; // qualitz not available
const CODE_FAILED_UNAVAILABLE: i8 = 12; // source unavailable (private / removed)
const CODE_FAILED_UNKNOWN: i8 = 13; // URL invalid, no handler

lazy_static! {
    pub static ref CONFIG: config::Config = {
        println!("Starting yayd-backend v{}",&VERSION);
        config::init_config()
    };
    pub static ref SLEEP_TIME: std::time::Duration = {
        std::time::Duration::new(5,0)
    };
}

macro_rules! try_return { ($e:expr) => (match $e { Ok(x) => x, Err(e) => {error!("{}",e);return; },}) }

//#[allow(non_camel_case_types)]
//#[derive(Clone, Eq, PartialEq, Debug, Copy)]
//#[repr(i8)]// broken, enum not usable as of #10292
//enum StatusCodes {
//    QueryStarted = 0,
//    InProgress = 1,
//    Success = 2,
//    Finished_Warnings = 3,
//    FailedInternal = 10,
//    FailedQuality = 11,
//    FailedUnavailable = 12,
//}
#[cfg(not(test))]
fn main() {
    logger::initialize();
    let pool = Arc::new(db::db_connect(db::mysql_options(&CONFIG), *SLEEP_TIME));
    debug!("cleaning db...");
    let mut conn = pool.get_conn().map_err(|_| panic!("Couldn't retrieve connection!")).unwrap();
    db::clear_query_states(&mut conn);

    let converter = Converter::new(&CONFIG.general.ffmpeg_bin_dir,&CONFIG.general.mp3_quality);

    if !converter.startup_test() {
        error!("Converter self test failed! Exiting");
        return;
    }

    let downloader = Arc::new(Downloader::new(&CONFIG.general));

    if !downloader.startup_test() {
        error!("Downloader self test failed! Exiting");
        return;
    }

    let handler = init_handlers(downloader.clone(),converter);

    let timer = timer::Timer::new();
    debug!("Auto cleanup old files: {}",CONFIG.cleanup.auto_delete_files);
    if CONFIG.cleanup.delete_files {
        run_auto_cleanup_thread(pool.clone(), &timer);
    }

    debug!("Cleanup marked entries with `delete` flag: {}",CONFIG.cleanup.delete_files);
    if CONFIG.cleanup.delete_files {
        run_cleanup_thread(pool.clone(), &timer);
    }

    debug!("Auto-Update yt-dl: {}",CONFIG.general.youtube_dl_auto_update);
    if CONFIG.general.youtube_dl_auto_update {
        run_update_thread(downloader.clone(), &timer);
    }

    debug!("finished startup");
    main_loop(&*pool, handler);
    //drop(update_thread);
}

fn main_loop(pool: &mysql::conn::pool::Pool, mut handler: Registry) {
    let mut print_pause = true;

    loop {
        if let Some(mut request) = db::request_entry(pool) {
            trace!("got request");
            print_pause = true;
            let qid = request.qid.clone();
            db::set_query_code(&mut request.get_conn(), &request.qid ,&CODE_STARTED);
            db::set_query_state(&mut request.get_conn(),&request.qid, "started");
            trace!("starting handler");
            let code: i8 = match handler.handle(&mut request) {
                Ok(_) => CODE_SUCCESS,
                Err(e) => {
                    trace!("Error: {:?}",e);
                    match e {
                        Error::NotAvailable => CODE_FAILED_UNAVAILABLE,
                        Error::ExtractorError => CODE_FAILED_UNAVAILABLE,
                        Error::QualityNotAvailable => CODE_FAILED_QUALITY,
                        Error::UnknownURL => CODE_FAILED_UNKNOWN,
                        _ => {
                            error!("Unknown Error: {:?}",e);
                            let details = match e {
                                Error::DBError(s) => format!("{:?}",s),
                                Error::DownloadError(s) => s,
                                Error::FFMPEGError(s) => s,
                                Error::InternalError(s) => s,
                                Error::InputError(s) => s,
                                Error::HandlerError(s) => s,
                                _ => unreachable!(),
                            };
                            db::add_query_error(&mut request.get_conn(),&qid, &details);
                            CODE_FAILED_INTERNAL
                        },
                    }
                }
            };
            trace!("handler finished");
            db::set_query_code(&mut request.get_conn(), &qid,&code);
            db::set_null_state(&mut request.get_conn(), &qid);
        } else {
            if print_pause { trace!("Worker idle.."); print_pause = false; }
            std::thread::sleep(*SLEEP_TIME);
        }
    }
}

/// Auto cleanup task
fn run_auto_cleanup_thread<'a>(pool: Arc<mysql::conn::pool::Pool>, timer: &'a Timer) {
    let path = std::path::PathBuf::from(&CONFIG.general.download_dir);
    let a = timer.schedule_repeating(chrono::Duration::minutes(CONFIG.cleanup.delete_interval as i64), move || {
        trace!("performing auto cleanup");
        let local_pool = &*pool;
        let val = lib::delete_files(local_pool,db::DeleteRequestType::AgedMin(&CONFIG.cleanup.auto_delete_age),&path);
        match val {
            Ok(_) => (),
            Err(e) => error!("Couldn't auto cleanup! {:?}",e),
        }
    });
    a.ignore(); // ignore schedule guard a
}

/// Cleanup requested task
fn run_cleanup_thread<'a>(pool: Arc<mysql::conn::pool::Pool>, timer: &'a Timer) {
    let path = std::path::PathBuf::from(&CONFIG.general.download_dir);
    let a = timer.schedule_repeating(chrono::Duration::minutes(CONFIG.cleanup.delete_interval as i64), move || {
        trace!("performing deletion requests");
        let local_pool = &*pool;
        let val = lib::delete_files(local_pool,db::DeleteRequestType::Marked,&path);
        match val {
            Ok(_) => (),
            Err(e) => error!("Couldn't perform deletions! {:?}",e),
        }
    });
    a.ignore(); // ignore schedule guard a
}

/// youtube-dl update task
fn run_update_thread<'a>(downloader: Arc<Downloader>,timer: &'a Timer) {
    let a = timer.schedule_repeating(chrono::Duration::hours(24), move || {
    match downloader.update_downloader() {
        Ok(_) => (),
        Err(e) => error!("Couldn't perform youtube-dl update! {:?}",e),
    }
    });
    a.ignore(); // ignore schedule guard a
}
<commit_msg>fix wrong config setting used for auto deletions<commit_after>extern crate mysql;

extern crate toml;
#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate log;
extern crate log4rs;

#[macro_use]
extern crate lazy_static;
extern crate timer;
extern crate chrono;
extern crate hyper;
extern crate hyper_native_tls;
extern crate json;
extern crate flate2;
extern crate sha2;

mod lib;
mod handler;

use lib::downloader::Downloader;
use lib::converter::Converter;
use handler::init_handlers;
use handler::Registry;
use timer::{Timer};
use std::sync::Arc;
use lib::config;
use lib::db;
use lib::logger;
use lib::Error;

const VERSION: &'static str = "0.6.3";
const CONFIG_PATH: &'static str = "config.cfg";
const USER_AGENT: &'static str = "hyper/yayd (github.com/0xpr03/yayd)";
const LOG_CONFIG: &'static str = "logger.yaml";
const LOG_PATTERN: &'static str = "{d(%d-%m-%Y %H:%M:%S)}\t{l}\t{f}:{L} \t{m:>10}{n}";
const CODE_WAITING: i8 = -1;
const CODE_STARTED: i8 = 0;
const CODE_IN_PROGRESS: i8 = 1;
const CODE_SUCCESS: i8 = 2;
const CODE_SUCCESS_WARNINGS: i8 = 3; // finished with warnings
const CODE_FAILED_INTERNAL: i8 = 10; // internal error
const CODE_FAILED_QUALITY: i8 = 11; // qualitz not available
const CODE_FAILED_UNAVAILABLE: i8 = 12; // source unavailable (private / removed)
const CODE_FAILED_UNKNOWN: i8 = 13; // URL invalid, no handler

lazy_static! {
    pub static ref CONFIG: config::Config = {
        println!("Starting yayd-backend v{}",&VERSION);
        config::init_config()
    };
    pub static ref SLEEP_TIME: std::time::Duration = {
        std::time::Duration::new(5,0)
    };
}

macro_rules! try_return { ($e:expr) => (match $e { Ok(x) => x, Err(e) => {error!("{}",e);return; },}) }

//#[allow(non_camel_case_types)]
//#[derive(Clone, Eq, PartialEq, Debug, Copy)]
//#[repr(i8)]// broken, enum not usable as of #10292
//enum StatusCodes {
//    QueryStarted = 0,
//    InProgress = 1,
//    Success = 2,
//    Finished_Warnings = 3,
//    FailedInternal = 10,
//    FailedQuality = 11,
//    FailedUnavailable = 12,
//}
#[cfg(not(test))]
fn main() {
    logger::initialize();
    let pool = Arc::new(db::db_connect(db::mysql_options(&CONFIG), *SLEEP_TIME));
    debug!("cleaning db...");
    let mut conn = pool.get_conn().map_err(|_| panic!("Couldn't retrieve connection!")).unwrap();
    db::clear_query_states(&mut conn);

    let converter = Converter::new(&CONFIG.general.ffmpeg_bin_dir,&CONFIG.general.mp3_quality);

    if !converter.startup_test() {
        error!("Converter self test failed! Exiting");
        return;
    }

    let downloader = Arc::new(Downloader::new(&CONFIG.general));

    if !downloader.startup_test() {
        error!("Downloader self test failed! Exiting");
        return;
    }

    let handler = init_handlers(downloader.clone(),converter);

    let timer = timer::Timer::new();
    debug!("Auto cleanup old files: {}",CONFIG.cleanup.auto_delete_files);
    if CONFIG.cleanup.auto_delete_files {
        run_auto_cleanup_thread(pool.clone(), &timer);
    }

    debug!("Cleanup marked entries with `delete` flag: {}",CONFIG.cleanup.delete_files);
    if CONFIG.cleanup.delete_files {
        run_cleanup_thread(pool.clone(), &timer);
    }

    debug!("Auto-Update yt-dl: {}",CONFIG.general.youtube_dl_auto_update);
    if CONFIG.general.youtube_dl_auto_update {
        run_update_thread(downloader.clone(), &timer);
    }

    debug!("finished startup");
    main_loop(&*pool, handler);
    //drop(update_thread);
}

fn main_loop(pool: &mysql::conn::pool::Pool, mut handler: Registry) {
    let mut print_pause = true;

    loop {
        if let Some(mut request) = db::request_entry(pool) {
            trace!("got request");
            print_pause = true;
            let qid = request.qid.clone();
            db::set_query_code(&mut request.get_conn(), &request.qid ,&CODE_STARTED);
            db::set_query_state(&mut request.get_conn(),&request.qid, "started");
            trace!("starting handler");
            let code: i8 = match handler.handle(&mut request) {
                Ok(_) => CODE_SUCCESS,
                Err(e) => {
                    trace!("Error: {:?}",e);
                    match e {
                        Error::NotAvailable => CODE_FAILED_UNAVAILABLE,
                        Error::ExtractorError => CODE_FAILED_UNAVAILABLE,
                        Error::QualityNotAvailable => CODE_FAILED_QUALITY,
                        Error::UnknownURL => CODE_FAILED_UNKNOWN,
                        _ => {
                            error!("Unknown Error: {:?}",e);
                            let details = match e {
                                Error::DBError(s) => format!("{:?}",s),
                                Error::DownloadError(s) => s,
                                Error::FFMPEGError(s) => s,
                                Error::InternalError(s) => s,
                                Error::InputError(s) => s,
                                Error::HandlerError(s) => s,
                                _ => unreachable!(),
                            };
                            db::add_query_error(&mut request.get_conn(),&qid, &details);
                            CODE_FAILED_INTERNAL
                        },
                    }
                }
            };
            trace!("handler finished");
            db::set_query_code(&mut request.get_conn(), &qid,&code);
            db::set_null_state(&mut request.get_conn(), &qid);
        } else {
            if print_pause { trace!("Worker idle.."); print_pause = false; }
            std::thread::sleep(*SLEEP_TIME);
        }
    }
}

/// Auto cleanup task
fn run_auto_cleanup_thread<'a>(pool: Arc<mysql::conn::pool::Pool>, timer: &'a Timer) {
    let path = std::path::PathBuf::from(&CONFIG.general.download_dir);
    let a = timer.schedule_repeating(chrono::Duration::minutes(CONFIG.cleanup.delete_interval as i64), move || {
        trace!("performing auto cleanup");
        let local_pool = &*pool;
        let val = lib::delete_files(local_pool,db::DeleteRequestType::AgedMin(&CONFIG.cleanup.auto_delete_age),&path);
        match val {
            Ok(_) => (),
            Err(e) => error!("Couldn't auto cleanup! {:?}",e),
        }
    });
    a.ignore(); // ignore schedule guard a
}

/// Cleanup requested task
fn run_cleanup_thread<'a>(pool: Arc<mysql::conn::pool::Pool>, timer: &'a Timer) {
    let path = std::path::PathBuf::from(&CONFIG.general.download_dir);
    let a = timer.schedule_repeating(chrono::Duration::minutes(CONFIG.cleanup.delete_interval as i64), move || {
        trace!("performing deletion requests");
        let local_pool = &*pool;
        let val = lib::delete_files(local_pool,db::DeleteRequestType::Marked,&path);
        match val {
            Ok(_) => (),
            Err(e) => error!("Couldn't perform deletions! {:?}",e),
        }
    });
    a.ignore(); // ignore schedule guard a
}

/// youtube-dl update task
fn run_update_thread<'a>(downloader: Arc<Downloader>,timer: &'a Timer) {
    let a = timer.schedule_repeating(chrono::Duration::hours(24), move || {
    match downloader.update_downloader() {
        Ok(_) => (),
        Err(e) => error!("Couldn't perform youtube-dl update! {:?}",e),
    }
    });
    a.ignore(); // ignore schedule guard a
}
<|endoftext|>


<commit_before>#![feature(custom_attribute, custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate hyper;
extern crate serde;

mod entity;
mod error;

use entity::ZipResult;
use error::ZipError;
use hyper::Client;
use serde::json;
use std::io::Read;

fn main() {
    let result = std::env::args().nth(1).ok_or(ZipError::Input)
        .and_then(|candidate| query(candidate))
        .and_then(|(candidate, response)| parse_result(candidate, response));

    match result {
        Ok(zip_result) => println!("{}", zip_result),
        Err(e) => println!("{}", e),
    }
}

fn query(candidate: String) -> Result<(String, String), ZipError> {
    let mut client = Client::new();

    match client.get(&format!("http://api.zippopotam.us/us/{}", candidate)).send() {
        Ok(mut res) => Ok((candidate, read_response(&mut res))),
        _ => Err(ZipError::API),
    }
}

#[allow(unused)]
fn read_response(response: &mut hyper::client::response::Response) -> String {
    let mut buf = String::new();
    response.read_to_string(&mut buf);
    buf
}

fn parse_result(candidate: String, result: String) -> Result<ZipResult, ZipError> {
    match json::from_str(&result) {
        Ok(result) => Ok(result),
        Err(_) => Err(ZipError::Invalid(candidate)),
    }
}
<commit_msg>Fix for lifetime error?<commit_after>#![feature(custom_attribute, custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate hyper;
extern crate serde;

mod entity;
mod error;

use entity::ZipResult;
use error::ZipError;
use hyper::Client;
use serde::json;
use std::io::Read;

fn main() {
    let mut client = Client::new();
    let result = std::env::args().nth(1).ok_or(ZipError::Input)
        .and_then(|candidate| query(&mut client, candidate))
        .and_then(|(candidate, response)| parse_result(candidate, response));

    match result {
        Ok(zip_result) => println!("{}", zip_result),
        Err(e) => println!("{}", e),
    }
}

fn query(client: &mut Client, candidate: String) -> Result<(String, String), ZipError> {
    match client.get(&format!("http://api.zippopotam.us/us/{}", candidate)).send() {
        Ok(mut res) => Ok((candidate, read_response(&mut res))),
        _ => Err(ZipError::API),
    }
}

#[allow(unused)]
fn read_response(response: &mut hyper::client::response::Response) -> String {
    let mut buf = String::new();
    response.read_to_string(&mut buf);
    buf
}

fn parse_result(candidate: String, result: String) -> Result<ZipResult, ZipError> {
    match json::from_str(&result) {
        Ok(result) => Ok(result),
        Err(_) => Err(ZipError::Invalid(candidate)),
    }
}
<|endoftext|>


<commit_before>extern crate byteorder;
extern crate stats;
extern crate iron;
extern crate staticfile;
extern crate mount;
extern crate persistent;
#[macro_use]
extern crate lazy_static;
mod lib;

use std::fs::File;
use std::io::*;
use iron::{Iron, Request, Response, IronResult, IronError, Plugin};
use iron::typemap::Key;
use iron::status;
use iron::mime::Mime;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use lib::caching::CorrelationCache;

#[derive(Copy, Clone)]
pub struct CorrCache;
impl Key for CorrCache { type Value = CorrelationCache; }

lazy_static! {
    static ref DATA_SETS: Vec<lib::btsf::BinaryTimeSeries> = {
        lib::btsf::read_btsf_file(&mut File::open("./btsf/mortality.btsf").unwrap()).unwrap()
    };
}

fn main() {
    fn request_handler(req: &mut Request) -> IronResult<Response>{
        let mut buffer: Vec<u8> = Vec::new();
        req.body.read_to_end(&mut buffer).unwrap();
        let input_charts = match lib::btsf::read_btsf_file(&mut Cursor::new(&mut buffer)) {
            Ok(charts) => charts,
            Err(e) => return Err(IronError::new(e, status::BadRequest)),
        };
        if input_charts.len() != 1 {
            return Ok(Response::with((status::BadRequest, "Please send a BTSF file with precisely one chart in it")))
        }

        let mutex = req.get::<persistent::Write<CorrCache>>().unwrap();
        let mut cache = mutex.lock().unwrap();
        let result = cache.correlate(&input_charts[0], &DATA_SETS[..]);

        let mut response_data: Vec<u8> = Vec::new();
        if let Err(e) = lib::btsf::write_correlated_btsf_file(&result[..], &mut response_data) {
            return Err(IronError::new(e, status::InternalServerError));
        }

        let content_type: Mime = "application/octet-stream".parse().unwrap();
        return Ok(Response::with((status::Ok, content_type, response_data)));
    };

    let mut mount = Mount::new();
    mount
        .mount("/", Static::new(Path::new("./public")))
        .mount("/find", request_handler);

    let corr_cache = CorrelationCache::new();
    let mut chain = iron::Chain::new(mount);
    chain.link_before(persistent::Write::<CorrCache>::one(corr_cache));

    // This print statement is partially just to invoke the lazy static
    println!("Serving up {} data sets!", DATA_SETS.len());
    Iron::new(chain).http("localhost:8080").unwrap();
}
<commit_msg>Release mutex as soon as possible.<commit_after>extern crate byteorder;
extern crate stats;
extern crate iron;
extern crate staticfile;
extern crate mount;
extern crate persistent;
#[macro_use]
extern crate lazy_static;
mod lib;

use std::fs::File;
use std::io::*;
use iron::{Iron, Request, Response, IronResult, IronError, Plugin};
use iron::typemap::Key;
use iron::status;
use iron::mime::Mime;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use lib::caching::CorrelationCache;

#[derive(Copy, Clone)]
pub struct CorrCache;
impl Key for CorrCache { type Value = CorrelationCache; }

lazy_static! {
    static ref DATA_SETS: Vec<lib::btsf::BinaryTimeSeries> = {
        lib::btsf::read_btsf_file(&mut File::open("./btsf/mortality.btsf").unwrap()).unwrap()
    };
}

fn main() {
    fn request_handler(req: &mut Request) -> IronResult<Response>{
        let mut buffer: Vec<u8> = Vec::new();
        req.body.read_to_end(&mut buffer).unwrap();
        let input_charts = match lib::btsf::read_btsf_file(&mut Cursor::new(&mut buffer)) {
            Ok(charts) => charts,
            Err(e) => return Err(IronError::new(e, status::BadRequest)),
        };
        if input_charts.len() != 1 {
            return Ok(Response::with((status::BadRequest, "Please send a BTSF file with precisely one chart in it")))
        }

        let result = {
            let mutex = req.get::<persistent::Write<CorrCache>>().unwrap();
            let mut cache = mutex.lock().unwrap();
            cache.correlate(&input_charts[0], &DATA_SETS[..])
        };

        let mut response_data: Vec<u8> = Vec::new();
        if let Err(e) = lib::btsf::write_correlated_btsf_file(&result[..], &mut response_data) {
            return Err(IronError::new(e, status::InternalServerError));
        }

        let content_type: Mime = "application/octet-stream".parse().unwrap();
        return Ok(Response::with((status::Ok, content_type, response_data)));
    };

    let mut mount = Mount::new();
    mount
        .mount("/", Static::new(Path::new("./public")))
        .mount("/find", request_handler);

    let corr_cache = CorrelationCache::new();
    let mut chain = iron::Chain::new(mount);
    chain.link_before(persistent::Write::<CorrCache>::one(corr_cache));

    // This print statement is partially just to invoke the lazy static
    println!("Serving up {} data sets!", DATA_SETS.len());
    Iron::new(chain).http("localhost:8080").unwrap();
}
<|endoftext|>