Skip to content

Commit

Permalink
Make put() return value at the right node
Browse files Browse the repository at this point in the history
  • Loading branch information
jonhoo committed Jan 25, 2020
1 parent 3b0c4ca commit 051ca79
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ where
let n = unsafe { p.deref() }.as_node().unwrap();
if n.hash == h && &n.key == key {
// the key already exists in the map!
let current_value = head.value.load(Ordering::SeqCst, guard);
let current_value = n.value.load(Ordering::SeqCst, guard);

// safety: since the value is present now, and we've held a guard from
// the beginning of the search, the value cannot be dropped until the
Expand Down
83 changes: 57 additions & 26 deletions tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,37 +85,68 @@ fn insert_and_get_key_value() {
}
}

#[test]
fn insert_in_same_bucket_and_get_distinct_entries() {
use std::hash::{BuildHasher, Hasher};
use std::hash::{BuildHasher, Hasher};

struct OneBucketState;
struct OneBucketHasher;
impl BuildHasher for OneBucketState {
type Hasher = OneBucketHasher;
struct OneBucketState;
struct OneBucketHasher;
impl BuildHasher for OneBucketState {
type Hasher = OneBucketHasher;

fn build_hasher(&self) -> Self::Hasher {
OneBucketHasher
}
fn build_hasher(&self) -> Self::Hasher {
OneBucketHasher
}
impl Hasher for OneBucketHasher {
fn write(&mut self, _bytes: &[u8]) {}
fn finish(&self) -> u64 {
0
}
}
impl Hasher for OneBucketHasher {
fn write(&mut self, _bytes: &[u8]) {}
fn finish(&self) -> u64 {
0
}
}

let map = HashMap::<usize, usize, _>::with_hasher(OneBucketState);

map.insert(42, 0, &epoch::pin());
map.insert(50, 20, &epoch::pin());
{
let guard = epoch::pin();
let e = map.get(&42, &guard).unwrap();
assert_eq!(e, &0);
let e = map.get(&50, &guard).unwrap();
assert_eq!(e, &20);
}
#[test]
fn one_bucket() {
let guard = epoch::pin();
let map = HashMap::<&'static str, usize, _>::with_hasher(OneBucketState);

// we want to check that all operations work regardless on whether
// we are operating on the head of a bucket, the tail of the bucket,
// or somewhere in the middle.
let v = map.insert("head", 0, &guard);
assert_eq!(v, None);
let v = map.insert("middle", 10, &guard);
assert_eq!(v, None);
let v = map.insert("tail", 100, &guard);
assert_eq!(v, None);
let e = map.get("head", &guard).unwrap();
assert_eq!(e, &0);
let e = map.get("middle", &guard).unwrap();
assert_eq!(e, &10);
let e = map.get("tail", &guard).unwrap();
assert_eq!(e, &100);

// check that replacing the keys returns the correct old value
let v = map.insert("head", 1, &guard);
assert_eq!(v, Some(&0));
let v = map.insert("middle", 11, &guard);
assert_eq!(v, Some(&10));
let v = map.insert("tail", 101, &guard);
assert_eq!(v, Some(&100));
// and updated the right value
let e = map.get("head", &guard).unwrap();
assert_eq!(e, &1);
let e = map.get("middle", &guard).unwrap();
assert_eq!(e, &11);
let e = map.get("tail", &guard).unwrap();
assert_eq!(e, &101);
// and that remove produces the right value
// note that we must remove them in a particular order
// so that we test all three node positions
let v = map.remove("middle", &guard);
assert_eq!(v, Some(&11));
let v = map.remove("tail", &guard);
assert_eq!(v, Some(&101));
let v = map.remove("head", &guard);
assert_eq!(v, Some(&1));
}

#[test]
Expand Down

0 comments on commit 051ca79

Please sign in to comment.