diff --git a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java index a09c46587..101150f8e 100644 --- a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java @@ -22,8 +22,6 @@ import net.openhft.chronicle.hash.*; import net.openhft.chronicle.hash.serialization.MetaBytesInterop; import net.openhft.chronicle.hash.serialization.MetaBytesWriter; import net.openhft.chronicle.hash.serialization.MetaProvider; -import net.openhft.lang.threadlocal.Provider; -import net.openhft.lang.threadlocal.ThreadLocalCopies; import net.openhft.chronicle.set.ChronicleSetBuilder; import net.openhft.lang.Maths; import net.openhft.lang.io.ByteBufferBytes; @@ -35,6 +33,8 @@ 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.Byteable; +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; @@ -48,18 +48,18 @@ import java.util.concurrent.TimeUnit; import static net.openhft.chronicle.map.Objects.builderEquals; /** - * {@code AbstractChronicleMapBuilder} manages most of {@link ChronicleMap} configurations; has two - * concrete subclasses: {@link ChronicleMapBuilder} should be used to create maps with ordinary - * values, {@link OffHeapUpdatableChronicleMapBuilder} -- maps with {@link Byteable} values, which - * point directly to off-heap memory; could be used as a classic builder and/or factory. This means + * {@code AbstractChronicleMapBuilder} manages most of {@link ChronicleMap} configurations; has two concrete subclasses: + * {@link ChronicleMapBuilder} should be used to create maps with ordinary values, {@link + * OffHeapUpdatableChronicleMapBuilder} -- maps with {@link Byteable} values, which point directly to off-heap memory; + * could be used as a classic builder and/or factory. This means * that in addition to the standard builder usage pattern:
{@code
* ChronicleMap map = ChronicleMapBuilder
* .of(Key.class, Value.class)
* .entries(100500)
* // ... other configurations
* .create();}
- * one of concrete {@code AbstractChronicleMapBuilder} subclasses, {@link ChronicleMapBuilder} or
- * {@link OffHeapUpdatableChronicleMapBuilder}, could be prepared and used to create many similar
+ * one of concrete {@code AbstractChronicleMapBuilder} subclasses, {@link ChronicleMapBuilder} or {@link
+ * OffHeapUpdatableChronicleMapBuilder}, could be prepared and used to create many similar
* maps: {@code
* OffHeapUpdatableChronicleMapBuilder builder = OffHeapUpdatableChronicleMapBuilder
* .of(Key.class, Value.class)
@@ -69,22 +69,22 @@ import static net.openhft.chronicle.map.Objects.builderEquals;
* ChronicleMap map2 = builder.create();}
* i. e. created {@code ChronicleMap} instances don't depend on the builder.
*
- * {@code AbstractChronicleMapBuilder} and it's subclasses are mutable, see a note in - * {@link ChronicleHashBuilder} interface documentation. - * - *
Later in this documentation, "ChronicleMap" means "ChronicleMaps, created by {@code - * AbstractChronicleMapBuilder}", unless specified different, because theoretically someone might - * provide {@code ChronicleMap} implementations with completely different properties. - * - *
{@code ChronicleMap} ("ChronicleMaps, created by {@code AbstractChronicleMapBuilder}") - * currently doesn't support resizing. That is why you should always configure {@linkplain - * #entries(long) number of entries} you are going to insert into the created map at most. - * See {@link #entries(long)} method documentation for more information on this. - * - *
{@code ChronicleMap} allocates memory by equally sized chunks. This size is called {@linkplain - * #entrySize(int) entry size}, you are strongly recommended to configure it to achieve least memory - * consumption and best speed. See {@link #entrySize(int)} method documentation for more information + *
{@code AbstractChronicleMapBuilder} and it's subclasses are mutable, see a note in {@link ChronicleHashBuilder} + * interface documentation. + *
+ *Later in this documentation, "ChronicleMap" means "ChronicleMaps, created by {@code AbstractChronicleMapBuilder}", + * unless specified different, because theoretically someone might provide {@code ChronicleMap} implementations with + * completely different properties. + *
+ *{@code ChronicleMap} ("ChronicleMaps, created by {@code AbstractChronicleMapBuilder}") currently doesn't support + * resizing. That is why you should always configure {@linkplain #entries(long) number of entries} you are going + * to insert into the created map at most. See {@link #entries(long)} method documentation for more information * on this. + *
+ *{@code ChronicleMap} allocates memory by equally sized chunks. This size is called {@linkplain #entrySize(int) + * entry size}, you are strongly recommended to configure it to achieve least memory consumption and best speed. See + * {@link #entrySize(int)} method documentation for more information on this. + *
* * @paramIf entry size is not configured explicitly by calling this method, it is computed based on - * {@linkplain #metaDataBytes(int) meta data bytes}, plus {@linkplain #keySize(int) key size}, - * plus {@linkplain #valueSize(int) value size}, plus a few bytes required by implementations. + *
In fully default case you can expect entry size to be about 256 bytes. But it is strongly recommended always + * to configure {@linkplain #keySize(int) key size} and {@linkplain #valueSize(int) value size}, if they couldn't be + * derived statically.
If entry size is not configured explicitly by calling this method, it is computed + * based on {@linkplain #metaDataBytes(int) meta data bytes}, plus {@linkplain #keySize(int) key size}, plus + * {@linkplain #valueSize(int) value size}, plus a few bytes required by implementations.
* * @see #entries(long) */ @@ -350,8 +366,8 @@ public abstract class AbstractChronicleMapBuilder{@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
- * instead return {@code null}
+ * @param putReturnsNull {@code true} if you want {@link ChronicleMap#put(Object, Object) ChronicleMap.put()} to not
+ * return the value that was replaced but instead return {@code null}
* @return an instance of the map builder back
* @see #removeReturnsNull(boolean)
*/
@@ -474,17 +478,16 @@ public abstract class AbstractChronicleMapBuilder {@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.
+ * 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 internally delegates to instance pool or {@link ThreadLocal}, to reduce
+ * allocations.
+ * This configuration overrides any previous {@link #defaultValueProvider(DefaultValueProvider)} configuration
+ * to this {@code AbstractChronicleMapBuilder}.
+ * This configuration overrides any previous {@link #defaultValue(Object)} configuration to this {@code
+ * AbstractChronicleMapBuilder}.
+ * The entry will only be removed if {@code expectedValue} equals to {@code null} or the
- * value previously corresponding to the specified key.
+ * The entry will only be removed if {@code expectedValue} equals to {@code null} or the value previously
+ * corresponding to the specified key.
*
* @param hash2 a hash code related to the {@code keyBytes}
- * @return the value of the entry that was removed if the entry corresponding to the {@code
- * keyBytes} exists and {@link #removeReturnsNull} is {@code false}, {@code null} otherwise
+ * @return the value of the entry that was removed if the entry corresponding to the {@code keyBytes} exists and
+ * {@link #removeReturnsNull} is {@code false}, {@code null} otherwise
*/
V remove(ThreadLocalCopies copies, MKI metaKeyInterop, KI keyInterop, K key,
V expectedValue, long hash2) {
@@ -1052,9 +1061,8 @@ class VanillaChronicleMap