use std::{cmp,env,mem,ops,iter,marker,collections,hash,slice,ptr,borrow};
use hadean::{Sender,Receiver,Connection,Process,ChannelEndpoint,Channel,pid,spawn,ProcessTransfer};
use list::{Leaf,LeafIndex};
use std::hash::Hasher;
fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> u64 where T: hash::Hash, S: hash::BuildHasher {
let mut state = hash_state.build_hasher();
t.hash(&mut state);
state.finish()
}
const PARTITIONS: usize = 10000;
pub struct HashMap<K, V, S = collections::hash_map::RandomState> where K: ProcessTransfer, V: ProcessTransfer {
hash_builder: S,
list: Box<Leaf<u8>>,
start: LeafIndex,
end: LeafIndex,
indices: Box<[LeafIndex; PARTITIONS-1]>,
phantom1: marker::PhantomData<K>,
phantom2: marker::PhantomData<V>
}
impl<K: hash::Hash + cmp::Eq, V> HashMap<K, V, collections::hash_map::RandomState> where K: ProcessTransfer, V: ProcessTransfer {
pub fn new() -> HashMap<K, V, collections::hash_map::RandomState> {
let mut leaf: Box<Leaf<u8>> = box unsafe{mem::uninitialized()};
let (start, mut end) = Leaf::init(&mut leaf);
let mut indices: Box<[LeafIndex; PARTITIONS-1]> = box unsafe{mem::uninitialized()};
for i in 0..indices.len() {
unsafe{ptr::write(&mut indices[i], end.clone_left())};
}
HashMap{hash_builder:Default::default(),list:leaf,start:start,end:end,indices:indices,phantom1:marker::PhantomData,phantom2:marker::PhantomData}
}
}
impl<K, V, S> HashMap<K, V, S> where K: hash::Hash + cmp::Eq + ProcessTransfer, S: hash::BuildHasher, V: ProcessTransfer {
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
let partition = make_hash(&self.hash_builder, &k) as usize % PARTITIONS;
let mut iter = if partition == 0 { self.start.clone_right() } else { self.indices[partition-1].clone_right() };
let end = if partition == PARTITIONS-1 { self.end.clone_left() } else { self.indices[partition].clone_left() };
while iter != end {
let start = iter.clone_left();
let mut key: K = unsafe{mem::uninitialized()};
key.processsendable_read(&mut |buf,len| {
let start2 = iter.clone_left();
for _ in 0..len {
self.list.increment(&mut iter);
}
let key = self.list.read(&start2, &iter);
unsafe{ptr::copy_nonoverlapping(key.as_ptr(), buf, len)};
});
let mut start2 = iter.clone_left();
let mut val: V = unsafe{mem::uninitialized()};
val.processsendable_read(&mut |buf,len| {
let start2 = iter.clone_left();
for _ in 0..len {
self.list.increment(&mut iter);
}
let val = self.list.read(&start2, &iter);
unsafe{ptr::copy_nonoverlapping(val.as_ptr(), buf, len)};
});
if key == k {
self.list.replace(&mut start2, &mut iter, iter::empty());
v.processsendable_write(&mut |buf,len| {
let mut start = iter.clone_left();
self.list.replace(&mut start, &mut iter, unsafe{slice::from_raw_parts(buf, len)}.iter().map(|&x|x));
});
return Some(val);
}
}
k.processsendable_write(&mut |buf,len| {
let mut start = iter.clone_left();
self.list.replace(&mut start, &mut iter, unsafe{slice::from_raw_parts(buf, len)}.iter().map(|&x|x));
});
v.processsendable_write(&mut |buf,len| {
let mut start = iter.clone_left();
self.list.replace(&mut start, &mut iter, unsafe{slice::from_raw_parts(buf, len)}.iter().map(|&x|x));
});
None
}
pub fn get<Q: ?Sized>(&mut self, k: &Q) -> Option<V> where K: borrow::Borrow<Q>, Q: hash::Hash + cmp::Eq {
let partition = make_hash(&self.hash_builder, &k) as usize % PARTITIONS;
let mut iter = if partition == 0 { self.start.clone_right() } else { self.indices[partition-1].clone_right() };
let end = if partition == PARTITIONS-1 { self.end.clone_left() } else { self.indices[partition].clone_left() };
while iter != end {
let mut key: K = unsafe{mem::uninitialized()};
key.processsendable_read(&mut |buf,len| {
let start2 = iter.clone_left();
for _ in 0..len {
self.list.increment(&mut iter);
}
let key = self.list.read(&start2, &iter);
unsafe{ptr::copy_nonoverlapping(key.as_ptr(), buf, len)};
});
let mut val: V = unsafe{mem::uninitialized()};
val.processsendable_read(&mut |buf,len| {
let start2 = iter.clone_left();
for _ in 0..len {
self.list.increment(&mut iter);
}
let val = self.list.read(&start2, &iter);
unsafe{ptr::copy_nonoverlapping(val.as_ptr(), buf, len)};
});
if key.borrow() == k {
return Some(val); }
}
None
}
}
pub struct HashMapIter<'a,K,V> where K: 'a + hash::Hash + cmp::Eq + ProcessTransfer, V: 'a + ProcessTransfer {
list: &'a mut Box<Leaf<u8>>,
iter: LeafIndex,
phantom1: marker::PhantomData<K>,
phantom2: marker::PhantomData<V>
}
impl<'a,K,V> iter::Iterator for HashMapIter<'a,K,V> where K: hash::Hash + cmp::Eq + ProcessTransfer, V: ProcessTransfer {
type Item = (K,V); fn next(&mut self) -> Option<Self::Item> {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hashmap() {
let mut hash_map: HashMap<String,String> = HashMap::new();
hash_map.insert(String::from("abc"),String::from("123"));
hash_map.insert(String::from("def"),String::from("456"));
for (key,value) in hash_map.iter() {
println!("{}:{}", key, value);
}
}
}