<commit_before>use std::collections::HashMap;
use std::error;

use super::row::{Row, RowError};
use super::schema::{Schema, Type};
use super::field::Field;

pub enum StreamError {
    ValidationError(String),
    FieldNotFound(String),
    MissingRowId
}

impl From<RowError> for StreamError {
    fn from(err: RowError) -> StreamError {
        StreamError::MissingRowId
    }

}

pub struct Stream {
    max_id: u64,
    rows: Vec<Row>,
    schema: Schema,
}

/**
This is a weird DB.  There's no primary key, since everything is based off append only streaming

*/
impl Stream {
    pub fn new() -> Stream {
        let mut stream = Stream {
            max_id: 0,
            rows: Vec::new(),
            schema: Schema::new(),
        };
        stream.schema.add_type("_id", Type::Int);
        stream.schema.add_type("_created", Type::Timestamp);
        stream
    }

    /* we take a HashMap of String -> Field here
    * we're going to convert it to HashMap<u8, Field> for the Row struct
    */
    pub fn insert(&mut self, mut data: HashMap<String, Field>) -> Result<Row, StreamError> {
        // validate the inserted data
        let mut row_map : HashMap<u8, Field> = HashMap::new();
        for (key, val) in data.drain() {
            // get the field from the schema
            // TypeDef
            let tmp = try!(self.schema.get(&key)
                                      .ok_or(StreamError::FieldNotFound(key.to_string())));
            row_map.insert(tmp.id, val);

        }
        let row = try!(Row::new(row_map));
        Ok(row)
    }

}

#[cfg(test)]
mod tests {
    use super::Stream;
    use super::super::schema::{Schema, Type};
    use super::super::field::Field;
    use std::collections::HashMap;

    #[test]
    fn test_insert_works_normal_case() {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        let mut row = HashMap::new();
        row.insert("name".to_string(), Field::String("Jon".to_string()));
        let result = s.insert(row);

    }
}<commit_msg>adding row builder which will help simplify development<commit_after>use std::collections::HashMap;
use std::error;

use super::row::{Row, RowError};
use super::schema::{Schema, Type};
use super::field::Field;

pub enum StreamError {
    ValidationError(String),
    FieldNotFound(String),
    MissingRowId
}

impl From<RowError> for StreamError {
    fn from(err: RowError) -> StreamError {
        StreamError::MissingRowId
    }

}

pub struct RowBuilder {
    data: HashMap<String, Field>,
}

impl RowBuilder {
    fn new() -> RowBuilder {
        RowBuilder{data:HashMap::new()}
    }
    fn set_string(&mut self, key: &str, val: &str) {

    }
    fn commit(&mut self) {

    }
}

pub struct Stream {
    max_id: u64,
    rows: Vec<Row>,
    schema: Schema,
}

/**
This is a weird DB.  There's no primary key, since everything is based off append only streaming

*/
impl Stream {
    pub fn new() -> Stream {
        let mut stream = Stream {
            max_id: 0,
            rows: Vec::new(),
            schema: Schema::new(),
        };
        stream.schema.add_type("_id", Type::Int);
        stream.schema.add_type("_created", Type::Timestamp);
        stream
    }

    /* we take a HashMap of String -> Field here
    * we're going to convert it to HashMap<u8, Field> for the Row struct
    */
    pub fn insert(&mut self, mut data: HashMap<String, Field>) -> Result<Row, StreamError> {
        // validate the inserted data
        let mut row_map : HashMap<u8, Field> = HashMap::new();
        for (key, val) in data.drain() {
            // get the field from the schema
            // TypeDef
            let tmp = try!(self.schema.get(&key)
                                      .ok_or(StreamError::FieldNotFound(key.to_string())));
            row_map.insert(tmp.id, val);

        }
        let row = try!(Row::new(row_map));
        Ok(row)
    }
    pub fn builder(&self) -> RowBuilder {
        let builder = RowBuilder::new();
        builder
    }

}

#[cfg(test)]
mod tests {
    use super::Stream;
    use super::super::schema::{Schema, Type};
    use super::super::field::Field;
    use std::collections::HashMap;

    fn get_stream() -> Stream {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        s.schema.add_type("age", Type::Int);
        s.schema.add_type("created", Type::Timestamp);
        s

    }

    #[test]
    fn test_insert_works_normal_case() {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        let mut row = HashMap::new();
        row.insert("name".to_string(), Field::String("Jon".to_string()));
        let result = s.insert(row);

    }

    fn test_builder() {
        let mut s = get_stream();
        let mut row = s.builder();
        row.set_string("name", "value");
        row.commit();
    }
}<|endoftext|>


<commit_before>use libc::{c_int, c_longlong, c_char, c_void};
use std::mem;
use std::sync::{Arc, Once, ONCE_INIT};
use std::cell::Cell;

/// Typedef for initialization function.
type EnergyMonInitFn = extern fn(*mut EMImpl) -> c_int;
/// Typedef for read function.
type EnergyMonReadTotalFn = extern fn(*mut EMImpl) -> c_longlong;
/// Typedef for cleanup function.
type EnergyMonFinishFn = extern fn(*mut EMImpl) -> c_int;
/// Typedef for function to get human-readable name.
type EnergyMonGetSourceFn = extern fn(*mut c_char) -> *mut c_char;

#[allow(raw_pointer_derive)]
#[derive(Clone, Copy)]
#[repr(C)]
/// Representation of native C struct `em_impl`.
struct EMImpl {
    /// Native C function type signature that initializes the `EMImpl`.
    finit: EnergyMonInitFn,
    /// Native C function type signature that reads energy data from the `EMImpl`.
    fread: EnergyMonReadTotalFn,
    /// Native C function type signature that cleans up the `EMImpl`.
    ffinish: EnergyMonFinishFn,
    /// Native C function type signature that gets the `EMImpl`'s human-readable name.
    fsource: EnergyMonGetSourceFn,
    /// Native C pointer used by the underlying `EMImpl` implementation for storing state.
    state: *mut c_void,
}

extern {
    /// Native C function that fills in the EMImpl struct values and may allocate other resources.
    fn em_impl_get(em: *mut EMImpl) -> c_int;
}

impl EMImpl {
    /// Create an `EMImpl` which represents a C struct.
    fn new() -> Result<EMImpl, &'static str> {
        unsafe {
            let mut em: EMImpl = mem::uninitialized();
            match em_impl_get(&mut em) {
                0 => Ok(em),
                _ => Err("Failed to create EMImpl"),
            }
        }
    }

    /// Initialize the `EMImpl` - may allocate more resources and/or start threads.
    fn init(&mut self) -> Result<(), &'static str> {
        match (self.finit)(self) {
            0 => Ok(()),
            _ => Err("Failed to initialize EMImpl"),
        }
    }

    /// Read the total energy from the `EMImpl`.
    fn read(&mut self) -> i64 {
        (self.fread)(self)
    }

    /// Cleanup the `EMImpl` - may deallocate associated resources and/or stop threads.
    fn finish(&mut self) -> Result<(), &'static str> {
        match (self.ffinish)(self) {
            0 => Ok(()),
            _ => Err("Failed to cleanup EMImpl"),
        }
    }

    /// Utility function to get a human-readable name of the `EMImpl`'s source.
    fn source(&mut self) -> String {
        const BUFSIZE: usize = 100;
        let mut buf: [c_char; BUFSIZE] = [0; BUFSIZE];
        let ret: *mut c_char = (self.fsource)(buf.as_mut_ptr());
        if ret.is_null() {
            return "UNKNOWN".to_owned();
        }
        let buf: &[u8] = unsafe {
            mem::transmute::<&[c_char], &[u8]>(&buf)
        };
        String::from_utf8_lossy(buf).into_owned()
    }
}

/// A basic energy monitor.
pub struct EnergyMon {
    /// The native C struct.
    em: EMImpl,
}

impl EnergyMon {
    /// Create and initialize an `EnergyMon`.
    pub fn new() -> Result<EnergyMon, &'static str> {
        println!("Initializing energy monitor");
        let mut em = try!{EMImpl::new()};
        try!{em.init()};
        Ok(EnergyMon { em: em })
    }

    /// Read the total energy from the `EnergyMon`.
    pub fn read(&mut self) -> i64 {
        self.em.read()
    }

    /// Get a human-readable name of the `EnergyMon`'s source.
    pub fn source(&mut self) -> String {
        self.em.source()
    }
}

impl Drop for EnergyMon {
    fn drop(&mut self) {
        println!("Finishing energy monitor");
        let _ = self.em.finish();
    }
}

#[derive(Clone)]
pub struct SingletonEnergyMon {
    em: Arc<Cell<EMImpl>>,
}

impl SingletonEnergyMon {
    pub fn instance() -> Option<SingletonEnergyMon> {
        static mut EM: *const SingletonEnergyMon = 0 as *const SingletonEnergyMon;
        static ONCE: Once = ONCE_INIT;

        unsafe {
            ONCE.call_once(|| {
                println!("Initializing singleton energy monitor");
                let mut em = match EMImpl::new() {
                    Ok(e) => e,
                    Err(e) => {
                        println!("{}", e);
                        return;
                    },
                };
                match em.init() {
                    Ok(_) => (),
                    Err(e) => {
                        println!("{}", e);
                        let _ = em.finish();
                        return;
                    },
                }
                let sem: SingletonEnergyMon = SingletonEnergyMon {
                    em: Arc::new(Cell::new(em))
                };
                // put it on the heap
                EM = mem::transmute(Box::new(sem));
            });
            if EM.is_null() {
                None
            } else {
                Some((*EM).clone())
            }
        }
    }

    pub fn read(&self) -> i64 {
        self.em.get().read()
    }

    pub fn source(&self) -> String {
        self.em.get().source()
    }

    pub unsafe fn destroy(&self) {
        println!("Finishing singleton energy monitor");
        let _ = self.em.get().finish();
    }
}

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

    #[test]
    fn test_interface() {
        let mut em: EnergyMon = EnergyMon::new().unwrap();
        let val = em.read();
        assert!(val >= 0);
        println!("Read {} from {}", val, em.source());
    }

    #[test]
    fn test_singleton() {
        for _ in 0..2 {
            let sem: SingletonEnergyMon = SingletonEnergyMon::instance().unwrap();
            let val = sem.read();
            println!("Read {} from {} singleton", val, sem.source());
        }
        unsafe {
            SingletonEnergyMon::instance().unwrap().destroy();
        }
    }

}
<commit_msg>Added new function to get refresh interval<commit_after>use libc::{c_int, c_longlong, c_ulonglong, c_char, c_void};
use std::mem;
use std::sync::{Arc, Once, ONCE_INIT};
use std::cell::Cell;

/// Typedef for initialization function.
type EnergyMonInitFn = extern fn(*mut EMImpl) -> c_int;
/// Typedef for read function.
type EnergyMonReadTotalFn = extern fn(*mut EMImpl) -> c_longlong;
/// Typedef for cleanup function.
type EnergyMonFinishFn = extern fn(*mut EMImpl) -> c_int;
/// Typedef for function to get human-readable name.
type EnergyMonGetSourceFn = extern fn(*mut c_char) -> *mut c_char;
/// Typedef for function to get refresh interval.
type EnergyMonGetIntervalFn = extern fn(*const EMImpl) -> c_ulonglong;

#[allow(raw_pointer_derive)]
#[derive(Clone, Copy)]
#[repr(C)]
/// Representation of native C struct `em_impl`.
struct EMImpl {
    /// Native C function type signature that initializes the `EMImpl`.
    finit: EnergyMonInitFn,
    /// Native C function type signature that reads energy data from the `EMImpl`.
    fread: EnergyMonReadTotalFn,
    /// Native C function type signature that cleans up the `EMImpl`.
    ffinish: EnergyMonFinishFn,
    /// Native C function type signature that gets the `EMImpl`'s human-readable name.
    fsource: EnergyMonGetSourceFn,
    /// Native C function type signature that gets the `EMImpl`'s refresh interval.
    finterval: EnergyMonGetIntervalFn,
    /// Native C pointer used by the underlying `EMImpl` implementation for storing state.
    state: *mut c_void,
}

extern {
    /// Native C function that fills in the EMImpl struct values and may allocate other resources.
    fn em_impl_get(em: *mut EMImpl) -> c_int;
}

impl EMImpl {
    /// Create an `EMImpl` which represents a C struct.
    fn new() -> Result<EMImpl, &'static str> {
        unsafe {
            let mut em: EMImpl = mem::uninitialized();
            match em_impl_get(&mut em) {
                0 => Ok(em),
                _ => Err("Failed to create EMImpl"),
            }
        }
    }

    /// Initialize the `EMImpl` - may allocate more resources and/or start threads.
    fn init(&mut self) -> Result<(), &'static str> {
        match (self.finit)(self) {
            0 => Ok(()),
            _ => Err("Failed to initialize EMImpl"),
        }
    }

    /// Read the total energy from the `EMImpl`.
    fn read(&mut self) -> i64 {
        (self.fread)(self)
    }

    /// Cleanup the `EMImpl` - may deallocate associated resources and/or stop threads.
    fn finish(&mut self) -> Result<(), &'static str> {
        match (self.ffinish)(self) {
            0 => Ok(()),
            _ => Err("Failed to cleanup EMImpl"),
        }
    }

    /// Utility function to get a human-readable name of the `EMImpl`'s source.
    fn source(&mut self) -> String {
        const BUFSIZE: usize = 100;
        let mut buf: [c_char; BUFSIZE] = [0; BUFSIZE];
        let ret: *mut c_char = (self.fsource)(buf.as_mut_ptr());
        if ret.is_null() {
            return "UNKNOWN".to_owned();
        }
        let buf: &[u8] = unsafe {
            mem::transmute::<&[c_char], &[u8]>(&buf)
        };
        String::from_utf8_lossy(buf).into_owned()
    }

    /// Get the refresh interval from the `EMImpl`.
    fn interval(&self) -> u64 {
        (self.finterval)(self)
    }
}

/// A basic energy monitor.
pub struct EnergyMon {
    /// The native C struct.
    em: EMImpl,
}

impl EnergyMon {
    /// Create and initialize an `EnergyMon`.
    pub fn new() -> Result<EnergyMon, &'static str> {
        println!("Initializing energy monitor");
        let mut em = try!{EMImpl::new()};
        try!{em.init()};
        Ok(EnergyMon { em: em })
    }

    /// Read the total energy from the `EnergyMon`.
    pub fn read(&mut self) -> i64 {
        self.em.read()
    }

    /// Get a human-readable name of the `EnergyMon`'s source.
    pub fn source(&mut self) -> String {
        self.em.source()
    }

    /// Get the refresh interval for the `EnergyMon`.
    pub fn interval(&self) -> u64 {
        self.em.interval()
    }
}

impl Drop for EnergyMon {
    fn drop(&mut self) {
        println!("Finishing energy monitor");
        let _ = self.em.finish();
    }
}

#[derive(Clone)]
pub struct SingletonEnergyMon {
    em: Arc<Cell<EMImpl>>,
}

impl SingletonEnergyMon {
    pub fn instance() -> Option<SingletonEnergyMon> {
        static mut EM: *const SingletonEnergyMon = 0 as *const SingletonEnergyMon;
        static ONCE: Once = ONCE_INIT;

        unsafe {
            ONCE.call_once(|| {
                println!("Initializing singleton energy monitor");
                let mut em = match EMImpl::new() {
                    Ok(e) => e,
                    Err(e) => {
                        println!("{}", e);
                        return;
                    },
                };
                match em.init() {
                    Ok(_) => (),
                    Err(e) => {
                        println!("{}", e);
                        let _ = em.finish();
                        return;
                    },
                }
                let sem: SingletonEnergyMon = SingletonEnergyMon {
                    em: Arc::new(Cell::new(em))
                };
                // put it on the heap
                EM = mem::transmute(Box::new(sem));
            });
            if EM.is_null() {
                None
            } else {
                Some((*EM).clone())
            }
        }
    }

    pub fn read(&self) -> i64 {
        self.em.get().read()
    }

    pub fn source(&self) -> String {
        self.em.get().source()
    }

    pub fn interval(&self) -> u64 {
        self.em.get().interval()
    }

    pub unsafe fn destroy(&self) {
        println!("Finishing singleton energy monitor");
        let _ = self.em.get().finish();
    }
}

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

    #[test]
    fn test_interface() {
        let mut em: EnergyMon = EnergyMon::new().unwrap();
        let val = em.read();
        assert!(val >= 0);
        println!("Read {} from {} with refresh interval {}", val, em.source(), em.interval());
    }

    #[test]
    fn test_singleton() {
        for _ in 0..2 {
            let sem: SingletonEnergyMon = SingletonEnergyMon::instance().unwrap();
            let val = sem.read();
            println!("Read {} from {} singleton with refresh interval {}", val, sem.source(),
                     sem.interval());
        }
        unsafe {
            SingletonEnergyMon::instance().unwrap().destroy();
        }
    }

}
<|endoftext|>


<commit_before>use std::error;
use std::fs;
use std::io;
use std::io::{Read,Write};
use std::mem;

use fat::RootEntry;
use fat::BIOSParam;

// TODO: Kill me
const SECTORS_PER_DATA_AREA: usize = 2847;

// Always the same
const SECTORS_PER_ROOT: usize = 14;
const BYTES_PER_ROOT_ENTRY: usize = 32;

#[test]
fn test_root_entry_size() {
    assert_eq!(mem::size_of::<RootEntry>(), BYTES_PER_ROOT_ENTRY);
}

#[derive(Debug)]
pub struct Image {
    boot_sector: Vec<u8>,
    fat_1: Vec<u8>,
    fat_2: Vec<u8>,
    root_dir: Vec<u8>,
    data_area: Vec<u8>,
    bpb_data: BIOSParam,
}

#[allow(dead_code)]
impl Image {
    /// Create a new blank FAT Image from a defined BPB
    fn new(bpb: BIOSParam) -> Image {
        let boot_sector_size = bpb.bytes_per_sector as usize * bpb.reserved_sectors as usize;
        let bytes_per_fat = (bpb.sectors_per_fat * bpb.bytes_per_sector as u32) as usize;
        let bytes_per_root = SECTORS_PER_ROOT * bpb.bytes_per_sector as usize;
        let data_offset = bpb.bytes_per_sector as usize + (bytes_per_fat as usize * 2) + bytes_per_root as usize;
        let bytes_per_data_area = bpb.len() - data_offset;
        Image {
            boot_sector: vec![0; boot_sector_size],
            fat_1: vec![0; bytes_per_fat],
            fat_2: vec![0; bytes_per_fat],
            root_dir: vec![0; bytes_per_root],
            data_area: vec![0; bytes_per_data_area],
            bpb_data: bpb,
        }
    }

    /// Create a new FAT Image from the specified file.
    pub fn from(image_fn: String)
        -> Result<Image, Box<error::Error>>
    {
        let bpb = BIOSParam::from(image_fn.clone())?;
        let mut file = fs::File::open(image_fn)?;
        let mut image = Image::new(bpb);

        try!(file.read_exact(&mut image.boot_sector));
        try!(file.read_exact(&mut image.fat_1));
        try!(file.read_exact(&mut image.fat_2));
        try!(file.read_exact(&mut image.root_dir));
        try!(file.read_exact(&mut image.data_area));

        Ok(image)
    }

    /// Save the FAT filesystem image to the specified file.
    pub fn save(&self, image_fn: String)
        -> Result<(), io::Error>
    {
        let mut file = fs::File::create(image_fn)?;

        try!(file.write_all(&self.boot_sector));
        try!(file.write_all(&self.fat_1));
        try!(file.write_all(&self.fat_2));
        try!(file.write_all(&self.root_dir));
        try!(file.write_all(&self.data_area));

        Ok(())
    }

    /// Extract the BIOS Parameter Block (BPB) from the FAT filesystem.
    pub fn bios_parameter(&self) -> BIOSParam {
        self.bpb_data.clone()
    }

    /// FAT sector size in bytes.
    pub fn sector_size(&self) -> usize {
        self.bpb_data.bytes_per_sector as usize
    }

    // TODO: Make this an iterator
    pub fn root_entries(&self) -> Vec<RootEntry> {
        self.root_dir
            .chunks(BYTES_PER_ROOT_ENTRY)
            .map(|chunk| {
                let mut entry_bytes = [0; BYTES_PER_ROOT_ENTRY];
                entry_bytes.clone_from_slice(chunk);

                let entry: RootEntry;
                unsafe { entry = mem::transmute(entry_bytes); }
                entry
            })
            .filter(|entry| { entry.filename[0] != 0xe5 })
            .take_while(|entry| { entry.filename[0] != 0 })
            .collect::<Vec<RootEntry>>()
    }

    /// Get the RootEntry for the specified file within the Image.
    pub fn get_file_entry(&self, filename: String)
        -> Result<RootEntry, Box<error::Error>>
    {
        let entries = self.root_entries();
        for entry in entries {
            let entry_name: String;
            match entry.filename() {
                Ok(name) => entry_name = name,
                Err(_) => continue,
            }

            if entry_name.to_lowercase() == filename.to_lowercase() {
                return Ok(entry);
            }
        }

        Err(From::from(format!("file {} not found", filename)))
    }

    /// Create a new RootEntry within the Image with the specified filename.
    pub fn create_file_entry(&self, filename: String)
        -> Result<(RootEntry, u16), Box<error::Error>>
    {
        for (index, e) in self.root_entries().iter().enumerate() {
            if !e.is_free() { continue; }

            let mut entry = RootEntry::new();
            try!(entry.set_filename(filename));
            return Ok((entry.clone(), index as u16));
        }

        Err(From::from("no free entries"))
    }

    pub fn save_file_entry(&mut self, entry: RootEntry, index: u16)
        -> Result<(), Box<error::Error>>
    {
        let entry_bytes: [u8; BYTES_PER_ROOT_ENTRY];
        unsafe { entry_bytes = mem::transmute(entry); }

        self.root_dir[
            index as usize * BYTES_PER_ROOT_ENTRY ..
            (index as usize + 1) * BYTES_PER_ROOT_ENTRY
        ].clone_from_slice(&entry_bytes[..]);
        Ok(())
    }

    pub fn fat_entries<'a>(&'a self)
        -> Box<Iterator<Item=(usize, u16)> + 'a>
    {
        Box::new(
            self.fat_1
            .windows(2)
            .enumerate()
            .filter_map(|(i, w)|
                if i % 3 == 2 {
                    None
                } else {
                    let val = if i % 3 == 0 {
                        ((w[1] as u16 & 0xf) << 8) | w[0] as u16
                    } else {
                        (w[1] as u16 & 0xf0) | ((w[1] as u16) << 4)
                    };
                    Some((i, val))
                }
            )
        )
    }

    pub fn get_fat_entry(&self, cluster_num: u16) -> u16 {
        let offset: usize = cluster_num as usize * 3 / 2;
        let byte_1: u16 = self.fat_1[offset] as u16;
        let byte_2: u16 = self.fat_1[offset + 1] as u16;

        if cluster_num % 2 == 0 { byte_1 | ((byte_2 & 0x0f) << 8) }
        else                    { (byte_1 >> 4) | (byte_2 << 4) }
    }

    pub fn get_free_fat_entry(&self) -> Option<usize> {
        self.fat_entries()
            .filter(|&(_, e)| e == 0)
            .map(|(i, _)| i + 2)
            .nth(0)
    }

    pub fn write_data_sector(&mut self, sector: usize, data: &[u8])
        -> Result<(), Box<error::Error>>
    {
        let sector = sector - 2;
        if sector >= SECTORS_PER_DATA_AREA {
            return Err(From::from(format!("sector {} too high to write to", sector)))
        }

        let mut target_slice = &mut self.data_area[
            self.bpb_data.bytes_per_sector as usize * sector ..
            self.bpb_data.bytes_per_sector as usize * (sector + 1)
        ];

        target_slice.copy_from_slice(data);
        Ok(())
    }
}
<commit_msg>fat/image: Dynamic data area length<commit_after>use std::error;
use std::fs;
use std::io;
use std::io::{Read,Write};
use std::mem;

use fat::RootEntry;
use fat::BIOSParam;

// Always the same
const SECTORS_PER_ROOT: usize = 14;
const BYTES_PER_ROOT_ENTRY: usize = 32;

#[test]
fn test_root_entry_size() {
    assert_eq!(mem::size_of::<RootEntry>(), BYTES_PER_ROOT_ENTRY);
}

#[derive(Debug)]
pub struct Image {
    boot_sector: Vec<u8>,
    fat_1: Vec<u8>,
    fat_2: Vec<u8>,
    root_dir: Vec<u8>,
    data_area: Vec<u8>,
    bpb_data: BIOSParam,
}

#[allow(dead_code)]
impl Image {
    /// Create a new blank FAT Image from a defined BPB
    fn new(bpb: BIOSParam, length: usize) -> Image {
        let boot_sector_size = bpb.bytes_per_sector as usize * bpb.reserved_sectors as usize;
        let bytes_per_fat = (bpb.sectors_per_fat * bpb.bytes_per_sector as u32) as usize;
        let bytes_per_root = SECTORS_PER_ROOT * bpb.bytes_per_sector as usize;
        let data_offset = boot_sector_size as usize + (bytes_per_fat * 2) as usize + bytes_per_root as usize;
        let bytes_per_data_area = length - data_offset;
        Image {
            boot_sector: vec![0; boot_sector_size],
            fat_1: vec![0; bytes_per_fat],
            fat_2: vec![0; bytes_per_fat],
            root_dir: vec![0; bytes_per_root],
            data_area: vec![0; bytes_per_data_area],
            bpb_data: bpb,
        }
    }

    /// Create a new FAT Image from the specified file.
    pub fn from(image_fn: String)
        -> Result<Image, Box<error::Error>>
    {
        let metadata = fs::metadata(image_fn.clone())?;
        let bpb = BIOSParam::from(image_fn.clone())?;

        let mut file = fs::File::open(image_fn)?;
        let mut image = Image::new(bpb, metadata.len() as usize);

        try!(file.read_exact(&mut image.boot_sector));
        try!(file.read_exact(&mut image.fat_1));
        try!(file.read_exact(&mut image.fat_2));
        try!(file.read_exact(&mut image.root_dir));
        try!(file.read_exact(&mut image.data_area));

        Ok(image)
    }

    /// Save the FAT filesystem image to the specified file.
    pub fn save(&self, image_fn: String)
        -> Result<(), io::Error>
    {
        let mut file = fs::File::create(image_fn)?;

        try!(file.write_all(&self.boot_sector));
        try!(file.write_all(&self.fat_1));
        try!(file.write_all(&self.fat_2));
        try!(file.write_all(&self.root_dir));
        try!(file.write_all(&self.data_area));

        Ok(())
    }

    /// Extract the BIOS Parameter Block (BPB) from the FAT filesystem.
    pub fn bios_parameter(&self) -> BIOSParam {
        self.bpb_data.clone()
    }

    /// FAT sector size in bytes.
    pub fn sector_size(&self) -> usize {
        self.bpb_data.bytes_per_sector as usize
    }

    // TODO: Make this an iterator
    pub fn root_entries(&self) -> Vec<RootEntry> {
        self.root_dir
            .chunks(BYTES_PER_ROOT_ENTRY)
            .map(|chunk| {
                let mut entry_bytes = [0; BYTES_PER_ROOT_ENTRY];
                entry_bytes.clone_from_slice(chunk);

                let entry: RootEntry;
                unsafe { entry = mem::transmute(entry_bytes); }
                entry
            })
            .filter(|entry| { entry.filename[0] != 0xe5 })
            .take_while(|entry| { entry.filename[0] != 0 })
            .collect::<Vec<RootEntry>>()
    }

    /// Get the RootEntry for the specified file within the Image.
    pub fn get_file_entry(&self, filename: String)
        -> Result<RootEntry, Box<error::Error>>
    {
        let entries = self.root_entries();
        for entry in entries {
            let entry_name: String;
            match entry.filename() {
                Ok(name) => entry_name = name,
                Err(_) => continue,
            }

            if entry_name.to_lowercase() == filename.to_lowercase() {
                return Ok(entry);
            }
        }

        Err(From::from(format!("file {} not found", filename)))
    }

    /// Create a new RootEntry within the Image with the specified filename.
    pub fn create_file_entry(&self, filename: String)
        -> Result<(RootEntry, u16), Box<error::Error>>
    {
        for (index, e) in self.root_entries().iter().enumerate() {
            if !e.is_free() { continue; }

            let mut entry = RootEntry::new();
            try!(entry.set_filename(filename));
            return Ok((entry.clone(), index as u16));
        }

        Err(From::from("no free entries"))
    }

    pub fn save_file_entry(&mut self, entry: RootEntry, index: u16)
        -> Result<(), Box<error::Error>>
    {
        let entry_bytes: [u8; BYTES_PER_ROOT_ENTRY];
        unsafe { entry_bytes = mem::transmute(entry); }

        self.root_dir[
            index as usize * BYTES_PER_ROOT_ENTRY ..
            (index as usize + 1) * BYTES_PER_ROOT_ENTRY
        ].clone_from_slice(&entry_bytes[..]);
        Ok(())
    }

    pub fn fat_entries<'a>(&'a self)
        -> Box<Iterator<Item=(usize, u16)> + 'a>
    {
        Box::new(
            self.fat_1
            .windows(2)
            .enumerate()
            .filter_map(|(i, w)|
                if i % 3 == 2 {
                    None
                } else {
                    let val = if i % 3 == 0 {
                        ((w[1] as u16 & 0xf) << 8) | w[0] as u16
                    } else {
                        (w[1] as u16 & 0xf0) | ((w[1] as u16) << 4)
                    };
                    Some((i, val))
                }
            )
        )
    }

    pub fn get_fat_entry(&self, cluster_num: u16) -> u16 {
        let offset: usize = cluster_num as usize * 3 / 2;
        let byte_1: u16 = self.fat_1[offset] as u16;
        let byte_2: u16 = self.fat_1[offset + 1] as u16;

        if cluster_num % 2 == 0 { byte_1 | ((byte_2 & 0x0f) << 8) }
        else                    { (byte_1 >> 4) | (byte_2 << 4) }
    }

    pub fn get_free_fat_entry(&self) -> Option<usize> {
        self.fat_entries()
            .filter(|&(_, e)| e == 0)
            .map(|(i, _)| i + 2)
            .nth(0)
    }

    pub fn write_data_sector(&mut self, sector: usize, data: &[u8])
        -> Result<(), Box<error::Error>>
    {
        let sector = sector - 2;
        let bytes = sector * self.bpb_data.bytes_per_sector as usize;
        if bytes >= self.data_area.len() {
            return Err(From::from(format!("sector {} too high to write to", sector)))
        }

        let mut target_slice = &mut self.data_area[
            self.bpb_data.bytes_per_sector as usize * sector ..
            self.bpb_data.bytes_per_sector as usize * (sector + 1)
        ];

        target_slice.copy_from_slice(data);
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::hash::BuildHasher;
use std::hash::BuildHasherDefault;
use std::hash::Hasher;
use std::collections::HashMap;
use std::collections::BinaryHeap;
use std::fmt::{self};
use twox_hash::XxHash64;

/// As a convenience, rust-hash-ring provides a default struct to hold node
/// information. It is optional and you can define your own.
#[derive(Clone, Debug, PartialEq)]
pub struct NodeInfo {
    pub host: &'static str,
    pub port: u16,
}

impl fmt::Display for NodeInfo {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(fmt, "{}:{}", self.host, self.port)
    }
}

type XxHash64Hasher = BuildHasherDefault<XxHash64>;

/// HashRing
pub struct HashRing<T, S = XxHash64Hasher> {
    replicas: isize,
    ring: HashMap<u64, T>,
    sorted_keys: Vec<u64>,
    hash_builder: S,
}

impl<T: ToString + Clone> HashRing<T, XxHash64Hasher> {
    /// Creates a new hash ring with the specified nodes.
    /// Replicas is the number of virtual nodes each node has to make a better distribution.
    pub fn new(nodes: Vec<T>, replicas: isize) -> HashRing<T, XxHash64Hasher> {
        return HashRing::with_hasher(nodes, replicas, XxHash64Hasher::default());
    }
}

impl<T, S> HashRing<T, S>
where
    T: ToString + Clone,
    S: BuildHasher,
{

    pub fn with_hasher(nodes: Vec<T>, replicas: isize, hash_builder: S) -> HashRing<T, S> {
        let mut new_hash_ring: HashRing<T, S> = HashRing {
            replicas: replicas,
            ring: HashMap::new(),
            sorted_keys: Vec::new(),
            hash_builder: hash_builder,
        };

        for i in 0..nodes.len() {
            let n = &nodes[i];
            new_hash_ring.add_node(n);
        }
        return new_hash_ring;
    }

    /// Adds a node to the hash ring
    pub fn add_node(&mut self, node: &T) {
        for i in 0..self.replicas {
            let key = self.gen_key(format!("{}:{}", node.to_string(), i));
            self.ring.insert(key.clone(), (*node).clone());
            self.sorted_keys.push(key.clone());
        }

        self.sorted_keys = BinaryHeap::from(self.sorted_keys.clone()).into_sorted_vec();
    }

    /// Deletes a node from the hash ring
    pub fn remove_node(&mut self, node: &T) {
        for i in 0..self.replicas {
            let key = self.gen_key(format!("{}:{}", node.to_string(), i));
            if !self.ring.contains_key(&key) {
                return;
            }
            self.ring.remove(&key);
            let mut index = 0;
            for j in 0..self.sorted_keys.len() {
                if self.sorted_keys[j] == key {
                    index = j;
                    break;
                }
            }
            self.sorted_keys.remove(index);
        }
    }

    /// Gets the node a specific key belongs to
    pub fn get_node(&self, key: String) -> Option<&T> {
        if self.sorted_keys.is_empty() {
            return None;
        }

        let generated_key = self.gen_key(key);
        let nodes = self.sorted_keys.clone();

        for i in 0..nodes.len() {
            let node = &nodes[i];
            if generated_key <= *node {
                return Some(self.ring.get(node).unwrap());
            }
        }

        let node = &nodes[0];
        return Some(self.ring.get(node).unwrap());
    }

    /// Generates a key from a string value
    fn gen_key(&self, key: String) -> u64 {
        let mut hasher = self.hash_builder.build_hasher();
        hasher.write(key.as_bytes());
        return hasher.finish();
    }
}

#[cfg(test)]
mod test {
    use std::hash::Hasher;
    use std::hash::BuildHasherDefault;
    use hash_ring::{NodeInfo, HashRing};

    // Defines a NodeInfo for a localhost address with a given port.
    fn node(port: u16) -> NodeInfo {
        NodeInfo {
            host: "localhost",
            port,
        }
    }

    #[test]
    fn test_empty_ring() {
        let hash_ring: HashRing<NodeInfo> = HashRing::new(vec![], 10);
        assert_eq!(None, hash_ring.get_node("hello".to_string()));
    }

    #[test]
    fn test_default_nodes() {
        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let mut hash_ring: HashRing<NodeInfo> = HashRing::new(nodes, 10);

        assert_eq!(Some(&node(15326)), hash_ring.get_node("hello".to_string()));
        assert_eq!(Some(&node(15327)), hash_ring.get_node("dude".to_string()));
        assert_eq!(Some(&node(15324)), hash_ring.get_node("two".to_string()));

        hash_ring.remove_node(&node(15329));
        assert_eq!(Some(&node(15326)), hash_ring.get_node("hello".to_string()));

        hash_ring.add_node(&node(15329));
        assert_eq!(Some(&node(15326)), hash_ring.get_node("hello".to_string()));
    }

    #[derive(Clone)]
    struct CustomNodeInfo {
        pub host: &'static str,
        pub port: u16,
    }

    impl ToString for CustomNodeInfo {
        fn to_string(&self) -> String {
            format!("{}:{}", self.host, self.port)
        }
    }

    #[test]
    fn test_custom_nodes() {
        let mut nodes: Vec<CustomNodeInfo> = Vec::new();
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15324,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15325,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15326,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15327,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15328,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15329,
        });

        let mut hash_ring: HashRing<CustomNodeInfo> = HashRing::new(nodes, 10);

        assert_eq!(
            Some("localhost:15326".to_string()),
            hash_ring.get_node("hello".to_string()).map(
                |x| x.to_string(),
            )
        );
        assert_eq!(
            Some("localhost:15327".to_string()),
            hash_ring.get_node("dude".to_string()).map(
                |x| x.to_string(),
            )
        );

        hash_ring.remove_node(&CustomNodeInfo {
            host: "localhost",
            port: 15329,
        });
        assert_eq!(
            Some("localhost:15326".to_string()),
            hash_ring.get_node("hello".to_string()).map(
                |x| x.to_string(),
            )
        );

        hash_ring.add_node(&CustomNodeInfo {
            host: "localhost",
            port: 15329,
        });
        assert_eq!(
            Some("localhost:15326".to_string()),
            hash_ring.get_node("hello".to_string()).map(
                |x| x.to_string(),
            )
        );
    }

    #[test]
    fn test_remove_actual_node() {
        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let mut hash_ring: HashRing<NodeInfo> = HashRing::new(nodes, 10);

        // This should be num nodes * num replicas
        assert_eq!(60, hash_ring.sorted_keys.len());
        assert_eq!(60, hash_ring.ring.len());

        hash_ring.remove_node(&node(15326));

        // This should be num nodes * num replicas
        assert_eq!(50, hash_ring.sorted_keys.len());
        assert_eq!(50, hash_ring.ring.len());
    }

    #[test]
    fn test_remove_non_existent_node() {
        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let mut hash_ring: HashRing<NodeInfo> = HashRing::new(nodes, 10);

        hash_ring.remove_node(&node(15330));

        // This should be num nodes * num replicas
        assert_eq!(60, hash_ring.sorted_keys.len());
        assert_eq!(60, hash_ring.ring.len());
    }

    #[test]
    fn test_custom_hasher() {
        #[derive(Default)]
        struct ConstantHasher;

        impl Hasher for ConstantHasher {
            fn write(&mut self, _bytes: &[u8]) {
                // Do nothing
            }

            fn finish(&self) -> u64 {
                return 1;
            }
        }

        type ConstantBuildHasher = BuildHasherDefault<ConstantHasher>;

        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let hash_ring: HashRing<NodeInfo, ConstantBuildHasher> = HashRing::with_hasher(nodes, 10, ConstantBuildHasher::default());

        assert_eq!(Some(&node(15329)), hash_ring.get_node("hello".to_string()));
        assert_eq!(Some(&node(15329)), hash_ring.get_node("dude".to_string()));
        assert_eq!(Some(&node(15329)), hash_ring.get_node("two".to_string()));
    }
}
<commit_msg>Fix clippy suggestions in code<commit_after>use std::hash::BuildHasher;
use std::hash::BuildHasherDefault;
use std::hash::Hasher;
use std::collections::HashMap;
use std::collections::BinaryHeap;
use std::fmt::{self};
use twox_hash::XxHash64;

/// As a convenience, rust-hash-ring provides a default struct to hold node
/// information. It is optional and you can define your own.
#[derive(Clone, Debug, PartialEq)]
pub struct NodeInfo {
    pub host: &'static str,
    pub port: u16,
}

impl fmt::Display for NodeInfo {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(fmt, "{}:{}", self.host, self.port)
    }
}

type XxHash64Hasher = BuildHasherDefault<XxHash64>;

/// HashRing
pub struct HashRing<T, S = XxHash64Hasher> {
    replicas: isize,
    ring: HashMap<u64, T>,
    sorted_keys: Vec<u64>,
    hash_builder: S,
}

impl<T: ToString + Clone> HashRing<T, XxHash64Hasher> {
    /// Creates a new hash ring with the specified nodes.
    /// Replicas is the number of virtual nodes each node has to make a better distribution.
    pub fn new(nodes: Vec<T>, replicas: isize) -> HashRing<T, XxHash64Hasher> {
        HashRing::with_hasher(nodes, replicas, XxHash64Hasher::default())
    }
}

impl<T, S> HashRing<T, S>
where
    T: ToString + Clone,
    S: BuildHasher,
{

    pub fn with_hasher(nodes: Vec<T>, replicas: isize, hash_builder: S) -> HashRing<T, S> {
        let mut new_hash_ring: HashRing<T, S> = HashRing {
            replicas,
            ring: HashMap::new(),
            sorted_keys: Vec::new(),
            hash_builder,
        };

        for n in &nodes {
            new_hash_ring.add_node(n);
        }
        new_hash_ring
    }

    /// Adds a node to the hash ring
    pub fn add_node(&mut self, node: &T) {
        for i in 0..self.replicas {
            let key = self.gen_key(format!("{}:{}", node.to_string(), i));
            self.ring.insert(key, (*node).clone());
            self.sorted_keys.push(key);
        }

        self.sorted_keys = BinaryHeap::from(self.sorted_keys.clone()).into_sorted_vec();
    }

    /// Deletes a node from the hash ring
    pub fn remove_node(&mut self, node: &T) {
        for i in 0..self.replicas {
            let key = self.gen_key(format!("{}:{}", node.to_string(), i));
            if !self.ring.contains_key(&key) {
                return;
            }
            self.ring.remove(&key);
            let mut index = 0;
            for j in 0..self.sorted_keys.len() {
                if self.sorted_keys[j] == key {
                    index = j;
                    break;
                }
            }
            self.sorted_keys.remove(index);
        }
    }

    /// Gets the node a specific key belongs to
    pub fn get_node(&self, key: String) -> Option<&T> {
        if self.sorted_keys.is_empty() {
            return None;
        }

        let generated_key = self.gen_key(key);
        let nodes = self.sorted_keys.clone();

        for node in &nodes {
            if generated_key <= *node {
                return Some(self.ring.get(node).unwrap());
            }
        }

        let node = &nodes[0];
        return Some(self.ring.get(node).unwrap());
    }

    /// Generates a key from a string value
    fn gen_key(&self, key: String) -> u64 {
        let mut hasher = self.hash_builder.build_hasher();
        hasher.write(key.as_bytes());
        hasher.finish()
    }
}

#[cfg(test)]
mod test {
    use std::hash::Hasher;
    use std::hash::BuildHasherDefault;
    use hash_ring::{NodeInfo, HashRing};

    // Defines a NodeInfo for a localhost address with a given port.
    fn node(port: u16) -> NodeInfo {
        NodeInfo {
            host: "localhost",
            port,
        }
    }

    #[test]
    fn test_empty_ring() {
        let hash_ring: HashRing<NodeInfo> = HashRing::new(vec![], 10);
        assert_eq!(None, hash_ring.get_node("hello".to_string()));
    }

    #[test]
    fn test_default_nodes() {
        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let mut hash_ring: HashRing<NodeInfo> = HashRing::new(nodes, 10);

        assert_eq!(Some(&node(15326)), hash_ring.get_node("hello".to_string()));
        assert_eq!(Some(&node(15327)), hash_ring.get_node("dude".to_string()));
        assert_eq!(Some(&node(15324)), hash_ring.get_node("two".to_string()));

        hash_ring.remove_node(&node(15329));
        assert_eq!(Some(&node(15326)), hash_ring.get_node("hello".to_string()));

        hash_ring.add_node(&node(15329));
        assert_eq!(Some(&node(15326)), hash_ring.get_node("hello".to_string()));
    }

    #[derive(Clone)]
    struct CustomNodeInfo {
        pub host: &'static str,
        pub port: u16,
    }

    impl ToString for CustomNodeInfo {
        fn to_string(&self) -> String {
            format!("{}:{}", self.host, self.port)
        }
    }

    #[test]
    fn test_custom_nodes() {
        let mut nodes: Vec<CustomNodeInfo> = Vec::new();
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15324,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15325,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15326,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15327,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15328,
        });
        nodes.push(CustomNodeInfo {
            host: "localhost",
            port: 15329,
        });

        let mut hash_ring: HashRing<CustomNodeInfo> = HashRing::new(nodes, 10);

        assert_eq!(
            Some("localhost:15326".to_string()),
            hash_ring.get_node("hello".to_string()).map(
                |x| x.to_string(),
            )
        );
        assert_eq!(
            Some("localhost:15327".to_string()),
            hash_ring.get_node("dude".to_string()).map(
                |x| x.to_string(),
            )
        );

        hash_ring.remove_node(&CustomNodeInfo {
            host: "localhost",
            port: 15329,
        });
        assert_eq!(
            Some("localhost:15326".to_string()),
            hash_ring.get_node("hello".to_string()).map(
                |x| x.to_string(),
            )
        );

        hash_ring.add_node(&CustomNodeInfo {
            host: "localhost",
            port: 15329,
        });
        assert_eq!(
            Some("localhost:15326".to_string()),
            hash_ring.get_node("hello".to_string()).map(
                |x| x.to_string(),
            )
        );
    }

    #[test]
    fn test_remove_actual_node() {
        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let mut hash_ring: HashRing<NodeInfo> = HashRing::new(nodes, 10);

        // This should be num nodes * num replicas
        assert_eq!(60, hash_ring.sorted_keys.len());
        assert_eq!(60, hash_ring.ring.len());

        hash_ring.remove_node(&node(15326));

        // This should be num nodes * num replicas
        assert_eq!(50, hash_ring.sorted_keys.len());
        assert_eq!(50, hash_ring.ring.len());
    }

    #[test]
    fn test_remove_non_existent_node() {
        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let mut hash_ring: HashRing<NodeInfo> = HashRing::new(nodes, 10);

        hash_ring.remove_node(&node(15330));

        // This should be num nodes * num replicas
        assert_eq!(60, hash_ring.sorted_keys.len());
        assert_eq!(60, hash_ring.ring.len());
    }

    #[test]
    fn test_custom_hasher() {
        #[derive(Default)]
        struct ConstantHasher;

        impl Hasher for ConstantHasher {
            fn write(&mut self, _bytes: &[u8]) {
                // Do nothing
            }

            fn finish(&self) -> u64 {
                return 1;
            }
        }

        type ConstantBuildHasher = BuildHasherDefault<ConstantHasher>;

        let mut nodes: Vec<NodeInfo> = Vec::new();
        nodes.push(node(15324));
        nodes.push(node(15325));
        nodes.push(node(15326));
        nodes.push(node(15327));
        nodes.push(node(15328));
        nodes.push(node(15329));

        let hash_ring: HashRing<NodeInfo, ConstantBuildHasher> = HashRing::with_hasher(nodes, 10, ConstantBuildHasher::default());

        assert_eq!(Some(&node(15329)), hash_ring.get_node("hello".to_string()));
        assert_eq!(Some(&node(15329)), hash_ring.get_node("dude".to_string()));
        assert_eq!(Some(&node(15329)), hash_ring.get_node("two".to_string()));
    }
}
<|endoftext|>


<commit_before>#![crate_name = "head"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Alan Andrade <alan.andradec@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * Synced with: https://raw.github.com/avsm/src/master/usr.bin/head/head.c
 */

extern crate getopts;

use std::io::{BufRead, BufReader, Read, stdin, Write};
use std::fs::File;
use std::path::Path;
use std::str::from_utf8;

#[path = "../common/util.rs"]
#[macro_use]
mod util;

static NAME: &'static str = "head";
static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> i32 {
    let mut line_count = 10usize;
    let mut byte_count = 0usize;

    // handle obsolete -number syntax
    let options = match obsolete(&args[1..]) {
        (args, Some(n)) => { line_count = n; args },
        (args, None) => args
    };

    let args = options;

    let mut opts = getopts::Options::new();

    opts.optopt("c", "bytes", "Print the first K bytes.  With the leading '-', print all but the last K bytes", "[-]K");
    opts.optopt("n", "lines", "Print the first K lines.  With the leading '-', print all but the last K lines", "[-]K");
    opts.optflag("h", "help", "help");
    opts.optflag("V", "version", "version");

    let given_options = match opts.parse(&args) {
        Ok (m) => { m }
        Err(_) => {
            println!("{}", opts.usage(""));
            return 1;
        }
    };

    if given_options.opt_present("h") {
        println!("{}", opts.usage(""));
        return 0;
    }
    if given_options.opt_present("V") { version(); return 0 }

    let use_bytes = given_options.opt_present("c");

    // TODO: suffixes (e.g. b, kB, etc.)
    match given_options.opt_str("n") {
        Some(n) => {
            if use_bytes {
                show_error!("cannot specify both --bytes and --lines.");
                return 1;
            }
            match n.parse::<usize>() {
                Ok(m) => { line_count = m }
                Err(e) => {
                    show_error!("invalid line count '{}': {}", n, e);
                    return 1;
                }
            }
        }
        None => match given_options.opt_str("c") {
            Some(count) => match count.parse::<usize>() {
                Ok(m) => byte_count = m,
                Err(e)=> {
                    show_error!("invalid byte count '{}': {}", count, e);
                    return 1;
                }
            },
            None => {}
        }
    };

    let files = given_options.free;

    let count =
        if use_bytes {
            byte_count
        } else {
            line_count
        };

    if files.is_empty() {
        let mut buffer = BufReader::new(stdin());
        head(&mut buffer, count, use_bytes);
    } else {
        let mut multiple = false;
        let mut firstime = true;

        if files.len() > 1 {
            multiple = true;
        }

        for file in files.iter() {
            if multiple {
                if !firstime { pipe_println!(""); }
                pipe_println!("==> {} <==", file);
            }
            firstime = false;

            let path = Path::new(file);
            let reader = File::open(&path).unwrap();
            let mut buffer = BufReader::new(reader);
            if !head(&mut buffer, count, use_bytes) {
                break;
            }
        }
    }

    0
}

// It searches for an option in the form of -123123
//
// In case is found, the options vector will get rid of that object so that
// getopts works correctly.
fn obsolete(options: &[String]) -> (Vec<String>, Option<usize>) {
    let mut options: Vec<String> = options.to_vec();
    let mut a = 0;
    let b = options.len();

    while a < b {
        let current = options[a].clone();
        let current = current.as_bytes();

        if current.len() > 1 && current[0] == '-' as u8 {
            let len = current.len();
            for pos in (1 .. len) {
                // Ensure that the argument is only made out of digits
                if !(current[pos] as char).is_numeric() { break; }

                // If this is the last number
                if pos == len - 1 {
                    options.remove(a);
                    let number: Option<usize> = from_utf8(&current[1..len]).unwrap().parse::<usize>().ok();
                    return (options, Some(number.unwrap()));
                }
            }
        }

        a += 1;
    };

    (options, None)
}

// TODO: handle errors on read
fn head<T: Read>(reader: &mut BufReader<T>, count: usize, use_bytes: bool) -> bool {
    if use_bytes {
        for byte in reader.bytes().take(count) {
            if !pipe_print!("{}", byte.unwrap() as char) {
                return false;
            }
        }
    } else {
        for line in reader.lines().take(count) {
            if !pipe_println!("{}", line.unwrap()) {
                return false;
            }
        }
    }
    true
}

fn version() {
    println!("{} {}", NAME, VERSION);
}
<commit_msg>Improve descriptions of available options.<commit_after>#![crate_name = "head"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Alan Andrade <alan.andradec@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * Synced with: https://raw.github.com/avsm/src/master/usr.bin/head/head.c
 */

extern crate getopts;

use std::io::{BufRead, BufReader, Read, stdin, Write};
use std::fs::File;
use std::path::Path;
use std::str::from_utf8;

#[path = "../common/util.rs"]
#[macro_use]
mod util;

static NAME: &'static str = "head";
static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> i32 {
    let mut line_count = 10usize;
    let mut byte_count = 0usize;

    // handle obsolete -number syntax
    let options = match obsolete(&args[1..]) {
        (args, Some(n)) => { line_count = n; args },
        (args, None) => args
    };

    let args = options;

    let mut opts = getopts::Options::new();

    opts.optopt("c", "bytes", "Print the first K bytes.  With the leading '-', print all but the last K bytes", "[-]K");
    opts.optopt("n", "lines", "Print the first K lines.  With the leading '-', print all but the last K lines", "[-]K");
    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("V", "version", "output version information and exit");

    let given_options = match opts.parse(&args) {
        Ok (m) => { m }
        Err(_) => {
            println!("{}", opts.usage(""));
            return 1;
        }
    };

    if given_options.opt_present("h") {
        println!("{}", opts.usage(""));
        return 0;
    }
    if given_options.opt_present("V") { version(); return 0 }

    let use_bytes = given_options.opt_present("c");

    // TODO: suffixes (e.g. b, kB, etc.)
    match given_options.opt_str("n") {
        Some(n) => {
            if use_bytes {
                show_error!("cannot specify both --bytes and --lines.");
                return 1;
            }
            match n.parse::<usize>() {
                Ok(m) => { line_count = m }
                Err(e) => {
                    show_error!("invalid line count '{}': {}", n, e);
                    return 1;
                }
            }
        }
        None => match given_options.opt_str("c") {
            Some(count) => match count.parse::<usize>() {
                Ok(m) => byte_count = m,
                Err(e)=> {
                    show_error!("invalid byte count '{}': {}", count, e);
                    return 1;
                }
            },
            None => {}
        }
    };

    let files = given_options.free;

    let count =
        if use_bytes {
            byte_count
        } else {
            line_count
        };

    if files.is_empty() {
        let mut buffer = BufReader::new(stdin());
        head(&mut buffer, count, use_bytes);
    } else {
        let mut multiple = false;
        let mut firstime = true;

        if files.len() > 1 {
            multiple = true;
        }

        for file in files.iter() {
            if multiple {
                if !firstime { pipe_println!(""); }
                pipe_println!("==> {} <==", file);
            }
            firstime = false;

            let path = Path::new(file);
            let reader = File::open(&path).unwrap();
            let mut buffer = BufReader::new(reader);
            if !head(&mut buffer, count, use_bytes) {
                break;
            }
        }
    }

    0
}

// It searches for an option in the form of -123123
//
// In case is found, the options vector will get rid of that object so that
// getopts works correctly.
fn obsolete(options: &[String]) -> (Vec<String>, Option<usize>) {
    let mut options: Vec<String> = options.to_vec();
    let mut a = 0;
    let b = options.len();

    while a < b {
        let current = options[a].clone();
        let current = current.as_bytes();

        if current.len() > 1 && current[0] == '-' as u8 {
            let len = current.len();
            for pos in (1 .. len) {
                // Ensure that the argument is only made out of digits
                if !(current[pos] as char).is_numeric() { break; }

                // If this is the last number
                if pos == len - 1 {
                    options.remove(a);
                    let number: Option<usize> = from_utf8(&current[1..len]).unwrap().parse::<usize>().ok();
                    return (options, Some(number.unwrap()));
                }
            }
        }

        a += 1;
    };

    (options, None)
}

// TODO: handle errors on read
fn head<T: Read>(reader: &mut BufReader<T>, count: usize, use_bytes: bool) -> bool {
    if use_bytes {
        for byte in reader.bytes().take(count) {
            if !pipe_print!("{}", byte.unwrap() as char) {
                return false;
            }
        }
    } else {
        for line in reader.lines().take(count) {
            if !pipe_println!("{}", line.unwrap()) {
                return false;
            }
        }
    }
    true
}

fn version() {
    println!("{} {}", NAME, VERSION);
}
<|endoftext|>


<commit_before>//! Tests

use std::thread;
use std::time::Duration;
use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ParserError, ErrorCode};

use ipc::unique_ish_id;
use super::channel::*;

const COMPLEX_JSON: &'static str =
    r#"{ "foo": "bar", "baz": 1, "bar": [ "a", "b", "c", 22], "obj":
{ "foo": "bar", "baz": 22.4 } }"#;

const BAD_JSON_DELIMITER: &'static str = r#"{ "foo": "bar" "#;

#[test]
fn u32_coversion() {
    let nums = [0u32, !2, 255, 256, 1024, 2048, 12, 4096, 1, 0xfffffffe,
                0b11111111, 0xffefff, 0x11111111, 0x0101011, 0xffffffff];
    for num in &nums {
        let be_num = num.to_be();
        let le_num = num.to_le();
        assert_eq!(u32_to_bytes(be_num), u32_to_bytes(be_num));
        assert_eq!(u32_from_bytes(u32_to_bytes(le_num)), le_num);
    }
}

#[test]
fn uniquesh_id_is_uniqueish() {
    let mut ids = Vec::with_capacity(15);
    for _ in 0..15 {
        println!("New id: {}", unique_ish_id());
        ids.push(unique_ish_id());
        thread::sleep(Duration::from_millis(50));
    }
    ids.dedup();
    assert!(ids.len() == 15, "unique_ish_id conflict: {:?}", ids);
}

fn packet_stream_from_str(text: &str) -> Vec<u8> {
    let mut turn = Vec::with_capacity(text.len()+4);
    let mut bytes = text.as_bytes();
    assert!(bytes.len() < 255,
            "Tests only work with < 255 char packets!");
    turn.push(0);
    turn.push(0);
    turn.push(0);
    turn.push(bytes.len() as u8);
    turn.extend_from_slice(&mut bytes);
    return turn;
}

#[test]
fn read_packet_bad_json() {
    let packet = packet_stream_from_str(BAD_JSON_DELIMITER);
    match read_packet(&mut &*packet) {
        Ok(json) => panic!("Got some Json somehow: {:?}", json),
        Err(response) => match response {
            ResponseError::InvalidJson(err) => match err {
                ParserError::SyntaxError(code, start, end) => {
                    assert_eq!(code, ErrorCode::EOFWhileParsingObject);
                    assert_eq!(start, 1);
                    assert_eq!(end, 16);
                },
                other_json @ _ =>
                    panic!("Unexpected json errr: {:?}", other_json)
            },
            other @ _ => panic!("Unexpected err: {:?}", other)
        }
    }
}

#[test]
fn read_packet_json() {
    let packet = packet_stream_from_str(r#"{ "foo": "bar" }"#);
    match read_packet(&mut &*packet) {
        Ok(json) => {
            let mut desired_map = BTreeMap::new();
            desired_map.insert("foo".to_string(),
                             Json::String("bar".to_string()));
            assert_eq!(json, Json::Object(desired_map));
        }
        Err(err) => panic!("Unable to parse Json: {:?}", err)
    }
}

#[test]
fn read_packet_short_length() {
    let mut packet = Vec::new();
    packet.push(0); packet.push(0); packet.push(0);
    packet.push(5); // Len == 5
    packet.extend_from_slice(br#"{ "foo": 1 }"#);
    // Gets to just before close quote of foo

    match read_packet(&mut &*packet) {
        Ok(json) => panic!("Got a json {:?}, read too much?", json),
        Err(response) => match response {
            ResponseError::InvalidJson(json_err) => match json_err {
                ParserError::SyntaxError(code, start, end) => {
                    assert_eq!(code, ErrorCode::EOFWhileParsingString);
                    assert_eq!(start, 1); assert_eq!(end, 6);
                },
                other_json @ _ => panic!("Wrong json err: {:?}", other_json)
            },
            other @ _ => panic!("Wrong error: {:?}", other)
        }
    }
}

#[test]
fn write_packet_integrity() {
    let packet_json = Json::from_str(COMPLEX_JSON).expect("complex_json");
    let mut packet = Vec::new();
    write_packet(&mut packet, &packet_json).expect("Unable to write pakcet");
    // Remove length
    for _ in 0 .. 4 { packet.remove(0); }
    let text = String::from_utf8(packet).expect("Packet had invalid utf8");
    assert_eq!(packet_json, Json::from_str(&text).expect("Couldn't parse text"));
}

#[test]
fn read_write_packet() {
    let packet_json = Json::from_str(COMPLEX_JSON).expect("complex_json");
    let mut packet = Vec::new();
    write_packet(&mut packet, &packet_json).expect("Could not write");
    let read_json = read_packet(&mut &*packet).expect("Could not read");
    assert_eq!(read_json, packet_json);
}
<commit_msg>Add success_json() test<commit_after>//! Tests

use std::thread;
use std::time::Duration;
use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ParserError, ErrorCode};

use ipc::unique_ish_id;
use super::channel::*;

const COMPLEX_JSON: &'static str =
    r#"{ "foo": "bar", "baz": 1, "bar": [ "a", "b", "c", 22], "obj":
{ "foo": "bar", "baz": 22.4 } }"#;

const BAD_JSON_DELIMITER: &'static str = r#"{ "foo": "bar" "#;
const SUCCESS_JSON: &'static str = r#"{ "type": "success" }"#;

#[test]
fn u32_coversion() {
    let nums = [0u32, !2, 255, 256, 1024, 2048, 12, 4096, 1, 0xfffffffe,
                0b11111111, 0xffefff, 0x11111111, 0x0101011, 0xffffffff];
    for num in &nums {
        let be_num = num.to_be();
        let le_num = num.to_le();
        assert_eq!(u32_to_bytes(be_num), u32_to_bytes(be_num));
        assert_eq!(u32_from_bytes(u32_to_bytes(le_num)), le_num);
    }
}

#[test]
fn uniquesh_id_is_uniqueish() {
    let mut ids = Vec::with_capacity(15);
    for _ in 0..15 {
        println!("New id: {}", unique_ish_id());
        ids.push(unique_ish_id());
        thread::sleep(Duration::from_millis(50));
    }
    ids.dedup();
    assert!(ids.len() == 15, "unique_ish_id conflict: {:?}", ids);
}

fn packet_stream_from_str(text: &str) -> Vec<u8> {
    let mut turn = Vec::with_capacity(text.len()+4);
    let mut bytes = text.as_bytes();
    assert!(bytes.len() < 255,
            "Tests only work with < 255 char packets!");
    turn.push(0);
    turn.push(0);
    turn.push(0);
    turn.push(bytes.len() as u8);
    turn.extend_from_slice(&mut bytes);
    return turn;
}

#[test]
fn read_packet_bad_json() {
    let packet = packet_stream_from_str(BAD_JSON_DELIMITER);
    match read_packet(&mut &*packet) {
        Ok(json) => panic!("Got some Json somehow: {:?}", json),
        Err(response) => match response {
            ResponseError::InvalidJson(err) => match err {
                ParserError::SyntaxError(code, start, end) => {
                    assert_eq!(code, ErrorCode::EOFWhileParsingObject);
                    assert_eq!(start, 1);
                    assert_eq!(end, 16);
                },
                other_json @ _ =>
                    panic!("Unexpected json errr: {:?}", other_json)
            },
            other @ _ => panic!("Unexpected err: {:?}", other)
        }
    }
}

#[test]
fn read_packet_json() {
    let packet = packet_stream_from_str(r#"{ "foo": "bar" }"#);
    match read_packet(&mut &*packet) {
        Ok(json) => {
            let mut desired_map = BTreeMap::new();
            desired_map.insert("foo".to_string(),
                             Json::String("bar".to_string()));
            assert_eq!(json, Json::Object(desired_map));
        }
        Err(err) => panic!("Unable to parse Json: {:?}", err)
    }
}

#[test]
fn read_packet_short_length() {
    let mut packet = Vec::new();
    packet.push(0); packet.push(0); packet.push(0);
    packet.push(5); // Len == 5
    packet.extend_from_slice(br#"{ "foo": 1 }"#);
    // Gets to just before close quote of foo

    match read_packet(&mut &*packet) {
        Ok(json) => panic!("Got a json {:?}, read too much?", json),
        Err(response) => match response {
            ResponseError::InvalidJson(json_err) => match json_err {
                ParserError::SyntaxError(code, start, end) => {
                    assert_eq!(code, ErrorCode::EOFWhileParsingString);
                    assert_eq!(start, 1); assert_eq!(end, 6);
                },
                other_json @ _ => panic!("Wrong json err: {:?}", other_json)
            },
            other @ _ => panic!("Wrong error: {:?}", other)
        }
    }
}

#[test]
fn write_packet_integrity() {
    let packet_json = Json::from_str(COMPLEX_JSON).expect("complex_json");
    let mut packet = Vec::new();
    write_packet(&mut packet, &packet_json).expect("Unable to write pakcet");
    // Remove length
    for _ in 0 .. 4 { packet.remove(0); }
    let text = String::from_utf8(packet).expect("Packet had invalid utf8");
    assert_eq!(packet_json, Json::from_str(&text).expect("Couldn't parse text"));
}

#[test]
fn read_write_packet() {
    let packet_json = Json::from_str(COMPLEX_JSON).expect("complex_json");
    let mut packet = Vec::new();
    write_packet(&mut packet, &packet_json).expect("Could not write");
    let read_json = read_packet(&mut &*packet).expect("Could not read");
    assert_eq!(read_json, packet_json);
}

#[test]
fn success_json_is_successful() {
    assert_eq!(success_json(),
               Json::from_str(SUCCESS_JSON).expect("Can't get success Json"));
}
<|endoftext|>


<commit_before>use nalgebra::Point3;
use num::{Float, Unsigned};
use std::ops::Range;

use super::generate::{Conjoint, Indexed};
use super::primitive::{MapPrimitiveInto, Quad};

pub trait Cube: Iterator + Sized {
    type Point;

    fn point(&self, index: usize) -> Self::Point;

    fn face(&self, index: usize) -> Quad<Self::Point> {
        self.indexed_face(index).map_points_into(|index| self.point(index))
    }

    fn indexed_face(&self, index: usize) -> Quad<usize> {
        match index {
            0 => Quad::new(0, 1, 3, 2),
            1 => Quad::new(6, 7, 5, 4),
            2 => Quad::new(4, 5, 1, 0),
            3 => Quad::new(3, 7, 6, 2),
            4 => Quad::new(0, 2, 6, 4),
            5 => Quad::new(5, 7, 3, 1),
            _ => panic!(),
        }
    }
}

impl<C> Indexed<Quad<usize>> for C
    where C: Cube
{
    fn indexed_polygon(&self, index: usize) -> Quad<usize> {
        self.indexed_face(index)
    }

    fn indexed_polygon_count(&self) -> usize {
        6
    }
}

impl<T, C> Conjoint<T> for C
    where C: Cube<Point = T>
{
    fn conjoint_point(&self, index: usize) -> T {
        self.point(index)
    }

    fn conjoint_point_count(&self) -> usize {
        8
    }
}

pub struct FCube<T>
    where T: Float
{
    faces: Range<usize>,
    low: T,
    high: T,
}

impl<T> FCube<T>
    where T: Float
{
    fn new(low: T, high: T) -> Self {
        FCube {
            faces: 0..6,
            low: low,
            high: high,
        }
    }

    pub fn with_unit_radius() -> Self {
        FCube::new(-T::one(), T::one())
    }

    pub fn with_unit_width() -> Self {
        let half = T::one() / (T::one() + T::one());
        FCube::new(-half, half)
    }
}

impl<T> Cube for FCube<T>
    where T: Float
{
    type Point = Point3<T>;

    fn point(&self, index: usize) -> Self::Point {
        point(index, self.low, self.high)
    }
}

impl<T> Iterator for FCube<T>
    where T: Float
{
    type Item = Quad<<Self as Cube>::Point>;

    fn next(&mut self) -> Option<Self::Item> {
        self.faces.next().map(|index| self.face(index))
    }
}

pub struct UCube<T>
    where T: Copy + Unsigned
{
    faces: Range<usize>,
    low: T,
    high: T,
}

impl<T> UCube<T>
    where T: Copy + Unsigned
{
    fn new(low: T, high: T) -> Self {
        UCube {
            faces: 0..6,
            low: low,
            high: high,
        }
    }

    pub fn with_unit_radius() -> Self {
        UCube::new(T::zero(), T::one() + T::one())
    }

    pub fn with_unit_width() -> Self {
        UCube::new(T::zero(), T::one())
    }
}

impl<T> Cube for UCube<T>
    where T: Copy + Unsigned
{
    type Point = Point3<T>;

    fn point(&self, index: usize) -> Self::Point {
        point(index, self.low, self.high)
    }
}

impl<T> Iterator for UCube<T>
    where T: Copy + Unsigned
{
    type Item = Quad<<Self as Cube>::Point>;

    fn next(&mut self) -> Option<Self::Item> {
        self.faces.next().map(|index| self.face(index))
    }
}

fn point<T>(index: usize, low: T, high: T) -> Point3<T>
    where T: Copy
{
    let x = if index & 0b100 == 0b100 { high } else { low };
    let y = if index & 0b010 == 0b010 { high } else { low };
    let z = if index & 0b001 == 0b001 { high } else { low };
    Point3::new(x, y, z)
}
<commit_msg>Reorder faces of cube mesh so that `Conjoint` is not required.<commit_after>use nalgebra::Point3;
use num::{Float, Unsigned};
use std::ops::Range;

use super::generate::{Conjoint, Indexed};
use super::primitive::{MapPrimitiveInto, Quad};

pub trait Cube: Iterator + Sized {
    type Point;

    fn point(&self, index: usize) -> Self::Point;

    fn face(&self, index: usize) -> Quad<Self::Point> {
        self.indexed_face(index).map_points_into(|index| self.point(index))
    }

    fn indexed_face(&self, index: usize) -> Quad<usize> {
        match index {
            0 => Quad::new(5, 7, 3, 1),
            1 => Quad::new(6, 7, 5, 4),
            2 => Quad::new(3, 7, 6, 2),
            3 => Quad::new(0, 1, 3, 2),
            4 => Quad::new(4, 5, 1, 0),
            5 => Quad::new(0, 2, 6, 4),
            _ => panic!(),
        }
    }
}

impl<C> Indexed<Quad<usize>> for C
    where C: Cube
{
    fn indexed_polygon(&self, index: usize) -> Quad<usize> {
        self.indexed_face(index)
    }

    fn indexed_polygon_count(&self) -> usize {
        6
    }
}

impl<T, C> Conjoint<T> for C
    where C: Cube<Point = T>
{
    fn conjoint_point(&self, index: usize) -> T {
        self.point(index)
    }

    fn conjoint_point_count(&self) -> usize {
        8
    }
}

pub struct FCube<T>
    where T: Float
{
    faces: Range<usize>,
    low: T,
    high: T,
}

impl<T> FCube<T>
    where T: Float
{
    fn new(low: T, high: T) -> Self {
        FCube {
            faces: 0..6,
            low: low,
            high: high,
        }
    }

    pub fn with_unit_radius() -> Self {
        FCube::new(-T::one(), T::one())
    }

    pub fn with_unit_width() -> Self {
        let half = T::one() / (T::one() + T::one());
        FCube::new(-half, half)
    }
}

impl<T> Cube for FCube<T>
    where T: Float
{
    type Point = Point3<T>;

    fn point(&self, index: usize) -> Self::Point {
        point(index, self.low, self.high)
    }
}

impl<T> Iterator for FCube<T>
    where T: Float
{
    type Item = Quad<<Self as Cube>::Point>;

    fn next(&mut self) -> Option<Self::Item> {
        self.faces.next().map(|index| self.face(index))
    }
}

pub struct UCube<T>
    where T: Copy + Unsigned
{
    faces: Range<usize>,
    low: T,
    high: T,
}

impl<T> UCube<T>
    where T: Copy + Unsigned
{
    fn new(low: T, high: T) -> Self {
        UCube {
            faces: 0..6,
            low: low,
            high: high,
        }
    }

    pub fn with_unit_radius() -> Self {
        UCube::new(T::zero(), T::one() + T::one())
    }

    pub fn with_unit_width() -> Self {
        UCube::new(T::zero(), T::one())
    }
}

impl<T> Cube for UCube<T>
    where T: Copy + Unsigned
{
    type Point = Point3<T>;

    fn point(&self, index: usize) -> Self::Point {
        point(index, self.low, self.high)
    }
}

impl<T> Iterator for UCube<T>
    where T: Copy + Unsigned
{
    type Item = Quad<<Self as Cube>::Point>;

    fn next(&mut self) -> Option<Self::Item> {
        self.faces.next().map(|index| self.face(index))
    }
}

fn point<T>(index: usize, low: T, high: T) -> Point3<T>
    where T: Copy
{
    let x = if index & 0b100 == 0b100 { high } else { low };
    let y = if index & 0b010 == 0b010 { high } else { low };
    let z = if index & 0b001 == 0b001 { high } else { low };
    Point3::new(x, y, z)
}
<|endoftext|>


<commit_before>#![allow(unused)]

//! Implements a map from integer indices to data.
//! Rather than storing data for every index, internally, this maps entire ranges to the data.
//! To this end, the APIs all work on ranges, not on individual integers. Ranges are split as
//! necessary (e.g. when [0,5) is first associated with X, and then [1,2) is mutated).
//! Users must not depend on whether a range is coalesced or not, even though this is observable
//! via the iteration APIs.

use std::ops;
use std::num::NonZeroU64;

use rustc::ty::layout::Size;

#[derive(Clone, Debug)]
struct Elem<T> {
    range: ops::Range<u64>, // the range covered by this element, never empty
    data: T,
}
#[derive(Clone, Debug)]
pub struct RangeMap<T> {
    v: Vec<Elem<T>>,
}

impl<T> RangeMap<T> {
    /// Create a new RangeMap for the given size, and with the given initial value used for
    /// the entire range.
    #[inline(always)]
    pub fn new(size: Size, init: T) -> RangeMap<T> {
        let size = size.bytes();
        let mut map = RangeMap { v: Vec::new() };
        if size > 0 {
            map.v.push(Elem {
                range: 0..size,
                data: init
            });
        }
        map
    }

    /// Find the index containing the given offset.
    fn find_offset(&self, offset: u64) -> usize {
        // We do a binary search
        let mut left = 0usize; // inclusive
        let mut right = self.v.len(); // exclusive
        loop {
            debug_assert!(left < right, "find_offset: offset {} is out-of-bounds", offset);
            let candidate = left.checked_add(right).unwrap() / 2;
            let elem = &self.v[candidate];
            if offset < elem.range.start {
                // we are too far right (offset is further left)
                debug_assert!(candidate < right); // we are making progress
                right = candidate;
            } else if offset >= elem.range.end {
                // we are too far left (offset is further right)
                debug_assert!(candidate >= left); // we are making progress
                left = candidate+1;
            } else {
                // This is it!
                return candidate;
            }
        }
    }

    /// Provide read-only iteration over everything in the given range.  This does
    /// *not* split items if they overlap with the edges.  Do not use this to mutate
    /// through interior mutability.
    pub fn iter<'a>(&'a self, offset: Size, len: Size) -> impl Iterator<Item = &'a T> + 'a {
        let offset = offset.bytes();
        let len = len.bytes();
        // Compute a slice starting with the elements we care about
        let slice: &[Elem<T>] = if len == 0 {
                // We just need any empty iterator.  We don't even want to
                // yield the element that surrounds this position.
                &[]
            } else {
                let first_idx = self.find_offset(offset);
                &self.v[first_idx..]
            };
        let end = offset + len; // the first offset that is not included any more
        slice.iter()
            .take_while(move |elem| elem.range.start < end)
            .map(|elem| &elem.data)
    }

    pub fn iter_mut_all<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T> + 'a {
        self.v.iter_mut().map(|elem| &mut elem.data)
    }

    // Split the element situated at the given `index`, such that the 2nd one starts at offset `split_offset`.
    // Do nothing if the element already starts there.
    // Return whether a split was necessary.
    fn split_index(&mut self, index: usize, split_offset: u64) -> bool
    where
        T: Clone,
    {
        let elem = &mut self.v[index];
        if split_offset == elem.range.start || split_offset == elem.range.end {
            // Nothing to do
            return false;
        }
        debug_assert!(elem.range.contains(&split_offset),
            "The split_offset is not in the element to be split");

        // Now we really have to split.  Reduce length of first element.
        let second_range = split_offset..elem.range.end;
        elem.range.end = split_offset;
        // Copy the data, and insert 2nd element
        let second = Elem {
            range: second_range,
            data: elem.data.clone(),
        };
        self.v.insert(index+1, second);
        return true;
    }

    /// Provide mutable iteration over everything in the given range.  As a side-effect,
    /// this will split entries in the map that are only partially hit by the given range,
    /// to make sure that when they are mutated, the effect is constrained to the given range.
    pub fn iter_mut<'a>(
        &'a mut self,
        offset: Size,
        len: Size,
    ) -> impl Iterator<Item = &'a mut T> + 'a
    where
        T: Clone + PartialEq,
    {
        let offset = offset.bytes();
        let len = len.bytes();
        // Compute a slice containing exactly the elements we care about
        let slice: &mut [Elem<T>] = if len == 0 {
                // We just need any empty iterator.  We don't even want to
                // yield the element that surrounds this position, nor do
                // any splitting.
                &mut []
            } else {
                // Make sure we got a clear beginning
                let mut first_idx = self.find_offset(offset);
                if self.split_index(first_idx, offset) {
                    // The newly created 2nd element is ours
                    first_idx += 1;
                }
                let first_idx = first_idx; // no more mutation
                // Find our end.  Linear scan, but that's okay because the iteration
                // is doing the same linear scan anyway -- no increase in complexity.
                // We combine this scan with a scan for duplicates that we can merge, to reduce
                // the number of elements.
                // We stop searching after the first "block" of size 1, to avoid spending excessive
                // amounts of time on the merging.
                let mut equal_since_idx = first_idx;
                // Once we see too many non-mergeable blocks, we stop.
                // The initial value is chosen via... magic.  Benchmarking and magic.
                let mut successful_merge_count = 3usize;
                let mut end_idx = first_idx; // when the loop is done, this is the first excluded element.
                loop {
                    // Compute if `end` is the last element we need to look at.
                    let done = (self.v[end_idx].range.end >= offset+len);
                    // We definitely need to include `end`, so move the index.
                    end_idx += 1;
                    debug_assert!(done || end_idx < self.v.len(), "iter_mut: end-offset {} is out-of-bounds", offset+len);
                    // see if we want to merge everything in `equal_since..end` (exclusive at the end!)
                    if successful_merge_count > 0 {
                        if done || self.v[end_idx].data != self.v[equal_since_idx].data {
                            // Everything in `equal_since..end` was equal.  Make them just one element covering
                            // the entire range.
                            let removed_elems = end_idx - equal_since_idx - 1; // number of elements that we would remove
                            if removed_elems > 0 {
                                // Adjust the range of the first element to cover all of them.
                                let equal_until = self.v[end_idx - 1].range.end; // end of range of last of the equal elements
                                self.v[equal_since_idx].range.end = equal_until;
                                // Delete the rest of them.
                                self.v.splice(equal_since_idx+1..end_idx, std::iter::empty());
                                // Adjust `end_idx` because we made the list shorter.
                                end_idx -= removed_elems;
                                // adjust the count for the cutoff
                                successful_merge_count += removed_elems;
                            } else {
                                // adjust the count for the cutoff
                                successful_merge_count -= 1;
                            }
                            // Go on scanning for the next block starting here.
                            equal_since_idx = end_idx;
                        }
                    }
                    // Leave loop if this is the last element.
                    if done {
                        break;
                    }
                }
                let end_idx = end_idx-1; // Move to last included instead of first excluded index.
                // We need to split the end as well.  Even if this performs a
                // split, we don't have to adjust our index as we only care about
                // the first part of the split.
                self.split_index(end_idx, offset+len);
                // Now we yield the slice. `end` is inclusive.
                &mut self.v[first_idx..=end_idx]
            };
        slice.iter_mut().map(|elem| &mut elem.data)
    }
}

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

    /// Query the map at every offset in the range and collect the results.
    fn to_vec<T: Copy>(map: &RangeMap<T>, offset: u64, len: u64) -> Vec<T> {
        (offset..offset + len)
            .into_iter()
            .map(|i| map
                .iter(Size::from_bytes(i), Size::from_bytes(1))
                .next()
                .map(|&t| t)
                .unwrap()
            )
            .collect()
    }

    #[test]
    fn basic_insert() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        // Insert
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(1)) {
            *x = 42;
        }
        // Check
        assert_eq!(to_vec(&map, 10, 1), vec![42]);
        assert_eq!(map.v.len(), 3);

        // Insert with size 0
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(0)) {
            *x = 19;
        }
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(0)) {
            *x = 19;
        }
        assert_eq!(to_vec(&map, 10, 2), vec![42, -1]);
        assert_eq!(map.v.len(), 3);
    }

    #[test]
    fn gaps() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(1)) {
            *x = 42;
        }
        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(1)) {
            *x = 43;
        }
        assert_eq!(map.v.len(), 5);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![-1, 42, -1, -1, -1, 43, -1, -1, -1, -1]
        );

        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(10)) {
            if *x < 42 {
                *x = 23;
            }
        }
        assert_eq!(map.v.len(), 6);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 43, 23, 23, 23, 23]
        );
        assert_eq!(to_vec(&map, 13, 5), vec![23, 23, 43, 23, 23]);

        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(5)) {
            *x = 19;
        }
        assert_eq!(map.v.len(), 6);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 19, 19, 19, 19, 19]
        );
        // Should be seeing two blocks with 19
        assert_eq!(map.iter(Size::from_bytes(15), Size::from_bytes(2))
            .map(|&t| t).collect::<Vec<_>>(), vec![19, 19]);

        // a NOP iter_mut should trigger merging
        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(5)) { }
        assert_eq!(map.v.len(), 5);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 19, 19, 19, 19, 19]
        );
    }
}
<commit_msg>expand docs<commit_after>#![allow(unused)]

//! Implements a map from integer indices to data.
//! Rather than storing data for every index, internally, this maps entire ranges to the data.
//! To this end, the APIs all work on ranges, not on individual integers. Ranges are split as
//! necessary (e.g. when [0,5) is first associated with X, and then [1,2) is mutated).
//! Users must not depend on whether a range is coalesced or not, even though this is observable
//! via the iteration APIs.

use std::ops;
use std::num::NonZeroU64;

use rustc::ty::layout::Size;

#[derive(Clone, Debug)]
struct Elem<T> {
    range: ops::Range<u64>, // the range covered by this element, never empty
    data: T,
}
#[derive(Clone, Debug)]
pub struct RangeMap<T> {
    v: Vec<Elem<T>>,
}

impl<T> RangeMap<T> {
    /// Create a new RangeMap for the given size, and with the given initial value used for
    /// the entire range.
    #[inline(always)]
    pub fn new(size: Size, init: T) -> RangeMap<T> {
        let size = size.bytes();
        let mut map = RangeMap { v: Vec::new() };
        if size > 0 {
            map.v.push(Elem {
                range: 0..size,
                data: init
            });
        }
        map
    }

    /// Find the index containing the given offset.
    fn find_offset(&self, offset: u64) -> usize {
        // We do a binary search
        let mut left = 0usize; // inclusive
        let mut right = self.v.len(); // exclusive
        loop {
            debug_assert!(left < right, "find_offset: offset {} is out-of-bounds", offset);
            let candidate = left.checked_add(right).unwrap() / 2;
            let elem = &self.v[candidate];
            if offset < elem.range.start {
                // we are too far right (offset is further left)
                debug_assert!(candidate < right); // we are making progress
                right = candidate;
            } else if offset >= elem.range.end {
                // we are too far left (offset is further right)
                debug_assert!(candidate >= left); // we are making progress
                left = candidate+1;
            } else {
                // This is it!
                return candidate;
            }
        }
    }

    /// Provide read-only iteration over everything in the given range.  This does
    /// *not* split items if they overlap with the edges.  Do not use this to mutate
    /// through interior mutability.
    pub fn iter<'a>(&'a self, offset: Size, len: Size) -> impl Iterator<Item = &'a T> + 'a {
        let offset = offset.bytes();
        let len = len.bytes();
        // Compute a slice starting with the elements we care about
        let slice: &[Elem<T>] = if len == 0 {
                // We just need any empty iterator.  We don't even want to
                // yield the element that surrounds this position.
                &[]
            } else {
                let first_idx = self.find_offset(offset);
                &self.v[first_idx..]
            };
        let end = offset + len; // the first offset that is not included any more
        slice.iter()
            .take_while(move |elem| elem.range.start < end)
            .map(|elem| &elem.data)
    }

    pub fn iter_mut_all<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T> + 'a {
        self.v.iter_mut().map(|elem| &mut elem.data)
    }

    // Split the element situated at the given `index`, such that the 2nd one starts at offset `split_offset`.
    // Do nothing if the element already starts there.
    // Return whether a split was necessary.
    fn split_index(&mut self, index: usize, split_offset: u64) -> bool
    where
        T: Clone,
    {
        let elem = &mut self.v[index];
        if split_offset == elem.range.start || split_offset == elem.range.end {
            // Nothing to do
            return false;
        }
        debug_assert!(elem.range.contains(&split_offset),
            "The split_offset is not in the element to be split");

        // Now we really have to split.  Reduce length of first element.
        let second_range = split_offset..elem.range.end;
        elem.range.end = split_offset;
        // Copy the data, and insert 2nd element
        let second = Elem {
            range: second_range,
            data: elem.data.clone(),
        };
        self.v.insert(index+1, second);
        return true;
    }

    /// Provide mutable iteration over everything in the given range.  As a side-effect,
    /// this will split entries in the map that are only partially hit by the given range,
    /// to make sure that when they are mutated, the effect is constrained to the given range.
    /// Moreover, this will opportunistically merge neighbouring equal blocks.
    pub fn iter_mut<'a>(
        &'a mut self,
        offset: Size,
        len: Size,
    ) -> impl Iterator<Item = &'a mut T> + 'a
    where
        T: Clone + PartialEq,
    {
        let offset = offset.bytes();
        let len = len.bytes();
        // Compute a slice containing exactly the elements we care about
        let slice: &mut [Elem<T>] = if len == 0 {
                // We just need any empty iterator.  We don't even want to
                // yield the element that surrounds this position, nor do
                // any splitting.
                &mut []
            } else {
                // Make sure we got a clear beginning
                let mut first_idx = self.find_offset(offset);
                if self.split_index(first_idx, offset) {
                    // The newly created 2nd element is ours
                    first_idx += 1;
                }
                let first_idx = first_idx; // no more mutation
                // Find our end.  Linear scan, but that's okay because the iteration
                // is doing the same linear scan anyway -- no increase in complexity.
                // We combine this scan with a scan for duplicates that we can merge, to reduce
                // the number of elements.
                // We stop searching after the first "block" of size 1, to avoid spending excessive
                // amounts of time on the merging.
                let mut equal_since_idx = first_idx;
                // Once we see too many non-mergeable blocks, we stop.
                // The initial value is chosen via... magic.  Benchmarking and magic.
                let mut successful_merge_count = 3usize;
                let mut end_idx = first_idx; // when the loop is done, this is the first excluded element.
                loop {
                    // Compute if `end` is the last element we need to look at.
                    let done = (self.v[end_idx].range.end >= offset+len);
                    // We definitely need to include `end`, so move the index.
                    end_idx += 1;
                    debug_assert!(done || end_idx < self.v.len(), "iter_mut: end-offset {} is out-of-bounds", offset+len);
                    // see if we want to merge everything in `equal_since..end` (exclusive at the end!)
                    if successful_merge_count > 0 {
                        if done || self.v[end_idx].data != self.v[equal_since_idx].data {
                            // Everything in `equal_since..end` was equal.  Make them just one element covering
                            // the entire range.
                            let removed_elems = end_idx - equal_since_idx - 1; // number of elements that we would remove
                            if removed_elems > 0 {
                                // Adjust the range of the first element to cover all of them.
                                let equal_until = self.v[end_idx - 1].range.end; // end of range of last of the equal elements
                                self.v[equal_since_idx].range.end = equal_until;
                                // Delete the rest of them.
                                self.v.splice(equal_since_idx+1..end_idx, std::iter::empty());
                                // Adjust `end_idx` because we made the list shorter.
                                end_idx -= removed_elems;
                                // adjust the count for the cutoff
                                successful_merge_count += removed_elems;
                            } else {
                                // adjust the count for the cutoff
                                successful_merge_count -= 1;
                            }
                            // Go on scanning for the next block starting here.
                            equal_since_idx = end_idx;
                        }
                    }
                    // Leave loop if this is the last element.
                    if done {
                        break;
                    }
                }
                let end_idx = end_idx-1; // Move to last included instead of first excluded index.
                // We need to split the end as well.  Even if this performs a
                // split, we don't have to adjust our index as we only care about
                // the first part of the split.
                self.split_index(end_idx, offset+len);
                // Now we yield the slice. `end` is inclusive.
                &mut self.v[first_idx..=end_idx]
            };
        slice.iter_mut().map(|elem| &mut elem.data)
    }
}

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

    /// Query the map at every offset in the range and collect the results.
    fn to_vec<T: Copy>(map: &RangeMap<T>, offset: u64, len: u64) -> Vec<T> {
        (offset..offset + len)
            .into_iter()
            .map(|i| map
                .iter(Size::from_bytes(i), Size::from_bytes(1))
                .next()
                .map(|&t| t)
                .unwrap()
            )
            .collect()
    }

    #[test]
    fn basic_insert() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        // Insert
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(1)) {
            *x = 42;
        }
        // Check
        assert_eq!(to_vec(&map, 10, 1), vec![42]);
        assert_eq!(map.v.len(), 3);

        // Insert with size 0
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(0)) {
            *x = 19;
        }
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(0)) {
            *x = 19;
        }
        assert_eq!(to_vec(&map, 10, 2), vec![42, -1]);
        assert_eq!(map.v.len(), 3);
    }

    #[test]
    fn gaps() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(1)) {
            *x = 42;
        }
        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(1)) {
            *x = 43;
        }
        assert_eq!(map.v.len(), 5);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![-1, 42, -1, -1, -1, 43, -1, -1, -1, -1]
        );

        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(10)) {
            if *x < 42 {
                *x = 23;
            }
        }
        assert_eq!(map.v.len(), 6);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 43, 23, 23, 23, 23]
        );
        assert_eq!(to_vec(&map, 13, 5), vec![23, 23, 43, 23, 23]);

        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(5)) {
            *x = 19;
        }
        assert_eq!(map.v.len(), 6);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 19, 19, 19, 19, 19]
        );
        // Should be seeing two blocks with 19
        assert_eq!(map.iter(Size::from_bytes(15), Size::from_bytes(2))
            .map(|&t| t).collect::<Vec<_>>(), vec![19, 19]);

        // a NOP iter_mut should trigger merging
        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(5)) { }
        assert_eq!(map.v.len(), 5);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 19, 19, 19, 19, 19]
        );
    }
}
<|endoftext|>