use core::borrow::Borrow;
use core::hash::{BuildHasher, Hash, Hasher};
use core::marker::PhantomData;
use core::mem;
use core::ptr::{self, NonNull};
use core::slice;
use swim_core::murmur3::Murmur3;
use swim_mem::block::{Block, Layout};
use swim_mem::alloc::{AllocTag, Hold, HoldError, Stow, TryClone, CloneIntoHold};
mod map;
mod set;
pub use self::map::{HashTrieMap, HashTrieMapIter, HashTrieMapIterMut,
HashTrieMapKeys, HashTrieMapVals, HashTrieMapValsMut};
pub use self::set::{HashTrieSet, HashTrieSetIter};
pub(crate) type BranchBit = u32;
#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub(crate) enum BranchType {
Void = 0u32,
Leaf = 1u32,
Node = 2u32,
Knot = 3u32,
}
pub(crate) struct HashTrie<'a, K, V, H = Murmur3> {
root: NonNull<Node<'a, K, V>>,
len: usize,
hasher: H,
}
struct Node<'a, K, V> {
limb_map: u32,
leaf_map: u32,
data_marker: PhantomData<[(K, V)]>,
hold_marker: PhantomData<&'a ()>,
}
struct Knot<'a, K, V> {
hash: u64,
len: usize,
data_marker: PhantomData<[(K, V)]>,
hold_marker: PhantomData<&'a ()>,
}
union Limb<'a, K, V> {
#[allow(dead_code)]
node: Node<'a, K, V>,
#[allow(dead_code)]
knot: Knot<'a, K, V>,
}
enum NodeInsert<'a, K, V> {
None,
Diff(V),
Copy(*mut Node<'a, K, V>),
Fail(HoldError),
}
enum NodeRemove<'a, K, V> {
None,
Diff((K, V)),
Drop((K, V)),
Lift((K, V), (K, V)),
Copy((K, V), *mut Node<'a, K, V>),
Fail(HoldError),
}
enum KnotInsert<'a, K, V> {
Diff(V),
Copy(*mut Knot<'a, K, V>),
Fail(HoldError),
}
enum KnotRemove<'a, K, V> {
None,
Drop((K, V)),
Lift((K, V), (K, V)),
Copy((K, V), *mut Knot<'a, K, V>),
Fail(HoldError),
}
enum IterFrame<'a, K, V> {
Void,
Node {
limb_map: u32,
leaf_map: u32,
branch: BranchBit,
limb_ptr: *mut *mut Limb<'a, K, V>,
leaf_ptr: *mut (K, V),
},
Knot {
head_ptr: *mut (K, V),
foot_ptr: *mut (K, V),
},
}
pub(crate) struct HashTrieIter<'a, K, V> {
count: usize,
depth: i8,
stack: [IterFrame<'a, K, V>; 14],
}
#[inline]
fn hash_key<K, H>(hasher: &H, key: &K) -> u64
where K: Hash + ?Sized,
H: BuildHasher,
{
let mut h = hasher.build_hasher();
key.hash(&mut h);
h.finish()
}
#[inline]
fn branch32(hash: u64, shift: u32) -> BranchBit {
1 << ((hash >> shift) as u32 & 0x1F)
}
impl BranchType {
#[inline]
fn for_branch(limb_map: u32, leaf_map: u32, branch: BranchBit) -> BranchType {
let mut discriminant = 0;
if limb_map & branch != 0 {
discriminant |= BranchType::Node as u32;
}
if leaf_map & branch != 0 {
discriminant |= BranchType::Leaf as u32;
}
unsafe { mem::transmute(discriminant) }
}
}
impl<'a, K, V> HashTrie<'a, K, V> {
#[inline]
pub(crate) fn hold_new(hold: &dyn Hold<'a>) -> HashTrie<'a, K, V> {
unsafe {
let root = Node::empty(hold);
HashTrie {
root: NonNull::new_unchecked(root),
len: 0,
hasher: Murmur3::new(),
}
}
}
}
impl<'a, K, V, H> HashTrie<'a, K, V, H> {
#[inline]
pub(crate) fn hold_new_hasher(hold: &dyn Hold<'a>, hasher: H) -> HashTrie<'a, K, V, H> {
unsafe {
let root = Node::empty(hold);
HashTrie {
root: NonNull::new_unchecked(root),
len: 0,
hasher: hasher,
}
}
}
#[inline]
pub(crate) fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub(crate) fn len(&self) -> usize {
self.len
}
#[inline]
pub(crate) fn holder(&self) -> &'a dyn Hold<'a> {
let root = self.root.as_ptr() as *mut u8;
AllocTag::from_ptr(root).holder()
}
#[inline]
pub(crate) fn iterator(&self) -> HashTrieIter<'a, K, V> {
unsafe {
if self.len != 0 {
HashTrieIter::new(self.len, IterFrame::from_node(self.root.as_ptr()))
} else {
HashTrieIter::empty()
}
}
}
}
impl<'a, K: Eq + Hash, V, H: BuildHasher> HashTrie<'a, K, V, H> {
pub(crate) fn contains_key<J: Borrow<K> + ?Sized>(&self, key: &J) -> bool {
unsafe {
if self.len != 0 {
let hash = hash_key(&self.hasher, key.borrow());
self.root.as_ptr().contains_key(key.borrow(), hash, 0)
} else {
false
}
}
}
pub(crate) fn get<J: Borrow<K> + ?Sized>(&self, key: &J) -> Option<&V> {
unsafe {
if self.len != 0 {
let hash = hash_key(&self.hasher, key.borrow());
self.root.as_ptr().get(key.borrow(), hash, 0)
} else {
None
}
}
}
pub(crate) fn insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V, HoldError)> {
unsafe {
let hash = hash_key(&self.hasher, &key);
let old_root = self.root.as_ptr();
let old_len = self.len;
if old_len != 0 {
match old_root.insert(&self.hasher, &key, &value, hash, 0) {
NodeInsert::None => {
self.len = old_len.wrapping_add(1);
Ok(None)
},
NodeInsert::Diff(old_val) => {
Ok(Some(old_val))
},
NodeInsert::Copy(new_node) => {
old_root.dealloc();
self.len = old_len.wrapping_add(1);
self.root = NonNull::new_unchecked(new_node);
Ok(None)
},
NodeInsert::Fail(error) => Err((key, value, error)),
}
} else {
let root = match Node::unary(old_root.holder(), &key, &value, hash) {
Ok(root) => root,
Err(error) => return Err((key, value, error)),
};
old_root.dealloc();
self.root = NonNull::new_unchecked(root);
self.len = 1;
Ok(None)
}
}
}
pub(crate) fn remove<J: Borrow<K> + ?Sized>(&mut self, key: &J) -> Result<Option<V>, HoldError> {
unsafe {
let old_len = self.len;
if old_len != 0 {
let hash = hash_key(&self.hasher, key.borrow());
let old_root = self.root.as_ptr();
match old_root.remove(key.borrow(), hash, 0) {
NodeRemove::None => Ok(None),
NodeRemove::Diff((old_key, old_val)) => {
mem::drop(old_key);
self.len = old_len.wrapping_sub(1);
Ok(Some(old_val))
},
NodeRemove::Drop((old_key, old_val)) => {
mem::drop(old_key);
let new_root = Node::<'a, K, V>::empty(old_root.holder());
old_root.dealloc();
self.root = NonNull::new_unchecked(new_root);
self.len = 0;
Ok(Some(old_val))
},
NodeRemove::Lift((old_key, old_val), (new_key, new_val)) => {
let new_hash = hash_key(&self.hasher, &new_key);
let new_root = match Node::unary(old_root.holder(), &new_key, &new_val, new_hash) {
Ok(new_root) => new_root,
Err(error) => return Err(error),
};
old_root.dealloc();
mem::drop(old_key);
mem::forget(new_key);
mem::forget(new_val);
self.root = NonNull::new_unchecked(new_root);
self.len = 1;
Ok(Some(old_val))
},
NodeRemove::Copy((old_key, old_val), new_node) => {
old_root.dealloc();
mem::drop(old_key);
self.root = NonNull::new_unchecked(new_node);
self.len = old_len.wrapping_sub(1);
Ok(Some(old_val))
},
NodeRemove::Fail(error) => return Err(error),
}
} else {
Ok(None)
}
}
}
}
unsafe impl<'a, K: Send, V: Send, H: Send> Send for HashTrie<'a, K, V, H> {
}
unsafe impl<'a, K: Sync, V: Sync, H: Sync> Sync for HashTrie<'a, K, V, H> {
}
unsafe impl<'a, #[may_dangle] K, #[may_dangle] V, H> Drop for HashTrie<'a, K, V, H> {
fn drop(&mut self) {
unsafe {
let root = self.root.as_ptr();
if self.len != 0 {
root.drop();
} else {
let block = Block::from_raw_parts(root as *mut u8, 0);
root.holder().dealloc(block);
}
}
}
}
impl<'a, K: Clone, V: Clone, H: Clone> TryClone for HashTrie<'a, K, V, H> {
fn try_clone(&self) -> Result<HashTrie<'a, K, V, H>, HoldError> {
unsafe {
let old_root = self.root.as_ptr();
let len = self.len;
if len != 0 {
let new_root = old_root.clone_tree(old_root.holder())?;
Ok(HashTrie {
root: NonNull::new_unchecked(new_root),
len: len,
hasher: self.hasher.clone(),
})
} else {
Ok(HashTrie::hold_new_hasher(self.holder(), self.hasher.clone()))
}
}
}
}
impl<'a, K: Clone, V: Clone, H: Clone> CloneIntoHold<'a, HashTrie<'a, K, V, H>> for HashTrie<'a, K, V, H> {
fn try_clone_into_hold(&self, hold: &dyn Hold<'a>) -> Result<HashTrie<'a, K, V, H>, HoldError> {
unsafe {
let old_root = self.root.as_ptr();
let len = self.len;
if len != 0 {
let new_root = old_root.clone_tree(hold)?;
Ok(HashTrie {
root: NonNull::new_unchecked(new_root),
len: len,
hasher: self.hasher.clone(),
})
} else {
Ok(HashTrie::hold_new_hasher(hold, self.hasher.clone()))
}
}
}
}
impl<'a, 'b, K, V, H> Stow<'b, HashTrie<'b, K, V, H>> for HashTrie<'a, K, V, H>
where K: Stow<'b>,
V: Stow<'b>,
H: Stow<'b>,
{
unsafe fn stow(src: *mut HashTrie<'a, K, V, H>, dst: *mut HashTrie<'b, K, V, H>, hold: &Hold<'b>)
-> Result<(), HoldError>
{
let old_root = (*src).root.as_ptr();
let len = (*src).len;
if let err @ Err(_) = H::stow(&mut (*src).hasher, &mut (*dst).hasher, hold) {
return err;
}
if len != 0 {
let new_root = match old_root.move_tree(hold) {
Ok(new_root) => new_root,
Err(error) => {
H::unstow(&mut (*src).hasher, &mut (*dst).hasher);
return Err(error);
},
};
ptr::write(&mut (*dst).len, ptr::read(&(*src).len));
ptr::write(&mut (*dst).root, NonNull::new_unchecked(new_root));
ptr::write(&mut (*src).len, 0);
ptr::write(&mut (*src).root, NonNull::new_unchecked(Node::empty(old_root.holder())));
old_root.dealloc_tree();
} else {
ptr::write(&mut (*dst).len, 0);
ptr::write(&mut (*dst).root, NonNull::new_unchecked(Node::empty(hold)));
}
Ok(())
}
unsafe fn unstow(_src: *mut HashTrie<'a, K, V, H>, _dst: *mut HashTrie<'b, K, V, H>) {
panic!("unsupported");
}
}
impl<'a, K, V> Node<'a, K, V> {
unsafe fn empty(hold: &dyn Hold<'a>) -> *mut Node<'a, K, V> {
let layout = Layout::empty();
let block = hold.alloc(layout).unwrap();
block.as_ptr() as *mut Node<'a, K, V>
}
unsafe fn alloc(hold: &dyn Hold<'a>, limb_map: u32, leaf_map: u32)
-> Result<*mut Node<'a, K, V>, HoldError>
{
debug_assert!(leaf_map != 0 || limb_map != 0);
let limb_count = limb_map.count_ones() as usize;
let leaf_count = (!limb_map & leaf_map).count_ones() as usize;
let layout = Layout::for_type::<Node<'a, K, V>>()
.extended_by_array::<*mut *mut Limb<'a, K, V>>(limb_count)?.0
.extended_by_array::<(K, V)>(leaf_count)?.0;
let node = hold.alloc(layout)?.as_ptr() as *mut Node<'a, K, V>;
ptr::write(&mut (*node).limb_map, limb_map);
ptr::write(&mut (*node).leaf_map, leaf_map);
Ok(node)
}
unsafe fn dealloc(self: *mut Node<'a, K, V>) {
let limb_map = (*self).limb_map;
let leaf_map = (*self).leaf_map;
let limb_count = limb_map.count_ones() as usize;
let leaf_count = (!limb_map & leaf_map).count_ones() as usize;
let layout = Layout::for_type::<Node<'a, K, V>>()
.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count).0
.extended_by_array_unchecked::<(K, V)>(leaf_count).0;
let block = Block::from_raw_parts(self as *mut u8, layout.size());
self.holder().dealloc(block);
}
unsafe fn dealloc_tree(self: *mut Node<'a, K, V>) {
let mut limb_map = (*self).limb_map;
let mut leaf_map = (*self).leaf_map;
let limb_count = limb_map.count_ones() as usize;
let leaf_count = (!limb_map & leaf_map).count_ones() as usize;
let layout = Layout::for_type::<Node<'a, K, V>>();
let (layout, limb_offset) = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count);
let layout = layout.extended_by_array_unchecked::<(K, V)>(leaf_count).0;
let mut limb_ptr = (self as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
while limb_map | leaf_map != 0 {
let branch_type = BranchType::for_branch(limb_map, leaf_map, 1);
if branch_type == BranchType::Void {
} else if branch_type == BranchType::Leaf {
} else {
if branch_type == BranchType::Node {
(*(limb_ptr as *mut *mut Node<'a, K, V>)).dealloc_tree();
} else if branch_type == BranchType::Knot {
(*(limb_ptr as *mut *mut Knot<'a, K, V>)).dealloc();
}
limb_ptr = limb_ptr.wrapping_add(1);
}
limb_map >>= 1;
leaf_map >>= 1;
}
let block = Block::from_raw_parts(self as *mut u8, layout.size());
self.holder().dealloc(block);
}
unsafe fn drop(self: *mut Node<'a, K, V>) {
let mut limb_map = (*self).limb_map;
let mut leaf_map = (*self).leaf_map;
let limb_count = limb_map.count_ones() as usize;
let leaf_count = (!limb_map & leaf_map).count_ones() as usize;
let layout = Layout::for_type::<Node<'a, K, V>>();
let (layout, limb_offset) = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count);
let (layout, leaf_offset) = layout.extended_by_array_unchecked::<(K, V)>(leaf_count);
let mut limb_ptr = (self as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
let mut leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
while limb_map | leaf_map != 0 {
let branch_type = BranchType::for_branch(limb_map, leaf_map, 1);
if branch_type == BranchType::Void {
} else if branch_type == BranchType::Leaf {
ptr::drop_in_place(leaf_ptr);
leaf_ptr = leaf_ptr.wrapping_add(1);
} else {
if branch_type == BranchType::Node {
(*(limb_ptr as *mut *mut Node<'a, K, V>)).drop();
} else if branch_type == BranchType::Knot {
(*(limb_ptr as *mut *mut Knot<'a, K, V>)).drop();
}
limb_ptr = limb_ptr.wrapping_add(1);
}
limb_map >>= 1;
leaf_map >>= 1;
}
let block = Block::from_raw_parts(self as *mut u8, layout.size());
self.holder().dealloc(block);
}
unsafe fn unary(hold: &dyn Hold<'a>, key: *const K, val: *const V, hash: u64)
-> Result<*mut Node<'a, K, V>, HoldError>
{
let limb_map = 0;
let leaf_map = branch32(hash, 0);
let node = Node::alloc(hold, limb_map, leaf_map)?;
let leaf_offset = Layout::for_type::<Node<'a, K, V>>()
.aligned_to_type::<*mut Limb<'a, K, V>>()
.aligned_to_type::<(K, V)>()
.size();
let leaf_ptr = (node as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
ptr::copy_nonoverlapping(key, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(val, &mut (*leaf_ptr).1, 1);
Ok(node)
}
#[inline]
unsafe fn holder(self: *mut Node<'a, K, V>) -> &'a dyn Hold<'a> {
AllocTag::from_ptr(self as *mut u8).holder()
}
unsafe fn remap(self: *mut Node<'a, K, V>, hold: &dyn Hold<'a>,
mut new_limb_map: u32, mut new_leaf_map: u32)
-> Result<*mut Node<'a, K, V>, HoldError>
{
debug_assert!(new_leaf_map != 0 || new_limb_map != 0);
let mut old_limb_map = (*self).limb_map;
let mut old_leaf_map = (*self).leaf_map;
let layout = Layout::for_type::<Node<'a, K, V>>();
let old_limb_count = old_limb_map.count_ones() as usize;
let (old_layout, old_limb_offset) =
layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(old_limb_count);
let old_leaf_offset = old_layout.padded_to_type::<(K, V)>().size();
let new_limb_count = new_limb_map.count_ones() as usize;
let new_leaf_count = (!new_limb_map & new_leaf_map).count_ones() as usize;
let (new_layout, new_limb_offset) =
layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(new_limb_count);
let (new_layout, new_leaf_offset) =
new_layout.extended_by_array_unchecked::<(K, V)>(new_leaf_count);
let new_node = hold.alloc(new_layout)?.as_ptr() as *mut Node<'a, K, V>;
ptr::write(&mut (*new_node).limb_map, new_limb_map);
ptr::write(&mut (*new_node).leaf_map, new_leaf_map);
let mut old_limb_ptr = (self as *mut u8).wrapping_add(old_limb_offset) as *mut *mut Limb<'a, K, V>;
let mut old_leaf_ptr = (self as *mut u8).wrapping_add(old_leaf_offset) as *mut (K, V);
let mut new_limb_ptr = (new_node as *mut u8).wrapping_add(new_limb_offset) as *mut *mut Limb<'a, K, V>;
let mut new_leaf_ptr = (new_node as *mut u8).wrapping_add(new_leaf_offset) as *mut (K, V);
while new_limb_map | new_leaf_map != 0 {
if (old_limb_map & new_limb_map) & 1 != 0 {
ptr::copy_nonoverlapping(old_limb_ptr, new_limb_ptr, 1);
old_limb_ptr = old_limb_ptr.wrapping_add(1);
new_limb_ptr = new_limb_ptr.wrapping_add(1);
} else if (old_limb_map | new_limb_map) & 1 == 0 && (old_leaf_map & new_leaf_map) & 1 != 0 {
ptr::copy_nonoverlapping(old_leaf_ptr, new_leaf_ptr, 1);
old_leaf_ptr = old_leaf_ptr.wrapping_add(1);
new_leaf_ptr = new_leaf_ptr.wrapping_add(1);
} else {
if old_limb_map & 1 != 0 {
old_limb_ptr = old_limb_ptr.wrapping_add(1);
} else if old_leaf_map & 1 != 0 {
old_leaf_ptr = old_leaf_ptr.wrapping_add(1);
}
if new_limb_map & 1 != 0 {
new_limb_ptr = new_limb_ptr.wrapping_add(1);
} else if new_leaf_map & 1 != 0 {
new_leaf_ptr = new_leaf_ptr.wrapping_add(1);
}
}
old_limb_map >>= 1;
old_leaf_map >>= 1;
new_limb_map >>= 1;
new_leaf_map >>= 1;
}
Ok(new_node)
}
unsafe fn move_tree<'b>(self: *mut Node<'a, K, V>, hold: &dyn Hold<'b>)
-> Result<*mut Node<'b, K, V>, HoldError>
where K: Stow<'b>,
V: Stow<'b>,
{
let limb_map = (*self).limb_map;
let leaf_map = (*self).leaf_map;
let layout = Layout::for_type::<Node<'a, K, V>>();
let limb_count = limb_map.count_ones() as usize;
let leaf_count = (!limb_map & leaf_map).count_ones() as usize;
let (layout, limb_offset) = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count);
let (layout, leaf_offset) = layout.extended_by_array_unchecked::<(K, V)>(leaf_count);
let new_node = hold.alloc(layout)?.as_ptr() as *mut Node<'b, K, V>;
ptr::write(&mut (*new_node).limb_map, limb_map);
ptr::write(&mut (*new_node).leaf_map, leaf_map);
let mut old_limb_ptr = (self as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
let mut old_leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let mut new_limb_ptr = (new_node as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
let mut new_leaf_ptr = (new_node as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let mut branch = 1u32;
while (limb_map | leaf_map) & !branch.wrapping_sub(1) != 0 {
let branch_type = BranchType::for_branch(limb_map, leaf_map, branch);
if branch_type == BranchType::Void {
} else if branch_type == BranchType::Leaf {
if let Err(error) = Stow::stow(old_leaf_ptr, new_leaf_ptr, hold) {
while (limb_map | leaf_map) & branch.wrapping_sub(1) != 0 {
branch >>= 1;
let branch_type = BranchType::for_branch(limb_map, leaf_map, branch);
if branch_type == BranchType::Void {
} else if branch_type == BranchType::Leaf {
old_leaf_ptr = old_leaf_ptr.wrapping_sub(1);
new_leaf_ptr = new_leaf_ptr.wrapping_sub(1);
Stow::unstow(old_leaf_ptr, new_leaf_ptr);
} else {
new_limb_ptr = new_limb_ptr.wrapping_sub(1);
if branch_type == BranchType::Node {
(*new_limb_ptr as *mut Node<'a, K, V>).dealloc_tree();
} else if branch_type == BranchType::Knot {
(*new_limb_ptr as *mut Knot<'a, K, V>).dealloc();
}
}
}
new_node.dealloc();
return Err(error);
}
old_leaf_ptr = old_leaf_ptr.wrapping_add(1);
new_leaf_ptr = new_leaf_ptr.wrapping_add(1);
} else {
let old_sub_limb = *old_limb_ptr;
let new_sub_limb = if branch_type == BranchType::Node {
let new_sub_node = (old_sub_limb as *mut Node<'a, K, V>).move_tree(hold);
mem::transmute::<_, Result<*mut Limb<'a, K, V>, HoldError>>(new_sub_node)
} else if branch_type == BranchType::Knot {
let new_sub_knot = (old_sub_limb as *mut Knot<'a, K, V>).move_tree(hold);
mem::transmute::<_, Result<*mut Limb<'a, K, V>, HoldError>>(new_sub_knot)
} else {
unreachable!()
};
match new_sub_limb {
Ok(new_sub_limb) => {
ptr::write(new_limb_ptr, new_sub_limb);
old_limb_ptr = old_limb_ptr.wrapping_add(1);
new_limb_ptr = new_limb_ptr.wrapping_add(1);
},
Err(error) => {
while (limb_map | leaf_map) & branch.wrapping_sub(1) != 0 {
branch >>= 1;
let branch_type = BranchType::for_branch(limb_map, leaf_map, branch);
if branch_type == BranchType::Void {
} else if branch_type == BranchType::Leaf {
old_leaf_ptr = old_leaf_ptr.wrapping_sub(1);
new_leaf_ptr = new_leaf_ptr.wrapping_sub(1);
Stow::unstow(old_leaf_ptr, new_leaf_ptr);
} else {
new_limb_ptr = new_limb_ptr.wrapping_sub(1);
if branch_type == BranchType::Node {
(*new_limb_ptr as *mut Node<'a, K, V>).dealloc_tree();
} else if branch_type == BranchType::Knot {
(*new_limb_ptr as *mut Knot<'a, K, V>).dealloc();
}
}
}
new_node.dealloc();
return Err(error);
},
}
}
branch <<= 1;
}
Ok(new_node)
}
unsafe fn clone_tree(self: *mut Node<'a, K, V>, hold: &dyn Hold<'a>)
-> Result<*mut Node<'a, K, V>, HoldError>
where K: Clone, V: Clone
{
let limb_map = (*self).limb_map;
let leaf_map = (*self).leaf_map;
let layout = Layout::for_type::<Node<'a, K, V>>();
let limb_count = limb_map.count_ones() as usize;
let leaf_count = (!limb_map & leaf_map).count_ones() as usize;
let (layout, limb_offset) = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count);
let (layout, leaf_offset) = layout.extended_by_array_unchecked::<(K, V)>(leaf_count);
let new_node = hold.alloc(layout)?.as_ptr() as *mut Node<'a, K, V>;
ptr::write(&mut (*new_node).limb_map, limb_map);
ptr::write(&mut (*new_node).leaf_map, leaf_map);
let mut old_limb_ptr = (self as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
let mut old_leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let mut new_limb_ptr = (new_node as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
let mut new_leaf_ptr = (new_node as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let mut branch = 1u32;
while (limb_map | leaf_map) & !branch.wrapping_sub(1) != 0 {
let branch_type = BranchType::for_branch(limb_map, leaf_map, branch);
if branch_type == BranchType::Void {
} else if branch_type == BranchType::Leaf {
ptr::write(new_leaf_ptr, (*old_leaf_ptr).clone());
old_leaf_ptr = old_leaf_ptr.wrapping_add(1);
new_leaf_ptr = new_leaf_ptr.wrapping_add(1);
} else {
let old_sub_limb = *old_limb_ptr;
let new_sub_limb = if branch_type == BranchType::Node {
let new_sub_node = (old_sub_limb as *mut Node<'a, K, V>).clone_tree(hold);
mem::transmute::<_, Result<*mut Limb<'a, K, V>, HoldError>>(new_sub_node)
} else if branch_type == BranchType::Knot {
let new_sub_knot = (old_sub_limb as *mut Knot<'a, K, V>).clone_tree(hold);
mem::transmute::<_, Result<*mut Limb<'a, K, V>, HoldError>>(new_sub_knot)
} else {
unreachable!()
};
match new_sub_limb {
Ok(new_sub_limb) => {
ptr::write(new_limb_ptr, new_sub_limb);
old_limb_ptr = old_limb_ptr.wrapping_add(1);
new_limb_ptr = new_limb_ptr.wrapping_add(1);
},
Err(error) => {
while (limb_map | leaf_map) & branch.wrapping_sub(1) != 0 {
branch >>= 1;
let branch_type = BranchType::for_branch(limb_map, leaf_map, branch);
if branch_type == BranchType::Void {
} else if branch_type == BranchType::Leaf {
new_leaf_ptr = new_leaf_ptr.wrapping_sub(1);
ptr::drop_in_place(new_leaf_ptr);
} else {
new_limb_ptr = new_limb_ptr.wrapping_sub(1);
if branch_type == BranchType::Node {
(*new_limb_ptr as *mut Node<'a, K, V>).drop();
} else if branch_type == BranchType::Knot {
(*new_limb_ptr as *mut Knot<'a, K, V>).drop();
}
}
}
new_node.dealloc();
return Err(error);
},
}
}
branch <<= 1;
}
Ok(new_node)
}
unsafe fn merged_leaf(hold: &dyn Hold<'a>, key0: *const K, val0: *const V, hash0: u64,
key1: *const K, val1: *const V, hash1: u64, shift: u32)
-> Result<*mut Node<'a, K, V>, HoldError>
{
debug_assert!(hash0 != hash1);
let branch0 = branch32(hash0, shift);
let branch1 = branch32(hash1, shift);
let layout = Layout::for_type::<Node<'a, K, V>>();
let node;
if branch0 == branch1 {
let (layout, limb_offset) = layout.extended_by_array::<*mut *mut Limb<'a, K, V>>(1)?;
let layout = layout.padded_to_type::<(K, V)>();
node = hold.alloc(layout)?.as_ptr() as *mut Node<'a, K, V>;
ptr::write(&mut (*node).limb_map, branch0 & branch1);
ptr::write(&mut (*node).leaf_map, 0);
let sub_node = match Node::merged_leaf(hold, key0, val0, hash0,
key1, val1, hash1, shift.wrapping_add(5)) {
Ok(sub_node) => sub_node,
err @ Err(..) => {
node.dealloc();
return err;
},
};
let sub_node_ptr = (node as *mut u8).wrapping_add(limb_offset) as *mut *mut Node<'a, K, V>;
ptr::write(sub_node_ptr, sub_node);
} else {
let layout = layout.padded_to_type::<*mut Limb<'a, K, V>>();
let (layout, leaf_offset) = layout.extended_by_array::<(K, V)>(2)?;
node = hold.alloc(layout)?.as_ptr() as *mut Node<'a, K, V>;
ptr::write(&mut (*node).limb_map, 0);
ptr::write(&mut (*node).leaf_map, branch0 | branch1);
let leaf_ptr = (node as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
if branch0.wrapping_sub(1) & branch1 == 0 {
ptr::copy_nonoverlapping(key0, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(val0, &mut (*leaf_ptr).1, 1);
let leaf_ptr = leaf_ptr.wrapping_add(1);
ptr::copy_nonoverlapping(key1, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(val1, &mut (*leaf_ptr).1, 1);
} else {
ptr::copy_nonoverlapping(key1, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(val1, &mut (*leaf_ptr).1, 1);
let leaf_ptr = leaf_ptr.wrapping_add(1);
ptr::copy_nonoverlapping(key0, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(val0, &mut (*leaf_ptr).1, 1);
}
}
Ok(node)
}
unsafe fn merged_knot(hold: &dyn Hold<'a>, knot0: *mut Knot<'a, K, V>, hash0: u64,
key1: *const K, val1: *const V, hash1: u64, shift: u32)
-> Result<*mut Node<'a, K, V>, HoldError>
{
debug_assert!(hash0 != hash1);
let branch0 = branch32(hash0, shift);
let branch1 = branch32(hash1, shift);
let layout = Layout::for_type::<Node<'a, K, V>>();
let node;
if branch0 == branch1 {
let (layout, limb_offset) = layout.extended_by_array::<*mut *mut Limb<'a, K, V>>(1)?;
let layout = layout.padded_to_type::<(K, V)>();
node = hold.alloc(layout)?.as_ptr() as *mut Node<'a, K, V>;
ptr::write(&mut (*node).limb_map, branch0 & branch1);
ptr::write(&mut (*node).leaf_map, 0);
let sub_node = match Node::merged_knot(hold, knot0, hash0,
key1, val1, hash1, shift.wrapping_add(5)) {
Ok(sub_node) => sub_node,
err @ Err(..) => {
node.dealloc();
return err;
},
};
let sub_node_ptr = (node as *mut u8).wrapping_add(limb_offset) as *mut *mut Node<'a, K, V>;
ptr::write(sub_node_ptr, sub_node);
} else {
let (layout, limb_offset) = layout.extended_by_array::<*mut *mut Limb<'a, K, V>>(1)?;
let (layout, leaf_offset) = layout.extended_by_array::<(K, V)>(1)?;
node = hold.alloc(layout)?.as_ptr() as *mut Node<'a, K, V>;
ptr::write(&mut (*node).limb_map, branch0);
ptr::write(&mut (*node).leaf_map, branch0 | branch1);
let sub_knot_ptr = (node as *mut u8).wrapping_add(limb_offset) as *mut *mut Knot<'a, K, V>;
ptr::write(sub_knot_ptr, knot0);
let leaf_ptr = (node as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
ptr::copy_nonoverlapping(key1, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(val1, &mut (*leaf_ptr).1, 1);
}
Ok(node)
}
}
impl<'a, K: Eq + Hash, V> Node<'a, K, V> {
unsafe fn contains_key(mut self: *mut Node<'a, K, V>, key: &K, hash: u64, mut shift: u32) -> bool {
loop {
let limb_map = (*self).limb_map;
let leaf_map = (*self).leaf_map;
let branch = branch32(hash, shift);
let branch_type = BranchType::for_branch(limb_map, leaf_map, branch);
if branch_type == BranchType::Void {
return false;
} else {
let layout = Layout::for_type::<Node<'a, K, V>>();
if branch_type == BranchType::Leaf {
let limb_count = limb_map.count_ones() as usize;
let leaf_idx = (!limb_map & leaf_map & branch.wrapping_sub(1)).count_ones() as usize;
let leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count).0
.extended_by_array_unchecked::<(K, V)>(leaf_idx).0
.size();
let leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
return &(*leaf_ptr).0 == key;
} else {
let limb_idx = (limb_map & branch.wrapping_sub(1)).count_ones() as usize;
let limb_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_idx).0
.size();
let limb_ptr = (self as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
if branch_type == BranchType::Node {
self = *(limb_ptr as *mut *mut Node<'a, K, V>);
shift += 5;
continue;
} else if branch_type == BranchType::Knot {
return (*(limb_ptr as *mut *mut Knot<'a, K, V>)).contains_key(key);
}
}
}
unreachable!();
}
}
unsafe fn get<'b, 'c>(mut self: *mut Node<'a, K, V>, key: &'b K, hash: u64, mut shift: u32)
-> Option<&'c V>
{
loop {
let limb_map = (*self).limb_map;
let leaf_map = (*self).leaf_map;
let branch = branch32(hash, shift);
let branch_type = BranchType::for_branch(limb_map, leaf_map, branch);
if branch_type == BranchType::Void {
return None;
} else {
let layout = Layout::for_type::<Node<'a, K, V>>();
if branch_type == BranchType::Leaf {
let limb_count = limb_map.count_ones() as usize;
let leaf_idx = (!limb_map & leaf_map & branch.wrapping_sub(1)).count_ones() as usize;
let leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count).0
.extended_by_array_unchecked::<(K, V)>(leaf_idx).0
.size();
let leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
if &(*leaf_ptr).0 == key {
return Some(&(*leaf_ptr).1);
} else {
return None;
}
} else {
let limb_idx = (limb_map & branch.wrapping_sub(1)).count_ones() as usize;
let limb_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_idx).0
.size();
let limb_ptr = (self as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
if branch_type == BranchType::Node {
self = *(limb_ptr as *mut *mut Node<'a, K, V>);
shift += 5;
continue;
} else if branch_type == BranchType::Knot {
return (*(limb_ptr as *mut *mut Knot<'a, K, V>)).get(key);
}
}
}
unreachable!();
}
}
unsafe fn insert<H: BuildHasher>(self: *mut Node<'a, K, V>, hasher: &H,
new_key: *const K, new_val: *const V, new_hash: u64,
shift: u32)
-> NodeInsert<'a, K, V>
{
let old_limb_map = (*self).limb_map;
let old_leaf_map = (*self).leaf_map;
let layout = Layout::for_type::<Node<'a, K, V>>();
let branch = branch32(new_hash, shift);
let branch_type = BranchType::for_branch(old_limb_map, old_leaf_map, branch);
if branch_type == BranchType::Void {
let new_limb_map = old_limb_map;
let new_leaf_map = old_leaf_map | branch;
let new_node = match self.remap(self.holder(), old_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeInsert::Fail(error),
};
let new_limb_count = new_limb_map.count_ones() as usize;
let new_leaf_idx = (!new_limb_map & new_leaf_map & branch.wrapping_sub(1)).count_ones() as usize;
let new_leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(new_limb_count).0
.extended_by_array_unchecked::<(K, V)>(new_leaf_idx).0
.size();
let new_leaf_ptr = (new_node as *mut u8).wrapping_add(new_leaf_offset) as *mut (K, V);
ptr::copy_nonoverlapping(new_key, &mut (*new_leaf_ptr).0, 1);
ptr::copy_nonoverlapping(new_val, &mut (*new_leaf_ptr).1, 1);
return NodeInsert::Copy(new_node);
} else if branch_type == BranchType::Leaf {
let old_limb_count = old_limb_map.count_ones() as usize;
let old_leaf_idx = (!old_limb_map & old_leaf_map & branch.wrapping_sub(1)).count_ones() as usize;
let old_leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(old_limb_count).0
.extended_by_array_unchecked::<(K, V)>(old_leaf_idx).0
.size();
let old_leaf_ptr = (self as *mut u8).wrapping_add(old_leaf_offset) as *mut (K, V);
if &(*old_leaf_ptr).0 == &*new_key {
ptr::drop_in_place(&mut (*old_leaf_ptr).0);
let old_val = ptr::read(&(*old_leaf_ptr).1);
ptr::copy_nonoverlapping(new_key, &mut (*old_leaf_ptr).0, 1);
ptr::copy_nonoverlapping(new_val, &mut (*old_leaf_ptr).1, 1);
return NodeInsert::Diff(old_val);
} else {
let new_limb_map = old_limb_map | branch;
let sub_limb_idx = (new_limb_map & branch.wrapping_sub(1)).count_ones() as usize;
let sub_limb_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(sub_limb_idx).0
.size();
let old_hash = hash_key(hasher, &(*old_leaf_ptr).0);
if old_hash != new_hash {
let new_leaf_map = old_leaf_map ^ branch;
let new_node = match self.remap(self.holder(), new_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeInsert::Fail(error),
};
let sub_node = match Node::merged_leaf(self.holder(),
&(*old_leaf_ptr).0, &(*old_leaf_ptr).1, old_hash,
new_key, new_val, new_hash,
shift.wrapping_add(5)) {
Ok(sub_node) => sub_node,
Err(error) => {
new_node.dealloc();
return NodeInsert::Fail(error);
},
};
let sub_node_ptr = (new_node as *mut u8).wrapping_add(sub_limb_offset) as *mut *mut Node<'a, K, V>;
ptr::write(sub_node_ptr, sub_node);
return NodeInsert::Copy(new_node);
} else {
let new_leaf_map = old_leaf_map;
let new_node = match self.remap(self.holder(), new_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeInsert::Fail(error),
};
let sub_knot = match Knot::binary(self.holder(), new_hash,
&(*old_leaf_ptr).0, &(*old_leaf_ptr).1,
new_key, new_val) {
Ok(sub_knot) => sub_knot,
Err(error) => {
new_node.dealloc();
return NodeInsert::Fail(error);
},
};
let sub_knot_ptr = (new_node as *mut u8).wrapping_add(sub_limb_offset) as *mut *mut Knot<'a, K, V>;
ptr::write(sub_knot_ptr, sub_knot);
return NodeInsert::Copy(new_node);
}
}
} else {
let sub_limb_idx = (old_limb_map & branch.wrapping_sub(1)).count_ones() as usize;
let sub_limb_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(sub_limb_idx).0
.size();
let sub_limb_ptr = (self as *mut u8).wrapping_add(sub_limb_offset) as *mut *mut Limb<'a, K, V>;
if branch_type == BranchType::Node {
let old_sub_node = *(sub_limb_ptr as *mut *mut Node<'a, K, V>);
match old_sub_node.insert(hasher, new_key, new_val, new_hash, shift.wrapping_add(5)) {
none @ NodeInsert::None => return none,
diff @ NodeInsert::Diff(..) => return diff,
NodeInsert::Copy(new_sub_node) => {
old_sub_node.dealloc();
ptr::write(sub_limb_ptr as *mut *mut Node<'a, K, V>, new_sub_node);
return NodeInsert::None;
},
fail @ NodeInsert::Fail(..) => return fail,
}
} else if branch_type == BranchType::Knot {
let old_sub_knot = *(sub_limb_ptr as *mut *mut Knot<'a, K, V>);
let old_hash = (*old_sub_knot).hash;
if old_hash == new_hash {
match old_sub_knot.insert(new_key, new_val) {
KnotInsert::Diff(old_val) => return NodeInsert::Diff(old_val),
KnotInsert::Copy(new_sub_knot) => {
old_sub_knot.dealloc();
ptr::write(sub_limb_ptr as *mut *mut Knot<'a, K, V>, new_sub_knot);
return NodeInsert::None;
},
KnotInsert::Fail(error) => return NodeInsert::Fail(error),
}
} else {
let sub_node = match Node::merged_knot(self.holder(), old_sub_knot, old_hash,
new_key, new_val, new_hash,
shift.wrapping_add(5)) {
Ok(sub_node) => sub_node,
Err(error) => return NodeInsert::Fail(error),
};
(*self).leaf_map = old_leaf_map ^ branch;
ptr::write(sub_limb_ptr as *mut *mut Node<'a, K, V>, sub_node);
return NodeInsert::None;
}
}
}
unreachable!();
}
unsafe fn remove(self: *mut Node<'a, K, V>, new_key: &K, new_hash: u64, shift: u32)
-> NodeRemove<'a, K, V>
{
let old_limb_map = (*self).limb_map;
let old_leaf_map = (*self).leaf_map;
let layout = Layout::for_type::<Node<'a, K, V>>();
let branch = branch32(new_hash, shift);
let branch_type = BranchType::for_branch(old_limb_map, old_leaf_map, branch);
if branch_type == BranchType::Void {
return NodeRemove::None;
} else if branch_type == BranchType::Leaf {
let old_limb_count = old_limb_map.count_ones() as usize;
let old_leaf_idx = (!old_limb_map & old_leaf_map & branch.wrapping_sub(1)).count_ones() as usize;
let layout = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(old_limb_count).0;
let old_leaf_offset = layout.extended_by_array_unchecked::<(K, V)>(old_leaf_idx).0
.size();
let old_leaf_ptr = (self as *mut u8).wrapping_add(old_leaf_offset) as *mut (K, V);
if &(*old_leaf_ptr).0 == new_key {
let old_leaf = ptr::read(old_leaf_ptr);
let new_limb_map = old_limb_map;
let new_leaf_map = old_leaf_map ^ branch;
let new_limb_count = old_limb_count;
if new_limb_count == 0 {
let new_leaf_count = (!new_limb_map & new_leaf_map).count_ones();
if new_leaf_count == 0 {
return NodeRemove::Drop(old_leaf);
}
if new_leaf_count == 1 {
let new_leaf_idx = 1usize.wrapping_sub(old_leaf_idx);
let new_leaf_offset = layout.extended_by_array_unchecked::<(K, V)>(new_leaf_idx).0
.size();
let new_leaf_ptr = (self as *mut u8).wrapping_add(new_leaf_offset) as *mut (K, V);
let new_leaf = ptr::read(new_leaf_ptr);
return NodeRemove::Lift(old_leaf, new_leaf);
}
}
let new_node = match self.remap(self.holder(), new_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeRemove::Fail(error),
};
return NodeRemove::Copy(old_leaf, new_node);
} else {
return NodeRemove::None;
}
} else {
let sub_limb_idx = (old_limb_map & branch.wrapping_sub(1)).count_ones() as usize;
let sub_limb_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(sub_limb_idx).0
.size();
let sub_limb_ptr = (self as *mut u8).wrapping_add(sub_limb_offset) as *mut *mut Limb<'a, K, V>;
if branch_type == BranchType::Node {
let old_sub_node = *(sub_limb_ptr as *mut *mut Node<'a, K, V>);
match old_sub_node.remove(new_key, new_hash, shift.wrapping_add(5)) {
none @ NodeRemove::None => return none,
diff @ NodeRemove::Diff(..) => return diff,
NodeRemove::Drop(old_leaf) => {
let new_limb_map = old_limb_map ^ branch;
let new_leaf_map = old_leaf_map;
let new_limb_count = new_limb_map.count_ones();
if new_limb_count == 0 {
let new_leaf_count = (!new_limb_map & new_leaf_map).count_ones();
if new_leaf_count == 0 {
old_sub_node.dealloc();
return NodeRemove::Drop(old_leaf);
}
if new_leaf_count == 1 {
old_sub_node.dealloc();
let new_leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(1).0
.padded_to_type::<(K, V)>()
.size();
let new_leaf_ptr = (self as *mut u8).wrapping_add(new_leaf_offset) as *mut (K, V);
let new_leaf = ptr::read(new_leaf_ptr);
return NodeRemove::Lift(old_leaf, new_leaf);
}
}
let new_node = match self.remap(self.holder(), new_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeRemove::Fail(error),
};
old_sub_node.dealloc();
return NodeRemove::Copy(old_leaf, new_node);
},
NodeRemove::Lift(old_leaf, new_leaf) => {
let new_limb_map = old_limb_map ^ branch;
let new_leaf_map = old_leaf_map | branch;
let new_node = match self.remap(self.holder(), new_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeRemove::Fail(error),
};
old_sub_node.dealloc();
let new_limb_count = new_limb_map.count_ones() as usize;
let new_leaf_idx = (!new_limb_map & new_leaf_map & branch.wrapping_sub(1)).count_ones() as usize;
let new_leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(new_limb_count).0
.extended_by_array_unchecked::<(K, V)>(new_leaf_idx).0
.size();
let new_leaf_ptr = (new_node as *mut u8).wrapping_add(new_leaf_offset) as *mut (K, V);
ptr::write(new_leaf_ptr, new_leaf);
return NodeRemove::Copy(old_leaf, new_node)
},
NodeRemove::Copy(old_leaf, new_node) => {
old_sub_node.dealloc();
ptr::write(sub_limb_ptr as *mut *mut Node<'a, K, V>, new_node);
return NodeRemove::Diff(old_leaf)
},
fail @ NodeRemove::Fail(..) => return fail,
}
} else if branch_type == BranchType::Knot {
let old_sub_knot = *(sub_limb_ptr as *mut *mut Knot<'a, K, V>);
match old_sub_knot.remove(new_key) {
KnotRemove::None => return NodeRemove::None,
KnotRemove::Drop(old_leaf) => {
let new_limb_map = old_limb_map ^ branch;
let new_leaf_map = old_leaf_map;
let new_limb_count = new_limb_map.count_ones();
if new_limb_count == 0 {
let new_leaf_count = (!new_limb_map & new_leaf_map).count_ones();
if new_leaf_count == 0 {
old_sub_knot.dealloc();
return NodeRemove::Drop(old_leaf);
}
if new_leaf_count == 1 {
old_sub_knot.dealloc();
let new_leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(1).0
.padded_to_type::<(K, V)>()
.size();
let new_leaf_ptr = (self as *mut u8).wrapping_add(new_leaf_offset) as *mut (K, V);
let new_leaf = ptr::read(new_leaf_ptr);
return NodeRemove::Lift(old_leaf, new_leaf);
}
}
let new_node = match self.remap(self.holder(), new_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeRemove::Fail(error),
};
old_sub_knot.dealloc();
return NodeRemove::Copy(old_leaf, new_node);
},
KnotRemove::Lift(old_leaf, new_leaf) => {
let new_limb_map = old_limb_map ^ branch;
let new_leaf_map = old_leaf_map | branch;
let new_node = match self.remap(self.holder(), new_limb_map, new_leaf_map) {
Ok(new_node) => new_node,
Err(error) => return NodeRemove::Fail(error),
};
old_sub_knot.dealloc();
let new_limb_count = new_limb_map.count_ones() as usize;
let new_leaf_idx = (!new_limb_map & new_leaf_map & branch.wrapping_sub(1)).count_ones() as usize;
let new_leaf_offset = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(new_limb_count).0
.extended_by_array_unchecked::<(K, V)>(new_leaf_idx).0
.size();
let new_leaf_ptr = (new_node as *mut u8).wrapping_add(new_leaf_offset) as *mut (K, V);
ptr::write(new_leaf_ptr, new_leaf);
return NodeRemove::Copy(old_leaf, new_node);
},
KnotRemove::Copy(old_leaf, new_knot) => {
old_sub_knot.dealloc();
ptr::write(sub_limb_ptr as *mut *mut Knot<'a, K, V>, new_knot);
return NodeRemove::Diff(old_leaf);
},
KnotRemove::Fail(error) => return NodeRemove::Fail(error),
}
}
}
unreachable!();
}
}
impl<'a, K, V> Knot<'a, K, V> {
unsafe fn alloc(hold: &dyn Hold<'a>, hash: u64, len: usize) -> Result<*mut Knot<'a, K, V>, HoldError> {
debug_assert!(len != 0);
let layout = Layout::for_type::<Knot<'a, K, V>>().extended_by_array::<(K, V)>(len)?.0;
let knot = hold.alloc(layout)?.as_ptr() as *mut Knot<'a, K, V>;
ptr::write(&mut (*knot).hash, hash);
ptr::write(&mut (*knot).len, len);
Ok(knot)
}
unsafe fn dealloc(self: *mut Knot<'a, K, V>) {
let len = (*self).len;
let layout = Layout::for_type::<Knot<'a, K, V>>().extended_by_array_unchecked::<(K, V)>(len).0;
let block = Block::from_raw_parts(self as *mut u8, layout.size());
self.holder().dealloc(block);
}
unsafe fn drop(self: *mut Knot<'a, K, V>) {
let len = (*self).len;
let (layout, leaf_offset) = Layout::for_type::<Knot<'a, K, V>>()
.extended_by_array_unchecked::<(K, V)>(len);
let leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
ptr::drop_in_place(slice::from_raw_parts_mut(leaf_ptr, len));
let block = Block::from_raw_parts(self as *mut u8, layout.size());
self.holder().dealloc(block);
}
unsafe fn binary(hold: &dyn Hold<'a>, hash: u64, key0: *const K, value0: *const V,
key1: *const K, value1: *const V) -> Result<*mut Knot<'a, K, V>, HoldError> {
let knot = Knot::alloc(hold, hash, 2)?;
let leaf_ptr = knot.leaf_array();
ptr::copy_nonoverlapping(key0, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(value0, &mut (*leaf_ptr).1, 1);
let leaf_ptr = leaf_ptr.wrapping_add(1);
ptr::copy_nonoverlapping(key1, &mut (*leaf_ptr).0, 1);
ptr::copy_nonoverlapping(value1, &mut (*leaf_ptr).1, 1);
Ok(knot)
}
#[inline]
unsafe fn holder(self: *mut Knot<'a, K, V>) -> &'a dyn Hold<'a> {
AllocTag::from_ptr(self as *mut u8).holder()
}
#[inline]
unsafe fn leaf_array(self: *mut Knot<'a, K, V>) -> *mut (K, V) {
let offset = Layout::for_type::<Knot<'a, K, V>>().padded_to_type::<(K, V)>().size();
(self as *mut u8).wrapping_add(offset) as *mut (K, V)
}
unsafe fn move_tree<'b>(self: *mut Knot<'a, K, V>, hold: &dyn Hold<'b>)
-> Result<*mut Knot<'b, K, V>, HoldError>
where K: Stow<'b>,
V: Stow<'b>,
{
let len = (*self).len;
debug_assert!(len != 0);
let (layout, leaf_offset) = Layout::for_type::<Knot<'a, K, V>>()
.extended_by_array_unchecked::<(K, V)>(len);
let new_knot = hold.alloc(layout)?.as_ptr() as *mut Knot<'b, K, V>;
ptr::write(&mut (*new_knot).hash, (*self).hash);
ptr::write(&mut (*new_knot).len, len);
let mut old_leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let mut new_leaf_ptr = (new_knot as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let mut i = 0;
while i < len {
if let Err(error) = Stow::stow(old_leaf_ptr, new_leaf_ptr, hold) {
while i > 0 {
old_leaf_ptr = old_leaf_ptr.wrapping_sub(1);
new_leaf_ptr = new_leaf_ptr.wrapping_sub(1);
i = i.wrapping_sub(1);
Stow::unstow(old_leaf_ptr, new_leaf_ptr);
}
return Err(error);
}
old_leaf_ptr = old_leaf_ptr.wrapping_add(1);
new_leaf_ptr = new_leaf_ptr.wrapping_add(1);
i = i.wrapping_add(1);
}
Ok(new_knot)
}
unsafe fn clone_tree(self: *mut Knot<'a, K, V>, hold: &dyn Hold<'a>)
-> Result<*mut Knot<'a, K, V>, HoldError>
where K: Clone, V: Clone
{
let len = (*self).len;
debug_assert!(len != 0);
let (layout, leaf_offset) = Layout::for_type::<Knot<'a, K, V>>()
.extended_by_array_unchecked::<(K, V)>(len);
let new_knot = hold.alloc(layout)?.as_ptr() as *mut Knot<'a, K, V>;
ptr::write(&mut (*new_knot).hash, (*self).hash);
ptr::write(&mut (*new_knot).len, len);
let old_leaf_ptr = (self as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let new_leaf_ptr = (new_knot as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
let old_slice = slice::from_raw_parts(old_leaf_ptr, len);
let new_slice = slice::from_raw_parts_mut(new_leaf_ptr, len);
new_slice.clone_from_slice(old_slice);
Ok(new_knot)
}
}
impl<'a, K: Eq, V> Knot<'a, K, V> {
unsafe fn contains_key(self: *mut Knot<'a, K, V>, key: &K) -> bool {
let mut head = self.leaf_array();
let foot = head.wrapping_add((*self).len);
while head < foot {
if &(*head).0 == key {
return true;
}
head = head.wrapping_add(1);
}
false
}
unsafe fn get<'b, 'c>(self: *mut Knot<'a, K, V>, key: &'b K) -> Option<&'c V> {
let mut head = self.leaf_array();
let foot = head.wrapping_add((*self).len);
while head < foot {
if &(*head).0 == key {
return Some(&(*head).1);
}
head = head.wrapping_add(1);
}
None
}
unsafe fn insert(self: *mut Knot<'a, K, V>, new_key: *const K, new_val: *const V)
-> KnotInsert<'a, K, V>
{
let old_len = (*self).len;
let old_base = self.leaf_array();
let mut old_head = old_base;
let old_foot = old_base.wrapping_add(old_len);
while old_head < old_foot {
if &(*old_head).0 == &*new_key {
ptr::drop_in_place(&mut (*old_head).0);
let old_val = ptr::read(&(*old_head).1);
ptr::copy_nonoverlapping(new_key, &mut (*old_head).0, 1);
ptr::copy_nonoverlapping(new_val, &mut (*old_head).1, 1);
return KnotInsert::Diff(old_val);
}
old_head = old_head.wrapping_add(1);
}
let new_len = old_len.wrapping_add(1);
let new_knot = match Knot::alloc(self.holder(), (*self).hash, new_len) {
Ok(new_knot) => new_knot,
Err(error) => return KnotInsert::Fail(error),
};
let new_base = new_knot.leaf_array();
ptr::copy_nonoverlapping(old_base, new_base, old_len);
let new_head = new_base.wrapping_add(old_len);
ptr::copy_nonoverlapping(new_key, &mut (*new_head).0, 1);
ptr::copy_nonoverlapping(new_val, &mut (*new_head).1, 1);
KnotInsert::Copy(new_knot)
}
unsafe fn remove(self: *mut Knot<'a, K, V>, key: &K) -> KnotRemove<'a, K, V> {
let old_len = (*self).len;
let old_base = self.leaf_array();
let mut old_head = old_base;
let old_foot = old_base.wrapping_add(old_len);
let mut idx = 0usize;
while old_head < old_foot {
if &(*old_head).0 == &*key {
let old_leaf = ptr::read(old_head);
let new_len = old_len.wrapping_sub(1);
if new_len == 0 {
return KnotRemove::Drop(old_leaf);
}
if new_len == 1 {
let new_leaf = ptr::read(old_base.wrapping_add(1usize.wrapping_sub(idx)));
return KnotRemove::Lift(old_leaf, new_leaf);
}
let new_knot = match Knot::alloc(self.holder(), (*self).hash, new_len) {
Ok(new_knot) => new_knot,
Err(error) => return KnotRemove::Fail(error),
};
let new_base = new_knot.leaf_array();
ptr::copy_nonoverlapping(old_base, new_base, idx);
old_head = old_head.wrapping_add(1);
let new_head = new_base.wrapping_add(idx);
ptr::copy_nonoverlapping(old_head, new_head, new_len.wrapping_sub(idx));
return KnotRemove::Copy(old_leaf, new_knot);
}
old_head = old_head.wrapping_add(1);
idx = idx.wrapping_add(1);
}
KnotRemove::None
}
}
impl<'a, K, V> IterFrame<'a, K, V> {
#[inline]
unsafe fn from_node(node: *mut Node<'a, K, V>) -> IterFrame<'a, K, V> {
let limb_map = (*node).limb_map;
let leaf_map = (*node).leaf_map;
let limb_count = limb_map.count_ones() as usize;
let layout = Layout::for_type::<Node<'a, K, V>>();
let (layout, limb_offset) = layout.extended_by_array_unchecked::<*mut Limb<'a, K, V>>(limb_count);
let leaf_offset = layout.padded_to_type::<(K, V)>().size();
let limb_ptr = (node as *mut u8).wrapping_add(limb_offset) as *mut *mut Limb<'a, K, V>;
let leaf_ptr = (node as *mut u8).wrapping_add(leaf_offset) as *mut (K, V);
IterFrame::Node {
limb_map: limb_map,
leaf_map: leaf_map,
branch: 1,
limb_ptr: limb_ptr,
leaf_ptr: leaf_ptr,
}
}
#[inline]
unsafe fn from_knot(knot: *mut Knot<'a, K, V>) -> IterFrame<'a, K, V> {
let head_offset = Layout::for_type::<Knot<'a, K, V>>().padded_to_type::<(K, V)>().size();
let head_ptr = (knot as *mut u8).wrapping_add(head_offset) as *mut (K, V);
let foot_ptr = head_ptr.wrapping_add((*knot).len);
IterFrame::Knot {
head_ptr: head_ptr,
foot_ptr: foot_ptr,
}
}
}
impl<'a, K, V> Clone for IterFrame<'a, K, V> {
fn clone(&self) -> IterFrame<'a, K, V> {
match *self {
IterFrame::Void => IterFrame::Void,
IterFrame::Node { limb_map, leaf_map, branch, limb_ptr, leaf_ptr } => IterFrame::Node {
limb_map: limb_map,
leaf_map: leaf_map,
branch: branch,
limb_ptr: limb_ptr,
leaf_ptr: leaf_ptr,
},
IterFrame::Knot { head_ptr, foot_ptr } => IterFrame::Knot {
head_ptr: head_ptr,
foot_ptr: foot_ptr,
}
}
}
}
impl<'a, K, V> HashTrieIter<'a, K, V> {
#[inline]
pub(crate) fn empty() -> HashTrieIter<'a, K, V> {
HashTrieIter {
count: 0,
depth: -1,
stack: [IterFrame::Void, IterFrame::Void, IterFrame::Void, IterFrame::Void,
IterFrame::Void, IterFrame::Void, IterFrame::Void, IterFrame::Void,
IterFrame::Void, IterFrame::Void, IterFrame::Void, IterFrame::Void,
IterFrame::Void, IterFrame::Void],
}
}
#[inline]
fn new(count: usize, base_frame: IterFrame<'a, K, V>) -> HashTrieIter<'a, K, V> {
HashTrieIter {
count: count,
depth: 0,
stack: [base_frame, IterFrame::Void, IterFrame::Void, IterFrame::Void,
IterFrame::Void, IterFrame::Void, IterFrame::Void, IterFrame::Void,
IterFrame::Void, IterFrame::Void, IterFrame::Void, IterFrame::Void,
IterFrame::Void, IterFrame::Void],
}
}
#[inline]
pub(crate) fn len(&self) -> usize {
return self.count;
}
pub(crate) unsafe fn next(&mut self) -> Option<NonNull<(K, V)>> {
let mut stack_ptr = self.stack.as_mut_ptr().wrapping_add(self.depth as usize);
while self.depth >= 0 {
match *stack_ptr {
IterFrame::Void => return None,
IterFrame::Node { limb_map, leaf_map, ref mut branch, ref mut limb_ptr, ref mut leaf_ptr } => {
if *branch != 0 && (limb_map | leaf_map) & !(*branch - 1) != 0 {
let branch_type = BranchType::for_branch(limb_map, leaf_map, *branch);
*branch = *branch << 1;
match branch_type {
BranchType::Void => (),
BranchType::Leaf => {
let leaf = NonNull::new_unchecked(*leaf_ptr);
*leaf_ptr = (*leaf_ptr).wrapping_add(1);
return Some(leaf);
},
BranchType::Node => {
let node_ptr = **limb_ptr as *mut Node<'a, K, V>;
*limb_ptr = (*limb_ptr).wrapping_add(1);
self.depth = self.depth.wrapping_add(1);
stack_ptr = stack_ptr.wrapping_add(1);
*stack_ptr = IterFrame::from_node(node_ptr);
},
BranchType::Knot => {
let knot_ptr = **limb_ptr as *mut Knot<'a, K, V>;
*limb_ptr = (*limb_ptr).wrapping_add(1);
self.depth = self.depth.wrapping_add(1);
stack_ptr = stack_ptr.wrapping_add(1);
*stack_ptr = IterFrame::from_knot(knot_ptr);
},
};
} else {
self.depth = self.depth.wrapping_sub(1);
*stack_ptr = IterFrame::Void;
stack_ptr = stack_ptr.wrapping_sub(1);
}
},
IterFrame::Knot { ref mut head_ptr, foot_ptr } => {
if *head_ptr < foot_ptr {
let leaf = NonNull::new_unchecked(*head_ptr);
*head_ptr = (*head_ptr).wrapping_add(1);
return Some(leaf);
} else {
self.depth = self.depth.wrapping_sub(1);
*stack_ptr = IterFrame::Void;
stack_ptr = stack_ptr.wrapping_sub(1);
}
}
};
}
None
}
pub(crate) unsafe fn next_back(&mut self) -> Option<NonNull<(K, V)>> {
let mut stack_ptr = self.stack.as_mut_ptr().wrapping_add(self.depth as usize);
while self.depth >= 0 {
match *stack_ptr {
IterFrame::Void => return None,
IterFrame::Node { limb_map, leaf_map, ref mut branch, ref mut limb_ptr, ref mut leaf_ptr } => {
if *branch != 1 && (limb_map | leaf_map) & (*branch - 1) != 0 {
*branch = *branch >> 1;
let branch_type = BranchType::for_branch(limb_map, leaf_map, *branch);
match branch_type {
BranchType::Void => (),
BranchType::Leaf => {
*leaf_ptr = (*leaf_ptr).wrapping_sub(1);
let leaf = NonNull::new_unchecked(*leaf_ptr);
return Some(leaf);
},
BranchType::Node => {
*limb_ptr = (*limb_ptr).wrapping_sub(1);
let node_ptr = **limb_ptr as *mut Node<'a, K, V>;
self.depth = self.depth.wrapping_add(1);
stack_ptr = stack_ptr.wrapping_add(1);
*stack_ptr = IterFrame::from_node(node_ptr);
},
BranchType::Knot => {
*limb_ptr = (*limb_ptr).wrapping_sub(1);
let knot_ptr = **limb_ptr as *mut Knot<'a, K, V>;
self.depth = self.depth.wrapping_add(1);
stack_ptr = stack_ptr.wrapping_add(1);
*stack_ptr = IterFrame::from_knot(knot_ptr);
},
};
} else {
self.depth = self.depth.wrapping_sub(1);
*stack_ptr = IterFrame::Void;
stack_ptr = stack_ptr.wrapping_sub(1);
}
},
IterFrame::Knot { head_ptr, ref mut foot_ptr } => {
if *foot_ptr != head_ptr {
*foot_ptr = (*foot_ptr).wrapping_sub(1);
let leaf = NonNull::new_unchecked(*foot_ptr);
return Some(leaf);
} else {
self.depth = self.depth.wrapping_sub(1);
*stack_ptr = IterFrame::Void;
stack_ptr = stack_ptr.wrapping_sub(1);
}
}
};
}
None
}
}
unsafe impl<'a, K: Send, V: Send> Send for HashTrieIter<'a, K, V> {
}
unsafe impl<'a, K: Sync, V: Sync> Sync for HashTrieIter<'a, K, V> {
}
impl<'a, K: 'a, V: 'a> Clone for HashTrieIter<'a, K, V> {
fn clone(&self) -> HashTrieIter<'a, K, V> {
HashTrieIter {
count: self.count,
depth: self.depth,
stack: self.stack.clone(),
}
}
}