From 2aaf5b53950d7b5d9cc0e26142e7d901bf754c70 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Sat, 15 Nov 2014 12:31:02 +0000 Subject: [PATCH] HCOLL-81 extend support for mapForkey to all maps. --- .../net/openhft/chronicle/map/ChronicleMap.java | 13 ++++++++++++- .../chronicle/map/StatelessChronicleMap.java | 4 ++-- .../chronicle/map/VanillaChronicleMap.java | 13 ++++++++----- .../chronicle/map/ReplicationCheckingMap.java | 5 +++++ .../chronicle/map/StatelessClientTest.java | 16 +++++++--------- .../jrs166/map/StatelessChronicleMapTest.java | 10 ++++++---- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java index 4bc5d71ed..b73730be2 100644 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java @@ -166,7 +166,7 @@ public interface ChronicleMap extends ConcurrentMap, ChronicleHash { * defaultValueProvider.} * *

If the {@code ChronicleMap} is off-heap updatable, i. e. created via {@link - * ChronicleMapBuilder} builder (values are {@link Byteable}), there is one more option of + * ChronicleMapBuilder} builder (values are {@tlink Byteable}), there is one more option of * what to do if the key is absent in the map, see {@link ChronicleMapBuilder#prepareValueBytesOnAcquire(PrepareValueBytes)}. * By default, value bytes are just zeroed out, no default value, either provided for key or constant, is * put for the absent key. @@ -182,5 +182,16 @@ public interface ChronicleMap extends ConcurrentMap, ChronicleHash { @NotNull WriteContext acquireUsingLocked(@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. + * + * @param key to apply the mapping to + * @param function to calculate a result + * @param return type. + * @return the result of the function. + */ + R mapForKey(K key, @NotNull Function function); + } diff --git a/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java b/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java index f357c8da8..04c291fe5 100644 --- a/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java @@ -458,7 +458,7 @@ class StatelessChronicleMap implements ChronicleMap, Closeable { } - public synchronized R mapForKey(K key, @NotNull Function function) { + public synchronized R mapForKey(K key, @NotNull Function function) { final ThreadLocalCopies local = keyValueSerializer.threadLocalCopies(); final long sizeLocation = writeEventAnSkip(MAP_FOR_KEY); @@ -471,7 +471,7 @@ class StatelessChronicleMap implements ChronicleMap, Closeable { } - private void writeObject(@NotNull Function function) { + private void writeObject(@NotNull Object function) { long start = bytes.position(); for (; ; ) { try { diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index 908ee3ccc..3e4cfb765 100755 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -34,8 +34,6 @@ import net.openhft.lang.model.constraints.Nullable; import net.openhft.lang.threadlocal.Provider; import net.openhft.lang.threadlocal.ThreadLocalCopies; import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -56,9 +54,6 @@ class VanillaChronicleMap, V, VW, MVW extends MetaBytesWriter> extends AbstractMap implements ChronicleMap, Serializable { - - private static final Logger LOG = LoggerFactory.getLogger(VanillaChronicleMap.class); - /** * Because DirectBitSet implementations couldn't find more than 64 continuous clear or set bits. */ @@ -372,6 +367,14 @@ class VanillaChronicleMap, } } + @Override + public R mapForKey(K key, @NotNull Function function) { + try (Context entry = lookupUsing(key, null, + LockType.READ_LOCK, false)) { + return function.apply(entry.value()); + } + } + @NotNull @Override public WriteContext acquireUsingLocked(@NotNull K key, @NotNull V usingValue) { diff --git a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java index 1be6f380b..9bfc62abc 100644 --- a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java +++ b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java @@ -244,6 +244,11 @@ public class ReplicationCheckingMap implements ChronicleMap { return map1.getUsing(key, usingValue); } + @Override + public R mapForKey(K key, @NotNull Function function) { + return map1.mapForKey(key, function); + } + @Override public V acquireUsing(@NotNull K key, V usingValue) { return map1.acquireUsing(key, usingValue); diff --git a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java index 853c6cfbd..1c54ff668 100644 --- a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java +++ b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java @@ -35,15 +35,15 @@ import java.util.Set; */ public class StatelessClientTest { - - public static final int SIZE = 100000; + public static final int SIZE = 2500; - static class StringBuilderToStringFunction implements Function { + enum ToString implements Function { + INSTANCE; @Override - public String apply(StringBuilder stringBuilder) { - return stringBuilder.toString(); + public String apply(Object obj) { + return obj.toString(); } } @@ -63,8 +63,7 @@ public class StatelessClientTest { .class, StringBuilder.class) .statelessClient(new InetSocketAddress("localhost", 8056)).create()) { - String actual = (String) ((StatelessChronicleMap) statelessMap).mapForKey(10, new - StringBuilderToStringFunction()); + String actual = statelessMap.mapForKey(10, ToString.INSTANCE); Assert.assertEquals("Hello World", actual); } @@ -87,8 +86,7 @@ public class StatelessClientTest { .class, StringBuilder.class) .statelessClient(new InetSocketAddress("localhost", 8056)).create()) { - String actual = (String) ((StatelessChronicleMap) statelessMap).mapForKey(11, new - StringBuilderToStringFunction()); + String actual = statelessMap.mapForKey(11, ToString.INSTANCE); Assert.assertEquals("", actual); } 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 4a251f27a..539d8db76 100755 --- a/src/test/java/net/openhft/chronicle/map/jrs166/map/StatelessChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/jrs166/map/StatelessChronicleMapTest.java @@ -19,10 +19,7 @@ package net.openhft.chronicle.map.jrs166.map; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; -import net.openhft.chronicle.map.ChronicleMap; -import net.openhft.chronicle.map.ChronicleMapBuilder; -import net.openhft.chronicle.map.ReadContext; -import net.openhft.chronicle.map.WriteContext; +import net.openhft.chronicle.map.*; import net.openhft.chronicle.map.jrs166.JSR166TestCase; import org.jetbrains.annotations.NotNull; import org.junit.Ignore; @@ -169,6 +166,11 @@ public class StatelessChronicleMapTest extends JSR166TestCase { throw new UnsupportedOperationException(); } + @Override + public R mapForKey(K key, @NotNull Function function) { + return d.mapForKey(key, function); + } + @Override public V putIfAbsent(K key, V value) { return d.putIfAbsent(key, value);