From bcc5501499cb5eb53fc35dfeed9611c5ee21d29c Mon Sep 17 00:00:00 2001 From: leventov Date: Tue, 16 Dec 2014 12:14:02 +0700 Subject: [PATCH 1/3] HCOLL-253 optimized VanillaChronicleMap.HeapWriteLocked.close() (force put), added force replication on NativeWriteLocked.close() --- .../chronicle/map/VanillaChronicleMap.java | 30 +++++++++++++++++-- ...ReplicationWithAcquireUsingLockedTest.java | 13 ++++---- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index 3164a834c..c286c476f 100755 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -2818,6 +2818,14 @@ class VanillaChronicleMap, @Override public void close() { + // TODO optimize -- keep replication bytes offset in SegmentState to jump directly + long pos = segmentState.pos; + long offset = segment.offsetFromPos(pos); + MultiStoreBytes entry = segment.reuse(segmentState.tmpBytes, offset); + long keySize = map.keySizeMarshaller.readSize(entry); + entry.skip(keySize); + segment.manageReplicationBytes(entry, true, false); + map.onPut(segment, pos); segmentState.close(); segment.writeUnlock(); } @@ -2849,9 +2857,25 @@ class VanillaChronicleMap, @Override public void close() { if (putOnClose) { - segment.putWithoutLock(copies, segmentState, - metaKeyInterop, keyInterop, key(), keySize, map.keyIdentity(), - map, value(), map.valueIdentity(), segmentHash, true, map, true); + // TODO optimize -- keep keySize, valueSizePos, entryEndAddr, etc. inside + // segmentState + long pos = segmentState.pos; + long offset = segment.offsetFromPos(pos); + MultiStoreBytes entry = segment.reuse(segmentState.tmpBytes, offset); + long keySize = map.keySizeMarshaller.readSize(entry); + entry.skip(keySize); + segment.manageReplicationBytes(entry, true, false); + long valueSizePos = entry.position(); + long valueSize = map.readValueSize(entry); + long entryEndAddr = entry.positionAddr() + valueSize; + VI valueInterop = map.valueInteropProvider.get(copies, map.originalValueInterop); + V value = value(); + MVI metaValueInterop = map.metaValueInteropProvider + .get(copies, map.originalMetaValueInterop, valueInterop, value); + long newValueSize = metaValueInterop.size(valueInterop, value); + segment.putValue(pos, offset, entry, valueSizePos, entryEndAddr, segmentState, + metaValueInterop, valueInterop, value, newValueSize, segment.hashLookup()); + map.onPut(segment, segmentState.pos); } putOnClose = true; segmentState.close(); diff --git a/src/test/java/net/openhft/chronicle/map/TcpReplicationWithAcquireUsingLockedTest.java b/src/test/java/net/openhft/chronicle/map/TcpReplicationWithAcquireUsingLockedTest.java index d71615c9a..d802908fc 100644 --- a/src/test/java/net/openhft/chronicle/map/TcpReplicationWithAcquireUsingLockedTest.java +++ b/src/test/java/net/openhft/chronicle/map/TcpReplicationWithAcquireUsingLockedTest.java @@ -3,7 +3,6 @@ package net.openhft.chronicle.map; import eg.TestInstrumentVOInterface; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import java.net.InetSocketAddress; @@ -14,7 +13,6 @@ import java.net.InetSocketAddress; public class TcpReplicationWithAcquireUsingLockedTest { - @Ignore("HCOLL-253 TcpReplication is not working when used with acquireUsingLocked") @Test public void testReplicationWithAcquireUsingLocked() throws Exception { @@ -31,10 +29,12 @@ public class TcpReplicationWithAcquireUsingLockedTest { map1a = map1; - TcpTransportAndNetworkConfig config2 = TcpTransportAndNetworkConfig.of(8077, new InetSocketAddress("127.0.0.1", 8076)); + TcpTransportAndNetworkConfig config2 = + TcpTransportAndNetworkConfig.of(8077, new InetSocketAddress("127.0.0.1", 8076)); - try (ChronicleMap map2 = ChronicleMapBuilder.of(CharSequence.class, + try (ChronicleMap map2 = + ChronicleMapBuilder.of(CharSequence.class, TestInstrumentVOInterface.class) .replication((byte) 2, config2) .create()) { @@ -45,9 +45,8 @@ public class TcpReplicationWithAcquireUsingLockedTest { TestInstrumentVOInterface instrumentVOInterface = map1.newValueInstance(); - try (WriteContext wc = map1 - .acquireUsingLocked - ("KEY1", instrumentVOInterface)) { + try (WriteContext wc = + map1.acquireUsingLocked("KEY1", instrumentVOInterface)) { instrumentVOInterface.setSymbol("Flyer"); instrumentVOInterface.setCurrencyCode("USA"); } From d8df6d571753eebcb62e4ba1c307abf0a0da8de6 Mon Sep 17 00:00:00 2001 From: leventov Date: Tue, 16 Dec 2014 12:40:21 +0700 Subject: [PATCH 2/3] HCOLL-248 changed the ChronicleMap code and defaults regarding CharSequences/StringBuilders to fit CHMUseCases --- .../internal/CharSequenceReader.java | 28 +++++++++++++++---- .../chronicle/map/ChronicleMapBuilder.java | 4 +++ .../chronicle/map/SerializationBuilder.java | 5 +++- .../chronicle/map/VanillaChronicleMap.java | 2 +- .../chronicle/map/CHMUseCasesTest.java | 3 +- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java b/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java index 0fc614406..9d110aacc 100644 --- a/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java +++ b/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java @@ -33,7 +33,16 @@ public final class CharSequenceReader implements BytesReader, StatefulCopyable> { private static final long serialVersionUID = 0L; - private enum NoInterning implements CharSequenceInterner { + private enum NoInterningIdentity implements CharSequenceInterner { + INSTANCE; + + @Override + public CharSequence intern(CharSequence cs) { + return cs; + } + } + + private enum NoInterningToString implements CharSequenceInterner { INSTANCE; @Override public String intern(CharSequence cs) { @@ -41,13 +50,20 @@ public final class CharSequenceReader } } - private static final CharSequenceReader DEFAULT_READER = - new CharSequenceReader(NoInterning.INSTANCE, NoInterning.INSTANCE); + private static final CharSequenceReader STRING_READER = + new CharSequenceReader(NoInterningToString.INSTANCE, NoInterningToString.INSTANCE); - public static CharSequenceReader of() { + private static final CharSequenceReader DEFAULT_READER = + new CharSequenceReader(NoInterningIdentity.INSTANCE, NoInterningIdentity.INSTANCE); + + public static CharSequenceReader of() { return DEFAULT_READER; } + public static CharSequenceReader ofString() { + return STRING_READER; + } + public static & Serializable> CharSequenceReader of(@NotNull I interner, @NotNull Serializable stateIdentity) { return new CharSequenceReader(interner, stateIdentity); @@ -111,7 +127,9 @@ public final class CharSequenceReader } private Object readResolve() throws ObjectStreamException { - if (interner == NoInterning.INSTANCE) + if (interner == NoInterningToString.INSTANCE) + return STRING_READER; + if (interner == NoInterningIdentity.INSTANCE) return DEFAULT_READER; return this; } diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index 0d3e701cc..d5c8268d4 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -104,6 +104,8 @@ public final class ChronicleMapBuilder implements Cloneable, LoggerFactory.getLogger(ChronicleMapBuilder.class.getName()); public static final long DEFAULT_STATELESS_CLIENT_TIMEOUT = TimeUnit.SECONDS.toMillis(10); + private static final StringBuilder EMTRY_STRING_BUILDER = new StringBuilder(); + SerializationBuilder keyBuilder; SerializationBuilder valueBuilder; @@ -148,6 +150,8 @@ public final class ChronicleMapBuilder implements Cloneable, if (CharSequence.class == valueClass) defaultValue = (V) ""; + if (StringBuilder.class == valueClass) + defaultValue = (V) EMTRY_STRING_BUILDER; } /** diff --git a/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java b/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java index 87cb452db..06603eca6 100644 --- a/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java @@ -127,9 +127,12 @@ final class SerializationBuilder implements Cloneable, Serializable { sizeMarshaller(byteableMarshaller); reader(byteableMarshaller); interop(byteableMarshaller); - } else if (eClass == CharSequence.class || eClass == String.class) { + } else if (eClass == CharSequence.class || eClass == StringBuilder.class) { reader((BytesReader) CharSequenceReader.of()); writer((BytesWriter) CharSequenceWriter.instance()); + } else if (eClass == String.class) { + reader((BytesReader) CharSequenceReader.ofString()); + writer((BytesWriter) CharSequenceWriter.instance()); } else if (eClass == Void.class) { sizeMarshaller(VoidMarshaller.INSTANCE); reader((BytesReader) VoidMarshaller.INSTANCE); diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index c286c476f..3b7f70e95 100755 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -652,7 +652,7 @@ class VanillaChronicleMap, @Override public V newValueInstance() { - if (vClass.equals(CharSequence.class) || vClass.equals(StringBuilder.class)) { + if (vClass == CharSequence.class || vClass == StringBuilder.class) { return (V) new StringBuilder(); } diff --git a/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java b/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java index 32b069333..19039c4c8 100644 --- a/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java +++ b/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java @@ -436,10 +436,11 @@ public class CHMUseCasesTest { } } - @Ignore("HCOLL-248 Issue with acquireUsingLocked() for a StringBuilder Value") @Test public void testAcquireUsingWithIntValueKeyStringBuilderValue() throws IOException { + if (typeOfMap == TypeOfMap.STATELESS) + return; // acquireUsingLocked supported by the STATELESS client ChronicleMapBuilder builder = ChronicleMapBuilder .of(IntValue.class, StringBuilder.class); From b2ad8f6acbc3d524d72479af9ef0009d3055c398 Mon Sep 17 00:00:00 2001 From: leventov Date: Tue, 16 Dec 2014 13:20:38 +0700 Subject: [PATCH 3/3] HCOLL-248 changed default behaviour again --- .../hash/serialization/internal/CharSequenceReader.java | 6 +++--- .../net/openhft/chronicle/map/SerializationBuilder.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java b/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java index 9d110aacc..60eb7b516 100644 --- a/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java +++ b/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharSequenceReader.java @@ -57,11 +57,11 @@ public final class CharSequenceReader new CharSequenceReader(NoInterningIdentity.INSTANCE, NoInterningIdentity.INSTANCE); public static CharSequenceReader of() { - return DEFAULT_READER; + return STRING_READER; } - public static CharSequenceReader ofString() { - return STRING_READER; + public static CharSequenceReader ofStringBuilder() { + return DEFAULT_READER; } public static & Serializable> diff --git a/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java b/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java index 06603eca6..a94e29540 100644 --- a/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java @@ -127,11 +127,11 @@ final class SerializationBuilder implements Cloneable, Serializable { sizeMarshaller(byteableMarshaller); reader(byteableMarshaller); interop(byteableMarshaller); - } else if (eClass == CharSequence.class || eClass == StringBuilder.class) { + } else if (eClass == CharSequence.class || eClass == String.class) { reader((BytesReader) CharSequenceReader.of()); writer((BytesWriter) CharSequenceWriter.instance()); - } else if (eClass == String.class) { - reader((BytesReader) CharSequenceReader.ofString()); + } else if (eClass == StringBuilder.class) { + reader((BytesReader) CharSequenceReader.ofStringBuilder()); writer((BytesWriter) CharSequenceWriter.instance()); } else if (eClass == Void.class) { sizeMarshaller(VoidMarshaller.INSTANCE);