<commit_before>extern crate num;
extern crate rand;
extern crate bignum = "bignum#0.1.1-pre";

use bignum::{BigUint, ToBigUint, RandBigInt};
use num::{div_mod_floor, Integer};
use std::num::{Zero, One, pow, Float, FromPrimitive};
use rand::{task_rng, Rng};
use rand::distributions::range::SampleRange;
use std::vec::Vec;
use std::iter;
use std::clone::Clone;
use std::ops::{Shr, BitAnd};

static pow_offsets : &'static[uint] = &[0u, 4u, 6u, 10u, 12u, 16u];

#[inline]
fn big<T: ToBigUint>(i : T) -> BigUint {
    i.to_biguint().unwrap()
}

// Source: https://gist.github.com/jsanders/8739134#file-generate_big_primes-rs-L35
fn mod_exp<T: Integer + Clone + Shr<uint,T> + BitAnd<T,T>>
    (base: &T, exponent: &T, modulus: &T) -> T {

    let (zero, one): (T, T) = (Zero::zero(), One::one());
    let mut result = one.clone();
    let mut baseAcc = base.clone();
    let mut exponentAcc = exponent.clone();

    while exponentAcc > zero {
        // Accumulate current base if current exponent bit is 1
        if (exponentAcc & one) == one {
            result = result.mul(&baseAcc);
            result = result.rem(modulus);
        }
        // Get next base by squaring
        baseAcc = baseAcc * baseAcc;
        baseAcc = baseAcc % *modulus;

        // Get next bit of exponent
        exponentAcc = exponentAcc.shr(&1);
    }
    result

}

// Rabin-Miller primality test, probabilistic
fn try_composite(a : &BigUint, d : &BigUint, n : &BigUint, s : &BigUint) -> bool {

    let one : BigUint = One::one();
    if mod_exp(a, d, n) == one {
        return false
    }
    let mut i = 0u;
    loop {
        if big(i) == *s {
            break
        }
        if mod_exp(a, &(pow(one+one, i) * *d), n) == *n-one {
            return false
        }
        i += 1;
    }
    true

}
fn is_prime(n : &BigUint) -> bool {

    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    assert!(n >= &two);

    let mut s = zero.clone();
    let mut d = *n-one;
    let num_trials = 5;
    if n == &two {
        return true
    } else if n == &one || n.is_even() {
        return false
    } else {
        loop {
            let (quotient, remainder) = div_mod_floor(d.clone(), two.clone());
            if remainder == one { break }
            s = s + one;
            d = quotient;
        }
    }

    let mut rng = task_rng();
    for _ in range(0, num_trials) {
        let a = rng.gen_biguint_range(&two, n);
        if try_composite(&a, &d, n, &s) {
            return false
        }
    }
    true

}

fn fermat_is_prime(n : &BigUint) -> bool {
    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    if n == &two {
        true
    } else if n.is_even() {
        false
    } else if mod_exp(&two, &(n-one), n) == one {
        true
    } else {
        false
    }
}

fn is_valid_pow(prime : &BigUint) -> bool {
    for offset in [big(0u), big(4u), big(6u), big(10u), big(12u), big(16u)].iter() {
        if !is_prime(&(*prime + *offset)) {
            return false;
        }
    }
    true
}

// Source: http://rosettacode.org/wiki/Sieve_of_Eratosthenes#Rust
fn simple_sieve(limit: uint) -> ~[uint] {

    #[inline]
    fn int_sqrt(n: uint) -> uint { (n as f64).sqrt() as uint }

    if limit < 2 {
        return ~[];
    }

    let mut primes = Vec::from_elem(limit + 1, true);

    for prime in iter::range_inclusive(2, int_sqrt(limit) + 1) {
        if *primes.get(prime) {
            for multiple in iter::range_step(prime * prime, limit + 1, prime) {
                *primes.get_mut(multiple) = false
            }
        }
    }
    iter::range_inclusive(2, limit).filter(|&n| *primes.get(n)).collect()

}

fn gen_prime(max_val : &BigUint, verbose : bool) -> uint {

    fn candidate_killed_by(candidate : &BigUint, prime : &BigUint) -> bool {
        let zero : BigUint = Zero::zero();
        for &offset in pow_offsets.iter() {
            let o : BigUint = FromPrimitive::from_uint(offset).unwrap();
            if (*candidate + o) % *prime == zero {
                return true;
            }
        }
        false
    }

    fn add_next_prime (max_val : &BigUint, offsets : Vec<BigUint>, prime : BigUint, primorial : BigUint) -> Vec<BigUint> {
        let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
        let mut base : BigUint = Zero::zero();
        let mut new_offsets : Vec<BigUint> = Vec::new();
        let mut counter = zero.clone();
        while counter < prime {
            if base > *max_val {
                break
            }
            for o in offsets.iter() {
                    let val = base + *o;
                    if val > *max_val {
                        break
                    }
                    if !candidate_killed_by(&val, &prime) {
                        new_offsets.push(val);
                    }
            }
            base = base + primorial;
            counter = counter + one;
        }
        return new_offsets
    }
    let primorial_max : uint = 29u;
    let primorial_start : uint = 7u;
    let mut primorial : uint = 210u;  // 2*3*5*7
    let mut offsets : Vec<BigUint> = Vec::from_slice([big(97u)]);
    for i in simple_sieve(primorial_max).iter() {
        if *i <= primorial_start {
            continue
        }
        offsets = add_next_prime(max_val, offsets, big(*i), big(primorial));
        primorial = primorial * *i;
    }
    let mut count : uint = 0;
    for o in offsets.iter() {
        if is_valid_pow(o) {
            count = count + 1;
            if verbose { println!("prime: {}", o) }
        }
    }
    count
}

#[cfg(test)]
mod test_primes {
    use super::{big, gen_prime};

    #[test]
    fn gen_prime_is_correct() {
        let v = gen_prime(&big(1000000000), true);
        println!("{}", v);
        assert!(v == 81u);
    }
}

fn main() {
    println!("{}", gen_prime(&big(1000000000), false));
}<commit_msg>Switch back to Fermat for speed<commit_after>extern crate num;
extern crate rand;
extern crate bignum = "bignum#0.1.1-pre";

use bignum::{BigUint, ToBigUint, RandBigInt};
use num::{div_mod_floor, Integer};
use std::num::{Zero, One, pow, Float, FromPrimitive};
use rand::{task_rng, Rng};
use rand::distributions::range::SampleRange;
use std::vec::Vec;
use std::iter;
use std::clone::Clone;
use std::ops::{Shr, BitAnd};

static pow_offsets : &'static[uint] = &[0u, 4u, 6u, 10u, 12u, 16u];

#[inline]
fn big<T: ToBigUint>(i : T) -> BigUint {
    i.to_biguint().unwrap()
}

// Source: https://gist.github.com/jsanders/8739134#file-generate_big_primes-rs-L35
fn mod_exp<T: Integer + Clone + Shr<uint,T> + BitAnd<T,T>>
    (base: &T, exponent: &T, modulus: &T) -> T {

    let (zero, one): (T, T) = (Zero::zero(), One::one());
    let mut result = one.clone();
    let mut baseAcc = base.clone();
    let mut exponentAcc = exponent.clone();

    while exponentAcc > zero {
        // Accumulate current base if current exponent bit is 1
        if (exponentAcc & one) == one {
            result = result.mul(&baseAcc);
            result = result.rem(modulus);
        }
        // Get next base by squaring
        baseAcc = baseAcc * baseAcc;
        baseAcc = baseAcc % *modulus;

        // Get next bit of exponent
        exponentAcc = exponentAcc.shr(&1);
    }
    result

}

// Rabin-Miller primality test, probabilistic
fn try_composite(a : &BigUint, d : &BigUint, n : &BigUint, s : &BigUint) -> bool {

    let one : BigUint = One::one();
    if mod_exp(a, d, n) == one {
        return false
    }
    let mut i = 0u;
    loop {
        if big(i) == *s {
            break
        }
        if mod_exp(a, &(pow(one+one, i) * *d), n) == *n-one {
            return false
        }
        i += 1;
    }
    true

}
fn rm_is_prime(n : &BigUint) -> bool {

    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    assert!(n >= &two);

    let mut s = zero.clone();
    let mut d = *n-one;
    let num_trials = 5;
    if n == &two {
        return true
    } else if n == &one || n.is_even() {
        return false
    } else {
        loop {
            let (quotient, remainder) = div_mod_floor(d.clone(), two.clone());
            if remainder == one { break }
            s = s + one;
            d = quotient;
        }
    }

    let mut rng = task_rng();
    for _ in range(0, num_trials) {
        let a = rng.gen_biguint_range(&two, n);
        if try_composite(&a, &d, n, &s) {
            return false
        }
    }
    true

}

fn fermat_is_prime(n : &BigUint) -> bool {
    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let two = one + one;

    if n == &two {
        true
    } else if n.is_even() {
        false
    } else if mod_exp(&two, &(n-one), n) == one {
        true
    } else {
        false
    }
}

fn is_valid_pow(prime : &BigUint) -> bool {
    for offset in [big(0u), big(4u), big(6u), big(10u), big(12u), big(16u)].iter() {
        if !fermat_is_prime(&(*prime + *offset)) {
            return false;
        }
    }
    true
}

// Source: http://rosettacode.org/wiki/Sieve_of_Eratosthenes#Rust
fn simple_sieve(limit: uint) -> ~[uint] {

    #[inline]
    fn int_sqrt(n: uint) -> uint { (n as f64).sqrt() as uint }

    if limit < 2 {
        return ~[];
    }

    let mut primes = Vec::from_elem(limit + 1, true);

    for prime in iter::range_inclusive(2, int_sqrt(limit) + 1) {
        if *primes.get(prime) {
            for multiple in iter::range_step(prime * prime, limit + 1, prime) {
                *primes.get_mut(multiple) = false
            }
        }
    }
    iter::range_inclusive(2, limit).filter(|&n| *primes.get(n)).collect()

}

fn gen_prime(max_val : &BigUint, verbose : bool) -> uint {

    fn candidate_killed_by(candidate : &BigUint, prime : &BigUint) -> bool {
        let zero : BigUint = Zero::zero();
        for &offset in pow_offsets.iter() {
            let o : BigUint = FromPrimitive::from_uint(offset).unwrap();
            if (*candidate + o) % *prime == zero {
                return true;
            }
        }
        false
    }

    fn add_next_prime (max_val : &BigUint, offsets : Vec<BigUint>, prime : BigUint, primorial : BigUint) -> Vec<BigUint> {
        let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
        let mut base : BigUint = Zero::zero();
        let mut new_offsets : Vec<BigUint> = Vec::new();
        let mut counter = zero.clone();
        while counter < prime {
            if base > *max_val {
                break
            }
            for o in offsets.iter() {
                    let val = base + *o;
                    if val > *max_val {
                        break
                    }
                    if !candidate_killed_by(&val, &prime) {
                        new_offsets.push(val);
                    }
            }
            base = base + primorial;
            counter = counter + one;
        }
        return new_offsets
    }
    let primorial_max : uint = 29u;
    let primorial_start : uint = 7u;
    let mut primorial : uint = 210u;  // 2*3*5*7
    let mut offsets : Vec<BigUint> = Vec::from_slice([big(97u)]);
    for i in simple_sieve(primorial_max).iter() {
        if *i <= primorial_start {
            continue
        }
        offsets = add_next_prime(max_val, offsets, big(*i), big(primorial));
        primorial = primorial * *i;
    }
    let mut count : uint = 0;
    for o in offsets.iter() {
        if is_valid_pow(o) {
            count = count + 1;
            if verbose { println!("prime: {}", o) }
        }
    }
    count
}

#[cfg(test)]
mod test_primes {
    use super::{big, gen_prime};

    #[test]
    fn gen_prime_is_correct() {
        let v = gen_prime(&big(1000000000), false);
        println!("{}", v);
        assert!(v == 81u);
    }
}

fn main() {
    println!("{}", gen_prime(&big(1000000000000), true));
}<|endoftext|>


<commit_before>// A version of pstree targetting linux written in rust!
//
// This is based on the following exercise from the excellent
// book "The Linux Programming Interface" by Michael Kerridsk.
//
//----------------------------------------------------------------------
//
// Write a program that draws a tree showing the hierarchical
// parent-child relationships of all processes on the system, going all
// the way back to init.  For each process, the program should display
// the process ID and the command being executed.  The output of the
// program should be similar to that produced by pstree(1), although it
// does need not to be as sophisticated.  The parent of each process on
// the system can be found by inspecing the PPid: line of all of the
// /proc/PID/status files on the system.  Be careful to handle the
// possibilty that a process's parent (and thus its /proc/PID directory)
// disappears during the scan of all /proc/PID directories.

// Implementation Notes
// --------------------
// The linux /proc filesystem is a virtual filesystem that provides information
// about processes running on a linux system among other things.  The /proc
// filesystem contains a directory, /proc/<pid>, for each running process in
// the system.
//
// Each process directory has a status file with contents including a bunch
// of different items, notably the process name and its parent process id (ppid).
// And with that information, we can build the process tree.

use std::path::Path;
use std::fs;
use std::io::prelude::*;
use std::fs::File;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;

#[derive(Clone,Debug)]
struct ProcessRecord {
    name: String,
    pid: i32,
    ppid: i32,
}

#[derive(Clone,Debug)]
struct ProcessTreeNode {
    record: ProcessRecord,  // the node owns the associated record
    children: Vec<ProcessTreeNode>, // nodes own their children
}

#[derive(Clone,Debug)]
struct ProcessTree {
    root: ProcessTreeNode, // tree owns ref to root node
}

impl ProcessTreeNode {
    // constructor
    fn new(record : &ProcessRecord) -> ProcessTreeNode {
        ProcessTreeNode { record: (*record).clone(), children: Vec::new() }
    }
}

// Given a status file path, return a hashmap with the following form:
// pid -> ProcessRecord
fn get_process_record(status_path: &Path) -> Option<ProcessRecord> {
    let mut pid : Option<i32> = None;
    let mut ppid : Option<i32> = None;
    let mut name : Option<String> = None;

    let mut reader = std::io::BufReader::new(File::open(status_path).unwrap());
    loop {
        let mut linebuf = String::new();
        match reader.read_line(&mut linebuf) {
            Ok(_) => {
                if linebuf.is_empty() {
                    break;
                }
                let parts : Vec<&str> = linebuf[..].splitn(2, ':').collect();
                if parts.len() == 2 {
                    let key = parts[0].trim();
                    let value = parts[1].trim();
                    match key {
                        "Name" => name = Some(value.to_string()),
                        "Pid" => pid = value.parse().ok(),
                        "PPid" => ppid = value.parse().ok(),
                        _ => (),
                    }
                }
            },
            Err(_) => break,
        }
    }
    return if pid.is_some() && ppid.is_some() && name.is_some() {
        Some(ProcessRecord { name: name.unwrap(), pid: pid.unwrap(), ppid: ppid.unwrap() })
    } else {
        None
    }
}

// build a simple struct (ProcessRecord) for each process
fn get_process_records() -> Vec<ProcessRecord> {
    let proc_directory = Path::new("/proc");

    // find potential process directories under /proc
    let proc_directory_contents = fs::read_dir(&proc_directory).unwrap();
    proc_directory_contents.filter_map(|entry| {
        let entry_path = entry.unwrap().path();
        if fs::metadata(entry_path.as_path()).unwrap().is_dir() {
            let status_path = entry_path.join("status");
            if fs::metadata(status_path.as_path()).unwrap().is_file() {
                return get_process_record(status_path.as_path())
            }
        }
        None
    }).collect()
}

fn populate_node_helper(node: &mut ProcessTreeNode, pid_map: &HashMap<i32, &ProcessRecord>, ppid_map: &HashMap<i32, Vec<i32>>) {
    let pid = node.record.pid; // avoid binding node as immutable in closure
    let child_nodes = &mut node.children;
    match ppid_map.get(&pid) {
        Some(children) => {
            child_nodes.extend(children.iter().map(|child_pid| {
                let record = pid_map[child_pid];
                let mut child = ProcessTreeNode::new(record);
                populate_node_helper(&mut child, pid_map, ppid_map);
                child
            }));
        },
        None => {},
    }
}

fn populate_node(node : &mut ProcessTreeNode, records: &Vec<ProcessRecord>) {
    // O(n): build a mapping of pids to vectors of children.  That is, each
    // key is a pid and its value is a vector of the whose parent pid is the key
    let mut ppid_map : HashMap<i32, Vec<i32>> = HashMap::new();
    let mut pid_map : HashMap<i32, &ProcessRecord> = HashMap::new();
    for record in records.iter() {
        // entry returns either a vacant or occupied entry.  If vacant,
        // we insert a new vector with this records pid.  If occupied,
        // we push this record's pid onto the vec
        pid_map.insert(record.pid, record);
        match ppid_map.entry(record.ppid) {
            Vacant(entry) => { entry.insert(vec![record.pid]); },
            Occupied(mut entry) => { entry.get_mut().push(record.pid); },
        };
    }

    // With the data structures built, it is off to the races
    populate_node_helper(node, &pid_map, &ppid_map);
}

fn build_process_tree() -> ProcessTree {
    let records = get_process_records();
    let mut tree = ProcessTree {
        root : ProcessTreeNode::new(
            &ProcessRecord {
                name: "/".to_string(),
                pid: 0,
                ppid: -1
            })
    };

    // recursively populate all nodes in the tree starting from root (pid 0)
    {
        let root = &mut tree.root;
        populate_node(root, &records);
    }
    tree
}

fn print_node(node : &ProcessTreeNode, indent_level : i32) {
    // print indentation
    for _ in (0..indent_level) {
        print!("  ");
    }
    println!("- {} #{}", node.record.name, node.record.pid);
    for child in node.children.iter() {
        print_node(child, indent_level + 1);  // recurse
    }
}

fn main() {
    let ptree = build_process_tree();
    print_node(&(ptree.root), 0)
}
<commit_msg>fix: don't panic! if potential status path doesn't exist<commit_after>// A version of pstree targetting linux written in rust!
//
// This is based on the following exercise from the excellent
// book "The Linux Programming Interface" by Michael Kerridsk.
//
//----------------------------------------------------------------------
//
// Write a program that draws a tree showing the hierarchical
// parent-child relationships of all processes on the system, going all
// the way back to init.  For each process, the program should display
// the process ID and the command being executed.  The output of the
// program should be similar to that produced by pstree(1), although it
// does need not to be as sophisticated.  The parent of each process on
// the system can be found by inspecing the PPid: line of all of the
// /proc/PID/status files on the system.  Be careful to handle the
// possibilty that a process's parent (and thus its /proc/PID directory)
// disappears during the scan of all /proc/PID directories.

// Implementation Notes
// --------------------
// The linux /proc filesystem is a virtual filesystem that provides information
// about processes running on a linux system among other things.  The /proc
// filesystem contains a directory, /proc/<pid>, for each running process in
// the system.
//
// Each process directory has a status file with contents including a bunch
// of different items, notably the process name and its parent process id (ppid).
// And with that information, we can build the process tree.

use std::path::Path;
use std::fs;
use std::io::prelude::*;
use std::fs::File;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;

#[derive(Clone,Debug)]
struct ProcessRecord {
    name: String,
    pid: i32,
    ppid: i32,
}

#[derive(Clone,Debug)]
struct ProcessTreeNode {
    record: ProcessRecord,  // the node owns the associated record
    children: Vec<ProcessTreeNode>, // nodes own their children
}

#[derive(Clone,Debug)]
struct ProcessTree {
    root: ProcessTreeNode, // tree owns ref to root node
}

impl ProcessTreeNode {
    // constructor
    fn new(record : &ProcessRecord) -> ProcessTreeNode {
        ProcessTreeNode { record: (*record).clone(), children: Vec::new() }
    }
}

// Given a status file path, return a hashmap with the following form:
// pid -> ProcessRecord
fn get_process_record(status_path: &Path) -> Option<ProcessRecord> {
    let mut pid : Option<i32> = None;
    let mut ppid : Option<i32> = None;
    let mut name : Option<String> = None;

    let mut reader = std::io::BufReader::new(File::open(status_path).unwrap());
    loop {
        let mut linebuf = String::new();
        match reader.read_line(&mut linebuf) {
            Ok(_) => {
                if linebuf.is_empty() {
                    break;
                }
                let parts : Vec<&str> = linebuf[..].splitn(2, ':').collect();
                if parts.len() == 2 {
                    let key = parts[0].trim();
                    let value = parts[1].trim();
                    match key {
                        "Name" => name = Some(value.to_string()),
                        "Pid" => pid = value.parse().ok(),
                        "PPid" => ppid = value.parse().ok(),
                        _ => (),
                    }
                }
            },
            Err(_) => break,
        }
    }
    return if pid.is_some() && ppid.is_some() && name.is_some() {
        Some(ProcessRecord { name: name.unwrap(), pid: pid.unwrap(), ppid: ppid.unwrap() })
    } else {
        None
    }
}

// build a simple struct (ProcessRecord) for each process
fn get_process_records() -> Vec<ProcessRecord> {
    let proc_directory = Path::new("/proc");

    // find potential process directories under /proc
    let proc_directory_contents = fs::read_dir(&proc_directory).unwrap();
    proc_directory_contents.filter_map(|entry| {
        let entry_path = entry.unwrap().path();
        if fs::metadata(entry_path.as_path()).unwrap().is_dir() {
            let status_path = entry_path.join("status");
            if let Ok(metadata) = fs::metadata(status_path.as_path()) {
                if metadata.is_file() {
                    return get_process_record(status_path.as_path());
                }
            }
        }
        None
    }).collect()
}

fn populate_node_helper(node: &mut ProcessTreeNode, pid_map: &HashMap<i32, &ProcessRecord>, ppid_map: &HashMap<i32, Vec<i32>>) {
    let pid = node.record.pid; // avoid binding node as immutable in closure
    let child_nodes = &mut node.children;
    match ppid_map.get(&pid) {
        Some(children) => {
            child_nodes.extend(children.iter().map(|child_pid| {
                let record = pid_map[child_pid];
                let mut child = ProcessTreeNode::new(record);
                populate_node_helper(&mut child, pid_map, ppid_map);
                child
            }));
        },
        None => {},
    }
}

fn populate_node(node : &mut ProcessTreeNode, records: &Vec<ProcessRecord>) {
    // O(n): build a mapping of pids to vectors of children.  That is, each
    // key is a pid and its value is a vector of the whose parent pid is the key
    let mut ppid_map : HashMap<i32, Vec<i32>> = HashMap::new();
    let mut pid_map : HashMap<i32, &ProcessRecord> = HashMap::new();
    for record in records.iter() {
        // entry returns either a vacant or occupied entry.  If vacant,
        // we insert a new vector with this records pid.  If occupied,
        // we push this record's pid onto the vec
        pid_map.insert(record.pid, record);
        match ppid_map.entry(record.ppid) {
            Vacant(entry) => { entry.insert(vec![record.pid]); },
            Occupied(mut entry) => { entry.get_mut().push(record.pid); },
        };
    }

    // With the data structures built, it is off to the races
    populate_node_helper(node, &pid_map, &ppid_map);
}

fn build_process_tree() -> ProcessTree {
    let records = get_process_records();
    let mut tree = ProcessTree {
        root : ProcessTreeNode::new(
            &ProcessRecord {
                name: "/".to_string(),
                pid: 0,
                ppid: -1
            })
    };

    // recursively populate all nodes in the tree starting from root (pid 0)
    {
        let root = &mut tree.root;
        populate_node(root, &records);
    }
    tree
}

fn print_node(node : &ProcessTreeNode, indent_level : i32) {
    // print indentation
    for _ in (0..indent_level) {
        print!("  ");
    }
    println!("- {} #{}", node.record.name, node.record.pid);
    for child in node.children.iter() {
        print_node(child, indent_level + 1);  // recurse
    }
}

fn main() {
    let ptree = build_process_tree();
    print_node(&(ptree.root), 0)
}
<|endoftext|>


<commit_before>use syn;
use quote;

pub fn generate_index_struct(ast: &syn::MacroInput) -> quote::Tokens {
    let ident = &ast.ident;
    let index_ident = syn::Ident::from(format!("{}Index", ident).to_string());
    let pipes_ident = syn::Ident::from(format!("{}Pipes", ident).to_string());

    let variant_data = if let syn::Body::Struct(ref variant_data) = ast.body {
        variant_data
    } else {
        panic!("derive(PerlinDocument) only implemented for Structs!");
    };

    let ext_id = external_id_field(ast);
    let external_id_param = external_id_param(ast);
    let add_external_id = add_external_id(ast);
    let create_external_ids = create_external_ids(ast);
    let pipeline_setters = set_pipelines(variant_data.fields(), ident);
    let run_query = run_query(ast);
    let field_matches = field_matches(variant_data.fields());
    let frequent_terms = frequent_terms(variant_data.fields());
    let create_sorted_fields = create_sorted_fields(variant_data.fields());
    let sorted_fields_param = sorted_fields_param(variant_data.fields());
    let construct_sorted_fields = construct_sorted_fields(variant_data.fields());
    quote!(
        pub struct #index_ident {
            pub documents: #ident,
            pipelines: #pipes_ident,
            pub query_pipeline: Option<QueryPipeline<#ident>>,
            doc_counter: DocId,
            #(#sorted_fields_param)*
            #ext_id
        }

        impl #index_ident {
            pub fn create(base_path: PathBuf) -> Self {
                #index_ident {
                    documents: #ident::create(&base_path),
                    pipelines: #pipes_ident::default(),
                    query_pipeline: None,
                    doc_counter: DocId::none(),
                    #(#create_sorted_fields)*
                    #create_external_ids
                }
            }

            pub fn commit(&mut self) {
                self.documents.commit();

                #(#construct_sorted_fields)*
            }

            pub fn add_document(&mut self, key_values: &[(Cow<str>, Cow<str>)] #external_id_param) {
                self.doc_counter.inc();
                let doc_id = self.doc_counter;

                for &(ref key, ref value) in key_values {
                    match key.as_ref() {
                        //"field_name" =>
                        //self.pipelines.field_name(doc_id, &mut self.documents, value);
                        #(#field_matches,)*
                        _ => {
                           // panic!("#ident not found!")
                        }
                    }
                }
                #add_external_id
            }

            pub fn set_query_pipeline(&mut self, pipe: QueryPipeline<#ident>) {
                self.query_pipeline = Some(pipe);
            }

            #run_query

            //Pipeline setter
            //fn set_field_pipeline(&mut self, pipe: Pipeline<Type, Ident>)
            #(#pipeline_setters)*

            //Frequent terms
            //fn frequent_terms_field(&self) ->
            //Box<Iterator<Item = (usize, &TTerm, PostingIterator)>>
            #(#frequent_terms)*
        }
    )
}

fn run_query(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(ext_id_type) = get_external_id_type(&ast.attrs) {
        quote!{
            pub fn run_query<'a>(&'a self, query: Query<'a>) ->
                QueryResultIterator<'a, #ext_id_type> {
                use perlin_core::index::posting::Posting;
                if let Some(ref query_pipe) = self.query_pipeline {
                    QueryResultIterator::new(query_pipe(&self.documents, query), &self.external_ids)
                } else {
                    panic!("Query Pipe not set!");
                }
            }
        }
    } else {
        quote!{
            pub fn run_query<'a>(&'a self, query: Query<'a>) -> Operand<'a> {
                if let Some(ref query_pipe) = self.query_pipeline {
                    query_pipe(&self.documents, query)
                } else {
                    panic!("Query Pipe not set!");
                }
            }
        }
    }
}

/// Generates typed setters for indexing pipelines
/// Runs over all fields of the derived struct and implements a setter for
/// each of them
/// Ignores fields with a #[no_pipe]-Attribute
fn set_pipelines(fields: &[syn::Field], ident: &syn::Ident) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if field.attrs.iter().any(|attr| attr.name() == "no_pipe") {
            continue;
        }
        let field_ident = &field.ident;
        let fn_ident = syn::Ident::from(format!("set_{}_pipeline", field_ident.clone().unwrap())
                                            .to_string());
        let ty = get_generics_from_field(&field.ty);
        result.push(quote!{
            pub fn #fn_ident(&mut self, pipe: Pipeline<#ty, #ident>) {
                self.pipelines.#field_ident = Some(pipe);
            }
        });
    }

    result
}

/// Generates the frequent_terms method for all fields with a `filter`
/// attribute!
fn frequent_terms(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }
        let field_ident = &field.ident;
        let fn_ident = syn::Ident::from(format!("frequent_terms_{}", field_ident.clone().unwrap())
                                            .to_string());
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap())
                                                .to_string());
        let ty = get_generics_from_field(&field.ty);

        result.push(quote!{
            pub fn #fn_ident<'a>(&'a self) ->
                Box<Iterator<Item = (usize, &#ty, PostingIterator)> + 'a> {
                Box::new(self.#sorted_ident.iter().map(move |&(ref df, ref t, ref term_id)| {
                    (*df, t, self.documents.#field_ident.query_term(term_id))
                }))
            }
        });
    }
    result
}

fn get_generics_from_field(field: &syn::Ty) -> quote::Tokens {
    if let &syn::Ty::Path(_, ref path) = field {
        for segment in &path.segments {
            if segment.ident == "Field" {
                if let syn::PathParameters::AngleBracketed(ref params) = segment.parameters {
                    let params = &params.types.first();
                    return quote!(#params);
                }
            }
        }
    }
    panic!("NO FIELD FOUND!");
}

fn field_matches(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        let ident = &field.ident;
        result.push(quote!{
                stringify!(#ident) => {
                    if let Some(ref pipeline) = self.pipelines.#ident {
                        pipeline(doc_id, &mut self.documents, value.as_ref());
                    } else {
                        //panic!("Tried to index field #ident without initialized pipeline!")
                    }
                }
            });
    }
    result
}

fn create_external_ids(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(_) = get_external_id_type(&ast.attrs) {
        quote!{
            external_ids: Vec::new()
        }
    } else {
        quote!()
    }
}

// For struct creation
fn create_sorted_fields(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }

        let field_ident = &field.ident;
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap()).to_string());

        result.push(quote!{
            #sorted_ident: Vec::new(),
        })

    }
    result
}

// For use inside of the commit function
fn construct_sorted_fields(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }
        let field_ident = &field.ident;
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap())
                                                .to_string());
        result.push(quote!{
            let mut #sorted_ident = self.documents.#field_ident.iterate_terms().map(|(t, term_id)| {
                (self.documents.#field_ident.term_df(term_id), t.clone(), *term_id)
            }).collect::<Vec<_>>();

            #sorted_ident.sort_by(|a, b| a.0.cmp(&b.0).reverse());
            self.#sorted_ident = #sorted_ident;
        });
    }
    result
}

// For Struct definition
fn sorted_fields_param(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }
        let field_ident = &field.ident;
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap())
                                                .to_string());
        let ty = get_generics_from_field(&field.ty);

        result.push(quote!{
            #sorted_ident: Vec<(usize, #ty, TermId)>,
        });
    }
    result
}

fn add_external_id(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(_) = get_external_id_type(&ast.attrs) {
        quote!{
            self.external_ids.push((doc_id, external_id));
        }
    } else {
        quote!()
    }
}

fn external_id_param(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(ext_id) = get_external_id_type(&ast.attrs) {
        quote!(, external_id: #ext_id)
    } else {
        quote!()
    }
}

fn external_id_field(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(ext_id) = get_external_id_type(&ast.attrs) {
        quote!(external_ids: Vec<(DocId, #ext_id)>,)
    } else {
        quote!()
    }
}

fn get_external_id_type(attributes: &[syn::Attribute]) -> Option<syn::NestedMetaItem> {
    for attribute in attributes {
        if attribute.name() == "ExternalId" {
            if let syn::MetaItem::List(_, ref nested_items) = attribute.value {
                return Some(nested_items[0].clone());
            }
        }
    }
    None
}
<commit_msg>return term_ides not posting_iterators in frequent_terms methods<commit_after>use syn;
use quote;

pub fn generate_index_struct(ast: &syn::MacroInput) -> quote::Tokens {
    let ident = &ast.ident;
    let index_ident = syn::Ident::from(format!("{}Index", ident).to_string());
    let pipes_ident = syn::Ident::from(format!("{}Pipes", ident).to_string());

    let variant_data = if let syn::Body::Struct(ref variant_data) = ast.body {
        variant_data
    } else {
        panic!("derive(PerlinDocument) only implemented for Structs!");
    };

    let ext_id = external_id_field(ast);
    let external_id_param = external_id_param(ast);
    let add_external_id = add_external_id(ast);
    let create_external_ids = create_external_ids(ast);
    let pipeline_setters = set_pipelines(variant_data.fields(), ident);
    let run_query = run_query(ast);
    let field_matches = field_matches(variant_data.fields());
    let frequent_terms = frequent_terms(variant_data.fields());
    let create_sorted_fields = create_sorted_fields(variant_data.fields());
    let sorted_fields_param = sorted_fields_param(variant_data.fields());
    let construct_sorted_fields = construct_sorted_fields(variant_data.fields());
    quote!(
        pub struct #index_ident {
            pub documents: #ident,
            pipelines: #pipes_ident,
            pub query_pipeline: Option<QueryPipeline<#ident>>,
            doc_counter: DocId,
            #(#sorted_fields_param)*
            #ext_id
        }

        impl #index_ident {
            pub fn create(base_path: PathBuf) -> Self {
                #index_ident {
                    documents: #ident::create(&base_path),
                    pipelines: #pipes_ident::default(),
                    query_pipeline: None,
                    doc_counter: DocId::none(),
                    #(#create_sorted_fields)*
                    #create_external_ids
                }
            }

            pub fn commit(&mut self) {
                self.documents.commit();

                #(#construct_sorted_fields)*
            }

            pub fn add_document(&mut self, key_values: &[(Cow<str>, Cow<str>)] #external_id_param) {
                self.doc_counter.inc();
                let doc_id = self.doc_counter;

                for &(ref key, ref value) in key_values {
                    match key.as_ref() {
                        //"field_name" =>
                        //self.pipelines.field_name(doc_id, &mut self.documents, value);
                        #(#field_matches,)*
                        _ => {
                           // panic!("#ident not found!")
                        }
                    }
                }
                #add_external_id
            }

            pub fn set_query_pipeline(&mut self, pipe: QueryPipeline<#ident>) {
                self.query_pipeline = Some(pipe);
            }

            #run_query

            //Pipeline setter
            //fn set_field_pipeline(&mut self, pipe: Pipeline<Type, Ident>)
            #(#pipeline_setters)*

            //Frequent terms
            //fn frequent_terms_field(&self) ->
            //Box<Iterator<Item = (usize, &TTerm, PostingIterator)>>
            #(#frequent_terms)*
        }
    )
}

fn run_query(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(ext_id_type) = get_external_id_type(&ast.attrs) {
        quote!{
            pub fn run_query<'a>(&'a self, query: Query<'a>) ->
                QueryResultIterator<'a, #ext_id_type> {
                use perlin_core::index::posting::Posting;
                if let Some(ref query_pipe) = self.query_pipeline {
                    QueryResultIterator::new(query_pipe(&self.documents, query), &self.external_ids)
                } else {
                    panic!("Query Pipe not set!");
                }
            }
        }
    } else {
        quote!{
            pub fn run_query<'a>(&'a self, query: Query<'a>) -> Operand<'a> {
                if let Some(ref query_pipe) = self.query_pipeline {
                    query_pipe(&self.documents, query)
                } else {
                    panic!("Query Pipe not set!");
                }
            }
        }
    }
}

/// Generates typed setters for indexing pipelines
/// Runs over all fields of the derived struct and implements a setter for
/// each of them
/// Ignores fields with a #[no_pipe]-Attribute
fn set_pipelines(fields: &[syn::Field], ident: &syn::Ident) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if field.attrs.iter().any(|attr| attr.name() == "no_pipe") {
            continue;
        }
        let field_ident = &field.ident;
        let fn_ident = syn::Ident::from(format!("set_{}_pipeline", field_ident.clone().unwrap())
                                            .to_string());
        let ty = get_generics_from_field(&field.ty);
        result.push(quote!{
            pub fn #fn_ident(&mut self, pipe: Pipeline<#ty, #ident>) {
                self.pipelines.#field_ident = Some(pipe);
            }
        });
    }

    result
}

/// Generates the frequent_terms method for all fields with a `filter`
/// attribute!
fn frequent_terms(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }
        let field_ident = &field.ident;
        let fn_ident = syn::Ident::from(format!("frequent_terms_{}", field_ident.clone().unwrap())
                                            .to_string());
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap())
                                                .to_string());
        let ty = get_generics_from_field(&field.ty);

        result.push(quote!{
            pub fn #fn_ident<'a>(&'a self) ->
                Box<Iterator<Item = (usize, &#ty, TermId)> + 'a> {
                Box::new(self.#sorted_ident.iter().map(move |&(ref df, ref t, ref term_id)| {
                    (*df, t, *term_id)
                }))
            }
        });
    }
    result
}

fn get_generics_from_field(field: &syn::Ty) -> quote::Tokens {
    if let &syn::Ty::Path(_, ref path) = field {
        for segment in &path.segments {
            if segment.ident == "Field" {
                if let syn::PathParameters::AngleBracketed(ref params) = segment.parameters {
                    let params = &params.types.first();
                    return quote!(#params);
                }
            }
        }
    }
    panic!("NO FIELD FOUND!");
}

fn field_matches(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        let ident = &field.ident;
        result.push(quote!{
                stringify!(#ident) => {
                    if let Some(ref pipeline) = self.pipelines.#ident {
                        pipeline(doc_id, &mut self.documents, value.as_ref());
                    } else {
                        //panic!("Tried to index field #ident without initialized pipeline!")
                    }
                }
            });
    }
    result
}

fn create_external_ids(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(_) = get_external_id_type(&ast.attrs) {
        quote!{
            external_ids: Vec::new()
        }
    } else {
        quote!()
    }
}

// For struct creation
fn create_sorted_fields(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }

        let field_ident = &field.ident;
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap()).to_string());

        result.push(quote!{
            #sorted_ident: Vec::new(),
        })

    }
    result
}

// For use inside of the commit function
fn construct_sorted_fields(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }
        let field_ident = &field.ident;
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap())
                                                .to_string());
        result.push(quote!{
            let mut #sorted_ident = self.documents.#field_ident.iterate_terms().map(|(t, term_id)| {
                (self.documents.#field_ident.term_df(term_id), t.clone(), *term_id)
            }).collect::<Vec<_>>();

            #sorted_ident.sort_by(|a, b| a.0.cmp(&b.0).reverse());
            self.#sorted_ident = #sorted_ident;
        });
    }
    result
}

// For Struct definition
fn sorted_fields_param(fields: &[syn::Field]) -> Vec<quote::Tokens> {
    let mut result = Vec::new();
    for field in fields {
        if !field.attrs.iter().any(|attr| attr.name() == "filter") {
            continue;
        }
        let field_ident = &field.ident;
        let sorted_ident = syn::Ident::from(format!("sorted_{}", field_ident.clone().unwrap())
                                                .to_string());
        let ty = get_generics_from_field(&field.ty);

        result.push(quote!{
            #sorted_ident: Vec<(usize, #ty, TermId)>,
        });
    }
    result
}

fn add_external_id(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(_) = get_external_id_type(&ast.attrs) {
        quote!{
            self.external_ids.push((doc_id, external_id));
        }
    } else {
        quote!()
    }
}

fn external_id_param(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(ext_id) = get_external_id_type(&ast.attrs) {
        quote!(, external_id: #ext_id)
    } else {
        quote!()
    }
}

fn external_id_field(ast: &syn::MacroInput) -> quote::Tokens {
    if let Some(ext_id) = get_external_id_type(&ast.attrs) {
        quote!(external_ids: Vec<(DocId, #ext_id)>,)
    } else {
        quote!()
    }
}

fn get_external_id_type(attributes: &[syn::Attribute]) -> Option<syn::NestedMetaItem> {
    for attribute in attributes {
        if attribute.name() == "ExternalId" {
            if let syn::MetaItem::List(_, ref nested_items) = attribute.value {
                return Some(nested_items[0].clone());
            }
        }
    }
    None
}
<|endoftext|>


<commit_before>//! Useful stuff related to the spaceapi.

/// An ``Optional`` can contain ``Optional::Value<T>`` or ``Optional::Absent``.
/// It is similar to an ``Option``, but ``Optional::Absent`` means it will be
/// omitted when serialized, while ``None`` will be serialized to ``null``.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Optional<T> {
    Value(T),
    Absent,
}

impl<T> Optional<T> {

    /// Moves the value `v` out of the `Optional<T>` if it is `Value(v)`.
    ///
    /// # Panics
    ///
    /// Panics if the self value equals `Absent`.
    ///
    /// # Safety note
    ///
    /// In general, because this function may panic, its use is discouraged.
    /// Instead, prefer to use pattern matching and handle the `Absent`
    /// case explicitly.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let x = Value("air");
    /// assert_eq!(x.unwrap(), "air");
    /// ```
    ///
    /// ```{.should_panic}
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let x: Optional<&str> = Absent;
    /// assert_eq!(x.unwrap(), "air"); // fails
    /// ```
    pub fn unwrap(self) -> T {
        match self {
            Optional::Value(val) => val,
            Optional::Absent => panic!("called `Optional::unwrap()` on a `Absent` value"),
        }
    }

    /// Returns the contained value or computes it from a closure.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let k = 10;
    /// assert_eq!(Value(4).unwrap_or_else(|| 2 * k), 4);
    /// assert_eq!(Absent.unwrap_or_else(|| 2 * k), 20);
    /// ```
    pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
        match self {
            Optional::Value(x) => x,
            Optional::Absent => f()
        }
    }

    /// Applies a function to the contained value or returns a default.  see
    /// [`std::option::Option<T>::map_or`](http://doc.rust-lang.org/std/option/enum.Option.html#method.map_or)
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Optional::Value(v) => f(v),
            Optional::Absent => def,
        }
    }

    /// Converts from `Optional<T>` to `Optional<&mut T>`
    pub fn as_mut<'r>(&'r mut self) -> Optional<&'r mut T> {
        match *self {
            Optional::Value(ref mut x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    /// Converts from `Optional<T>` to `Optional<&T>`
    pub fn as_ref<'r>(&'r self) -> Optional<&'r T> {
        match *self {
            Optional::Value(ref x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    /// Returns `true` if the optional is a `Absent` value
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let x: Optional<u32> = Value(2);
    /// assert_eq!(x.is_absent(), false);
    ///
    /// let x: Optional<u32> = Absent;
    /// assert_eq!(x.is_absent(), true);
    /// ```
    pub fn is_absent(&self) -> bool {
        match *self {
            Optional::Absent => true,
            _ => false
        }
    }

}
<commit_msg>Optional: Add map<commit_after>//! Useful stuff related to the spaceapi.

/// An ``Optional`` can contain ``Optional::Value<T>`` or ``Optional::Absent``.
/// It is similar to an ``Option``, but ``Optional::Absent`` means it will be
/// omitted when serialized, while ``None`` will be serialized to ``null``.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Optional<T> {
    Value(T),
    Absent,
}

impl<T> Optional<T> {

    /// Moves the value `v` out of the `Optional<T>` if it is `Value(v)`.
    ///
    /// # Panics
    ///
    /// Panics if the self value equals `Absent`.
    ///
    /// # Safety note
    ///
    /// In general, because this function may panic, its use is discouraged.
    /// Instead, prefer to use pattern matching and handle the `Absent`
    /// case explicitly.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let x = Value("air");
    /// assert_eq!(x.unwrap(), "air");
    /// ```
    ///
    /// ```{.should_panic}
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let x: Optional<&str> = Absent;
    /// assert_eq!(x.unwrap(), "air"); // fails
    /// ```
    pub fn unwrap(self) -> T {
        match self {
            Optional::Value(val) => val,
            Optional::Absent => panic!("called `Optional::unwrap()` on a `Absent` value"),
        }
    }

    /// Returns the contained value or computes it from a closure.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let k = 10;
    /// assert_eq!(Value(4).unwrap_or_else(|| 2 * k), 4);
    /// assert_eq!(Absent.unwrap_or_else(|| 2 * k), 20);
    /// ```
    pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
        match self {
            Optional::Value(x) => x,
            Optional::Absent => f()
        }
    }

    /// Maps an `Optional<T>` to `Optional<U>` by applying a function to a contained value
    ///
    /// # Examples
    ///
    /// Convert an `Optional<String>` into an `Optional<usize>`, consuming the original:
    ///
    /// ```
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let num_as_str: Optional<String> = Value("10".to_string());
    /// // `Optional::map` takes self *by value*, consuming `num_as_str`
    /// let num_as_int: Optional<usize> = num_as_str.map(|n| n.len());
    /// ```
    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
        match self {
            Optional::Value(x) => Optional::Value(f(x)),
            Optional::Absent => Optional::Absent
        }
    }

    /// Applies a function to the contained value or returns a default.  see
    /// [`std::option::Option<T>::map_or`](http://doc.rust-lang.org/std/option/enum.Option.html#method.map_or)
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Optional::Value(v) => f(v),
            Optional::Absent => def,
        }
    }

    /// Converts from `Optional<T>` to `Optional<&mut T>`
    pub fn as_mut<'r>(&'r mut self) -> Optional<&'r mut T> {
        match *self {
            Optional::Value(ref mut x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    /// Converts from `Optional<T>` to `Optional<&T>`
    pub fn as_ref<'r>(&'r self) -> Optional<&'r T> {
        match *self {
            Optional::Value(ref x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    /// Returns `true` if the optional is a `Absent` value
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::utils::Optional;
    /// # use spaceapi::utils::Optional::{Value,Absent};
    /// let x: Optional<u32> = Value(2);
    /// assert_eq!(x.is_absent(), false);
    ///
    /// let x: Optional<u32> = Absent;
    /// assert_eq!(x.is_absent(), true);
    /// ```
    pub fn is_absent(&self) -> bool {
        match *self {
            Optional::Absent => true,
            _ => false
        }
    }

}
<|endoftext|>


<commit_before>extern crate num;
extern crate rand;

use num::bigint::{BigUint, ToBigUint,RandBigInt};
use num::{mod_floor, div_mod_floor};
use std::num::pow;
use rand::{task_rng, Rng};

use std::os;

fn to_biguint (i : u64) -> BigUint {
    i.to_biguint().unwrap()
}

/* Since we use Miller-Rabin, this function technically finds if a number is
 * *probably* correct.
 */
fn is_prime(n : BigUint) -> bool {
    let zero = to_biguint(0);
    let one = to_biguint(1);
    let two = to_biguint(2);
    let three = to_biguint(3);
    let mut s = zero;
    let mut d = n-one;
    let num_trials = 20;
    if n.eq(&two) || n.eq(&three) {
        return true
    } else if n.eq(&one) || mod_floor(n, two).eq(&zero) {
        return false
    } else {
        while true {
            let (quotient, remainder) = div_mod_floor(d, two);
            if remainder == one { break }
            s = s + one;
            d = quotient;
        }
    }

    fn try_composite(a : BigUint, d : BigUint, n : BigUint, s : BigUint) -> bool {
        let one = to_biguint(1);
        if (mod_floor(pow(a, d), n) == one) { return false }
        for i in range(0, s) {
            if (mod_floor(pow(a, (pow(2,i) * d)), n) == n-one) { return false }
        }
        return true;
    }

    for i in range(0, num_trials) {
        let mut rng = task_rng();
        let a : BigUint = rng.gen_biguint_range(&two, &n);
        if try_composite(a, d, n, s) { return false }
    }
    return true;
}

fn main () {
    let args : ~[~str] = os::args();
    if args.len() < 2 {
        println!("You need to provide a natural number as an input argument.")
    } else {
        match from_str::<BigUint>(args[1]) {
            Some(n) => {
                let p : bool = is_prime(n.clone());
                println!("Is {} is prime? {}", n, if p {"Yes"} else {"No"});
            },
            None => println!(
                "You need to provide a natural number as an input argument.")
        };
    }

}<commit_msg>Fast, correct and sequential Miller-Rabin<commit_after>extern crate num;
extern crate rand;
extern crate bignum = "bignum#0.1.0-pre";

use bignum::{BigUint, ToBigUint,RandBigInt};
use num::{div_mod_floor, Integer};
use std::num::{Zero, One, pow};
use rand::task_rng;

use std::os;

fn to_biguint (i : u64) -> BigUint {
    i.to_biguint().unwrap()
}

// Source: https://gist.github.com/jsanders/8739134#file-generate_big_primes-rs-L35
fn mod_exp(base: &BigUint, exponent: &BigUint, modulus: &BigUint) -> BigUint {
    let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one());
    let mut result = one.clone();
    let mut baseAcc = base.clone();
    let mut exponentAcc = exponent.clone();

    while exponentAcc > zero {
        // Accumulate current base if current exponent bit is 1
        if (exponentAcc & one) == one {
            result = result.mul(&baseAcc);
            result = result.rem(modulus);
        }
        // Get next base by squaring
        baseAcc = baseAcc * baseAcc;
        baseAcc = baseAcc % *modulus;

        // Get next bit of exponent
        exponentAcc = exponentAcc.shr(&1);
    }
    result
}

/* Since we use Miller-Rabin, this function technically finds if a number is
 * *probably* correct.
 */
fn is_prime(n : &BigUint) -> bool {
    let zero : BigUint = Zero::zero();
    let one : BigUint = One::one();
    let two = one + one;
    assert!(n >= &two);
    let mut s = zero.clone();
    let mut d = n-one;
    let num_trials = 5;
    if n == &two {
        return true
    } else if n == &one || n.is_even() {
        return false
    } else {
        loop {
            let (quotient, remainder) = div_mod_floor(d.clone(), two.clone());
            if remainder == one { break }
            s = s + one;
            d = quotient;
        }
    }

    fn try_composite(a : &BigUint, d : &BigUint, n : &BigUint, s : &BigUint) -> bool {
        let one = to_biguint(1);
        let two = to_biguint(2);
        if mod_exp(a, d, n) == one {
            return false
        }
        let mut i : uint = 0;
        loop {
            if &i.to_biguint().unwrap() == s {
                break
            }
            if mod_exp(a, &(pow(two.clone(), i) * *d), n) == n-one {
                return false
            }
            i += 1;
        }
        true
    }

    let mut rng = task_rng();
    for _ in range(0, num_trials) {
        let a = rng.gen_biguint_range(&two, n);
        if try_composite(&a, &d, n, &s) {
            return false
        }
    }
    true
}

fn main () {
    let args : ~[~str] = os::args();
    if args.len() < 2 {
        println!("You need to provide a natural number as an input argument.")
    } else {
        match from_str::<BigUint>(args[1]) {
            Some(n) => {
                let p : bool = is_prime(&n);
                println!("{}", p);
            },
            None => println!(
                "You need to provide a natural number as an input argument.")
        };
    }

}
<|endoftext|>


<commit_before>use Configuration;
use join;
use {scope, Scope};
use spawn;
use std::sync::Arc;
use std::error::Error;
use std::fmt;
use registry::{Registry, WorkerThread};

mod internal;
mod test;
/// # ThreadPool
///
/// The [`ThreadPool`] struct represents a user created [thread-pool]. [`ThreadPool::new()`]
/// takes a [`Configuration`] struct that you can use to specify the number and/or
/// names of threads in the pool. You can then execute functions explicitly within
/// this [`ThreadPool`] using [`ThreadPool::install()`]. By contrast, top level
/// rayon functions (like `join()`)  will execute implicitly within the current thread-pool.
///
///
/// ## Creating a ThreadPool
///
/// ```rust
/// # use rayon_core as rayon;
/// let pool = rayon::ThreadPool::new(rayon::Configuration::new().num_threads(8)).unwrap();
/// ```
///
/// [`install()`][`ThreadPool::install()`] executes a closure in one of the `ThreadPool`'s
/// threads. In addition, any other rayon operations called inside of `install()` will also
/// execute in the context of the `ThreadPool`.
///
/// When the `ThreadPool` is dropped, that's a signal for the threads it manages to terminate,
/// they will complete executing any remaining work that you have spawned, and automatically
/// terminate.
///
///
/// [thread-pool]: https://en.wikipedia.org/wiki/Thread_pool
/// [`ThreadPool`]: struct.ThreadPool.html
/// [`ThreadPool::new()`]: struct.ThreadPool.html#method.new
/// [`Configuration`]: struct.Configuration.html
/// [`ThreadPool::install()`]: struct.ThreadPool.html#method.install
pub struct ThreadPool {
    registry: Arc<Registry>,
}

impl ThreadPool {
    /// Constructs a new thread pool with the given configuration. If
    /// the configuration is not valid, returns a suitable `Err`
    /// result.  See `InitError` for more details.
    pub fn new(configuration: Configuration) -> Result<ThreadPool, Box<Error>> {
        let registry = try!(Registry::new(configuration));
        Ok(ThreadPool { registry: registry })
    }

    /// Returns a handle to the global thread pool. This is the pool
    /// that Rayon will use by default when you perform a `join()` or
    /// `scope()` operation, if no other thread-pool is installed. If
    /// no global thread-pool has yet been started when this function
    /// is called, then the global thread-pool will be created (with
    /// the default configuration). If you wish to configure the
    /// global thread-pool differently, then you can use [the
    /// `rayon::initialize()` function][f] to do so.
    ///
    /// [f]: fn.initialize.html
    #[cfg(rayon_unstable)]
    pub fn global() -> &'static Arc<ThreadPool> {
        lazy_static! {
            static ref DEFAULT_THREAD_POOL: Arc<ThreadPool> =
                Arc::new(ThreadPool { registry: Registry::global() });
        }

        &DEFAULT_THREAD_POOL
    }

    /// Executes `op` within the threadpool. Any attempts to use
    /// `join`, `scope`, or parallel iterators will then operate
    /// within that threadpool.
    ///
    /// # Warning: thread-local data
    ///
    /// Because `op` is executing within the Rayon thread-pool,
    /// thread-local data from the current thread will not be
    /// accessible.
    ///
    /// # Panics
    ///
    /// If `op` should panic, that panic will be propagated.
    ///
    /// ## Using `install()`
    ///
    /// ```rust
    ///    # use rayon_core as rayon;
    ///    fn main() {
    ///         let pool = rayon::ThreadPool::new(rayon::Configuration::new().num_threads(8)).unwrap();
    ///         let n = pool.install(|| fib(20));
    ///         println!("{}", n);
    ///    }
    ///
    ///    fn fib(n: usize) -> usize {
    ///         if n == 0 || n == 1 {
    ///             return n;
    ///         }
    ///         let (a, b) = rayon::join(|| fib(n - 1), || fib(n - 2)); // runs inside of `pool`
    ///         return a + b;
    ///     }
    /// ```
    pub fn install<OP, R>(&self, op: OP) -> R
        where OP: FnOnce() -> R + Send,
              R: Send
    {
        self.registry.in_worker(|_, _| op())
    }

    /// Returns the (current) number of threads in the thread pool.
    ///
    /// ### Future compatibility note
    ///
    /// Note that unless this thread-pool was created with a
    /// configuration that specifies the number of threads, then this
    /// number may vary over time in future versions (see [the
    /// `num_threads()` method for details][snt]).
    ///
    /// [snt]: struct.Configuration.html#method.num_threads
    #[inline]
    pub fn current_num_threads(&self) -> usize {
        self.registry.num_threads()
    }

    /// If called from a Rayon worker thread in this thread-pool,
    /// returns the index of that thread; if not called from a Rayon
    /// thread, or called from a Rayon thread that belongs to a
    /// different thread-pool, returns `None`.
    ///
    /// The index for a given thread will not change over the thread's
    /// lifetime. However, multiple threads may share the same index if
    /// they are in distinct thread-pools.
    ///
    /// ### Future compatibility note
    ///
    /// Currently, every thread-pool (including the global
    /// thread-pool) has a fixed number of threads, but this may
    /// change in future Rayon versions (see [the `num_threads()` method
    /// for details][snt]). In that case, the index for a
    /// thread would not change during its lifetime, but thread
    /// indices may wind up being reused if threads are terminated and
    /// restarted.
    ///
    /// [snt]: struct.Configuration.html#method.num_threads
    #[inline]
    pub fn current_thread_index(&self) -> Option<usize> {
        unsafe {
            let curr = WorkerThread::current();
            if curr.is_null() {
                None
            } else if (*curr).registry().id() != self.registry.id() {
                None
            } else {
                Some((*curr).index())
            }
        }
    }

    /// Returns true if the current worker thread currently has "local
    /// tasks" pending. This can be useful as part of a heuristic for
    /// deciding whether to spawn a new task or execute code on the
    /// current thread, particularly in breadth-first
    /// schedulers. However, keep in mind that this is an inherently
    /// racy check, as other worker threads may be actively "stealing"
    /// tasks from our local deque.
    ///
    /// **Background:** Rayon's uses a [work-stealing] scheduler. The
    /// key idea is that each thread has its own [deque] of
    /// tasks. Whenever a new task is spawned -- whether through
    /// `join()`, `Scope::spawn()`, or some other means -- that new
    /// task is pushed onto the thread's *local* deque. Worker threads
    /// have a preference for executing their own tasks; if however
    /// they run out of tasks, they will go try to "steal" tasks from
    /// other threads. This function therefore has an inherent race
    /// with other active worker threads, which may be removing items
    /// from the local deque.
    ///
    /// [work-stealing]: https://en.wikipedia.org/wiki/Work_stealing
    /// [deque]: https://en.wikipedia.org/wiki/Double-ended_queue
    #[inline]
    pub fn current_thread_has_pending_tasks(&self) -> Option<bool> {
        unsafe {
            let curr = WorkerThread::current();
            if curr.is_null() {
                None
            } else if (*curr).registry().id() != self.registry.id() {
                None
            } else {
                Some(!(*curr).local_deque_is_empty())
            }
        }
    }

    /// Execute `oper_a` and `oper_b` in the thread-pool and return
    /// the results. Equivalent to `self.install(|| join(oper_a,
    /// oper_b))`.
    pub fn join<A, B, RA, RB>(&self, oper_a: A, oper_b: B) -> (RA, RB)
        where A: FnOnce() -> RA + Send,
              B: FnOnce() -> RB + Send,
              RA: Send,
              RB: Send
    {
        self.install(|| join(oper_a, oper_b))
    }

    /// Creates a scope that executes within this thread-pool.
    /// Equivalent to `self.install(|| scope(...))`.
    ///
    /// See also: [the `scope()` function][scope].
    ///
    /// [scope]: fn.scope.html
    pub fn scope<'scope, OP, R>(&self, op: OP) -> R
        where OP: for<'s> FnOnce(&'s Scope<'scope>) -> R + 'scope + Send, R: Send
    {
        self.install(|| scope(op))
    }

    /// Spawns an asynchronous task in this thread-pool. This task will
    /// run in the implicit, global scope, which means that it may outlast
    /// the current stack frame -- therefore, it cannot capture any references
    /// onto the stack (you will likely need a `move` closure).
    ///
    /// See also: [the `spawn()` function defined on scopes][spawn].
    ///
    /// [spawn]: struct.Scope.html#method.spawn
    pub fn spawn<OP>(&self, op: OP)
        where OP: FnOnce() + Send + 'static
    {
        // We assert that `self.registry` has not terminated.
        unsafe { spawn::spawn_in(op, &self.registry) }
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        self.registry.terminate();
    }
}

impl fmt::Debug for ThreadPool {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("ThreadPool")
            .field("num_threads", &self.current_num_threads())
            .field("id", &self.registry.id())
            .finish()
    }
}

/// If called from a Rayon worker thread, returns the index of that
/// thread within its current pool; if not called from a Rayon thread,
/// returns `None`.
///
/// The index for a given thread will not change over the thread's
/// lifetime. However, multiple threads may share the same index if
/// they are in distinct thread-pools.
///
/// See also: [the `ThreadPool::current_thread_index()` method].
///
/// [m]: struct.ThreadPool.html#method.current_thread_index
///
/// ### Future compatibility note
///
/// Currently, every thread-pool (including the global
/// thread-pool) has a fixed number of threads, but this may
/// change in future Rayon versions (see [the `num_threads()` method
/// for details][snt]). In that case, the index for a
/// thread would not change during its lifetime, but thread
/// indices may wind up being reused if threads are terminated and
/// restarted.
///
/// [snt]: struct.Configuration.html#method.num_threads
#[inline]
pub fn current_thread_index() -> Option<usize> {
    unsafe {
        let curr = WorkerThread::current();
        if curr.is_null() {
            None
        } else {
            Some((*curr).index())
        }
    }
}

/// If called from a Rayon worker thread, indicates whether that
/// thread's local deque still has pending tasks. Otherwise, returns
/// `None`. For more information, see [the
/// `ThreadPool::current_thread_has_pending_tasks()` method][m].
///
/// [m]: struct.ThreadPool.html#method.current_thread_has_pending_tasks
#[inline]
pub fn current_thread_has_pending_tasks() -> Option<bool> {
    unsafe {
        let curr = WorkerThread::current();
        if curr.is_null() {
            None
        } else {
            Some(!(*curr).local_deque_is_empty())
        }
    }
}
<commit_msg>document the thread-pool module<commit_after>//! Contains support for user-managed thread pools, represented by the
//! the [`ThreadPool`] type (see that struct for details).
//!
//! [`ThreadPool`]: struct.ThreadPool.html

use Configuration;
use join;
use {scope, Scope};
use spawn;
use std::sync::Arc;
use std::error::Error;
use std::fmt;
use registry::{Registry, WorkerThread};

mod internal;
mod test;

/// # ThreadPool
///
/// The [`ThreadPool`] struct represents a user created [thread-pool]. [`ThreadPool::new()`]
/// takes a [`Configuration`] struct that you can use to specify the number and/or
/// names of threads in the pool. You can then execute functions explicitly within
/// this [`ThreadPool`] using [`ThreadPool::install()`]. By contrast, top level
/// rayon functions (like `join()`)  will execute implicitly within the current thread-pool.
///
///
/// ## Creating a ThreadPool
///
/// ```rust
/// # use rayon_core as rayon;
/// let pool = rayon::ThreadPool::new(rayon::Configuration::new().num_threads(8)).unwrap();
/// ```
///
/// [`install()`][`ThreadPool::install()`] executes a closure in one of the `ThreadPool`'s
/// threads. In addition, any other rayon operations called inside of `install()` will also
/// execute in the context of the `ThreadPool`.
///
/// When the `ThreadPool` is dropped, that's a signal for the threads it manages to terminate,
/// they will complete executing any remaining work that you have spawned, and automatically
/// terminate.
///
///
/// [thread-pool]: https://en.wikipedia.org/wiki/Thread_pool
/// [`ThreadPool`]: struct.ThreadPool.html
/// [`ThreadPool::new()`]: struct.ThreadPool.html#method.new
/// [`Configuration`]: struct.Configuration.html
/// [`ThreadPool::install()`]: struct.ThreadPool.html#method.install
pub struct ThreadPool {
    registry: Arc<Registry>,
}

impl ThreadPool {
    /// Constructs a new thread pool with the given configuration. If
    /// the configuration is not valid, returns a suitable `Err`
    /// result.  See `InitError` for more details.
    pub fn new(configuration: Configuration) -> Result<ThreadPool, Box<Error>> {
        let registry = try!(Registry::new(configuration));
        Ok(ThreadPool { registry: registry })
    }

    /// Returns a handle to the global thread pool. This is the pool
    /// that Rayon will use by default when you perform a `join()` or
    /// `scope()` operation, if no other thread-pool is installed. If
    /// no global thread-pool has yet been started when this function
    /// is called, then the global thread-pool will be created (with
    /// the default configuration). If you wish to configure the
    /// global thread-pool differently, then you can use [the
    /// `rayon::initialize()` function][f] to do so.
    ///
    /// [f]: fn.initialize.html
    #[cfg(rayon_unstable)]
    pub fn global() -> &'static Arc<ThreadPool> {
        lazy_static! {
            static ref DEFAULT_THREAD_POOL: Arc<ThreadPool> =
                Arc::new(ThreadPool { registry: Registry::global() });
        }

        &DEFAULT_THREAD_POOL
    }

    /// Executes `op` within the threadpool. Any attempts to use
    /// `join`, `scope`, or parallel iterators will then operate
    /// within that threadpool.
    ///
    /// # Warning: thread-local data
    ///
    /// Because `op` is executing within the Rayon thread-pool,
    /// thread-local data from the current thread will not be
    /// accessible.
    ///
    /// # Panics
    ///
    /// If `op` should panic, that panic will be propagated.
    ///
    /// ## Using `install()`
    ///
    /// ```rust
    ///    # use rayon_core as rayon;
    ///    fn main() {
    ///         let pool = rayon::ThreadPool::new(rayon::Configuration::new().num_threads(8)).unwrap();
    ///         let n = pool.install(|| fib(20));
    ///         println!("{}", n);
    ///    }
    ///
    ///    fn fib(n: usize) -> usize {
    ///         if n == 0 || n == 1 {
    ///             return n;
    ///         }
    ///         let (a, b) = rayon::join(|| fib(n - 1), || fib(n - 2)); // runs inside of `pool`
    ///         return a + b;
    ///     }
    /// ```
    pub fn install<OP, R>(&self, op: OP) -> R
        where OP: FnOnce() -> R + Send,
              R: Send
    {
        self.registry.in_worker(|_, _| op())
    }

    /// Returns the (current) number of threads in the thread pool.
    ///
    /// ### Future compatibility note
    ///
    /// Note that unless this thread-pool was created with a
    /// configuration that specifies the number of threads, then this
    /// number may vary over time in future versions (see [the
    /// `num_threads()` method for details][snt]).
    ///
    /// [snt]: struct.Configuration.html#method.num_threads
    #[inline]
    pub fn current_num_threads(&self) -> usize {
        self.registry.num_threads()
    }

    /// If called from a Rayon worker thread in this thread-pool,
    /// returns the index of that thread; if not called from a Rayon
    /// thread, or called from a Rayon thread that belongs to a
    /// different thread-pool, returns `None`.
    ///
    /// The index for a given thread will not change over the thread's
    /// lifetime. However, multiple threads may share the same index if
    /// they are in distinct thread-pools.
    ///
    /// ### Future compatibility note
    ///
    /// Currently, every thread-pool (including the global
    /// thread-pool) has a fixed number of threads, but this may
    /// change in future Rayon versions (see [the `num_threads()` method
    /// for details][snt]). In that case, the index for a
    /// thread would not change during its lifetime, but thread
    /// indices may wind up being reused if threads are terminated and
    /// restarted.
    ///
    /// [snt]: struct.Configuration.html#method.num_threads
    #[inline]
    pub fn current_thread_index(&self) -> Option<usize> {
        unsafe {
            let curr = WorkerThread::current();
            if curr.is_null() {
                None
            } else if (*curr).registry().id() != self.registry.id() {
                None
            } else {
                Some((*curr).index())
            }
        }
    }

    /// Returns true if the current worker thread currently has "local
    /// tasks" pending. This can be useful as part of a heuristic for
    /// deciding whether to spawn a new task or execute code on the
    /// current thread, particularly in breadth-first
    /// schedulers. However, keep in mind that this is an inherently
    /// racy check, as other worker threads may be actively "stealing"
    /// tasks from our local deque.
    ///
    /// **Background:** Rayon's uses a [work-stealing] scheduler. The
    /// key idea is that each thread has its own [deque] of
    /// tasks. Whenever a new task is spawned -- whether through
    /// `join()`, `Scope::spawn()`, or some other means -- that new
    /// task is pushed onto the thread's *local* deque. Worker threads
    /// have a preference for executing their own tasks; if however
    /// they run out of tasks, they will go try to "steal" tasks from
    /// other threads. This function therefore has an inherent race
    /// with other active worker threads, which may be removing items
    /// from the local deque.
    ///
    /// [work-stealing]: https://en.wikipedia.org/wiki/Work_stealing
    /// [deque]: https://en.wikipedia.org/wiki/Double-ended_queue
    #[inline]
    pub fn current_thread_has_pending_tasks(&self) -> Option<bool> {
        unsafe {
            let curr = WorkerThread::current();
            if curr.is_null() {
                None
            } else if (*curr).registry().id() != self.registry.id() {
                None
            } else {
                Some(!(*curr).local_deque_is_empty())
            }
        }
    }

    /// Execute `oper_a` and `oper_b` in the thread-pool and return
    /// the results. Equivalent to `self.install(|| join(oper_a,
    /// oper_b))`.
    pub fn join<A, B, RA, RB>(&self, oper_a: A, oper_b: B) -> (RA, RB)
        where A: FnOnce() -> RA + Send,
              B: FnOnce() -> RB + Send,
              RA: Send,
              RB: Send
    {
        self.install(|| join(oper_a, oper_b))
    }

    /// Creates a scope that executes within this thread-pool.
    /// Equivalent to `self.install(|| scope(...))`.
    ///
    /// See also: [the `scope()` function][scope].
    ///
    /// [scope]: fn.scope.html
    pub fn scope<'scope, OP, R>(&self, op: OP) -> R
        where OP: for<'s> FnOnce(&'s Scope<'scope>) -> R + 'scope + Send, R: Send
    {
        self.install(|| scope(op))
    }

    /// Spawns an asynchronous task in this thread-pool. This task will
    /// run in the implicit, global scope, which means that it may outlast
    /// the current stack frame -- therefore, it cannot capture any references
    /// onto the stack (you will likely need a `move` closure).
    ///
    /// See also: [the `spawn()` function defined on scopes][spawn].
    ///
    /// [spawn]: struct.Scope.html#method.spawn
    pub fn spawn<OP>(&self, op: OP)
        where OP: FnOnce() + Send + 'static
    {
        // We assert that `self.registry` has not terminated.
        unsafe { spawn::spawn_in(op, &self.registry) }
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        self.registry.terminate();
    }
}

impl fmt::Debug for ThreadPool {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("ThreadPool")
            .field("num_threads", &self.current_num_threads())
            .field("id", &self.registry.id())
            .finish()
    }
}

/// If called from a Rayon worker thread, returns the index of that
/// thread within its current pool; if not called from a Rayon thread,
/// returns `None`.
///
/// The index for a given thread will not change over the thread's
/// lifetime. However, multiple threads may share the same index if
/// they are in distinct thread-pools.
///
/// See also: [the `ThreadPool::current_thread_index()` method].
///
/// [m]: struct.ThreadPool.html#method.current_thread_index
///
/// ### Future compatibility note
///
/// Currently, every thread-pool (including the global
/// thread-pool) has a fixed number of threads, but this may
/// change in future Rayon versions (see [the `num_threads()` method
/// for details][snt]). In that case, the index for a
/// thread would not change during its lifetime, but thread
/// indices may wind up being reused if threads are terminated and
/// restarted.
///
/// [snt]: struct.Configuration.html#method.num_threads
#[inline]
pub fn current_thread_index() -> Option<usize> {
    unsafe {
        let curr = WorkerThread::current();
        if curr.is_null() {
            None
        } else {
            Some((*curr).index())
        }
    }
}

/// If called from a Rayon worker thread, indicates whether that
/// thread's local deque still has pending tasks. Otherwise, returns
/// `None`. For more information, see [the
/// `ThreadPool::current_thread_has_pending_tasks()` method][m].
///
/// [m]: struct.ThreadPool.html#method.current_thread_has_pending_tasks
#[inline]
pub fn current_thread_has_pending_tasks() -> Option<bool> {
    unsafe {
        let curr = WorkerThread::current();
        if curr.is_null() {
            None
        } else {
            Some(!(*curr).local_deque_is_empty())
        }
    }
}
<|endoftext|>


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

#![feature(core, plugin, test)]
#![plugin(regex_macros)]

extern crate regex;
extern crate test;

macro_rules! searcher_expr { ($e:expr) => ($e) }

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

#![feature(pattern, plugin, test)]
#![plugin(regex_macros)]

extern crate regex;
extern crate test;

macro_rules! searcher_expr { ($e:expr) => ($e) }

mod tests;
mod native_static;
<|endoftext|>


<commit_before>use super::Policy;

use utils::argmaxima;

extern crate rand;
use rand::Rng;

pub struct Greedy;

impl Policy for Greedy {
    fn sample(&mut self, qs: &[f64]) -> usize {
        let maxima = argmaxima(qs).1;

        if maxima.len() == 1 {
            maxima[0]
        } else {
            *rand::thread_rng().choose(&maxima).unwrap()
        }
    }

    fn probabilities(&mut self, qs: &[f64]) -> Vec<f64> {
        let mut ps = vec![0.0; qs.len()];

        let maxima = argmaxima(qs).1;

        let p = 1.0 / maxima.len() as f64;
        for i in maxima {
            ps[i] = p;
        }

        ps
    }
}

#[cfg(test)]
mod tests {
    use super::{Policy, Greedy};

    #[test]
    #[should_panic]
    fn test_0d() {
        Greedy.sample(&vec![]);
    }

    #[test]
    fn test_1d() {
        let mut g = Greedy;

        let mut v = vec![1.0];
        assert!(g.sample(&v) == 0);

        v = vec![-100.0];
        assert!(g.sample(&v) == 0);
    }

    #[test]
    fn test_two_positive() {
        let mut g = Greedy;

        let mut v = vec![10.0, 1.0];
        assert!(g.sample(&v) == 0);

        v = vec![1.0, 10.0];
        assert!(g.sample(&v) == 1);
    }

    #[test]
    fn test_two_negative() {
        let mut g = Greedy;

        let mut v = vec![-10.0, -1.0];
        assert!(g.sample(&v) == 1);

        v = vec![-1.0, -10.0];
        assert!(g.sample(&v) == 0);
    }

    #[test]
    fn test_two_alt() {
        let mut g = Greedy;

        let mut v = vec![10.0, -1.0];
        assert!(g.sample(&v) == 0);

        v = vec![-10.0, 1.0];
        assert!(g.sample(&v) == 1);

        v = vec![1.0, -10.0];
        assert!(g.sample(&v) == 0);

        v = vec![-1.0, 10.0];
        assert!(g.sample(&v) == 1);
    }

    #[test]
    fn test_long() {
        let mut g = Greedy;

        let v = vec![-123.1, 123.1, 250.5, -1240.0, -4500.0, 10000.0, 20.1];
        assert!(g.sample(&v) == 5);
    }

    #[test]
    fn test_precision() {
        let mut g = Greedy;

        let v = vec![1e-7, 2e-7];
        assert!(g.sample(&v) == 1);
    }

    #[test]
    fn test_probabilites() {
        let mut g = Greedy;

        assert_eq!(g.probabilities(&[1e-7, 2e-7, 3e-7, 4e-7]),
                   vec![0.0, 0.0, 0.0, 1.0]);

        assert_eq!(g.probabilities(&[1e-7, 1e-7, 1e-7, 1e-7]),
                   vec![0.25, 0.25, 0.25, 0.25]);
    }
}
<commit_msg>chore: improve error handling in `Greedy`<commit_after>use super::Policy;

use utils::argmaxima;

extern crate rand;
use rand::Rng;

pub struct Greedy;

impl Policy for Greedy {
    fn sample(&mut self, qs: &[f64]) -> usize {
        let maxima = argmaxima(qs).1;

        if maxima.len() == 1 {
            maxima[0]
        } else {
            *rand::thread_rng()
                .choose(&maxima)
                .expect("no valid actions to choose from in `Greedy::sample(qs)`")
        }
    }

    fn probabilities(&mut self, qs: &[f64]) -> Vec<f64> {
        let mut ps = vec![0.0; qs.len()];

        let maxima = argmaxima(qs).1;

        let p = 1.0 / maxima.len() as f64;
        for i in maxima {
            ps[i] = p;
        }

        ps
    }
}

#[cfg(test)]
mod tests {
    use super::{Policy, Greedy};

    #[test]
    #[should_panic]
    fn test_0d() {
        Greedy.sample(&vec![]);
    }

    #[test]
    fn test_1d() {
        let mut g = Greedy;

        let mut v = vec![1.0];
        assert!(g.sample(&v) == 0);

        v = vec![-100.0];
        assert!(g.sample(&v) == 0);
    }

    #[test]
    fn test_two_positive() {
        let mut g = Greedy;

        let mut v = vec![10.0, 1.0];
        assert!(g.sample(&v) == 0);

        v = vec![1.0, 10.0];
        assert!(g.sample(&v) == 1);
    }

    #[test]
    fn test_two_negative() {
        let mut g = Greedy;

        let mut v = vec![-10.0, -1.0];
        assert!(g.sample(&v) == 1);

        v = vec![-1.0, -10.0];
        assert!(g.sample(&v) == 0);
    }

    #[test]
    fn test_two_alt() {
        let mut g = Greedy;

        let mut v = vec![10.0, -1.0];
        assert!(g.sample(&v) == 0);

        v = vec![-10.0, 1.0];
        assert!(g.sample(&v) == 1);

        v = vec![1.0, -10.0];
        assert!(g.sample(&v) == 0);

        v = vec![-1.0, 10.0];
        assert!(g.sample(&v) == 1);
    }

    #[test]
    fn test_long() {
        let mut g = Greedy;

        let v = vec![-123.1, 123.1, 250.5, -1240.0, -4500.0, 10000.0, 20.1];
        assert!(g.sample(&v) == 5);
    }

    #[test]
    fn test_precision() {
        let mut g = Greedy;

        let v = vec![1e-7, 2e-7];
        assert!(g.sample(&v) == 1);
    }

    #[test]
    fn test_probabilites() {
        let mut g = Greedy;

        assert_eq!(g.probabilities(&[1e-7, 2e-7, 3e-7, 4e-7]),
                   vec![0.0, 0.0, 0.0, 1.0]);

        assert_eq!(g.probabilities(&[1e-7, 1e-7, 1e-7, 1e-7]),
                   vec![0.25, 0.25, 0.25, 0.25]);
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Proper_divisors
use std::num::Float;

// Populate input vector with prime numbers < maxvalue
fn add_more_prime_numbers(v:&mut Vec<usize>,maxvalue:usize) {
    let mut prime:usize=v[v.len()-1];
    if prime <= 2 {prime=1;} // start with odd number
    loop {
        prime+=2;
        if prime >= maxvalue {break;}
        let mut isprime=true;
        let ceiling = (prime as f64).sqrt() as usize;
        // check below sqrt(prime)
        for i in v.iter().skip(1).take_while(|&i| *i <= ceiling) {
            if prime % *i == 0 {
                isprime=false;
                break;
            }
        }
        if isprime {
                v.push(prime);
        }
    }
}

// Get proper divisors
fn find_divisors(primes:&mut Vec<usize>, num:usize) -> Vec<usize> {
    assert!(num > 0);
    let mut kprime_factors=vec![1];
    let ceiling = ((num as f64).sqrt()  as usize) + 1;
    add_more_prime_numbers(primes,ceiling);
    // Filter all primes num % p == 0
    let prime_factors:Vec<usize> =
                            primes.iter()
                            .filter(|&p| num % *p == 0)
                            .map(|&n| n)
                            .collect();
    // Check all k*p p..ceiling
    // Following code is ineffective (due to duplicates) but simple
    for p in prime_factors {
        let mut kp=p;
        while kp < ceiling {
            if num % kp == 0 {
                kprime_factors.push(kp);
                kprime_factors.push(num/kp)}
            kp += p;
        }
    }
    kprime_factors.sort();
    kprime_factors.dedup();
    return kprime_factors;
}

#[allow(dead_code)]
fn proper_divisors(num:usize) -> Vec<usize> {
    let mut primes:Vec<usize>=vec![2,3];
    return find_divisors(&mut primes,num);
}

fn main() {
    let mut primes:Vec<usize>=vec![2,3]; // reusable prime number array

    // Show the proper divisors of the numbers 1 to 10 inclusive.
    for i in 1..11 {
        print!("{}: ", i);
        println!("{:?}", find_divisors(&mut primes,i));
    }

    //Find a number in the range 1 to 20,000
    //with the most proper divisors.
    let mut max_divs:(usize, Vec<usize>)=(0,Vec::new());
    for n in (1..20001) {
        let div_q = find_divisors(&mut primes,n).len();
        if div_q > max_divs.0 {
            max_divs.0 = div_q;
            max_divs.1.clear();
            max_divs.1.push(n);
        } else if div_q == max_divs.0 {
            max_divs.1.push(n);
        }
    }
    println!("Most divisors a number within 1 to 20000 has: {}",  max_divs.0);
    print!("Numbers with {} divisors: ", max_divs.0);
    println!("{:?}", max_divs.1);
}

#[test]
fn test_divisors() {
    assert!(proper_divisors(6) == vec!(1,2,3));
    assert!(proper_divisors(100) == vec!(1,2,4,5,10,20,25,50));
}
<commit_msg>Update proper_divisors.rs<commit_after>use std::num::Float;

// Populate input vector with prime numbers < maxvalue
fn add_more_prime_numbers(v:&mut Vec<usize>,maxvalue:usize) {
    let mut prime:usize=v[v.len()-1];
    if prime <= 2 {prime=1;} // start with odd number
    loop {
        prime+=2;
        if prime >= maxvalue {break;}
        let mut isprime=true;
        let ceiling = (prime as f64).sqrt() as usize;
        // check below sqrt(prime)
        for i in v.iter().skip(1).take_while(|&i| *i <= ceiling) {
            if prime % *i == 0 {
                isprime=false;
                break;
            }
        }
        if isprime {
                v.push(prime);
        }
    }
}

// Get proper divisors
fn find_divisors(primes:&mut Vec<usize>, num:usize) -> Vec<usize> {
    assert!(num > 0);
    if num == 1 {return Vec::new()}
    let mut kprime_factors=vec![1];
    let ceiling = ((num as f64).sqrt()  as usize) + 1;
    add_more_prime_numbers(primes,ceiling);
    // Filter all primes num % p == 0
    let prime_factors:Vec<usize> =
                            primes.iter()
                            .filter(|&p| num % *p == 0)
                            .map(|&n| n)
                            .collect();
    // Check all k*p p..ceiling
    // Following code is ineffective (due to duplicates) but simple
    for p in prime_factors {
        let mut kp=p;
        while kp < ceiling {
            if num % kp == 0 {
                kprime_factors.push(kp);
                kprime_factors.push(num/kp)}
            kp += p;
        }
    }
    kprime_factors.sort();
    kprime_factors.dedup();
    return kprime_factors;
}

#[allow(dead_code)]
fn proper_divisors(num:usize) -> Vec<usize> {
    let mut primes:Vec<usize>=vec![2,3];
    return find_divisors(&mut primes,num);
}

fn main() {
    let mut primes:Vec<usize>=vec![2,3]; // reusable prime number array

    // Show the proper divisors of the numbers 1 to 10 inclusive.
    for i in 1..11 {
        print!("{}: ", i);
        println!("{:?}", find_divisors(&mut primes,i));
    }

    //Find a number in the range 1 to 20,000
    //with the most proper divisors.
    let mut max_divs:(usize, Vec<usize>)=(0,Vec::new());
    for n in (1..20001) {
        let div_q = find_divisors(&mut primes,n).len();
        if div_q > max_divs.0 {
            max_divs.0 = div_q;
            max_divs.1.clear();
            max_divs.1.push(n);
        } else if div_q == max_divs.0 {
            max_divs.1.push(n);
        }
    }
    println!("Most divisors a number within 1 to 20000 has: {}",  max_divs.0);
    print!("Numbers with {} divisors: ", max_divs.0);
    println!("{:?}", max_divs.1);
}

#[test]
fn test_divisors() {
    assert!(proper_divisors(6) == vec!(1,2,3));
    assert!(proper_divisors(100) == vec!(1,2,4,5,10,20,25,50));
}
<|endoftext|>