Skip to content

Commit

Permalink
Merge pull request #15 from ethanhs/generichash
Browse files Browse the repository at this point in the history
Allow passing the hasher.
  • Loading branch information
xacrimon authored Jan 15, 2020
2 parents 7606f79 + bc904a4 commit d6f1025
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 124 deletions.
61 changes: 38 additions & 23 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ use crate::util::SharedValue;
use crate::HashMap;
use parking_lot::{RwLockReadGuard, RwLockWriteGuard};
use std::collections::hash_map;
use std::hash::Hash;
use std::hash::{BuildHasher, Hash};
use std::marker::PhantomData;
use std::sync::Arc;

type GuardIter<'a, K, V> = (
Arc<RwLockReadGuard<'a, HashMap<K, V>>>,
type GuardIter<'a, K, V, S> = (
Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>,
hash_map::Iter<'a, K, SharedValue<V>>,
);
type GuardIterMut<'a, K, V> = (
Arc<RwLockWriteGuard<'a, HashMap<K, V>>>,
type GuardIterMut<'a, K, V, S> = (
Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>,
hash_map::IterMut<'a, K, SharedValue<V>>,
);

Expand All @@ -28,30 +29,37 @@ type GuardIterMut<'a, K, V> = (
/// map.insert("hello", "world");
/// assert_eq!(map.iter().count(), 1);
/// ```
pub struct Iter<'a, K: Eq + Hash, V, M: Map<'a, K, V>> {
pub struct Iter<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> {
map: &'a M,
shard_i: usize,
current: Option<GuardIter<'a, K, V>>,
current: Option<GuardIter<'a, K, V, S>>,
phantom: PhantomData<S>,
}

unsafe impl<'a, K: Eq + Hash + Send, V: Send, M: Map<'a, K, V>> Send for Iter<'a, K, V, M> {}
unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, M: Map<'a, K, V>> Sync
for Iter<'a, K, V, M>
unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: 'a + BuildHasher, M: Map<'a, K, V, S>> Send
for Iter<'a, K, V, S, M>
{
}
unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: 'a + BuildHasher, M: Map<'a, K, V, S>>
Sync for Iter<'a, K, V, S, M>
{
}

impl<'a, K: Eq + Hash, V, M: Map<'a, K, V>> Iter<'a, K, V, M> {
impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> Iter<'a, K, V, S, M> {
pub(crate) fn new(map: &'a M) -> Self {
Self {
map,
shard_i: 0,
current: None,
phantom: PhantomData,
}
}
}

impl<'a, K: Eq + Hash, V, M: Map<'a, K, V>> Iterator for Iter<'a, K, V, M> {
type Item = RefMulti<'a, K, V>;
impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> Iterator
for Iter<'a, K, V, S, M>
{
type Item = RefMulti<'a, K, V, S>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -67,7 +75,7 @@ impl<'a, K: Eq + Hash, V, M: Map<'a, K, V>> Iterator for Iter<'a, K, V, M> {
}

let guard = unsafe { self.map._yield_read_shard(self.shard_i) };
let sref: &HashMap<K, V> = unsafe { util::change_lifetime_const(&*guard) };
let sref: &HashMap<K, V, S> = unsafe { util::change_lifetime_const(&*guard) };
let iter = sref.iter();
self.current = Some((Arc::new(guard), iter));
self.shard_i += 1;
Expand All @@ -88,30 +96,37 @@ impl<'a, K: Eq + Hash, V, M: Map<'a, K, V>> Iterator for Iter<'a, K, V, M> {
/// map.iter_mut().for_each(|mut r| *r += 1);
/// assert_eq!(*map.get("Johnny").unwrap(), 22);
/// ```
pub struct IterMut<'a, K: Eq + Hash, V, M: Map<'a, K, V>> {
pub struct IterMut<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> {
map: &'a M,
shard_i: usize,
current: Option<GuardIterMut<'a, K, V>>,
current: Option<GuardIterMut<'a, K, V, S>>,
phantom: PhantomData<S>,
}

unsafe impl<'a, K: Eq + Hash + Send, V: Send, M: Map<'a, K, V>> Send for IterMut<'a, K, V, M> {}
unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, M: Map<'a, K, V>> Sync
for IterMut<'a, K, V, M>
unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: 'a + BuildHasher, M: Map<'a, K, V, S>> Send
for IterMut<'a, K, V, S, M>
{
}
unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: 'a + BuildHasher, M: Map<'a, K, V, S>>
Sync for IterMut<'a, K, V, S, M>
{
}

impl<'a, K: Eq + Hash, V, M: Map<'a, K, V>> IterMut<'a, K, V, M> {
impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> IterMut<'a, K, V, S, M> {
pub(crate) fn new(map: &'a M) -> Self {
Self {
map,
shard_i: 0,
current: None,
phantom: PhantomData,
}
}
}

impl<'a, K: Eq + Hash, V, M: Map<'a, K, V>> Iterator for IterMut<'a, K, V, M> {
type Item = RefMutMulti<'a, K, V>;
impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> Iterator
for IterMut<'a, K, V, S, M>
{
type Item = RefMutMulti<'a, K, V, S>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -131,7 +146,7 @@ impl<'a, K: Eq + Hash, V, M: Map<'a, K, V>> Iterator for IterMut<'a, K, V, M> {
}

let mut guard = unsafe { self.map._yield_write_shard(self.shard_i) };
let sref: &mut HashMap<K, V> = unsafe { util::change_lifetime_mut(&mut *guard) };
let sref: &mut HashMap<K, V, S> = unsafe { util::change_lifetime_mut(&mut *guard) };
let iter = sref.iter_mut();
self.current = Some((Arc::new(guard), iter));
self.shard_i += 1;
Expand Down
Loading

0 comments on commit d6f1025

Please sign in to comment.