diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index e7c1789b2..4156a4cc8 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -32,11 +32,14 @@ import net.openhft.chronicle.hash.impl.util.CanonicalRandomAccessFiles; import net.openhft.chronicle.hash.impl.util.Throwables; import net.openhft.chronicle.hash.impl.util.math.PoissonDistribution; import net.openhft.chronicle.hash.serialization.*; +import net.openhft.chronicle.hash.serialization.impl.BytesMarshallableReaderWriter; +import net.openhft.chronicle.hash.serialization.impl.MarshallableReaderWriter; import net.openhft.chronicle.hash.serialization.impl.SerializationBuilder; import net.openhft.chronicle.map.replication.MapRemoteOperations; import net.openhft.chronicle.set.ChronicleSetBuilder; import net.openhft.chronicle.values.ValueModel; import net.openhft.chronicle.values.Values; +import net.openhft.chronicle.wire.Marshallable; import net.openhft.chronicle.wire.TextWire; import net.openhft.chronicle.wire.Wire; import org.jetbrains.annotations.NotNull; @@ -281,6 +284,54 @@ public final class ChronicleMapBuilder implements return new ChronicleMapBuilder<>(keyClass, valueClass); } + /** + * Returns a new {@code ChronicleMapBuilder} instance which is able to {@linkplain #create() + * create} maps with the specified key and value classes. It makes some assumptions about the size of entries + * and the marshallers used + * + * @param keyClass class object used to infer key type and discover it's properties via + * reflection + * @param valueClass class object used to infer value type and discover it's properties via + * reflection + * @param key type of the maps, created by the returned builder + * @param value type of the maps, created by the returned builder + * @return a new builder for the given key and value classes + */ + public static ChronicleMapBuilder simpleMapOf( + @NotNull Class keyClass, @NotNull Class valueClass) { + ChronicleMapBuilder builder = + new ChronicleMapBuilder<>(keyClass, valueClass) + .putReturnsNull(true) + .removeReturnsNull(true); + builder.name(toCamelCase(valueClass.getSimpleName())); + if (!builder.isKeySizeKnown()) + builder.averageKeySize(128); + if (!builder.isValueSizeKnown()) + builder.averageValueSize(512); + if (Marshallable.class.isAssignableFrom(valueClass)) { + //noinspection unchecked + builder.averageValueSize(1024) + .valueMarshaller(new MarshallableReaderWriter<>((Class) valueClass)); + } else if (BytesMarshallable.class.isAssignableFrom(valueClass)) { + builder.valueMarshaller(new BytesMarshallableReaderWriter<>((Class) valueClass)); + } + + return builder; + } + + private static String toCamelCase(String name) { + return Character.toLowerCase(name.charAt(0)) + name.substring(1); + } + + private boolean isKeySizeKnown() { + return keyBuilder.sizeIsStaticallyKnown; + } + + private boolean isValueSizeKnown() { + return valueBuilder.sizeIsStaticallyKnown; + } + + private static void checkSegments(long segments) { if (segments <= 0) { throw new IllegalArgumentException("segments should be positive, " + diff --git a/src/test/java/net/openhft/chronicle/map/ForEachSegmentTest.java b/src/test/java/net/openhft/chronicle/map/ForEachSegmentTest.java index f4603d090..25581065b 100644 --- a/src/test/java/net/openhft/chronicle/map/ForEachSegmentTest.java +++ b/src/test/java/net/openhft/chronicle/map/ForEachSegmentTest.java @@ -1,16 +1,9 @@ package net.openhft.chronicle.map; -import net.openhft.chronicle.bytes.Bytes; import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.core.OS; import net.openhft.chronicle.core.pool.ClassAliasPool; -import net.openhft.chronicle.hash.serialization.SizedReader; -import net.openhft.chronicle.hash.serialization.SizedWriter; -import net.openhft.chronicle.hash.serialization.impl.BytesMarshallableReader; -import net.openhft.chronicle.hash.serialization.impl.BytesMarshallableReaderWriter; import net.openhft.chronicle.wire.AbstractBytesMarshallable; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.junit.Test; import java.io.File; @@ -23,11 +16,9 @@ public class ForEachSegmentTest { @Test public void forEachSegmentEntryWhileReleasesLock() throws IOException { - ChronicleMapBuilder builder = ChronicleMapBuilder.of(Integer.class, MyDto.class) + ChronicleMapBuilder builder = ChronicleMapBuilder.simpleMapOf(Integer.class, MyDto.class) .entries(256) - .averageValueSize(128) - .actualSegments(1) - .valueMarshaller(new BytesMarshallableReaderWriter<>(MyDto.class)); + .actualSegments(1); File tmp = new File(OS.TMP, "stressTest-" + System.nanoTime()); tmp.deleteOnExit(); try (ChronicleMap map = builder.createOrRecoverPersistedTo(tmp)) { @@ -44,11 +35,9 @@ public class ForEachSegmentTest { @Test public void stressTest() throws IOException, InterruptedException { - ChronicleMapBuilder builder = ChronicleMapBuilder.of(Integer.class, MyDto.class) + ChronicleMapBuilder builder = ChronicleMapBuilder.simpleMapOf(Integer.class, MyDto.class) .entries(256) - .averageValueSize(128) - .actualSegments(1) - .valueMarshaller(new BytesMarshallableReaderWriter<>(MyDto.class)); + .actualSegments(1); File tmp = new File(OS.TMP, "stressTest-" + System.nanoTime()); Thread t = null; try (ChronicleMap map = builder.createOrRecoverPersistedTo(tmp)) { diff --git a/src/test/java/net/openhft/chronicle/map/SerializableTest.java b/src/test/java/net/openhft/chronicle/map/SerializableTest.java index 9cf2f5104..6fcdf44fc 100755 --- a/src/test/java/net/openhft/chronicle/map/SerializableTest.java +++ b/src/test/java/net/openhft/chronicle/map/SerializableTest.java @@ -1,7 +1,5 @@ package net.openhft.chronicle.map; -import net.openhft.chronicle.hash.serialization.impl.BytesMarshallableReaderWriter; -import net.openhft.chronicle.hash.serialization.impl.MarshallableReaderWriter; import net.openhft.chronicle.wire.AbstractBytesMarshallable; import net.openhft.chronicle.wire.AbstractMarshallable; import org.junit.Test; @@ -60,11 +58,10 @@ public class SerializableTest { @Test public void test2b() { - ChronicleMap map = ChronicleMapBuilder.of(Integer.class, Bar.class) + ChronicleMap map = ChronicleMapBuilder.simpleMapOf(Integer.class, Bar.class) .name("bar") .averageValueSize(4096) .entries(10) - .valueMarshaller(new BytesMarshallableReaderWriter<>(Bar.class)) .create(); String expected = IntStream.range(0, 4096) @@ -80,11 +77,10 @@ public class SerializableTest { @Test public void test2c() { - ChronicleMap map = ChronicleMapBuilder.of(Integer.class, Bar2.class) + ChronicleMap map = ChronicleMapBuilder.simpleMapOf(Integer.class, Bar2.class) .name("bar") .averageValueSize(1024) .entries(10) - .valueMarshaller(new MarshallableReaderWriter<>(Bar2.class)) .create(); String expected = IntStream.range(0, 4096)