From aeeffff7815c97fd5d57dfdaaea1a6eaba2e15dd Mon Sep 17 00:00:00 2001 From: nitsanw Date: Tue, 28 May 2019 15:38:30 +0200 Subject: [PATCH] Fix #244 for the long map version. Fix issue for other replace case --- .../src/main/java/org/jctools/maps/NonBlockingHashMap.java | 2 +- .../main/java/org/jctools/maps/NonBlockingHashMapLong.java | 6 +++--- .../java/org/jctools/maps/nbhm_test/NBHML_Tester2.java | 7 +++++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMap.java b/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMap.java index 90d31725..7cd94d1e 100644 --- a/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMap.java +++ b/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMap.java @@ -767,7 +767,7 @@ private static final Object putIfMatch0( (expVal != MATCH_ANY || V == TOMBSTONE || V == null) && !(V==null && expVal == TOMBSTONE) && // Match on null/TOMBSTONE combo (expVal == null || !expVal.equals(V)) ) // Expensive equals check at the last - return V; // Do not update! + return (V==null) ? TOMBSTONE : V; // Do not update! // Actually change the Value in the Key,Value pair if( CAS_val(kvs, idx, V, putval ) ) break; diff --git a/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMapLong.java b/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMapLong.java index fe28bd8b..6a22df74 100644 --- a/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMapLong.java +++ b/jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMapLong.java @@ -561,8 +561,8 @@ private Object putIfMatch( final long key, final Object putval, final Object exp if( K == NO_KEY ) { // Slot is free? // Found an empty Key slot - which means this Key has never been in // this table. No need to put a Tombstone - the Key is not here! - if( putval == TOMBSTONE ) return putval; // Not-now & never-been in this table - if( expVal == MATCH_ANY ) return null; // Will not match, even after K inserts + if( putval == TOMBSTONE ) return TOMBSTONE; // Not-now & never-been in this table + if( expVal == MATCH_ANY ) return TOMBSTONE; // Will not match, even after K inserts // Claim the zero key-slot if( CAS_key(idx, NO_KEY, key) ) { // Claim slot for Key _slots.add(1); // Raise key-slots-used count @@ -635,7 +635,7 @@ private Object putIfMatch( final long key, final Object putval, final Object exp (expVal != MATCH_ANY || V == TOMBSTONE || V == null) && !(V==null && expVal == TOMBSTONE) && // Match on null/TOMBSTONE combo (expVal == null || !expVal.equals(V)) ) // Expensive equals check at the last - return V; // Do not update! + return (V==null) ? TOMBSTONE : V; // Do not update! // Actually change the Value in the Key,Value pair if( CAS_val(idx, V, putval ) ) { diff --git a/jctools-core/src/test/java/org/jctools/maps/nbhm_test/NBHML_Tester2.java b/jctools-core/src/test/java/org/jctools/maps/nbhm_test/NBHML_Tester2.java index 518ef3ad..657e0f73 100644 --- a/jctools-core/src/test/java/org/jctools/maps/nbhm_test/NBHML_Tester2.java +++ b/jctools-core/src/test/java/org/jctools/maps/nbhm_test/NBHML_Tester2.java @@ -129,6 +129,13 @@ private void checkSizes(String msg, int sz, Iterator it, int expectedSize) } + @Test + public void replaceMissingValue() { + NonBlockingHashMapLong map = new NonBlockingHashMapLong<>(); + assertNull(map.replace(1, 2)); + assertFalse(map.replace(1, 2, 3)); + } + @Test public void testIterationBig2() {