#![no_std]
extern crate alloc;
use alloc::boxed::Box;
#[derive(Debug, Clone)]
pub struct BitTree<K: GetBytes, V: GetBytes> {
is_keys: bool,
value: Option<V>,
next_vals: *mut BitTree<V, K>,
next: [Option<*mut BitTree<K, V>>; 2],
phdata: core::marker::PhantomData<K>
}
pub mod getbytes;
use getbytes::GetBytes;
#[derive(Debug, Clone)]
struct Bits<'a> {
inner: &'a [u8],
bitpos: usize
}
impl<'a> Iterator for Bits<'a> {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
if self.bitpos >> 3 >= self.inner.len() {
None
} else {
let shift_by = core::mem::size_of::<usize>() * 8 - 3;
let current_bit = (self.bitpos << shift_by) >> shift_by;
let out = Some(self.inner[self.bitpos >> 3] & (1 << current_bit) != 0);
self.bitpos += 1;
out
}
}
}
impl<K: GetBytes, V: GetBytes> Default for BitTree<K, V> {
fn default() -> Self {
let mut out = BitTree {
is_keys: true,
value: None,
next_vals: 1usize as *mut BitTree<V, K>,
next: [None, None],
phdata: core::marker::PhantomData
};
out.next_vals = Box::leak(Box::new(BitTree {
value: None,
is_keys: false,
next_vals: &mut out as *mut BitTree<K, V>,
next: [None, None],
phdata: core::marker::PhantomData
}));
out
}
}
impl<K: GetBytes, V: GetBytes> BitTree<K, V> {
pub fn new() -> BitTree<K, V> {
Self::default()
}
pub fn add(&mut self, key: &K, value: Option<V>) {
let bytes = key.get_bytes();
let bits = Bits {
inner: bytes,
bitpos: 0
};
let mut current = self;
if current.is_keys && value.is_some() {
unsafe {
(&mut *current.next_vals).add(&value.clone().unwrap(), Some(key.clone()));
}
}
for bit in bits {
unsafe {
if current.next[bit as usize].as_mut().is_some() {
current = &mut **current.next[bit as usize].as_mut().unwrap();
} else {
current.next[bit as usize] = Some(Box::leak(Box::new(BitTree::new())));
current = &mut **current.next[bit as usize].as_mut().unwrap();
}
}
}
current.value = value;
}
pub fn remove(&mut self, key: &K) {
let bytes = key.get_bytes();
let bits = Bits {
inner: bytes,
bitpos: 0
};
let mut current = self;
if current.is_keys {
unsafe {
let res = (&mut *current.next_vals).find(key);
(&mut *current.next_vals).remove(res.as_ref().unwrap());
}
}
for (i, bit) in bits.enumerate() {
if current.next[bit as usize].is_some() && i == core::mem::size_of::<K>() * 8 - 2 {
current.next[bit as usize] = None;
} else if current.next[bit as usize].is_none() {
break;
} else {
unsafe {
current = &mut **current.next[bit as usize].as_mut().unwrap();
}
}
}
}
pub fn find(&mut self, value: &V) -> Option<K> {
let bytes = value.get_bytes();
let bits = Bits {
inner: bytes,
bitpos: 0
};
let mut current = unsafe {
&mut *self.next_vals
};
for bit in bits {
unsafe {
if let Some(next) = current.next[bit as usize].as_mut() {
current = &mut **next;
} else {
return None;
}
}
}
current.value.clone()
}
}
impl<K: GetBytes, V: GetBytes> core::ops::Index<&K> for BitTree<K, V> {
type Output = Option<V>;
fn index(&self, index: &K) -> &Self::Output {
let bytes = index.get_bytes();
let bits = Bits {
inner: bytes,
bitpos: 0
};
let mut current = self;
for bit in bits {
if current.next[bit as usize].is_some() {
unsafe {
current = &**current.next[bit as usize].as_ref().unwrap();
}
} else {
return ¤t.value;
}
}
¤t.value
}
}
impl<K: GetBytes, V: GetBytes> core::ops::IndexMut<&K> for BitTree<K, V> {
fn index_mut(&mut self, index: &K) -> &mut Option<V> {
let bytes = index.get_bytes();
let bits = Bits {
inner: bytes,
bitpos: 0
};
let mut current = self;
for bit in bits {
if current.next[bit as usize].is_some() {
unsafe {
current = &mut **current.next[bit as usize].as_mut().unwrap();
}
} else {
return &mut current.value;
}
}
&mut current.value
}
}
#[test]
fn basic_add_remove() {
let mut btree = BitTree::new();
btree.add(&0usize, Some(0usize));
assert!(btree.find(&0usize).is_some());
assert_eq!(btree[&0usize], Some(0usize));
btree.remove(&0usize);
assert!(btree.find(&0usize).is_none());
assert!(btree[&0usize].is_none());
}