diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index ebf938d2c..b23d1d9a2 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -20,12 +20,7 @@ package net.openhft.chronicle.map; import net.openhft.chronicle.hash.*; import net.openhft.chronicle.hash.replication.*; -import net.openhft.chronicle.hash.serialization.BytesInterop; -import net.openhft.chronicle.hash.serialization.BytesReader; -import net.openhft.chronicle.hash.serialization.BytesWriter; -import net.openhft.chronicle.hash.serialization.DeserializationFactoryConfigurableBytesReader; -import net.openhft.chronicle.hash.serialization.SizeMarshaller; -import net.openhft.chronicle.hash.serialization.SizeMarshallers; +import net.openhft.chronicle.hash.serialization.*; import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop; import net.openhft.chronicle.hash.serialization.internal.MetaBytesWriter; import net.openhft.chronicle.hash.serialization.internal.MetaProvider; @@ -38,7 +33,7 @@ import net.openhft.lang.io.serialization.*; import net.openhft.lang.io.serialization.impl.AllocateInstanceObjectFactory; import net.openhft.lang.io.serialization.impl.NewInstanceObjectFactory; import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory; -import net.openhft.lang.model.*; +import net.openhft.lang.model.Byteable; import net.openhft.lang.threadlocal.Provider; import net.openhft.lang.threadlocal.ThreadLocalCopies; import org.jetbrains.annotations.NotNull; @@ -59,8 +54,8 @@ import static net.openhft.chronicle.map.Objects.builderEquals; import static net.openhft.lang.model.DataValueGenerator.firstPrimitiveFieldType; /** - * {@code ChronicleMapBuilder} manages {@link ChronicleMap} configurations; could be used as - * a classic builder and/or factory. This means that in addition to the standard builder usage + * {@code ChronicleMapBuilder} manages {@link ChronicleMap} configurations; could be used as a + * classic builder and/or factory. This means that in addition to the standard builder usage * pattern:
{@code
* ChronicleMap map = ChronicleMapOnHeapUpdatableBuilder
* .of(Key.class, Value.class)
@@ -79,9 +74,9 @@ import static net.openhft.lang.model.DataValueGenerator.firstPrimitiveFieldType;
* {@code ChronicleMapBuilder} is mutable, see a note in {@link ChronicleHashBuilder} interface
* documentation.
*
- *
Later in this documentation, "ChronicleMap" means "ChronicleMaps, created by
- * {@code ChronicleMapBuilder}", unless specified different, because theoretically someone might
- * provide {@code ChronicleMap} implementations with completely different properties.
+ *
Later in this documentation, "ChronicleMap" means "ChronicleMaps, created by {@code
+ * ChronicleMapBuilder}", unless specified different, because theoretically someone might provide
+ * {@code ChronicleMap} implementations with completely different properties.
*
*
{@code ChronicleMap} ("ChronicleMaps, created by {@code ChronicleMapBuilder}") currently
* doesn't support resizing. That is why you should always configure {@linkplain
@@ -101,7 +96,7 @@ import static net.openhft.lang.model.DataValueGenerator.firstPrimitiveFieldType;
public final class ChronicleMapBuilder implements Cloneable,
ChronicleHashBuilder, ChronicleMapBuilder>, Serializable {
- static final byte UDP_REPLICATION_MODIFICATION_ITERATOR_ID = (byte)128;
+ static final byte UDP_REPLICATION_MODIFICATION_ITERATOR_ID = (byte) 128;
private static final int DEFAULT_KEY_OR_VALUE_SIZE = 120;
private static final int MAX_SEGMENTS = (1 << 30);
private static final int MAX_SEGMENTS_TO_CHAISE_COMPACT_MULTI_MAPS = (1 << 20);
@@ -150,16 +145,21 @@ public final class ChronicleMapBuilder implements Cloneable,
ChronicleMapBuilder(Class keyClass, Class valueClass) {
keyBuilder = new SerializationBuilder<>(keyClass, SerializationBuilder.Role.KEY);
valueBuilder = new SerializationBuilder<>(valueClass, SerializationBuilder.Role.VALUE);
+
+ if (String.class.isAssignableFrom(valueClass)) {
+ defaultValue = (V) "";
+ this.defaultValueProvider = null;
+ }
}
/**
* Returns a new {@code ChronicleMapBuilder} instance which is able to {@linkplain #create()
* create} maps with the specified key and value classes.
*
- * @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 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
@@ -228,10 +228,10 @@ public final class ChronicleMapBuilder implements Cloneable,
* // shouldn't specify valueSize(), because it is statically known
* .create();}
* (Note that 10 is chosen as key size in bytes despite strings in Java are UTF-16 encoded (and
- * each character takes 2 bytes on-heap), because default off-heap {@link String} encoding
- * is UTF-8 in {@code ChronicleMap}.)
+ * each character takes 2 bytes on-heap), because default off-heap {@link String} encoding is
+ * UTF-8 in {@code ChronicleMap}.)
*
- * @throws IllegalStateException {@inheritDoc}
+ * @throws IllegalStateException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see #constantKeySizeBySample(Object)
* @see #valueSize(int)
@@ -274,8 +274,8 @@ public final class ChronicleMapBuilderIf values are of boxed primitive type or {@link Byteable} subclass, i. e. if value size - * is known statically, it is automatically accounted and shouldn't be specified by user. + *
If values are of boxed primitive type or {@link Byteable} subclass, i. e. if value size is + * known statically, it is automatically accounted and shouldn't be specified by user. * *
If value size varies moderately, specify the size higher than average, but lower than the
* maximum possible, to minimize average memory overuse. If value size varies in a wide range,
@@ -284,8 +284,8 @@ public final class ChronicleMapBuilder If values are of boxed primitive type or {@link Byteable} subclass, i. e. if value size
- * is known statically, it is automatically accounted and this method shouldn't be called.
+ * If values are of boxed primitive type or {@link Byteable} subclass, i. e. if value size is
+ * known statically, it is automatically accounted and this method shouldn't be called.
*
* If value size varies, method {@link #valueSize(int)} or {@link #entrySize(int)} should be
* called instead of this one.
@@ -351,12 +351,13 @@ public final class ChronicleMapBuilder Note that the actual entrySize will be aligned by the configured {@linkplain
- * #entryAndValueAlignment(Alignment) entry and value alignment}. I. e. if you set entry size
- * to 30, and entry alignment is set to {@link Alignment#OF_4_BYTES}, the actual entry size will
- * be 32 (30 aligned to 4 bytes).
+ * #entryAndValueAlignment(Alignment) entry and value alignment}. I. e. if you set entry size to
+ * 30, and entry alignment is set to {@link Alignment#OF_4_BYTES}, the actual entry size will be
+ * 32 (30 aligned to 4 bytes).
*
* @throws IllegalStateException is sizes of both keys and values of maps created by this
- * builder are statically known, hence entry size shouldn't be configured by user
+ * builder are statically known, hence entry size shouldn't be
+ * configured by user
* @see #entryAndValueAlignment(Alignment)
* @see #entries(long)
* @see #maxEntryOversizeFactor(int)
@@ -430,8 +431,8 @@ public final class ChronicleMapBuilder If values couldn't reference off-heap memory (i. e. it is not {@link Byteable} or
- * "data value generated"), alignment configuration makes no sense and forbidden.
+ * If values couldn't reference off-heap memory (i. e. it is not {@link Byteable} or "data
+ * value generated"), alignment configuration makes no sense and forbidden.
*
* Default is {@link Alignment#NO_ALIGNMENT} if values couldn't reference off-heap memory,
* otherwise chosen heuristically (configure explicitly for being sure and to compare
@@ -440,7 +441,7 @@ public final class ChronicleMapBuilder {@link Map#put(Object, Object) Map.put()} returns the previous value, functionality which
* is rarely used but fairly cheap for {@link HashMap}. In the case, for an off heap collection,
* it has to create a new object and deserialize the data from off-heap memory. It's expensive
* for something you probably don't use.
*
- * By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract
- * and returns the previous mapped value on {@code put()} calls.
+ * By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract and
+ * returns the previous mapped value on {@code put()} calls.
*
* @param putReturnsNull {@code true} if you want {@link ChronicleMap#put(Object, Object)
* ChronicleMap.put()} to not return the value that was replaced but
@@ -643,12 +645,12 @@ public final class ChronicleMapBuilder {@link Map#remove(Object) Map.remove()} returns the previous value, functionality which is
- * rarely used but fairly cheap for {@link HashMap}. In the case, for an off heap collection,
- * it has to create a new object and deserialize the data from off-heap memory. It's expensive
- * for something you probably don't use.
+ * rarely used but fairly cheap for {@link HashMap}. In the case, for an off heap collection, it
+ * has to create a new object and deserialize the data from off-heap memory. It's expensive for
+ * something you probably don't use.
*
- * By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract
- * and returns the mapped value on {@code remove()} calls.
+ * By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract and
+ * returns the mapped value on {@code remove()} calls.
*
* @param removeReturnsNull {@code true} if you want {@link ChronicleMap#remove(Object)
* ChronicleMap.remove()} to not return the value of the removed entry
@@ -809,9 +811,8 @@ public final class ChronicleMapBuilder Configuring marshalling this way results to a little bit more compact in-memory layout
- * of the map, comparing to a single interface configuration: {@link #valueMarshaller(
- * BytesMarshaller)}.
+ * Configuring marshalling this way results to a little bit more compact in-memory layout of
+ * the map, comparing to a single interface configuration: {@link #valueMarshaller(
+ *BytesMarshaller)}.
*
* Passing {@link BytesInterop} instead of plain {@link BytesWriter} is, of cause, possible,
* but currently pointless for values.
@@ -861,8 +861,8 @@ public final class ChronicleMapBuilder Default value deserialization factory is {@link NewInstanceObjectFactory}, which creates
- * a new value instance using {@link Class#newInstance()} default constructor. You could provide
+ * Default value deserialization factory is {@link NewInstanceObjectFactory}, which creates a
+ * new value instance using {@link Class#newInstance()} default constructor. You could provide
* an {@link AllocateInstanceObjectFactory}, which uses {@code Unsafe.allocateInstance(Class)}
* (you might want to do this for better performance or if you don't want to initialize fields),
* or a factory which calls a value class constructor with some arguments, or a factory which
@@ -888,8 +888,8 @@ public final class ChronicleMapBuilder This configuration overrides any previous {@link #defaultValueProvider(
- * DefaultValueProvider)} and {@link #prepareDefaultValueBytes(PrepareValueBytes)}
+ *DefaultValueProvider)} and {@link #prepareDefaultValueBytes(PrepareValueBytes)}
* configurations to this builder.
*
* @param defaultValue the default value to be put to the map for absent keys during {@code
@@ -975,8 +975,8 @@ public final class ChronicleMapBuilder The default preparation callback zeroes out the value bytes.
*
* @param prepareValueBytes what to do with the value bytes before assigning them into the
- * {@link Byteable} value or deserializing the value from,
- * to return from {@code acquireUsing()} call
+ * {@link Byteable} value or deserializing the value from, to return
+ * from {@code acquireUsing()} call
* @return this builder back
* @throws IllegalStateException is value size is not constant
* @see PrepareValueBytes
@@ -995,7 +995,7 @@ public final class ChronicleMapBuilder