From 051ca79fe2458af0e0e75ab93f8cd113078cd2bd Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Sat, 25 Jan 2020 10:59:56 -0500 Subject: [PATCH] Make put() return value at the right node Good catch @voidc! https://github.com/jonhoo/flurry/pull/32/files#r370940037 --- src/map.rs | 2 +- tests/basic.rs | 83 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/map.rs b/src/map.rs index a6684e68..da0cd0de 100644 --- a/src/map.rs +++ b/src/map.rs @@ -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 diff --git a/tests/basic.rs b/tests/basic.rs index 304fd187..ab52e69d 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -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::::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]