use std::sync::Arc;
use bits::{bitpos, index, Bitmap, HASH_BITS, HASH_SIZE};
use shared::Shared;
pub trait HashValue: Clone {
type Key: Eq;
fn extract_key(&self) -> &Self::Key;
fn ptr_eq(&self, other: &Self) -> bool;
}
#[derive(PartialEq, Eq, Clone)]
pub struct Node<A> {
datamap: Bitmap,
nodemap: Bitmap,
data: Vec<Entry<A>>,
nodes: Vec<Arc<Node<A>>>,
}
#[derive(PartialEq, Eq, Clone)]
pub struct CollisionNode<A> {
hash: Bitmap,
data: Vec<A>,
}
#[derive(PartialEq, Eq, Clone)]
pub enum Entry<A> {
Value(A, Bitmap),
Collision(Arc<CollisionNode<A>>),
}
enum SizePredicate {
Empty,
One,
Many,
}
impl<A: HashValue> Node<A> {
#[inline]
pub fn iter(root: Arc<Self>, size: usize) -> Iter<A> {
Iter::new(root, size)
}
#[inline]
pub fn new() -> Self {
Node {
datamap: 0,
nodemap: 0,
data: Vec::new(),
nodes: Vec::new(),
}
}
#[inline]
pub fn singleton(bitpos: Bitmap, value: Entry<A>) -> Self {
Node {
datamap: bitpos,
data: vec![value],
nodemap: 0,
nodes: Vec::new(),
}
}
#[inline]
pub fn pair(bitmap: Bitmap, value1: Entry<A>, value2: Entry<A>) -> Self {
Node {
datamap: bitmap,
data: vec![value1, value2],
nodemap: 0,
nodes: Vec::new(),
}
}
#[inline]
pub fn single_child(bitpos: Bitmap, node: Self) -> Self {
Node {
datamap: 0,
data: Vec::new(),
nodemap: bitpos,
nodes: vec![Arc::new(node)],
}
}
#[inline]
fn data_arity(&self) -> usize {
self.data.len()
}
#[inline]
fn node_arity(&self) -> usize {
self.nodes.len()
}
fn size_predicate(&self) -> SizePredicate {
if self.node_arity() == 0 {
match self.data_arity() {
0 => SizePredicate::Empty,
1 => SizePredicate::One,
_ => SizePredicate::Many,
}
} else {
SizePredicate::Many
}
}
#[inline]
fn data_index(&self, bitpos: Bitmap) -> usize {
index(self.datamap, bitpos)
}
#[inline]
fn node_index(&self, bitpos: Bitmap) -> usize {
index(self.nodemap, bitpos)
}
fn update_node<RN>(&self, bitpos: Bitmap, node: RN) -> Self
where
RN: Shared<Node<A>>,
{
let index = self.node_index(bitpos);
let mut new_nodes = Vec::with_capacity(self.nodes.len());
new_nodes.extend(self.nodes.iter().cloned().take(index));
new_nodes.push(node.shared());
new_nodes.extend(self.nodes.iter().cloned().skip(index + 1));
Node {
nodemap: self.nodemap,
nodes: new_nodes,
datamap: self.datamap,
data: self.data.clone(),
}
}
fn update_value(&self, bitpos: Bitmap, value: Entry<A>) -> Self {
let index = self.data_index(bitpos);
let mut new_data = Vec::with_capacity(self.data.len());
new_data.extend(self.data.iter().cloned().take(index));
new_data.push(value);
new_data.extend(self.data.iter().cloned().skip(index + 1));
Node {
nodemap: self.nodemap,
nodes: self.nodes.clone(),
datamap: self.datamap,
data: new_data,
}
}
fn update_value_mut(&mut self, bitpos: Bitmap, value: Entry<A>) {
let index = self.data_index(bitpos);
self.data[index] = value;
}
fn insert_value(&self, bitpos: Bitmap, value: Entry<A>) -> Self {
let index = self.data_index(bitpos);
let mut new_data = Vec::with_capacity(self.data.len() + 1);
new_data.extend(self.data.iter().cloned().take(index));
new_data.push(value);
new_data.extend(self.data.iter().cloned().skip(index));
Node {
nodemap: self.nodemap,
nodes: self.nodes.clone(),
datamap: self.datamap | bitpos,
data: new_data,
}
}
fn insert_value_mut(&mut self, bitpos: Bitmap, value: Entry<A>) {
let index = self.data_index(bitpos);
self.data.insert(index, value);
self.datamap |= bitpos;
}
fn remove_value(&self, bitpos: Bitmap) -> Self {
let index = self.data_index(bitpos);
let mut new_data = Vec::with_capacity(self.data.len() - 1);
new_data.extend(self.data.iter().cloned().take(index));
new_data.extend(self.data.iter().cloned().skip(index + 1));
Node {
nodemap: self.nodemap,
nodes: self.nodes.clone(),
datamap: self.datamap ^ bitpos,
data: new_data,
}
}
fn remove_value_mut(&mut self, bitpos: Bitmap) {
let index = self.data_index(bitpos);
self.data.remove(index);
self.datamap ^= bitpos;
}
fn value_to_node<RN>(&self, bitpos: Bitmap, node: RN) -> Self
where
RN: Shared<Node<A>>,
{
let old_index = self.data_index(bitpos);
let new_index = self.node_index(bitpos);
let mut new_data = Vec::with_capacity(self.data.len() - 1);
new_data.extend(self.data.iter().cloned().take(old_index));
new_data.extend(self.data.iter().cloned().skip(old_index + 1));
let mut new_nodes = Vec::with_capacity(self.nodes.len() + 1);
new_nodes.extend(self.nodes.iter().cloned().take(new_index));
new_nodes.push(node.shared());
new_nodes.extend(self.nodes.iter().cloned().skip(new_index));
Node {
nodemap: self.nodemap | bitpos,
nodes: new_nodes,
datamap: self.datamap ^ bitpos,
data: new_data,
}
}
fn value_to_node_mut<RN>(&mut self, bitpos: Bitmap, node: RN)
where
RN: Shared<Node<A>>,
{
let old_index = self.data_index(bitpos);
let new_index = self.node_index(bitpos);
self.data.remove(old_index);
self.datamap ^= bitpos;
self.nodes.insert(new_index, node.shared());
self.nodemap |= bitpos;
}
fn node_to_value(&self, bitpos: Bitmap, node: &Node<A>) -> Self {
let old_index = self.node_index(bitpos);
let new_index = self.data_index(bitpos);
let mut new_data = Vec::with_capacity(self.data.len() + 1);
new_data.extend(self.data.iter().cloned().take(new_index));
new_data.push(node.data[0].clone());
new_data.extend(self.data.iter().cloned().skip(new_index));
let mut new_nodes = Vec::with_capacity(self.nodes.len() - 1);
new_nodes.extend(self.nodes.iter().cloned().take(old_index));
new_nodes.extend(self.nodes.iter().cloned().skip(old_index + 1));
Node {
nodemap: self.nodemap ^ bitpos,
nodes: new_nodes,
datamap: self.datamap | bitpos,
data: new_data,
}
}
fn node_to_value_mut(&mut self, bitpos: Bitmap, value: Entry<A>) {
let old_index = self.node_index(bitpos);
let new_index = self.data_index(bitpos);
self.nodes.remove(old_index);
self.nodemap ^= bitpos;
self.data.insert(new_index, value);
self.datamap |= bitpos;
}
fn merge_values(
value1: Entry<A>,
value2: Entry<A>,
hash1: Bitmap,
hash2: Bitmap,
shift: usize,
) -> Self {
let bitpos1 = bitpos(hash1, shift);
let bitpos2 = bitpos(hash2, shift);
if bitpos1 != bitpos2 {
let datamap = bitpos1 | bitpos2;
if bitpos1 < bitpos2 {
Node::pair(datamap, value1, value2)
} else {
Node::pair(datamap, value2, value1)
}
} else {
if shift + HASH_BITS >= HASH_SIZE {
return Node::singleton(
bitpos(hash1, shift),
Entry::Collision(Arc::new(CollisionNode::new(hash1, value1, value2))),
);
}
let node = Node::merge_values(value1, value2, hash1, hash2, shift + HASH_BITS);
Node::single_child(bitpos1, node)
}
}
pub fn get(&self, hash: Bitmap, shift: usize, key: &A::Key) -> Option<&A> {
let bitpos = bitpos(hash, shift);
if self.datamap & bitpos != 0 {
match self.data[self.data_index(bitpos)] {
Entry::Value(ref value, _) => if key == value.extract_key() {
Some(value)
} else {
None
},
Entry::Collision(ref coll) => coll.get(key),
}
} else if self.nodemap & bitpos != 0 {
self.nodes[self.node_index(bitpos)].get(hash, shift + HASH_BITS, key)
} else {
None
}
}
pub fn get_mut(&mut self, hash: Bitmap, shift: usize, key: &A::Key) -> Option<&mut A> {
let bitpos = bitpos(hash, shift);
let data_index = self.data_index(bitpos);
let node_index = self.node_index(bitpos);
if self.datamap & bitpos != 0 {
match self.data[data_index] {
Entry::Value(ref mut value, _) => if key == value.extract_key() {
Some(value)
} else {
None
},
Entry::Collision(ref mut coll_ref) => {
let coll = Arc::make_mut(coll_ref);
coll.get_mut(key)
}
}
} else if self.nodemap & bitpos != 0 {
let child = Arc::make_mut(&mut self.nodes[node_index]);
child.get_mut(hash, shift + HASH_BITS, key)
} else {
None
}
}
pub fn insert(&self, hash: Bitmap, shift: usize, value: A) -> (bool, Self) {
let bitpos = bitpos(hash, shift);
if self.datamap & bitpos != 0 {
let index = self.data_index(bitpos);
match self.data[index] {
Entry::Value(ref current, hash2) => {
if value.extract_key() == current.extract_key() {
(false, self.update_value(bitpos, Entry::Value(value, hash)))
} else {
let value2 = current.clone();
if shift + HASH_BITS >= HASH_SIZE {
let coll = CollisionNode::new(
hash,
Entry::Value(value, hash),
Entry::Value(value2, hash),
);
(
true,
self.update_value(bitpos, Entry::Collision(Arc::new(coll))),
)
} else {
let node = Node::merge_values(
Entry::Value(value, hash),
Entry::Value(value2, hash2),
hash,
hash2,
shift + HASH_BITS,
);
(true, self.value_to_node(bitpos, Arc::new(node)))
}
}
}
Entry::Collision(ref coll) => {
let (added, new_coll) = coll.insert(value);
(
added,
self.update_value(bitpos, Entry::Collision(Arc::new(new_coll))),
)
}
}
} else if self.nodemap & bitpos != 0 {
let index = self.node_index(bitpos);
let child = &self.nodes[index];
let (added, new_child) = child.insert(hash, shift + HASH_BITS, value);
(added, self.update_node(bitpos, Arc::new(new_child)))
} else {
(true, self.insert_value(bitpos, Entry::Value(value, hash)))
}
}
pub fn insert_mut(&mut self, hash: Bitmap, shift: usize, value: A) -> bool {
let bitpos = bitpos(hash, shift);
if self.datamap & bitpos != 0 {
let index = self.data_index(bitpos);
let mut insert = false;
let mut merge = None;
match self.data[index] {
Entry::Value(ref current, hash2) => {
if value.extract_key() == current.extract_key() {
insert = true;
} else {
merge = Some((current.clone(), hash2));
}
}
Entry::Collision(ref mut collision) => {
let coll = Arc::make_mut(collision);
return coll.insert_mut(value);
}
}
if insert {
self.update_value_mut(bitpos, Entry::Value(value, hash));
return false;
}
if let Some((value2, hash2)) = merge {
if shift + HASH_BITS >= HASH_SIZE {
let coll = CollisionNode::new(
hash,
Entry::Value(value, hash),
Entry::Value(value2, hash2),
);
self.update_value_mut(bitpos, Entry::Collision(Arc::new(coll)));
return true;
} else {
let node = Node::merge_values(
Entry::Value(value, hash),
Entry::Value(value2, hash2),
hash,
hash2,
shift + HASH_BITS,
);
self.value_to_node_mut(bitpos, Arc::new(node));
return true;
}
}
unreachable!()
} else if self.nodemap & bitpos != 0 {
let index = self.node_index(bitpos);
let child = Arc::make_mut(&mut self.nodes[index]);
child.insert_mut(hash, shift + HASH_BITS, value)
} else {
self.insert_value_mut(bitpos, Entry::Value(value, hash));
true
}
}
pub fn remove(&self, hash: Bitmap, shift: usize, key: &A::Key) -> Option<(A, Self)> {
let pos = bitpos(hash, shift);
if self.datamap & pos != 0 {
let index = self.data_index(pos);
match self.data[index] {
Entry::Value(ref value, _) => if key == value.extract_key() {
Some((value.clone(), self.remove_value(pos)))
} else {
None
},
Entry::Collision(ref coll) => match coll.remove(key) {
None => None,
Some((value, next_coll)) => Some((
value,
self.update_value(pos, Entry::Collision(Arc::new(next_coll))),
)),
},
}
} else if self.nodemap & pos != 0 {
let remove_result =
self.nodes[self.node_index(pos)].remove(hash, shift + HASH_BITS, key);
match remove_result {
None => None,
Some((value, next_node)) => {
match next_node.size_predicate() {
SizePredicate::Empty => panic!(
"HashMap::remove: encountered unexpectedly empty subnode after removal"
),
SizePredicate::One => {
Some((value, self.node_to_value(pos, &next_node)))
}
SizePredicate::Many => Some((value, self.update_node(pos, next_node))),
}
}
}
} else {
None
}
}
pub fn remove_mut(&mut self, hash: Bitmap, shift: usize, key: &A::Key) -> Option<A> {
let pos = bitpos(hash, shift);
if self.datamap & pos != 0 {
let index = self.data_index(pos);
let removed;
match self.data[index] {
Entry::Value(ref value, _) => if key == value.extract_key() {
removed = value.clone();
} else {
return None;
},
Entry::Collision(ref mut collisions) => {
let mut coll = Arc::make_mut(collisions);
return coll.remove_mut(key);
}
}
self.remove_value_mut(pos);
Some(removed)
} else if self.nodemap & pos != 0 {
let index = self.node_index(pos);
let removed;
let remaining;
{
let child = Arc::make_mut(&mut self.nodes[index]);
match child.remove_mut(hash, shift + HASH_BITS, key) {
None => return None,
Some(value) => match child.size_predicate() {
SizePredicate::Empty => panic!(
"HashMap::remove: encountered unexpectedly empty subnode after removal"
),
SizePredicate::One => {
removed = value;
remaining = child.data[0].clone();
}
SizePredicate::Many => return Some(value),
},
}
}
self.node_to_value_mut(pos, remaining);
Some(removed)
} else {
None
}
}
}
impl<A: HashValue> CollisionNode<A> {
fn new(hash: Bitmap, value1: Entry<A>, value2: Entry<A>) -> Self {
let mut data = Vec::new();
match value1 {
Entry::Value(value, _) => data.push(value),
Entry::Collision(ref node) => data.extend(node.data.iter().cloned()),
}
match value2 {
Entry::Value(value, _) => data.push(value),
Entry::Collision(ref node) => data.extend(node.data.iter().cloned()),
}
CollisionNode { hash, data }
}
fn get(&self, key: &A::Key) -> Option<&A> {
for entry in &self.data {
if key == entry.extract_key() {
return Some(entry);
}
}
None
}
fn get_mut(&mut self, key: &A::Key) -> Option<&mut A> {
for entry in &mut self.data {
if key == entry.extract_key() {
return Some(entry);
}
}
None
}
fn insert(&self, value: A) -> (bool, Self) {
let mut data = Vec::with_capacity(self.data.len() + 1);
let mut add = true;
for item in &self.data {
if value.extract_key() == item.extract_key() {
data.push(value.clone());
add = false;
} else {
data.push(item.clone());
}
}
if add {
data.push(value);
}
(
add,
CollisionNode {
hash: self.hash,
data,
},
)
}
fn insert_mut(&mut self, value: A) -> bool {
for item in &mut self.data {
if value.extract_key() == item.extract_key() {
*item = value;
return false;
}
}
self.data.push(value);
true
}
fn remove(&self, key: &A::Key) -> Option<(A, Self)> {
for (index, item) in self.data.iter().enumerate() {
if key == item.extract_key() {
let mut data = self.data.clone();
let value = data.remove(index);
return Some((
value,
CollisionNode {
hash: self.hash,
data,
},
));
}
}
None
}
fn remove_mut(&mut self, key: &A::Key) -> Option<A> {
let mut loc = None;
for (index, item) in self.data.iter().enumerate() {
if key == item.extract_key() {
loc = Some(index);
}
}
if let Some(index) = loc {
Some(self.data.remove(index))
} else {
None
}
}
}
pub struct Iter<A> {
count: usize,
stack: Vec<(Arc<Node<A>>, usize)>,
node: Arc<Node<A>>,
index: usize,
nodes: bool,
collision: Option<Arc<CollisionNode<A>>>,
coll_index: usize,
}
impl<A> Iter<A> {
fn new(root: Arc<Node<A>>, size: usize) -> Self {
Iter {
count: size,
stack: Vec::with_capacity((HASH_SIZE / HASH_BITS) + 1),
node: root,
index: 0,
nodes: false,
collision: None,
coll_index: 0,
}
}
}
impl<A: Clone> Iterator for Iter<A> {
type Item = A;
fn next(&mut self) -> Option<Self::Item> {
if let Some(ref coll) = self.collision {
if coll.data.len() > self.coll_index {
let value = coll.data[self.coll_index].clone();
self.coll_index += 1;
self.count -= 1;
return Some(value);
}
}
self.collision = None;
if !self.nodes {
if self.node.data.len() > self.index {
match self.node.data[self.index] {
Entry::Value(ref value, _) => {
self.index += 1;
self.count -= 1;
return Some(value.clone());
}
Entry::Collision(ref coll) => {
self.index += 1;
self.collision = Some(coll.clone());
self.coll_index = 0;
}
}
return self.next();
}
self.index = 0;
self.nodes = true;
}
if self.node.nodes.len() > self.index {
self.stack.push((self.node.clone(), self.index + 1));
self.node = self.node.nodes[self.index].clone();
self.index = 0;
self.nodes = false;
return self.next();
}
match self.stack.pop() {
None => None,
Some((node, index)) => {
self.node = node;
self.index = index;
self.nodes = true;
self.next()
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.count, Some(self.count))
}
}
impl<A: Clone> ExactSizeIterator for Iter<A> {}