hashgrid 0.1.0

A 2D spatial-hash grid library
Documentation
use std::hash::{BuildHasher, Hash};

/// A fixed-size hash table where the elements are initialized with `Default::default`.
#[derive(Debug, Default, Clone)]
pub struct Table<T, S> {
    hash_builder: S,
    data: Vec<T>,
}

impl<T: Default, S: Default> Table<T, S> {
    /// Creates a new table with the given size.
    pub fn with_capacity(size: usize) -> Self {
        Self::with_capacity_and_hasher(size, S::default())
    }
}

impl<T: Default, S> Table<T, S> {
    /// Creates a new table with the given size.
    pub fn with_capacity_and_hasher(size: usize, hasher: S) -> Self {
        let mut data = Vec::with_capacity(size);
        data.resize_with(size, || T::default());
        Self {
            data,
            hash_builder: hasher,
        }
    }
}

impl<T: Default, S> Table<T, S> {
    pub fn inner(&self) -> &[T] {
        &self.data
    }

    pub fn inner_mut(&mut self) -> &mut [T] {
        &mut self.data
    }

    pub fn get(&self, index: usize) -> &T {
        // SAFETY: the calculated hash modulo the vector's length.
        unsafe { self.data.get_unchecked(index % self.data.len()) }
    }

    pub fn get_mut(&mut self, index: usize) -> &mut T {
        let len = self.data.len();
        // SAFETY: the calculated hash modulo the vector's length.
        unsafe { self.data.get_unchecked_mut(index % len) }
    }
}

impl<T: Default, S: BuildHasher> Table<T, S> {
    pub fn get_hash<U: Hash>(&self, key: &U) -> &T {
        self.get(self.hash_builder.hash_one(key) as usize)
    }

    pub fn get_hash_mut<U: Hash>(&mut self, key: &U) -> &mut T {
        self.get_mut(self.hash_builder.hash_one(key) as usize)
    }
}