Skip to content

Commit

Permalink
Merge pull request #21 from michael-p/custom-hasher.
Browse files Browse the repository at this point in the history
Implement traits when SparseSecondaryMap uses custom hasher.
  • Loading branch information
orlp authored Aug 25, 2019
2 parents 5fa5404 + b9fa052 commit 9fad143
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ unstable = []
serde = { version = "1.0", optional = true, features = ["derive"] }

[dev-dependencies]
fxhash = "0.2.1"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
Expand Down
106 changes: 90 additions & 16 deletions src/sparse_secondary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,13 +606,21 @@ impl<K: Key, V, S: hash::BuildHasher> SparseSecondaryMap<K, V, S> {
}
}

impl<K: Key, V> Default for SparseSecondaryMap<K, V> {
impl<K, V, S> Default for SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher + Default,
{
fn default() -> Self {
Self::new()
Self::with_hasher(Default::default())
}
}

impl<K: Key, V> Index<K> for SparseSecondaryMap<K, V> {
impl<K, V, S> Index<K> for SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher,
{
type Output = V;

fn index(&self, key: K) -> &V {
Expand All @@ -623,7 +631,11 @@ impl<K: Key, V> Index<K> for SparseSecondaryMap<K, V> {
}
}

impl<K: Key, V> IndexMut<K> for SparseSecondaryMap<K, V> {
impl<K, V, S> IndexMut<K> for SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher,
{
fn index_mut(&mut self, key: K) -> &mut V {
match self.get_mut(key) {
Some(r) => r,
Expand All @@ -632,7 +644,12 @@ impl<K: Key, V> IndexMut<K> for SparseSecondaryMap<K, V> {
}
}

impl<K: Key, V: PartialEq> PartialEq for SparseSecondaryMap<K, V> {
impl<K, V, S> PartialEq for SparseSecondaryMap<K, V, S>
where
K: Key,
V: PartialEq,
S: hash::BuildHasher,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
Expand All @@ -646,17 +663,31 @@ impl<K: Key, V: PartialEq> PartialEq for SparseSecondaryMap<K, V> {
}
}

impl<K: Key, V: Eq> Eq for SparseSecondaryMap<K, V> {}
impl<K, V, S> Eq for SparseSecondaryMap<K, V, S>
where
K: Key,
V: Eq,
S: hash::BuildHasher,
{
}

impl<K: Key, V> FromIterator<(K, V)> for SparseSecondaryMap<K, V> {
impl<K, V, S> FromIterator<(K, V)> for SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher + Default,
{
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
let mut sec = Self::new();
let mut sec = Self::default();
sec.extend(iter);
sec
}
}

impl<K: Key, V> Extend<(K, V)> for SparseSecondaryMap<K, V> {
impl<K, V, S> Extend<(K, V)> for SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher,
{
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
let iter = iter.into_iter();
for (k, v) in iter {
Expand All @@ -665,7 +696,12 @@ impl<K: Key, V> Extend<(K, V)> for SparseSecondaryMap<K, V> {
}
}

impl<'a, K: Key, V: 'a + Copy> Extend<(K, &'a V)> for SparseSecondaryMap<K, V> {
impl<'a, K, V, S> Extend<(K, &'a V)> for SparseSecondaryMap<K, V, S>
where
K: Key,
V: 'a + Copy,
S: hash::BuildHasher,
{
fn extend<I: IntoIterator<Item = (K, &'a V)>>(&mut self, iter: I) {
let iter = iter.into_iter();
for (k, v) in iter {
Expand Down Expand Up @@ -823,7 +859,11 @@ impl<'a, K: Key, V> Iterator for ValuesMut<'a, K, V> {
}
}

impl<'a, K: Key, V> IntoIterator for &'a SparseSecondaryMap<K, V> {
impl<'a, K, V, S> IntoIterator for &'a SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher,
{
type Item = (K, &'a V);
type IntoIter = Iter<'a, K, V>;

Expand All @@ -832,7 +872,11 @@ impl<'a, K: Key, V> IntoIterator for &'a SparseSecondaryMap<K, V> {
}
}

impl<'a, K: Key, V> IntoIterator for &'a mut SparseSecondaryMap<K, V> {
impl<'a, K, V, S> IntoIterator for &'a mut SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher,
{
type Item = (K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;

Expand All @@ -841,7 +885,11 @@ impl<'a, K: Key, V> IntoIterator for &'a mut SparseSecondaryMap<K, V> {
}
}

impl<K: Key, V> IntoIterator for SparseSecondaryMap<K, V> {
impl<K, V, S> IntoIterator for SparseSecondaryMap<K, V, S>
where
K: Key,
S: hash::BuildHasher,
{
type Item = (K, V);
type IntoIter = IntoIter<K, V>;

Expand Down Expand Up @@ -876,7 +924,12 @@ mod serialize {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::SecondaryMap;

impl<K: Key, V: Serialize> Serialize for SparseSecondaryMap<K, V> {
impl<K, V, H> Serialize for SparseSecondaryMap<K, V, H>
where
K: Key,
V: Serialize,
H: hash::BuildHasher,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
Expand All @@ -890,13 +943,18 @@ mod serialize {
}
}

impl<'de, K: Key, V: Deserialize<'de>> Deserialize<'de> for SparseSecondaryMap<K, V> {
impl<'de, K, V, S> Deserialize<'de> for SparseSecondaryMap<K, V, S>
where
K: Key,
V: Deserialize<'de>,
S: hash::BuildHasher + Default,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let serde_sec: SecondaryMap<K, V> = Deserialize::deserialize(deserializer)?;
let mut sec = Self::new();
let mut sec = Self::default();

for (k, v) in serde_sec {
sec.insert(k, v);
Expand All @@ -915,6 +973,22 @@ mod tests {
#[cfg(feature = "serde")]
use serde_json;

#[test]
fn custom_hasher() {
type FastSparseSecondaryMap<K, V> = SparseSecondaryMap<K, V, fxhash::FxBuildHasher>;
let mut sm = SlotMap::new();
let mut sec = FastSparseSecondaryMap::default();
let key1 = sm.insert(42);
sec.insert(key1, 1234);
assert_eq!(sec[key1], 1234);
assert_eq!(sec.len(), 1);
let sec2 = sec
.iter()
.map(|(k, &v)| (k, v))
.collect::<FastSparseSecondaryMap<_, _>>();
assert_eq!(sec, sec2);
}

quickcheck! {
fn qc_secmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {
let mut hm = HashMap::new();
Expand Down

0 comments on commit 9fad143

Please sign in to comment.