From 12c85034346ad7586639f1cdc0dce33fb51cc603 Mon Sep 17 00:00:00 2001 From: leventov Date: Tue, 15 Dec 2015 14:27:56 +0300 Subject: [PATCH] Javadoc improvements --- .../chronicle/hash/ChronicleHashBuilder.java | 68 +++++++++++++---- .../hash/ChronicleHashInstanceBuilder.java | 73 +++++++++++++++++-- .../openhft/chronicle/map/ChronicleMap.java | 5 +- .../chronicle/map/ChronicleMapBuilder.java | 19 ++--- 4 files changed, 128 insertions(+), 37 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java index 00bd382bc..5a1381679 100755 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java @@ -17,6 +17,7 @@ package net.openhft.chronicle.hash; import net.openhft.chronicle.bytes.Byteable; +import net.openhft.chronicle.bytes.Bytes; import net.openhft.chronicle.hash.replication.ReplicableEntry; import net.openhft.chronicle.hash.replication.SingleChronicleHashReplication; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; @@ -44,6 +45,16 @@ import java.util.concurrent.TimeUnit; * the corresponding configuration changed. To make an independent configuration, {@linkplain * #clone} the builder. * + *

{@code ChronicleHashBuilder} focuses on configurations, it could be used to create several + * containers of the same key-value domain. In this case {@code ChronicleHashBuilder} play like a + * factory (design pattern), rather than builder. The {@code ChronicleHashBuilder} could be + * "converted" to an {@link ChronicleHashInstanceBuilder} using {@link #instance()} method. + * {@code ChronicleHashInstanceBuilder} is a classic disposable builder, allowing to configure + * parameters, supposed to be unique for each created Chronicle Hash. + * + *

{@code ChronicleHashBuilder} instances are not safe for concurrent use from multiple threads, + * if at least one of the threads mutates the {@code ChronicleHashBuilder}'s state. + * *

There are some "low-level" configurations in this builder, * that require deep understanding of the Chronicle implementation design to be properly used. * Know what you do. These configurations are applied as-is, without extra round-ups, adjustments, @@ -472,7 +483,10 @@ public interface ChronicleHashBuilder, /** * Shortcut for {@link #keyMarshallers(SizedReader, SizedWriter) * keyMarshallers(sizedMarshaller, sizedMarshaller)}. - * @param sizedMarshaller + * + * @param sizedMarshaller implementation of both {@link SizedReader} and {@link SizedWriter} + * interfaces + * @return this builder back */ & SizedWriter> B keyMarshaller(@NotNull M sizedMarshaller); @@ -485,8 +499,8 @@ public interface ChronicleHashBuilder, * 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(net.openhft.chronicle.bytes.Bytes)} calls, is used instead of any {@code - * SizeMarshaller} configured using this method. + * SizeMarshaller#readSize(Bytes)} calls, is used instead of any {@code SizeMarshaller} + * configured using this method. * * @param keySizeMarshaller the new marshaller, used to serialize actual key sizes to off-heap * memory @@ -527,8 +541,8 @@ public interface ChronicleHashBuilder, *

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 #replication(byte, TcpTransportAndNetworkConfig)} shortcut - * method. + * either by this method or {@link #replication(byte, TcpTransportAndNetworkConfig)}, or + * {@link #replication(byte)} shortcut methods. * * @param replication the replication config * @return this builder back @@ -538,7 +552,8 @@ public interface ChronicleHashBuilder, B replication(SingleChronicleHashReplication replication); /** - * Shortcut for {@code replication(SimpleReplication.builder() .tcpTransportAndNetwork(tcpTransportAndNetwork).createWithId(identifier))}. + * Shortcut for {@code replication(SingleChronicleHashReplication.builder() + * .tcpTransportAndNetwork(tcpTransportAndNetwork).createWithId(identifier))}. * * @param identifier the network-wide identifier of the containers, created by this * builder @@ -549,28 +564,49 @@ public interface ChronicleHashBuilder, */ B replication(byte identifier, TcpTransportAndNetworkConfig tcpTransportAndNetwork); + /** + * Shortcut for {@link #replication(SingleChronicleHashReplication) + * replication(SingleChronicleHashReplication.builder().createWithId(identifier)}. + * + *

This method is used to configure a replicated Chronicle Hash, that shouldn't communicate + * to other nodes. For example, if several processes access the same persisted Chronicle Hash, + * only one of them should communicate to other nodes and replicate entries. + * + * @param identifier the network-wide identifier for containers, created by this builder. This + * identifier is used when calling e. g. put() of the created container, to write the entry + * origin identifier (along with timestamp) into the entry memory. This change may be replicated + * to other nodes by a concurrent (or later) process, mapping to the same file. + * @return this builder back + */ B replication(byte identifier); + /** + * Returns a new {@code ChronicleHashInstanceBuilder}, which inherits configuration from this + * builder (in it's current state) and could be used to specify individual configurations + * for a Chronicle Hash container. Changes to this {@code ChronicleHashBuilder}, made after + * an instance is create, doesn't affect that instance, i. e. the returned instance is + * independent from the {@code ChronicleHashBuilder}, used to create it. + * + * @return a new Chronicle Hash instance builder + */ ChronicleHashInstanceBuilder instance(); /** - * 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. - * - *

This method is a shortcut for {@code instance().create()}. + * Creates a new hash container from this builder, 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 * @see #createPersistedTo(File) - * @see #instance() */ H create(); /** - * 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. + * Opens a hash container residing the specified file, or creates a new one from this builder, + * if the file doesn't yet exist 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. diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashInstanceBuilder.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashInstanceBuilder.java index 206571436..9d9710bc5 100644 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashInstanceBuilder.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashInstanceBuilder.java @@ -19,10 +19,32 @@ package net.openhft.chronicle.hash; import net.openhft.chronicle.hash.replication.ReplicationChannel; import net.openhft.chronicle.hash.replication.SingleChronicleHashReplication; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; +import net.openhft.chronicle.map.ChronicleMap; +import net.openhft.chronicle.set.ChronicleSet; import java.io.File; import java.io.IOException; +/** + * A disposable builder of {@link ChronicleHash} instances, allowing to set unique configurations + * using "chaining" pattern. + * + *

Usage example:

{@code
+ * ChronicleMap = ChronicleMap
+ *     .of(LongValue.class, Order.class)
+ *     .entries(10_000_000)
+ *     .instance()      // a ChronicleHashInstanceBuilder is returned from this method
+ *                      // continue "chaining"
+ *     .replicated(...)
+ *     .name(...)
+ *     .persistedTo(...)
+ *     .create();
+ * }
+ * + * @param the container type, created by this builder, {@link ChronicleMap} or + * {@link ChronicleSet} + * @see ChronicleHashBuilder#instance() + */ public interface ChronicleHashInstanceBuilder { ChronicleHashInstanceBuilder replicated( @@ -31,13 +53,13 @@ public interface ChronicleHashInstanceBuilder { ChronicleHashInstanceBuilder replicated(SingleChronicleHashReplication replication); /** - * 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. + * Configures replication of the hash container, which is going to be 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 is {@link #replicated(SingleChronicleHashReplication)} method - * or it's shortcut: {@link #replicated(byte, TcpTransportAndNetworkConfig)}. + *

Another way to establish replication is {@link #replicated(SingleChronicleHashReplication) + * } method or it's shortcut: {@link #replicated(byte, TcpTransportAndNetworkConfig)}. * *

By default, hash containers, created by this builder doesn't replicate their data. * @@ -52,9 +74,44 @@ public interface ChronicleHashInstanceBuilder { */ ChronicleHashInstanceBuilder replicatedViaChannel(ReplicationChannel channel); - ChronicleHashInstanceBuilder persistedTo(File file); - + /** + * Configures the name for the Chronicle Hash, which is going to be created by this builder. It + * is used to name background threads, run by replicated Chronicle Hash instances. + * + * @param name the name for the Chronicle Hash is going to be created by this builder + * @return this builder back + */ ChronicleHashInstanceBuilder name(String name); + /** + * Configures the file, the Chronicle Hash, which is going to be created by this builder, should + * be persisted to. See {@link ChronicleHashBuilder#createPersistedTo(File)} for more + * information on Chronicle Hash persistence. If the given file is {@code null}, in-memory + * Chronicle Hash is created, like by {@link ChronicleHashBuilder#create()}. + * + *

By default, persistence file is configured to {@code null}, i. e. the in-memory Chronicle + * Hash instance is created. + * + * @param file the file the Chronicle Hash, which is going to be created by this builder, should + * be persisted to, to {@code null}, if the Chronicle Hash should be purely + * in-memory + * @return this builder back + */ + ChronicleHashInstanceBuilder persistedTo(File file); + + /** + * Creates (or opens existing, if {@link #persistedTo(File)} is configured with the existing + * file) a Chronicle Hash from this builder. After this method is called once the builder + * couldn't be used to create new Chronicle Hash instances, a new {@code + * ChronicleHashInstanceBuilder} should be created via {@link ChronicleHashBuilder#instance()}. + * + * @return a new in-memory or persisted Chronicle Hash instance + * @throws IOException if any IO error, related to off-heap memory allocation or file mapping, + * or establishing replication connections, occurs + * @throws IllegalStateException if {@code create()} method has already been called on this + * {@code ChronicleHashInstanceBuilder} + * @see ChronicleHashBuilder#create() + * @see ChronicleHashBuilder#createPersistedTo(File) + */ H 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 78a8aa20a..cf8084bb8 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java @@ -23,10 +23,7 @@ import net.openhft.chronicle.hash.serialization.SizedReader; import net.openhft.chronicle.hash.serialization.SizedWriter; import org.jetbrains.annotations.NotNull; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.Serializable; +import java.io.*; 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 df7911232..970e22c26 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -66,13 +66,13 @@ import static net.openhft.chronicle.map.VanillaChronicleMap.alignAddr; * pattern:

{@code
  * ChronicleMap map = ChronicleMapOnHeapUpdatableBuilder
  *     .of(Key.class, Value.class)
- *     .entries(100500)
  *     // ... other configurations
  *     .create();}
* it could be prepared and used to create many similar maps:
{@code
  * ChronicleMapBuilder builder = ChronicleMapBuilder
  *     .of(Key.class, Value.class)
- *     .entries(100500);
+ *     .entries(..)
+ *     // ... other configurations
  *
  * ChronicleMap map1 = builder.create();
  * ChronicleMap map2 = builder.create();}
@@ -85,19 +85,20 @@ import static net.openhft.chronicle.map.VanillaChronicleMap.alignAddr; * ChronicleMapBuilder}", unless specified different, because theoretically someone might provide * {@code ChronicleMap} implementations with completely different properties. * - *

{@code ChronicleMap} ("ChronicleMaps, created by {@code ChronicleMapBuilder}") currently - * doesn't support resizing. That is why you must configure {@linkplain #entries(long) number - * of entries} you are going to insert into the created map at most. See {@link + *

In addition to the key and value types, you must configure {@linkplain #entries(long) + * number of entries} you are going to insert into the created map at most. See {@link * #entries(long)} method documentation for more information on this. * *

If you key or value type is not constantly sized and known to {@code ChronicleHashBuilder}, i. - * e. it is not a boxed primitive, value interface, or {@link Byteable}, you must provide the - * {@code ChronicleHashBuilder} with some information about you keys or values: if they are - * constantly-sized, call {@link #constantKeySizeBySample(Object)}, otherwise {@link - * ChronicleHashBuilder#averageKeySize(double)} method, accordingly for values. + * e. it is not a boxed primitive, {@linkplain net.openhft.chronicle.values.Values value interface}, + * or {@link Byteable}, you must provide the {@code ChronicleHashBuilder} with some + * information about you keys or values: if they are constantly-sized, call {@link + * #constantKeySizeBySample(Object)}, otherwise {@link #averageKey(Object)} or {@link + * #averageKeySize(double)} method, and accordingly for values. * * @param key type of the maps, produced by this builder * @param value type of the maps, produced by this builder + * @see ChronicleHashBuilder * @see ChronicleMap * @see ChronicleSetBuilder */