Skip to content

Commit

Permalink
Implement Eq and Debug traits (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stupremee authored and jonhoo committed Jan 24, 2020
1 parent 592b909 commit d3706b2
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
39 changes: 38 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ use node::*;

use crossbeam::epoch::{Atomic, Guard, Owned, Shared};
use std::collections::hash_map::RandomState;
use std::fmt::{self, Debug, Formatter};
use std::hash::{BuildHasher, Hash};
use std::iter::FromIterator;
use std::sync::{
Expand Down Expand Up @@ -257,7 +258,6 @@ pub mod epoch {
/// A concurrent hash table.
///
/// See the [crate-level documentation](index.html) for details.
#[derive(Debug)]
pub struct FlurryHashMap<K, V, S = RandomState> {
/// The array of bins. Lazily initialized upon first insertion.
/// Size is always a power of two. Accessed directly by iterators.
Expand Down Expand Up @@ -1253,6 +1253,43 @@ where
}
}

impl<K, V, S> PartialEq for FlurryHashMap<K, V, S>
where
K: Sync + Send + Clone + Eq + Hash,
V: Sync + Send + PartialEq,
S: BuildHasher,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}

let guard = epoch::pin();
self.iter(&guard)
.all(|(key, value)| other.get(key, &guard).map_or(false, |v| *value == *v))
}
}

impl<K, V, S> Eq for FlurryHashMap<K, V, S>
where
K: Sync + Send + Clone + Eq + Hash,
V: Sync + Send + Eq,
S: BuildHasher,
{
}

impl<K, V, S> fmt::Debug for FlurryHashMap<K, V, S>
where
K: Sync + Send + Clone + Debug + Eq + Hash,
V: Sync + Send + Debug,
S: BuildHasher,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let guard = epoch::pin();
f.debug_map().entries(self.iter(&guard)).finish()
}
}

impl<K, V, S> Drop for FlurryHashMap<K, V, S> {
fn drop(&mut self) {
// safety: we have &mut self _and_ all references we have returned are bound to the
Expand Down
51 changes: 51 additions & 0 deletions tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,57 @@ fn current_kv_dropped() {
assert_eq!(Arc::strong_count(&dropped2), 1);
}

#[test]
fn empty_maps_equal() {
let map1 = FlurryHashMap::<usize, usize>::new();
let map2 = FlurryHashMap::<usize, usize>::new();
assert_eq!(map1, map2);
assert_eq!(map2, map1);
}

#[test]
fn different_size_maps_not_equal() {
let map1 = FlurryHashMap::<usize, usize>::new();
let map2 = FlurryHashMap::<usize, usize>::new();
{
let guard = epoch::pin();
map1.insert(1, 0, &guard);
map1.insert(2, 0, &guard);
map2.insert(1, 0, &guard);
}

assert_ne!(map1, map2);
assert_ne!(map2, map1);
}

#[test]
fn same_values_equal() {
let map1 = FlurryHashMap::<usize, usize>::new();
let map2 = FlurryHashMap::<usize, usize>::new();
{
let guard = epoch::pin();
map1.insert(1, 0, &guard);
map2.insert(1, 0, &guard);
}

assert_eq!(map1, map2);
assert_eq!(map2, map1);
}

#[test]
fn different_values_not_equal() {
let map1 = FlurryHashMap::<usize, usize>::new();
let map2 = FlurryHashMap::<usize, usize>::new();
{
let guard = epoch::pin();
map1.insert(1, 0, &guard);
map2.insert(1, 1, &guard);
}

assert_ne!(map1, map2);
assert_ne!(map2, map1);
}

#[test]
#[ignore]
// ignored because we cannot control when destructors run
Expand Down

0 comments on commit d3706b2

Please sign in to comment.