,
/**
* Removes a key (or key-value pair) from the Segment.
*
- * The entry will only be removed if {@code expectedValue} equals to {@code null} or the value previously
- * corresponding to the specified key.
+ *
The entry will only be removed if {@code expectedValue} equals to {@code null} or the
+ * value previously corresponding to the specified key.
*
* @param hash2 a hash code related to the {@code keyBytes}
- * @return the value of the entry that was removed if the entry corresponding to the {@code keyBytes} exists and
- * {@link #removeReturnsNull} is {@code false}, {@code null} otherwise
+ * @return the value of the entry that was removed if the entry corresponding to the {@code
+ * keyBytes} exists and {@link #removeReturnsNull} is {@code false}, {@code null} otherwise
*/
V remove(ThreadLocalCopies copies, MKI metaKeyInterop, KI keyInterop, K key,
V expectedValue, long hash2) {
@@ -1068,8 +1141,9 @@ class VanillaChronicleMap,
}
/**
- * Replaces the specified value for the key with the given value. {@code newValue} is set only if the existing
- * value corresponding to the specified key is equal to {@code expectedValue} or {@code expectedValue == null}.
+ * Replaces the specified value for the key with the given value. {@code newValue} is set
+ * only if the existing value corresponding to the specified key is equal to {@code
+ * expectedValue} or {@code expectedValue == null}.
*
* @param hash2 a hash code related to the {@code keyBytes}
* @return the replaced value or {@code null} if the value was not replaced
@@ -1145,15 +1219,17 @@ class VanillaChronicleMap,
}
/**
- * Replaces value in existing entry. May cause entry relocation, because there may be not enough space for new
- * value in location already allocated for this entry.
+ * Replaces value in existing entry. May cause entry relocation, because there may be not
+ * enough space for new value in location already allocated for this entry.
*
* @param pos index of the first block occupied by the entry
- * @param offset relative offset of the entry in Segment bytes (before, i. e. including metaData)
+ * @param offset relative offset of the entry in Segment bytes (before, i. e.
+ * including metaData)
* @param entry relative pointer in Segment bytes
* @param valueSizePos relative position of value size in entry
* @param entryEndAddr absolute address of the entry end
- * @return relative offset of the entry in Segment bytes after putting value (that may cause entry relocation)
+ * @return relative offset of the entry in Segment bytes after putting value (that may cause
+ * entry relocation)
*/
long putValue(long pos, long offset, NativeBytes entry, long valueSizePos,
long entryEndAddr, ThreadLocalCopies copies, V value, Bytes valueBytes,
diff --git a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java
index 255308c93..2771aebf0 100644
--- a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java
+++ b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java
@@ -251,6 +251,16 @@ public class ReplicationCheckingMap implements ChronicleMap {
return map1.acquireUsing(key, usingValue);
}
+ @Override
+ public SegmentLock acquireUsingReadLocked(K key, V usingValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SegmentLock acquireUsingWriteLocked(K key, V usingValue) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public File file() {
throw new UnsupportedOperationException();
diff --git a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java
index fd413aa1c..e3495a017 100644
--- a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java
+++ b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java
@@ -270,6 +270,133 @@ public class StatelessClientTest {
}
+ @Test
+ public void testBufferOverFlowPutAllWherePutReturnsNull() throws IOException,
+ InterruptedException {
+
+ final ChronicleMap serverMap;
+ final ChronicleMap statelessMap;
+
+
+ // stateless client
+ {
+ statelessMap = ChronicleMapBuilder.of(Integer
+ .class, CharSequence.class)
+ .putReturnsNull(true)
+ .stateless(remoteAddress(new InetSocketAddress("localhost", 8086))).create();
+ }
+
+ // server
+ {
+ serverMap = ChronicleMapBuilder.of(Integer.class, CharSequence.class)
+ .replicators((byte) 2, TcpReplicationConfig.of(8086))
+ .putReturnsNull(true)
+ .create();
+ }
+
+
+ Map payload = new HashMap();
+
+ for (int i = 0; i < SIZE; i++) {
+ payload.put(i, "some value=" + i);
+ }
+
+
+ statelessMap.putAll(payload);
+
+ int value = SIZE - 10;
+
+ Assert.assertEquals("some value=" + value, statelessMap.get(value));
+ Assert.assertEquals(SIZE, statelessMap.size());
+
+ serverMap.close();
+ statelessMap.close();
+
+ }
+
+
+ @Test
+ public void testPutWherePutReturnsNull() throws IOException,
+ InterruptedException {
+
+ final ChronicleMap serverMap;
+ final ChronicleMap statelessMap;
+
+
+ // stateless client
+ {
+ statelessMap = ChronicleMapBuilder.of(Integer
+ .class, CharSequence.class)
+ .putReturnsNull(true)
+ .removeReturnsNull(true)
+ .stateless(remoteAddress(new InetSocketAddress("localhost", 8086))).create();
+ }
+
+ // server
+ {
+ serverMap = ChronicleMapBuilder.of(Integer.class, CharSequence.class)
+ .replicators((byte) 2, TcpReplicationConfig.of(8086))
+ .putReturnsNull(true)
+ .removeReturnsNull(true)
+ .create();
+ }
+
+
+ statelessMap.put(1, "some value");
+
+ Assert.assertEquals("some value", statelessMap.get(1));
+ Assert.assertEquals(1, statelessMap.size());
+
+
+ serverMap.close();
+ statelessMap.close();
+
+ }
+
+
+
+ @Test
+ public void testRemoveWhereRemoveReturnsNull() throws IOException,
+ InterruptedException {
+
+ final ChronicleMap serverMap;
+ final ChronicleMap statelessMap;
+
+
+ // stateless client
+ {
+ statelessMap = ChronicleMapBuilder.of(Integer
+ .class, CharSequence.class)
+ .putReturnsNull(true)
+ .removeReturnsNull(true)
+ .stateless(remoteAddress(new InetSocketAddress("localhost", 8086))).create();
+ }
+
+ // server
+ {
+ serverMap = ChronicleMapBuilder.of(Integer.class, CharSequence.class)
+ .replicators((byte) 2, TcpReplicationConfig.of(8086))
+ .putReturnsNull(true)
+ .removeReturnsNull(true)
+ .create();
+ }
+
+
+ statelessMap.put(1, "some value");
+
+ Assert.assertEquals("some value", statelessMap.get(1));
+ Assert.assertEquals(1, statelessMap.size());
+
+ statelessMap.remove(1);
+
+ Assert.assertEquals(null, statelessMap.get(1));
+ Assert.assertEquals(0, statelessMap.size());
+
+ serverMap.close();
+ statelessMap.close();
+
+ }
+
@Test
public void testEquals() throws IOException, InterruptedException {
diff --git a/src/test/java/net/openhft/chronicle/map/jrs166/map/StatelessChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/jrs166/map/StatelessChronicleMapTest.java
index 28f850b0d..51a70cd46 100644
--- a/src/test/java/net/openhft/chronicle/map/jrs166/map/StatelessChronicleMapTest.java
+++ b/src/test/java/net/openhft/chronicle/map/jrs166/map/StatelessChronicleMapTest.java
@@ -21,6 +21,7 @@ package net.openhft.chronicle.map.jrs166.map;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.ChronicleMapBuilder;
import net.openhft.chronicle.hash.TcpReplicationConfig;
+import net.openhft.chronicle.map.SegmentLock;
import net.openhft.chronicle.map.jrs166.JSR166TestCase;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
@@ -149,6 +150,16 @@ public class StatelessChronicleMapTest extends JSR166TestCase {
return d.acquireUsing(key, usingValue);
}
+ @Override
+ public SegmentLock acquireUsingReadLocked(K key, V usingValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SegmentLock acquireUsingWriteLocked(K key, V usingValue) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public V putIfAbsent(K key, V value) {
return d.putIfAbsent(key, value);