diff --git a/README.md b/README.md index 7385846ad..88cac1466 100644 --- a/README.md +++ b/README.md @@ -117,9 +117,9 @@ hardware or get more hardware. Chronicle Map on the other hand sends the latest This will naturally drop updates and is a more natural choice for low bandwidth connections. #### What is the difference between [SharedHashMap](https://github.com/OpenHFT/HugeCollections) and Chronicle Map -SharedHashMap is an outdated version of ChronicleMap project. -Effectively SharedHashMap has just been renamed to ChronicleMap, to further enrich the Chronicle -product suite. In addition, The original Chronicle has been renamed to Chronicle Queue. +SharedHashMap was the old name given to ChronicleMap, Since the last release of SharedHashMap + we have added a lot of new features to ChronicleMap, most of these are listed in this readme. + ## Getting Started @@ -189,7 +189,7 @@ this for best performance. or value objects that are created through, a directClass interface, for example : ``` java - ChronicleMap chm = OffHeapUpdatableChronicleMapBuilder + ChronicleMap chm = ChronicleMapBuilder .of(String.class, BondVOInterface.class) .create(); @@ -428,10 +428,10 @@ bond.getCoupon() lets say that it is only the `coupon` field that we are interested in, then its better not to have to deserialize the whole object that implements the `BondVOInterface`. It would be more efficient to just deserialize the field(s) that we require, in this example just the coupon. This is why we created -the`OffHeapUpdatableChronicleMapBuilder`, when you use this builder chronicle will not create on heap copies of your whole data structure. You can instead use proxy objects that can read and write into the off heap data structures, this reduced serialisation can give you a big performance boost. Below we show you how you can work directly with the off heap entries. +the`ChronicleMapBuilder`, when you use this builder chronicle will not create on heap copies of your whole data structure. You can instead use proxy objects that can read and write into the off heap data structures, this reduced serialisation can give you a big performance boost. Below we show you how you can work directly with the off heap entries. ``` java - ChronicleMap chm = OffHeapUpdatableChronicleMapBuilder + ChronicleMap chm = ChronicleMapBuilder .of(String.class, BondVOInterface.class) .keySize(10) .create(); diff --git a/pom.xml b/pom.xml index 27d2dfc31..72d5d7bdb 100644 --- a/pom.xml +++ b/pom.xml @@ -144,7 +144,7 @@ maven-javadoc-plugin - http://openhft.github.io/Java-Lang/apidocs/ + http://openhft.github.io/Chronicle-Map/apidocs/ net.openhft.chronicle.hash.serialization.internal diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java index 74c757787..be25be9b4 100644 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java @@ -45,7 +45,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** - * This interface defines the meaning of configurations, common to {@link ChronicleMapBuilder} and + * This interface defines the meaning of configurations, common to {@link net.openhft.chronicle.map.ChronicleMapOnHeapUpdatableBuilder} and * {@link ChronicleSetBuilder}, i. e. Chronicle hash container configurations. * *

{@code ChronicleHashBuilder} is mutable. Configuration methods mutate the builder and return @@ -56,7 +56,7 @@ import java.util.concurrent.TimeUnit; * @param the type of keys in hash containers, created by this builder * @param the container type, created by this builder, i. e. {@link ChronicleMap} or {@link * ChronicleSet} - * @param the concrete builder type, i. e. {@link ChronicleMapBuilder} or {@link + * @param the concrete builder type, i. e. {@link net.openhft.chronicle.map.ChronicleMapOnHeapUpdatableBuilder} or {@link * ChronicleSetBuilder} */ public interface ChronicleHashBuilderThere are three major patterns of this configuration usage:

  1. Key (and value, in * {@code ChronicleMap} case) sizes are constant. Configure them via {@link - * #constantKeySizeBySample(Object)} and {@link ChronicleMapBuilder#constantValueSizeBySample(Object)} + * #constantKeySizeBySample(Object)} and {@link net.openhft.chronicle.map.ChronicleMapOnHeapUpdatableBuilder#constantValueSizeBySample(Object)} * methods, and you will experience no memory waste at all.
  2. Key (and/or value size, in * {@code ChronicleMap} case) varies moderately. Specify them using corresponding methods, or * specify entry size directly by calling this method, by sizes somewhere between average and @@ -154,7 +154,7 @@ public interface ChronicleHashBuilder{@code - * Map socialGraph = ChronicleMapBuilder + * Map socialGraph = ChronicleMapOnHeapUpdatableBuilder * .of(Long.class, long[].class) * // given that graph should have of 1 billion nodes, and 150 average adjacency list size * // => values takes 3 chuncks on average @@ -183,7 +183,7 @@ public interface ChronicleHashBuilder
  3. If key (and/or value, in {@code ChronicleMap} case) size varies * moderately, you should pass to this method the maximum number of entries + 5-25%, depending * on your data properties and configured {@linkplain #keySize(int) key}/{@linkplain - * ChronicleMapBuilder#valueSize(int) value}/{@linkplain #entrySize(int) entry} sizes.
  4. + * net.openhft.chronicle.map.ChronicleMapOnHeapUpdatableBuilder#valueSize(int) value}/{@linkplain #entrySize(int) entry} sizes. *
  5. If your data size varies in a wide range, pass the maximum number of entries multiplied * by average data size and divided by the configured "entry size" (i. e. chunk size). See an * example in the documentation to {@link #entrySize(int)} method.
diff --git a/src/main/java/net/openhft/chronicle/java8/Function.java b/src/main/java/net/openhft/chronicle/java8/Function.java new file mode 100644 index 000000000..3d680e259 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/java8/Function.java @@ -0,0 +1,27 @@ +package net.openhft.chronicle.java8; + +import java.io.Serializable; + +/** + * Represents a function that accepts one argument and produces a result. + * + *

This is a functional interface whose functional method is {@link + * #apply(Object)}. + * + * @param the type of the input to the function + * @param the type of the result of the function + * @since 1.8 + */ + +public interface Function extends Serializable { + + /** + * Applies this function to the given argument. + * + * @param t the function argument + * @return the function result + */ + R apply(T t); + + +} diff --git a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java index 590ff2b9d..1e26a0720 100644 --- a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java @@ -57,19 +57,19 @@ 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 + * 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
- * ChronicleMap map = ChronicleMapBuilder
+ * ChronicleMap map = ChronicleMapOnHeapUpdatableBuilder
  *     .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 OnHeapUpdatableChronicleMapBuilder} or {@link + * ChronicleMapBuilder}, could be prepared and used to create many similar * maps:
{@code
- * OffHeapUpdatableChronicleMapBuilder builder = OffHeapUpdatableChronicleMapBuilder
+ * ChronicleMapBuilder builder = ChronicleMapBuilder
  *     .of(Key.class, Value.class)
  *     .entries(100500);
  *
@@ -201,7 +201,7 @@ public abstract class AbstractChronicleMapBuilderExample: if keys in your map(s) are English words in {@link String} form, keys size 10
      * (a bit more than average English word length) would be a good choice: 
{@code
-     * ChronicleMap wordFrequencies = OffHeapUpdatableChronicleMapBuilder
+     * ChronicleMap wordFrequencies = ChronicleMapBuilder
      *     .of(String.class, LongValue.class)
      *     .entries(50000)
      *     .keySize(10)
@@ -532,7 +532,7 @@ public abstract class AbstractChronicleMapBuilderUse static {@link #of(Class, Class) of(Key.class, Value.class)} method to obtain
- * a {@code ChronicleMapBuilder} instance.
+ * {@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 OffHeapUpdatableChronicleMapBuilder
  * @see AbstractChronicleMapBuilder
- * @see ChronicleHashBuilder
+ * @see net.openhft.chronicle.hash.ChronicleHashBuilder
  */
-public final class ChronicleMapBuilder
-        extends AbstractChronicleMapBuilder> {
+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.
+     * 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 and effective serializer which it is aware about. Read - * the section about - * serialization in Chronicle Map manual for more information. + *

{@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 + * @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) { - return new ChronicleMapBuilder(keyClass, valueClass); + + if (valueClass.isEnum()) + return new ChronicleMapBuilder(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 new ChronicleMapBuilder(OnHeapUpdatableChronicleMapBuilder.of(keyClass, valueClass)); + } + OffHeapUpdatableChronicleMapBuilder kvOffHeapUpdatableChronicleMapBuilder = new + OffHeapUpdatableChronicleMapBuilder(keyClass, valueClass); + return new ChronicleMapBuilder(kvOffHeapUpdatableChronicleMapBuilder); } - ChronicleMapBuilder(Class keyClass, Class valueClass) { - super(keyClass, valueClass); + ChronicleMapBuilder(ChronicleMapBuilderI delegate) { + this.delegate = delegate; } + + 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). + * + * @see #entryAndValueAlignment(Alignment) // * @see #entries(long) + */ @Override - ChronicleMapBuilder self() { + public ChronicleMapBuilder entrySize(int entrySize) { + delegate.entrySize(entrySize); return this; } /** - * {@inheritDoc} + * 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. * - * @see #constantKeySizeBySample(Object) - * @see #valueSize(int) - * @see #entrySize(int) + *

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 ChronicleMapBuilder entryAndValueAlignment(Alignment alignment) { + delegate.entryAndValueAlignment(alignment); + return this; + } + + /** + * {@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 ChronicleMapBuilder defaultValue(V defaultValue) { + delegate.defaultValue(defaultValue); + return this; + } + + /** + * 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) + */ + @Override + public ChronicleMapBuilder prepareValueBytesOnAcquire(@NotNull PrepareValueBytes prepareValueBytes) { + delegate.prepareValueBytesOnAcquire(prepareValueBytes); + return this; + } + + @Override public ChronicleMapBuilder keySize(int keySize) { - return super.keySize(keySize); + delegate.keySize(keySize); + return this; } - /** - * {@inheritDoc} - * - * @see #keySize(int) - * @see #constantValueSizeBySample(Object) - */ + @Override public ChronicleMapBuilder constantKeySizeBySample(K sampleKey) { - return super.constantKeySizeBySample(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. + * 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 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. + *

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 ChronicleMapBuilder} back + * @return this {@code ChronicleMapOnHeapUpdatableBuilder} back * @see #constantValueSizeBySample(Object) * @see #keySize(int) * @see #entrySize(int) */ @Override public ChronicleMapBuilder valueSize(int valueSize) { - return super.valueSize(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. + * 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 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. + *

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) { - return super.constantValueSizeBySample(sampleValue); + public ChronicleMapBuilder constantValueSizeBySample(@NotNull V sampleValue) { + delegate.constantValueSizeBySample(sampleValue); + return this; } /** @@ -161,124 +223,258 @@ public final class ChronicleMapBuilder * // 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 ChronicleMapBuilder objectSerializer( - @NotNull ObjectSerializer objectSerializer) { - return super.objectSerializer(objectSerializer); + 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} * - *

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 ChronicleMapBuilder valueDeserializationFactory( - @NotNull ObjectFactory valueDeserializationFactory) { - return super.valueDeserializationFactory(valueDeserializationFactory); - } - - /** - * {@inheritDoc} - * - *

By default, the default value is set to {@code null}. - * - * @see #defaultValueProvider(DefaultValueProvider) - */ - @Override - public ChronicleMapBuilder defaultValue(V defaultValue) { - return super.defaultValue(defaultValue); - } - - /** - * {@inheritDoc} - * - *

By default, default value provider is not specified, {@link #defaultValue(Object) default - * value} is specified instead. + *

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) { - return super.defaultValueProvider(defaultValueProvider); + 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 + * 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 OffHeapUpdatableChronicleMapBuilder + * @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) { - valueBuilder.marshaller(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. + * 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)}. + *

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. + *

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 Bytes} writer (interop) strategy - * @param valueReader the new {@link Bytes} → value object reader strategy + * @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) */ - public ChronicleMapBuilder valueMarshallers( - @NotNull BytesWriter valueWriter, @NotNull BytesReader valueReader) { - valueBuilder.writer(valueWriter); - valueBuilder.reader(valueReader); + @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. + * 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. + *

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 + * @param valueSizeMarshaller the new marshaller, used to serialize actual value sizes to off-heap memory * @return this builder back */ - public ChronicleMapBuilder valueSizeMarshaller( - @NotNull SizeMarshaller valueSizeMarshaller) { - valueBuilder.sizeMarshaller(valueSizeMarshaller); + @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/NodeDiscovery.java b/src/main/java/net/openhft/chronicle/map/NodeDiscovery.java index 6e614410c..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(); diff --git a/src/main/java/net/openhft/chronicle/map/OffHeapUpdatableChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/OffHeapUpdatableChronicleMapBuilder.java index 41ef51679..fa50e5db0 100644 --- a/src/main/java/net/openhft/chronicle/map/OffHeapUpdatableChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/OffHeapUpdatableChronicleMapBuilder.java @@ -16,24 +16,31 @@ 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; -public final class OffHeapUpdatableChronicleMapBuilder - extends AbstractChronicleMapBuilder> { +final class OffHeapUpdatableChronicleMapBuilder + extends AbstractChronicleMapBuilder> implements ChronicleMapBuilderI { - public static OffHeapUpdatableChronicleMapBuilder of( + 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()) { + + 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 OnHeapUpdatableChronicleMapBuilder.of(keyClass, valueClass); } return new OffHeapUpdatableChronicleMapBuilder(keyClass, valueClass); } @@ -48,13 +55,18 @@ public final class OffHeapUpdatableChronicleMapBuilder 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). + * #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) @@ -65,21 +77,21 @@ public final class OffHeapUpdatableChronicleMapBuilder } /** - * 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. * * @param alignment the new alignment of the maps constructed by this builder - * @return this {@code ChronicleMapBuilder} back + * @return this {@code ChronicleMapOnHeapUpdatableBuilder} back */ @Override public OffHeapUpdatableChronicleMapBuilder entryAndValueAlignment(Alignment alignment) { @@ -87,11 +99,11 @@ public final class OffHeapUpdatableChronicleMapBuilder } /** - * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire} - * configuration to this {@code OffHeapUpdatableChronicleMapBuilder}. + * {@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) @@ -102,8 +114,8 @@ public final class OffHeapUpdatableChronicleMapBuilder } /** - * {@inheritDoc} Also, it overrides any previous {@link #prepareValueBytesOnAcquire} - * configuration to this {@code OffHeapUpdatableChronicleMapBuilder}. + * {@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. @@ -118,15 +130,14 @@ public final class OffHeapUpdatableChronicleMapBuilder } /** - * 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 + * Byteable} value to return from {@code acquireUsing()} call * @return this builder back * @see PrepareValueBytes * @see #defaultValue(Object) @@ -137,4 +148,25 @@ public final class OffHeapUpdatableChronicleMapBuilder @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. + * + *

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 OnHeapUpdatableChronicleMapBuilder 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 OnHeapUpdatableChronicleMapBuilder constantValueSizeBySample( + @NotNull V sampleValue) { + return super.constantValueSizeBySample(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();}
+ * + *

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 OnHeapUpdatableChronicleMapBuilder 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 OnHeapUpdatableChronicleMapBuilder valueDeserializationFactory( + @NotNull ObjectFactory valueDeserializationFactory) { + return super.valueDeserializationFactory(valueDeserializationFactory); + } + + /** + * {@inheritDoc} + * + *

By default, the default value is set to {@code null}. + * + * @see #defaultValueProvider(DefaultValueProvider) + */ + @Override + public OnHeapUpdatableChronicleMapBuilder 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 OnHeapUpdatableChronicleMapBuilder 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 OnHeapUpdatableChronicleMapBuilder 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 net.openhft.chronicle.hash.serialization.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 OnHeapUpdatableChronicleMapBuilder 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 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 + * 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 OnHeapUpdatableChronicleMapBuilder valueSizeMarshaller( + @NotNull SizeMarshaller valueSizeMarshaller) { + valueBuilder.sizeMarshaller(valueSizeMarshaller); + return this; + } + + /** + * 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 OnHeapUpdatableChronicleMapBuilder prepareValueBytesOnAcquire( + @NotNull PrepareValueBytes prepareValueBytes) { + throw new UnsupportedOperationException("not supported for this combination of key/value type"); + } + + + public OnHeapUpdatableChronicleMapBuilder entryAndValueAlignment(Alignment a) { + throw new UnsupportedOperationException("not supported for this combination of key/value type"); + } + + +} diff --git a/src/main/java/net/openhft/chronicle/map/PrepareValueBytes.java b/src/main/java/net/openhft/chronicle/map/PrepareValueBytes.java index e2b726fec..87462f6a8 100644 --- a/src/main/java/net/openhft/chronicle/map/PrepareValueBytes.java +++ b/src/main/java/net/openhft/chronicle/map/PrepareValueBytes.java @@ -26,11 +26,11 @@ import java.io.Serializable; * value during {@link ChronicleMap#acquireUsing(Object, Object) * chronicleMap.acquireUsing()} call, when the given key is absent in the map. Example: if you * want {@code 1L} to be the off-heap updatable ChronicleMap's {@linkplain - * OffHeapUpdatableChronicleMapBuilder#defaultValue(Object) default value}, the most simple way - * to achieve this is to {@linkplain OffHeapUpdatableChronicleMapBuilder#prepareValueBytesOnAcquire( + * ChronicleMapBuilder#defaultValue(Object) default value}, the most simple way + * to achieve this is to {@linkplain ChronicleMapBuilder#prepareValueBytesOnAcquire( * PrepareValueBytes) configure} custom {@code PrepareValueBytes} strategy in {@link - * OffHeapUpdatableChronicleMapBuilder}:

{@code
- * OffHeapUpdatableChronicleMapBuilder.of(Key.class, LongValue.class)
+ * ChronicleMapBuilder}: 
{@code
+ * ChronicleMapBuilder.of(Key.class, LongValue.class)
  *     .prepareValueBytesOnAcquire((bytes, k) -> bytes.writeLong(1L))
  *     ...
  *     .create();}
@@ -41,7 +41,7 @@ import java.io.Serializable; * * @param the key type of {@link ChronicleMap}, on which {@code acquireUsing()} is queried * @param the value type of {@link ChronicleMap}, on which {@code acquireUsing()} is queried - * @see OffHeapUpdatableChronicleMapBuilder#prepareValueBytesOnAcquire(PrepareValueBytes) + * @see ChronicleMapBuilder#prepareValueBytesOnAcquire(PrepareValueBytes) */ public interface PrepareValueBytes extends Serializable { diff --git a/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java b/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java index 9c10faa0f..1c1303cac 100644 --- a/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java @@ -20,6 +20,7 @@ package net.openhft.chronicle.map; import com.sun.jdi.connect.spi.ClosedConnectionException; import net.openhft.chronicle.hash.RemoteCallTimeoutException; +import net.openhft.chronicle.java8.Function; import net.openhft.lang.io.ByteBufferBytes; import net.openhft.lang.io.Bytes; import net.openhft.lang.threadlocal.ThreadLocalCopies; @@ -35,7 +36,6 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.SocketChannel; import java.util.*; -import java.util.function.Function; import static java.nio.ByteBuffer.allocateDirect; import static net.openhft.chronicle.map.AbstractChannelReplicator.SIZE_OF_SIZE; @@ -138,7 +138,7 @@ class StatelessChronicleMap implements ChronicleMap, Closeable { result = AbstractChannelReplicator.openSocketChannel(closeables); result.connect(builder.remoteAddress()); result.socket().setTcpNoDelay(true); - result.socket().setReuseAddress(true); + doHandShaking(result); break; @@ -240,6 +240,11 @@ class StatelessChronicleMap implements ChronicleMap, Closeable { if (closeables != null) closeables.closeQuietly(); closeables = null; + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // + } } @@ -468,9 +473,9 @@ class StatelessChronicleMap implements ChronicleMap, Closeable { private void writeObject(@NotNull Function function) { + long start = bytes.position(); for (; ; ) { try { - bytes.writeObject(function); return; } catch (IllegalStateException e) { @@ -480,6 +485,8 @@ class StatelessChronicleMap implements ChronicleMap, Closeable { if (cause instanceof IOException && cause.getMessage().contains("Not enough available space")) { LOG.debug("resizing buffer"); resizeBuffer(buffer.capacity() + 1024); + bytes.limit(bytes.capacity()); + bytes.position(start); } else throw e; @@ -557,7 +564,6 @@ class StatelessChronicleMap implements ChronicleMap, Closeable { writeKey(key, local); - final V value = e.getValue(); final Class valueClass = value.getClass(); diff --git a/src/main/java/net/openhft/chronicle/map/TcpReplicator.java b/src/main/java/net/openhft/chronicle/map/TcpReplicator.java index dff0d86e6..1b895a7c1 100644 --- a/src/main/java/net/openhft/chronicle/map/TcpReplicator.java +++ b/src/main/java/net/openhft/chronicle/map/TcpReplicator.java @@ -21,6 +21,7 @@ package net.openhft.chronicle.map; import net.openhft.chronicle.hash.replication.RemoteNodeValidator; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; import net.openhft.chronicle.hash.replication.ThrottlingConfig; +import net.openhft.chronicle.java8.Function; import net.openhft.lang.io.ByteBufferBytes; import net.openhft.lang.io.Bytes; import net.openhft.lang.threadlocal.ThreadLocalCopies; @@ -38,7 +39,6 @@ import java.nio.channels.*; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import static java.nio.channels.SelectionKey.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -1348,16 +1348,12 @@ class StatelessServerConnector { final ThreadLocalCopies local = keyValueSerializer.threadLocalCopies(); final K key = readKey(reader, local); - V value = using.getAndSet(null); - if (value == null) { - // a simple way to create a value - value = map.getUsing(key, null); - } - + final V value = using.getAndSet(null); final Function o = (Function) reader.readObject(); - try (WriteContext wc = map.acquireUsingLocked(key, value)) { - Object result = o.apply(value); + try (WriteContext wc = map.lookupUsing(key, value, VanillaChronicleMap.LockType.WRITE_LOCK, + false)) { + Object result = o.apply(wc.value()); keyValueSerializer.writeObject(result, writer); } catch (RuntimeException e) { diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index d8e45fb3a..908ee3ccc 100755 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -349,6 +349,9 @@ class VanillaChronicleMap, replaceIfPresent); } + + + enum LockType {READ_LOCK, WRITE_LOCK} @Override diff --git a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java index 017bf24f3..afd9b463f 100644 --- a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java +++ b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java @@ -45,20 +45,20 @@ import java.util.concurrent.TimeUnit; * {@code ChronicleSetBuilder} manages the whole set of {@link ChronicleSet} configurations, could be used as * a classic builder and/or factory. * - *

{@code ChronicleMapBuilder} is mutable, see a note in {@link ChronicleHashBuilder} interface + *

{@code ChronicleMapOnHeapUpdatableBuilder} is mutable, see a note in {@link ChronicleHashBuilder} interface * documentation. * * @param element type of the sets, created by this builder * @see ChronicleSet - * @see ChronicleMapBuilder + * @see net.openhft.chronicle.map.ChronicleMapOnHeapUpdatableBuilder */ public class ChronicleSetBuilder implements ChronicleHashBuilder, ChronicleSetBuilder> { - private ChronicleMapBuilder chronicleMapBuilder; + private ChronicleMapBuilder chronicleMapBuilderOnHeap; ChronicleSetBuilder(Class keyClass) { - chronicleMapBuilder = ChronicleMapBuilder.of(keyClass, DummyValue.class) + chronicleMapBuilderOnHeap = ChronicleMapBuilder.of(keyClass, DummyValue.class) .valueMarshallers(DummyValueMarshaller.INSTANCE, DummyValueMarshaller.INSTANCE) .valueSizeMarshaller(DummyValueMarshaller.INSTANCE); } @@ -72,7 +72,7 @@ public class ChronicleSetBuilder try { @SuppressWarnings("unchecked") final ChronicleSetBuilder result = (ChronicleSetBuilder) super.clone(); - result.chronicleMapBuilder = chronicleMapBuilder.clone(); + result.chronicleMapBuilderOnHeap = chronicleMapBuilderOnHeap.clone(); return result; } catch (CloneNotSupportedException e) { throw new AssertionError(e); @@ -81,19 +81,19 @@ public class ChronicleSetBuilder @Override public ChronicleSetBuilder actualSegments(int actualSegments) { - chronicleMapBuilder.actualSegments(actualSegments); + chronicleMapBuilderOnHeap.actualSegments(actualSegments); return this; } @Override public ChronicleSetBuilder minSegments(int minSegments) { - chronicleMapBuilder.minSegments(minSegments); + chronicleMapBuilderOnHeap.minSegments(minSegments); return this; } @Override public ChronicleSetBuilder actualEntriesPerSegment(long actualEntriesPerSegment) { - chronicleMapBuilder.actualEntriesPerSegment(actualEntriesPerSegment); + chronicleMapBuilderOnHeap.actualEntriesPerSegment(actualEntriesPerSegment); return this; } @@ -116,7 +116,7 @@ public class ChronicleSetBuilder */ @Override public ChronicleSetBuilder keySize(int keySize) { - chronicleMapBuilder.keySize(keySize); + chronicleMapBuilderOnHeap.keySize(keySize); return this; } @@ -132,7 +132,7 @@ public class ChronicleSetBuilder */ @Override public ChronicleSetBuilder constantKeySizeBySample(E sampleKey) { - chronicleMapBuilder.constantKeySizeBySample(sampleKey); + chronicleMapBuilderOnHeap.constantKeySizeBySample(sampleKey); return this; } @@ -149,38 +149,38 @@ public class ChronicleSetBuilder */ @Override public ChronicleSetBuilder entrySize(int entrySize) { - chronicleMapBuilder.entrySize(entrySize); + chronicleMapBuilderOnHeap.entrySize(entrySize); return this; } @Override public ChronicleSetBuilder entries(long entries) { - chronicleMapBuilder.entries(entries); + chronicleMapBuilderOnHeap.entries(entries); return this; } @Override public ChronicleSetBuilder lockTimeOut(long lockTimeOut, TimeUnit unit) { - chronicleMapBuilder.lockTimeOut(lockTimeOut, unit); + chronicleMapBuilderOnHeap.lockTimeOut(lockTimeOut, unit); return this; } @Override public ChronicleSetBuilder errorListener(ChronicleHashErrorListener errorListener) { - chronicleMapBuilder.errorListener(errorListener); + chronicleMapBuilderOnHeap.errorListener(errorListener); return this; } @Override public ChronicleSetBuilder metaDataBytes(int metaDataBytes) { - chronicleMapBuilder.metaDataBytes(metaDataBytes); + chronicleMapBuilderOnHeap.metaDataBytes(metaDataBytes); return this; } @Override public String toString() { return " ChronicleSetBuilder{" + - "chronicleMapBuilder=" + chronicleMapBuilder + + "chronicleMapBuilderOnHeap=" + chronicleMapBuilderOnHeap + '}'; } @@ -189,7 +189,7 @@ public class ChronicleSetBuilder public boolean equals(Object o) { if (!(o instanceof ChronicleSetBuilder)) return false; - return chronicleMapBuilder.equals(((ChronicleSetBuilder) o).chronicleMapBuilder); + return chronicleMapBuilderOnHeap.equals(((ChronicleSetBuilder) o).chronicleMapBuilderOnHeap); } @Override @@ -199,14 +199,14 @@ public class ChronicleSetBuilder @Override public ChronicleSetBuilder timeProvider(TimeProvider timeProvider) { - chronicleMapBuilder.timeProvider(timeProvider); + chronicleMapBuilderOnHeap.timeProvider(timeProvider); return this; } @Override public ChronicleSetBuilder bytesMarshallerFactory( BytesMarshallerFactory bytesMarshallerFactory) { - chronicleMapBuilder.bytesMarshallerFactory(bytesMarshallerFactory); + chronicleMapBuilderOnHeap.bytesMarshallerFactory(bytesMarshallerFactory); return this; } @@ -222,26 +222,26 @@ public class ChronicleSetBuilder */ @Override public ChronicleSetBuilder objectSerializer(ObjectSerializer objectSerializer) { - chronicleMapBuilder.objectSerializer(objectSerializer); + chronicleMapBuilderOnHeap.objectSerializer(objectSerializer); return this; } @Override public ChronicleSetBuilder keyMarshaller(@NotNull BytesMarshaller keyMarshaller) { - chronicleMapBuilder.keyMarshaller(keyMarshaller); + chronicleMapBuilderOnHeap.keyMarshaller(keyMarshaller); return this; } @Override public ChronicleSetBuilder keyMarshallers(@NotNull BytesWriter keyWriter, @NotNull BytesReader keyReader) { - chronicleMapBuilder.keyMarshallers(keyWriter, keyReader); + chronicleMapBuilderOnHeap.keyMarshallers(keyWriter, keyReader); return this; } @Override public ChronicleSetBuilder keySizeMarshaller(@NotNull SizeMarshaller keySizeMarshaller) { - chronicleMapBuilder.keySizeMarshaller(keySizeMarshaller); + chronicleMapBuilderOnHeap.keySizeMarshaller(keySizeMarshaller); return this; } @@ -258,54 +258,54 @@ public class ChronicleSetBuilder @Override public ChronicleSetBuilder keyDeserializationFactory( @NotNull ObjectFactory keyDeserializationFactory) { - chronicleMapBuilder.keyDeserializationFactory(keyDeserializationFactory); + chronicleMapBuilderOnHeap.keyDeserializationFactory(keyDeserializationFactory); return this; } @Override public ChronicleSetBuilder immutableKeys() { - chronicleMapBuilder.immutableKeys(); + chronicleMapBuilderOnHeap.immutableKeys(); return this; } @Override public ChronicleSetBuilder replication(SingleChronicleHashReplication replication) { - chronicleMapBuilder.replication(replication); + chronicleMapBuilderOnHeap.replication(replication); return this; } @Override public ChronicleSetBuilder replication(byte identifier, TcpTransportAndNetworkConfig tcpTransportAndNetwork) { - chronicleMapBuilder.replication(identifier, tcpTransportAndNetwork); + chronicleMapBuilderOnHeap.replication(identifier, tcpTransportAndNetwork); return this; } @Override public ChronicleSetBuilder replication(byte identifier) { - chronicleMapBuilder.replication(identifier); + chronicleMapBuilderOnHeap.replication(identifier); return this; } @Override public StatelessClientConfig> statelessClient( InetSocketAddress remoteAddress) { - return new StatelessSetConfig<>(chronicleMapBuilder.statelessClient(remoteAddress)); + return new StatelessSetConfig<>(chronicleMapBuilderOnHeap.statelessClient(remoteAddress)); } @Override public ChronicleHashInstanceConfig> instance() { - return new InstanceConfig<>(chronicleMapBuilder.instance()); + return new InstanceConfig<>(chronicleMapBuilderOnHeap.instance()); } @Override public ChronicleSet create() throws IOException { - final ChronicleMap map = chronicleMapBuilder.create(); + final ChronicleMap map = chronicleMapBuilderOnHeap.create(); return new SetFromMap(map); } @Override public ChronicleSet createPersistedTo(File file) throws IOException { - ChronicleMap map = chronicleMapBuilder.createPersistedTo(file); + ChronicleMap map = chronicleMapBuilderOnHeap.createPersistedTo(file); return new SetFromMap(map); } diff --git a/src/main/java/net/openhft/chronicle/set/DummyValue.java b/src/main/java/net/openhft/chronicle/set/DummyValue.java index 5145f9239..a7e4fb305 100644 --- a/src/main/java/net/openhft/chronicle/set/DummyValue.java +++ b/src/main/java/net/openhft/chronicle/set/DummyValue.java @@ -18,6 +18,6 @@ package net.openhft.chronicle.set; -enum DummyValue { + enum DummyValue { DUMMY_VALUE } diff --git a/src/test/java/eg/BigData.java b/src/test/java/eg/BigData.java index 177b1059f..8c8fe917f 100644 --- a/src/test/java/eg/BigData.java +++ b/src/test/java/eg/BigData.java @@ -20,6 +20,7 @@ package eg; import net.openhft.affinity.AffinitySupport; import net.openhft.chronicle.map.ChronicleMapBuilder; +import net.openhft.chronicle.map.ChronicleMapBuilder; import net.openhft.lang.io.Bytes; import java.io.*; diff --git a/src/test/java/net/openhft/chronicle/map/AcquireGetUsingMain.java b/src/test/java/net/openhft/chronicle/map/AcquireGetUsingMain.java index fe6b10497..7dfcbf72b 100644 --- a/src/test/java/net/openhft/chronicle/map/AcquireGetUsingMain.java +++ b/src/test/java/net/openhft/chronicle/map/AcquireGetUsingMain.java @@ -30,7 +30,7 @@ public class AcquireGetUsingMain { public static void main(String[] args) throws Exception { File file = new File(System.getProperty("java.io.tmpdir") + "/test1"); ChronicleMap theSharedMap = - OffHeapUpdatableChronicleMapBuilder.of(String.class, Data.class) + ChronicleMapBuilder.of(String.class, Data.class) .createPersistedTo(file); Data data = DataValueClasses.newDirectReference(Data.class); String processType = "testkey"; diff --git a/src/test/java/net/openhft/chronicle/map/Builder.java b/src/test/java/net/openhft/chronicle/map/Builder.java index 073e204fb..dd0773d38 100644 --- a/src/test/java/net/openhft/chronicle/map/Builder.java +++ b/src/test/java/net/openhft/chronicle/map/Builder.java @@ -75,9 +75,8 @@ public class Builder { TcpTransportAndNetworkConfig tcpConfig = TcpTransportAndNetworkConfig.of(serverPort, Arrays.asList(endpoints)) .heartBeatInterval(1L, TimeUnit.SECONDS); return ChronicleMapBuilder.of(kClass, vClass) - .replication(identifier, tcpConfig); + .replication(identifier, tcpConfig); } - } diff --git a/src/test/java/net/openhft/chronicle/map/CHMLatencyTestMain.java b/src/test/java/net/openhft/chronicle/map/CHMLatencyTestMain.java index 6649c1d86..8e6863439 100644 --- a/src/test/java/net/openhft/chronicle/map/CHMLatencyTestMain.java +++ b/src/test/java/net/openhft/chronicle/map/CHMLatencyTestMain.java @@ -76,7 +76,7 @@ public class CHMLatencyTestMain { // File file = new File("testCHMLatency.deleteme"); file.delete(); ChronicleMap countersMap = - OffHeapUpdatableChronicleMapBuilder.of(LongValue.class, LongValue.class) + ChronicleMapBuilder.of(LongValue.class, LongValue.class) .entries(KEYS) .entrySize(16) .createPersistedTo(file); diff --git a/src/test/java/net/openhft/chronicle/map/CHMTest5.java b/src/test/java/net/openhft/chronicle/map/CHMTest5.java index 6979bc473..b6fd2b907 100644 --- a/src/test/java/net/openhft/chronicle/map/CHMTest5.java +++ b/src/test/java/net/openhft/chronicle/map/CHMTest5.java @@ -34,12 +34,12 @@ public class CHMTest5 { public static void main(String[] args) throws Exception { //First create (or access if already created) the shared map - OffHeapUpdatableChronicleMapBuilder builder = - OffHeapUpdatableChronicleMapBuilder.of(String.class, CHMTest5Data.class) + ChronicleMapBuilder builder = + ChronicleMapBuilder.of(String.class, CHMTest5Data.class) .entries(1000); //// don't include this, just to check it is as expected. - assertEquals(8, builder.minSegments()); + assertEquals(8, ((AbstractChronicleMapBuilder) builder.delegate).minSegments()); //// end of test String chmPath = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "CHMTest5"; diff --git a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java index 941a1cf87..e3bb59119 100755 --- a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java @@ -110,7 +110,7 @@ public class ChronicleMapTest { private static ChronicleMap getSharedMap( long entries, int segments, int entrySize, Alignment alignment) throws IOException { - return OffHeapUpdatableChronicleMapBuilder.of(CharSequence.class, LongValue.class) + return ChronicleMapBuilder.of(CharSequence.class, LongValue.class) .entries(entries) .minSegments(segments) .entrySize(entrySize) @@ -582,7 +582,7 @@ public class ChronicleMapTest { // JAVA 8 produces more garbage than previous versions for internal work. // System.gc(); final long entries = runs * 1000 * 1000L; - OffHeapUpdatableChronicleMapBuilder builder = OffHeapUpdatableChronicleMapBuilder + ChronicleMapBuilder builder = ChronicleMapBuilder .of(CharSequence.class, LongValue.class) .entries(entries) .actualSegments(8 * 1024) @@ -654,7 +654,7 @@ public class ChronicleMapTest { // JAVA 8 produces more garbage than previous versions for internal work. // System.gc(); final long entries = runs * 1000 * 1000L; - OffHeapUpdatableChronicleMapBuilder builder = OffHeapUpdatableChronicleMapBuilder + ChronicleMapBuilder builder = ChronicleMapBuilder .of(CharSequence.class, LongValue.class) .entries(entries) .entryAndValueAlignment(OF_8_BYTES) @@ -728,7 +728,7 @@ public class ChronicleMapTest { // JAVA 8 produces more garbage than previous versions for internal work. // System.gc(); final long entries = runs * 1000 * 1000L; - OffHeapUpdatableChronicleMapBuilder builder = OffHeapUpdatableChronicleMapBuilder + ChronicleMapBuilder builder = ChronicleMapBuilder .of(LongValue.class, LongValue.class) .entries(entries) .entryAndValueAlignment(OF_8_BYTES) @@ -1356,13 +1356,13 @@ public class ChronicleMapTest { @Test public void equalsTest() throws IOException { - final ChronicleMap map1 = ChronicleMapBuilder + final ChronicleMap map1 = OnHeapUpdatableChronicleMapBuilder .of(Integer.class, String.class).create(); map1.put(1, "one"); map1.put(2, "two"); - final ChronicleMap map2 = ChronicleMapBuilder + final ChronicleMap map2 = OnHeapUpdatableChronicleMapBuilder .of(Integer.class, String.class).create(); map2.put(1, "one"); @@ -1406,7 +1406,7 @@ public class ChronicleMapTest { @Test public void testOffheapAcquireUsingLocked() throws IOException { - OffHeapUpdatableChronicleMapBuilder builder = OffHeapUpdatableChronicleMapBuilder + ChronicleMapBuilder builder = ChronicleMapBuilder .of(CharSequence.class, LongValue.class) .entries(1000) .entrySize(16); @@ -1487,8 +1487,31 @@ public class ChronicleMapTest { } + } + + @Test + public void testOnheapAcquireUsingLockedStringBuilder() throws IOException { + + try (final ChronicleMap map = ChronicleMapBuilder + .of(CharSequence.class, CharSequence.class) + .entries(1000) + .entrySize(40) + .defaultValue("") + .create()) { + + StringBuilder value = new StringBuilder(); + + try (WriteContext context = map.acquireUsingLocked("one", value)) { + value.append("Hello World"); + } + + assertEquals("Hello World", value.toString()); + } + } + + @Test public void testOnheapAcquireUsingLocked() throws IOException { ChronicleMapBuilder builder = ChronicleMapBuilder diff --git a/src/test/java/net/openhft/chronicle/map/ConcurrentMap8Test.java b/src/test/java/net/openhft/chronicle/map/ConcurrentMap8Test.java index 1d1596e20..3c1b31f1e 100644 --- a/src/test/java/net/openhft/chronicle/map/ConcurrentMap8Test.java +++ b/src/test/java/net/openhft/chronicle/map/ConcurrentMap8Test.java @@ -42,7 +42,7 @@ public class ConcurrentMap8Test extends JSR166TestCase { /* private static ConcurrentMap newLongMap() { //First create (or access if already created) the shared map - final ChronicleMapBuilder builder = ChronicleMapBuilder.of(Long.class, Long.class); + final ChronicleMapOnHeapUpdatableBuilder builder = ChronicleMapBuilder.of(Long.class, Long.class); //// don't include this, just to check it is as expected. @@ -64,7 +64,7 @@ public class ConcurrentMap8Test extends JSR166TestCase { private static ConcurrentMap newIntegerStringMap() { - final ChronicleMapBuilder builder = ChronicleMapBuilder.of(Integer.class, + final ChronicleMapOnHeapUpdatableBuilder builder = ChronicleMapBuilder.of(Integer.class, String.class); diff --git a/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java b/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java index 7e47e4bf0..d0b773361 100644 --- a/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java +++ b/src/test/java/net/openhft/chronicle/map/DefaultValueTest.java @@ -37,7 +37,7 @@ public class DefaultValueTest { ArrayList defaultValue = new ArrayList(); defaultValue.add(42); - try (ChronicleMap> map = ChronicleMapBuilder + try (ChronicleMap> map = OnHeapUpdatableChronicleMapBuilder .of(String.class, (Class>) ((Class) List.class)) .defaultValue(defaultValue).createPersistedTo(file)) { ArrayList using = new ArrayList(); @@ -49,7 +49,7 @@ public class DefaultValueTest { } ArrayList using = new ArrayList(); - try (ChronicleMap> map = ChronicleMapBuilder + try (ChronicleMap> map = OnHeapUpdatableChronicleMapBuilder .of(String.class, (Class>) ((Class) List.class)) .createPersistedTo(file)) { assertEquals(defaultValue, map.acquireUsing("c", using)); diff --git a/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java index c85c8f86f..c970ab11c 100755 --- a/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java @@ -17,7 +17,7 @@ public class DemoChronicleMapTest { File file = File.createTempFile("DummyOrders", ".test"); file.deleteOnExit(); int maxEntries = 1000; - ChronicleMap map = OffHeapUpdatableChronicleMapBuilder + ChronicleMap map = ChronicleMapBuilder .of(IntValue.class, DemoOrderVOInterface.class) .putReturnsNull(true) .removeReturnsNull(true) @@ -59,7 +59,7 @@ public class DemoChronicleMapTest { File file = File.createTempFile("DummyOrders", ".test"); file.deleteOnExit(); int maxEntries = 1000; - ChronicleMap map = OffHeapUpdatableChronicleMapBuilder + ChronicleMap map = ChronicleMapBuilder .of(IntValue.class, DemoOrderVOInterface.class) .putReturnsNull(true) .removeReturnsNull(true) diff --git a/src/test/java/net/openhft/chronicle/map/EntryCountMapTest.java b/src/test/java/net/openhft/chronicle/map/EntryCountMapTest.java index 742366961..f98d29ee3 100644 --- a/src/test/java/net/openhft/chronicle/map/EntryCountMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/EntryCountMapTest.java @@ -51,7 +51,8 @@ public class EntryCountMapTest { private static ChronicleMap getSharedMap( long entries, int segments, int entrySize, Alignment alignment) throws IOException { - OffHeapUpdatableChronicleMapBuilder mapBuilder = OffHeapUpdatableChronicleMapBuilder.of(CharSequence.class, LongValue.class) + ChronicleMapBuilder mapBuilder = ChronicleMapBuilder.of(CharSequence + .class, LongValue.class) .entries(entries) .actualSegments(segments) .entrySize(entrySize) diff --git a/src/test/java/net/openhft/chronicle/map/IntValueMapTest.java b/src/test/java/net/openhft/chronicle/map/IntValueMapTest.java index 59a14633b..597bb622e 100644 --- a/src/test/java/net/openhft/chronicle/map/IntValueMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/IntValueMapTest.java @@ -37,7 +37,7 @@ public class IntValueMapTest { @Test public void test() throws IOException { - final ChronicleMap map = ChronicleMapBuilder + final ChronicleMap map = OnHeapUpdatableChronicleMapBuilder .of(IntValue.class, CharSequence.class) .entries(20000) .keyMarshaller(ByteableIntValueMarshaller.INSTANCE).create(); diff --git a/src/test/java/net/openhft/chronicle/map/Issue42Test.java b/src/test/java/net/openhft/chronicle/map/Issue42Test.java index a3fcc7aac..4b1681623 100755 --- a/src/test/java/net/openhft/chronicle/map/Issue42Test.java +++ b/src/test/java/net/openhft/chronicle/map/Issue42Test.java @@ -32,7 +32,7 @@ public class Issue42Test { if (!Jvm.isWindows()) return; - final ChronicleMap map = ChronicleMapBuilder + final ChronicleMap map = OnHeapUpdatableChronicleMapBuilder .of(CharSequence.class, CharSequence.class) .entrySize(18) .entries(1500000) diff --git a/src/test/java/net/openhft/chronicle/map/SerializerTest.java b/src/test/java/net/openhft/chronicle/map/SerializerTest.java index 4bf4a05e7..7551c4037 100644 --- a/src/test/java/net/openhft/chronicle/map/SerializerTest.java +++ b/src/test/java/net/openhft/chronicle/map/SerializerTest.java @@ -72,7 +72,13 @@ public class SerializerTest { final ByteBufferBytes out = new ByteBufferBytes(ByteBuffer.allocateDirect(1024)); ByteBufferBytes in = out.slice(); - ChronicleMapBuilder builder = ChronicleMapBuilder.of(Integer.class, valueClass); + + ChronicleMapBuilder cBuilder = ChronicleMapBuilder.of(Integer + .class, valueClass); + + OnHeapUpdatableChronicleMapBuilder builder = (OnHeapUpdatableChronicleMapBuilder) cBuilder.delegate; + + builder.preMapConstruction(false); Serializer v = new Serializer(builder.valueBuilder); @@ -95,7 +101,10 @@ public class SerializerTest { final ByteBufferBytes out = new ByteBufferBytes(ByteBuffer.allocateDirect(1024)); ByteBufferBytes in = out.slice(); - ChronicleMapBuilder builder = ChronicleMapBuilder.of(clazz, Integer.class); + ChronicleMapBuilder cBuilder = ChronicleMapBuilder.of(clazz, Integer.class); + + OnHeapUpdatableChronicleMapBuilder builder = (OnHeapUpdatableChronicleMapBuilder) cBuilder.delegate; + builder.preMapConstruction(false); { Serializer v = new Serializer(builder.keyBuilder); diff --git a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java index db8a40030..d2385a1cb 100644 --- a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java +++ b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java @@ -19,17 +19,16 @@ package net.openhft.chronicle.map; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; +import net.openhft.chronicle.java8.Function; import org.junit.Assert; import org.junit.Test; import java.io.IOException; -import java.io.Serializable; import java.net.InetSocketAddress; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.function.Function; /** @@ -41,7 +40,7 @@ public class StatelessClientTest { public static final int SIZE = 100000; - static class StringBuilderToStringFunction implements Function, Serializable { + static class StringBuilderToStringFunction implements Function { @Override public String apply(StringBuilder stringBuilder) { @@ -51,11 +50,12 @@ public class StatelessClientTest { @Test - public void testMapForKey() throws IOException, InterruptedException { + public void testMapForKeyWithEntry() throws IOException, InterruptedException { try (ChronicleMap serverMap = ChronicleMapBuilder.of(Integer.class, StringBuilder.class) + .defaultValue(new StringBuilder()) .replication((byte) 2, TcpTransportAndNetworkConfig.of(8056)).create()) { serverMap.put(10, new StringBuilder("Hello World")); @@ -64,7 +64,8 @@ public class StatelessClientTest { .class, StringBuilder.class) .statelessClient(new InetSocketAddress("localhost", 8056)).create()) { - String actual = (String) ((StatelessChronicleMap) statelessMap).mapForKey(10, new StringBuilderToStringFunction()); + String actual = (String) ((StatelessChronicleMap) statelessMap).mapForKey(10, new + StringBuilderToStringFunction()); Assert.assertEquals("Hello World", actual); } @@ -72,6 +73,30 @@ public class StatelessClientTest { } + + @Test + public void testMapForKeyWhenNoEntry() throws IOException, InterruptedException { + + + try (ChronicleMap serverMap = ChronicleMapBuilder.of(Integer.class, + StringBuilder.class) + .defaultValue(new StringBuilder()) + .replication((byte) 2, TcpTransportAndNetworkConfig.of(8056)).create()) { + + serverMap.put(10, new StringBuilder("Hello World")); + + try (ChronicleMap statelessMap = ChronicleMapBuilder.of(Integer + .class, StringBuilder.class) + .statelessClient(new InetSocketAddress("localhost", 8056)).create()) { + + String actual = (String) ((StatelessChronicleMap) statelessMap).mapForKey(11, new + StringBuilderToStringFunction()); + + Assert.assertEquals("", actual); + } + } + } + @Test(timeout = 5000) public void testBufferOverFlowPutAllAndEntrySet() throws IOException, InterruptedException { diff --git a/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationNativeTest.java b/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationNativeTest.java index 6db9d081f..5b6e479fd 100644 --- a/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationNativeTest.java +++ b/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationNativeTest.java @@ -53,13 +53,13 @@ public class TCPSocketReplicationNativeTest { TcpTransportAndNetworkConfig tcpConfig1 = TcpTransportAndNetworkConfig.of(8076, endpoint) .heartBeatInterval(1L, TimeUnit.SECONDS); - map1 = OffHeapUpdatableChronicleMapBuilder.of(Integer.class, LongValue.class) + map1 = ChronicleMapBuilder.of(Integer.class, LongValue.class) .replication((byte) 1, tcpConfig1).create(); TcpTransportAndNetworkConfig tcpConfig2 = TcpTransportAndNetworkConfig.of(8077) .heartBeatInterval(1L, TimeUnit.SECONDS); - map2 = OffHeapUpdatableChronicleMapBuilder.of(Integer.class, LongValue.class) + map2 = ChronicleMapBuilder.of(Integer.class, LongValue.class) .replication((byte) 2, tcpConfig2).create(); } diff --git a/src/test/java/net/openhft/chronicle/map/example/ChannelExample.java b/src/test/java/net/openhft/chronicle/map/example/ChannelExample.java index 6adebf43c..0189fa77b 100644 --- a/src/test/java/net/openhft/chronicle/map/example/ChannelExample.java +++ b/src/test/java/net/openhft/chronicle/map/example/ChannelExample.java @@ -4,6 +4,7 @@ import net.openhft.chronicle.hash.replication.ReplicationHub; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; import net.openhft.chronicle.map.ChronicleMap; import net.openhft.chronicle.map.ChronicleMapBuilder; +import net.openhft.chronicle.map.ChronicleMapBuilder; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/openhft/chronicle/map/example/DistributedSequenceMain.java b/src/test/java/net/openhft/chronicle/map/example/DistributedSequenceMain.java index 1a8d3b140..13f03e882 100644 --- a/src/test/java/net/openhft/chronicle/map/example/DistributedSequenceMain.java +++ b/src/test/java/net/openhft/chronicle/map/example/DistributedSequenceMain.java @@ -23,7 +23,6 @@ import net.openhft.chronicle.map.ChronicleMapBuilder; import net.openhft.lang.model.DataValueClasses; import net.openhft.lang.values.LongValue; -import java.io.File; import java.io.IOException; public class DistributedSequenceMain { diff --git a/src/test/java/net/openhft/chronicle/map/example/StringsMapMain.java b/src/test/java/net/openhft/chronicle/map/example/StringsMapMain.java index b4729d9a9..08b700c13 100644 --- a/src/test/java/net/openhft/chronicle/map/example/StringsMapMain.java +++ b/src/test/java/net/openhft/chronicle/map/example/StringsMapMain.java @@ -52,8 +52,7 @@ public class StringsMapMain { public static void startRemoteClient(String hostname) throws IOException { final ChronicleMap map; if (stateless) { - map = ChronicleMapBuilder - .of(CharSequence.class, CharSequence.class) + map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class) .putReturnsNull(true) .statelessClient(new InetSocketAddress(hostname, port)).create(); } else { diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java b/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java index 949c4b117..c2cfed303 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java @@ -19,7 +19,7 @@ package net.openhft.chronicle.map.fromdocs; import net.openhft.chronicle.map.ChronicleMap; -import net.openhft.chronicle.map.OffHeapUpdatableChronicleMapBuilder; +import net.openhft.chronicle.map.ChronicleMapBuilder; import net.openhft.chronicle.map.ReadContext; import net.openhft.chronicle.map.WriteContext; import net.openhft.lang.model.DataValueClasses; @@ -56,7 +56,7 @@ public class OpenJDKAndHashMapExamplesTest { File file = new File(TMP + "/chm-myBondPortfolioCHM-" + System.nanoTime()); file.deleteOnExit(); - ChronicleMap chm = OffHeapUpdatableChronicleMapBuilder + ChronicleMap chm = ChronicleMapBuilder .of(String.class, BondVOInterface.class) .keySize(10) .createPersistedTo(file); @@ -76,7 +76,7 @@ public class OpenJDKAndHashMapExamplesTest { mpx1030.setBidPx(107.6); } - ChronicleMap chmB = OffHeapUpdatableChronicleMapBuilder + ChronicleMap chmB = ChronicleMapBuilder .of(String.class, BondVOInterface.class) .keySize(10) .createPersistedTo(file); diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/pingpong_latency/PingPongCASLeft.java b/src/test/java/net/openhft/chronicle/map/fromdocs/pingpong_latency/PingPongCASLeft.java index 0d31aaade..cd1a98c5e 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/pingpong_latency/PingPongCASLeft.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/pingpong_latency/PingPongCASLeft.java @@ -23,7 +23,6 @@ import net.openhft.chronicle.map.ChronicleMap; import net.openhft.chronicle.map.ChronicleMapBuilder; import net.openhft.chronicle.map.fromdocs.BondVOInterface; -import java.io.File; import java.io.IOException; import java.util.Arrays;