<commit_before>use std::str;

use std::ffi::{CStr,OsStr};
use std::path::Path;
use std::str::FromStr;

use libc::{c_char,dev_t};

use ::context::Context;
use ::handle::*;

pub fn new(context: &Context, device: *mut ::ffi::udev_device) -> Device {
    Device {
        _context: context,
        device: device,
    }
}

/// A structure that provides access to sysfs/kernel devices.
pub struct Device<'a> {
    _context: &'a Context,
    device: *mut ::ffi::udev_device,
}

impl<'a> Drop for Device<'a> {
    fn drop(&mut self) {
        unsafe {
            ::ffi::udev_device_unref(self.device);
        }
    }
}

#[doc(hidden)]
impl<'a> Handle<::ffi::udev_device> for Device<'a> {
    fn as_ptr(&self) -> *mut ::ffi::udev_device {
        self.device
    }
}

impl<'a> Device<'a> {
    /// Checks whether the device has already been handled by udev.
    ///
    /// When a new device is connected to the system, udev initializes the device by setting
    /// permissions, renaming network devices, and possibly other initialization routines. This
    /// method returns `true` if udev has performed all of its work to initialize this device.
    ///
    /// This method only applies to devices with device nodes or network interfaces. All other
    /// devices return `true` by default.
    pub fn is_initialized(&self) -> bool {
        unsafe {
            ::ffi::udev_device_get_is_initialized(self.device) > 0
        }
    }

    /// Gets the device's major/minor number.
    pub fn devnum(&self) -> Option<dev_t> {
        match unsafe { ::ffi::udev_device_get_devnum(self.device) } {
            0 => None,
            n => Some(n)
        }
    }

    /// Returns the syspath of the device.
    ///
    /// The path is an absolute path and includes the sys mount point. For example, the syspath for
    /// `tty0` could be `/sys/devices/virtual/tty/tty0`, which includes the sys mount point,
    /// `/sys`.
    pub fn syspath(&self) -> Option<&Path> {
        ::util::ptr_to_path(unsafe {
            ::ffi::udev_device_get_syspath(self.device)
        })
    }

    /// Returns the kernel devpath value of the device.
    ///
    /// The path does not contain the sys mount point, but does start with a `/`. For example, the
    /// devpath for `tty0` could be `/devices/virtual/tty/tty0`.
    pub fn devpath(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_devpath(self.device)
        })
    }

    /// Returns the path to the device node belonging to the device.
    ///
    /// The path is an absolute path and starts with the device directory. For example, the device
    /// node for `tty0` could be `/dev/tty0`.
    pub fn devnode(&self) -> Option<&Path> {
        ::util::ptr_to_path(unsafe {
            ::ffi::udev_device_get_devnode(self.device)
        })
    }

    /// Returns the parent of the device.
    pub fn parent(&self) -> Option<Device> {
        let ptr = unsafe { ::ffi::udev_device_get_parent(self.device) };

        if !ptr.is_null() {
            unsafe {
                ::ffi::udev_device_ref(ptr);
            }

            Some(Device {
                _context: self._context,
                device: ptr,
            })
        }
        else {
            None
        }
    }

    /// Returns the subsystem name of the device.
    ///
    /// The subsystem name is a string that indicates which kernel subsystem the device belongs to.
    /// Examples of subsystem names are `tty`, `vtconsole`, `block`, `scsi`, and `net`.
    pub fn subsystem(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe { ::ffi::udev_device_get_subsystem(self.device) })
    }

    /// Returns the kernel device name for the device.
    ///
    /// The sysname is a string that differentiates the device from others in the same subsystem.
    /// For example, `tty0` is the sysname for a TTY device that differentiates it from others,
    /// such as `tty1`.
    pub fn sysname(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_sysname(self.device)
        })
    }

    /// Returns the instance number of the device.
    ///
    /// The instance number is used to differentiate many devices of the same type. For example,
    /// `/dev/tty0` and `/dev/tty1` are both TTY devices but have instance numbers of 0 and 1,
    /// respectively.
    ///
    /// Some devices don't have instance numbers, such as `/dev/console`, in which case the method
    /// returns `None`.
    pub fn sysnum(&self) -> Option<usize> {
        let ptr = unsafe { ::ffi::udev_device_get_sysnum(self.device) };

        if !ptr.is_null() {
            match str::from_utf8(unsafe { CStr::from_ptr(ptr) }.to_bytes()) {
                Err(_) => None,
                Ok(s) => FromStr::from_str(s).ok()
            }
        }
        else {
            None
        }
    }

    /// Returns the devtype name of the device.
    pub fn devtype(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe { ::ffi::udev_device_get_devtype(self.device) })
    }

    /// Returns the name of the kernel driver attached to the device.
    pub fn driver(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe { ::ffi::udev_device_get_driver(self.device) })
    }

    /// Retreives the value of a device property.
    pub fn property_value<T: AsRef<OsStr>>(&self, property: T) -> Option<&OsStr> {
        let prop = match ::util::os_str_to_cstring(property) {
            Ok(s) => s,
            Err(_) => return None
        };

        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_property_value(self.device, prop.as_ptr())
        })
    }

    /// Retreives the value of a device attribute.
    pub fn attribute_value<T: AsRef<OsStr>>(&self, attribute: T) -> Option<&OsStr> {
        let attr = match ::util::os_str_to_cstring(attribute) {
            Ok(s) => s,
            Err(_) => return None
        };

        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_sysattr_value(self.device, attr.as_ptr())
        })
    }

    /// Sets the value of a device attribute.
    pub fn set_attribute_value<T: AsRef<OsStr>, U: AsRef<OsStr>>(&mut self, attribute: T, value: U) -> ::Result<()> {
        let attribute = try!(::util::os_str_to_cstring(attribute));
        let value = try!(::util::os_str_to_cstring(value));

        ::util::errno_to_result(unsafe {
            ::ffi::udev_device_set_sysattr_value(self.device, attribute.as_ptr(), value.as_ptr() as *mut c_char)
        })
    }

    /// Returns an iterator over the device's properties.
    ///
    /// ## Example
    ///
    /// This example prints out all of a device's properties:
    ///
    /// ```no_run
    /// # use std::path::Path;
    /// # let mut context = libudev::Context::new().unwrap();
    /// # let device = context.device_from_syspath(Path::new("/sys/devices/virtual/tty/tty0")).unwrap();
    /// for property in device.properties() {
    ///     println!("{:?} = {:?}", property.name(), property.value());
    /// }
    /// ```
    pub fn properties(&self) -> Properties {
        Properties {
            _device: self,
            entry: unsafe { ::ffi::udev_device_get_properties_list_entry(self.device) }
        }
    }

    /// Returns an iterator over the device's attributes.
    ///
    /// ## Example
    ///
    /// This example prints out all of a device's attributes:
    ///
    /// ```no_run
    /// # use std::path::Path;
    /// # let mut context = libudev::Context::new().unwrap();
    /// # let device = context.device_from_syspath(Path::new("/sys/devices/virtual/tty/tty0")).unwrap();
    /// for attribute in device.attributes() {
    ///     println!("{:?} = {:?}", attribute.name(), attribute.value());
    /// }
    /// ```
    pub fn attributes(&self) -> Attributes {
        Attributes {
            device: self,
            entry: unsafe { ::ffi::udev_device_get_sysattr_list_entry(self.device) }
        }
    }
}

/// Iterator over a device's properties.
pub struct Properties<'a> {
    _device: &'a Device<'a>,
    entry: *mut ::ffi::udev_list_entry
}

impl<'a> Iterator for Properties<'a> {
    type Item = Property<'a>;

    fn next(&mut self) -> Option<Property<'a>> {
        if self.entry.is_null() {
            None
        }
        else {
            let name = unsafe { ::util::ptr_to_os_str_unchecked(::ffi::udev_list_entry_get_name(self.entry)) };
            let value = unsafe { ::util::ptr_to_os_str_unchecked(::ffi::udev_list_entry_get_value(self.entry)) };

            self.entry = unsafe { ::ffi::udev_list_entry_get_next(self.entry) };

            Some(Property {
                name: name,
                value: value
            })
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

/// A device property.
pub struct Property<'a> {
    name: &'a OsStr,
    value: &'a OsStr
}

impl<'a> Property<'a> {
    /// Returns the property name.
    pub fn name(&self) -> &OsStr {
        self.name
    }

    /// Returns the property value.
    pub fn value(&self) -> &OsStr {
        self.value
    }
}

/// Iterator over a device's attributes.
pub struct Attributes<'a> {
    device: &'a Device<'a>,
    entry: *mut ::ffi::udev_list_entry
}

impl<'a> Iterator for Attributes<'a> {
    type Item = Attribute<'a>;

    fn next(&mut self) -> Option<Attribute<'a>> {
        if !self.entry.is_null() {
            let name = unsafe { ::util::ptr_to_os_str_unchecked(::ffi::udev_list_entry_get_name(self.entry)) };

            self.entry = unsafe { ::ffi::udev_list_entry_get_next(self.entry) };

            Some(Attribute {
                device: self.device,
                name: name
            })
        }
        else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

/// A device attribute.
pub struct Attribute<'a> {
    device: &'a Device<'a>,
    name: &'a OsStr
}

impl<'a> Attribute<'a> {
    /// Returns the attribute name.
    pub fn name(&self) -> &OsStr {
        self.name
    }

    /// Returns the attribute value.
    pub fn value(&self) -> Option<&OsStr> {
        self.device.attribute_value(self.name)
    }
}
<commit_msg>Fix a typo<commit_after>use std::str;

use std::ffi::{CStr,OsStr};
use std::path::Path;
use std::str::FromStr;

use libc::{c_char,dev_t};

use ::context::Context;
use ::handle::*;

pub fn new(context: &Context, device: *mut ::ffi::udev_device) -> Device {
    Device {
        _context: context,
        device: device,
    }
}

/// A structure that provides access to sysfs/kernel devices.
pub struct Device<'a> {
    _context: &'a Context,
    device: *mut ::ffi::udev_device,
}

impl<'a> Drop for Device<'a> {
    fn drop(&mut self) {
        unsafe {
            ::ffi::udev_device_unref(self.device);
        }
    }
}

#[doc(hidden)]
impl<'a> Handle<::ffi::udev_device> for Device<'a> {
    fn as_ptr(&self) -> *mut ::ffi::udev_device {
        self.device
    }
}

impl<'a> Device<'a> {
    /// Checks whether the device has already been handled by udev.
    ///
    /// When a new device is connected to the system, udev initializes the device by setting
    /// permissions, renaming network devices, and possibly other initialization routines. This
    /// method returns `true` if udev has performed all of its work to initialize this device.
    ///
    /// This method only applies to devices with device nodes or network interfaces. All other
    /// devices return `true` by default.
    pub fn is_initialized(&self) -> bool {
        unsafe {
            ::ffi::udev_device_get_is_initialized(self.device) > 0
        }
    }

    /// Gets the device's major/minor number.
    pub fn devnum(&self) -> Option<dev_t> {
        match unsafe { ::ffi::udev_device_get_devnum(self.device) } {
            0 => None,
            n => Some(n)
        }
    }

    /// Returns the syspath of the device.
    ///
    /// The path is an absolute path and includes the sys mount point. For example, the syspath for
    /// `tty0` could be `/sys/devices/virtual/tty/tty0`, which includes the sys mount point,
    /// `/sys`.
    pub fn syspath(&self) -> Option<&Path> {
        ::util::ptr_to_path(unsafe {
            ::ffi::udev_device_get_syspath(self.device)
        })
    }

    /// Returns the kernel devpath value of the device.
    ///
    /// The path does not contain the sys mount point, but does start with a `/`. For example, the
    /// devpath for `tty0` could be `/devices/virtual/tty/tty0`.
    pub fn devpath(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_devpath(self.device)
        })
    }

    /// Returns the path to the device node belonging to the device.
    ///
    /// The path is an absolute path and starts with the device directory. For example, the device
    /// node for `tty0` could be `/dev/tty0`.
    pub fn devnode(&self) -> Option<&Path> {
        ::util::ptr_to_path(unsafe {
            ::ffi::udev_device_get_devnode(self.device)
        })
    }

    /// Returns the parent of the device.
    pub fn parent(&self) -> Option<Device> {
        let ptr = unsafe { ::ffi::udev_device_get_parent(self.device) };

        if !ptr.is_null() {
            unsafe {
                ::ffi::udev_device_ref(ptr);
            }

            Some(Device {
                _context: self._context,
                device: ptr,
            })
        }
        else {
            None
        }
    }

    /// Returns the subsystem name of the device.
    ///
    /// The subsystem name is a string that indicates which kernel subsystem the device belongs to.
    /// Examples of subsystem names are `tty`, `vtconsole`, `block`, `scsi`, and `net`.
    pub fn subsystem(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe { ::ffi::udev_device_get_subsystem(self.device) })
    }

    /// Returns the kernel device name for the device.
    ///
    /// The sysname is a string that differentiates the device from others in the same subsystem.
    /// For example, `tty0` is the sysname for a TTY device that differentiates it from others,
    /// such as `tty1`.
    pub fn sysname(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_sysname(self.device)
        })
    }

    /// Returns the instance number of the device.
    ///
    /// The instance number is used to differentiate many devices of the same type. For example,
    /// `/dev/tty0` and `/dev/tty1` are both TTY devices but have instance numbers of 0 and 1,
    /// respectively.
    ///
    /// Some devices don't have instance numbers, such as `/dev/console`, in which case the method
    /// returns `None`.
    pub fn sysnum(&self) -> Option<usize> {
        let ptr = unsafe { ::ffi::udev_device_get_sysnum(self.device) };

        if !ptr.is_null() {
            match str::from_utf8(unsafe { CStr::from_ptr(ptr) }.to_bytes()) {
                Err(_) => None,
                Ok(s) => FromStr::from_str(s).ok()
            }
        }
        else {
            None
        }
    }

    /// Returns the devtype name of the device.
    pub fn devtype(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe { ::ffi::udev_device_get_devtype(self.device) })
    }

    /// Returns the name of the kernel driver attached to the device.
    pub fn driver(&self) -> Option<&OsStr> {
        ::util::ptr_to_os_str(unsafe { ::ffi::udev_device_get_driver(self.device) })
    }

    /// Retrieves the value of a device property.
    pub fn property_value<T: AsRef<OsStr>>(&self, property: T) -> Option<&OsStr> {
        let prop = match ::util::os_str_to_cstring(property) {
            Ok(s) => s,
            Err(_) => return None
        };

        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_property_value(self.device, prop.as_ptr())
        })
    }

    /// Retrieves the value of a device attribute.
    pub fn attribute_value<T: AsRef<OsStr>>(&self, attribute: T) -> Option<&OsStr> {
        let attr = match ::util::os_str_to_cstring(attribute) {
            Ok(s) => s,
            Err(_) => return None
        };

        ::util::ptr_to_os_str(unsafe {
            ::ffi::udev_device_get_sysattr_value(self.device, attr.as_ptr())
        })
    }

    /// Sets the value of a device attribute.
    pub fn set_attribute_value<T: AsRef<OsStr>, U: AsRef<OsStr>>(&mut self, attribute: T, value: U) -> ::Result<()> {
        let attribute = try!(::util::os_str_to_cstring(attribute));
        let value = try!(::util::os_str_to_cstring(value));

        ::util::errno_to_result(unsafe {
            ::ffi::udev_device_set_sysattr_value(self.device, attribute.as_ptr(), value.as_ptr() as *mut c_char)
        })
    }

    /// Returns an iterator over the device's properties.
    ///
    /// ## Example
    ///
    /// This example prints out all of a device's properties:
    ///
    /// ```no_run
    /// # use std::path::Path;
    /// # let mut context = libudev::Context::new().unwrap();
    /// # let device = context.device_from_syspath(Path::new("/sys/devices/virtual/tty/tty0")).unwrap();
    /// for property in device.properties() {
    ///     println!("{:?} = {:?}", property.name(), property.value());
    /// }
    /// ```
    pub fn properties(&self) -> Properties {
        Properties {
            _device: self,
            entry: unsafe { ::ffi::udev_device_get_properties_list_entry(self.device) }
        }
    }

    /// Returns an iterator over the device's attributes.
    ///
    /// ## Example
    ///
    /// This example prints out all of a device's attributes:
    ///
    /// ```no_run
    /// # use std::path::Path;
    /// # let mut context = libudev::Context::new().unwrap();
    /// # let device = context.device_from_syspath(Path::new("/sys/devices/virtual/tty/tty0")).unwrap();
    /// for attribute in device.attributes() {
    ///     println!("{:?} = {:?}", attribute.name(), attribute.value());
    /// }
    /// ```
    pub fn attributes(&self) -> Attributes {
        Attributes {
            device: self,
            entry: unsafe { ::ffi::udev_device_get_sysattr_list_entry(self.device) }
        }
    }
}

/// Iterator over a device's properties.
pub struct Properties<'a> {
    _device: &'a Device<'a>,
    entry: *mut ::ffi::udev_list_entry
}

impl<'a> Iterator for Properties<'a> {
    type Item = Property<'a>;

    fn next(&mut self) -> Option<Property<'a>> {
        if self.entry.is_null() {
            None
        }
        else {
            let name = unsafe { ::util::ptr_to_os_str_unchecked(::ffi::udev_list_entry_get_name(self.entry)) };
            let value = unsafe { ::util::ptr_to_os_str_unchecked(::ffi::udev_list_entry_get_value(self.entry)) };

            self.entry = unsafe { ::ffi::udev_list_entry_get_next(self.entry) };

            Some(Property {
                name: name,
                value: value
            })
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

/// A device property.
pub struct Property<'a> {
    name: &'a OsStr,
    value: &'a OsStr
}

impl<'a> Property<'a> {
    /// Returns the property name.
    pub fn name(&self) -> &OsStr {
        self.name
    }

    /// Returns the property value.
    pub fn value(&self) -> &OsStr {
        self.value
    }
}

/// Iterator over a device's attributes.
pub struct Attributes<'a> {
    device: &'a Device<'a>,
    entry: *mut ::ffi::udev_list_entry
}

impl<'a> Iterator for Attributes<'a> {
    type Item = Attribute<'a>;

    fn next(&mut self) -> Option<Attribute<'a>> {
        if !self.entry.is_null() {
            let name = unsafe { ::util::ptr_to_os_str_unchecked(::ffi::udev_list_entry_get_name(self.entry)) };

            self.entry = unsafe { ::ffi::udev_list_entry_get_next(self.entry) };

            Some(Attribute {
                device: self.device,
                name: name
            })
        }
        else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

/// A device attribute.
pub struct Attribute<'a> {
    device: &'a Device<'a>,
    name: &'a OsStr
}

impl<'a> Attribute<'a> {
    /// Returns the attribute name.
    pub fn name(&self) -> &OsStr {
        self.name
    }

    /// Returns the attribute value.
    pub fn value(&self) -> Option<&OsStr> {
        self.device.attribute_value(self.name)
    }
}
<|endoftext|>


<commit_before>use std;

// macro_rules! if_any_divides {
//      ( $( $div:tt ),* | $n:ident $if_b:block ) => { if $(($n % $div == 0))|* $if_b};
// }
// macro_rules! if_sm_prime_divides{
//     ( $n:ident $if_b:block ) => {if_any_divides!(
//     2, 3, 5, 7, 11, 13,
//     17, 19, 23, 29, 31,
//     37, 41, 43, 47, 53,
//     59, 61, 67, 71, 73,
//     79, 83, 89, 97, 101,
//     103, 107, 109, 113, 127,
//     131, 137, 139, 149, 151,
//     157, 163, 167, 173, 179,
//     181, 191, 193, 197, 199 | $n $if_b)};
// }
macro_rules! set_true_if_in_range{
    ( $( $i:tt ),* => $filter:ident + $offset:expr, $min:expr, $max:expr) => {
        $(if ($min <= $i) & ($max > $i) {$filter[$i-$offset] = true;})*
    };
    ( $( $i:tt ),* => $filter:ident, $min:expr, $max:expr) => {
        $(if ($min <= $i) & ($max > $i) {$filter[$i] = true;})*
    };
}
// macro_rules! set_sm_primes_true {
//     ($filter:expr, $min:expr, $max:expr) => {
//         set_true_if_in_range!(
//         2, 3, 5, 7, 11, 13,
//         17, 19, 23, 29, 31,
//         37, 41, 43, 47, 53,
//         59, 61, 67, 71, 73,
//         79, 83, 89, 97, 101,
//         103, 107, 109, 113, 127,
//         131, 137, 139, 149, 151,
//         157, 163, 167, 173, 179,
//         181, 191, 193, 197, 199 => $filter + $min, $min, $max)
//     };
// }

fn int_sqrt(n:usize) -> usize{
    match n {
        0 => 0,
        1 ... 3 => 1,
        4 ... 8 => 2,
        9 ... 15 => 3,
        k => {
        let mut x = k;
            loop{
                x = match (x + n/x) >> 1 {
                    new_x if new_x == x => break,
                    new_x if new_x*new_x == n + 1 => {x = new_x - 1; break},
                    new_x => new_x,
                };
            }
            x
        },
    }

}

fn ceil_sqrt(n:usize) -> usize{
    match int_sqrt(n){
        sqrt if sqrt*sqrt == n => sqrt,
        sqrt => sqrt+1,
    }
}

pub fn prime_filter(iter_size: usize) -> Vec<bool>{
    if iter_size<100{
        slow_prime_filter(iter_size)
    }else{
        prime_filter_section(0, iter_size)
    }
}
pub fn prime_filter_section(min:usize, max: usize) -> Vec<bool>{
    //Sieve of Atkin
    assert!(min<max);
    let mut prime_filter = vec![false; max-min];

    set_true_if_in_range!(2, 3, 5 => prime_filter + min, min, max);
    //Macro equivilent:
    // if (min <= 2) & (max > 2) {prime_filter[2-min] = true;}
    // if (min <= 3) & (max > 3) {prime_filter[3-min] = true;}
    // if (min <= 5) & (max > 5) {prime_filter[5-min] = true;}

    let (mut y_sq, mut to_next_y_sq) = (1, 3);

    while y_sq<max {
        if y_sq%2 == 1 {
            //CASE 1
            //n_1 = 4x^2 + y^2 === 1 (mod 4)
            let (mut n_1, mut to_next_n_1) = match y_sq < min {
                false => (y_sq+4, 12),
                _ => {
                    let min_x = ceil_sqrt((min - y_sq)/4);
                    (4*min_x*min_x + y_sq, 8*min_x + 4)
                },
            };
            loop{

                match n_1{
                    n if n >= max => break,
                    n => {match n%60{
                        1 | 13 | 17 | 29 | 37 | 41 | 49 | 53 => match n.checked_sub(min){
                            Some(i) => prime_filter[i] ^= true,
                            None => (),
                        },
                        _ => (),
                    };},
                };

                n_1 += to_next_n_1;
                to_next_n_1 += 8;
            };
        };
        if y_sq%3 == 1 {
            //CASE 2
            //n_2 = 3x^2 + y^2 === 1 (mod 6)
            let (mut n_2, mut to_next_n_2) = match y_sq < min {
                false => (y_sq+3, 9),
                _ => {
                    let min_x = ceil_sqrt((min - y_sq)/3);
                    (3*min_x*min_x + y_sq, 6*min_x + 3)
                },
            };
            loop {
                match n_2{
                    n if n >= max => break,
                    n => {match n%60{
                            7 | 19 | 31 | 43 => match n.checked_sub(min){
                                Some(i) => prime_filter[i] ^= true,
                                None => (),
                            },
                            _ => (),
                        };}
                };
                n_2 += to_next_n_2;
                to_next_n_2 += 6;
            };
            //CASE 3
            //n_3 = 3x^2 - y^2 === 11 (mod 12)
            //Initially, we set x = y+1 -> n_3 = 3(y+1)^2 - y^2 = 2*y^2 + 6*y + 3
            //Amd then hop x by 2 each iteration.
            let (mut n_3, mut to_next_n_3) = match (y_sq << 1) < min {
                false => (2*y_sq+3*to_next_y_sq, 6*to_next_y_sq+18),
                _ => {
                    let min_x = match ceil_sqrt((min + y_sq)/3){
                        mx if (mx+y_sq)%2 == 0 => mx + 1,
                        mx => mx,
                    };
                    (3*min_x*min_x - y_sq, 12*min_x + 12)
                },
            };
            loop {
                match n_3{
                    n if n >= max => break,
                    n => {match n%60{
                            11 | 23 | 47 | 59 => match n.checked_sub(min){
                                Some(i) => prime_filter[i] ^= true,
                                None => (),
                            },
                            _ => (),
                    };},
                };
                n_3 += to_next_n_3;
                to_next_n_3 += 24;
            };
        };
        while{ //Do-while
            y_sq += to_next_y_sq;
            to_next_y_sq += 2;
            y_sq%6 == 0
        } {};
    };

    //Eliminate non-squarefree numbers
    let mut n_sq = 49; // 7^2
    let mut next_n_sq = 32; //9^2 - 7^2, skip even numbers.
    while n_sq < max {
        let mut non_sq_free = n_sq;
        while non_sq_free < max {
            if non_sq_free >= min {
                prime_filter[non_sq_free - min] = false;
            }
            while{ //Do-while
                non_sq_free += n_sq + n_sq;
                (non_sq_free%3==0) | (non_sq_free%5==0)
            } {};
        };
        while{ //Do-while
            n_sq += next_n_sq;
            next_n_sq += 8;
            (n_sq%3==0) | (n_sq%5 == 0)
        } {};
    }
    prime_filter
}

#[cfg(test)]
pub fn old_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    slow_prime_filter(iter_size)
}

#[test]
fn private_filter_test(){
    assert_eq!(5, ceil_sqrt(24));
    assert_eq!(2, int_sqrt(4));
    assert_eq!(4, int_sqrt(24));
    assert_eq!(10, int_sqrt(101));
    assert_eq!(1, int_sqrt(1));
    assert_eq!(10, int_sqrt(100));
    assert_eq!(3, int_sqrt(13));
}

fn slow_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    if iter_size < 5 {
         let mut ret = vec![false, false, true, true];
         ret.truncate(iter_size);
         return ret
     }
    let mut prime_filter = vec![true; iter_size];
    prime_filter[0] = false;
    prime_filter[1] = false;
    let mut cur_num = 2;
    'outer: loop{
        for i in (cur_num+1)..iter_size{
            if 0 == i%cur_num { prime_filter[i] = false; }
        }
        cur_num += 1;
        while !prime_filter[cur_num]{
            if cur_num*cur_num > iter_size {
                break 'outer
            }
            cur_num += 1;
        }
    };
    prime_filter
}
<commit_msg>Import num_cpus<commit_after>extern crate num_cpus;

use std;

// macro_rules! if_any_divides {
//      ( $( $div:tt ),* | $n:ident $if_b:block ) => { if $(($n % $div == 0))|* $if_b};
// }
// macro_rules! if_sm_prime_divides{
//     ( $n:ident $if_b:block ) => {if_any_divides!(
//     2, 3, 5, 7, 11, 13,
//     17, 19, 23, 29, 31,
//     37, 41, 43, 47, 53,
//     59, 61, 67, 71, 73,
//     79, 83, 89, 97, 101,
//     103, 107, 109, 113, 127,
//     131, 137, 139, 149, 151,
//     157, 163, 167, 173, 179,
//     181, 191, 193, 197, 199 | $n $if_b)};
// }
macro_rules! set_true_if_in_range{
    ( $( $i:tt ),* => $filter:ident + $offset:expr, $min:expr, $max:expr) => {
        $(if ($min <= $i) & ($max > $i) {$filter[$i-$offset] = true;})*
    };
    ( $( $i:tt ),* => $filter:ident, $min:expr, $max:expr) => {
        $(if ($min <= $i) & ($max > $i) {$filter[$i] = true;})*
    };
}
// macro_rules! set_sm_primes_true {
//     ($filter:expr, $min:expr, $max:expr) => {
//         set_true_if_in_range!(
//         2, 3, 5, 7, 11, 13,
//         17, 19, 23, 29, 31,
//         37, 41, 43, 47, 53,
//         59, 61, 67, 71, 73,
//         79, 83, 89, 97, 101,
//         103, 107, 109, 113, 127,
//         131, 137, 139, 149, 151,
//         157, 163, 167, 173, 179,
//         181, 191, 193, 197, 199 => $filter + $min, $min, $max)
//     };
// }

fn int_sqrt(n:usize) -> usize{
    match n {
        0 => 0,
        1 ... 3 => 1,
        4 ... 8 => 2,
        9 ... 15 => 3,
        k => {
        let mut x = k;
            loop{
                x = match (x + n/x) >> 1 {
                    new_x if new_x == x => break,
                    new_x if new_x*new_x == n + 1 => {x = new_x - 1; break},
                    new_x => new_x,
                };
            }
            x
        },
    }

}

fn ceil_sqrt(n:usize) -> usize{
    match int_sqrt(n){
        sqrt if sqrt*sqrt == n => sqrt,
        sqrt => sqrt+1,
    }
}

pub fn prime_filter(iter_size: usize) -> Vec<bool>{
    if iter_size<100{
        slow_prime_filter(iter_size)
    }else{
        prime_filter_section(0, iter_size)
    }
}
pub fn prime_filter_section(min:usize, max: usize) -> Vec<bool>{
    //Sieve of Atkin
    assert!(min<max);
    let mut prime_filter = vec![false; max-min];

    set_true_if_in_range!(2, 3, 5 => prime_filter + min, min, max);
    //Macro equivilent:
    // if (min <= 2) & (max > 2) {prime_filter[2-min] = true;}
    // if (min <= 3) & (max > 3) {prime_filter[3-min] = true;}
    // if (min <= 5) & (max > 5) {prime_filter[5-min] = true;}

    let (mut y_sq, mut to_next_y_sq) = (1, 3);

    while y_sq<max {
        if y_sq%2 == 1 {
            //CASE 1
            //n_1 = 4x^2 + y^2 === 1 (mod 4)
            let (mut n_1, mut to_next_n_1) = match y_sq < min {
                false => (y_sq+4, 12),
                _ => {
                    let min_x = ceil_sqrt((min - y_sq)/4);
                    (4*min_x*min_x + y_sq, 8*min_x + 4)
                },
            };
            loop{

                match n_1{
                    n if n >= max => break,
                    n => {match n%60{
                        1 | 13 | 17 | 29 | 37 | 41 | 49 | 53 => match n.checked_sub(min){
                            Some(i) => prime_filter[i] ^= true,
                            None => (),
                        },
                        _ => (),
                    };},
                };

                n_1 += to_next_n_1;
                to_next_n_1 += 8;
            };
        };
        if y_sq%3 == 1 {
            //CASE 2
            //n_2 = 3x^2 + y^2 === 1 (mod 6)
            let (mut n_2, mut to_next_n_2) = match y_sq < min {
                false => (y_sq+3, 9),
                _ => {
                    let min_x = ceil_sqrt((min - y_sq)/3);
                    (3*min_x*min_x + y_sq, 6*min_x + 3)
                },
            };
            loop {
                match n_2{
                    n if n >= max => break,
                    n => {match n%60{
                            7 | 19 | 31 | 43 => match n.checked_sub(min){
                                Some(i) => prime_filter[i] ^= true,
                                None => (),
                            },
                            _ => (),
                        };}
                };
                n_2 += to_next_n_2;
                to_next_n_2 += 6;
            };
            //CASE 3
            //n_3 = 3x^2 - y^2 === 11 (mod 12)
            //Initially, we set x = y+1 -> n_3 = 3(y+1)^2 - y^2 = 2*y^2 + 6*y + 3
            //Amd then hop x by 2 each iteration.
            let (mut n_3, mut to_next_n_3) = match (y_sq << 1) < min {
                false => (2*y_sq+3*to_next_y_sq, 6*to_next_y_sq+18),
                _ => {
                    let min_x = match ceil_sqrt((min + y_sq)/3){
                        mx if (mx+y_sq)%2 == 0 => mx + 1,
                        mx => mx,
                    };
                    (3*min_x*min_x - y_sq, 12*min_x + 12)
                },
            };
            loop {
                match n_3{
                    n if n >= max => break,
                    n => {match n%60{
                            11 | 23 | 47 | 59 => match n.checked_sub(min){
                                Some(i) => prime_filter[i] ^= true,
                                None => (),
                            },
                            _ => (),
                    };},
                };
                n_3 += to_next_n_3;
                to_next_n_3 += 24;
            };
        };
        while{ //Do-while
            y_sq += to_next_y_sq;
            to_next_y_sq += 2;
            y_sq%6 == 0
        } {};
    };

    //Eliminate non-squarefree numbers
    let mut n_sq = 49; // 7^2
    let mut next_n_sq = 32; //9^2 - 7^2, skip even numbers.
    while n_sq < max {
        let mut non_sq_free = n_sq;
        while non_sq_free < max {
            if non_sq_free >= min {
                prime_filter[non_sq_free - min] = false;
            }
            while{ //Do-while
                non_sq_free += n_sq + n_sq;
                (non_sq_free%3==0) | (non_sq_free%5==0)
            } {};
        };
        while{ //Do-while
            n_sq += next_n_sq;
            next_n_sq += 8;
            (n_sq%3==0) | (n_sq%5 == 0)
        } {};
    }
    prime_filter
}

#[cfg(test)]
pub fn old_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    slow_prime_filter(iter_size)
}

#[test]
fn private_filter_test(){
    assert_eq!(5, ceil_sqrt(24));
    assert_eq!(2, int_sqrt(4));
    assert_eq!(4, int_sqrt(24));
    assert_eq!(10, int_sqrt(101));
    assert_eq!(1, int_sqrt(1));
    assert_eq!(10, int_sqrt(100));
    assert_eq!(3, int_sqrt(13));
}

fn slow_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    if iter_size < 5 {
         let mut ret = vec![false, false, true, true];
         ret.truncate(iter_size);
         return ret
     }
    let mut prime_filter = vec![true; iter_size];
    prime_filter[0] = false;
    prime_filter[1] = false;
    let mut cur_num = 2;
    'outer: loop{
        for i in (cur_num+1)..iter_size{
            if 0 == i%cur_num { prime_filter[i] = false; }
        }
        cur_num += 1;
        while !prime_filter[cur_num]{
            if cur_num*cur_num > iter_size {
                break 'outer
            }
            cur_num += 1;
        }
    };
    prime_filter
}
<|endoftext|>


<commit_before>use super::*;
use derivative::Derivative;
use log::LevelFilter;
use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Config, Root};
use log4rs::encode::pattern::PatternEncoder;

#[derive(Derivative)]
#[derivative(Debug)]
#[derive(Serialize)]
pub struct Logger {
    pub level: LevelFilter,
    pub path: Option<PathBuf>,

    #[derivative(Debug = "ignore")]
    #[serde(skip_serializing)]
    handle: log4rs::Handle,
}

impl Logger {
    pub fn new() -> Fallible<Self> {
        let level = LevelFilter::Warn;
        let path = None;

        let config = create_config(&path, level)?;
        let handle = log4rs::init_config(config)?;
        Ok(Logger {
            path,
            level,
            handle,
        })
    }

    pub fn update_settings(&mut self, level: LevelFilter, path: Option<PathBuf>) -> Fallible<()> {
        let config = create_config(&path, level)?;
        self.handle.set_config(config);
        self.level = level;
        self.path = path;
        Ok(())
    }

    pub fn set_level(&mut self, level: LevelFilter) -> Fallible<()> {
        let config = create_config(&self.path, level)?;
        self.handle.set_config(config);
        self.level = level;
        Ok(())
    }

    #[allow(dead_code)]
    pub fn set_path(&mut self, path: Option<PathBuf>) -> Fallible<()> {
        let config = create_config(&path, self.level)?;
        self.handle.set_config(config);
        self.path = path;
        Ok(())
    }
}

fn create_config(path: &Option<PathBuf>, level: LevelFilter) -> Fallible<Config> {
    let encoder =
        PatternEncoder::new("{date(%H:%M:%S)} {level} {thread} {file}:{line} {message}{n}");

    let mut config_builder =
        Config::builder().logger(log4rs::config::Logger::builder().build("languageclient", level));

    let mut root_builder = Root::builder();
    if let Some(path) = path {
        #[cfg(any(target_os = "linux", target_os = "macos"))]
        let path = shellexpand::tilde(&path.to_string_lossy()).to_string();

        // Ensure log file writable.
        {
            let mut f = std::fs::OpenOptions::new()
                .create(true)
                .write(true)
                .truncate(true)
                .open(&path)
                .with_context(|err| format!("Failed to open file ({}): {}", path, err))?;
            #[allow(clippy::write_literal)]
            writeln!(
                f,
                "#######\nLanguageClient {} {}\n#######",
                env!("CARGO_PKG_VERSION"),
                env!("GIT_HASH")
            )?;
        }

        let appender = FileAppender::builder()
            .encoder(Box::new(encoder))
            .build(path)?;
        config_builder =
            config_builder.appender(Appender::builder().build("logfile", Box::new(appender)));
        root_builder = root_builder.appender("logfile");
    }
    let config = config_builder.build(root_builder.build(level))?;
    Ok(config)
}
<commit_msg>Fix compiling for Windows<commit_after>use super::*;
use derivative::Derivative;
use log::LevelFilter;
use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Config, Root};
use log4rs::encode::pattern::PatternEncoder;

#[derive(Derivative)]
#[derivative(Debug)]
#[derive(Serialize)]
pub struct Logger {
    pub level: LevelFilter,
    pub path: Option<PathBuf>,

    #[derivative(Debug = "ignore")]
    #[serde(skip_serializing)]
    handle: log4rs::Handle,
}

impl Logger {
    pub fn new() -> Fallible<Self> {
        let level = LevelFilter::Warn;
        let path = None;

        let config = create_config(&path, level)?;
        let handle = log4rs::init_config(config)?;
        Ok(Logger {
            path,
            level,
            handle,
        })
    }

    pub fn update_settings(&mut self, level: LevelFilter, path: Option<PathBuf>) -> Fallible<()> {
        let config = create_config(&path, level)?;
        self.handle.set_config(config);
        self.level = level;
        self.path = path;
        Ok(())
    }

    pub fn set_level(&mut self, level: LevelFilter) -> Fallible<()> {
        let config = create_config(&self.path, level)?;
        self.handle.set_config(config);
        self.level = level;
        Ok(())
    }

    #[allow(dead_code)]
    pub fn set_path(&mut self, path: Option<PathBuf>) -> Fallible<()> {
        let config = create_config(&path, self.level)?;
        self.handle.set_config(config);
        self.path = path;
        Ok(())
    }
}

fn create_config(path: &Option<PathBuf>, level: LevelFilter) -> Fallible<Config> {
    let encoder =
        PatternEncoder::new("{date(%H:%M:%S)} {level} {thread} {file}:{line} {message}{n}");

    let mut config_builder =
        Config::builder().logger(log4rs::config::Logger::builder().build("languageclient", level));

    let mut root_builder = Root::builder();
    if let Some(path) = path {
        let path = shellexpand::tilde(&path.to_string_lossy()).to_string();

        // Ensure log file writable.
        {
            let mut f = std::fs::OpenOptions::new()
                .create(true)
                .write(true)
                .truncate(true)
                .open(&path)
                .with_context(|err| format!("Failed to open file ({}): {}", path, err))?;
            #[allow(clippy::write_literal)]
            writeln!(
                f,
                "#######\nLanguageClient {} {}\n#######",
                env!("CARGO_PKG_VERSION"),
                env!("GIT_HASH")
            )?;
        }

        let appender = FileAppender::builder()
            .encoder(Box::new(encoder))
            .build(path)?;
        config_builder =
            config_builder.appender(Appender::builder().build("logfile", Box::new(appender)));
        root_builder = root_builder.appender("logfile");
    }
    let config = config_builder.build(root_builder.build(level))?;
    Ok(config)
}
<|endoftext|>


<commit_before>// Copyright © 2015, Peter Atashian
// Licensed under the MIT License <LICENSE.md>
//! Macros to make things easier to define
macro_rules! DECLARE_HANDLE {
    ($name:ident, $inner:ident) => {
        #[allow(missing_copy_implementations)] pub enum $inner { }
        pub type $name = *mut $inner;
    };
}
macro_rules! MAKE_HRESULT {
    ($sev:expr, $fac:expr, $code:expr) => {
        ($sev << 31) | ($fac << 16) | $code
    }
}
macro_rules! MAKE_SCODE {
    ($sev:expr, $fac:expr, $code:expr) => {
        ($sev << 31) | ($fac << 16) | $code
    }
}
macro_rules! HIDP_ERROR_CODES {
    ($sev:expr, $code:expr) => {
        ($sev << 28) | (FACILITY_HID_ERROR_CODE << 16) | $code
    }
}
macro_rules! MAKEFOURCC {
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        ($a as u32) | (($b as u32) << 8) | (($c as u32) << 16) | (($d as u32) << 24)
    }
}
macro_rules! DEFINE_GUID {
    (
        $name:ident, $l:expr, $w1:expr, $w2:expr,
        $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
    ) => {
        pub const $name: $crate::shared::guiddef::GUID = $crate::shared::guiddef::GUID {
            Data1: $l,
            Data2: $w1,
            Data3: $w2,
            Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
        };
    }
}
macro_rules! CTL_CODE {
    ($DeviceType:expr, $Function:expr, $Method:expr, $Access:expr) => {
        ($DeviceType << 16) | ($Access << 14) | ($Function << 2) | $Method
    }
}
macro_rules! HID_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_NEITHER, FILE_ANY_ACCESS)
    }
}
macro_rules! HID_BUFFER_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_BUFFERED, FILE_ANY_ACCESS)
    }
}
macro_rules! HID_IN_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
    }
}
macro_rules! HID_OUT_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
    }
}
macro_rules! AUDCLNT_ERR {
    ($n:expr) => {
        MAKE_HRESULT!(SEVERITY_ERROR, FACILITY_AUDCLNT, $n)
    };
}
macro_rules! AUDCLNT_SUCCESS {
    ($n:expr) => {
        MAKE_SCODE!(SEVERITY_SUCCESS, FACILITY_AUDCLNT, $n)
    };
}
macro_rules! BCRYPT_MAKE_INTERFACE_VERSION {
    ($major:expr, $minor:expr) => {
        $crate::shared::bcrypt::BCRYPT_INTERFACE_VERSION {
            MajorVersion: $major, MinorVersion: $minor,
        }
    }
}
macro_rules! RIDL {
    (#[uuid($($uuid:expr),+)]
    interface $interface:ident ($vtbl:ident) {$(
        fn $method:ident($($p:ident : $t:ty),*) -> $rtr:ty
    ),+}) => (
        #[repr(C)]
        pub struct $vtbl {
            $(pub $method: unsafe extern "system" fn(
                This: *mut $interface,
                $($p: $t),*
            ) -> $rtr),+
        }
        #[repr(C)]
        pub struct $interface {
            pub lpVtbl: *const $vtbl,
        }
        RIDL!{@impl $interface {$(fn $method($($p: $t),*) -> $rtr),+}}
        RIDL!{@uuid $interface $($uuid),+}
    );
    (#[uuid($($uuid:expr),+)]
    interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {
    }) => (
        #[repr(C)]
        pub struct $vtbl {
            pub parent: $pvtbl,
        }
        #[repr(C)]
        pub struct $interface {
            pub lpVtbl: *const $vtbl,
        }
        RIDL!{@deref $interface $pinterface}
        RIDL!{@uuid $interface $($uuid),+}
    );
    (interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$(
        fn $method:ident($($p:ident : $t:ty),*) -> $rtr:ty
    ),+}) => (
        #[repr(C)]
        pub struct $vtbl {
            pub parent: $pvtbl
            $(,pub $method: unsafe extern "system" fn(
                This: *mut $interface,
                $($p: $t),*
            ) -> $rtr)+
        }
        #[repr(C)]
        pub struct $interface {
            pub lpVtbl: *const $vtbl,
        }
        RIDL!{@impl $interface {$(fn $method($($p: $t),*) -> $rtr),+}}
        RIDL!{@deref $interface $pinterface}
    );
    (#[uuid($($uuid:expr),+)]
    interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$(
        fn $method:ident($($p:ident : $t:ty),*) -> $rtr:ty
    ),+}) => (
        #[repr(C)]
        pub struct $vtbl {
            pub parent: $pvtbl
            $(,pub $method: unsafe extern "system" fn(
                This: *mut $interface,
                $($p: $t),*
            ) -> $rtr)+
        }
        #[repr(C)]
        pub struct $interface {
            pub lpVtbl: *const $vtbl,
        }
        RIDL!{@impl $interface {$(fn $method($($p: $t),*) -> $rtr),+}}
        RIDL!{@deref $interface $pinterface}
        RIDL!{@uuid $interface $($uuid),+}
    );
    (@deref $interface:ident $pinterface:ident) => (
        impl $crate::core::ops::Deref for $interface {
            type Target = $pinterface;
            #[inline]
            fn deref(&self) -> &$pinterface {
                unsafe { &*(self as *const $interface as *const $pinterface) }
            }
        }
    );
    (@impl $interface:ident {$(
        fn $method:ident($($p:ident : $t:ty),*) -> $rtr:ty
    ),+}) => (
        impl $interface {
            $(#[inline] pub unsafe fn $method(&self $(,$p: $t)*) -> $rtr {
                ((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p),*)
            })+
        }
    );
    (@uuid $interface:ident
        $l:expr, $w1:expr, $w2:expr,
        $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
    ) => (
        impl ::Interface for $interface {
            #[inline]
            fn uuidof() -> $crate::shared::guiddef::GUID {
                $crate::shared::guiddef::GUID {
                    Data1: $l,
                    Data2: $w1,
                    Data3: $w2,
                    Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
                }
            }
        }
    );
}
macro_rules! UNION {
    ($base:ident, $field:ident, $variant:ident, $variantmut:ident, $fieldtype:ty) => {
        impl $base {
            #[inline]
            pub unsafe fn $variant(&self) -> &$fieldtype {
                &*(&self.$field as *const _ as *const _)
            }
            #[inline]
            pub unsafe fn $variantmut(&mut self) -> &mut $fieldtype {
                &mut *(&mut self.$field as *mut _ as *mut _)
            }
        }
    }
}
macro_rules! BITFIELD {
    ($base:ident $field:ident: $fieldtype:ty [
        $($thing:ident $set_thing:ident[$r:expr],)+
    ]) => {
        impl $base {$(
            #[inline]
            pub fn $thing(&self) -> $fieldtype {
                let size = $crate::core::mem::size_of::<$fieldtype>() * 8;
                self.$field << (size - $r.end) >> (size - $r.end + $r.start)
            }
            #[inline]
            pub fn $set_thing(&mut self, val: $fieldtype) {
                let mask = ((1 << ($r.end - $r.start)) - 1) << $r.start;
                self.$field &= !mask;
                self.$field |= (val << $r.start) & mask;
            }
        )+}
    }
}
macro_rules! ENUM {
    {enum $name:ident { $($variant:ident = $value:expr,)+ }} => {
        pub type $name = u32;
        $(pub const $variant: u32 = $value;)+
    };
    {enum $name:ident { $variant:ident = $value:expr, $($rest:tt)* }} => {
        pub type $name = u32;
        pub const $variant: u32 = $value;
        ENUM!{@gen $name $variant, $($rest)*}
    };
    {enum $name:ident { $variant:ident, $($rest:tt)* }} => {
        ENUM!{enum $name { $variant = 0, $($rest)* }}
    };
    {@gen $name:ident $base:ident,} => {};
    {@gen $name:ident $base:ident, $variant:ident = $value:expr, $($rest:tt)*} => {
        pub const $variant: $name = $value;
        ENUM!{@gen $name $variant, $($rest)*}
    };
    {@gen $name:ident $base:ident, $variant:ident, $($rest:tt)*} => {
        pub const $variant: $name = $base + 1u32;
        ENUM!{@gen $name $variant, $($rest)*}
    };
}
macro_rules! STRUCT {
    {$(#[$attrs:meta])* struct $name:ident { $($field:ident: $ftype:ty,)+ }} => {
        #[repr(C)] $(#[$attrs])*
        pub struct $name {
            $(pub $field: $ftype,)+
        }
        impl Copy for $name {}
        impl Clone for $name {
            #[inline]
            fn clone(&self) -> $name { *self }
        }
    };
}
macro_rules! EXTERN {
    (stdcall fn $func:ident(
        $($p:ident: $t:ty),*
    ) -> $ret:ty) => (EXTERN!{@fix
        extern "stdcall" {
            pub fn $func(
                $($p: $t),*
            ) -> $ret;
        }
    });
    (cdecl fn $func:ident(
        $($p:ident: $t:ty),*
    ) -> $ret:ty) => (EXTERN!{@fix
        extern "cdecl" {
            pub fn $func(
                $($p: $t),*
            ) -> $ret;
        }
    });
    (@fix $x:item) => ($x);
}
macro_rules! IFDEF {
    ($($thing:item)*) => ($($thing)*)
}
macro_rules! FN {
    (stdcall $func:ident($($t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "stdcall" fn($($t),*) -> $ret>;
    );
    (stdcall $func:ident($($p:ident: $t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "stdcall" fn($($p: $t),*) -> $ret>;
    );
    (cdecl $func:ident($($t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "cdecl" fn($($t),*) -> $ret>;
    );
    (cdecl $func:ident($($p:ident: $t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "cdecl" fn($($p: $t),*) -> $ret>;
    );
}
<commit_msg>Remove no longer needed RIDL branch<commit_after>// Copyright © 2015, Peter Atashian
// Licensed under the MIT License <LICENSE.md>
//! Macros to make things easier to define
macro_rules! DECLARE_HANDLE {
    ($name:ident, $inner:ident) => {
        #[allow(missing_copy_implementations)] pub enum $inner { }
        pub type $name = *mut $inner;
    };
}
macro_rules! MAKE_HRESULT {
    ($sev:expr, $fac:expr, $code:expr) => {
        ($sev << 31) | ($fac << 16) | $code
    }
}
macro_rules! MAKE_SCODE {
    ($sev:expr, $fac:expr, $code:expr) => {
        ($sev << 31) | ($fac << 16) | $code
    }
}
macro_rules! HIDP_ERROR_CODES {
    ($sev:expr, $code:expr) => {
        ($sev << 28) | (FACILITY_HID_ERROR_CODE << 16) | $code
    }
}
macro_rules! MAKEFOURCC {
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        ($a as u32) | (($b as u32) << 8) | (($c as u32) << 16) | (($d as u32) << 24)
    }
}
macro_rules! DEFINE_GUID {
    (
        $name:ident, $l:expr, $w1:expr, $w2:expr,
        $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
    ) => {
        pub const $name: $crate::shared::guiddef::GUID = $crate::shared::guiddef::GUID {
            Data1: $l,
            Data2: $w1,
            Data3: $w2,
            Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
        };
    }
}
macro_rules! CTL_CODE {
    ($DeviceType:expr, $Function:expr, $Method:expr, $Access:expr) => {
        ($DeviceType << 16) | ($Access << 14) | ($Function << 2) | $Method
    }
}
macro_rules! HID_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_NEITHER, FILE_ANY_ACCESS)
    }
}
macro_rules! HID_BUFFER_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_BUFFERED, FILE_ANY_ACCESS)
    }
}
macro_rules! HID_IN_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
    }
}
macro_rules! HID_OUT_CTL_CODE {
    ($id:expr) => {
        CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
    }
}
macro_rules! AUDCLNT_ERR {
    ($n:expr) => {
        MAKE_HRESULT!(SEVERITY_ERROR, FACILITY_AUDCLNT, $n)
    };
}
macro_rules! AUDCLNT_SUCCESS {
    ($n:expr) => {
        MAKE_SCODE!(SEVERITY_SUCCESS, FACILITY_AUDCLNT, $n)
    };
}
macro_rules! BCRYPT_MAKE_INTERFACE_VERSION {
    ($major:expr, $minor:expr) => {
        $crate::shared::bcrypt::BCRYPT_INTERFACE_VERSION {
            MajorVersion: $major, MinorVersion: $minor,
        }
    }
}
macro_rules! RIDL {
    (#[uuid($($uuid:expr),+)]
    interface $interface:ident ($vtbl:ident) {$(
        fn $method:ident($($p:ident : $t:ty),*) -> $rtr:ty
    ),+}) => (
        #[repr(C)]
        pub struct $vtbl {
            $(pub $method: unsafe extern "system" fn(
                This: *mut $interface,
                $($p: $t),*
            ) -> $rtr),+
        }
        #[repr(C)]
        pub struct $interface {
            pub lpVtbl: *const $vtbl,
        }
        RIDL!{@impl $interface {$(fn $method($($p: $t),*) -> $rtr),+}}
        RIDL!{@uuid $interface $($uuid),+}
    );
    (#[uuid($($uuid:expr),+)]
    interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {
    }) => (
        #[repr(C)]
        pub struct $vtbl {
            pub parent: $pvtbl,
        }
        #[repr(C)]
        pub struct $interface {
            pub lpVtbl: *const $vtbl,
        }
        RIDL!{@deref $interface $pinterface}
        RIDL!{@uuid $interface $($uuid),+}
    );
    (#[uuid($($uuid:expr),+)]
    interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$(
        fn $method:ident($($p:ident : $t:ty),*) -> $rtr:ty
    ),+}) => (
        #[repr(C)]
        pub struct $vtbl {
            pub parent: $pvtbl
            $(,pub $method: unsafe extern "system" fn(
                This: *mut $interface,
                $($p: $t),*
            ) -> $rtr)+
        }
        #[repr(C)]
        pub struct $interface {
            pub lpVtbl: *const $vtbl,
        }
        RIDL!{@impl $interface {$(fn $method($($p: $t),*) -> $rtr),+}}
        RIDL!{@deref $interface $pinterface}
        RIDL!{@uuid $interface $($uuid),+}
    );
    (@deref $interface:ident $pinterface:ident) => (
        impl $crate::core::ops::Deref for $interface {
            type Target = $pinterface;
            #[inline]
            fn deref(&self) -> &$pinterface {
                unsafe { &*(self as *const $interface as *const $pinterface) }
            }
        }
    );
    (@impl $interface:ident {$(
        fn $method:ident($($p:ident : $t:ty),*) -> $rtr:ty
    ),+}) => (
        impl $interface {
            $(#[inline] pub unsafe fn $method(&self $(,$p: $t)*) -> $rtr {
                ((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p),*)
            })+
        }
    );
    (@uuid $interface:ident
        $l:expr, $w1:expr, $w2:expr,
        $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
    ) => (
        impl ::Interface for $interface {
            #[inline]
            fn uuidof() -> $crate::shared::guiddef::GUID {
                $crate::shared::guiddef::GUID {
                    Data1: $l,
                    Data2: $w1,
                    Data3: $w2,
                    Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
                }
            }
        }
    );
}
macro_rules! UNION {
    ($base:ident, $field:ident, $variant:ident, $variantmut:ident, $fieldtype:ty) => {
        impl $base {
            #[inline]
            pub unsafe fn $variant(&self) -> &$fieldtype {
                &*(&self.$field as *const _ as *const _)
            }
            #[inline]
            pub unsafe fn $variantmut(&mut self) -> &mut $fieldtype {
                &mut *(&mut self.$field as *mut _ as *mut _)
            }
        }
    }
}
macro_rules! BITFIELD {
    ($base:ident $field:ident: $fieldtype:ty [
        $($thing:ident $set_thing:ident[$r:expr],)+
    ]) => {
        impl $base {$(
            #[inline]
            pub fn $thing(&self) -> $fieldtype {
                let size = $crate::core::mem::size_of::<$fieldtype>() * 8;
                self.$field << (size - $r.end) >> (size - $r.end + $r.start)
            }
            #[inline]
            pub fn $set_thing(&mut self, val: $fieldtype) {
                let mask = ((1 << ($r.end - $r.start)) - 1) << $r.start;
                self.$field &= !mask;
                self.$field |= (val << $r.start) & mask;
            }
        )+}
    }
}
macro_rules! ENUM {
    {enum $name:ident { $($variant:ident = $value:expr,)+ }} => {
        pub type $name = u32;
        $(pub const $variant: u32 = $value;)+
    };
    {enum $name:ident { $variant:ident = $value:expr, $($rest:tt)* }} => {
        pub type $name = u32;
        pub const $variant: u32 = $value;
        ENUM!{@gen $name $variant, $($rest)*}
    };
    {enum $name:ident { $variant:ident, $($rest:tt)* }} => {
        ENUM!{enum $name { $variant = 0, $($rest)* }}
    };
    {@gen $name:ident $base:ident,} => {};
    {@gen $name:ident $base:ident, $variant:ident = $value:expr, $($rest:tt)*} => {
        pub const $variant: $name = $value;
        ENUM!{@gen $name $variant, $($rest)*}
    };
    {@gen $name:ident $base:ident, $variant:ident, $($rest:tt)*} => {
        pub const $variant: $name = $base + 1u32;
        ENUM!{@gen $name $variant, $($rest)*}
    };
}
macro_rules! STRUCT {
    {$(#[$attrs:meta])* struct $name:ident { $($field:ident: $ftype:ty,)+ }} => {
        #[repr(C)] $(#[$attrs])*
        pub struct $name {
            $(pub $field: $ftype,)+
        }
        impl Copy for $name {}
        impl Clone for $name {
            #[inline]
            fn clone(&self) -> $name { *self }
        }
    };
}
macro_rules! EXTERN {
    (stdcall fn $func:ident(
        $($p:ident: $t:ty),*
    ) -> $ret:ty) => (EXTERN!{@fix
        extern "stdcall" {
            pub fn $func(
                $($p: $t),*
            ) -> $ret;
        }
    });
    (cdecl fn $func:ident(
        $($p:ident: $t:ty),*
    ) -> $ret:ty) => (EXTERN!{@fix
        extern "cdecl" {
            pub fn $func(
                $($p: $t),*
            ) -> $ret;
        }
    });
    (@fix $x:item) => ($x);
}
macro_rules! IFDEF {
    ($($thing:item)*) => ($($thing)*)
}
macro_rules! FN {
    (stdcall $func:ident($($t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "stdcall" fn($($t),*) -> $ret>;
    );
    (stdcall $func:ident($($p:ident: $t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "stdcall" fn($($p: $t),*) -> $ret>;
    );
    (cdecl $func:ident($($t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "cdecl" fn($($t),*) -> $ret>;
    );
    (cdecl $func:ident($($p:ident: $t:ty),*) -> $ret:ty) => (
        pub type $func = Option<unsafe extern "cdecl" fn($($p: $t),*) -> $ret>;
    );
}
<|endoftext|>


<commit_before>const HEAP_START: usize = 0xC0_00_00_00;
const HEAP_END: usize = 0xD0_00_00_00;

use core;
use mutex::Mutex;
use rlibc;

static HEAP_PTR_MUTEX: Mutex<usize> = mutex!(HEAP_START);

#[no_mangle]
pub extern fn rust_allocate(size: usize, align: usize) -> *mut u8 {
    let mut heap_ptr = HEAP_PTR_MUTEX.lock();
    let new_heap_ptr = *heap_ptr +
        if *heap_ptr % align == 0 {
            0
        }
        else {
            align - (*heap_ptr % align)
        };
    if new_heap_ptr + size >= HEAP_END {
        core::ptr::null_mut()
    }
    else {
        *heap_ptr = new_heap_ptr + size;
        new_heap_ptr as *mut u8
    }
}

#[no_mangle]
pub extern fn rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
    let new_ptr = rust_allocate(size, align);
    if !ptr.is_null() {
        unsafe {
            rlibc::memcpy(new_ptr, ptr, old_size);
        }
    }
    ptr
}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> usize {
    old_size
}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_usable_size(size: usize, align: usize) -> usize {
    size
}

#[no_mangle]
pub extern fn rust_stats_print() {}
<commit_msg>New malloc<commit_after>const HEAP_START: usize = 0xC0_00_00_00;
// const HEAP_END: usize = 0xD0_00_00_00;

use core::cmp;
use core::ptr::null_mut;
use core::option::Option::{self, Some, None};
use core::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
use core::intrinsics::copy_nonoverlapping;

use mutex::Mutex;

// This mutex does not guard anything.
// However, all top-level functions that manipulate the heap must take it
static HEAP_MUTEX: Mutex<()> = mutex!(());

const MAX_ORDER: u8 = 22;
const BLOCK_BITS: u8 = 5;

const USED_MAGIC: [u8; 4] = [0; 4];
const FREE_MAGIC: [u8; 4] = ['F' as u8, 'R' as u8, 'E' as u8, 'E' as u8];

#[repr(packed)]
struct Block {
    pub order: u8,
    pub magic: [u8; 4],
    prev: *mut Block,
    next: *mut Block,
}

// Guarded by the big fat heap lock
static mut free_lists: [*mut Block; (MAX_ORDER + 1) as usize] =
    [0 as *mut Block; (MAX_ORDER + 1) as usize];

static INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT;

unsafe fn to_block<'r>(ptr: *mut u8) -> &'r mut Block {
    &mut *(ptr.offset(-1) as *mut Block)
}

impl Block {
    unsafe fn to_pointer(&mut self) -> *mut u8 {
        &mut self.magic[0] as *mut u8
    }

    unsafe fn to_const_pointer(&self) -> *const u8 {
        &self.magic[0] as *const u8
    }

    fn buddy<'r>(&self) -> &'r mut Block {
        unsafe {
            let addr = self.to_const_pointer() as usize;
            let buddy_addr = addr ^ ((1 << (self.order + BLOCK_BITS)) as usize);
            &mut *to_block(buddy_addr as *mut u8)
        }
    }

    unsafe fn free_insert(&mut self) {
        let mut prev = null_mut();
        let mut next = free_lists[self.order as usize];
        let self_ptr = self as *mut Block;
        let addr = self_ptr as usize;
        while !next.is_null() && (next as usize) < addr {
            prev = next;
            next = (*next).next;
        }
        self.prev = prev;
        self.next = next;
        if !next.is_null() {
            (*next).prev = self_ptr;
        }
        if prev.is_null() {
            free_lists[self.order as usize] = self_ptr;
        }
        else {
            (*prev).next = self_ptr
        }
    }

    unsafe fn free_remove(&mut self) {
        if !self.prev.is_null() {
            (*self.prev).next = self.next;
        }
        if !self.next.is_null() {
            (*self.next).prev = self.prev;
        }
        if free_lists[self.order as usize] == self as *mut Block {
            free_lists[self.order as usize] = self.next;
        }
    }

    fn make_used(&mut self) {
        self.magic = USED_MAGIC;
        unsafe { self.free_remove() ;}
        self.prev = null_mut();
        self.next = null_mut();
    }

    fn free(&mut self) {
        self.magic = FREE_MAGIC;
        unsafe { self.free_insert(); }
    }

    fn split<'r>(&mut self) -> &'r mut Block {
        self.make_used();
        self.order -= 1;
        self.free();
        let ret = self.buddy();
        ret.order = self.order;
        ret.free();
        ret
    }

    fn maybe_merge<'r>(&mut self){
        let buddy = self.buddy();
        if self.magic != FREE_MAGIC || buddy.magic != FREE_MAGIC || self.order == MAX_ORDER {
            return;
        }
        let is_self_smaller = (self as *mut Block as usize) < (buddy as *mut Block as usize);
        let (smaller, larger) = if is_self_smaller { (self, buddy) } else { (buddy, self) };
        if smaller.next != larger || larger.prev != smaller {
            return // Not actually free blocks, unless weird things happened
        }
        smaller.make_used();
        larger.make_used();
        larger.order = 0;
        smaller.order += 1;
        smaller.free();
        smaller.maybe_merge(); // Get as much merging in as we can
    }
}

unsafe fn init() {
    if INITIALIZED.compare_and_swap(false, true, Ordering::SeqCst) == false {
        let top_addr = HEAP_START - 1;
        let top = &mut *(top_addr as *mut u8 as *mut Block);
        top.order = MAX_ORDER;
        top.free();

        let buddy = top.buddy();
        buddy.order = MAX_ORDER;
        buddy.free();
    }
}

fn order_of(size: usize) -> u8 {
    let rounded = size.next_power_of_two();
    let log = rounded.trailing_zeros() as u8;
    cmp::max(log, BLOCK_BITS) - BLOCK_BITS
}

#[inline]
fn block_size(order: u8) -> usize {
    (1 << (order + BLOCK_BITS)) - 1
}

fn find_block_of_order<'r>(order: u8) -> Option<&'r mut Block> {
    if order > MAX_ORDER {
        return None
    }
    unsafe {
        if !INITIALIZED.load(Ordering::Relaxed) {
            init();
        }
        let maybe_head = free_lists[order as usize];
        if !maybe_head.is_null() {
            Some(&mut *maybe_head)
        }
        else {
            match find_block_of_order(order + 1) {
                Some(block) => {
                    block.split();
                    Some(block)
                }
                None => None
            }
        }
    }
}

#[inline]
fn to_order(size: usize, align: usize) -> u8 {
    cmp::max(order_of(size), order_of(align))
}

#[no_mangle]
pub unsafe extern fn rust_allocate(size: usize, align: usize) -> *mut u8 {
    let _lock = HEAP_MUTEX.lock();
    let order = to_order(size + 1, align);
    match find_block_of_order(order) {
        Some(block) => {
            block.make_used();
            block.to_pointer()
        }
        None => null_mut()
    }
}

#[inline]
pub unsafe fn malloc(size: usize) -> *mut u8 {
    rust_allocate(size, 1)
}

#[inline]
#[no_mangle]
pub unsafe extern fn rust_deallocate(ptr: *mut u8,
                                     _old_size: usize, _align: usize) {
    free(ptr)
}

pub unsafe fn free(ptr: *mut u8) {
    let _lock = HEAP_MUTEX.lock();
    let block = to_block(ptr);
    block.free();
    block.maybe_merge();
}

#[inline]
pub unsafe fn realloc(ptr: *mut u8, size: usize) -> *mut u8 {
    rust_reallocate(ptr, 1, size, 1)
}

#[no_mangle]
pub unsafe extern fn rust_reallocate(ptr: *mut u8, _old_size: usize,
                                     size: usize, align: usize) -> *mut u8 {
    let _lock = HEAP_MUTEX.lock();
    let block = to_block(ptr);
    let new_order = to_order(size + 1, align);
    if block.order >= new_order {
        ptr
    }
    else {
        match find_block_of_order(new_order) {
            Some(new_block) => {
                new_block.make_used();
                let ret = new_block.to_pointer();
                copy_nonoverlapping(ptr, ret, block_size(block.order));
                block.free();
                block.maybe_merge();
                ret
            }
            None => null_mut()
        }
    }
}

#[no_mangle]
pub unsafe extern fn rust_reallocate_inplace(ptr: *mut u8, old_size: usize,
                                             size: usize, align: usize) -> usize {
    let _lock = HEAP_MUTEX.lock();
    let block = to_block(ptr);
    let new_order = to_order(size + 1, align);
    if block.order >= new_order {
        block_size(block.order)
    }
    else {
        rust_usable_size(old_size, align)
    }
}

#[no_mangle]
pub extern fn rust_usable_size(size: usize, align: usize) -> usize {
    let order = to_order(size + 1, align);
    block_size(order)
}

#[no_mangle]
pub extern fn rust_stats_print() {}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

use crate::datatypes::DataType;

/// A type that Rust's custom allocator knows how to allocate and deallocate.
/// This is implemented for all Arrow's physical types whose in-memory representation
/// matches Rust's physical types. Consider this trait sealed.
/// # Safety
/// Do not implement this trait.
pub unsafe trait NativeType:
    Sized + Copy + std::fmt::Debug + std::fmt::Display + PartialEq + Default + Sized + 'static
{
    type Bytes: AsRef<[u8]>;

    /// Whether a DataType is a valid type for this physical representation.
    fn is_valid(data_type: &DataType) -> bool;

    /// How this type represents itself as bytes in little endianess.
    /// This is used for IPC, where data is communicated with a specific endianess.
    fn to_le_bytes(&self) -> Self::Bytes;
}

unsafe impl NativeType for u8 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::UInt8
    }
}

unsafe impl NativeType for u16 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::UInt16
    }
}

unsafe impl NativeType for u32 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::UInt32
    }
}

unsafe impl NativeType for u64 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::UInt64
    }
}

unsafe impl NativeType for i8 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::Int8
    }
}

unsafe impl NativeType for i16 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::Int16
    }
}

unsafe impl NativeType for i32 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        matches!(
            data_type,
            DataType::Int32 | DataType::Date32 | DataType::Time32(_)
        )
    }
}

unsafe impl NativeType for i64 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        matches!(
            data_type,
            DataType::Int64
                | DataType::Date64
                | DataType::Time64(_)
                | DataType::Timestamp(_, _)
        )
    }
}

unsafe impl NativeType for f32 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::Float32
    }
}

unsafe impl NativeType for f64 {
    type Bytes = [u8; std::mem::size_of::<Self>()];
    #[inline]
    fn to_le_bytes(&self) -> Self::Bytes {
        Self::to_le_bytes(*self)
    }

    #[inline]
    fn is_valid(data_type: &DataType) -> bool {
        data_type == &DataType::Float64
    }
}
<commit_msg>ARROW-11820: [Rust] Added macro to create native types<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

use crate::datatypes::DataType;

/// A type that Rust's custom allocator knows how to allocate and deallocate.
/// This is implemented for all Arrow's physical types whose in-memory representation
/// matches Rust's physical types. Consider this trait sealed.
/// # Safety
/// Do not implement this trait.
pub unsafe trait NativeType:
    Sized + Copy + std::fmt::Debug + std::fmt::Display + PartialEq + Default + Sized + 'static
{
    type Bytes: AsRef<[u8]>;

    /// Whether a DataType is a valid type for this physical representation.
    fn is_valid(data_type: &DataType) -> bool;

    /// How this type represents itself as bytes in little endianess.
    /// This is used for IPC, where data is communicated with a specific endianess.
    fn to_le_bytes(&self) -> Self::Bytes;
}

macro_rules! create_native {
    ($native_ty:ty,$($impl_pattern:pat)|+) => {
        unsafe impl NativeType for $native_ty {
            type Bytes = [u8; std::mem::size_of::<Self>()];

            #[inline]
            fn to_le_bytes(&self) -> Self::Bytes {
                Self::to_le_bytes(*self)
            }

            #[inline]
            fn is_valid(data_type: &DataType) -> bool {
                matches!(data_type, $($impl_pattern)|+)
            }
        }
    };
}

create_native!(u8, DataType::UInt8);
create_native!(u16, DataType::UInt16);
create_native!(u32, DataType::UInt32);
create_native!(u64, DataType::UInt64);
create_native!(i8, DataType::Int8);
create_native!(i16, DataType::Int16);
create_native!(
    i32,
    DataType::Int32 | DataType::Date32 | DataType::Time32(_)
);
create_native!(
    i64,
    DataType::Int64 | DataType::Date64 | DataType::Time64(_) | DataType::Timestamp(_, _)
);
create_native!(f32, DataType::Float32);
create_native!(f64, DataType::Float64);
<|endoftext|>


<commit_before>use rom;

pub struct Memory {
    pub rom: rom::Rom,
    ram: [u8, ..0x2000],
    hram: [u8, ..0x80]
}

impl Memory {
    pub fn new(rom: rom::Rom) -> Memory {
        Memory {
            rom: rom,
            ram: [0x00, ..0x2000],
            hram: [0x00, ..0x80]
        }
    }

    pub fn read_byte(&self, address: u16) -> u8 {
        match address {
            0x0000..0x3FFF => self.rom.bytes[address as uint],
            0xC000..0xDFFF => self.ram[address as uint - 0xC000],
            0xFF80..0xFFFF => self.hram[address as uint - 0xFF80],
            _ => 0x00
        }
    }

    pub fn write_byte(&mut self, address: u16, value: u8) {
        match address {
            0xC000..0xDFFF => {
                self.ram[address as uint - 0xC000] = value
            },
            0xFF00..0xFF7F => {
                print!("Implement I/O ports stuff... ")
            },
            0xFF80..0xFFFF => {
                self.hram[address as uint - 0xFF80] = value
            },
            _ => println!("Can't write to memory address {:#06x}", address)
        }
    }

    pub fn read_word(&self, address: u16) -> u16 {
        self.read_byte(address) as u16 |
            self.read_byte(address + 1) as u16 << 8
    }

    pub fn write_word(&mut self, address: u16, value: u16) {
        self.write_byte(address, (value & 0xFF) as u8);
        self.write_byte(address + 1, (value >> 8) as u8);
    }
}
<commit_msg>Improve Memory abstraction<commit_after>use rom;

pub struct Memory {
    pub rom: rom::Rom,
    ram: [u8, ..0x4000],
    hram: [u8, ..0x79],
    ie: u8
}

impl Memory {
    pub fn new(rom: rom::Rom) -> Memory {
        Memory {
            rom: rom,
            ram: [0x00, ..0x4000],
            hram: [0x00, ..0x79],
            ie: 0x00
        }
    }

    pub fn read_byte(&self, address: u16) -> u8 {
        match address {
            0x0000..0x7FFF => self.rom.bytes[address as uint],
            0x8000..0x9FFF => {
                print!("Video RAM not implemented!");
                0x00
            },
            0xA000..0xBFFF => {
                print!("External RAM not implemented!");
                0x00
            },
            0xC000..0xDFFF => self.ram[address as uint - 0xC000],
            0xE000..0xFDFF => self.ram[address as uint - 0xE000],
            0xFE00..0xFE9F => {
                print!("Sprite attribute table not implemented!");
                0x00
            },
            0xFEA0..0xFEFF => fail!("0xFEA0..0xFEFF segment is no usable"),
            0xFF00..0xFF7F => {
                print!("I/O ports not implemented!");
                0x00
            },
            0xFF80..0xFFFE => self.hram[address as uint - 0xFF80],
            0xFFFF => self.ie,
            _ => unreachable!()
        }
    }

    pub fn write_byte(&mut self, address: u16, value: u8) {
        match address {
            0x0000..0x7FFF => {
                fail!("Address not writable in MBC0: {:#06x}", address);
            },
            0x8000..0x9FFF => {
                print!("Video RAM not implemented!");
            },
            0xA000..0xBFFF => {
                print!("External RAM not implemented!");
            }
            0xC000..0xDFFF => {
                self.ram[address as uint - 0xC000] = value;
            },
            0xE000..0xFDFF => {
                self.ram[address as uint - 0xE000] = value;
            },
            0xFE00..0xFE9F => {
                print!("Sprite attribute table not implemented!");
            },
            0xFEA0..0xFEFF => fail!("0xFEA0..0xFEFF segment is no usable"),
            0xFF00..0xFF7F => {
                print!("Implement I/O ports stuff... ");
            },
            0xFF80..0xFFFE => {
                self.hram[address as uint - 0xFF80] = value;
            },
            0xFFFF => {
                self.ie = value;
            },
            _ => unreachable!()
        }
    }

    pub fn read_word(&self, address: u16) -> u16 {
        self.read_byte(address) as u16 |
            self.read_byte(address + 1) as u16 << 8
    }

    pub fn write_word(&mut self, address: u16, value: u16) {
        self.write_byte(address, (value & 0xFF) as u8);
        self.write_byte(address + 1, (value >> 8) as u8);
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Sub};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::collections::VecDeque;

struct WordVecBuilder {
    pub word: String,
    pub count: u64,
    vec: Box<[f32; 10_000]>,
}

pub struct WordVec {
    pub word: String,
    pub count: u64,
    vec: Box<[f32; 10_000]>,
}

impl WordVecBuilder {
    fn new(word: String) -> WordVecBuilder {
        WordVecBuilder {
            word: word,
            count: 0,
            vec: Box::new([0f32; 10_000]),
        }
    }

    fn normalize(mut self, word_freqs: &Vec<f32>) -> WordVec {
        let count = self.count as f32;
        for i in 0..word_freqs.len() {
            self.vec[i] = self.vec[i] / count /  word_freqs[i];
        }

        WordVec {
            word: self.word,
            count: self.count,
            vec: self.vec,
        }
    }

    fn inc(&mut self, i: usize) {
        self.vec[i] += 1.0;
    }
}

impl WordVec {

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| (x*x - y*y).abs().sqrt())
                .fold(0.0, |x, y| x + y)
    }

}

impl<'a> Add for &'a WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: Box::new([0f32; 10_000]),
        };

        for i in 0..10_000 {
            newvec.vec[i] = self.vec[i] + other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub for &'a WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: Box::new([0f32; 10_000]),
        };

        for i in 0..10_000 {
            newvec.vec[i] = self.vec[i] - other.vec[i];
        }

        newvec
    }
}

pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_width: u32,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVecBuilder>,
}

pub struct WordAcceptor<'a> {
    window: VecDeque<String>,
    focus: usize,
    builder: &'a mut LanguageModelBuilder,
}

impl<'a> LanguageModelBuilder {
    pub fn new(words: Vec<String>) -> LanguageModelBuilder {
        assert_eq!(words.len(), 10_000);

        let word_vecs = words.iter()
                             .map(|s| WordVecBuilder::new(s.clone()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_width: 21,
            words: words,
            word_vecs: word_vecs,
        }
    }

    pub fn build(self) -> LanguageModel {
        let total_words = self.word_vecs.iter().fold(0.0, |a, b| a + b.count as f32);
        let word_freqs = self.word_vecs.iter()
                                       .map(|v| v.count as f32 / total_words)
                                       .collect::<Vec<_>>();
        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs.into_iter()
                                     .map(|b| b.normalize(&word_freqs))
                                     .collect(),
        }
    }

    pub fn new_file(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            window: VecDeque::new(),
            focus: 0,
            builder: self,
        }
    }

    fn add_word(&mut self, word: &str) {
        let idx = self.words[word];
        let word_vec = &mut self.word_vecs[idx];
        word_vec.inc(idx);
    }
}

impl<'a> WordAcceptor<'a> {
    fn add_word(&mut self, word: String) {
        let idx = self.builder.words.get(&word).map(|i| *i);

        if let Some(idx) = idx {
            self.window.push_back(word);
            if (self.window.len() > 21) {
                self.window.pop_front();
            }
            if (self.window.len() == 21) {
                for i in (0..21).filter(|a| *a != 10) {
                    self.builder.add_word(&self.window[i]);
                }
            }
        }
    }
}<commit_msg>Add methods to the language model and simplify the word acceptor slightly<commit_after>use std::ops::{Add, Sub};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::collections::VecDeque;
use std::cmp::Ordering::Equal;

struct WordVecBuilder {
    pub word: String,
    pub count: u64,
    vec: Box<[f32; 10_000]>,
}

pub struct WordVec {
    pub word: String,
    pub count: u64,
    vec: Box<[f32; 10_000]>,
}

impl WordVecBuilder {
    fn new(word: String) -> WordVecBuilder {
        WordVecBuilder {
            word: word,
            count: 0,
            vec: Box::new([0f32; 10_000]),
        }
    }

    fn normalize(mut self, word_freqs: &Vec<f32>) -> WordVec {
        let count = self.count as f32;
        for i in 0..word_freqs.len() {
            self.vec[i] = self.vec[i] / count /  word_freqs[i];
        }

        WordVec {
            word: self.word,
            count: self.count,
            vec: self.vec,
        }
    }

    fn inc(&mut self, i: usize) {
        self.vec[i] += 1.0;
    }
}

impl WordVec {

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| (x*x - y*y).abs().sqrt())
                .fold(0.0, |x, y| x + y)
    }

}

impl<'a> Add for &'a WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: Box::new([0f32; 10_000]),
        };

        for i in 0..10_000 {
            newvec.vec[i] = self.vec[i] + other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub for &'a WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: Box::new([0f32; 10_000]),
        };

        for i in 0..10_000 {
            newvec.vec[i] = self.vec[i] - other.vec[i];
        }

        newvec
    }
}

pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_width: u32,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVecBuilder>,
}

pub struct WordAcceptor<'a> {
    window: VecDeque<String>,
    focus: usize,
    builder: &'a mut LanguageModelBuilder,
}

impl<'a> LanguageModelBuilder {
    pub fn new(words: Vec<String>) -> LanguageModelBuilder {
        assert_eq!(words.len(), 10_000);

        let word_vecs = words.iter()
                             .map(|s| WordVecBuilder::new(s.clone()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_width: 21,
            words: words,
            word_vecs: word_vecs,
        }
    }

    pub fn build(self) -> LanguageModel {
        let total_words = self.word_vecs.iter().fold(0.0, |a, b| a + b.count as f32);
        let word_freqs = self.word_vecs.iter()
                                       .map(|v| v.count as f32 / total_words)
                                       .collect::<Vec<_>>();
        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs.into_iter()
                                     .map(|b| b.normalize(&word_freqs))
                                     .collect(),
        }
    }

    pub fn new_file(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            window: VecDeque::new(),
            focus: 0,
            builder: self,
        }
    }

    fn add_word(&mut self, word: &str) {
        let idx = self.words[word];
        let word_vec = &mut self.word_vecs[idx];
        word_vec.inc(idx);
    }
}

impl<'a> WordAcceptor<'a> {
    pub fn add_word(&mut self, word: String) {
        let allow_word = self.builder.words.contains_key(&word);

        if allow_word {
            self.window.push_back(word);
            if (self.window.len() > 21) {
                self.window.pop_front();
            }
            if (self.window.len() == 21) {
                for i in (0..21).filter(|a| *a != 10) {
                    self.builder.add_word(&self.window[i]);
                }
            }
        }
    }
}

impl LanguageModel {
    pub fn get(&self, word: &str) -> Option<&WordVec> {
        if let Some(i) = self.words.get(word) {
            Some(&self.word_vecs[*i])
        } else {
            None
        }
    }

    pub fn nearest_words(&self, word: &WordVec) -> Vec<&WordVec> {
        let mut vec_refs = self.word_vecs.iter().map(|v| v).collect::<Vec<_>>();
        vec_refs.sort_by(|a, b| a.distance(word).partial_cmp(&b.distance(word)).unwrap_or(Equal));
        vec_refs
    }
}<|endoftext|>