<commit_before>use ndarray::*;
use ndarray_linalg::*;

#[test]
fn solve_random() {
    let a: Array2<f64> = random((3, 3));
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn solve_random_t() {
    let a: Array2<f64> = random((3, 3).f());
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn rcond() {
    macro_rules! rcond {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a: Array2<$elem> = random_hpd($rows);
            let rcond = 1. / (a.opnorm_one().unwrap() * a.inv().unwrap().opnorm_one().unwrap());
            assert_aclose!(a.rcond().unwrap(), rcond, $atol);
            assert_aclose!(a.rcond_into().unwrap(), rcond, $atol);
        };
    }
    for rows in 1..6 {
        rcond!(f64, rows, 0.2);
        rcond!(f32, rows, 0.5);
        rcond!(c64, rows, 0.2);
        rcond!(c32, rows, 0.5);
    }
}

#[test]
fn rcond_hilbert() {
    macro_rules! rcond_hilbert {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::from_shape_fn(($rows, $rows), |(i, j)| {
                1. / (i as $elem + j as $elem - 1.)
            });
            assert_aclose!(a.rcond().unwrap(), 0., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 0., $atol);
        };
    }
    rcond_hilbert!(f64, 10, 1e-9);
    rcond_hilbert!(f32, 10, 1e-3);
}

#[test]
fn rcond_identity() {
    macro_rules! rcond_identity {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::eye($rows);
            assert_aclose!(a.rcond().unwrap(), 1., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 1., $atol);
        };
    }
    for rows in 1..6 {
        rcond_identity!(f64, rows, 1e-9);
        rcond_identity!(f32, rows, 1e-3);
        rcond_identity!(c64, rows, 1e-9);
        rcond_identity!(c32, rows, 1e-3);
    }
}
<commit_msg>To confirm #213 resolved #228<commit_after>use ndarray::*;
use ndarray_linalg::*;

#[test]
fn solve_random() {
    let a: Array2<f64> = random((3, 3));
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn solve_random_t() {
    let a: Array2<f64> = random((3, 3).f());
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn solve_factorized() {
    let a: Array2<f64> = random((3, 3));
    let ans: Array1<f64> = random(3);
    let b = a.dot(&ans);
    let f = a.factorize_into().unwrap();
    let x = f.solve_into(b).unwrap();
    assert_close_l2!(&x, &ans, 1e-7);
}

#[test]
fn solve_factorized_t() {
    let a: Array2<f64> = random((3, 3).f());
    let ans: Array1<f64> = random(3);
    let b = a.dot(&ans);
    let f = a.factorize_into().unwrap();
    let x = f.solve_into(b).unwrap();
    assert_close_l2!(&x, &ans, 1e-7);
}

#[test]
fn rcond() {
    macro_rules! rcond {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a: Array2<$elem> = random_hpd($rows);
            let rcond = 1. / (a.opnorm_one().unwrap() * a.inv().unwrap().opnorm_one().unwrap());
            assert_aclose!(a.rcond().unwrap(), rcond, $atol);
            assert_aclose!(a.rcond_into().unwrap(), rcond, $atol);
        };
    }
    for rows in 1..6 {
        rcond!(f64, rows, 0.2);
        rcond!(f32, rows, 0.5);
        rcond!(c64, rows, 0.2);
        rcond!(c32, rows, 0.5);
    }
}

#[test]
fn rcond_hilbert() {
    macro_rules! rcond_hilbert {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::from_shape_fn(($rows, $rows), |(i, j)| {
                1. / (i as $elem + j as $elem - 1.)
            });
            assert_aclose!(a.rcond().unwrap(), 0., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 0., $atol);
        };
    }
    rcond_hilbert!(f64, 10, 1e-9);
    rcond_hilbert!(f32, 10, 1e-3);
}

#[test]
fn rcond_identity() {
    macro_rules! rcond_identity {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::eye($rows);
            assert_aclose!(a.rcond().unwrap(), 1., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 1., $atol);
        };
    }
    for rows in 1..6 {
        rcond_identity!(f64, rows, 1e-9);
        rcond_identity!(f32, rows, 1e-3);
        rcond_identity!(c64, rows, 1e-9);
        rcond_identity!(c32, rows, 1e-3);
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/100_doors
// this is the unoptimized version that performs all 100
// passes, as per the original description of the problem
use std::iter::range_inclusive;

#[cfg(not(test))]
fn main() {
    // states for the 100 doors
    // uses a vector of booleans,
    // where state==false means the door is closed
    let mut doors = [false, ..100];
    solve(&mut doors);

    for (idx, door) in doors.iter().enumerate() {
        println!("door {} open: {}", idx+1, door);
    }

}

// unoptimized solution for the 100 Doors problem,
// performs all 100 passes and mutates the vector with
// the states in place
fn solve(doors: &mut [bool, ..100])  {
    for pass in range_inclusive(1u, 100u) {
        for door in range_inclusive(1u, 100u) {
            if (door % pass) == 0 {
                // flip the state of the door
                doors[door-1] = !(doors[door-1])
            }
        }
     }
}

#[test]
fn solution() {
    let mut doors = [false, ..100];
    solve(&mut doors);

    // test that the doors with index corresponding to
    // a perfect square are now open
    for i in range_inclusive(1u,10u) {
        assert!(doors[i*i - 1]);
    }
}
<commit_msg>use range step inclusive for 100_doors_unoptimized<commit_after>// Implements http://rosettacode.org/wiki/100_doors
// this is the unoptimized version that performs all 100
// passes, as per the original description of the problem
use std::iter::range_inclusive;
use std::iter::range_step_inclusive;

#[cfg(not(test))]
fn main() {
    // states for the 100 doors
    // uses a vector of booleans,
    // where state==false means the door is closed
    let mut doors = [false, ..100];
    solve(&mut doors);

    for (idx, door) in doors.iter().enumerate() {
        println!("door {} open: {}", idx+1, door);
    }

}

// unoptimized solution for the 100 Doors problem,
// performs all 100 passes and mutates the vector with
// the states in place
fn solve(doors: &mut [bool, ..100])  {
    for pass in range_inclusive(1u, 100u) {
        for door in range_step_inclusive(pass, 100u, pass) {
            // flip the state of the door
            doors[door-1] = !doors[door-1]
        }
     }
}

#[test]
fn solution() {
    let mut doors = [false, ..100];
    solve(&mut doors);

    // test that the doors with index corresponding to
    // a perfect square are now open
    for i in range_inclusive(1u,10u) {
        assert!(doors[i*i - 1]);
    }
}
<|endoftext|>


<commit_before>use std::thread::sleep_ms;
use std::io::{Read, Write, Result, BufRead, BufReader, BufWriter};
use std::fs::File;

use std::net::{TcpListener, TcpStream};
use std::mem::size_of;

use std::sync::mpsc::{Sender, Receiver, channel};

use std::thread;
use std::sync::Arc;
use std::mem;

use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};

use communication::communicator::{Binary, Process};
use drain::DrainExt;

// TODO : Much of this only relates to BinaryWriter/BinaryReader based communication, not networking.
// TODO : Could be moved somewhere less networking-specific.

#[derive(Copy, Clone)]
pub struct MessageHeader {
    pub graph:      u64,   // graph identifier
    pub channel:    u64,   // index of channel
    pub source:     u64,   // index of worker sending message
    pub target:     u64,   // index of worker receiving message
    pub length:     u64,   // number of bytes in message
}

impl MessageHeader {
    // returns a header when there is enough supporting data
    fn try_read(bytes: &mut &[u8]) -> Option<MessageHeader> {
        if bytes.len() > size_of::<MessageHeader>() {
            // capture original in case we need to rewind
            let original = *bytes;

            // unclear what order struct initializers run in, so ...
            let graph = bytes.read_u64::<LittleEndian>().unwrap();
            let channel = bytes.read_u64::<LittleEndian>().unwrap();
            let source = bytes.read_u64::<LittleEndian>().unwrap();
            let target = bytes.read_u64::<LittleEndian>().unwrap();
            let length = bytes.read_u64::<LittleEndian>().unwrap();

            if bytes.len() >= length as usize {
                Some(MessageHeader {
                    graph: graph,
                    channel: channel,
                    source: source,
                    target: target,
                    length: length,
                })
            }
            else {
                // rewind the reader
                *bytes = original;
                None
            }
        }
        else { None }
    }

    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
        try!(writer.write_u64::<LittleEndian>(self.graph));
        try!(writer.write_u64::<LittleEndian>(self.channel));
        try!(writer.write_u64::<LittleEndian>(self.source));
        try!(writer.write_u64::<LittleEndian>(self.target));
        try!(writer.write_u64::<LittleEndian>(self.length));
        Ok(())
    }
}

// // structure in charge of receiving data from a Reader, for example the network
// struct BinaryReceiver<R: Read> {
//     reader:     R,          // the generic reader
//     buffer:     Vec<u8>,    // current working buffer
//     double:     Vec<u8>,    // second working buffer
//     staging:    Vec<u8>,    // 1 << 20 of buffer to read into
//     targets:    Switchboard<(Sender<Vec<u8>>, Receiver<Vec<u8>>)>,
// }
//
// impl<R: Read> BinaryReceiver<R> {
//     fn new(reader: R, channels: Receiver<((u64, u64, u64), (Sender<Vec<u8>>, Receiver<Vec<u8>>))>) -> BinaryReceiver<R> {
//         BinaryReceiver {
//             reader:     reader,
//             buffer:     Vec::new(),
//             double:     Vec::new(),
//             staging:    vec![0u8; 1 << 20],
//             targets:    Switchboard::new(channels),
//         }
//     }
//
//     fn recv_loop(&mut self) {
//         loop {
//
//             // attempt to read some more bytes into our buffer
//             // TODO : We read in to self.staging because extending a Vec<u8> is hard without
//             // TODO : using set_len, which is unsafe.
//             // TODO : Could consider optimizing for the self.buffer.len() == 0 case, swapping
//             // TODO : self.staging with self.buffer, rather than using write_all.
//             let read = self.reader.read(&mut self.staging[..]).unwrap_or(0);
//             self.buffer.write_all(&self.staging[..read]).unwrap(); // <-- shouldn't fail
//
//             {
//                 // get a view of available bytes
//                 let mut slice = &self.buffer[..];
//
//                 while let Some(header) = MessageHeader::try_read(&mut slice) {
//
//                     let h_len = header.length as usize;  // length in bytes
//                     let target = self.targets.ensure(header.target, header.graph, header.channel);
//                     let mut buffer = target.1.try_recv().unwrap_or(Vec::new());
//
//                     buffer.clear();
//                     buffer.write_all(&slice[..h_len]).unwrap();
//                     slice = &slice[h_len..];
//
//                     target.0.send(buffer).unwrap();
//                 }
//
//                 // TODO: way inefficient... =/ Fix! :D
//                 // if slice.len() < self.buffer.len() {
//                     self.double.clear();
//                     self.double.write_all(slice).unwrap();
//                 // }
//             }
//
//             // if self.double.len() > 0 {
//                 mem::swap(&mut self.buffer, &mut self.double);
//                 // self.double.clear();
//             // }
//         }
//     }
// }

// structure in charge of receiving data from a Reader, for example the network
struct BinaryReceiver<R: Read> {
    reader:     R,          // the generic reader
    buffer:     Vec<u8>,    // current working buffer
    length:     usize,
    targets:    Switchboard<(Sender<Vec<u8>>, Receiver<Vec<u8>>)>,
}

impl<R: Read> BinaryReceiver<R> {
    fn new(reader: R, channels: Receiver<((u64, u64, u64), (Sender<Vec<u8>>, Receiver<Vec<u8>>))>) -> BinaryReceiver<R> {
        BinaryReceiver {
            reader:     reader,
            buffer:     vec![0u8; 1 << 20],
            length:     0,
            targets:    Switchboard::new(channels),
        }
    }

    fn recv_loop(&mut self) {
        loop {

            // if we've mostly filled our buffer and still can't read a whole message from it,
            // we'll need more space / to read more at once. let's double the buffer!
            if self.length >= self.buffer.len() / 2 {
                self.buffer.extend(::std::iter::repeat(0u8).take(self.length));
            }

            // attempt to read some more bytes into our buffer
            let read = self.reader.read(&mut self.buffer[self.length..]).unwrap_or(0);
            self.length += read;

            let remaining = {
                let mut slice = &self.buffer[..self.length];
                while let Some(header) = MessageHeader::try_read(&mut slice) {
                    let h_len = header.length as usize;  // length in bytes
                    let target = &mut self.targets.ensure(header.target, header.graph, header.channel).0;
                    target.send(slice[..h_len].to_vec()).unwrap();
                    slice = &slice[h_len..];
                }

                slice.len()
            };

            // we consumed bytes, must shift to beginning.
            // this should optimize to copy_overlapping;
            // would just do that if it weren't unsafe =/
            if remaining < self.length {
                for index in 0..remaining {
                    self.buffer[index] = self.buffer[index + self.length - remaining];
                }
                self.length = remaining;
            }
        }
    }
}

// structure in charge of sending data to a Writer, for example the network
struct BinarySender<W: Write> {
    id:         u64,    // destination process
    writer:     W,
    sources:    Receiver<(MessageHeader, Vec<u8>)>,
    returns:    Switchboard<Sender<Vec<u8>>>,
}

impl<W: Write> BinarySender<W> {
    fn new(id: u64,
           writer: W,
           sources: Receiver<(MessageHeader, Vec<u8>)>,
           channels: Receiver<((u64, u64, u64), Sender<Vec<u8>>)>) -> BinarySender<W> {
        BinarySender {
            id:         id,
            writer:     writer,
            sources:    sources,
            returns: Switchboard::new(channels),
        }
    }

    fn send_loop(&mut self) {
        let mut stash = Vec::new();

        // block until data to recv
        while let Ok((header, buffer)) = self.sources.recv() {

            stash.push((header, buffer));

            // collect any additional outstanding data to send
            while let Ok((header, buffer)) = self.sources.try_recv() {
                stash.push((header, buffer));
            }

            // println!("send loop to process {}:\tstarting", self.id);
            for (mut header, mut buffer) in stash.drain_temp() {
                header.length = buffer.len() as u64;    // <-- is this really our job? O.o
                header.write_to(&mut self.writer).unwrap();
                self.writer.write_all(&buffer[..]).unwrap();
                buffer.clear();

                // self.returns.ensure(header.source, header.graph, header.channel).send(buffer).unwrap();
            }

            self.writer.flush().unwrap();    // <-- because writer is buffered
        }
    }
}

struct Switchboard<T:Send> {
    source: Receiver<((u64, u64, u64), T)>,
    buffer: Vec<Vec<Vec<Option<T>>>>,
}

impl<T:Send> Switchboard<T> {
    pub fn new(source: Receiver<((u64, u64, u64), T)>) -> Switchboard<T> {
        Switchboard {
            source: source,
            buffer: Vec::new(),
        }
    }

    pub fn ensure(&mut self, a: u64, b: u64, c: u64) -> &mut T {
        let a = a as usize;
        let b = b as usize;
        let c = c as usize;

        while self.buffer.len() <= a { self.buffer.push(Vec::new()); }
        while self.buffer[a].len() <= b { self.buffer[a].push(Vec::new()); }
        while self.buffer[a][b].len() <= c { self.buffer[a][b].push(None); }

        while let None = self.buffer[a][b][c] {
            let ((x, y, z), s) = self.source.recv().unwrap();

            let x = x as usize;
            let y = y as usize;
            let z = z as usize;

            while self.buffer.len() <= x { self.buffer.push(Vec::new()); }
            while self.buffer[x].len() <= y { self.buffer[x].push(Vec::new()); }
            while self.buffer[x][y].len() <= z { self.buffer[x][y].push(None); }
            self.buffer[x][y][z] = Some(s);
        }

        // we've just ensured that this is not None
        self.buffer[a][b][c].as_mut().unwrap()
    }
}

pub fn initialize_networking_from_file(filename: &str, my_index: u64, workers: u64) -> Result<Vec<Binary>> {

    let reader = BufReader::new(try!(File::open(filename)));
    let mut addresses = Vec::new();

    for line in reader.lines() {
        addresses.push(try!(line));
    }

    initialize_networking(addresses, my_index, workers)
}

pub fn initialize_networking(addresses: Vec<String>, my_index: u64, workers: u64) -> Result<Vec<Binary>> {

    let processes = addresses.len() as u64;
    let hosts1 = Arc::new(addresses);
    let hosts2 = hosts1.clone();

    let start_task = thread::spawn(move || start_connections(hosts1, my_index));
    let await_task = thread::spawn(move || await_connections(hosts2, my_index));

    let mut results = try!(start_task.join().unwrap());

    results.push(None);
    let mut to_extend = try!(await_task.join().unwrap());
    results.extend(to_extend.drain_temp());

    println!("worker {}:\tinitialization complete", my_index);

    let mut writers = Vec::new();   // handles to the BinarySenders (to present new channels)
    let mut readers = Vec::new();   // handles to the BinaryReceivers (to present new channels)
    let mut senders = Vec::new();   // destinations for serialized data (to send serialized data)

    // for each process, if a stream exists (i.e. not local) ...
    for index in (0..results.len()) {
        if let Some(stream) = results[index].take() {

            let (writer_channels_s, writer_channels_r) = channel();
            let (reader_channels_s, reader_channels_r) = channel();
            let (sender_channels_s, sender_channels_r) = channel();

            writers.push(writer_channels_s);    //
            readers.push(reader_channels_s);    //
            senders.push(sender_channels_s);    //

            let mut sender = BinarySender::new(index as u64,
                                               BufWriter::with_capacity(1 << 20, stream.try_clone().unwrap()),
                                               sender_channels_r,
                                               writer_channels_r);
            let mut recver = BinaryReceiver::new(stream.try_clone().unwrap(), reader_channels_r);

            // start senders and receivers associated with this stream
            thread::Builder::new().name(format!("send thread {}", index))
                                  .spawn(move || sender.send_loop())
                                  .unwrap();
            thread::Builder::new().name(format!("recv thread {}", index))
                                  .spawn(move || recver.recv_loop())
                                  .unwrap();

        }
    }

    let proc_comms = Process::new_vector(workers);

    let mut results = Vec::new();
    for (index, proc_comm) in proc_comms.into_iter().enumerate() {
        results.push(Binary {
            inner:          proc_comm,
            index:          my_index * workers + index as u64,
            peers:          workers * processes,
            graph:          0,          // TODO : Fix this
            allocated:      0,
            writers:        writers.clone(),
            readers:        readers.clone(),
            senders:        senders.clone(),
        });
    }

    return Ok(results);
}

// result contains connections [0, my_index - 1].
fn start_connections(addresses: Arc<Vec<String>>, my_index: u64) -> Result<Vec<Option<TcpStream>>> {
    let mut results: Vec<_> = (0..my_index).map(|_| None).collect();
    for index in (0..my_index) {
        let mut connected = false;
        while !connected {
            match TcpStream::connect(&addresses[index as usize][..]) {
                Ok(mut stream) => {
                    try!(stream.write_u64::<LittleEndian>(my_index));
                    results[index as usize] = Some(stream);
                    println!("worker {}:\tconnection to worker {}", my_index, index);
                    connected = true;
                },
                Err(error) => {
                    println!("worker {}:\terror connecting to worker {}: {}; retrying", my_index, index, error);
                    sleep_ms(1000);
                },
            }
        }
    }

    return Ok(results);
}

// result contains connections [my_index + 1, addresses.len() - 1].
fn await_connections(addresses: Arc<Vec<String>>, my_index: u64) -> Result<Vec<Option<TcpStream>>> {
    let mut results: Vec<_> = (0..(addresses.len() - my_index as usize - 1)).map(|_| None).collect();
    let listener = try!(TcpListener::bind(&addresses[my_index as usize][..]));

    for _ in (my_index as usize + 1 .. addresses.len()) {
        let mut stream = try!(listener.accept()).0;
        let identifier = try!(stream.read_u64::<LittleEndian>()) as usize;
        results[identifier - my_index as usize - 1] = Some(stream);
        println!("worker {}:\tconnection from worker {}", my_index, identifier);
    }

    return Ok(results);
}
<commit_msg>tidied up use statements<commit_after>use std::io::{Read, Write, Result, BufRead, BufReader, BufWriter};
use std::fs::File;
use std::net::{TcpListener, TcpStream};
use std::mem::size_of;
use std::sync::Arc;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::thread;
use std::thread::sleep_ms;

use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};

use communication::communicator::{Binary, Process};
use drain::DrainExt;

// TODO : Much of this only relates to BinaryWriter/BinaryReader based communication, not networking.
// TODO : Could be moved somewhere less networking-specific.

#[derive(Copy, Clone)]
pub struct MessageHeader {
    pub graph:      u64,   // graph identifier
    pub channel:    u64,   // index of channel
    pub source:     u64,   // index of worker sending message
    pub target:     u64,   // index of worker receiving message
    pub length:     u64,   // number of bytes in message
}

impl MessageHeader {
    // returns a header when there is enough supporting data
    fn try_read(bytes: &mut &[u8]) -> Option<MessageHeader> {
        if bytes.len() > size_of::<MessageHeader>() {
            // capture original in case we need to rewind
            let original = *bytes;

            // unclear what order struct initializers run in, so ...
            let graph = bytes.read_u64::<LittleEndian>().unwrap();
            let channel = bytes.read_u64::<LittleEndian>().unwrap();
            let source = bytes.read_u64::<LittleEndian>().unwrap();
            let target = bytes.read_u64::<LittleEndian>().unwrap();
            let length = bytes.read_u64::<LittleEndian>().unwrap();

            if bytes.len() >= length as usize {
                Some(MessageHeader {
                    graph: graph,
                    channel: channel,
                    source: source,
                    target: target,
                    length: length,
                })
            }
            else {
                // rewind the reader
                *bytes = original;
                None
            }
        }
        else { None }
    }

    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
        try!(writer.write_u64::<LittleEndian>(self.graph));
        try!(writer.write_u64::<LittleEndian>(self.channel));
        try!(writer.write_u64::<LittleEndian>(self.source));
        try!(writer.write_u64::<LittleEndian>(self.target));
        try!(writer.write_u64::<LittleEndian>(self.length));
        Ok(())
    }
}

// // structure in charge of receiving data from a Reader, for example the network
// struct BinaryReceiver<R: Read> {
//     reader:     R,          // the generic reader
//     buffer:     Vec<u8>,    // current working buffer
//     double:     Vec<u8>,    // second working buffer
//     staging:    Vec<u8>,    // 1 << 20 of buffer to read into
//     targets:    Switchboard<(Sender<Vec<u8>>, Receiver<Vec<u8>>)>,
// }
//
// impl<R: Read> BinaryReceiver<R> {
//     fn new(reader: R, channels: Receiver<((u64, u64, u64), (Sender<Vec<u8>>, Receiver<Vec<u8>>))>) -> BinaryReceiver<R> {
//         BinaryReceiver {
//             reader:     reader,
//             buffer:     Vec::new(),
//             double:     Vec::new(),
//             staging:    vec![0u8; 1 << 20],
//             targets:    Switchboard::new(channels),
//         }
//     }
//
//     fn recv_loop(&mut self) {
//         loop {
//
//             // attempt to read some more bytes into our buffer
//             // TODO : We read in to self.staging because extending a Vec<u8> is hard without
//             // TODO : using set_len, which is unsafe.
//             // TODO : Could consider optimizing for the self.buffer.len() == 0 case, swapping
//             // TODO : self.staging with self.buffer, rather than using write_all.
//             let read = self.reader.read(&mut self.staging[..]).unwrap_or(0);
//             self.buffer.write_all(&self.staging[..read]).unwrap(); // <-- shouldn't fail
//
//             {
//                 // get a view of available bytes
//                 let mut slice = &self.buffer[..];
//
//                 while let Some(header) = MessageHeader::try_read(&mut slice) {
//
//                     let h_len = header.length as usize;  // length in bytes
//                     let target = self.targets.ensure(header.target, header.graph, header.channel);
//                     let mut buffer = target.1.try_recv().unwrap_or(Vec::new());
//
//                     buffer.clear();
//                     buffer.write_all(&slice[..h_len]).unwrap();
//                     slice = &slice[h_len..];
//
//                     target.0.send(buffer).unwrap();
//                 }
//
//                 // TODO: way inefficient... =/ Fix! :D
//                 // if slice.len() < self.buffer.len() {
//                     self.double.clear();
//                     self.double.write_all(slice).unwrap();
//                 // }
//             }
//
//             // if self.double.len() > 0 {
//                 mem::swap(&mut self.buffer, &mut self.double);
//                 // self.double.clear();
//             // }
//         }
//     }
// }

// structure in charge of receiving data from a Reader, for example the network
struct BinaryReceiver<R: Read> {
    reader:     R,          // the generic reader
    buffer:     Vec<u8>,    // current working buffer
    length:     usize,
    targets:    Switchboard<(Sender<Vec<u8>>, Receiver<Vec<u8>>)>,
}

impl<R: Read> BinaryReceiver<R> {
    fn new(reader: R, channels: Receiver<((u64, u64, u64), (Sender<Vec<u8>>, Receiver<Vec<u8>>))>) -> BinaryReceiver<R> {
        BinaryReceiver {
            reader:     reader,
            buffer:     vec![0u8; 1 << 20],
            length:     0,
            targets:    Switchboard::new(channels),
        }
    }

    fn recv_loop(&mut self) {
        loop {

            // if we've mostly filled our buffer and still can't read a whole message from it,
            // we'll need more space / to read more at once. let's double the buffer!
            if self.length >= self.buffer.len() / 2 {
                self.buffer.extend(::std::iter::repeat(0u8).take(self.length));
            }

            // attempt to read some more bytes into our buffer
            let read = self.reader.read(&mut self.buffer[self.length..]).unwrap_or(0);
            self.length += read;

            let remaining = {
                let mut slice = &self.buffer[..self.length];
                while let Some(header) = MessageHeader::try_read(&mut slice) {
                    let h_len = header.length as usize;  // length in bytes
                    let target = &mut self.targets.ensure(header.target, header.graph, header.channel).0;
                    target.send(slice[..h_len].to_vec()).unwrap();
                    slice = &slice[h_len..];
                }

                slice.len()
            };

            // we consumed bytes, must shift to beginning.
            // this should optimize to copy_overlapping;
            // would just do that if it weren't unsafe =/
            if remaining < self.length {
                for index in 0..remaining {
                    self.buffer[index] = self.buffer[index + self.length - remaining];
                }
                self.length = remaining;
            }
        }
    }
}

// structure in charge of sending data to a Writer, for example the network
struct BinarySender<W: Write> {
    id:         u64,    // destination process
    writer:     W,
    sources:    Receiver<(MessageHeader, Vec<u8>)>,
    returns:    Switchboard<Sender<Vec<u8>>>,
}

impl<W: Write> BinarySender<W> {
    fn new(id: u64,
           writer: W,
           sources: Receiver<(MessageHeader, Vec<u8>)>,
           channels: Receiver<((u64, u64, u64), Sender<Vec<u8>>)>) -> BinarySender<W> {
        BinarySender {
            id:         id,
            writer:     writer,
            sources:    sources,
            returns: Switchboard::new(channels),
        }
    }

    fn send_loop(&mut self) {
        let mut stash = Vec::new();

        // block until data to recv
        while let Ok((header, buffer)) = self.sources.recv() {

            stash.push((header, buffer));

            // collect any additional outstanding data to send
            while let Ok((header, buffer)) = self.sources.try_recv() {
                stash.push((header, buffer));
            }

            // println!("send loop to process {}:\tstarting", self.id);
            for (mut header, mut buffer) in stash.drain_temp() {
                header.length = buffer.len() as u64;    // <-- is this really our job? O.o
                header.write_to(&mut self.writer).unwrap();
                self.writer.write_all(&buffer[..]).unwrap();
                buffer.clear();

                // self.returns.ensure(header.source, header.graph, header.channel).send(buffer).unwrap();
            }

            self.writer.flush().unwrap();    // <-- because writer is buffered
        }
    }
}

struct Switchboard<T:Send> {
    source: Receiver<((u64, u64, u64), T)>,
    buffer: Vec<Vec<Vec<Option<T>>>>,
}

impl<T:Send> Switchboard<T> {
    pub fn new(source: Receiver<((u64, u64, u64), T)>) -> Switchboard<T> {
        Switchboard {
            source: source,
            buffer: Vec::new(),
        }
    }

    pub fn ensure(&mut self, a: u64, b: u64, c: u64) -> &mut T {
        let a = a as usize;
        let b = b as usize;
        let c = c as usize;

        while self.buffer.len() <= a { self.buffer.push(Vec::new()); }
        while self.buffer[a].len() <= b { self.buffer[a].push(Vec::new()); }
        while self.buffer[a][b].len() <= c { self.buffer[a][b].push(None); }

        while let None = self.buffer[a][b][c] {
            let ((x, y, z), s) = self.source.recv().unwrap();

            let x = x as usize;
            let y = y as usize;
            let z = z as usize;

            while self.buffer.len() <= x { self.buffer.push(Vec::new()); }
            while self.buffer[x].len() <= y { self.buffer[x].push(Vec::new()); }
            while self.buffer[x][y].len() <= z { self.buffer[x][y].push(None); }
            self.buffer[x][y][z] = Some(s);
        }

        // we've just ensured that this is not None
        self.buffer[a][b][c].as_mut().unwrap()
    }
}

pub fn initialize_networking_from_file(filename: &str, my_index: u64, workers: u64) -> Result<Vec<Binary>> {

    let reader = BufReader::new(try!(File::open(filename)));
    let mut addresses = Vec::new();

    for line in reader.lines() {
        addresses.push(try!(line));
    }

    initialize_networking(addresses, my_index, workers)
}

pub fn initialize_networking(addresses: Vec<String>, my_index: u64, workers: u64) -> Result<Vec<Binary>> {

    let processes = addresses.len() as u64;
    let hosts1 = Arc::new(addresses);
    let hosts2 = hosts1.clone();

    let start_task = thread::spawn(move || start_connections(hosts1, my_index));
    let await_task = thread::spawn(move || await_connections(hosts2, my_index));

    let mut results = try!(start_task.join().unwrap());

    results.push(None);
    let mut to_extend = try!(await_task.join().unwrap());
    results.extend(to_extend.drain_temp());

    println!("worker {}:\tinitialization complete", my_index);

    let mut writers = Vec::new();   // handles to the BinarySenders (to present new channels)
    let mut readers = Vec::new();   // handles to the BinaryReceivers (to present new channels)
    let mut senders = Vec::new();   // destinations for serialized data (to send serialized data)

    // for each process, if a stream exists (i.e. not local) ...
    for index in (0..results.len()) {
        if let Some(stream) = results[index].take() {

            let (writer_channels_s, writer_channels_r) = channel();
            let (reader_channels_s, reader_channels_r) = channel();
            let (sender_channels_s, sender_channels_r) = channel();

            writers.push(writer_channels_s);    //
            readers.push(reader_channels_s);    //
            senders.push(sender_channels_s);    //

            let mut sender = BinarySender::new(index as u64,
                                               BufWriter::with_capacity(1 << 20, stream.try_clone().unwrap()),
                                               sender_channels_r,
                                               writer_channels_r);
            let mut recver = BinaryReceiver::new(stream.try_clone().unwrap(), reader_channels_r);

            // start senders and receivers associated with this stream
            thread::Builder::new().name(format!("send thread {}", index))
                                  .spawn(move || sender.send_loop())
                                  .unwrap();
            thread::Builder::new().name(format!("recv thread {}", index))
                                  .spawn(move || recver.recv_loop())
                                  .unwrap();

        }
    }

    let proc_comms = Process::new_vector(workers);

    let mut results = Vec::new();
    for (index, proc_comm) in proc_comms.into_iter().enumerate() {
        results.push(Binary {
            inner:          proc_comm,
            index:          my_index * workers + index as u64,
            peers:          workers * processes,
            graph:          0,          // TODO : Fix this
            allocated:      0,
            writers:        writers.clone(),
            readers:        readers.clone(),
            senders:        senders.clone(),
        });
    }

    return Ok(results);
}

// result contains connections [0, my_index - 1].
fn start_connections(addresses: Arc<Vec<String>>, my_index: u64) -> Result<Vec<Option<TcpStream>>> {
    let mut results: Vec<_> = (0..my_index).map(|_| None).collect();
    for index in (0..my_index) {
        let mut connected = false;
        while !connected {
            match TcpStream::connect(&addresses[index as usize][..]) {
                Ok(mut stream) => {
                    try!(stream.write_u64::<LittleEndian>(my_index));
                    results[index as usize] = Some(stream);
                    println!("worker {}:\tconnection to worker {}", my_index, index);
                    connected = true;
                },
                Err(error) => {
                    println!("worker {}:\terror connecting to worker {}: {}; retrying", my_index, index, error);
                    sleep_ms(1000);
                },
            }
        }
    }

    return Ok(results);
}

// result contains connections [my_index + 1, addresses.len() - 1].
fn await_connections(addresses: Arc<Vec<String>>, my_index: u64) -> Result<Vec<Option<TcpStream>>> {
    let mut results: Vec<_> = (0..(addresses.len() - my_index as usize - 1)).map(|_| None).collect();
    let listener = try!(TcpListener::bind(&addresses[my_index as usize][..]));

    for _ in (my_index as usize + 1 .. addresses.len()) {
        let mut stream = try!(listener.accept()).0;
        let identifier = try!(stream.read_u64::<LittleEndian>()) as usize;
        results[identifier - my_index as usize - 1] = Some(stream);
        println!("worker {}:\tconnection from worker {}", my_index, identifier);
    }

    return Ok(results);
}
<|endoftext|>


<commit_before>use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Msvc,
                vec!["/NOLOGO".to_string(),
                     "/NXCOMPAT".to_string()]);

    TargetOptions {
        function_sections: true,
        dynamic_linking: true,
        executables: true,
        dll_prefix: String::new(),
        dll_suffix: ".dll".to_string(),
        exe_suffix: ".exe".to_string(),
        staticlib_prefix: String::new(),
        staticlib_suffix: ".lib".to_string(),
        target_family: Some("windows".to_string()),
        is_like_windows: true,
        is_like_msvc: true,
        pre_link_args: args,
        crt_static_allows_dylibs: true,
        crt_static_respected: true,
        abi_return_struct_as_int: true,
        emit_debug_gdb_scripts: false,
        requires_uwtable: true,

        .. Default::default()
    }
}
<commit_msg>Just switch to English linker output using environment variable when using msvc.<commit_after>use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Msvc,
                vec!["/NOLOGO".to_string(),
                     "/NXCOMPAT".to_string()]);

    TargetOptions {
        function_sections: true,
        dynamic_linking: true,
        executables: true,
        dll_prefix: String::new(),
        dll_suffix: ".dll".to_string(),
        exe_suffix: ".exe".to_string(),
        staticlib_prefix: String::new(),
        staticlib_suffix: ".lib".to_string(),
        target_family: Some("windows".to_string()),
        is_like_windows: true,
        is_like_msvc: true,
        link_env: vec![("VSLANG".to_string(), "1033".to_string())],
        pre_link_args: args,
        crt_static_allows_dylibs: true,
        crt_static_respected: true,
        abi_return_struct_as_int: true,
        emit_debug_gdb_scripts: false,
        requires_uwtable: true,

        .. Default::default()
    }
}
<|endoftext|>


<commit_before>//! Types and traits for arranging collections.

use std::rc::{Rc, Weak};
use std::cell::RefCell;
use std::collections::VecDeque;

use timely::scheduling::Activator;
use trace::TraceReader;

/// Operating instructions on how to replay a trace.
pub enum TraceReplayInstruction

where
    Tr: TraceReader,
{
    /// Describes a frontier advance.
    Frontier(Vec
),
    /// Describes a batch of data and a capability hint.
    Batch(Tr::Batch, Option
),
}

// Short names for strongly and weakly owned activators and shared queues.
type BatchQueue
 = VecDeque<TraceReplayInstruction
>;
type TraceAgentQueueReader
 = Rc<(Activator, RefCell<BatchQueue
>)>;
type TraceAgentQueueWriter
 = Weak<(Activator, RefCell<BatchQueue
>)>;

pub mod writer;
pub mod agent;
pub mod arrangement;

pub use self::writer::TraceWriter;
pub use self::agent::TraceAgent;

pub use self::arrangement::{Arranged, ArrangeByKey, ArrangeBySelf};<commit_msg>documentation<commit_after>//! Types and traits for arranging collections.
//!
//! Differential dataflow collections can be "arranged" into maintained, worker-local
//! indices that can be re-used by other dataflows at relatively low cost.
//!
//! The `arrange` operator, and its variants, takes a `Collection` and produces as an
//! output an instance of the `Arrangement` type. An arrangement is logically equivalent
//! to its input collection, but it is distributed across workers and maintained in a
//! way that makes it easy to re-use.
//!
//! The `arrange` operator receives update triples `(data, time, diff)` from its input,
//! and responds to changes in its input frontier, which as it advances signals further
//! times that will no longer be observed in input updates. For each frontier advance,
//! the operator creates a new "batch", containing exactly those updates whose times are
//! in advance of the previous frontier but not in advance of the new frontier. Updates
//! are partitioned among workers by a key, and each batch is indexed by this key.
//!
//! This sequence of batches defines a continually expanding view of committed updates
//! in the collection.
//! The sequence is presented by the `Arrangement` in two forms (its fields):
//!
//! 1.  A timely dataflow `Stream` of batch elements.
//!
//!     The stream is used by operators that want to exploit the arranged structure of
//!     batches, but want the push-based computational model of timely dataflow.
//!     Many differential dataflow operators can consume streams of batches, although
//!     they may also rely on access to the second representation of the sequence.
//!
//! 2.  A `Trace` type that provides a compact representation of the accumulated batches.
//!
//!     A trace is logically equivalent to a sequence of batches, but it is able to alter
//!     the representation for efficiency. In particular, the trace may merge batches so
//!     that the total number is kept small, and it may merge logical times if it able to
//!     determine that no trace users can distinguish between them.
//!
//! Importantly, the `Trace` type has no connection to the timely dataflow runtime.
//! This means a trace can be used in a variety of contexts where a `Stream` would not be
//! appropriate, for example outside of the dataflow in which the arragement is performed.
//! Traces may be directly inspected by any code with access to them, and they can even be
//! used to introduce the batches to other dataflows with the `import` method.

use std::rc::{Rc, Weak};
use std::cell::RefCell;
use std::collections::VecDeque;

use timely::scheduling::Activator;
use trace::TraceReader;

/// Operating instructions on how to replay a trace.
pub enum TraceReplayInstruction

where
    Tr: TraceReader,
{
    /// Describes a frontier advance.
    Frontier(Vec
),
    /// Describes a batch of data and a capability hint.
    Batch(Tr::Batch, Option
),
}

// Short names for strongly and weakly owned activators and shared queues.
type BatchQueue
 = VecDeque<TraceReplayInstruction
>;
type TraceAgentQueueReader
 = Rc<(Activator, RefCell<BatchQueue
>)>;
type TraceAgentQueueWriter
 = Weak<(Activator, RefCell<BatchQueue
>)>;

pub mod writer;
pub mod agent;
pub mod arrangement;

pub use self::writer::TraceWriter;
pub use self::agent::TraceAgent;

pub use self::arrangement::{Arranged, ArrangeByKey, ArrangeBySelf};<|endoftext|>


<commit_before>use std::f64;

use na::{self, Real, Unit};

use bounding_volume::PolyhedralCone;
use math::{Isometry, Point, Vector};
use shape::{ConvexPolygonalFeature, ConvexPolyhedron, FeatureId, SupportMap};
use transformation;
use utils::{self, IsometryOps};

/// A 2D convex polygon.
pub struct ConvexPolygon<N: Real> {
    points: Vec<Point<N>>,
    normals: Vec<Unit<Vector<N>>>,
}

impl<N: Real> ConvexPolygon<N> {
    /// Creates a new 2D convex polygon from an arbitrary set of points.
    ///
    /// This explicitly computes the convex hull of the given set of points. Use
    /// Returns `None` if the convex hull computation failed.
    pub fn try_from_points(points: &[Point<N>]) -> Option<Self> {
        let hull = transformation::convex_hull(points);
        let mut vertices = hull.unwrap().0;
        vertices.reverse(); // FIXME: it is unfortunate to have to do this reverse.

        Self::try_new(vertices)
    }

    /// Creates a new 2D convex polygon from a set of points assumed to describe a convex polyline.
    ///
    /// Convexity of the input polyline is not checked.
    /// Returns `None` if some consecutive points are identical (or too close to being so).
    pub fn try_new(mut points: Vec<Point<N>>) -> Option<Self> {
        let eps = N::default_epsilon().sqrt();
        let mut normals = Vec::with_capacity(points.len());

        // First, compute all normals.
        for i1 in 0..points.len() {
            let i2 = (i1 + 1) % points.len();
            normals.push(utils::ccw_face_normal([&points[i1], &points[i2]])?);
        }

        let mut nremoved = 0;
        // See if the first vexrtex must be removed.
        if na::dot(&*normals[0], &*normals[normals.len() - 1]) > N::one() - eps {
            nremoved = 1;
        }

        // Second, find vertices that can be removed because
        // of collinearity of adjascent faces.
        for i2 in 1..points.len() {
            let i1 = i2 - 1;
            if na::dot(&*normals[i1], &*normals[i2]) > N::one() - eps {
                // Remove
                nremoved += 1;
            } else {
                points[i2 - nremoved] = points[i2];
                normals[i2 - nremoved] = normals[i2];
            }
        }

        let new_length = points.len() - nremoved;
        points.truncate(new_length);
        normals.truncate(new_length);

        if points.len() != 0 {
            Some(ConvexPolygon { points, normals })
        } else {
            None
        }
    }

    /// The vertices of this convex polygon.
    #[inline]
    pub fn points(&self) -> &[Point<N>] {
        &self.points
    }

    /// The normals of the edges of this convex polygon.
    #[inline]
    pub fn normals(&self) -> &[Unit<Vector<N>>] {
        &self.normals
    }
}

impl<N: Real> SupportMap<N> for ConvexPolygon<N> {
    #[inline]
    fn support_point(&self, m: &Isometry<N>, dir: &Vector<N>) -> Point<N> {
        let local_dir = m.inverse_transform_vector(dir);
        let best_pt = utils::point_cloud_support_point(&local_dir, self.points());

        m * best_pt
    }
}

impl<N: Real> ConvexPolyhedron<N> for ConvexPolygon<N> {
    fn vertex(&self, id: FeatureId) -> Point<N> {
        self.points[id.unwrap_vertex()]
    }

    fn face(&self, id: FeatureId, out: &mut ConvexPolygonalFeature<N>) {
        out.clear();

        let ia = id.unwrap_face();
        let ib = (ia + 1) % self.points.len();
        out.push(self.points[ia], FeatureId::Vertex(ia));
        out.push(self.points[ib], FeatureId::Vertex(ib));

        out.set_normal(self.normals[ia]);
        out.set_feature_id(FeatureId::Face(ia));
    }

    fn normal_cone(&self, feature: FeatureId) -> PolyhedralCone<N> {
        match feature {
            FeatureId::Face(id) => PolyhedralCone::HalfLine(self.normals[id]),
            FeatureId::Vertex(id2) => {
                let id1 = if id2 == 0 {
                    self.normals.len() - 1
                } else {
                    id2 - 1
                };
                PolyhedralCone::Span([self.normals[id1], self.normals[id2]])
            }
            _ => unreachable!(),
        }
    }

    fn support_face_toward(
        &self,
        m: &Isometry<N>,
        dir: &Unit<Vector<N>>,
        out: &mut ConvexPolygonalFeature<N>,
    ) {
        let ls_dir = m.inverse_transform_vector(dir);
        let mut best_face = 0;
        let mut max_dot = na::dot(&*self.normals[0], &ls_dir);

        for i in 1..self.points.len() {
            let dot = na::dot(&*self.normals[i], &ls_dir);

            if dot > max_dot {
                max_dot = dot;
                best_face = i;
            }
        }

        self.face(FeatureId::Face(best_face), out);
        out.transform_by(m);
    }

    fn support_feature_toward(
        &self,
        transform: &Isometry<N>,
        dir: &Unit<Vector<N>>,
        _angle: N,
        out: &mut ConvexPolygonalFeature<N>,
    ) {
        out.clear();
        // FIXME: actualy find the support feature.
        self.support_face_toward(transform, dir, out)
    }

    fn support_feature_id_toward(&self, local_dir: &Unit<Vector<N>>) -> FeatureId {
        let eps: N = na::convert(f64::consts::PI / 180.0);
        let ceps = eps.cos();

        // Check faces.
        for i in 0..self.normals.len() {
            let normal = &self.normals[i];

            if na::dot(normal.as_ref(), local_dir.as_ref()) >= ceps {
                return FeatureId::Face(i);
            }
        }

        // Support vertex.
        FeatureId::Vertex(utils::point_cloud_support_point_id(
            local_dir.as_ref(),
            &self.points,
        ))
    }
}
<commit_msg>Add Clone and Debug implementations to ConvexPolygon.<commit_after>use std::f64;

use na::{self, Real, Unit};

use bounding_volume::PolyhedralCone;
use math::{Isometry, Point, Vector};
use shape::{ConvexPolygonalFeature, ConvexPolyhedron, FeatureId, SupportMap};
use transformation;
use utils::{self, IsometryOps};

/// A 2D convex polygon.
#[derive(Clone, Debug)]
pub struct ConvexPolygon<N: Real> {
    points: Vec<Point<N>>,
    normals: Vec<Unit<Vector<N>>>,
}

impl<N: Real> ConvexPolygon<N> {
    /// Creates a new 2D convex polygon from an arbitrary set of points.
    ///
    /// This explicitly computes the convex hull of the given set of points. Use
    /// Returns `None` if the convex hull computation failed.
    pub fn try_from_points(points: &[Point<N>]) -> Option<Self> {
        let hull = transformation::convex_hull(points);
        let mut vertices = hull.unwrap().0;
        vertices.reverse(); // FIXME: it is unfortunate to have to do this reverse.

        Self::try_new(vertices)
    }

    /// Creates a new 2D convex polygon from a set of points assumed to describe a convex polyline.
    ///
    /// Convexity of the input polyline is not checked.
    /// Returns `None` if some consecutive points are identical (or too close to being so).
    pub fn try_new(mut points: Vec<Point<N>>) -> Option<Self> {
        let eps = N::default_epsilon().sqrt();
        let mut normals = Vec::with_capacity(points.len());

        // First, compute all normals.
        for i1 in 0..points.len() {
            let i2 = (i1 + 1) % points.len();
            normals.push(utils::ccw_face_normal([&points[i1], &points[i2]])?);
        }

        let mut nremoved = 0;
        // See if the first vexrtex must be removed.
        if na::dot(&*normals[0], &*normals[normals.len() - 1]) > N::one() - eps {
            nremoved = 1;
        }

        // Second, find vertices that can be removed because
        // of collinearity of adjascent faces.
        for i2 in 1..points.len() {
            let i1 = i2 - 1;
            if na::dot(&*normals[i1], &*normals[i2]) > N::one() - eps {
                // Remove
                nremoved += 1;
            } else {
                points[i2 - nremoved] = points[i2];
                normals[i2 - nremoved] = normals[i2];
            }
        }

        let new_length = points.len() - nremoved;
        points.truncate(new_length);
        normals.truncate(new_length);

        if points.len() != 0 {
            Some(ConvexPolygon { points, normals })
        } else {
            None
        }
    }

    /// The vertices of this convex polygon.
    #[inline]
    pub fn points(&self) -> &[Point<N>] {
        &self.points
    }

    /// The normals of the edges of this convex polygon.
    #[inline]
    pub fn normals(&self) -> &[Unit<Vector<N>>] {
        &self.normals
    }
}

impl<N: Real> SupportMap<N> for ConvexPolygon<N> {
    #[inline]
    fn support_point(&self, m: &Isometry<N>, dir: &Vector<N>) -> Point<N> {
        let local_dir = m.inverse_transform_vector(dir);
        let best_pt = utils::point_cloud_support_point(&local_dir, self.points());

        m * best_pt
    }
}

impl<N: Real> ConvexPolyhedron<N> for ConvexPolygon<N> {
    fn vertex(&self, id: FeatureId) -> Point<N> {
        self.points[id.unwrap_vertex()]
    }

    fn face(&self, id: FeatureId, out: &mut ConvexPolygonalFeature<N>) {
        out.clear();

        let ia = id.unwrap_face();
        let ib = (ia + 1) % self.points.len();
        out.push(self.points[ia], FeatureId::Vertex(ia));
        out.push(self.points[ib], FeatureId::Vertex(ib));

        out.set_normal(self.normals[ia]);
        out.set_feature_id(FeatureId::Face(ia));
    }

    fn normal_cone(&self, feature: FeatureId) -> PolyhedralCone<N> {
        match feature {
            FeatureId::Face(id) => PolyhedralCone::HalfLine(self.normals[id]),
            FeatureId::Vertex(id2) => {
                let id1 = if id2 == 0 {
                    self.normals.len() - 1
                } else {
                    id2 - 1
                };
                PolyhedralCone::Span([self.normals[id1], self.normals[id2]])
            }
            _ => unreachable!(),
        }
    }

    fn support_face_toward(
        &self,
        m: &Isometry<N>,
        dir: &Unit<Vector<N>>,
        out: &mut ConvexPolygonalFeature<N>,
    ) {
        let ls_dir = m.inverse_transform_vector(dir);
        let mut best_face = 0;
        let mut max_dot = na::dot(&*self.normals[0], &ls_dir);

        for i in 1..self.points.len() {
            let dot = na::dot(&*self.normals[i], &ls_dir);

            if dot > max_dot {
                max_dot = dot;
                best_face = i;
            }
        }

        self.face(FeatureId::Face(best_face), out);
        out.transform_by(m);
    }

    fn support_feature_toward(
        &self,
        transform: &Isometry<N>,
        dir: &Unit<Vector<N>>,
        _angle: N,
        out: &mut ConvexPolygonalFeature<N>,
    ) {
        out.clear();
        // FIXME: actualy find the support feature.
        self.support_face_toward(transform, dir, out)
    }

    fn support_feature_id_toward(&self, local_dir: &Unit<Vector<N>>) -> FeatureId {
        let eps: N = na::convert(f64::consts::PI / 180.0);
        let ceps = eps.cos();

        // Check faces.
        for i in 0..self.normals.len() {
            let normal = &self.normals[i];

            if na::dot(normal.as_ref(), local_dir.as_ref()) >= ceps {
                return FeatureId::Face(i);
            }
        }

        // Support vertex.
        FeatureId::Vertex(utils::point_cloud_support_point_id(
            local_dir.as_ref(),
            &self.points,
        ))
    }
}
<|endoftext|>


<commit_before>//! Top-down splay tree
use std::cmp;
use std::mem;
use std::hash;
use std::cmp::Ordering;
use std::borrow::Borrow;
use iter;

pub type BoxNode<K, V> = Box<Node<K, V>>;
pub type MaybeNode<K, V> = Option<BoxNode<K, V>>;

#[derive(Debug, Clone)]
pub struct Node<K, V> {
    pub key: K,
    pub val: V,
    pub lft: MaybeNode<K, V>,
    pub rgt: MaybeNode<K, V>,
}
impl<K, V> Node<K, V>
    where K: Ord
{
    fn new(key: K, value: V, lft: MaybeNode<K, V>, rgt: MaybeNode<K, V>) -> Box<Self> {
        Box::new(Node {
            key: key,
            val: value,
            lft: lft,
            rgt: rgt,
        })
    }
    fn splay<Q: ?Sized>(self: BoxNode<K, V>, key: &Q) -> (BoxNode<K, V>, Ordering)
        where K: Borrow<Q>,
              Q: Ord
    {
        self.splay_by(|k| key.cmp(k.borrow()))
    }
    fn splay_lftmost(self: BoxNode<K, V>) -> BoxNode<K, V> {
        self.splay_by(|_| Ordering::Less).0
    }
    fn splay_by<F>(self: BoxNode<K, V>, cmp: F) -> (BoxNode<K, V>, Ordering)
        where F: Fn(&K) -> Ordering
    {
        let mut node = self;
        let mut lft_root = None;
        let mut rgt_root = None;
        let mut order = cmp(node.key.borrow());
        {
            let mut lft_rgtmost = &mut lft_root;
            let mut rgt_lftmost = &mut rgt_root;
            loop {
                match order {
                    Ordering::Equal => break,
                    Ordering::Less => {
                        let mut child = if let Some(child) = node.lft.take() {
                            child
                        } else {
                            break;
                        };
                        // zig
                        order = cmp(child.key.borrow());
                        if let Ordering::Less = order {
                            if let Some(grand_child) = child.lft.take() {
                                // zig-zig
                                node.lft = child.rgt.take();
                                child.rgt = Some(node);
                                node = child;
                                child = grand_child;
                                order = cmp(child.key.borrow());
                            }
                        }
                        let node_lft: usize = unsafe { mem::transmute(&mut node.lft) };
                        *rgt_lftmost = Some(node);
                        rgt_lftmost = unsafe { mem::transmute(node_lft) };

                        node = child;
                    }
                    Ordering::Greater => {
                        let mut child = if let Some(child) = node.rgt.take() {
                            child
                        } else {
                            break;
                        };
                        // zag
                        order = cmp(child.key.borrow());
                        if let Ordering::Greater = order {
                            if let Some(grand_child) = child.rgt.take() {
                                // zag-zag
                                node.rgt = child.lft.take();
                                child.lft = Some(node);
                                node = child;
                                child = grand_child;
                                order = cmp(child.key.borrow());
                            }
                        }
                        let node_rgt: usize = unsafe { mem::transmute(&mut node.rgt) };
                        *lft_rgtmost = Some(node);
                        lft_rgtmost = unsafe { mem::transmute(node_rgt) };

                        node = child;
                    }
                }
            }
            *lft_rgtmost = node.lft.take();
            *rgt_lftmost = node.rgt.take();
        }
        node.lft = lft_root;
        node.rgt = rgt_root;
        (node, order)
    }
    fn pop(mut self) -> ((K, V), MaybeNode<K, V>) {
        let root = match (self.lft.take(), self.rgt.take()) {
            (None, None) => None,
            (Some(lft), None) => Some(lft),
            (None, Some(rgt)) => Some(rgt),
            (Some(mut lft), Some(mut rgt)) => {
                if let Some(lft_rgt) = lft.rgt.take() {
                    rgt = rgt.splay_lftmost();
                    rgt.lft = Some(lft_rgt);
                }
                lft.rgt = Some(rgt);
                Some(lft)
            }
        };
        ((self.key, self.val), root)
    }
}

#[derive(Debug, Clone)]
pub struct Tree<K, V> {
    pub root: MaybeNode<K, V>,
    pub len: usize,
}
impl<K, V> Tree<K, V>
    where K: Ord
{
    pub fn new() -> Self {
        Tree {
            root: None,
            len: 0,
        }
    }
    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
        let (new_root, old_value) = if let Some(root) = self.root.take() {
            let (mut root, order) = root.splay(&key);
            match order {
                Ordering::Equal => {
                    let old = mem::replace(&mut root.val, value);
                    (root, Some(old))
                }
                Ordering::Less => {
                    let lft = root.lft.take();
                    (Node::new(key, value, lft, Some(root)), None)
                }
                Ordering::Greater => {
                    let rgt = root.rgt.take();
                    (Node::new(key, value, Some(root), rgt), None)
                }
            }
        } else {
            (Node::new(key, value, None, None), None)
        };
        self.root = Some(new_root);
        if old_value.is_none() {
            self.len += 1;
        }
        old_value
    }
    pub fn find_lower_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.root.take().and_then(move |root| {
            let (root, order) = root.splay(key);
            self.root = Some(root);
            if let Ordering::Greater = order {
                let root = self.root.as_mut().unwrap();
                root.rgt = root.rgt.take().map(|r| r.splay_lftmost());
                root.rgt.as_ref().map(|r| &r.key)
            } else {
                self.root.as_ref().map(|n| &n.key)
            }
        })
    }
    pub fn find_upper_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.root.take().and_then(move |root| {
            let (root, order) = root.splay(key);
            self.root = Some(root);
            if let Ordering::Less = order {
                self.root.as_ref().map(|n| &n.key)
            } else {
                let root = self.root.as_mut().unwrap();
                root.rgt = root.rgt.take().map(|r| r.splay_lftmost());
                root.rgt.as_ref().map(|r| &r.key)
            }
        })
    }
    pub fn contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool
        where K: Borrow<Q>,
              Q: Ord
    {
        self.root.take().map_or(false, move |root| {
            let (root, order) = root.splay(key);
            self.root = Some(root);
            order == Ordering::Equal
        })
    }
    pub fn pop_root(&mut self) -> Option<(K, V)> {
        self.root.take().map(|root| {
            let (e, root) = root.pop();
            self.root = root;
            self.len -= 1;
            e
        })
    }
    pub fn get_lftmost(&mut self) -> Option<(&K, &V)> {
        self.root = self.root.take().map(|n| n.splay_lftmost());
        self.root.as_ref().map(|n| (&n.key, &n.val))
    }
    pub fn take_lftmost(&mut self) -> Option<(K, V)> {
        self.root = self.root.take().map(|n| n.splay_lftmost());
        self.pop_root()
    }
    pub fn get<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
        where K: Borrow<Q>,
              Q: Ord
    {
        if self.contains_key(key) {
            self.root.as_mut().map(|n| &mut n.val)
        } else {
            None
        }
    }
    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
        where K: Borrow<Q>,
              Q: Ord
    {
        if self.contains_key(key) {
            self.pop_root().map(|(_, v)| v)
        } else {
            None
        }
    }
}
impl<K, V> Tree<K, V> {
    fn iter(&self) -> iter::Iter<K, V> {
        iter::Iter::new(self)
    }
}
impl<K, V> hash::Hash for Tree<K, V>
    where K: hash::Hash,
          V: hash::Hash
{
    fn hash<H>(&self, state: &mut H)
        where H: hash::Hasher
    {
        for (k, v) in self.iter() {
            k.hash(state);
            v.hash(state);
        }
    }
}
impl<K, V> PartialEq for Tree<K, V>
    where K: PartialEq,
          V: PartialEq
{
    fn eq(&self, other: &Self) -> bool {
        self.len == other.len && self.iter().zip(other.iter()).all(|(a, b)| a.eq(&b))
    }
}
impl<K, V> Eq for Tree<K, V>
    where K: Eq,
          V: Eq
{
}
impl<K, V> PartialOrd for Tree<K, V>
    where K: PartialOrd,
          V: PartialOrd
{
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return Some(cmp::Ordering::Equal),
                (None, _) => return Some(cmp::Ordering::Less),
                (_, None) => return Some(cmp::Ordering::Greater),
                (Some(e0), Some(e1)) => {
                    match e0.partial_cmp(&e1) {
                        Some(cmp::Ordering::Equal) => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}
impl<K, V> Ord for Tree<K, V>
    where K: Ord,
          V: Ord
{
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return cmp::Ordering::Equal,
                (None, _) => return cmp::Ordering::Less,
                (_, None) => return cmp::Ordering::Greater,
                (Some(e0), Some(e1)) => {
                    match e0.cmp(&e1) {
                        cmp::Ordering::Equal => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}
<commit_msg>Use raw pointer instead of mem::transmute<commit_after>//! Top-down splay tree
use std::cmp;
use std::mem;
use std::hash;
use std::cmp::Ordering;
use std::borrow::Borrow;
use iter;

pub type BoxNode<K, V> = Box<Node<K, V>>;
pub type MaybeNode<K, V> = Option<BoxNode<K, V>>;

#[derive(Debug, Clone)]
pub struct Node<K, V> {
    pub key: K,
    pub val: V,
    pub lft: MaybeNode<K, V>,
    pub rgt: MaybeNode<K, V>,
}
impl<K, V> Node<K, V>
    where K: Ord
{
    fn new(key: K, value: V, lft: MaybeNode<K, V>, rgt: MaybeNode<K, V>) -> Box<Self> {
        Box::new(Node {
            key: key,
            val: value,
            lft: lft,
            rgt: rgt,
        })
    }
    fn splay<Q: ?Sized>(self: BoxNode<K, V>, key: &Q) -> (BoxNode<K, V>, Ordering)
        where K: Borrow<Q>,
              Q: Ord
    {
        self.splay_by(|k| key.cmp(k.borrow()))
    }
    fn splay_lftmost(self: BoxNode<K, V>) -> BoxNode<K, V> {
        self.splay_by(|_| Ordering::Less).0
    }
    fn splay_by<F>(self: BoxNode<K, V>, cmp: F) -> (BoxNode<K, V>, Ordering)
        where F: Fn(&K) -> Ordering
    {
        let mut node = self;
        let mut lft_root = None;
        let mut rgt_root = None;
        let mut order = cmp(node.key.borrow());
        {
            let mut lft_rgtmost = &mut lft_root;
            let mut rgt_lftmost = &mut rgt_root;
            loop {
                match order {
                    Ordering::Equal => break,
                    Ordering::Less => {
                        let mut child = if let Some(child) = node.lft.take() {
                            child
                        } else {
                            break;
                        };
                        // zig
                        order = cmp(child.key.borrow());
                        if let Ordering::Less = order {
                            if let Some(grand_child) = child.lft.take() {
                                // zig-zig
                                node.lft = child.rgt.take();
                                child.rgt = Some(node);
                                node = child;
                                child = grand_child;
                                order = cmp(child.key.borrow());
                            }
                        }
                        let node_lft = &mut node.lft as *mut _;
                        *rgt_lftmost = Some(node);
                        rgt_lftmost = unsafe { &mut *node_lft };

                        node = child;
                    }
                    Ordering::Greater => {
                        let mut child = if let Some(child) = node.rgt.take() {
                            child
                        } else {
                            break;
                        };
                        // zag
                        order = cmp(child.key.borrow());
                        if let Ordering::Greater = order {
                            if let Some(grand_child) = child.rgt.take() {
                                // zag-zag
                                node.rgt = child.lft.take();
                                child.lft = Some(node);
                                node = child;
                                child = grand_child;
                                order = cmp(child.key.borrow());
                            }
                        }
                        let node_rgt = &mut node.rgt as *mut _;
                        *lft_rgtmost = Some(node);
                        lft_rgtmost = unsafe { &mut *node_rgt };

                        node = child;
                    }
                }
            }
            *lft_rgtmost = node.lft.take();
            *rgt_lftmost = node.rgt.take();
        }
        node.lft = lft_root;
        node.rgt = rgt_root;
        (node, order)
    }
    fn pop(mut self) -> ((K, V), MaybeNode<K, V>) {
        let root = match (self.lft.take(), self.rgt.take()) {
            (None, None) => None,
            (Some(lft), None) => Some(lft),
            (None, Some(rgt)) => Some(rgt),
            (Some(mut lft), Some(mut rgt)) => {
                if let Some(lft_rgt) = lft.rgt.take() {
                    rgt = rgt.splay_lftmost();
                    rgt.lft = Some(lft_rgt);
                }
                lft.rgt = Some(rgt);
                Some(lft)
            }
        };
        ((self.key, self.val), root)
    }
}

#[derive(Debug, Clone)]
pub struct Tree<K, V> {
    pub root: MaybeNode<K, V>,
    pub len: usize,
}
impl<K, V> Tree<K, V>
    where K: Ord
{
    pub fn new() -> Self {
        Tree {
            root: None,
            len: 0,
        }
    }
    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
        let (new_root, old_value) = if let Some(root) = self.root.take() {
            let (mut root, order) = root.splay(&key);
            match order {
                Ordering::Equal => {
                    let old = mem::replace(&mut root.val, value);
                    (root, Some(old))
                }
                Ordering::Less => {
                    let lft = root.lft.take();
                    (Node::new(key, value, lft, Some(root)), None)
                }
                Ordering::Greater => {
                    let rgt = root.rgt.take();
                    (Node::new(key, value, Some(root), rgt), None)
                }
            }
        } else {
            (Node::new(key, value, None, None), None)
        };
        self.root = Some(new_root);
        if old_value.is_none() {
            self.len += 1;
        }
        old_value
    }
    pub fn find_lower_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.root.take().and_then(move |root| {
            let (root, order) = root.splay(key);
            self.root = Some(root);
            if let Ordering::Greater = order {
                let root = self.root.as_mut().unwrap();
                root.rgt = root.rgt.take().map(|r| r.splay_lftmost());
                root.rgt.as_ref().map(|r| &r.key)
            } else {
                self.root.as_ref().map(|n| &n.key)
            }
        })
    }
    pub fn find_upper_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.root.take().and_then(move |root| {
            let (root, order) = root.splay(key);
            self.root = Some(root);
            if let Ordering::Less = order {
                self.root.as_ref().map(|n| &n.key)
            } else {
                let root = self.root.as_mut().unwrap();
                root.rgt = root.rgt.take().map(|r| r.splay_lftmost());
                root.rgt.as_ref().map(|r| &r.key)
            }
        })
    }
    pub fn contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool
        where K: Borrow<Q>,
              Q: Ord
    {
        self.root.take().map_or(false, move |root| {
            let (root, order) = root.splay(key);
            self.root = Some(root);
            order == Ordering::Equal
        })
    }
    pub fn pop_root(&mut self) -> Option<(K, V)> {
        self.root.take().map(|root| {
            let (e, root) = root.pop();
            self.root = root;
            self.len -= 1;
            e
        })
    }
    pub fn get_lftmost(&mut self) -> Option<(&K, &V)> {
        self.root = self.root.take().map(|n| n.splay_lftmost());
        self.root.as_ref().map(|n| (&n.key, &n.val))
    }
    pub fn take_lftmost(&mut self) -> Option<(K, V)> {
        self.root = self.root.take().map(|n| n.splay_lftmost());
        self.pop_root()
    }
    pub fn get<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
        where K: Borrow<Q>,
              Q: Ord
    {
        if self.contains_key(key) {
            self.root.as_mut().map(|n| &mut n.val)
        } else {
            None
        }
    }
    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
        where K: Borrow<Q>,
              Q: Ord
    {
        if self.contains_key(key) {
            self.pop_root().map(|(_, v)| v)
        } else {
            None
        }
    }
}
impl<K, V> Tree<K, V> {
    fn iter(&self) -> iter::Iter<K, V> {
        iter::Iter::new(self)
    }
}
impl<K, V> hash::Hash for Tree<K, V>
    where K: hash::Hash,
          V: hash::Hash
{
    fn hash<H>(&self, state: &mut H)
        where H: hash::Hasher
    {
        for (k, v) in self.iter() {
            k.hash(state);
            v.hash(state);
        }
    }
}
impl<K, V> PartialEq for Tree<K, V>
    where K: PartialEq,
          V: PartialEq
{
    fn eq(&self, other: &Self) -> bool {
        self.len == other.len && self.iter().zip(other.iter()).all(|(a, b)| a.eq(&b))
    }
}
impl<K, V> Eq for Tree<K, V>
    where K: Eq,
          V: Eq
{
}
impl<K, V> PartialOrd for Tree<K, V>
    where K: PartialOrd,
          V: PartialOrd
{
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return Some(cmp::Ordering::Equal),
                (None, _) => return Some(cmp::Ordering::Less),
                (_, None) => return Some(cmp::Ordering::Greater),
                (Some(e0), Some(e1)) => {
                    match e0.partial_cmp(&e1) {
                        Some(cmp::Ordering::Equal) => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}
impl<K, V> Ord for Tree<K, V>
    where K: Ord,
          V: Ord
{
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return cmp::Ordering::Equal,
                (None, _) => return cmp::Ordering::Less,
                (_, None) => return cmp::Ordering::Greater,
                (Some(e0), Some(e1)) => {
                    match e0.cmp(&e1) {
                        cmp::Ordering::Equal => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate anymap;

use std::io::net::ip::IpAddr;
use anymap::AnyMap;

#[deriving(Show)]
enum HostAddress {
    DomainName(String),
    Ip(IpAddr),
}

#[deriving(Show)]
struct Port(u32);

#[deriving(Show)]
struct ConnectionLimit(u32);

fn main() {
    println!("24 days of Rust - anymap (day 9)");
    let mut config = AnyMap::new();
    config.insert(HostAddress::DomainName("siciarz.net".to_string()));
    config.insert(Port(666));
    config.insert(ConnectionLimit(32));
    println!("{}", config.get::<HostAddress>());
    println!("{}", config.get::<Port>());
    assert!(config.get::<String>().is_none());
    assert!(config.get::<u32>().is_none());
    config.insert(HostAddress::Ip(IpAddr::Ipv4Addr(127, 0, 0, 1)));
    println!("{}", config.get::<HostAddress>());
}
<commit_msg>Option<f32> vs Option<f64> example.<commit_after>extern crate anymap;

use std::io::net::ip::IpAddr;
use anymap::AnyMap;

#[deriving(Show)]
enum HostAddress {
    DomainName(String),
    Ip(IpAddr),
}

#[deriving(Show)]
struct Port(u32);

#[deriving(Show)]
struct ConnectionLimit(u32);

fn main() {
    println!("24 days of Rust - anymap (day 9)");
    let mut config = AnyMap::new();
    config.insert(HostAddress::DomainName("siciarz.net".to_string()));
    config.insert(Port(666));
    config.insert(ConnectionLimit(32));
    println!("{}", config.get::<HostAddress>());
    println!("{}", config.get::<Port>());
    assert!(config.get::<String>().is_none());
    assert!(config.get::<u32>().is_none());
    config.insert(HostAddress::Ip(IpAddr::Ipv4Addr(127, 0, 0, 1)));
    println!("{}", config.get::<HostAddress>());
    if config.contains::<Option<f32>>() {
        println!("There's no optional float in the configuration...");
    }
    let dummy: Option<f32> = None;
    config.insert(dummy);
    if config.contains::<Option<f32>>() {
        println!("There's an optional 32-bit float in the configuration...");
    }
    if !config.contains::<Option<f64>>() {
        println!("...but not an optional 64-bit float.");
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use gecko_bindings::structs;
use heapsize::HeapSizeOf;
use std::{mem, ptr};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

/// Trait for all objects that have Addref() and Release
/// methods and can be placed inside RefPtr<T>
pub unsafe trait RefCounted {
    fn addref(&self);
    unsafe fn release(&self);
}

/// Trait for types which can be shared across threads in RefPtr
pub unsafe trait ThreadSafeRefCounted: RefCounted {}

#[derive(Debug)]
pub struct RefPtr<T: RefCounted> {
    ptr: *mut T,
    _marker: PhantomData<T>,
}

/// A RefPtr that we know is uniquely owned
///
/// This is basically Box<T>, with the additional
/// guarantee that the box can be safely interpreted
/// as a RefPtr<T> (with refcount 1)
///
/// This is useful when you wish to create a refptr
/// and mutate it temporarily, while it is still
/// uniquely owned.
pub struct UniqueRefPtr<T: RefCounted>(RefPtr<T>);

// There is no safe conversion from &T to RefPtr<T> (like Gecko has)
// because this lets you break UniqueRefPtr's guarantee

impl<T: RefCounted> RefPtr<T> {
    /// Create a new RefPtr from an already addrefed
    /// pointer obtained from FFI. Pointer
    /// must be valid, non-null and have been addrefed
    pub unsafe fn from_addrefed(ptr: *mut T) -> Self {
        debug_assert!(!ptr.is_null());
        RefPtr {
            ptr: ptr,
            _marker: PhantomData,
        }
    }

    /// Create a new RefPtr from a pointer obtained
    /// from FFI. Pointer must be valid and non null.
    /// This method calls addref() internally
    pub unsafe fn new(ptr: *mut T) -> Self {
        debug_assert!(!ptr.is_null());
        let ret = RefPtr {
            ptr: ptr,
            _marker: PhantomData,
        };
        ret.addref();
        ret
    }

    /// Produces an FFI-compatible RefPtr that can be stored in
    /// style structs.
    ///
    /// structs::RefPtr does not have a destructor, so this may leak
    pub fn forget(self) -> structs::RefPtr<T> {
        let ret = structs::RefPtr {
            mRawPtr: self.ptr,
        };
        mem::forget(self);
        ret
    }

    /// Returns the raw inner pointer
    /// to be fed back into FFI
    pub fn get(&self) -> *mut T {
        self.ptr
    }

    /// Addref the inner data
    ///
    /// Leaky on its own
    pub fn addref(&self) {
        unsafe { (*self.ptr).addref(); }
    }

    /// Release the inner data
    ///
    /// Call only when the data actuall needs releasing
    pub unsafe fn release(&self) {
        (*self.ptr).release();
    }
}

impl<T: RefCounted> UniqueRefPtr<T> {
    /// Create a unique refptr from an already addrefed
    /// pointer obtained from FFI. The refcount must be one.
    /// The pointer must be valid and non null
    pub unsafe fn from_addrefed(ptr: *mut T) -> Self {
        UniqueRefPtr(RefPtr::from_addrefed(ptr))
    }

    /// Convert to a RefPtr so that it can be used
    pub fn get(self) -> RefPtr<T> {
        self.0
    }
}

impl<T: RefCounted> Deref for RefPtr<T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.ptr }
    }
}

impl<T: RefCounted> Deref for UniqueRefPtr<T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.0.ptr }
    }
}

impl<T: RefCounted> DerefMut for UniqueRefPtr<T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.0.ptr }
    }
}

impl<T: RefCounted> structs::RefPtr<T> {
    /// Produces a Rust-side RefPtr from an FFI RefPtr, bumping the refcount
    ///
    /// Must be called on a valid, non-null structs::RefPtr<T>
    pub unsafe fn to_safe(&self) -> RefPtr<T> {
        debug_assert!(!self.mRawPtr.is_null());
        let r = RefPtr {
            ptr: self.mRawPtr,
            _marker: PhantomData,
        };
        r.addref();
        r
    }
    /// Produces a Rust-side RefPtr, consuming the existing one (and not bumping the refcount)
    pub unsafe fn into_safe(self) -> RefPtr<T> {
        debug_assert!(!self.mRawPtr.is_null());
        RefPtr {
            ptr: self.mRawPtr,
            _marker: PhantomData,
        }
    }

    /// Replace a structs::RefPtr<T> with a different one, appropriately addref/releasing
    ///
    /// Both `self` and `other` must be valid, but can be null
    pub unsafe fn set(&mut self, other: &Self) {
        self.clear();
        if !other.mRawPtr.is_null() {
            *self = other.to_safe().forget();
        }
    }

    /// Clear an instance of the structs::RefPtr<T>, by releasing
    /// it and setting its contents to null
    ///
    /// `self` must be valid, but can be null
    pub unsafe fn clear(&mut self) {
        if !self.mRawPtr.is_null() {
            (*self.mRawPtr).release();
            self.mRawPtr = ptr::null_mut();
        }
    }

    /// Replace a `structs::RefPtr<T>` with a `RefPtr<T>`,
    /// consuming the `RefPtr<T>`, and releasing the old
    /// value in `self` if necessary.
    ///
    /// `self` must be valid, possibly null
    pub fn set_move(&mut self, other: RefPtr<T>) {
        if !self.mRawPtr.is_null() {
            unsafe { (*self.mRawPtr).release(); }
        }
        *self = other.forget();
    }
}

impl<T: RefCounted> Drop for RefPtr<T> {
    fn drop(&mut self) {
        unsafe { self.release() }
    }
}

impl<T: RefCounted> Clone for RefPtr<T> {
    fn clone(&self) -> Self {
        self.addref();
        RefPtr {
            ptr: self.ptr,
            _marker: PhantomData,
        }
    }
}

impl<T: RefCounted> HeapSizeOf for RefPtr<T> {
    fn heap_size_of_children(&self) -> usize { 0 }
}

impl<T: RefCounted> PartialEq for RefPtr<T> {
    fn eq(&self, other: &Self) -> bool {
        self.ptr == other.ptr
    }
}

unsafe impl<T: ThreadSafeRefCounted> Send for RefPtr<T> {}
unsafe impl<T: ThreadSafeRefCounted> Sync for RefPtr<T> {}

// Companion of NS_DECL_THREADSAFE_FFI_REFCOUNTING
//
// Gets you a free RefCounted impl
macro_rules! impl_threadsafe_refcount {
    ($t:ty, $addref:ident, $release:ident) => (
        unsafe impl RefCounted for $t {
            fn addref(&self) {
                unsafe { ::gecko_bindings::bindings::$addref(self as *const _ as *mut _) }
            }
            unsafe fn release(&self) {
                ::gecko_bindings::bindings::$release(self as *const _ as *mut _)
            }
        }
        unsafe impl ThreadSafeRefCounted for $t {}
    );
}

impl_threadsafe_refcount!(::gecko_bindings::structs::ThreadSafePrincipalHolder,
                          Gecko_AddRefPrincipalArbitraryThread,
                          Gecko_ReleasePrincipalArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::ThreadSafeURIHolder,
                          Gecko_AddRefURIArbitraryThread,
                          Gecko_ReleaseURIArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::nsStyleQuoteValues,
                          Gecko_AddRefQuoteValuesArbitraryThread,
                          Gecko_ReleaseQuoteValuesArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::nsCSSValueSharedList,
                          Gecko_AddRefCSSValueSharedListArbitraryThread,
                          Gecko_ReleaseCSSValueSharedListArbitraryThread);
pub type GeckoArcPrincipal = RefPtr<::gecko_bindings::structs::ThreadSafePrincipalHolder>;
pub type GeckoArcURI = RefPtr<::gecko_bindings::structs::ThreadSafeURIHolder>;
<commit_msg>style: Document the RefPtr sugar module.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A rust helper to ease the use of Gecko's refcounted types.

use gecko_bindings::structs;
use heapsize::HeapSizeOf;
use std::{mem, ptr};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

/// Trait for all objects that have Addref() and Release
/// methods and can be placed inside RefPtr<T>
pub unsafe trait RefCounted {
    /// Bump the reference count.
    fn addref(&self);
    /// Decrease the reference count.
    unsafe fn release(&self);
}

/// Trait for types which can be shared across threads in RefPtr.
pub unsafe trait ThreadSafeRefCounted: RefCounted {}

/// A custom RefPtr implementation to take into account Drop semantics and
/// a bit less-painful memory management.
#[derive(Debug)]
pub struct RefPtr<T: RefCounted> {
    ptr: *mut T,
    _marker: PhantomData<T>,
}

/// A RefPtr that we know is uniquely owned.
///
/// This is basically Box<T>, with the additional guarantee that the box can be
/// safely interpreted as a RefPtr<T> (with refcount 1)
///
/// This is useful when you wish to create a refptr and mutate it temporarily,
/// while it is still uniquely owned.
pub struct UniqueRefPtr<T: RefCounted>(RefPtr<T>);

// There is no safe conversion from &T to RefPtr<T> (like Gecko has)
// because this lets you break UniqueRefPtr's guarantee

impl<T: RefCounted> RefPtr<T> {
    /// Create a new RefPtr from an already addrefed pointer obtained from FFI.
    ///
    /// The pointer must be valid, non-null and have been addrefed.
    pub unsafe fn from_addrefed(ptr: *mut T) -> Self {
        debug_assert!(!ptr.is_null());
        RefPtr {
            ptr: ptr,
            _marker: PhantomData,
        }
    }

    /// Create a new RefPtr from a pointer obtained from FFI.
    ///
    /// The pointer must be valid and non null.
    ///
    /// This method calls addref() internally
    pub unsafe fn new(ptr: *mut T) -> Self {
        debug_assert!(!ptr.is_null());
        let ret = RefPtr {
            ptr: ptr,
            _marker: PhantomData,
        };
        ret.addref();
        ret
    }

    /// Produces an FFI-compatible RefPtr that can be stored in style structs.
    ///
    /// structs::RefPtr does not have a destructor, so this may leak
    pub fn forget(self) -> structs::RefPtr<T> {
        let ret = structs::RefPtr {
            mRawPtr: self.ptr,
        };
        mem::forget(self);
        ret
    }

    /// Returns the raw inner pointer to be fed back into FFI.
    pub fn get(&self) -> *mut T {
        self.ptr
    }

    /// Addref the inner data, obviously leaky on its own.
    pub fn addref(&self) {
        unsafe { (*self.ptr).addref(); }
    }

    /// Release the inner data.
    ///
    /// Call only when the data actually needs releasing.
    pub unsafe fn release(&self) {
        (*self.ptr).release();
    }
}

impl<T: RefCounted> UniqueRefPtr<T> {
    /// Create a unique refptr from an already addrefed pointer obtained from
    /// FFI.
    ///
    /// The refcount must be one.
    ///
    /// The pointer must be valid and non null
    pub unsafe fn from_addrefed(ptr: *mut T) -> Self {
        UniqueRefPtr(RefPtr::from_addrefed(ptr))
    }

    /// Convert to a RefPtr so that it can be used.
    pub fn get(self) -> RefPtr<T> {
        self.0
    }
}

impl<T: RefCounted> Deref for RefPtr<T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.ptr }
    }
}

impl<T: RefCounted> Deref for UniqueRefPtr<T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.0.ptr }
    }
}

impl<T: RefCounted> DerefMut for UniqueRefPtr<T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.0.ptr }
    }
}

impl<T: RefCounted> structs::RefPtr<T> {
    /// Produces a Rust-side RefPtr from an FFI RefPtr, bumping the refcount.
    ///
    /// Must be called on a valid, non-null structs::RefPtr<T>.
    pub unsafe fn to_safe(&self) -> RefPtr<T> {
        debug_assert!(!self.mRawPtr.is_null());
        let r = RefPtr {
            ptr: self.mRawPtr,
            _marker: PhantomData,
        };
        r.addref();
        r
    }
    /// Produces a Rust-side RefPtr, consuming the existing one (and not bumping
    /// the refcount).
    pub unsafe fn into_safe(self) -> RefPtr<T> {
        debug_assert!(!self.mRawPtr.is_null());
        RefPtr {
            ptr: self.mRawPtr,
            _marker: PhantomData,
        }
    }

    /// Replace a structs::RefPtr<T> with a different one, appropriately
    /// addref/releasing.
    ///
    /// Both `self` and `other` must be valid, but can be null.
    ///
    /// Safe when called on an aliased pointer because the refcount in that case
    /// needs to be at least two.
    pub unsafe fn set(&mut self, other: &Self) {
        self.clear();
        if !other.mRawPtr.is_null() {
            *self = other.to_safe().forget();
        }
    }

    /// Clear an instance of the structs::RefPtr<T>, by releasing
    /// it and setting its contents to null.
    ///
    /// `self` must be valid, but can be null.
    pub unsafe fn clear(&mut self) {
        if !self.mRawPtr.is_null() {
            (*self.mRawPtr).release();
            self.mRawPtr = ptr::null_mut();
        }
    }

    /// Replace a `structs::RefPtr<T>` with a `RefPtr<T>`,
    /// consuming the `RefPtr<T>`, and releasing the old
    /// value in `self` if necessary.
    ///
    /// `self` must be valid, possibly null.
    pub fn set_move(&mut self, other: RefPtr<T>) {
        if !self.mRawPtr.is_null() {
            unsafe { (*self.mRawPtr).release(); }
        }
        *self = other.forget();
    }
}

impl<T: RefCounted> Drop for RefPtr<T> {
    fn drop(&mut self) {
        unsafe { self.release() }
    }
}

impl<T: RefCounted> Clone for RefPtr<T> {
    fn clone(&self) -> Self {
        self.addref();
        RefPtr {
            ptr: self.ptr,
            _marker: PhantomData,
        }
    }
}

impl<T: RefCounted> HeapSizeOf for RefPtr<T> {
    fn heap_size_of_children(&self) -> usize { 0 }
}

impl<T: RefCounted> PartialEq for RefPtr<T> {
    fn eq(&self, other: &Self) -> bool {
        self.ptr == other.ptr
    }
}

unsafe impl<T: ThreadSafeRefCounted> Send for RefPtr<T> {}
unsafe impl<T: ThreadSafeRefCounted> Sync for RefPtr<T> {}

// Companion of NS_DECL_THREADSAFE_FFI_REFCOUNTING.
//
// Gets you a free RefCounted impl implemented via FFI.
macro_rules! impl_threadsafe_refcount {
    ($t:ty, $addref:ident, $release:ident) => (
        unsafe impl RefCounted for $t {
            fn addref(&self) {
                unsafe { ::gecko_bindings::bindings::$addref(self as *const _ as *mut _) }
            }
            unsafe fn release(&self) {
                ::gecko_bindings::bindings::$release(self as *const _ as *mut _)
            }
        }
        unsafe impl ThreadSafeRefCounted for $t {}
    );
}

impl_threadsafe_refcount!(::gecko_bindings::structs::ThreadSafePrincipalHolder,
                          Gecko_AddRefPrincipalArbitraryThread,
                          Gecko_ReleasePrincipalArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::ThreadSafeURIHolder,
                          Gecko_AddRefURIArbitraryThread,
                          Gecko_ReleaseURIArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::nsStyleQuoteValues,
                          Gecko_AddRefQuoteValuesArbitraryThread,
                          Gecko_ReleaseQuoteValuesArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::nsCSSValueSharedList,
                          Gecko_AddRefCSSValueSharedListArbitraryThread,
                          Gecko_ReleaseCSSValueSharedListArbitraryThread);
/// A Gecko `ThreadSafePrincipalHolder` wrapped in a safe refcounted pointer, to
/// use during stylesheet parsing and style computation.
pub type GeckoArcPrincipal = RefPtr<::gecko_bindings::structs::ThreadSafePrincipalHolder>;

/// A Gecko `ThreadSafeURIHolder` wrapped in a safe refcounted pointer, to use
/// during stylesheet parsing and style computation.
pub type GeckoArcURI = RefPtr<::gecko_bindings::structs::ThreadSafeURIHolder>;
<|endoftext|>