#![feature(const_in_array_repeat_expressions)] #![feature(const_fn)] #![feature(drain_filter)] #![cfg_attr(nightly, feature(test))] #![allow(dead_code)] #[cfg(nightly)] extern crate test; const MAX: usize = 256; //TODO: Move test //TODO: Document //TODO: Readme //TODO: LICENSE //TODO: Publish and upload to githubxc use std::{ borrow::Borrow, }; pub trait Collapse: Eq { fn collapse(&self) -> u8; } #[repr(transparent)] #[derive(Debug,Clone,PartialEq,Eq,Ord,PartialOrd,Hash)] pub struct Page([Option<(TKey, TValue)>; MAX]); impl Page where K: Collapse { /// Create a new blank page pub const fn new() -> Self { Self([None; MAX]) } pub fn len(&self) -> usize { self.0.iter().map(Option::as_ref).filter_map(std::convert::identity).count() } pub fn iter(&self) -> PageElements<'_, K,V> { PageElements(self.0.iter()) } pub fn iter_mut(&mut self) -> PageElementsMut<'_, K,V> { PageElementsMut(self.0.iter_mut()) } fn search(&self, key: &Q) -> &Option<(K,V)> where Q: Collapse { &self.0[usize::from(key.collapse())] } fn search_mut(&mut self, key: &Q) -> &mut Option<(K,V)> where Q: Collapse { &mut self.0[usize::from(key.collapse())] } fn replace(&mut self, k: K, v: V) -> Option<(K,V)> { std::mem::replace(&mut self.0[usize::from(k.collapse())], Some((k,v))) } } impl IntoIterator for Page where K: Collapse { type Item= (K,V); type IntoIter = IntoPageElements; fn into_iter(self) -> Self::IntoIter { IntoPageElements(self.0, 0) } } impl Default for Page where K: Collapse { #[inline] fn default() -> Self { Self::new() } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] pub struct Map(Vec>); pub mod iter; use iter::*; pub mod entry; pub use entry::Entry; impl Map where K: Collapse { fn new_page(&mut self) -> &mut Page { let len = self.0.len(); self.0.push(Page::new()); &mut self.0[len] } #[inline(always)] fn fuck_entry(&mut self, key: K) -> Option> { for page in self.0.iter_mut() { let re = page.search_mut(&key); match re { Some((ref ok, _)) if key.eq(ok.borrow()) => { return Some(Entry::Occupied(entry::OccupiedEntry(re))); }, None => { return Some(Entry::Vacant(entry::VacantEntry(re, key))); }, _ => (), } } None } pub fn entry(&mut self, key: K) -> Entry<'_, K, V> { if self.0.iter() .filter(|x| x.search(&key).is_none()) .count() == 0 { self.new_page(); }//so dumb..... SO dumb //will need to completely reimplement all entry::* shit to just have mut reference to Map and then usize indecies for location I guess. Fuck this self.fuck_entry(key).unwrap() } pub fn clean(&mut self) { self.0.drain_filter(|x| x.len() <1); } pub fn len(&self) -> usize { self.pages().map(Page::len).sum() } pub fn num_pages(&self) -> usize { self.0.len() } pub fn into_pages(self) -> Vec> { self.0 } pub fn pages(&self) -> Pages<'_, K, V> { iter::Pages(self.0.iter()) } pub fn pages_mut(&mut self) -> PagesMut<'_, K, V> { iter::PagesMut(self.0.iter_mut()) } pub(crate) fn iter_opaque(&self) -> impl Iterator + '_ { self.pages().map(|x| x.iter()).flatten() } pub fn iter(&self) -> Iter<'_, K, V> { Iter(None, self.pages()) } pub(crate) fn iter_mut_opaque(&mut self) -> impl Iterator + '_ { self.pages_mut().map(|x| x.iter_mut()).flatten() } pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { IterMut(None, self.pages_mut()) } pub fn new() -> Self { Self(vec![Page::new()]) } pub fn with_capacity(pages: usize) -> Self { let mut p = Vec::with_capacity(pages); p.push(Page::new()); Self(p) } pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where K: Borrow, Q: Collapse + Eq { for page in self.0.iter_mut() { match page.search_mut(key) { Some((ref ok, ov)) if key.eq(ok.borrow()) => { return Some(ov); }, _ => (), } } None } #[inline] pub fn contains_key(&self, key: &Q) -> bool where K: Borrow, Q: Collapse + Eq { self.get(key).is_some() } pub fn get(&self, key: &Q) -> Option<&V> where K: Borrow, Q: Collapse + Eq { for page in self.0.iter() { match page.search(key) { Some((ref ok, ov)) if key.eq(ok.borrow()) => { return Some(ov); }, _ => (), } } None } fn search_mut(&mut self, key: &Q) -> Option<&mut Option<(K,V)>> where K: Borrow, Q: Collapse + Eq { for page in self.0.iter_mut() { let se = page.search_mut(key); match se { Some((ref ok, _)) if key.eq(ok.borrow()) => { return Some(se); }, _ => (), } } None } pub fn remove(&mut self, key: &Q) -> Option where K: Borrow, Q: Collapse + Eq { for page in self.0.iter_mut() { let v = page.search_mut(key); match v { Some((ref ok, _)) if key.eq(ok.borrow()) => { return v.take().map(|(_, v)| v); }, _ => (), } } None } pub fn insert(&mut self, key: K, value: V) -> Option { for page in self.0.iter_mut() { match page.search_mut(&key) { Some((ref ok, ov)) if ok.eq(&key) => { return Some(std::mem::replace(ov, value)); }, empty @ None => { return empty.replace((key, value)) .map(|(_, v)| v); }, _ => (), } } let mut page = Page::new(); page.replace(key, value); self.0.push(page); None } } impl IntoIterator for Map { type Item= (K,V); type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter(None, self.0.into_iter()) } } pub trait CollapseMemory: Eq { fn as_memory(&self) -> &[u8]; } impl Collapse for T where T: CollapseMemory { fn collapse(&self) -> u8 { collapse(self.as_memory()) } } mod primitives; pub use primitives::*; mod defaults; pub use defaults::*; /// Collapse bytes with default XOR fold pub fn collapse>(bytes: T) -> u8 { bytes.as_ref().iter().copied().fold(0, |a, b| a ^ b) } #[cfg(test)] mod tests;