You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

335 lines
6.3 KiB

4 years ago
#![feature(const_in_array_repeat_expressions)]
#![feature(const_fn)]
4 years ago
#![feature(drain_filter)]
4 years ago
#![cfg_attr(nightly, feature(test))]
4 years ago
#![allow(dead_code)]
4 years ago
#[cfg(nightly)] extern crate test;
4 years ago
const MAX: usize = 256;
4 years ago
//TODO: Move test
//TODO: Document
//TODO: Readme
//TODO: LICENSE
//TODO: Publish and upload to githubxc
4 years ago
use std::{
borrow::Borrow,
};
4 years ago
pub trait Collapse: Eq
4 years ago
{
fn collapse(&self) -> u8;
}
#[repr(transparent)]
#[derive(Debug,Clone,PartialEq,Eq,Ord,PartialOrd,Hash)]
pub struct Page<TKey,TValue>([Option<(TKey, TValue)>; MAX]);
impl<K,V> Page<K,V>
4 years ago
where K: Collapse
4 years ago
{
/// 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<Q: ?Sized>(&self, key: &Q) -> &Option<(K,V)>
4 years ago
where Q: Collapse
4 years ago
{
&self.0[usize::from(key.collapse())]
}
fn search_mut<Q: ?Sized>(&mut self, key: &Q) -> &mut Option<(K,V)>
4 years ago
where Q: Collapse
4 years ago
{
&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<K,V> IntoIterator for Page<K,V>
4 years ago
where K: Collapse
4 years ago
{
type Item= (K,V);
type IntoIter = IntoPageElements<K,V>;
fn into_iter(self) -> Self::IntoIter
{
IntoPageElements(self.0, 0)
}
}
impl<K,V> Default for Page<K,V>
4 years ago
where K: Collapse
4 years ago
{
#[inline]
fn default() -> Self
{
Self::new()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub struct Map<TKey, TValue>(Vec<Page<TKey,TValue>>);
pub mod iter;
use iter::*;
4 years ago
pub mod entry;
pub use entry::Entry;
4 years ago
impl<K,V> Map<K,V>
4 years ago
where K: Collapse
4 years ago
{
4 years ago
fn new_page(&mut self) -> &mut Page<K,V>
{
let len = self.0.len();
self.0.push(Page::new());
&mut self.0[len]
}
#[inline(always)] fn fuck_entry(&mut self, key: K) -> Option<Entry<'_, K, V>>
{
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);
}
4 years ago
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<Page<K,V>>
{
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<Item = &(K, V)> + '_
{
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<Item = &mut (K, V)> + '_
{
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<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
where K: Borrow<Q>,
4 years ago
Q: Collapse + Eq
4 years ago
{
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<Q: ?Sized>(&self, key: &Q) -> bool
where K: Borrow<Q>,
4 years ago
Q: Collapse + Eq
4 years ago
{
self.get(key).is_some()
}
pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
where K: Borrow<Q>,
4 years ago
Q: Collapse + Eq
4 years ago
{
for page in self.0.iter()
{
match page.search(key) {
Some((ref ok, ov)) if key.eq(ok.borrow()) => {
return Some(ov);
},
_ => (),
}
}
None
}
4 years ago
4 years ago
4 years ago
fn search_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Option<(K,V)>>
where K: Borrow<Q>,
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
}
4 years ago
pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
where K: Borrow<Q>,
4 years ago
Q: Collapse + Eq
4 years ago
{
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
}
4 years ago
pub fn insert(&mut self, key: K, value: V) -> Option<V>
{
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
}
}
4 years ago
impl<K: Collapse, V> IntoIterator for Map<K,V>
4 years ago
{
type Item= (K,V);
type IntoIter = IntoIter<K,V>;
fn into_iter(self) -> Self::IntoIter
{
IntoIter(None, self.0.into_iter())
}
}
pub trait CollapseMemory: Eq
{
fn as_memory(&self) -> &[u8];
}
4 years ago
impl<T> Collapse for T
4 years ago
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<T: AsRef<[u8]>>(bytes: T) -> u8
{
bytes.as_ref().iter().copied().fold(0, |a, b| a ^ b)
}
#[cfg(test)]
4 years ago
mod tests;