diff --git a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java index c7cfe7fac..7aaed90a9 100644 --- a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java @@ -57,7 +57,7 @@ import static net.openhft.chronicle.map.Objects.builderEquals; /** * {@code AbstractChronicleMapBuilder} manages most of {@link ChronicleMap} configurations; has two concrete - * subclasses: {@link ChronicleMapOnHeapUpdatableBuilder} should be used to create maps with ordinary values, {@link + * subclasses: {@link OnHeapUpdatableChronicleMapBuilder} should be used to create maps with ordinary values, {@link * ChronicleMapBuilder} -- 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
@@ -66,7 +66,7 @@ import static net.openhft.chronicle.map.Objects.builderEquals;
* .entries(100500)
* // ... other configurations
* .create();}
- * one of concrete {@code AbstractChronicleMapBuilder} subclasses, {@link ChronicleMapOnHeapUpdatableBuilder} or {@link
+ * one of concrete {@code AbstractChronicleMapBuilder} subclasses, {@link OnHeapUpdatableChronicleMapBuilder} or {@link
* ChronicleMapBuilder}, could be prepared and used to create many similar
* maps: {@code
* ChronicleMapBuilder builder = ChronicleMapBuilder
@@ -227,7 +227,7 @@ public abstract class AbstractChronicleMapBuilderFor example, if your keys are Git commit hashes:{@code
* Map gitCommitMessagesByHash =
- * ChronicleMapOnHeapUpdatableBuilder.of(byte[].class, String.class)
+ * ChronicleMapBuilder.of(byte[].class, String.class)
* .constantKeySizeBySample(new byte[20])
* .create();}
*
@@ -839,12 +839,10 @@ public abstract class AbstractChronicleMapBuilder createReplicated(byte identifier) throws IOException {
+ public ChronicleMap createReplicated(byte identifier) throws IOException {
preMapConstruction(true);
VanillaChronicleMap map =
new ReplicatedChronicleMap,
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
index 0a0066f03..4bc5d71ed 100644
--- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
+++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
@@ -93,7 +93,7 @@ public interface ChronicleMap extends ConcurrentMap, ChronicleHash {
* for the key
* @see #get(Object)
* @see #acquireUsing(Object, Object)
- * @see ChronicleMapOnHeapUpdatableBuilder#valueMarshaller(BytesMarshaller)
+ * @see OnHeapUpdatableChronicleMapBuilder#valueMarshaller(BytesMarshaller)
*/
V getUsing(K key, V usingValue);
@@ -134,7 +134,7 @@ public interface ChronicleMap extends ConcurrentMap, ChronicleHash {
* no mapping for the key
* @see #get(Object)
* @see #getUsing(Object, Object)
- * @see ChronicleMapOnHeapUpdatableBuilder#valueMarshaller(BytesMarshaller)
+ * @see OnHeapUpdatableChronicleMapBuilder#valueMarshaller(BytesMarshaller)
*/
@NotNull
ReadContext getUsingLocked(@NotNull K key, @NotNull V usingValue);
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
index 8d28b4966..6f3c4d73a 100644
--- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
+++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
@@ -1,80 +1,109 @@
-/*
- * Copyright 2014 Higher Frequency Trading http://www.higherfrequencytrading.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package net.openhft.chronicle.map;
+import net.openhft.chronicle.hash.ChronicleHashErrorListener;
+import net.openhft.chronicle.hash.ChronicleHashInstanceConfig;
+import net.openhft.chronicle.hash.StatelessClientConfig;
+import net.openhft.chronicle.hash.replication.SingleChronicleHashReplication;
+import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig;
+import net.openhft.chronicle.hash.replication.TimeProvider;
+import net.openhft.chronicle.hash.serialization.BytesReader;
+import net.openhft.chronicle.hash.serialization.BytesWriter;
+import net.openhft.chronicle.hash.serialization.SizeMarshaller;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.io.serialization.BytesMarshallerFactory;
+import net.openhft.lang.io.serialization.ObjectFactory;
+import net.openhft.lang.io.serialization.ObjectSerializer;
import net.openhft.lang.model.Byteable;
import net.openhft.lang.model.DataValueClasses;
import org.jetbrains.annotations.NotNull;
-public final class ChronicleMapBuilder
- extends AbstractChronicleMapBuilder> {
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+/**
+ * {@code ChronicleMapBuilder} is intended to be used to create {@link ChronicleMap}s
+ *
+ * @param key type of the maps, created by this builder
+ * @param value type of the maps, created by this builder
+ * @see AbstractChronicleMapBuilder
+ * @see net.openhft.chronicle.hash.ChronicleHashBuilder
+ */
+public final class ChronicleMapBuilder implements ChronicleMapBuilderI {
+
+ final ChronicleMapBuilderI delegate;
+
+ /**
+ * Returns a new {@code ChronicleMapBuilder} instance which is able to {@linkplain #create() create} maps
+ * with the specified key and value classes.
+ *
+ * {@code ChronicleMapBuilder} analyzes provided key and value classes and automatically chooses the
+ * most specific internal builder.
+ *
+ * @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 of(
@NotNull Class keyClass, @NotNull Class valueClass) {
+
+ if (valueClass.isEnum())
+ return new ChronicleMapBuilder(OnHeapUpdatableChronicleMapBuilder.of(keyClass, valueClass));
+
if (keyClass.isInterface() && keyClass != CharSequence.class) {
keyClass = DataValueClasses.directClassFor(keyClass);
}
- if (valueClass.isInterface()) {
+
+ if ((valueClass.isInterface() && valueClass != CharSequence.class)) {
valueClass = DataValueClasses.directClassFor(valueClass);
} else if (!offHeapReference(valueClass)) {
- throw new IllegalArgumentException(
- "Value class should be either Byteable subclass or interface," +
- "allowing direct Byteable implementation generation");
+ return new ChronicleMapBuilder(OnHeapUpdatableChronicleMapBuilder.of(keyClass, valueClass));
}
- return new ChronicleMapBuilder(keyClass, valueClass);
+ OffHeapUpdatableChronicleMapBuilder kvOffHeapUpdatableChronicleMapBuilder = new
+ OffHeapUpdatableChronicleMapBuilder(keyClass, valueClass);
+ return new ChronicleMapBuilder(kvOffHeapUpdatableChronicleMapBuilder);
}
- ChronicleMapBuilder(Class keyClass, Class valueClass) {
- super(keyClass, valueClass);
- prepareValueBytesOnAcquire(new ZeroOutValueBytes(valueSize()));
+ ChronicleMapBuilder(ChronicleMapBuilderI delegate) {
+ this.delegate = delegate;
}
- @Override
- ChronicleMapBuilder self() {
- return this;
+
+ private static boolean offHeapReference(Class valueClass) {
+ return Byteable.class.isAssignableFrom(valueClass);
}
+
/**
* {@inheritDoc} With respect to {@linkplain #entryAndValueAlignment(Alignment) alignment}.
*
* Note that the actual entrySize will be aligned to 4 (default {@linkplain
- * #entryAndValueAlignment(Alignment) entry 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 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).
*
- * @see #entryAndValueAlignment(Alignment)
- * @see #entries(long)
+ * @see #entryAndValueAlignment(Alignment) // * @see #entries(long)
*/
@Override
public ChronicleMapBuilder entrySize(int entrySize) {
- return super.entrySize(entrySize);
+ delegate.entrySize(entrySize);
+ return this;
}
/**
- * Configures alignment strategy of address in memory of entries and independently of address in
- * memory of values within entries in ChronicleMaps, created by this builder.
+ * Configures alignment strategy of address in memory of entries and independently of address in memory of
+ * values within entries in ChronicleMaps, created by this builder.
*
- * Useful when values of the map are updated intensively, particularly fields with volatile
- * access, because it doesn't work well if the value crosses cache lines. Also, on some
- * (nowadays rare) architectures any misaligned memory access is more expensive than aligned.
+ *
Useful when values of the map are updated intensively, particularly fields with volatile access,
+ * because it doesn't work well if the value crosses cache lines. Also, on some (nowadays rare)
+ * architectures any misaligned memory access is more expensive than aligned.
*
- *
Note that {@linkplain #entrySize(int) entry size} will be aligned according to this
- * alignment. I. e. if you set {@code entrySize(20)} and {@link Alignment#OF_8_BYTES}, actual
- * entry size will be 24 (20 aligned to 8 bytes).
+ *
Note that {@linkplain #entrySize(int) entry size} will be aligned according to this alignment. I. e.
+ * if you set {@code entrySize(20)} and {@link Alignment#OF_8_BYTES}, actual entry size will be 24 (20
+ * aligned to 8 bytes).
*
*
Default is {@link Alignment#OF_4_BYTES} for Byteable values.
*
@@ -83,58 +112,369 @@ public final class ChronicleMapBuilder
*/
@Override
public ChronicleMapBuilder entryAndValueAlignment(Alignment alignment) {
- return super.entryAndValueAlignment(alignment);
+ delegate.entryAndValueAlignment(alignment);
+ return this;
}
/**
- * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire}
- * configuration to this {@code ChronicleMapBuilder}.
+ * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire} configuration to this
+ * {@code ChronicleMapBuilder}.
*
- * By default, the default value is not specified, default {@linkplain
- * #prepareValueBytesOnAcquire prepare value bytes routine} is specified instead.
+ *
By default, the default value is not specified, default {@linkplain #prepareValueBytesOnAcquire
+ * prepare value bytes routine} is specified instead.
*
* @see #defaultValueProvider(DefaultValueProvider)
* @see #prepareValueBytesOnAcquire(PrepareValueBytes)
*/
@Override
public ChronicleMapBuilder defaultValue(V defaultValue) {
- return super.defaultValue(defaultValue);
+ delegate.defaultValue(defaultValue);
+ return this;
}
/**
- * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire}
- * configuration to this {@code ChronicleMapBuilder}.
- *
- * By default, the default value provider is not specified, default {@linkplain
- * #prepareValueBytesOnAcquire prepare value bytes routine} is specified instead.
- *
- * @see #defaultValue(Object)
- * @see #prepareValueBytesOnAcquire(PrepareValueBytes)
- */
- @Override
- public ChronicleMapBuilder defaultValueProvider(
- @NotNull DefaultValueProvider defaultValueProvider) {
- return super.defaultValueProvider(defaultValueProvider);
- }
-
- /**
- * Configures the procedure which is called on the bytes, which later the returned value is
- * pointing to, if the key is absent, on {@link ChronicleMap#acquireUsing(Object, Object)
- * acquireUsing()} call on maps, created by this builder. See {@link PrepareValueBytes} for
- * more information.
+ * Configures the procedure which is called on the bytes, which later the returned value is pointing to,
+ * if the key is absent, on {@link ChronicleMap#acquireUsing(Object, Object) acquireUsing()} call on maps,
+ * created by this builder. See {@link PrepareValueBytes} for more information.
*
* 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 to return from {@code acquireUsing()} call
+ * @param prepareValueBytes what to do with the value bytes before assigning them into the {@link
+ * net.openhft.lang.model.Byteable} value to return from {@code acquireUsing()}
+ * call
* @return this builder back
* @see PrepareValueBytes
* @see #defaultValue(Object)
* @see #defaultValueProvider(DefaultValueProvider)
*/
@Override
- public ChronicleMapBuilder prepareValueBytesOnAcquire(
- @NotNull PrepareValueBytes prepareValueBytes) {
- return super.prepareValueBytesOnAcquire(prepareValueBytes);
+ public ChronicleMapBuilder prepareValueBytesOnAcquire(@NotNull PrepareValueBytes prepareValueBytes) {
+ delegate.prepareValueBytesOnAcquire(prepareValueBytes);
+ return this;
}
+
+
+ @Override
+ public ChronicleMapBuilder keySize(int keySize) {
+ delegate.keySize(keySize);
+ return this;
+ }
+
+
+ @Override
+ public ChronicleMapBuilder constantKeySizeBySample(K sampleKey) {
+ delegate.constantKeySizeBySample(sampleKey);
+ return this;
+ }
+
+ /**
+ * Configures the optimal number of bytes, taken by serialized form of values, put into maps, created by
+ * this builder. If value size is always the same, call {@link #constantValueSizeBySample(Object)} method
+ * instead of this one.
+ *
+ * If value is a boxed primitive type, 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, it's better to use
+ * {@linkplain #entrySize(int) entry size} in "chunk" mode and configure it directly.
+ *
+ * @param valueSize number of bytes, taken by serialized form of values
+ * @return this {@code ChronicleMapOnHeapUpdatableBuilder} back
+ * @see #constantValueSizeBySample(Object)
+ * @see #keySize(int)
+ * @see #entrySize(int)
+ */
+ @Override
+ public ChronicleMapBuilder valueSize(int valueSize) {
+ delegate.valueSize(valueSize);
+ return this;
+ }
+
+ /**
+ * Configures the constant number of bytes, taken by serialized form of values, put into maps, created by
+ * this builder. This is done by providing the {@code sampleValue}, all values should take the same number
+ * of bytes in serialized form, as this sample object.
+ *
+ * If values are of boxed primitive type or {@link net.openhft.lang.model.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.
+ *
+ * @param sampleValue the sample value
+ * @return this builder back
+ * @see #valueSize(int)
+ * @see #constantKeySizeBySample(Object)
+ */
+ @Override
+ public ChronicleMapBuilder constantValueSizeBySample(@NotNull V sampleValue) {
+ delegate.constantValueSizeBySample(sampleValue);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Example:
{@code Map map =
+ * ChronicleMapBuilder.of(Key.class, Value.class)
+ * .entries(1_000_000)
+ * .keySize(50).valueSize(200)
+ * // this class hasn't implemented yet, just for example
+ * .objectSerializer(new KryoObjectSerializer())
+ * .create();}
+ */
+ @Override
+ public ChronicleMapBuilder objectSerializer(@NotNull ObjectSerializer objectSerializer) {
+ delegate.objectSerializer(objectSerializer);
+ return this;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if custom value marshaller is specified or value class is not either
+ * {@code BytesMarshallable} or {@code Externalizable}
+ */
+
+ @Override
+ public ChronicleMapBuilder valueDeserializationFactory(@NotNull ObjectFactory valueDeserializationFactory) {
+ delegate.valueDeserializationFactory(valueDeserializationFactory);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * By default, default value provider is not specified, {@link #defaultValue(Object) default value} is
+ * specified instead.
+ *
+ * @see #defaultValue(Object)
+ */
+ @Override
+ public ChronicleMapBuilder defaultValueProvider(@NotNull DefaultValueProvider defaultValueProvider) {
+ delegate.defaultValueProvider(defaultValueProvider);
+ return this;
+ }
+
+ /**
+ * Configures the {@code BytesMarshaller} used to serialize/deserialize values to/from off-heap memory in
+ * maps, created by this builder. See the
+ * section about serialization in ChronicleMap manual for more information.
+ *
+ * @param valueMarshaller the marshaller used to serialize values
+ * @return this builder back
+ * @see #valueMarshallers(net.openhft.chronicle.hash.serialization.BytesWriter,
+ * net.openhft.chronicle.hash.serialization.BytesReader)
+ * @see ChronicleMapBuilder
+ * @see #objectSerializer(ObjectSerializer)
+ */
+ @Override
+ public ChronicleMapBuilder valueMarshaller(
+ @NotNull BytesMarshaller valueMarshaller) {
+ delegate.valueMarshaller(valueMarshaller);
+ return this;
+ }
+
+ /**
+ * Configures the marshallers, used to serialize/deserialize values to/from off-heap memory in maps,
+ * created by this builder. See the
+ * section about serialization in ChronicleMap manual for more information.
+ *
+ * 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 net.openhft.chronicle.hash.serialization.BytesInterop} instead of plain {@link
+ * net.openhft.chronicle.hash.serialization.BytesWriter} is, of cause, possible, but currently pointless
+ * for values.
+ *
+ * @param valueWriter the new value object → {@link net.openhft.lang.io.Bytes} writer (interop)
+ * strategy
+ * @param valueReader the new {@link net.openhft.lang.io.Bytes} → value object reader strategy
+ * @return this builder back
+ * @see #valueMarshaller(BytesMarshaller)
+ */
+ @Override
+ public ChronicleMapBuilder valueMarshallers(@NotNull BytesWriter valueWriter, @NotNull BytesReader valueReader) {
+ delegate.valueMarshallers(valueWriter, valueReader);
+ return this;
+ }
+
+
+ /**
+ * Configures the marshaller used to serialize actual value sizes to off-heap memory in maps, created by
+ * this builder.
+ *
+ * Default value size marshaller is so-called {@linkplain net.openhft.chronicle.hash.serialization.SizeMarshallers#stopBit()
+ * stop bit encoding marshalling}. If {@linkplain #constantValueSizeBySample(Object) constant value size}
+ * is configured, or defaulted if the value type is always constant and {@code ChronicleHashBuilder}
+ * implementation knows about it, this configuration takes no effect, because a special {@link
+ * net.openhft.chronicle.hash.serialization.SizeMarshaller} implementation, which doesn't actually do any
+ * marshalling, and just returns the known constant size on {@link net.openhft.chronicle.hash.serialization.SizeMarshaller#readSize(
+ *net.openhft.lang.io.Bytes)} calls, is used instead of any {@code SizeMarshaller} configured using this
+ * method.
+ *
+ * @param valueSizeMarshaller the new marshaller, used to serialize actual value sizes to off-heap memory
+ * @return this builder back
+ */
+ @Override
+ public ChronicleMapBuilder valueSizeMarshaller(@NotNull SizeMarshaller valueSizeMarshaller) {
+ delegate.valueSizeMarshaller(valueSizeMarshaller);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder entries(long l) {
+ delegate.entries(l);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder replication(SingleChronicleHashReplication withId) {
+ delegate.replication(withId);
+ return this;
+
+ }
+
+ @Override
+ public ChronicleMap create() throws IOException {
+ return delegate.create();
+ }
+
+ @Override
+ public ChronicleMapBuilder actualSegments(int actualSegments) {
+ delegate.actualSegments(actualSegments);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder minSegments(int minSegments) {
+ delegate.minSegments(minSegments);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder actualEntriesPerSegment(long actualEntriesPerSegment) {
+ delegate.actualEntriesPerSegment(actualEntriesPerSegment);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder lockTimeOut(long lockTimeOut, TimeUnit unit) {
+ delegate.lockTimeOut(lockTimeOut, unit);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder errorListener(ChronicleHashErrorListener errorListener) {
+ delegate.errorListener(errorListener);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder metaDataBytes(int metaDataBytes) {
+ delegate.metaDataBytes(metaDataBytes);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder timeProvider(TimeProvider timeProvider) {
+ delegate.timeProvider(timeProvider);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder bytesMarshallerFactory(BytesMarshallerFactory bytesMarshallerFactory) {
+ delegate.bytesMarshallerFactory(bytesMarshallerFactory);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder keyMarshaller(BytesMarshaller keyMarshaller) {
+ delegate.keyMarshaller(keyMarshaller);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder keyMarshallers(BytesWriter keyWriter, BytesReader keyReader) {
+ delegate.keyMarshallers(keyWriter, keyReader);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder keySizeMarshaller(SizeMarshaller keySizeMarshaller) {
+ delegate.keySizeMarshaller(keySizeMarshaller);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder keyDeserializationFactory(ObjectFactory keyDeserializationFactory) {
+ delegate.keyDeserializationFactory(keyDeserializationFactory);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder immutableKeys() {
+ delegate.immutableKeys();
+ return this;
+ }
+
+
+ @Override
+ public StatelessClientConfig> statelessClient(InetSocketAddress remoteAddress) {
+ return delegate.statelessClient(remoteAddress);
+ }
+
+ @Override
+ public ChronicleHashInstanceConfig> instance() {
+ return delegate.instance();
+ }
+
+ @Override
+ public ChronicleMapBuilder replication(byte identifier) {
+ delegate.replication(identifier);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder replication(byte identifier, TcpTransportAndNetworkConfig tcpTransportAndNetwork) {
+ delegate.replication(identifier, tcpTransportAndNetwork);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder clone() {
+ delegate.clone();
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder putReturnsNull(boolean b) {
+ delegate.putReturnsNull(b);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder removeReturnsNull(boolean b) {
+ delegate.removeReturnsNull(b);
+ return this;
+ }
+
+ @Override
+ public ChronicleMapBuilder eventListener(MapEventListener> eventListener) {
+ delegate.eventListener(eventListener);
+ return this;
+ }
+
+ @Override
+ public ChronicleMap createReplicated(byte b) throws IOException {
+ return delegate.createReplicated(b);
+ }
+
+ @Override
+ public ChronicleMap createPersistedTo(File file) throws IOException {
+ return delegate.createPersistedTo(file);
+ }
+
}
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilderI.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilderI.java
new file mode 100644
index 000000000..f121b6c7e
--- /dev/null
+++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilderI.java
@@ -0,0 +1,299 @@
+package net.openhft.chronicle.map;
+
+import net.openhft.chronicle.hash.ChronicleHashErrorListener;
+import net.openhft.chronicle.hash.ChronicleHashInstanceConfig;
+import net.openhft.chronicle.hash.StatelessClientConfig;
+import net.openhft.chronicle.hash.replication.SingleChronicleHashReplication;
+import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig;
+import net.openhft.chronicle.hash.replication.TimeProvider;
+import net.openhft.chronicle.hash.serialization.BytesReader;
+import net.openhft.chronicle.hash.serialization.BytesWriter;
+import net.openhft.chronicle.hash.serialization.SizeMarshaller;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.io.serialization.BytesMarshallerFactory;
+import net.openhft.lang.io.serialization.ObjectFactory;
+import net.openhft.lang.io.serialization.ObjectSerializer;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Rob Austin.
+ */
+interface ChronicleMapBuilderI {
+
+
+ /**
+ * {@inheritDoc} With respect to {@linkplain #entryAndValueAlignment(Alignment) alignment}.
+ *
+ * Note that the actual entrySize will be aligned to 4 (default {@linkplain
+ * #entryAndValueAlignment(Alignment) entry 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).
+ *
+ * @see #entryAndValueAlignment(Alignment) // * @see #entries(long)
+ */
+ ChronicleMapBuilderI entrySize(int entrySize);
+
+ /**
+ * Configures alignment strategy of address in memory of entries and independently of address in memory of
+ * values within entries in ChronicleMaps, created by this builder.
+ *
+ * Useful when values of the map are updated intensively, particularly fields with volatile access,
+ * because it doesn't work well if the value crosses cache lines. Also, on some (nowadays rare)
+ * architectures any misaligned memory access is more expensive than aligned.
+ *
+ *
Note that {@linkplain #entrySize(int) entry size} will be aligned according to this alignment. I. e.
+ * if you set {@code entrySize(20)} and {@link Alignment#OF_8_BYTES}, actual entry size will be 24 (20
+ * aligned to 8 bytes).
+ *
+ *
Default is {@link Alignment#OF_4_BYTES} for Byteable values.
+ *
+ * @param alignment the new alignment of the maps constructed by this builder
+ * @return this {@code ChronicleMapOnHeapUpdatableBuilder} back
+ */
+ ChronicleMapBuilderI entryAndValueAlignment(Alignment alignment);
+
+
+ /**
+ * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire} configuration to this
+ * {@code ChronicleMapBuilder}.
+ *
+ * By default, the default value is not specified, default {@linkplain #prepareValueBytesOnAcquire
+ * prepare value bytes routine} is specified instead.
+ *
+ * @see #defaultValueProvider(DefaultValueProvider)
+ * @see #prepareValueBytesOnAcquire(PrepareValueBytes)
+ */
+ ChronicleMapBuilderI defaultValue(V defaultValue);
+
+
+ /**
+ * Configures the procedure which is called on the bytes, which later the returned value is pointing to,
+ * if the key is absent, on {@link ChronicleMap#acquireUsing(Object, Object) acquireUsing()} call on maps,
+ * created by this builder. See {@link PrepareValueBytes} for more information.
+ *
+ * The default preparation callback zeroes out the value bytes.
+ *
+ * @param prepareValueBytes what to do with the value bytes before assigning them into the {@link
+ * net.openhft.lang.model.Byteable} value to return from {@code acquireUsing()}
+ * call
+ * @return this builder back
+ * @see PrepareValueBytes
+ * @see #defaultValue(Object)
+ * @see #defaultValueProvider(DefaultValueProvider)
+ */
+ ChronicleMapBuilderI prepareValueBytesOnAcquire(
+ @NotNull PrepareValueBytes prepareValueBytes);
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see #constantKeySizeBySample(Object)
+ * @see #valueSize(int)
+ * @see #entrySize(int)
+ */
+ ChronicleMapBuilderI keySize(int keySize);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see #keySize(int)
+ * @see #constantValueSizeBySample(Object)
+ */
+
+ ChronicleMapBuilderI constantKeySizeBySample(K sampleKey);
+
+ /**
+ * Configures the optimal number of bytes, taken by serialized form of values, put into maps, created by
+ * this builder. If value size is always the same, call {@link #constantValueSizeBySample(Object)} method
+ * instead of this one.
+ *
+ * If value is a boxed primitive type, 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, it's better to use
+ * {@linkplain #entrySize(int) entry size} in "chunk" mode and configure it directly.
+ *
+ * @param valueSize number of bytes, taken by serialized form of values
+ * @return this {@code ChronicleMapOnHeapUpdatableBuilder} back
+ * @see #constantValueSizeBySample(Object)
+ * @see #keySize(int)
+ * @see #entrySize(int)
+ */
+
+ ChronicleMapBuilderI valueSize(int valueSize);
+
+ /**
+ * Configures the constant number of bytes, taken by serialized form of values, put into maps, created by
+ * this builder. This is done by providing the {@code sampleValue}, all values should take the same number
+ * of bytes in serialized form, as this sample object.
+ *
+ * If values are of boxed primitive type or {@link net.openhft.lang.model.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.
+ *
+ * @param sampleValue the sample value
+ * @return this builder back
+ * @see #valueSize(int)
+ * @see #constantKeySizeBySample(Object)
+ */
+
+
+ ChronicleMapBuilderI constantValueSizeBySample(
+ @NotNull V sampleValue);
+
+ /**
+ * {@inheritDoc}
+ *
+ * Example:
{@code Map map =
+ * ChronicleMapBuilder.of(Key.class, Value.class)
+ * .entries(1_000_000)
+ * .keySize(50).valueSize(200)
+ * // this class hasn't implemented yet, just for example
+ * .objectSerializer(new KryoObjectSerializer())
+ * .create();}
+ */
+
+ ChronicleMapBuilderI objectSerializer(
+ @NotNull ObjectSerializer objectSerializer);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if custom value marshaller is specified or value class is not either
+ * {@code BytesMarshallable} or {@code Externalizable}
+ */
+
+ ChronicleMapBuilderI valueDeserializationFactory(
+ @NotNull ObjectFactory valueDeserializationFactory);
+
+ /**
+ * {@inheritDoc}
+ *
+ * By default, default value provider is not specified, {@link #defaultValue(Object) default value} is
+ * specified instead.
+ *
+ * @see #defaultValue(Object)
+ */
+
+ ChronicleMapBuilderI defaultValueProvider(
+ @NotNull DefaultValueProvider defaultValueProvider);
+
+ /**
+ * Configures the {@code BytesMarshaller} used to serialize/deserialize values to/from off-heap memory in
+ * maps, created by this builder. See the
+ * section about serialization in ChronicleMap manual for more information.
+ *
+ * @param valueMarshaller the marshaller used to serialize values
+ * @return this builder back
+ * @see #valueMarshallers(net.openhft.chronicle.hash.serialization.BytesWriter,
+ * net.openhft.chronicle.hash.serialization.BytesReader)
+ * @see ChronicleMapBuilder
+ * @see #objectSerializer(ObjectSerializer)
+ */
+ ChronicleMapBuilderI valueMarshaller(
+ @NotNull BytesMarshaller valueMarshaller);
+
+
+ /**
+ * Configures the marshallers, used to serialize/deserialize values to/from off-heap memory in maps,
+ * created by this builder. See the
+ * section about serialization in ChronicleMap manual for more information.
+ *
+ * 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 net.openhft.chronicle.hash.serialization.BytesInterop} instead of plain {@link
+ * net.openhft.chronicle.hash.serialization.BytesWriter} is, of cause, possible, but currently pointless
+ * for values.
+ *
+ * @param valueWriter the new value object → {@link net.openhft.lang.io.Bytes} writer (interop)
+ * strategy
+ * @param valueReader the new {@link net.openhft.lang.io.Bytes} → value object reader strategy
+ * @return this builder back
+ * @see #valueMarshaller(BytesMarshaller)
+ */
+ ChronicleMapBuilderI valueMarshallers(
+ @NotNull BytesWriter valueWriter, @NotNull BytesReader valueReader);
+
+ /**
+ * Configures the marshaller used to serialize actual value sizes to off-heap memory in maps, created by
+ * this builder.
+ *
+ * Default value size marshaller is so-called {@linkplain net.openhft.chronicle.hash.serialization.SizeMarshallers#stopBit()
+ * stop bit encoding marshalling}. If {@linkplain #constantValueSizeBySample(Object) constant value size}
+ * is configured, or defaulted if the value type is always constant and {@code ChronicleHashBuilder}
+ * implementation knows about it, this configuration takes no effect, because a special {@link
+ * net.openhft.chronicle.hash.serialization.SizeMarshaller} implementation, which doesn't actually do any
+ * marshalling, and just returns the known constant size on {@link net.openhft.chronicle.hash.serialization.SizeMarshaller#readSize(
+ *net.openhft.lang.io.Bytes)} calls, is used instead of any {@code SizeMarshaller} configured using this
+ * method.
+ *
+ * @param valueSizeMarshaller the new marshaller, used to serialize actual value sizes to off-heap memory
+ * @return this builder back
+ */
+ ChronicleMapBuilderI valueSizeMarshaller(
+ @NotNull SizeMarshaller valueSizeMarshaller);
+
+ ChronicleMapBuilderI entries(long l);
+
+ ChronicleMapBuilderI replication(SingleChronicleHashReplication withId);
+
+ ChronicleMap create() throws IOException;
+
+ ChronicleMapBuilderI actualSegments(int actualSegments);
+
+ ChronicleMapBuilderI minSegments(int minSegments);
+
+ ChronicleMapBuilderI actualEntriesPerSegment(long actualEntriesPerSegment);
+
+ ChronicleMapBuilderI lockTimeOut(long lockTimeOut, TimeUnit unit);
+
+ ChronicleMapBuilderI errorListener(ChronicleHashErrorListener errorListener);
+
+ ChronicleMapBuilderI metaDataBytes(int metaDataBytes);
+
+ ChronicleMapBuilderI timeProvider(TimeProvider timeProvider);
+
+ ChronicleMapBuilderI bytesMarshallerFactory(BytesMarshallerFactory bytesMarshallerFactory);
+
+ ChronicleMapBuilderI keyMarshaller(BytesMarshaller keyMarshaller);
+
+ ChronicleMapBuilderI keyMarshallers(BytesWriter keyWriter, BytesReader keyReader);
+
+ ChronicleMapBuilderI keySizeMarshaller(SizeMarshaller keySizeMarshaller);
+
+ ChronicleMapBuilderI keyDeserializationFactory(ObjectFactory keyDeserializationFactory);
+
+ ChronicleMapBuilderI immutableKeys();
+
+ ChronicleMap createPersistedTo(File file) throws IOException;
+
+ StatelessClientConfig> statelessClient(InetSocketAddress remoteAddress);
+
+ ChronicleHashInstanceConfig> instance();
+
+ ChronicleMapBuilderI replication(byte identifier);
+
+ ChronicleMapBuilderI replication(byte identifier, TcpTransportAndNetworkConfig tcpTransportAndNetwork);
+
+ ChronicleMapBuilderI clone();
+
+ ChronicleMapBuilderI eventListener(MapEventListener> eventListener);
+
+ ChronicleMapBuilderI putReturnsNull(boolean b);
+
+ ChronicleMap createReplicated(byte b) throws IOException;
+
+ ChronicleMapBuilderI removeReturnsNull(boolean b);
+
+
+}
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapOnHeapUpdatableBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapOnHeapUpdatableBuilder.java
deleted file mode 100644
index 8b9e98ee6..000000000
--- a/src/main/java/net/openhft/chronicle/map/ChronicleMapOnHeapUpdatableBuilder.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright 2014 Higher Frequency Trading http://www.higherfrequencytrading.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.openhft.chronicle.map;
-
-import net.openhft.chronicle.hash.ChronicleHashBuilder;
-import net.openhft.chronicle.hash.serialization.*;
-import net.openhft.lang.io.Bytes;
-import net.openhft.lang.io.serialization.BytesMarshallable;
-import net.openhft.lang.io.serialization.BytesMarshaller;
-import net.openhft.lang.io.serialization.ObjectFactory;
-import net.openhft.lang.io.serialization.ObjectSerializer;
-import net.openhft.lang.model.Byteable;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.Externalizable;
-import java.io.Serializable;
-
-
-/**
- * {@code ChronicleMapOnHeapUpdatableBuilder} is intended to be used to configure {@link ChronicleMap}s with
- * non-{@link Byteable} values, which don't point to off-heap memory directly, including primitives
- * ({@link Long}, {@link Double}, etc.), {@link String}s and {@link CharSequence}s, values
- * implementing {@link BytesMarshallable}, {@link Externalizable} or {@link Serializable} interface,
- * or any other values for which {@linkplain #valueMarshaller(BytesMarshaller) custom marshaller}
- * is provided.
- *
- * Use static {@link #of(Class, Class) of(Key.class, Value.class)} method to obtain
- * a {@code ChronicleMapOnHeapUpdatableBuilder} instance.
- *
- * @param key type of the maps, created by this builder
- * @param value type of the maps, created by this builder
- * @see ChronicleMapBuilder
- * @see AbstractChronicleMapBuilder
- * @see ChronicleHashBuilder
- */
-public final class ChronicleMapOnHeapUpdatableBuilder
- extends AbstractChronicleMapBuilder> {
-
- /**
- * Returns a new {@code ChronicleMapOnHeapUpdatableBuilder} instance which is able to {@linkplain #create()
- * create} maps with the specified key and value classes.
- *
- * {@code ChronicleMapOnHeapUpdatableBuilder} analyzes provided key and value classes and automatically
- * chooses the most specific and effective serializer which it is aware about. Read
- * the section about
- * serialization in Chronicle Map manual for more information.
- *
- * @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 ChronicleMapOnHeapUpdatableBuilder of(
- @NotNull Class keyClass, @NotNull Class valueClass) {
- return new ChronicleMapOnHeapUpdatableBuilder(keyClass, valueClass);
- }
-
- ChronicleMapOnHeapUpdatableBuilder(Class keyClass, Class valueClass) {
- super(keyClass, valueClass);
- }
-
- @Override
- ChronicleMapOnHeapUpdatableBuilder self() {
- return this;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see #constantKeySizeBySample(Object)
- * @see #valueSize(int)
- * @see #entrySize(int)
- */
- @Override
- public ChronicleMapOnHeapUpdatableBuilder keySize(int keySize) {
- return super.keySize(keySize);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see #keySize(int)
- * @see #constantValueSizeBySample(Object)
- */
- @Override
- public ChronicleMapOnHeapUpdatableBuilder constantKeySizeBySample(K sampleKey) {
- return super.constantKeySizeBySample(sampleKey);
- }
-
- /**
- * Configures the optimal number of bytes, taken by serialized form of values, put into maps,
- * created by this builder. If value size is always the same, call {@link
- * #constantValueSizeBySample(Object)} method instead of this one.
- *
- * If value is a boxed primitive type, 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,
- * it's better to use {@linkplain #entrySize(int) entry size} in "chunk" mode and configure it
- * directly.
- *
- * @param valueSize number of bytes, taken by serialized form of values
- * @return this {@code ChronicleMapOnHeapUpdatableBuilder} back
- * @see #constantValueSizeBySample(Object)
- * @see #keySize(int)
- * @see #entrySize(int)
- */
- @Override
- public ChronicleMapOnHeapUpdatableBuilder valueSize(int valueSize) {
- return super.valueSize(valueSize);
- }
-
- /**
- * Configures the constant number of bytes, taken by serialized form of values, put into maps,
- * created by this builder. This is done by providing the {@code sampleValue}, all values should
- * take the same number of bytes in serialized form, as this sample object.
- *
- * 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.
- *
- * @param sampleValue the sample value
- * @return this builder back
- * @see #valueSize(int)
- * @see #constantKeySizeBySample(Object)
- */
-
- @Override
- public ChronicleMapOnHeapUpdatableBuilder constantValueSizeBySample(
- @NotNull V sampleValue) {
- return super.constantValueSizeBySample(sampleValue);
- }
-
- /**
- * {@inheritDoc}
- *
- * Example:
{@code Map map =
- * ChronicleMapOnHeapUpdatableBuilder.of(Key.class, Value.class)
- * .entries(1_000_000)
- * .keySize(50).valueSize(200)
- * // this class hasn't implemented yet, just for example
- * .objectSerializer(new KryoObjectSerializer())
- * .create();}
- *
- * This serializer is used to serialize both keys and values, if they both require this:
- * loosely typed, nullable, and custom {@linkplain #keyMarshaller(BytesMarshaller) key} and
- * {@linkplain #valueMarshaller(BytesMarshaller) value} marshallers are not configured.
- */
- @Override
- public ChronicleMapOnHeapUpdatableBuilder objectSerializer(
- @NotNull ObjectSerializer objectSerializer) {
- return super.objectSerializer(objectSerializer);
- }
-
- /**
- * {@inheritDoc}
- *
- * If {@linkplain #valueMarshaller(BytesMarshaller) custom value marshaller} is configured,
- * this configuration is unused, because it is incapsulated in {@link
- * BytesMarshaller#read(Bytes)} method (without provided instance to read the data into),
- * i. e. it's is the user-side responsibility. Actually this is just a convenience method
- * supporting value marshaller configurations, made initially during {@link #of(Class, Class)}
- * call, if the value class is {@link BytesMarshallable} or {@link Externalizable} subclass.
- *
- * @throws IllegalStateException if custom value marshaller is specified or value class is not
- * either {@code BytesMarshallable} or {@code Externalizable}
- */
- @Override
- public ChronicleMapOnHeapUpdatableBuilder valueDeserializationFactory(
- @NotNull ObjectFactory valueDeserializationFactory) {
- return super.valueDeserializationFactory(valueDeserializationFactory);
- }
-
- /**
- * {@inheritDoc}
- *
- * By default, the default value is set to {@code null}.
- *
- * @see #defaultValueProvider(DefaultValueProvider)
- */
- @Override
- public ChronicleMapOnHeapUpdatableBuilder defaultValue(V defaultValue) {
- return super.defaultValue(defaultValue);
- }
-
- /**
- * {@inheritDoc}
- *
- * By default, default value provider is not specified, {@link #defaultValue(Object) default
- * value} is specified instead.
- *
- * @see #defaultValue(Object)
- */
- @Override
- public ChronicleMapOnHeapUpdatableBuilder defaultValueProvider(
- @NotNull DefaultValueProvider defaultValueProvider) {
- return super.defaultValueProvider(defaultValueProvider);
- }
-
- /**
- * Configures the {@code BytesMarshaller} used to serialize/deserialize values to/from off-heap
- * memory in maps, created by this builder. See
- * the
- * section about serialization in ChronicleMap manual for more information.
- *
- * @param valueMarshaller the marshaller used to serialize values
- * @return this builder back
- * @see #valueMarshallers(BytesWriter, BytesReader)
- * @see ChronicleMapBuilder
- * @see #objectSerializer(ObjectSerializer)
- */
- public ChronicleMapOnHeapUpdatableBuilder valueMarshaller(
- @NotNull BytesMarshaller valueMarshaller) {
- valueBuilder.marshaller(valueMarshaller);
- return this;
- }
-
- /**
- * Configures the marshallers, used to serialize/deserialize values to/from off-heap
- * memory in maps, created by this builder. See
- * the section about
- * serialization in ChronicleMap manual for more information.
- *
- * 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.
- *
- * @param valueWriter the new value object → {@link Bytes} writer (interop) strategy
- * @param valueReader the new {@link Bytes} → value object reader strategy
- * @return this builder back
- * @see #valueMarshaller(BytesMarshaller)
- */
- public ChronicleMapOnHeapUpdatableBuilder valueMarshallers(
- @NotNull BytesWriter valueWriter, @NotNull BytesReader valueReader) {
- valueBuilder.writer(valueWriter);
- valueBuilder.reader(valueReader);
- return this;
- }
-
- /**
- * Configures the marshaller used to serialize actual value sizes to off-heap memory in maps,
- * created by this builder.
- *
- * Default value size marshaller is so-called {@linkplain SizeMarshallers#stopBit()
- * stop bit encoding marshalling}. If {@linkplain #constantValueSizeBySample(Object) constant
- * value size} is configured, or defaulted if the value type is always constant and {@code
- * ChronicleHashBuilder} implementation knows about it, this configuration takes no effect,
- * because a special {@link SizeMarshaller} implementation, which doesn't actually do any
- * marshalling, and just returns the known constant size on {@link SizeMarshaller#readSize(
- * Bytes)} calls, is used instead of any {@code SizeMarshaller} configured using this method.
- *
- * @param valueSizeMarshaller the new marshaller, used to serialize actual value sizes to
- * off-heap memory
- * @return this builder back
- */
- public ChronicleMapOnHeapUpdatableBuilder valueSizeMarshaller(
- @NotNull SizeMarshaller valueSizeMarshaller) {
- valueBuilder.sizeMarshaller(valueSizeMarshaller);
- return this;
- }
-}
diff --git a/src/main/java/net/openhft/chronicle/map/NodeDiscovery.java b/src/main/java/net/openhft/chronicle/map/NodeDiscovery.java
index 877b69312..be5755ed2 100644
--- a/src/main/java/net/openhft/chronicle/map/NodeDiscovery.java
+++ b/src/main/java/net/openhft/chronicle/map/NodeDiscovery.java
@@ -124,8 +124,6 @@ public class NodeDiscovery {
if (proposedIdentifier == ourProposedIdentifier.get())
useAnotherIdentifier.set(true);
-
-
}
}
countDownLatch.get().countDown();
@@ -231,7 +229,7 @@ public class NodeDiscovery {
LOG.info("Using Remote identifier=" + identifier);
nodeDiscoveryEventListenerAtomicReference.set(null);
- return ChronicleMapOnHeapUpdatableBuilder.of(Integer.class,
+ return ChronicleMapBuilder.of(Integer.class,
CharSequence.class)
.entries(20000L)
.replication(SingleChronicleHashReplication.builder()
diff --git a/src/main/java/net/openhft/chronicle/map/OffHeapUpdatableChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/OffHeapUpdatableChronicleMapBuilder.java
new file mode 100644
index 000000000..fa50e5db0
--- /dev/null
+++ b/src/main/java/net/openhft/chronicle/map/OffHeapUpdatableChronicleMapBuilder.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2014 Higher Frequency Trading http://www.higherfrequencytrading.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.openhft.chronicle.map;
+
+import net.openhft.chronicle.hash.serialization.BytesReader;
+import net.openhft.chronicle.hash.serialization.BytesWriter;
+import net.openhft.chronicle.hash.serialization.SizeMarshaller;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.model.Byteable;
+import net.openhft.lang.model.DataValueClasses;
+import org.jetbrains.annotations.NotNull;
+
+final class OffHeapUpdatableChronicleMapBuilder
+ extends AbstractChronicleMapBuilder> implements ChronicleMapBuilderI {
+
+ public static ChronicleMapBuilderI of(
+ @NotNull Class keyClass, @NotNull Class valueClass) {
+
+ if (valueClass.isEnum())
+ return OnHeapUpdatableChronicleMapBuilder.of(keyClass, valueClass);
+
+ if (keyClass.isInterface() && keyClass != CharSequence.class) {
+ keyClass = DataValueClasses.directClassFor(keyClass);
+ }
+
+ if ((valueClass.isInterface() && valueClass != CharSequence.class)) {
+ valueClass = DataValueClasses.directClassFor(valueClass);
+ } else if (!offHeapReference(valueClass)) {
+ return OnHeapUpdatableChronicleMapBuilder.of(keyClass, valueClass);
+ }
+ return new OffHeapUpdatableChronicleMapBuilder(keyClass, valueClass);
+ }
+
+ OffHeapUpdatableChronicleMapBuilder(Class keyClass, Class valueClass) {
+ super(keyClass, valueClass);
+ prepareValueBytesOnAcquire(new ZeroOutValueBytes(valueSize()));
+ }
+
+ @Override
+ OffHeapUpdatableChronicleMapBuilder self() {
+ return this;
+ }
+
+ @Override
+ public OffHeapUpdatableChronicleMapBuilder valueSize(int valueSize) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc} With respect to {@linkplain #entryAndValueAlignment(Alignment) alignment}.
+ *
+ * Note that the actual entrySize will be aligned to 4 (default {@linkplain
+ * #entryAndValueAlignment(Alignment) entry 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).
+ *
+ * @see #entryAndValueAlignment(Alignment)
+ * @see #entries(long)
+ */
+ @Override
+ public OffHeapUpdatableChronicleMapBuilder entrySize(int entrySize) {
+ return super.entrySize(entrySize);
+ }
+
+ /**
+ * Configures alignment strategy of address in memory of entries and independently of address in memory of
+ * values within entries in ChronicleMaps, created by this builder.
+ *
+ * Useful when values of the map are updated intensively, particularly fields with volatile access,
+ * because it doesn't work well if the value crosses cache lines. Also, on some (nowadays rare)
+ * architectures any misaligned memory access is more expensive than aligned.
+ *
+ *
Note that {@linkplain #entrySize(int) entry size} will be aligned according to this alignment. I. e.
+ * if you set {@code entrySize(20)} and {@link Alignment#OF_8_BYTES}, actual entry size will be 24 (20
+ * aligned to 8 bytes).
+ *
+ *
Default is {@link Alignment#OF_4_BYTES} for Byteable values.
+ *
+ * @param alignment the new alignment of the maps constructed by this builder
+ * @return this {@code ChronicleMapOnHeapUpdatableBuilder} back
+ */
+ @Override
+ public OffHeapUpdatableChronicleMapBuilder entryAndValueAlignment(Alignment alignment) {
+ return super.entryAndValueAlignment(alignment);
+ }
+
+ /**
+ * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire} configuration to this
+ * {@code ChronicleMapBuilder}.
+ *
+ * By default, the default value is not specified, default {@linkplain #prepareValueBytesOnAcquire
+ * prepare value bytes routine} is specified instead.
+ *
+ * @see #defaultValueProvider(DefaultValueProvider)
+ * @see #prepareValueBytesOnAcquire(PrepareValueBytes)
+ */
+ @Override
+ public OffHeapUpdatableChronicleMapBuilder defaultValue(V defaultValue) {
+ return super.defaultValue(defaultValue);
+ }
+
+ /**
+ * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire} configuration to this
+ * {@code ChronicleMapBuilder}.
+ *
+ * By default, the default value provider is not specified, default {@linkplain
+ * #prepareValueBytesOnAcquire prepare value bytes routine} is specified instead.
+ *
+ * @see #defaultValue(Object)
+ * @see #prepareValueBytesOnAcquire(PrepareValueBytes)
+ */
+ @Override
+ public OffHeapUpdatableChronicleMapBuilder defaultValueProvider(
+ @NotNull DefaultValueProvider defaultValueProvider) {
+ return super.defaultValueProvider(defaultValueProvider);
+ }
+
+ /**
+ * Configures the procedure which is called on the bytes, which later the returned value is pointing to,
+ * if the key is absent, on {@link ChronicleMap#acquireUsing(Object, Object) acquireUsing()} call on maps,
+ * created by this builder. See {@link PrepareValueBytes} for more information.
+ *
+ * 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 to return from {@code acquireUsing()} call
+ * @return this builder back
+ * @see PrepareValueBytes
+ * @see #defaultValue(Object)
+ * @see #defaultValueProvider(DefaultValueProvider)
+ */
+ @Override
+ public OffHeapUpdatableChronicleMapBuilder prepareValueBytesOnAcquire(
+ @NotNull PrepareValueBytes prepareValueBytes) {
+ return super.prepareValueBytesOnAcquire(prepareValueBytes);
+ }
+
+ public ChronicleMapBuilderI valueMarshaller(@NotNull BytesMarshaller valueMarshaller) {
+ throw new UnsupportedOperationException("not supported for this combination of key/value type");
+ }
+
+
+ public ChronicleMapBuilderI valueMarshallers(@NotNull BytesWriter valueWriter, @NotNull BytesReader valueReader) {
+ throw new UnsupportedOperationException("not supported for this combination of key/value type");
+ }
+
+
+ public ChronicleMapBuilderI valueSizeMarshaller(@NotNull SizeMarshaller valueSizeMarshaller) {
+ throw new UnsupportedOperationException("not supported for this combination of key/value type");
+ }
+
+ @Override
+ public OffHeapUpdatableChronicleMapBuilder constantValueSizeBySample(V sampleValue) {
+ throw new UnsupportedOperationException("not supported for this combination of key/value type");
+ }
+
+
+}
diff --git a/src/main/java/net/openhft/chronicle/map/OnHeapUpdatableChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/OnHeapUpdatableChronicleMapBuilder.java
new file mode 100644
index 000000000..485099233
--- /dev/null
+++ b/src/main/java/net/openhft/chronicle/map/OnHeapUpdatableChronicleMapBuilder.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2014 Higher Frequency Trading http://www.higherfrequencytrading.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.openhft.chronicle.map;
+
+import net.openhft.chronicle.hash.ChronicleHashBuilder;
+import net.openhft.chronicle.hash.serialization.BytesReader;
+import net.openhft.chronicle.hash.serialization.BytesWriter;
+import net.openhft.chronicle.hash.serialization.SizeMarshaller;
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.BytesMarshallable;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.io.serialization.ObjectFactory;
+import net.openhft.lang.io.serialization.ObjectSerializer;
+import net.openhft.lang.model.Byteable;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.Serializable;
+
+
+/**
+ * {@code ChronicleMapOnHeapUpdatableBuilder} is intended to be used to configure {@link ChronicleMap}s with
+ * non-{@link Byteable} values, which don't point to off-heap memory directly, including primitives ({@link
+ * Long}, {@link Double}, etc.), {@link String}s and {@link CharSequence}s, values implementing {@link
+ * BytesMarshallable}, {@link Externalizable} or {@link Serializable} interface, or any other values for which
+ * {@linkplain #valueMarshaller(BytesMarshaller) custom marshaller} is provided.
+ *
+ * Use static {@link #of(Class, Class) of(Key.class, Value.class)} method to obtain a {@code
+ * ChronicleMapOnHeapUpdatableBuilder} instance.
+ *
+ * @param key type of the maps, created by this builder
+ * @param value type of the maps, created by this builder
+ * @see ChronicleMapBuilder
+ * @see AbstractChronicleMapBuilder
+ * @see ChronicleHashBuilder
+ */
+final class OnHeapUpdatableChronicleMapBuilder
+ extends AbstractChronicleMapBuilder> implements
+ ChronicleMapBuilderI {
+
+ /**
+ * Returns a new {@code ChronicleMapOnHeapUpdatableBuilder} instance which is able to {@linkplain
+ * #create() create} maps with the specified key and value classes.
+ *
+ * {@code ChronicleMapOnHeapUpdatableBuilder} analyzes provided key and value classes and automatically
+ * chooses the most specific and effective serializer which it is aware about. Read the section about serialization in
+ * Chronicle Map manual for more information.
+ *
+ * @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 ChronicleMapBuilderI of(
+ @NotNull Class keyClass, @NotNull Class valueClass) {
+ return new OnHeapUpdatableChronicleMapBuilder(keyClass, valueClass);
+ }
+
+ OnHeapUpdatableChronicleMapBuilder(Class keyClass, Class valueClass) {
+ super(keyClass, valueClass);
+ }
+
+ @Override
+ OnHeapUpdatableChronicleMapBuilder self() {
+ return this;
+ }
+
+ public ChronicleMap create() throws IOException {
+ return super.create();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see #constantKeySizeBySample(Object)
+ * @see #valueSize(int)
+ * @see #entrySize(int)
+ */
+ @Override
+ public OnHeapUpdatableChronicleMapBuilder keySize(int keySize) {
+ return super.keySize(keySize);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see #keySize(int)
+ * @see #constantValueSizeBySample(Object)
+ */
+ @Override
+ public OnHeapUpdatableChronicleMapBuilder constantKeySizeBySample(K sampleKey) {
+ return super.constantKeySizeBySample(sampleKey);
+ }
+
+ /**
+ * Configures the optimal number of bytes, taken by serialized form of values, put into maps, created by
+ * this builder. If value size is always the same, call {@link #constantValueSizeBySample(Object)} method
+ * instead of this one.
+ *
+ *