diff --git a/src/main/java/net/openhft/chronicle/ChronicleHashBuilder.java b/src/main/java/net/openhft/chronicle/ChronicleHashBuilder.java
index e4a21799a..107ab10c9 100644
--- a/src/main/java/net/openhft/chronicle/ChronicleHashBuilder.java
+++ b/src/main/java/net/openhft/chronicle/ChronicleHashBuilder.java
@@ -1,17 +1,14 @@
package net.openhft.chronicle;
-import net.openhft.chronicle.map.ChannelProvider;
-import net.openhft.chronicle.map.ChronicleMap;
-import net.openhft.chronicle.map.ChronicleMapBuilder;
-import net.openhft.chronicle.map.ReplicationConfig;
+import net.openhft.chronicle.map.*;
import net.openhft.chronicle.set.ChronicleSet;
import net.openhft.chronicle.set.ChronicleSetBuilder;
-import net.openhft.lang.io.serialization.BytesMarshaller;
-import net.openhft.lang.io.serialization.BytesMarshallerFactory;
-import net.openhft.lang.io.serialization.ObjectSerializer;
+import net.openhft.lang.io.serialization.*;
+import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory;
import net.openhft.lang.model.Byteable;
import org.jetbrains.annotations.NotNull;
+import java.io.Externalizable;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
@@ -22,20 +19,35 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
- * This interface defines the meaning of configurations, common to {@link ChronicleMapBuilder} and {@link
- * ChronicleSetBuilder}, i. e. Chronicle hash container configurations.
+ * This interface defines the meaning of configurations, common to {@link ChronicleMapBuilder}
+ * and {@link ChronicleSetBuilder}, i. e. Chronicle hash container configurations.
+ *
+ * {@code ChronicleHashBuilder} is mutable. Configuration methods mutate the builder and return
+ * the builder itself back to support chaining pattern, rather than the builder copies with
+ * the corresponding configuration changed. To make an independent configuration,
+ * {@linkplain #clone} the builder.
*
* @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 ChronicleSetBuilder}
+ * @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 ChronicleSetBuilder}
*/
public interface ChronicleHashBuilder> extends Cloneable {
+ /**
+ * Clones this builder. Useful for configuration persisting, because
+ * {@code ChronicleHashBuilder}s are mutable and changed on each configuration method call.
+ * Original and cloned builders are independent.
+ *
+ * @return a new clone of this builder
+ */
B clone();
/**
- * Set minimum number of segments. See concurrencyLevel in {@link ConcurrentHashMap}.
+ * Set minimum number of segments in hash containers, constructed by this builder.
+ * See concurrencyLevel in {@link ConcurrentHashMap}.
*
* @param minSegments the minimum number of segments in containers, constructed by this builder
* @return this builder object back
@@ -43,13 +55,14 @@ public interface ChronicleHashBuilderIf key size varies moderately, specify the size higher than average, but lower than the maximum
- * possible, to minimize average memory overuse. If key size varies in a wide range, it's better to use
- * {@linkplain #entrySize(int) entry size} in "chunk" mode and configure it directly.
+ * If key size varies moderately, specify the size higher than average, but lower than
+ * the maximum possible, to minimize average memory overuse. If key size varies in a wide range,
+ * it's better to use {@linkplain #entrySize(int) entry size} in "chunk" mode and configure it
+ * directly.
*
* @param keySize number of bytes, taken by serialized form of keys
* @return this builder back
@@ -59,15 +72,15 @@ public interface ChronicleHashBuilderIf keys are of boxed primitive type or {@link Byteable} subclass, i. e. if key size is known
- * statically, it is automatically accounted and this method shouldn't be called.
+ * If keys are of boxed primitive type or {@link Byteable} subclass, i. e. if key size
+ * is known statically, it is automatically accounted and this method shouldn't be called.
*
- *
If key size varies, method {@link #keySize(int)} or {@link #entrySize(int)} should be called instead
- * of this one.
+ *
If key size varies, method {@link #keySize(int)} or {@link #entrySize(int)} should be
+ * called instead of this one.
*
* @param sampleKey the sample key
* @return this builder back
@@ -76,43 +89,55 @@ public interface ChronicleHashBuilder{@link ChronicleMap} and {@link ChronicleSet} store their data off-heap, so it is required to
- * serialize key (and values, in {@code ChronicleMap} case) (unless they are direct {@link Byteable}
- * instances). Serialized key bytes (+ serialized value bytes, in {@code ChronicleMap} case) + some
- * metadata bytes comprise "entry space", which {@code ChronicleMap} or {@code ChronicleSet} should
- * allocate. So entry size is a minimum allocation portion in the hash containers, created by this
- * builder. E. g. if entry size is 100, the created container could only allocate 100, 200, 300... bytes
- * for an entry. If say 150 bytes of entry space are required by the entry, 200 bytes will be allocated,
- * 150 used and 50 wasted. To minimize memory overuse and improve speed, you should pay decent attention
- * to this configuration.
+ * {@link ChronicleMap} and {@link ChronicleSet} store their data off-heap, so it is required
+ * to serialize key (and values, in {@code ChronicleMap} case) (unless they are direct
+ * {@link Byteable} instances). Serialized key bytes (+ serialized value bytes,
+ * in {@code ChronicleMap} case) + some metadata bytes comprise "entry space", which
+ * {@code ChronicleMap} or {@code ChronicleSet} should allocate. So entry size
+ * is a minimum allocation portion in the hash containers, created by this builder.
+ * E. g. if entry size is 100, the created container could only allocate 100, 200, 300... bytes
+ * for an entry. If say 150 bytes of entry space are required by the entry, 200 bytes
+ * will be allocated, 150 used and 50 wasted. To minimize memory overuse and improve speed, you
+ * should pay decent attention to this configuration.
*
- *
There are three major patterns of this configuration usage:
- Key (and value, in {@code
- * ChronicleMap} case) sizes are constant. Configure them via {@link #constantKeySizeBySample(Object)} and
- * {@link ChronicleMapBuilder#constantValueSizeBySample(Object)} methods, and you will experience no
- * memory waste at all.
- 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 maximum possible. The idea is to have most (90% or more) entries to
- * fit a single "entry size" with moderate memory waste (10-20% on average), rest 10% or less of entries
- * should take 2 "entry sizes", thus with ~50% memory overuse.
- Key (and/or value size, in {@code
- * ChronicleMap} case) varies in a wide range. Then it's best to use entry size configuration in chunk
- * mode. Specify entry size so that most entries should take from 5 to several dozens of "chunks".
- * With this approach, average memory waste should be very low.
+ *
There are three major patterns of this configuration usage:
+ *
+ * - Key (and value, in {@code ChronicleMap} case) sizes are constant. Configure them
+ * via {@link #constantKeySizeBySample(Object)} and
+ * {@link ChronicleMapBuilder#constantValueSizeBySample(Object)} methods, and you will
+ * experience no memory waste at all.
+ * - 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 maximum possible. The idea is to have most
+ * (90% or more) entries to fit a single "entry size" with moderate memory waste
+ * (10-20% on average), rest 10% or less of entries should take 2 "entry sizes", thus with
+ * ~50% memory overuse.
+ * - Key (and/or value size, in {@code ChronicleMap} case) varies in a wide range.
+ * Then it's best to use entry size configuration in chunk mode. Specify entry size
+ * so that most entries should take from 5 to several dozens of "chunks". With this
+ * approach, average memory waste should be very low.
*
- *
However, remember that
- Operations with entries that span several "entry sizes" are a bit
- * slower, than entries which take a single "entry size". That is why "chunk" approach is not recommended,
- * when key (and/or value size) varies moderately.
- The maximum number of chunks could be taken by
- * an entry is 64. {@link IllegalArgumentException} is thrown on attempt to insert too large entry,
- * compared to the configured or computed entry size.
- The number of "entries" {@linkplain
- * #entries(long) in the whole map} and {@linkplain #actualEntriesPerSegment(int) per segment} is actually
- * the number "chunks".
+ * However, remember that
+ *
+ * - Operations with entries that span several "entry sizes" are a bit slower, than
+ * entries which take a single "entry size". That is why "chunk" approach
+ * is not recommended, when key (and/or value size) varies moderately.
+ * - The maximum number of chunks could be taken by an entry is 64.
+ * {@link IllegalArgumentException} is thrown on attempt to insert too large entry,
+ * compared to the configured or computed entry size.
+ * - The number of "entries" {@linkplain #entries(long) in the whole map} and
+ * {@linkplain #actualEntriesPerSegment(int) per segment} is actually the number
+ * "chunks".
+ *
*
- * Example: if values in your {@code ChronicleMap} are adjacency lists of some social graph, where
- * nodes are represented as {@code long} ids, and adjacency lists are serialized in efficient manner, for
- * example as {@code long[]} arrays. Typical number of connections is 100-300, maximum is 3000. In this
- * case entry size of
- * 50 * (8 bytes for each id) = 400 bytes would be a good choice:
{@code
+ * Example: if values in your {@code ChronicleMap} are adjacency lists of some social
+ * graph, where nodes are represented as {@code long} ids, and adjacency lists
+ * are serialized in efficient manner, for example as {@code long[]} arrays. Typical number
+ * of connections is 100-300, maximum is 3000. In this case entry size of
+ * 50 * (8 bytes for each id) = 400 bytes would be a good choice:
{@code
* Map socialGraph = ChronicleMapBuilder
* .of(Long.class, long[].class)
* // given that graph should have of 1 billion nodes, and 150 average adjacency list size
@@ -120,8 +145,11 @@ public interface ChronicleHashBuilder
- * It is minimum possible (because 3000 friends / 50 friends = 60 is close to 64 "max chunks by single
- * entry" limit, and ensures moderate average memory overuse (not more than 20%).
+ * It is minimum possible (because 3000 friends / 50 friends = 60 is close to 64 "max
+ * chunks by single entry" limit, and ensures moderate average memory overuse (not more
+ * than 20%).
+ *
+ *
*
* @param entrySize the "chunk size" in bytes
* @return this builder back
@@ -130,28 +158,35 @@ public interface ChronicleHashBuilder If key size (and value size, in {@code ChronicleMap} case) is constant, this number is equal
- * to the maximum number of entries (because each entry takes exactly one "entry size" memory unit).
- * 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. 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.
+ *
+ * - If key size (and value size, in {@code ChronicleMap} case) is constant, this number
+ * is equal to the maximum number of entries (because each entry takes exactly one
+ * "entry size" memory unit).
+ * - 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.
+ * - 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.
+ *
*
- * You shouldn't put additional margin over the number, computed according the rules above. This bad
- * practice was popularized by {@link HashMap#HashMap(int)} and {@link HashSet#HashSet(int)} constructors,
- * which accept "capacity", that should be multiplied by "load factor" to obtain actual maximum expected
- * number of entries. {@code ChronicleMap} and {@code ChronicleSet} don't have a notion of load factor.
+ *
You shouldn't put additional margin over the number, computed according the rules above.
+ * This bad practice was popularized by {@link HashMap#HashMap(int)}
+ * and {@link HashSet#HashSet(int)} constructors, which accept "capacity", that should
+ * be multiplied by "load factor" to obtain actual maximum expected number of entries.
+ * {@code ChronicleMap} and {@code ChronicleSet} don't have a notion of load factor.
*
*
Default value is 2^20 (~ 1 million).
*
- * @param entries maximum size of the created maps, in memory allocation units, so-called "entry size"
+ * @param entries maximum size of the created maps, in memory allocation units,
+ * so-called "entry size"
* @return this builder back
* @see #entrySize(int)
*/
@@ -161,6 +196,22 @@ public interface ChronicleHashBuilderDefault lock time out is 2 seconds.
+ *
+ * @param lockTimeOut new lock timeout for segments of containers created by this builder,
+ * in the given time units
+ * @param unit time unit of the given lock timeout
+ * @return this builder back
+ */
B lockTimeOut(long lockTimeOut, TimeUnit unit);
B errorListener(ChronicleHashErrorListener errorListener);
@@ -169,34 +220,182 @@ public interface ChronicleHashBuilder
+ * the section about replication in ChronicleMap manual for more information.
+ *
+ * Another way to establish replication is {@link #channel(ChannelProvider.ChronicleChannel)}
+ * method.
+ *
+ *
By default, hash containers, created by this builder doesn't replicate their data.
+ *
+ *
This method call overrides all previous replication configurations of this builder, made
+ * either by this method or {@link #channel(ChannelProvider.ChronicleChannel)} method.
+ *
+ * @param identifier the new {@linkplain Replica#identifier() identifier} of the containers,
+ * created by this builder
+ * @param replicators several replicators, used to sync the data across replicating nodes
+ * independently
+ * @return this builder back
+ * @see #channel(ChannelProvider.ChronicleChannel)
+ * @see #disableReplication()
+ */
B replicators(byte identifier, ReplicationConfig... replicators);
+ /**
+ * Configures replication of the hash containers, created by this builder,
+ * via so called "channels". See the section
+ * about Channels and ChannelProvider in ChronicleMap manual for more information.
+ *
+ *
Another way to establish replication if {@link #replicators(byte, ReplicationConfig[])}
+ * method.
+ *
+ *
By default, hash containers, created by this builder doesn't replicate their data.
+ *
+ *
This method call overrides all previous replication configurations of this builder, made
+ * either by means of this method or {@link #replicators(byte, ReplicationConfig[])} method
+ * calls.
+ *
+ * @param chronicleChannel the channel responsible for gathering updates of hash containers,
+ * created by this builder, and replicating them over network
+ * @return this builder object back
+ * @see #replicators(byte, ReplicationConfig[])
+ * @see #disableReplication()
+ */
B channel(ChannelProvider.ChronicleChannel chronicleChannel);
+ /**
+ * Specifies that hash containers, created by this builder, shouldn't replicate their data over
+ * network. This method call clears any replication configurations, made via {@link
+ * #replicators(byte, ReplicationConfig[])} or {@link #channel(
+ * ChannelProvider.ChronicleChannel)} method call.
+ *
+ *
By default replication is not configured, so this method is useful only to ensure
+ * that hash containers, created by some inherited or passed builder, wouldn't replicate. I. e.
+ * in rare cases.
+ *
+ * @return this builder back
+ * @see #replicators(byte, ReplicationConfig[])
+ * @see #channel(ChannelProvider.ChronicleChannel)
+ */
+ B disableReplication();
+
+ /**
+ * Configures a time provider, used by hash containers, created by this builder, for needs of
+ * replication consensus protocol (conflicting data updates resolution).
+ *
+ *
Default time provider is {@link TimeProvider#SYSTEM}.
+ * @param timeProvider a new time provider for replication needs
+ * @return this builder back
+ * @see #replicators(byte, ReplicationConfig[])
+ * @see #channel(ChannelProvider.ChronicleChannel)
+ */
B timeProvider(TimeProvider timeProvider);
+ /**
+ * Configures a {@link BytesMarshallerFactory} to be used with
+ * {@link BytesMarshallableSerializer}, which is a default {@link #objectSerializer
+ * ObjectSerializer}, to serialize/deserialize data to/from off-heap memory in hash containers,
+ * created by this builder.
+ *
+ *
Default {@code BytesMarshallerFactory} is an instance of {@link
+ * VanillaBytesMarshallerFactory}. This is a convenience configuration method, it has no effect
+ * on the resulting hash containers, if {@linkplain #keyMarshaller(BytesMarshaller) custom data
+ * marshallers} are configured, data types extends one of specific serialization interfaces,
+ * recognized by this builder (e. g. {@code Externalizable} or {@code BytesMarshallable}),
+ * or {@code ObjectSerializer} is configured.
+ *
+ * @param bytesMarshallerFactory the marshaller factory to be used with the default
+ * {@code ObjectSerializer}, i. e. {@code BytesMarshallableSerializer}
+ * @return this builder back
+ * @see #objectSerializer(ObjectSerializer)
+ */
B bytesMarshallerFactory(BytesMarshallerFactory bytesMarshallerFactory);
+ /**
+ * Configures the serializer used to serialize/deserialize data to/from off-heap memory, when
+ * specified class doesn't implement a specific serialization interface like {@link
+ * Externalizable} or {@link BytesMarshallable} (for example, if data is loosely typed and just
+ * {@code Object} is specified as the data class), or nullable data, and if custom marshaller
+ * is not {@linkplain #keyMarshaller(BytesMarshaller) configured}, in hash containers, created
+ * by this builder. Please read {@link ObjectSerializer} docs for more info and available
+ * options.
+ *
+ *
Default serializer is {@link BytesMarshallableSerializer}, configured with the specified
+ * or default {@link #bytesMarshallerFactory(BytesMarshallerFactory) BytesMarshallerFactory}.
+ *
+ * @param objectSerializer the serializer used to serialize loosely typed or nullable data
+ * if custom marshaller is not configured
+ * @return this builder back
+ * @see #bytesMarshallerFactory(BytesMarshallerFactory)
+ * @see #keyMarshaller(BytesMarshaller)
+ */
B objectSerializer(ObjectSerializer objectSerializer);
+ /**
+ * Configures the {@code BytesMarshaller} used to serialize/deserialize keys to/from off-heap
+ * memory in hash containers, created by this builder. See the section about serialization
+ * in ChronicleMap manual for more information.
+ *
+ * @param keyMarshaller the marshaller used to serialize keys
+ * @return this builder back
+ * @see #objectSerializer(ObjectSerializer)
+ */
B keyMarshaller(@NotNull BytesMarshaller keyMarshaller);
/**
- * Specifies that key objects, queried with the hash containers, created by this builder, are inherently
- * immutable. Keys in {@link ChronicleMap} or {@link ChronicleSet} are not required to be immutable, as in
- * ordinary {@link Map} or {@link Set} implementations, because they are serialized off-heap. However,
- * {@code ChronicleMap} and {@code ChronicleSet} implementations can benefit from the knowledge that keys
- * are not mutated between queries.
+ * Specifies that key objects, queried with the hash containers, created by this builder,
+ * are inherently immutable. Keys in {@link ChronicleMap} or {@link ChronicleSet}
+ * are not required to be immutable, as in ordinary {@link Map} or {@link Set} implementations,
+ * because they are serialized off-heap. However, {@code ChronicleMap} and {@code ChronicleSet}
+ * implementations can benefit from the knowledge that keys are not mutated between queries.
*
- * By default, {@code ChronicleHashBuilder}s detects immutability automatically only for very few
- * standard JDK types (for example, for {@link String}), it is not recommended to rely on {@code
- * ChronicleHashBuilder} to be smart enough about this.
+ *
By default, {@code ChronicleHashBuilder}s detects immutability automatically
+ * only for very few standard JDK types (for example, for {@link String}), it is not recommended
+ * to rely on {@code ChronicleHashBuilder} to be smart enough about this.
*
* @return this builder back
*/
B immutableKeys();
+ /**
+ * Opens a hash container residing the specified file, or creates a new one if the file not yet
+ * exists and maps its off-heap memory to the file. All changes to the map are persisted to disk
+ * (this is an operating system guarantee) independently from JVM process lifecycle.
+ *
+ *
Multiple containers could give access to the same data simultaneously, either inside
+ * a single JVM or across processes. Access is synchronized correctly across all instances,
+ * i. e. hash container mapping the data from the first JVM isn't able to modify the data,
+ * concurrently accessed from the second JVM by another hash container instance, mapping
+ * the same data.
+ *
+ *
On container's {@link ChronicleHash#close() close()} the data isn't removed, it remains
+ * on disk and available to be opened again (given the same file name) or during different JVM
+ * run.
+ *
+ * @param file the file with existing hash container or a desired location of a new off-heap
+ * persisted hash container
+ * @return a hash container mapped to the given file
+ * @throws IOException if any IO error, related to off-heap memory allocation or file mapping
+ * occurs
+ * @see ChronicleHash#file()
+ * @see ChronicleHash#close()
+ * @see #create()
+ */
C create(File file) throws IOException;
+ /**
+ * Creates a new hash container, storing it's data in off-heap memory, not mapped to any file.
+ * On {@link ChronicleHash#close()} called on the returned container, or after the container
+ * object is collected during GC, or on JVM shutdown the off-heap memory used by the returned
+ * container is freed.
+ *
+ * @return a new off-heap hash container
+ * @throws IOException if any IO error relates to off-heap memory allocation occurs
+ * @see #create()
+ */
C create() throws IOException;
}
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
index 57385aa98..fc28db0f2 100644
--- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
+++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
@@ -17,15 +17,13 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.ChronicleHash;
-import net.openhft.chronicle.map.serialization.BytesReader;
+import net.openhft.chronicle.serialization.BytesReader;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.BytesMarshaller;
import net.openhft.lang.io.serialization.ObjectFactory;
import net.openhft.lang.model.Byteable;
import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
index c400f0f43..b2d016bfc 100644
--- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
+++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
@@ -20,12 +20,13 @@ import net.openhft.chronicle.ChronicleHashBuilder;
import net.openhft.chronicle.ChronicleHashErrorListener;
import net.openhft.chronicle.ChronicleHashErrorListeners;
import net.openhft.chronicle.TimeProvider;
-import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
-import net.openhft.chronicle.map.serialization.MetaBytesInterop;
-import net.openhft.chronicle.map.serialization.MetaBytesWriter;
-import net.openhft.chronicle.map.serialization.MetaProvider;
-import net.openhft.chronicle.map.threadlocal.Provider;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.serialization.AgileBytesMarshaller;
+import net.openhft.chronicle.serialization.MetaBytesInterop;
+import net.openhft.chronicle.serialization.MetaBytesWriter;
+import net.openhft.chronicle.serialization.MetaProvider;
+import net.openhft.chronicle.set.ChronicleSetBuilder;
+import net.openhft.chronicle.threadlocal.Provider;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
import net.openhft.lang.Maths;
import net.openhft.lang.io.ByteBufferBytes;
import net.openhft.lang.io.Bytes;
@@ -66,9 +67,8 @@ import static net.openhft.chronicle.map.Objects.builderEquals;
*
*
Use static {@link #of(Class, Class)} method to obtain a {@code ChronicleMapBuilder} instance.
*
- *
{@code ChronicleMapBuilder} is mutable. Configuration methods mutate the builder and return the
- * builder itself back to support chaining pattern, rather than the builder copies with the corresponding
- * configuration changed. To make an independent configuration, {@linkplain #clone} the builder.
+ *
{@code ChronicleMapBuilder} is mutable, see a note in {@link ChronicleHashBuilder} interface
+ * documentation.
*
*
Later in this documentation, "ChronicleMap" means "ChronicleMaps, created by {@code
* ChronicleMapBuilder}", unless specified different, because theoretically someone might provide {@code
@@ -85,6 +85,8 @@ import static net.openhft.chronicle.map.Objects.builderEquals;
*
* @param key type of the maps, produced by this builder
* @param value type of the maps, produced by this builder
+ * @see ChronicleMap
+ * @see ChronicleSetBuilder
*/
public class ChronicleMapBuilder implements Cloneable,
ChronicleHashBuilder, ChronicleMapBuilder> {
@@ -586,6 +588,13 @@ public class ChronicleMapBuilder implements Cloneable,
return this;
}
+ @Override
+ public ChronicleMapBuilder disableReplication() {
+ identifier = -1;
+ replicators.clear();
+ return this;
+ }
+
@Override
public ChronicleMapBuilder timeProvider(TimeProvider timeProvider) {
this.timeProvider = timeProvider;
@@ -615,6 +624,22 @@ public class ChronicleMapBuilder implements Cloneable,
objectSerializer;
}
+ /**
+ * {@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 #valueMarshallerAndFactory(BytesMarshaller, ObjectFactory) value} marshallers
+ * are not configured.
+ */
@Override
public ChronicleMapBuilder objectSerializer(ObjectSerializer objectSerializer) {
this.objectSerializer = objectSerializer;
@@ -622,6 +647,11 @@ public class ChronicleMapBuilder implements Cloneable,
}
+ /**
+ * {@inheritDoc}
+ *
+ * Example:
+ */
@Override
public ChronicleMapBuilder keyMarshaller(@NotNull BytesMarshaller keyMarshaller) {
keyBuilder.marshaller(keyMarshaller, null);
diff --git a/src/main/java/net/openhft/chronicle/map/ConstantValueProvider.java b/src/main/java/net/openhft/chronicle/map/ConstantValueProvider.java
index b6b9ff825..048b5bb64 100644
--- a/src/main/java/net/openhft/chronicle/map/ConstantValueProvider.java
+++ b/src/main/java/net/openhft/chronicle/map/ConstantValueProvider.java
@@ -16,8 +16,8 @@
package net.openhft.chronicle.map;
-import net.openhft.chronicle.map.serialization.BytesReader;
-import net.openhft.chronicle.map.serialization.MetaBytesWriter;
+import net.openhft.chronicle.serialization.BytesReader;
+import net.openhft.chronicle.serialization.MetaBytesWriter;
import net.openhft.lang.io.ByteBufferBytes;
import java.nio.ByteBuffer;
diff --git a/src/main/java/net/openhft/chronicle/map/MapEventListener.java b/src/main/java/net/openhft/chronicle/map/MapEventListener.java
index 8bde8ff79..36a6450d7 100644
--- a/src/main/java/net/openhft/chronicle/map/MapEventListener.java
+++ b/src/main/java/net/openhft/chronicle/map/MapEventListener.java
@@ -21,10 +21,29 @@ import net.openhft.lang.io.Bytes;
import java.io.Serializable;
/**
- * This event listener is called when key events occur.
- * All these calls are synchronous while a lock is held so make them as quick as possible
- *
- * TODO specify more clearly in which cases methods are called.
+ * Contains methods which are called when {@link ChronicleMap} key events occur. Typical use cases:
+ *
+ * - Map data backup / replication.
+ * - Logging, monitoring, debugging.
+ *
+ *
+ * This is an adapter class - all methods have default implementations as no-ops. Extend this
+ * class and override only methods corresponding the events you are interested in.
+ *
+ *
To configure {@code MapEventListener} for {@code ChronicleMap}, use
+ * {@link ChronicleMapBuilder#eventListener(MapEventListener)} method.
+ *
+ *
{@link MapEventListeners} uninstantiable class contains several logging implementations and
+ * the default {@linkplain MapEventListeners#nop() no-op implementation}.
+ *
+ *
All these calls are synchronous while a {@code ChronicleMap} lock is held so make them
+ * as quick as possible.
+ *
+ * @param key type of the maps, trackable by this event listener
+ * @param value type of the maps, trackable by this event listener
+ * @param {@code ChronicleMap} subtype, trackable by this event listener
+ * @see ChronicleMapBuilder#eventListener(MapEventListener)
+ * @see MapEventListeners
*/
public abstract class MapEventListener>
implements Serializable {
@@ -51,14 +70,23 @@ public abstract class MapEventListener>
}
/**
- * This method is called if a key/value is put in the map.
+ * This method is call whenever a new value is put for the key in the map during calls of such
+ * methods as {@link ChronicleMap#put put}, {@link ChronicleMap#putIfAbsent putIfAbsent},
+ * {@link ChronicleMap#replace(Object, Object, Object) replace}, etc. When a new value is
+ * {@linkplain ChronicleMapBuilder#defaultValue(Object) default} for the map or obtained during
+ * {@link ChronicleMap#acquireUsing acquireUsing} call is put for the key, this method is called
+ * as well.
*
- * @param map accessed
- * @param entry added/modified
- * @param metaDataBytes length of the meta data
- * @param added if this is a new entry
- * @param key looked up
- * @param value set for key
+ * This method is called when put is already happened.
+ *
+ * @param map the accessed map
+ * @param entry bytes of the entry (with the value already written to)
+ * @param metaDataBytes length of meta data for this map
+ * @param added {@code true} is the key was absent in the map before current
+ * {@code ChronicleMap} method call, led to putting a value and inherently
+ * calling this listener method
+ * @param key the key the value is put for
+ * @param value the value which was associated with the key
*/
public void onPut(M map, Bytes entry, int metaDataBytes, boolean added, K key, V value) {
// do nothing
@@ -85,6 +113,4 @@ public abstract class MapEventListener>
void onRelocation(int pos, SharedSegment segment) {
// do nothing
}
-
-
}
diff --git a/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java
index 6c768546e..113cf982e 100644
--- a/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java
+++ b/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java
@@ -18,10 +18,10 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.TimeProvider;
-import net.openhft.chronicle.map.serialization.BytesReader;
-import net.openhft.chronicle.map.serialization.MetaBytesInterop;
-import net.openhft.chronicle.map.serialization.MetaBytesWriter;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.serialization.BytesReader;
+import net.openhft.chronicle.serialization.MetaBytesInterop;
+import net.openhft.chronicle.serialization.MetaBytesWriter;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
import net.openhft.lang.Maths;
import net.openhft.lang.collection.ATSDirectBitSet;
import net.openhft.lang.io.Bytes;
@@ -38,7 +38,7 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicReferenceArray;
-import static net.openhft.chronicle.map.serialization.Hasher.hash;
+import static net.openhft.chronicle.serialization.Hasher.hash;
import static net.openhft.lang.collection.DirectBitSet.NOT_FOUND;
/**
diff --git a/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java b/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java
index e95967aa9..22bca8eaa 100644
--- a/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java
+++ b/src/main/java/net/openhft/chronicle/map/SerializationBuilder.java
@@ -16,10 +16,10 @@
package net.openhft.chronicle.map;
-import net.openhft.chronicle.map.serialization.*;
-import net.openhft.chronicle.map.serialization.impl.*;
-import net.openhft.chronicle.map.threadlocal.Provider;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.threadlocal.Provider;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.serialization.*;
+import net.openhft.chronicle.serialization.impl.*;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.BytesMarshallable;
import net.openhft.lang.io.serialization.BytesMarshaller;
@@ -36,7 +36,7 @@ import java.io.Serializable;
import java.lang.reflect.Modifier;
import static net.openhft.chronicle.map.Objects.hash;
-import static net.openhft.chronicle.map.serialization.SizeMarshallers.stopBit;
+import static net.openhft.chronicle.serialization.SizeMarshallers.stopBit;
final class SerializationBuilder implements Cloneable {
@@ -99,6 +99,9 @@ final class SerializationBuilder implements Cloneable {
} else if (eClass == byte[].class) {
reader((BytesReader) ByteArrayMarshaller.INSTANCE, factory);
interop((BytesInterop) ByteArrayMarshaller.INSTANCE);
+ } else if (eClass == char[].class) {
+ reader((BytesReader) CharArrayMarshaller.INSTANCE, factory);
+ interop((BytesInterop) CharArrayMarshaller.INSTANCE);
} else if (concreteClass(eClass)) {
BytesMarshaller marshaller = chooseMarshaller(eClass, eClass);
if (marshaller != null)
diff --git a/src/main/java/net/openhft/chronicle/map/Serializer.java b/src/main/java/net/openhft/chronicle/map/Serializer.java
index d30bb388a..d459d2ceb 100644
--- a/src/main/java/net/openhft/chronicle/map/Serializer.java
+++ b/src/main/java/net/openhft/chronicle/map/Serializer.java
@@ -1,8 +1,8 @@
package net.openhft.chronicle.map;
-import net.openhft.chronicle.map.serialization.*;
-import net.openhft.chronicle.map.threadlocal.Provider;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.threadlocal.Provider;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.serialization.*;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.model.Byteable;
import net.openhft.lang.model.constraints.NotNull;
diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java
index d34852d43..495c01d95 100644
--- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java
+++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java
@@ -17,9 +17,9 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.ChronicleHashErrorListener;
-import net.openhft.chronicle.map.serialization.*;
-import net.openhft.chronicle.map.threadlocal.Provider;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.threadlocal.Provider;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.serialization.*;
import net.openhft.lang.Maths;
import net.openhft.lang.collection.DirectBitSet;
import net.openhft.lang.collection.SingleThreadedDirectBitSet;
@@ -969,8 +969,10 @@ class VanillaChronicleMap,
}
/**
- * Removes a key (or key-value pair) from the Segment. The entry will only be removed if {@code
- * expectedValue} equals to {@code null} or the value previously corresponding to the specified key.
+ * Removes a key (or key-value pair) from the Segment.
+ *
+ * The entry will only be removed if {@code expectedValue} equals to {@code null}
+ * or the value previously corresponding to the specified key.
*
* @param hash2 a hash code related to the {@code keyBytes}
* @return the value of the entry that was removed if the entry corresponding to the {@code keyBytes}
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/AgileBytesMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/AgileBytesMarshaller.java
similarity index 93%
rename from src/main/java/net/openhft/chronicle/map/serialization/AgileBytesMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/AgileBytesMarshaller.java
index d3cd897b1..205a19115 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/AgileBytesMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/AgileBytesMarshaller.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
public interface AgileBytesMarshaller extends BytesReader, BytesInterop, SizeMarshaller {
}
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/BytesInterop.java b/src/main/java/net/openhft/chronicle/serialization/BytesInterop.java
similarity index 96%
rename from src/main/java/net/openhft/chronicle/map/serialization/BytesInterop.java
rename to src/main/java/net/openhft/chronicle/serialization/BytesInterop.java
index 71a23a127..ac3ebf74f 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/BytesInterop.java
+++ b/src/main/java/net/openhft/chronicle/serialization/BytesInterop.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.model.Byteable;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/BytesReader.java b/src/main/java/net/openhft/chronicle/serialization/BytesReader.java
similarity index 94%
rename from src/main/java/net/openhft/chronicle/map/serialization/BytesReader.java
rename to src/main/java/net/openhft/chronicle/serialization/BytesReader.java
index e3dcabe48..ec559a713 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/BytesReader.java
+++ b/src/main/java/net/openhft/chronicle/serialization/BytesReader.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/BytesReaders.java b/src/main/java/net/openhft/chronicle/serialization/BytesReaders.java
similarity index 96%
rename from src/main/java/net/openhft/chronicle/map/serialization/BytesReaders.java
rename to src/main/java/net/openhft/chronicle/serialization/BytesReaders.java
index c0e2e7398..b95b7a5e5 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/BytesReaders.java
+++ b/src/main/java/net/openhft/chronicle/serialization/BytesReaders.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.BytesMarshaller;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/BytesWriter.java b/src/main/java/net/openhft/chronicle/serialization/BytesWriter.java
similarity index 94%
rename from src/main/java/net/openhft/chronicle/map/serialization/BytesWriter.java
rename to src/main/java/net/openhft/chronicle/serialization/BytesWriter.java
index ed8ecad11..b120ac778 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/BytesWriter.java
+++ b/src/main/java/net/openhft/chronicle/serialization/BytesWriter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/CopyingMetaBytesInterop.java b/src/main/java/net/openhft/chronicle/serialization/CopyingMetaBytesInterop.java
similarity index 97%
rename from src/main/java/net/openhft/chronicle/map/serialization/CopyingMetaBytesInterop.java
rename to src/main/java/net/openhft/chronicle/serialization/CopyingMetaBytesInterop.java
index 79e6111e3..362756e1a 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/CopyingMetaBytesInterop.java
+++ b/src/main/java/net/openhft/chronicle/serialization/CopyingMetaBytesInterop.java
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
-import net.openhft.chronicle.map.threadlocal.Provider;
-import net.openhft.chronicle.map.threadlocal.StatefulCopyable;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.threadlocal.Provider;
+import net.openhft.chronicle.threadlocal.StatefulCopyable;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.DirectBytes;
import net.openhft.lang.io.DirectStore;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/DelegatingMetaBytesInterop.java b/src/main/java/net/openhft/chronicle/serialization/DelegatingMetaBytesInterop.java
similarity index 97%
rename from src/main/java/net/openhft/chronicle/map/serialization/DelegatingMetaBytesInterop.java
rename to src/main/java/net/openhft/chronicle/serialization/DelegatingMetaBytesInterop.java
index 4413252a9..90c57f7f6 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/DelegatingMetaBytesInterop.java
+++ b/src/main/java/net/openhft/chronicle/serialization/DelegatingMetaBytesInterop.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/DelegatingMetaBytesInteropProvider.java b/src/main/java/net/openhft/chronicle/serialization/DelegatingMetaBytesInteropProvider.java
similarity index 93%
rename from src/main/java/net/openhft/chronicle/map/serialization/DelegatingMetaBytesInteropProvider.java
rename to src/main/java/net/openhft/chronicle/serialization/DelegatingMetaBytesInteropProvider.java
index 2544d2d61..e17afa503 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/DelegatingMetaBytesInteropProvider.java
+++ b/src/main/java/net/openhft/chronicle/serialization/DelegatingMetaBytesInteropProvider.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
import java.io.ObjectStreamException;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/Hasher.java b/src/main/java/net/openhft/chronicle/serialization/Hasher.java
similarity index 98%
rename from src/main/java/net/openhft/chronicle/map/serialization/Hasher.java
rename to src/main/java/net/openhft/chronicle/serialization/Hasher.java
index f6b431686..c113707a7 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/Hasher.java
+++ b/src/main/java/net/openhft/chronicle/serialization/Hasher.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.NativeBytes;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/MetaBytesInterop.java b/src/main/java/net/openhft/chronicle/serialization/MetaBytesInterop.java
similarity index 94%
rename from src/main/java/net/openhft/chronicle/map/serialization/MetaBytesInterop.java
rename to src/main/java/net/openhft/chronicle/serialization/MetaBytesInterop.java
index d900b9bfd..72d94702e 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/MetaBytesInterop.java
+++ b/src/main/java/net/openhft/chronicle/serialization/MetaBytesInterop.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/MetaBytesWriter.java b/src/main/java/net/openhft/chronicle/serialization/MetaBytesWriter.java
similarity index 94%
rename from src/main/java/net/openhft/chronicle/map/serialization/MetaBytesWriter.java
rename to src/main/java/net/openhft/chronicle/serialization/MetaBytesWriter.java
index 493bee0d7..2c1a029d2 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/MetaBytesWriter.java
+++ b/src/main/java/net/openhft/chronicle/serialization/MetaBytesWriter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/MetaProvider.java b/src/main/java/net/openhft/chronicle/serialization/MetaProvider.java
similarity index 88%
rename from src/main/java/net/openhft/chronicle/map/serialization/MetaProvider.java
rename to src/main/java/net/openhft/chronicle/serialization/MetaProvider.java
index b9620ce61..9c5a3661c 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/MetaProvider.java
+++ b/src/main/java/net/openhft/chronicle/serialization/MetaProvider.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
-import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
+import net.openhft.chronicle.threadlocal.ThreadLocalCopies;
import java.io.Serializable;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/SizeMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/SizeMarshaller.java
similarity index 94%
rename from src/main/java/net/openhft/chronicle/map/serialization/SizeMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/SizeMarshaller.java
index 024af8558..e4f0c3755 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/SizeMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/SizeMarshaller.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/SizeMarshallers.java b/src/main/java/net/openhft/chronicle/serialization/SizeMarshallers.java
similarity index 86%
rename from src/main/java/net/openhft/chronicle/map/serialization/SizeMarshallers.java
rename to src/main/java/net/openhft/chronicle/serialization/SizeMarshallers.java
index d5fdbc810..99254d13e 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/SizeMarshallers.java
+++ b/src/main/java/net/openhft/chronicle/serialization/SizeMarshallers.java
@@ -14,10 +14,12 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization;
+package net.openhft.chronicle.serialization;
import net.openhft.lang.io.Bytes;
+import static net.openhft.lang.io.IOTools.stopBitLength;
+
public final class SizeMarshallers {
public static SizeMarshaller stopBit() {
@@ -29,11 +31,7 @@ public final class SizeMarshallers {
@Override
public int sizeEncodingSize(long size) {
- if (size <= 127)
- return 1;
- // numberOfLeadingZeros is cheap intrinsic on modern CPUs
- // integral division is not... but there is no choice
- return ((70 - Long.numberOfLeadingZeros(size)) / 7);
+ return stopBitLength(size);
}
@Override
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/ByteArrayMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/impl/ByteArrayMarshaller.java
similarity index 88%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/ByteArrayMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/ByteArrayMarshaller.java
index 681c8513c..705723651 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/ByteArrayMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/ByteArrayMarshaller.java
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
-import net.openhft.chronicle.map.serialization.BytesInterop;
-import net.openhft.chronicle.map.serialization.BytesReader;
-import net.openhft.chronicle.map.serialization.Hasher;
+import net.openhft.chronicle.serialization.BytesInterop;
+import net.openhft.chronicle.serialization.BytesReader;
+import net.openhft.chronicle.serialization.Hasher;
import net.openhft.lang.io.Bytes;
public enum ByteArrayMarshaller implements BytesInterop, BytesReader {
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/ByteableMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/impl/ByteableMarshaller.java
similarity index 96%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/ByteableMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/ByteableMarshaller.java
index 2355662ea..977bbe4cd 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/ByteableMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/ByteableMarshaller.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
-import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
-import net.openhft.chronicle.map.serialization.Hasher;
+import net.openhft.chronicle.serialization.AgileBytesMarshaller;
+import net.openhft.chronicle.serialization.Hasher;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.NativeBytes;
import net.openhft.lang.io.serialization.*;
diff --git a/src/main/java/net/openhft/chronicle/serialization/impl/CharArrayMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/impl/CharArrayMarshaller.java
new file mode 100644
index 000000000..d995b106e
--- /dev/null
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/CharArrayMarshaller.java
@@ -0,0 +1,66 @@
+/*
+ * 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.serialization.impl;
+
+import net.openhft.chronicle.serialization.BytesInterop;
+import net.openhft.chronicle.serialization.BytesReader;
+import net.openhft.chronicle.serialization.Hasher;
+import net.openhft.lang.io.Bytes;
+
+public enum CharArrayMarshaller implements BytesInterop, BytesReader {
+ INSTANCE;
+
+ @Override
+ public boolean startsWith(Bytes bytes, char[] chars) {
+ long pos = bytes.position();
+ for (int i = 0; i < chars.length; i++) {
+ if (bytes.readChar(pos + (i * 2L)) != chars[i])
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public long hash(char[] chars) {
+ return Hasher.hash(chars, chars.length);
+ }
+
+ @Override
+ public char[] read(Bytes bytes, long size) {
+ char[] chars = new char[(int) size];
+ bytes.readFully(chars);
+ return chars;
+ }
+
+ @Override
+ public char[] read(Bytes bytes, long size, char[] chars) {
+ if (chars == null || chars.length != size)
+ chars = new char[(int) size];
+ bytes.readFully(chars);
+ return chars;
+ }
+
+ @Override
+ public long size(char[] chars) {
+ return chars.length * 2L;
+ }
+
+ @Override
+ public void write(Bytes bytes, char[] chars) {
+ bytes.write(chars);
+ }
+}
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/CharSequenceReader.java b/src/main/java/net/openhft/chronicle/serialization/impl/CharSequenceReader.java
similarity index 95%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/CharSequenceReader.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/CharSequenceReader.java
index aed9f7c71..b2e40f818 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/CharSequenceReader.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/CharSequenceReader.java
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
-import net.openhft.chronicle.map.serialization.BytesReader;
+import net.openhft.chronicle.serialization.BytesReader;
import net.openhft.lang.io.AbstractBytes;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.pool.CharSequenceInterner;
-import net.openhft.chronicle.map.threadlocal.StatefulCopyable;
+import net.openhft.chronicle.threadlocal.StatefulCopyable;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/CharSequenceWriter.java b/src/main/java/net/openhft/chronicle/serialization/impl/CharSequenceWriter.java
similarity index 92%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/CharSequenceWriter.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/CharSequenceWriter.java
index 38a5eb6a3..387de3ff2 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/CharSequenceWriter.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/CharSequenceWriter.java
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
+import net.openhft.chronicle.serialization.BytesWriter;
import net.openhft.lang.io.AbstractBytes;
import net.openhft.lang.io.Bytes;
-import net.openhft.chronicle.map.serialization.BytesWriter;
import java.io.ObjectStreamException;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/DoubleMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/impl/DoubleMarshaller.java
similarity index 90%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/DoubleMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/DoubleMarshaller.java
index ea3080b98..6d69ab18a 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/DoubleMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/DoubleMarshaller.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
-import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
-import net.openhft.chronicle.map.serialization.Hasher;
+import net.openhft.chronicle.serialization.AgileBytesMarshaller;
+import net.openhft.chronicle.serialization.Hasher;
import net.openhft.lang.io.Bytes;
import static java.lang.Double.doubleToLongBits;
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/IntegerMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/impl/IntegerMarshaller.java
similarity index 90%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/IntegerMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/IntegerMarshaller.java
index c8507ed21..fee023837 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/IntegerMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/IntegerMarshaller.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
-import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
-import net.openhft.chronicle.map.serialization.Hasher;
+import net.openhft.chronicle.serialization.AgileBytesMarshaller;
+import net.openhft.chronicle.serialization.Hasher;
import net.openhft.lang.io.Bytes;
public enum IntegerMarshaller implements AgileBytesMarshaller {
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/LongMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/impl/LongMarshaller.java
similarity index 89%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/LongMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/LongMarshaller.java
index 0ad365acf..b21550595 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/LongMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/LongMarshaller.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
-import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
-import net.openhft.chronicle.map.serialization.Hasher;
+import net.openhft.chronicle.serialization.AgileBytesMarshaller;
+import net.openhft.chronicle.serialization.Hasher;
import net.openhft.lang.io.Bytes;
public enum LongMarshaller implements AgileBytesMarshaller {
diff --git a/src/main/java/net/openhft/chronicle/map/serialization/impl/VoidMarshaller.java b/src/main/java/net/openhft/chronicle/serialization/impl/VoidMarshaller.java
similarity index 92%
rename from src/main/java/net/openhft/chronicle/map/serialization/impl/VoidMarshaller.java
rename to src/main/java/net/openhft/chronicle/serialization/impl/VoidMarshaller.java
index 257588f25..f1a1b7d8a 100644
--- a/src/main/java/net/openhft/chronicle/map/serialization/impl/VoidMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/serialization/impl/VoidMarshaller.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.serialization.impl;
+package net.openhft.chronicle.serialization.impl;
-import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
+import net.openhft.chronicle.serialization.AgileBytesMarshaller;
import net.openhft.lang.io.Bytes;
public enum VoidMarshaller implements AgileBytesMarshaller {
diff --git a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java
index 1b2571609..30fa67ca6 100644
--- a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java
+++ b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java
@@ -30,7 +30,17 @@ import java.io.File;
import java.io.IOException;
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
+ * documentation.
+ *
+ * @param element type of the sets, created by this builder
+ * @see ChronicleSet
+ * @see ChronicleMapBuilder
+ */
public class ChronicleSetBuilder
implements ChronicleHashBuilder, ChronicleSetBuilder> {
@@ -175,6 +185,12 @@ public class ChronicleSetBuilder
return this;
}
+ @Override
+ public ChronicleSetBuilder disableReplication() {
+ chronicleMapBuilder.disableReplication();
+ return this;
+ }
+
@Override
public String toString() {
@@ -209,6 +225,16 @@ public class ChronicleSetBuilder
return this;
}
+ /**
+ * {@inheritDoc}
+ *
+ * Example:
{@code Set set = ChronicleSetBuilder.of(Key.class)
+ * .entries(1_000_000)
+ * .keySize(100)
+ * // this class hasn't implemented yet, just for example
+ * .objectSerializer(new KryoObjectSerializer())
+ * .create();}
+ */
@Override
public ChronicleSetBuilder objectSerializer(ObjectSerializer objectSerializer) {
chronicleMapBuilder.objectSerializer(objectSerializer);
diff --git a/src/main/java/net/openhft/chronicle/set/DummyValueMarshaller.java b/src/main/java/net/openhft/chronicle/set/DummyValueMarshaller.java
index 85bb16462..9566014b5 100644
--- a/src/main/java/net/openhft/chronicle/set/DummyValueMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/set/DummyValueMarshaller.java
@@ -16,7 +16,7 @@
package net.openhft.chronicle.set;
-import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
+import net.openhft.chronicle.serialization.AgileBytesMarshaller;
import net.openhft.lang.io.Bytes;
import static net.openhft.chronicle.set.DummyValue.DUMMY_VALUE;
diff --git a/src/main/java/net/openhft/chronicle/map/threadlocal/Provider.java b/src/main/java/net/openhft/chronicle/threadlocal/Provider.java
similarity index 98%
rename from src/main/java/net/openhft/chronicle/map/threadlocal/Provider.java
rename to src/main/java/net/openhft/chronicle/threadlocal/Provider.java
index e8a832b41..349c85f2e 100644
--- a/src/main/java/net/openhft/chronicle/map/threadlocal/Provider.java
+++ b/src/main/java/net/openhft/chronicle/threadlocal/Provider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.threadlocal;
+package net.openhft.chronicle.threadlocal;
public abstract class Provider {
diff --git a/src/main/java/net/openhft/chronicle/map/threadlocal/StatefulCopyable.java b/src/main/java/net/openhft/chronicle/threadlocal/StatefulCopyable.java
similarity index 94%
rename from src/main/java/net/openhft/chronicle/map/threadlocal/StatefulCopyable.java
rename to src/main/java/net/openhft/chronicle/threadlocal/StatefulCopyable.java
index d246fd2b8..e666aa489 100644
--- a/src/main/java/net/openhft/chronicle/map/threadlocal/StatefulCopyable.java
+++ b/src/main/java/net/openhft/chronicle/threadlocal/StatefulCopyable.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.threadlocal;
+package net.openhft.chronicle.threadlocal;
public interface StatefulCopyable> {
Object stateIdentity();
diff --git a/src/main/java/net/openhft/chronicle/map/threadlocal/ThreadLocalCopies.java b/src/main/java/net/openhft/chronicle/threadlocal/ThreadLocalCopies.java
similarity index 97%
rename from src/main/java/net/openhft/chronicle/map/threadlocal/ThreadLocalCopies.java
rename to src/main/java/net/openhft/chronicle/threadlocal/ThreadLocalCopies.java
index e6dcec6d6..e94deb291 100644
--- a/src/main/java/net/openhft/chronicle/map/threadlocal/ThreadLocalCopies.java
+++ b/src/main/java/net/openhft/chronicle/threadlocal/ThreadLocalCopies.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package net.openhft.chronicle.map.threadlocal;
+package net.openhft.chronicle.threadlocal;
import java.util.concurrent.atomic.AtomicBoolean;
diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/StringEncodingExamples.java b/src/test/java/net/openhft/chronicle/map/fromdocs/StringEncodingExamples.java
new file mode 100644
index 000000000..66555f680
--- /dev/null
+++ b/src/test/java/net/openhft/chronicle/map/fromdocs/StringEncodingExamples.java
@@ -0,0 +1,201 @@
+/*
+ * 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.fromdocs;
+
+import net.openhft.chronicle.threadlocal.StatefulCopyable;
+import net.openhft.chronicle.set.ChronicleSet;
+import net.openhft.chronicle.set.ChronicleSetBuilder;
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.CharBuffers;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.pool.CharSequenceInterner;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+public class StringEncodingExamples {
+
+ static class CustomEncodingMarshaller implements BytesMarshaller,
+ StatefulCopyable {
+ private static final long serialVersionUID = 0L;
+
+ private String charsetName;
+ private transient Charset charset;
+ private transient CharsetEncoder encoder;
+ private transient CharsetDecoder decoder;
+ private transient ByteBuffer bytesAsBuffer;
+ private transient CharBuffer charSequenceAsBuffer;
+ private transient CharBuffer returnedCharBuffer;
+
+ CustomEncodingMarshaller(Charset charset) {
+ this.charsetName = charset.name().intern();
+ this.charset = charset;
+ initCoders();
+ }
+
+ CustomEncodingMarshaller(CustomEncodingMarshaller m) {
+ charsetName = m.charsetName;
+ charset = m.charset;
+ encoder = m.encoder;
+ decoder = m.decoder;
+ }
+
+ private void initCoders() {
+ encoder = charset.newEncoder();
+ decoder = charset.newDecoder();
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ charsetName = charsetName.intern();
+ charset = Charset.forName(charsetName);
+ initCoders();
+ }
+
+ @Override
+ public void write(Bytes bytes, CharSequence cs) {
+ bytes.writeStopBit(cs.length());
+ bytesAsBuffer = bytes.sliceAsByteBuffer(bytesAsBuffer);
+ charSequenceAsBuffer = CharBuffers.wrap(cs, charSequenceAsBuffer);
+ encoder.encode(charSequenceAsBuffer, bytesAsBuffer, true);
+ bytes.position(bytes.position() + bytesAsBuffer.position());
+ }
+
+ @Override
+ public CharSequence read(Bytes bytes) {
+ int csLen = (int) bytes.readStopBit();
+ if (returnedCharBuffer == null || returnedCharBuffer.capacity() < csLen) {
+ returnedCharBuffer = CharBuffer.allocate(csLen);
+ } else {
+ returnedCharBuffer.clear().limit(csLen);
+ }
+ bytesAsBuffer = bytes.sliceAsByteBuffer(bytesAsBuffer);
+ decoder.decode(bytesAsBuffer, returnedCharBuffer, true);
+ bytes.position(bytes.position() + bytesAsBuffer.position());
+ returnedCharBuffer.flip();
+ return returnedCharBuffer;
+ }
+
+ @Override
+ public CharSequence read(Bytes bytes, @Nullable CharSequence cs) {
+ return read(bytes);
+ }
+
+ @Override
+ public Object stateIdentity() {
+ return charsetName;
+ }
+
+ @Override
+ public CustomEncodingMarshaller copy() {
+ return new CustomEncodingMarshaller(this);
+ }
+ }
+
+ static class Utf16Marshaller implements BytesMarshaller,
+ StatefulCopyable> {
+ private static final long serialVersionUID = 0L;
+
+ private final Serializable identity;
+ private final CharSequenceInterner interner;
+ private transient char[] readBuffer;
+
+ & Serializable>
+ Utf16Marshaller(Serializable identity, I interner) {
+ this.identity = identity;
+ this.interner = interner;
+ }
+
+ @Override
+ public void write(Bytes bytes, CS cs) {
+ bytes.writeCompactInt(cs.length());
+ bytes.writeChars(cs);
+ }
+
+ @Override
+ public CS read(Bytes bytes) {
+ return read(bytes, null);
+ }
+
+ @Override
+ public CS read(Bytes bytes, @Nullable CS cs) {
+ int csLen = bytes.readCompactInt();
+ if (readBuffer == null || readBuffer.length < csLen)
+ readBuffer = new char[csLen];
+ bytes.readFully(readBuffer, 0, csLen);
+ return interner.intern(CharBuffer.wrap(readBuffer, 0, csLen));
+ }
+
+ @Override
+ public Object stateIdentity() {
+ return identity;
+ }
+
+ @Override
+ public Utf16Marshaller copy() {
+ return new Utf16Marshaller(identity, interner);
+ }
+ }
+
+ enum NoInterning implements CharSequenceInterner {
+ INSTANCE;
+
+ @Override
+ public CharSequence intern(@NotNull CharSequence cs) {
+ return cs;
+ }
+ }
+
+ @Test
+ public void testCustomEncodingMarshaller() throws IOException {
+ CustomEncodingMarshaller gbkStringMarshaller =
+ new CustomEncodingMarshaller(Charset.forName("GBK"));
+ testCustomKeyMarshaller(gbkStringMarshaller);
+ }
+
+
+ @Test
+ public void testNoEncodingMarshaller() throws IOException {
+ Utf16Marshaller noEncodingMarshaller =
+ new Utf16Marshaller(NoInterning.INSTANCE, NoInterning.INSTANCE);
+ testCustomKeyMarshaller(noEncodingMarshaller);
+ }
+
+ private void testCustomKeyMarshaller(BytesMarshaller marshaller)
+ throws IOException {
+ ChronicleSet chineseWordSet = ChronicleSetBuilder.of(CharSequence.class)
+ .keyMarshaller(marshaller)
+ .actualSegments(1)
+ .actualEntriesPerSegment(1000)
+ .create();
+
+ chineseWordSet.add("新闻");
+ chineseWordSet.add("地图");
+ chineseWordSet.add("贴吧");
+ chineseWordSet.add("登录");
+ chineseWordSet.add("设置");
+ Assert.assertEquals(5, chineseWordSet.size());
+ System.out.println(chineseWordSet);
+ }
+}