From 440b075f9db7fb721299274e2c56e982eaa899b8 Mon Sep 17 00:00:00 2001 From: leventov Date: Sun, 27 Sep 2015 15:41:07 +0300 Subject: [PATCH] Remove ChronicleMap.putMapped() as a duplicate of computeIfPresent(); Reduce the number of ignored tests --- .../chronicle/map/AbstractChronicleMap.java | 20 -- .../openhft/chronicle/map/ChronicleMap.java | 37 ++-- .../chronicle/map/VanillaChronicleMap.java | 9 +- .../map/impl/stage/entry/MapEntryStages.java | 2 +- .../stage/entry/ReplicatedMapEntryStages.java | 3 +- .../chronicle/map/CHMMetaDataTest.java | 91 --------- .../chronicle/map/CHMUseCasesTest.java | 180 ++++++------------ .../chronicle/map/ChronicleMapTest.java | 2 - .../chronicle/map/DefaultValueTest.java | 2 - ...tListenerWithTCPSocketReplicationTest.java | 91 ++++++--- .../chronicle/map/ReplicationCheckingMap.java | 5 - ...esSpanningSeveralChunksReplicationHub.java | 2 +- .../chronicle/map/WarnOnWindowsTest.java | 1 + .../SimpleMapOperationsListeningTest.java | 1 - 14 files changed, 149 insertions(+), 297 deletions(-) delete mode 100644 src/test/java/net/openhft/chronicle/map/CHMMetaDataTest.java diff --git a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java index 636d9f5fe..03496c13b 100644 --- a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java @@ -18,7 +18,6 @@ package net.openhft.chronicle.map; import net.openhft.chronicle.hash.function.SerializableFunction; import net.openhft.chronicle.hash.impl.util.CharSequences; -import net.openhft.chronicle.map.impl.IterationContextInterface; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -43,25 +42,6 @@ interface AbstractChronicleMap extends ChronicleMap, Serializable { } } - @Override - default V putMapped(K key, @NotNull UnaryOperator unaryOperator) { - requireNonNull(unaryOperator); - try (ExternalMapQueryContext c = queryContext(key)) { - // putMapped() should find a value, update & put most of the time, - // so don't try to check key presence under read lock first, - // as in putIfAbsent()/acquireUsing(), start with update lock: - c.updateLock().lock(); - MapEntry entry = c.entry(); - if (entry != null) { - V newValue = unaryOperator.update(entry.value().get()); - c.replaceValue(entry, c.wrapValueAsData(newValue)); - return newValue; - } else { - return null; - } - } - } - @Override default void getAll(File toFile) throws IOException { synchronized (this) { diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java index 0ad8d3379..2b698484f 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java @@ -100,10 +100,10 @@ public interface ChronicleMap extends ConcurrentMap, /** * Acquire a value for a key, creating if absent. * - *

If the specified key is absent in the map, {@linkplain ChronicleMapBuilder#defaultValue(Object) - * default value} is taken or {@linkplain ChronicleMapBuilder#defaultValueProvider(DefaultValueProvider) - * default value provider} is called. Then this object is put to this map for the specified - * key. + *

If the specified key is absent in the map, {@linkplain ChronicleMapBuilder#defaultValue( + * Object) default value} is taken or {@linkplain ChronicleMapBuilder#defaultValueProvider( + * DefaultValueProvider) default value provider} is called. Then this object is put to this map + * for the specified key. * *

Then, either if the key was initially absent in the map or already present, the value is * deserialized just as during {@link #getUsing(Object, Object) getUsing(key, usingValue)} call, @@ -140,25 +140,24 @@ public interface ChronicleMap extends ConcurrentMap, net.openhft.chronicle.core.io.Closeable acquireContext(@NotNull K key, @NotNull V usingValue); /** - * Apply a mapping to the value returned by a key and return a result. A read lock is assumed. + * Returns the result of application of the given function to the value to which the given key + * is mapped. If there is no mapping for the key, {@code null} is returned from {@code + * getMapped()} call without application of the given function. This method is primarily useful + * when accessing {@code ChronicleMap} implementation which delegates it's requests to some + * remote node (server) and pulls the result through serialization/deserialization path, and + * probably network. In this case, when you actually need only a part of the map value's state + * (e. g. a single field) it's cheaper to extract it on the server side and transmit lesser + * bytes. * - * @param key to apply the mapping to - * @param function to calculate a result - * @param return type. - * @return the result of the function, or null if there is no entry for the key. + * @param key the key whose associated value is to be queried + * @param function a function to transform the value to the actually needed result, + * which should be smaller than the map value + * @param the result type + * @return the result of applying the function to the mapped value, or {@code null} if there + * is no mapping for the key */ R getMapped(K key, @NotNull SerializableFunction function); - /** - * Apply a unaryOperator to the value for a key and return a result. A write lock is assumed. - *

If there is no entry for this key null will be returned - * - * @param key to apply the mapping to - * @param unaryOperator to alter the value and calculate a result - * @return the result of the function. - */ - V putMapped(K key, @NotNull UnaryOperator unaryOperator); - /** * Exports all the entries to a {@link File} storing them in JSON format, an attempt is * made where possible to use standard java serialisation and keep the data human readable, data diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index 4523a4a2d..665391dd7 100755 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -263,7 +263,7 @@ public class VanillaChronicleMap q = queryContext(key)) { - V returnValue = acquireUsingBody(q, usingValue); - return returnValue; + return acquireUsingBody(q, usingValue); } } private V acquireUsingBody(QueryContextInterface q, V usingValue) { q.usingReturnValue().initUsingReturnValue(usingValue); methods.acquireUsing(q, q.usingReturnValue()); - V returnValue = q.usingReturnValue().returnValue(); - checkAcquiredUsing(returnValue, usingValue); - return returnValue; + return q.usingReturnValue().returnValue(); } @Override diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java index 95fac487e..7baad557c 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java @@ -36,7 +36,7 @@ public abstract class MapEntryStages extends HashEntryStages @StageRef public VanillaChronicleMapHolder mh; @StageRef public AllocatedChunks allocatedChunks; - @StageRef KeySearch ks; + @StageRef KeySearch ks; long countValueSizeOffset() { return keyEnd(); diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/ReplicatedMapEntryStages.java b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/ReplicatedMapEntryStages.java index 9301b68f8..c5b1969e6 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/ReplicatedMapEntryStages.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/ReplicatedMapEntryStages.java @@ -172,6 +172,7 @@ public abstract class ReplicatedMapEntryStages extends MapEntryStages absentKey() { - return key(); + checkOnEachPublicOperation.checkOnEachPublicOperation(); + return ks.inputKey; } } diff --git a/src/test/java/net/openhft/chronicle/map/CHMMetaDataTest.java b/src/test/java/net/openhft/chronicle/map/CHMMetaDataTest.java deleted file mode 100644 index 49af2a646..000000000 --- a/src/test/java/net/openhft/chronicle/map/CHMMetaDataTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2015 higherfrequencytrading.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package net.openhft.chronicle.map; - -import org.junit.Ignore; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.concurrent.atomic.AtomicLong; - -import static org.junit.Assert.assertEquals; - -@Ignore("event listener API is not yet determined") -public class CHMMetaDataTest { - private static final String TMP = System.getProperty("java.io.tmpdir"); - - @Test - public void testAccessTimes() throws IOException { - File file = new File(TMP, "testAccessTimes"); -// MapBytesEventListener listener = -// new StringStringMapEventListener(new AtomicLong(1)); - ChronicleMap map = ChronicleMapBuilder.of(String.class, String.class) - .metaDataBytes(8) -// .bytesEventListener(listener) - .create(); - - try { - map.put("a", "aye"); - map.put("b", "bee"); - map.put("c", "see"); - map.put("d", "dee"); -// assertEquals(5, timeStamps.longValue()); - assertEquals("aye", map.get("a")); - assertEquals("bee", map.get("b")); - assertEquals("see", map.get("c")); - assertEquals("dee", map.get("d")); -// assertEquals(9, timeStamps.longValue()); - assertEquals("aye", map.remove("a")); - assertEquals("bee", map.remove("b")); - assertEquals("see", map.remove("c")); - assertEquals("dee", map.remove("d")); -// assertEquals(9, timeStamps.longValue()); - } finally { - map.close(); - file.delete(); - } - } - -// private static class StringStringMapEventListener -// extends MapBytesEventListener { -// private static final long serialVersionUID = 0L; -// -// private final AtomicLong timeStamps; -// -// public StringStringMapEventListener(AtomicLong timeStamps) { -// this.timeStamps = timeStamps; -// } -// -// @Override -// public void onGetFound(MapBytesEvent event) { -// entry.writeLong(metaDataPos, timeStamps.incrementAndGet()); -// } -// -// @Override -// public void onPut(MapPutBytesEvent event) { -// if (added) -// assertEquals(0, entry.readLong(metaDataPos)); -// entry.writeLong(metaDataPos, timeStamps.incrementAndGet()); -// } -// -// @Override -// public void onRemove(MapBytesEvent event) { -// System.out.println("Removed entry with ts of " + entry.readLong(metaDataPos));; -// } -// } -} diff --git a/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java b/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java index d461a728a..890d96ce2 100644 --- a/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java +++ b/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java @@ -44,6 +44,7 @@ import java.nio.ByteBuffer; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.function.BiFunction; import static java.util.Arrays.asList; import static net.openhft.chronicle.map.fromdocs.OpenJDKAndHashMapExamplesTest.parseYYYYMMDD; @@ -404,29 +405,23 @@ public class CHMUseCasesTest { } } - @Ignore @Test public void testByteArrayArrayValue() throws ExecutionException, InterruptedException, IOException { - for (int i = 0; i < 10000; i++) { - int valueSize = 10; + ChronicleMapBuilder builder = ChronicleMapBuilder + .of(byte[].class, byte[][].class) + .averageKey("Key".getBytes()) + .averageValue(new byte[][]{"value1".getBytes(), "value2".getBytes()}); - char[] expected = new char[valueSize]; - Arrays.fill(expected, 'X'); + try (ChronicleMap map = newInstance(builder)) { + byte[] bytes1 = "value1".getBytes(); + byte[] bytes2 = "value2".getBytes(); + byte[][] value = {bytes1, bytes2}; + map.put("Key".getBytes(), value); - ChronicleMapBuilder builder = ChronicleMapBuilder - .of(byte[].class, byte[][].class); - - try (ChronicleMap map = newInstance(builder)) { - byte[] bytes1 = "value1".getBytes(); - byte[] bytes2 = "value2".getBytes(); - byte[][] value = {bytes1, bytes2}; - map.put("Key".getBytes(), value); - - assertEquals(value, map.get("Key".getBytes())); - mapChecks(); - } + assertEquals(value, map.get("Key".getBytes())); + mapChecks(); } } @@ -556,7 +551,8 @@ public class CHMUseCasesTest { } - private static class StringPrefixUnaryOperator implements UnaryOperator, Serializable { + private static class StringPrefixUnaryOperator + implements BiFunction, Serializable { private String prefix; @@ -565,10 +561,9 @@ public class CHMUseCasesTest { } @Override - public String update(String s) { - return prefix + s; + public String apply(String k, String v) { + return prefix + v; } - } @@ -580,7 +575,7 @@ public class CHMUseCasesTest { try (ChronicleMap map = newInstance(builder)) { map.put("Hello", "World"); - map.putMapped("Hello", new StringPrefixUnaryOperator("New ")); + map.computeIfPresent("Hello", new StringPrefixUnaryOperator("New ")); mapChecks(); } } @@ -622,7 +617,9 @@ public class CHMUseCasesTest { * CharSequence is more efficient when object creation is avoided. * * The key can only be on heap and variable length serialised. */ - @Ignore("TODO HCOLL-306") + @Ignore("This test fails because assumes StringBuilder is fed to lambdas, but actually " + + "because interned in CharSequenceReader. Defer fixing this until Chronicle Map " + + "serialization framework is moved from Lang Bytes to Chronicle Bytes") @Test public void testCharSequenceCharSequenceMap() throws ExecutionException, InterruptedException, IOException { @@ -647,40 +644,21 @@ public class CHMUseCasesTest { assertNull(map.getUsing(key, value)); - assertEquals("New World", map.getMapped("Hello", new - SerializableFunction() { - @Override - public CharSequence apply(CharSequence s) { - return "New " + s; - } - })); - assertEquals(null, map.getMapped("No key", new - SerializableFunction() { - @Override - public CharSequence apply(CharSequence s) { - return "New " + s; - } - })); + assertEquals("New World", map.getMapped("Hello", s -> "New " + s)); + assertEquals(null, map.getMapped("No key", + (SerializableFunction) s -> "New " + s)); - assertEquals("New World !!", map.putMapped("Hello", new - UnaryOperator() { - @Override - public CharSequence update(CharSequence s) { - ((StringBuilder) s).append(" !!"); - return "New " + s; - } - })); + assertEquals("New World !!", map.computeIfPresent("Hello", (k, s) -> { + ((StringBuilder) s).append(" !!"); + return "New " + s; + })); assertEquals("New World !!", map.get("Hello").toString()); - assertEquals("New !!", map.putMapped("no-key", new - UnaryOperator() { - @Override - public CharSequence update(CharSequence s) { - ((StringBuilder) s).append("!!"); - return "New " + s; - } - })); + assertEquals("New !!", map.computeIfPresent("no-key", (k, s) -> { + ((StringBuilder) s).append("!!"); + return "New " + s; + })); mapChecks(); } @@ -1013,12 +991,7 @@ public class CHMUseCasesTest { mapChecks(); try { - map.putMapped(1, new UnaryOperator() { - @Override - public Integer update(Integer s) { - return s + 1; - } - }); + map.computeIfPresent(1, (k, s) -> s + 1); } catch (Exception todoMoreSpecificException) { } mapChecks(); @@ -1053,22 +1026,12 @@ public class CHMUseCasesTest { return 10 * s; } })); - assertEquals(null, map.getMapped(-1L, new SerializableFunction() { - @Override - public Long apply(Long s) { - return 10 * s; - } - })); + assertEquals(null, map.getMapped(-1L, (SerializableFunction) s -> 10 * s)); mapChecks(); try { - map.putMapped(1L, new UnaryOperator() { - @Override - public Long update(Long s) { - return s + 1; - } - }); + map.computeIfPresent(1L, (k, s) -> s + 1); } catch (Exception todoMoreSpecificException) { } @@ -1101,20 +1064,10 @@ public class CHMUseCasesTest { return 10 * s; } })); - assertEquals(null, map.getMapped(-1.0, new SerializableFunction() { - @Override - public Double apply(Double s) { - return 10 * s; - } - })); + assertEquals(null, map.getMapped(-1.0, (SerializableFunction) s -> 10 * s)); try { - map.putMapped(1.0, new UnaryOperator() { - @Override - public Double update(Double s) { - return s + 1; - } - }); + map.computeIfPresent(1.0, (k, s) -> s + 1); } catch (Exception todoMoreSpecificException) { } @@ -1159,13 +1112,10 @@ public class CHMUseCasesTest { })); assertTrue(Arrays.equals(new byte[]{12, 10}, - map.putMapped(key1, new UnaryOperator() { - @Override - public byte[] update(byte[] s) { - s[0]++; - s[1]--; - return Arrays.copyOf(s, 2); - } + map.computeIfPresent(key1, (k, s) -> { + s[0]++; + s[1]--; + return Arrays.copyOf(s, 2); }))); byte[] a2 = map.get(key1); @@ -1243,13 +1193,10 @@ public class CHMUseCasesTest { assertEquals(null, map.getMapped(key2, function)); mapChecks(); assertBBEquals(ByteBuffer.wrap(new byte[]{12, 10}), - map.putMapped(key1, new UnaryOperator() { - @Override - public ByteBuffer update(ByteBuffer s) { - s.put(0, (byte) (s.get(0) + 1)); - s.put(1, (byte) (s.get(1) - 1)); - return function.apply(s); - } + map.computeIfPresent(key1, (k, s) -> { + s.put(0, (byte) (s.get(0) + 1)); + s.put(1, (byte) (s.get(1) - 1)); + return function.apply(s); })); assertBBEquals(ByteBuffer.wrap(new byte[]{12, 10}), map.get(key1)); @@ -1362,7 +1309,7 @@ public class CHMUseCasesTest { assertEquals(null, map.getMapped(key2, function)); mapChecks(); assertBBEquals(ByteBuffer.wrap(new byte[]{12, 10}), - map.putMapped(key1, s -> { + map.computeIfPresent(key1, (k, s) -> { s.put(0, (byte) (s.get(0) + 1)); s.put(1, (byte) (s.get(1) - 1)); return function.apply(s); @@ -1480,31 +1427,6 @@ public class CHMUseCasesTest { } } - @Test - @Ignore("HCOLL-241 Generated code creates a field too large ie. it ignores the @Range") - public void testUnsignedIntValueUnsignedIntValueMapEntrySize() throws IOException { - - // TODO once this is working, merge the next test. - ChronicleMapBuilder builder = ChronicleMapBuilder - .of(UnsignedIntValue.class, UnsignedIntValue.class); - - try (ChronicleMap map = newInstance(builder)) { - - // this may change due to alignment - //assertEquals(8, entrySize(map)); - assertEquals(1, ((VanillaChronicleMap) map).maxChunksPerEntry); - UnsignedIntValue key1 = map.newKeyInstance(); - UnsignedIntValue value1 = map.newValueInstance(); - - key1.setValue(1); - value1.setValue(11); - map.put(key1, value1); - assertEquals(value1, map.get(key1)); - mapChecks(); - } - } - - /** * For unsigned int -> unsigned int entries, the key can be on heap or off heap. */ @@ -1516,10 +1438,18 @@ public class CHMUseCasesTest { try (ChronicleMap map = newInstance(builder)) { - + assertEquals(1, ((VanillaChronicleMap) map).maxChunksPerEntry); UnsignedIntValue key1 = map.newKeyInstance(); - UnsignedIntValue key2 = map.newKeyInstance(); UnsignedIntValue value1 = map.newValueInstance(); + + key1.setValue(1); + value1.setValue(11); + map.put(key1, value1); + assertEquals(value1, map.get(key1)); + + key1 = map.newKeyInstance(); + UnsignedIntValue key2 = map.newKeyInstance(); + value1 = map.newValueInstance(); UnsignedIntValue value2 = map.newValueInstance(); key1.setValue(1); diff --git a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java index 58b4426da..87530bc8b 100755 --- a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java @@ -499,7 +499,6 @@ public class ChronicleMapTest { } @Test - @Ignore("TODO clarify requrements -- if acquireUsing() should work with null value") public void testAcquireWithNullContainer() { try (ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, LongValue.class) @@ -690,7 +689,6 @@ public class ChronicleMapTest { } - @Ignore("Possible candidate for TC JVM crashes") @Test public void testAcquireFromMultipleThreads() throws InterruptedException { int entries = 1000 * 1000; diff --git a/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java b/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java index 0fc5a8382..7023498b2 100644 --- a/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java +++ b/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java @@ -16,7 +16,6 @@ package net.openhft.chronicle.map; -import org.junit.Ignore; import org.junit.Test; import java.io.File; @@ -30,7 +29,6 @@ import static org.junit.Assert.assertEquals; public class DefaultValueTest { @Test - @Ignore("Cannot reuse List instance in acquireUsing()") public void test() throws IllegalAccessException, InstantiationException, IOException { File file = Builder.getPersistenceFile(); try { diff --git a/src/test/java/net/openhft/chronicle/map/EventListenerWithTCPSocketReplicationTest.java b/src/test/java/net/openhft/chronicle/map/EventListenerWithTCPSocketReplicationTest.java index 7b161e6c1..5796dbada 100644 --- a/src/test/java/net/openhft/chronicle/map/EventListenerWithTCPSocketReplicationTest.java +++ b/src/test/java/net/openhft/chronicle/map/EventListenerWithTCPSocketReplicationTest.java @@ -16,10 +16,14 @@ package net.openhft.chronicle.map; +import net.openhft.chronicle.hash.Data; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; +import net.openhft.chronicle.map.replication.MapRemoteOperations; +import net.openhft.chronicle.map.replication.MapRemoteQueryContext; +import net.openhft.chronicle.map.replication.MapReplicableEntry; +import org.jetbrains.annotations.NotNull; import org.junit.After; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import java.io.Closeable; @@ -35,7 +39,6 @@ import java.util.concurrent.atomic.AtomicReference; * * @author Rob Austin. */ -@Ignore("event listening API yet determined") public class EventListenerWithTCPSocketReplicationTest { ChronicleMap map1; @@ -50,24 +53,64 @@ public class EventListenerWithTCPSocketReplicationTest { final AtomicBoolean wasRemoved = new AtomicBoolean(false); final AtomicReference valueRemoved = new AtomicReference(); -// final MapEventListener eventListener = new -// MapEventListener() { -// private static final long serialVersionUID = 1L; -// -// @Override -// public void onPut(MapPutEvent event) { -// putWasCalled.getAndSet(true); -// keyRef.set(key); -// valueRef.set(value); -// replacedValueRef.set(replacedValue); -// } -// -// @Override -// public void onRemove(MapEvent event) { -// wasRemoved.set(true); -// valueRemoved.set(value); -// } -// }; + final MapEntryOperations entryOperations = new + MapEntryOperations() { + + @Override + public Void remove(@NotNull MapEntry entry) { + wasRemoved.set(true); + valueRemoved.set(entry.value().get()); + entry.doRemove(); + return null; + } + + @Override + public Void replaceValue(@NotNull MapEntry entry, + Data newValue) { + putWasCalled.getAndSet(true); + keyRef.set(entry.key().get()); + valueRef.set(newValue.get()); + replacedValueRef.set(entry.value().get()); + entry.doReplaceValue(newValue); + return null; + } + + @Override + public Void insert(@NotNull MapAbsentEntry absentEntry, + Data value) { + putWasCalled.getAndSet(true); + keyRef.set(absentEntry.absentKey().get()); + valueRef.set(value.get()); + replacedValueRef.set(null); + absentEntry.doInsert(value); + return null; + } + }; + + final MapRemoteOperations remoteOperations = + new MapRemoteOperations() { + @Override + public void remove(MapRemoteQueryContext q) { + MapReplicableEntry entry = q.entry(); + if (entry != null) { + wasRemoved.set(true); + valueRemoved.set(entry.value().get()); + } + MapRemoteOperations.super.remove(q); + } + + @Override + public void put(MapRemoteQueryContext q, + Data newValue) { + MapReplicableEntry entry = q.entry(); + CharSequence oldValue = entry != null ? entry.value().get() : null; + putWasCalled.getAndSet(true); + keyRef.set(q.queriedKey().get()); + valueRef.set(newValue.get()); + replacedValueRef.set(oldValue); + MapRemoteOperations.super.put(q, newValue); + } + }; @After public void tearDown() throws InterruptedException { @@ -222,8 +265,9 @@ public class EventListenerWithTCPSocketReplicationTest { .autoReconnectedUponDroppedConnection(true); return ChronicleMapBuilder.of(Integer.class, CharSequence.class) .entries(20000L) - .replication((byte) 1, tcpConfig); -// .eventListener(eventListener); + .replication((byte) 1, tcpConfig) + .entryOperations(entryOperations) + .remoteOperations(remoteOperations); } private void waitTillReplicated(final int timeOutMs) throws InterruptedException { @@ -252,7 +296,8 @@ public class EventListenerWithTCPSocketReplicationTest { } private ChronicleMapBuilder serverBuilder() { - TcpTransportAndNetworkConfig tcpConfig = TcpTransportAndNetworkConfig.of(8076, new InetSocketAddress("localhost", 8077)) + TcpTransportAndNetworkConfig tcpConfig = TcpTransportAndNetworkConfig + .of(8076, new InetSocketAddress("localhost", 8077)) .autoReconnectedUponDroppedConnection(true); return ChronicleMapBuilder.of(Integer.class, CharSequence.class) .entries(20000L) diff --git a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java index 44f415199..4e53d830c 100644 --- a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java +++ b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java @@ -224,11 +224,6 @@ public class ReplicationCheckingMap implements ChronicleMap { return map1.getMapped(key, function); } - @Override - public V putMapped(K key, @NotNull UnaryOperator unaryOperator) { - return map1.putMapped(key, unaryOperator); - } - @Override public void getAll(File toFile) { throw new UnsupportedOperationException(); diff --git a/src/test/java/net/openhft/chronicle/map/TestEntriesSpanningSeveralChunksReplicationHub.java b/src/test/java/net/openhft/chronicle/map/TestEntriesSpanningSeveralChunksReplicationHub.java index 508654d1e..0251c8c3e 100644 --- a/src/test/java/net/openhft/chronicle/map/TestEntriesSpanningSeveralChunksReplicationHub.java +++ b/src/test/java/net/openhft/chronicle/map/TestEntriesSpanningSeveralChunksReplicationHub.java @@ -146,7 +146,7 @@ public class TestEntriesSpanningSeveralChunksReplicationHub { public static final int NUMBER_OF_CHANNELS = 1000; - @Ignore + @Ignore("TODO performance test? invalid test? a test revealing a bug?") @Test(timeout = 100000) public void test1000Channels() throws IOException, InterruptedException { diff --git a/src/test/java/net/openhft/chronicle/map/WarnOnWindowsTest.java b/src/test/java/net/openhft/chronicle/map/WarnOnWindowsTest.java index ddb5ea69b..3a4dc4158 100644 --- a/src/test/java/net/openhft/chronicle/map/WarnOnWindowsTest.java +++ b/src/test/java/net/openhft/chronicle/map/WarnOnWindowsTest.java @@ -22,6 +22,7 @@ import org.junit.Test; public class WarnOnWindowsTest { @Test + // TODO this does not emit a proper warning, there are TODOs in ChronicleMapBuilder/VanillaHash @Ignore("This test results to OOM/jvm crash, run manually to verify warning output") public void warnOnWindowsTest() { ChronicleMapBuilder.of(Long.class, Long.class) diff --git a/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java b/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java index aba2f6306..77eb2d840 100644 --- a/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java +++ b/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java @@ -82,7 +82,6 @@ public class SimpleMapOperationsListeningTest { } @Test - @Ignore("Example test, run manually to see the output") public void simpleLoggingTest() { ChronicleMap map = ChronicleMapBuilder .of(Integer.class, IntValue.class)