Rearrange and reformat code.

This commit is contained in:
Peter Lawrey
2016-01-01 09:34:41 +00:00
parent ab12d46956
commit 22b8a6b5fb
54 changed files with 305 additions and 312 deletions
@@ -33,7 +33,7 @@ public interface ChronicleHash extends Closeable {
* i. e. if it is created by {@link ChronicleHashBuilder#create()} call.
*
* @return the file this {@link ChronicleMap} or {@link ChronicleSet} is mapped to,
* or {@code null} if it is not mapped to any file
* or {@code null} if it is not mapped to any file
* @see ChronicleHashBuilder#createPersistedTo(java.io.File)
*/
File file();
@@ -44,15 +44,15 @@ public interface ChronicleHash extends Closeable {
* and there are other instances mapping the same data on the server across JVMs, the memory
* won't be actually freed on operation system level. I. e. this method call doesn't affect
* other {@link ChronicleMap} or {@link ChronicleSet} instances mapping the same data.
*
* <p>
* <p>If you won't call this method, memory would be held at least until next garbage
* collection. This could be a problem if, for example, you target rare garbage collections,
* but load and drop {@code ChronicleHash}es regularly.
*
* <p>
* <p>
* TODO what about commit guarantees, when ChronicleMap is used with memory-mapped files, if
* {@code ChronicleMap}/{@code ChronicleSet} closed/not?
*
* <p>
* <p>After this method call behaviour of <i>all</i> methods of {@code ChronicleMap}
* or {@code ChronicleSet} is undefined. <i>Any</i> method call on the map might throw
* <i>any</i> exception, or even JVM crash. Shortly speaking, don't call use map closing.
@@ -46,12 +46,12 @@ import java.util.concurrent.TimeUnit;
* This interface defines the meaning of configurations, common to {@link
* ChronicleMapBuilder} and {@link ChronicleSetBuilder}, i.
* e. <i>Chronicle hash container</i> configurations.
*
* <p>
* <p>{@code ChronicleHashBuilder} is mutable. Configuration methods mutate the builder and return
* <i>the builder itself</i> back to support chaining pattern, rather than the builder copies with
* the corresponding configuration changed. To make an independent configuration, {@linkplain
* #clone} the builder.
*
* <p>
* <p><a name="low-level-config"></a>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 picked up strictly as-is, without extra round-ups,
@@ -88,21 +88,21 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* Configures the average number of bytes, taken by serialized form of keys, put into hash
* containers, created by this builder. If key size is always the same, call {@link
* #constantKeySizeBySample(Object)} method instead of this one.
*
* <p>
* <p>{@code ChronicleHashBuilder} implementation heuristically chooses
* {@linkplain #actualChunkSize(int) the actual chunk size} based on this configuration, that,
* however, might result to quite high internal fragmentation, i. e. losses because only
* integral number of chunks could be allocated for the entry. If you want to avoid this, you
* should manually configure the actual chunk size in addition to this average key size
* configuration, which is anyway needed.
*
* <p>
* <p>If key is a boxed primitive type or {@link Byteable} subclass, i. e. if key size is known
* statically, it is automatically accounted and shouldn't be specified by user.
*
* @param averageKeySize the average number of bytes, taken by serialized form of keys
* @return this builder back
* @throws IllegalStateException if key size is known statically and shouldn't be configured
* by user
* @throws IllegalStateException if key size is known statically and shouldn't be configured
* by user
* @throws IllegalArgumentException if the given {@code keySize} is non-positive
* @see #constantKeySizeBySample(Object)
* @see #actualChunkSize(int)
@@ -113,10 +113,10 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* Configures the constant number of bytes, taken by serialized form of keys, put into hash
* containers, created by this builder. This is done by providing the {@code sampleKey}, all
* keys should take the same number of bytes in serialized form, as this sample object.
*
* <p>
* <p>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.
*
* <p>
* <p>If key size varies, method {@link #averageKeySize(double)} should be called instead of
* this one.
*
@@ -129,7 +129,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
/**
* Configures the size in bytes of allocation unit of hash container instances, created by this
* builder.
*
* <p>
* <p>{@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}
@@ -139,16 +139,16 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* 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. This is called
* internal fragmentation.
*
* <p>
* <p>To minimize memory overuse and improve speed, you should pay decent attention to this
* configuration. Alternatively, you can just trust the heuristics and doesn't configure
* the chunk size.
*
* <p>
* <p>Specify chunk size so that most entries would take from 5 to several dozens of chunks.
* However, remember that operations with entries that span several chunks are a bit slower,
* than with entries which take a single chunk. Particularly avoid entries to take more than
* 64 chunks.
*
* <p>
* <p>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
@@ -160,7 +160,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* .averageValueSize(150 * 8) // 150 is average adjacency list size
* .actualChunkSize(30 * 8) // average 5-6 chunks per entry
* .create();}</pre>
*
* <p>
* <p>This is a <a href="#low-level-config">low-level configuration</a>. The configured number
* of bytes is strictly used as-is, without anything like round-up to the multiple of 8 or
* 16, or any other adjustment.
@@ -185,7 +185,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* @param maxChunksPerEntry how many chunks a single entry could span at most
* @return this builder back
* @throws IllegalArgumentException if the given {@code maxChunksPerEntry} is lesser than 1
* or greater than 64
* or greater than 64
* @see #actualChunkSize(int)
*/
B maxChunksPerEntry(int maxChunksPerEntry);
@@ -195,13 +195,13 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* created by this builder. If you try to insert more data, {@link IllegalStateException}
* <i>might</i> be thrown, because currently {@link ChronicleMap} and {@link ChronicleSet}
* don't support resizing.
*
* <p>
* <p><b>You shouldn't put additional margin over the actual maximum number of entries.</b>
* This bad practice was popularized by {@link HashMap#HashMap(int)} and {@link
* HashSet#HashSet(int)} constructors, which accept <i>capacity</i>, that should be multiplied
* by <i>load factor</i> to obtain the actual maximum expected number of entries.
* {@code ChronicleMap} and {@code ChronicleSet} don't have a notion of load factor.
*
* <p>
* <p>Default maximum entries is 2^20 (~ 1 million).
*
* @param entries maximum size of the maps or sets, created by this builder
@@ -214,11 +214,11 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* of the hash containers, created by this builder. Configuring both the actual number of
* entries per segment and {@linkplain #actualSegments(int) actual segments} replaces a single
* {@link #entries(long)} configuration.
*
* <p>
* <p>This is a <a href="#low-level-config">low-level configuration</a>.
*
* @param entriesPerSegment the actual maximum number entries per segment in the
* hash containers, created by this builder
* hash containers, created by this builder
* @return this builder back
* @see #entries(long)
* @see #actualSegments(int)
@@ -242,7 +242,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* Configures the actual number of segments in the hash containers, created by this builder.
* With {@linkplain #entriesPerSegment(long) actual number of segments}, this
* configuration replaces a single {@link #entries(long)} call.
*
* <p>
* <p>This is a <a href="#low-level-config">low-level configuration</a>. The configured number
* is used as-is, without anything like round-up to the closest power of 2.
*
@@ -262,7 +262,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* until thread is interrupted. However, you can configure {@linkplain
* #errorListener(ChronicleHashErrorListener) error listener} to throw an exception on the first
* (or n-th) lock acquisition fail.
*
* <p>
* <p>Default lock time out is 2 seconds.
*
* @param lockTimeOut new lock timeout for segments of containers created by this builder, in
@@ -279,7 +279,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
/**
* Configures a time provider, used by hash containers, created by this builder, for needs of
* replication consensus protocol (conflicting data updates resolution).
*
* <p>
* <p>Default time provider is {@link TimeProvider#SYSTEM}.
*
* @param timeProvider a new time provider for replication needs
@@ -293,7 +293,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* BytesMarshallableSerializer}, which is a default {@link #objectSerializer ObjectSerializer},
* to serialize/deserialize data to/from off-heap memory in hash containers, created by this
* builder.
*
* <p>
* <p>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
@@ -315,7 +315,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* {@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.
*
* <p>
* <p>Default serializer is {@link BytesMarshallableSerializer}, configured with the specified
* or default {@link #bytesMarshallerFactory(BytesMarshallerFactory) BytesMarshallerFactory}.
*
@@ -343,10 +343,10 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* Configures the marshallers, used to serialize/deserialize keys to/from off-heap memory in
* hash containers, created by this builder. See <a href="https://github.com/OpenHFT/Chronicle-Map#serialization">the
* section about serialization in ChronicleMap manual</a> for more information.
*
* <p>
* <p>Configuring marshalling this way results to a little bit more compact in-memory layout of
* the map, comparing to a single interface configuration: {@link #keyMarshaller(BytesMarshaller)}.
*
* <p>
* <p>Passing {@link BytesInterop} (which is a subinterface of {@link BytesWriter}) as the first
* argument is supported, and even more advantageous from performance perspective.
*
@@ -360,7 +360,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
/**
* Configures the marshaller used to serialize actual key sizes to off-heap memory in hash
* containers, created by this builder.
*
* <p>
* <p>Default key size marshaller is so-called {@linkplain SizeMarshallers#stopBit() stop bit
* encoding marshalling}. If {@linkplain #constantKeySizeBySample(Object) constant key size} is
* configured, or defaulted if the key type is always constant and {@code ChronicleHashBuilder}
@@ -381,7 +381,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* eligible for data value generation, or {@linkplain #keyMarshallers(BytesWriter, BytesReader)
* configured custom key reader} implements {@link DeserializationFactoryConfigurableBytesReader
* }, in maps, created by this builder.
*
* <p>
* <p>Default key deserialization factory is {@link NewInstanceObjectFactory}, which creates a
* new key instance using {@link Class#newInstance()} default constructor. You could provide an
* {@link AllocateInstanceObjectFactory}, which uses {@code Unsafe.allocateInstance(Class)} (you
@@ -403,7 +403,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* 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.
*
* <p>
* <p>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.
@@ -416,9 +416,9 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* Configures replication of the hash containers, created by this builder. See <a
* href="https://github.com/OpenHFT/Chronicle-Map#tcp--udp-replication"> the section about
* replication in ChronicleMap manual</a> for more information.
*
* <p>
* <p>By default, hash containers, created by this builder doesn't replicate their data.
*
* <p>
* <p>This method call overrides all previous replication configurations of this builder, made
* either by this method or {@link #replication(byte, TcpTransportAndNetworkConfig)} shortcut
* method.
@@ -451,7 +451,7 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* 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.
*
* <p>
* <p>This method is a shortcut for {@code instance().create()}.
*
* @return a new off-heap hash container
@@ -464,17 +464,17 @@ public interface ChronicleHashBuilder<K, C extends ChronicleHash,
* 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.
*
* <p>
* <p>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.
*
* <p>
* <p>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.
*
* <p>
* <p>This method is shortcut for {@code instance().persistedTo(file).create()}.
*
* @param file the file with existing hash container or a desired location of a new off-heap
@@ -34,12 +34,12 @@ public interface ChronicleHashInstanceBuilder<C extends ChronicleHash> {
* "channels". See
* <a href="https://github.com/OpenHFT/Chronicle-Map#channels-and-channelprovider">the
* section about Channels and ChannelProvider in ChronicleMap manual</a> for more information.
*
* <p>
* <p>Another way to establish replication is {@link #replicated(SingleChronicleHashReplication)} method
* or it's shortcut: {@link #replicated(byte, TcpTransportAndNetworkConfig)}.
*
* <p>
* <p>By default, hash containers, created by this builder doesn't replicate their data.
*
* <p>
* <p>This method call overrides all previous replication configurations of this builder, made
* either by means of this method, {@link #replicated(SingleChronicleHashReplication)}
* or {@link #replicated(byte, TcpTransportAndNetworkConfig)} method calls.
@@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit;
* another host
*
* @param <H> the type of {@code ChronicleHash} accessed remotely, {@code ChronicleMap} or
* {@code ChronicleSet}
* {@code ChronicleSet}
*/
public interface ChronicleHashStatelessClientBuilder<
C extends ChronicleHashStatelessClientBuilder<C, H>, H extends ChronicleHash> {
@@ -18,6 +18,7 @@ package net.openhft.chronicle.hash;
/**
* TODO mention in docs
*
* @author Rob Austin.
*/
public class RemoteCallTimeoutException extends RuntimeException {
@@ -25,19 +25,19 @@ import java.nio.ByteOrder;
* Access} implementation returns {@link ByteOrder#LITTLE_ENDIAN} on {@link #byteOrder(Object)
* byteOrder(input)} call, the following expressions should always have the same value:
* <ul>
* <li>{@code getLong(input, 0)}</li>
* <li>{@code getUnsignedInt(input, 0) | (getUnsignedInt(input, 4) << 32)}</li>
* <li><pre>{@code getUnsignedInt(input, 0) |
* <li>{@code getLong(input, 0)}</li>
* <li>{@code getUnsignedInt(input, 0) | (getUnsignedInt(input, 4) << 32)}</li>
* <li><pre>{@code getUnsignedInt(input, 0) |
* ((long) getUnsignedShort(input, 4) << 32) |
* ((long) getUnsignedByte(input, 6) << 48) |
* ((long) getUnsignedByte(input, 7) << 56)}</pre></li>
* <li>And so on</li>
* <li>And so on</li>
* </ul>
*
* <p>
* <p>{@code getXXX(input, offset)} methods could throw unchecked exceptions when requested bytes
* range is outside of the bounds of the byte sequence, represented by the given {@code input}.
* However, they could omit checks for better performance.
*
* <p>
* <p>{@code Access} API is designed for inputs, that actually represent byte sequences that lay
* continuously in memory. Theoretically {@code Access} strategy could be implemented for
* non-continuous byte sequences, or abstractions which aren't actually present in memory as they
@@ -52,9 +52,9 @@ public interface Access<T> {
* Reads {@code [offset, offset + 7]} bytes of the byte sequence represented by the given
* {@code input} as a single {@code long} value.
*
* @param input the object to access
* @param input the object to access
* @param offset offset to the first byte to read within the byte sequence represented
* by the given object
* by the given object
* @return eight bytes as a {@code long} value, in {@linkplain #byteOrder(Object) the expected
* order}
*/
@@ -64,9 +64,9 @@ public interface Access<T> {
* Shortcut for {@code getInt(input, offset) & 0xFFFFFFFFL}. Could be implemented more
* efficiently.
*
* @param input the object to access
* @param input the object to access
* @param offset offset to the first byte to read within the byte sequence represented
* by the given object
* by the given object
* @return four bytes as an unsigned int value, in {@linkplain #byteOrder(Object) the expected
* order}
*/
@@ -76,9 +76,9 @@ public interface Access<T> {
* Reads {@code [offset, offset + 3]} bytes of the byte sequence represented by the given
* {@code input} as a single {@code int} value.
*
* @param input the object to access
* @param input the object to access
* @param offset offset to the first byte to read within the byte sequence represented
* by the given object
* by the given object
* @return four bytes as an {@code int} value, in {@linkplain #byteOrder(Object) the expected
* order}
*/
@@ -88,9 +88,9 @@ public interface Access<T> {
* Shortcut for {@code getShort(input, offset) & 0xFFFF}. Could be implemented more
* efficiently.
*
* @param input the object to access
* @param input the object to access
* @param offset offset to the first byte to read within the byte sequence represented
* by the given object
* by the given object
* @return two bytes as an unsigned short value, in {@linkplain #byteOrder(Object) the expected
* order}
*/
@@ -100,9 +100,9 @@ public interface Access<T> {
* Reads {@code [offset, offset + 1]} bytes of the byte sequence represented by the given
* {@code input} as a single {@code short} value, returned widened to {@code int}.
*
* @param input the object to access
* @param input the object to access
* @param offset offset to the first byte to read within the byte sequence represented
* by the given object
* by the given object
* @return two bytes as a {@code short} value, in {@linkplain #byteOrder(Object) the expected
* order}, widened to {@code int}
*/
@@ -111,9 +111,9 @@ public interface Access<T> {
/**
* Shortcut for {@code getByte(input, offset) & 0xFF}. Could be implemented more efficiently.
*
* @param input the object to access
* @param input the object to access
* @param offset offset to the byte to read within the byte sequence represented
* by the given object
* by the given object
* @return a byte by the given {@code offset}, interpreted as unsigned
*/
int getUnsignedByte(T input, long offset);
@@ -122,9 +122,9 @@ public interface Access<T> {
* Reads a single byte at the given {@code offset} in the byte sequence represented by the given
* {@code input}, returned widened to {@code int}.
*
* @param input the object to access
* @param input the object to access
* @param offset offset to the byte to read within the byte sequence represented
* by the given object
* by the given object
* @return a byte by the given {@code offset}, widened to {@code int}
*/
int getByte(T input, long offset);
@@ -25,22 +25,25 @@ import java.nio.ByteBuffer;
*/
public final class Accesses {
private Accesses() {
}
/**
* Returns the {@code Access} delegating {@code getXXX(input, offset)} methods to {@code
* sun.misc.Unsafe.getXXX(input, offset)}.
*
* <p>
* <p>Usage example: <pre>{@code
* class Pair {
* long first, second;
*
* <p>
* static final long pairDataOffset =
* theUnsafe.objectFieldOffset(Pair.class.getDeclaredField("first"));
*
* <p>
* static long hashPair(Pair pair, LongHashFunction hashFunction) {
* return hashFunction.hash(pair, Accesses.unsafe(), pairDataOffset, 16L);
* }
* }}</pre>
*
* <p>
* <p>{@code null} is a valid input, on accepting {@code null} {@code Unsafe} just interprets
* the given offset as a wild memory address.
*
@@ -63,6 +66,4 @@ public final class Accesses {
public static Access<Bytes> toBytes() {
return BytesAccess.INSTANCE;
}
private Accesses() {}
}
@@ -37,7 +37,7 @@ public final class Hasher {
* Returns the hash code for {@code len} continuous bytes of the given {@code input} object,
* starting from the given offset. The abstraction of input as ordered byte sequence and
* "offset within the input" is defined by the given {@code access} strategy.
*
* <p>
* <p>This method doesn't promise to throw a {@code RuntimeException} if {@code
* [off, off + len - 1]} subsequence exceeds the bounds of the bytes sequence, defined by {@code
* access} strategy for the given {@code input}, so use this method with caution.
@@ -47,7 +47,7 @@ public final class Hasher {
* as ordered byte sequence
* @param offset offset to the first byte of the subsequence to hash
* @param length length of the subsequence to hash
* @param <T> the type of the input
* @param <T> the type of the input
* @return hash code for the specified bytes subsequence
*/
public static <T> long hash(T input, Access<T> access, long offset, long length) {
@@ -18,7 +18,8 @@ package net.openhft.chronicle.hash.hashing;
final class Primitives {
private Primitives() {}
private Primitives() {
}
static long unsignedInt(int i) {
return i & 0xFFFFFFFFL;
@@ -164,7 +164,7 @@ public abstract class AbstractReplication implements Serializable {
* Configures if the node, provided with replication, created by this builder, should
* replicate only local data, last updated with own identifier, or all data currently
* present on the node, when a new node joins the replication grid.
*
* <p>
* <p>Default configuration is {@code false}, potentially swamping new nodes with
* duplicates. However, this does guarantee that all the data is replicated over to the new
* node and is useful especially in the case that the originating node of some data is not
@@ -30,7 +30,7 @@ public interface ConnectionListener {
void onConnect(InetAddress address, byte identifier, boolean isServer);
/**
* @param address the address that we have been disconnected from
* @param address the address that we have been disconnected from
* @param identifier the identifer the address that we have been disconnected from or Byte
*/
void onDisconnect(InetAddress address, byte identifier);
@@ -28,8 +28,8 @@ public interface RemoteNodeValidator {
* and host.
*
* @param remoteIdentifier remoteIdentifier
* @param remoteAddress remoteAddress
* @return true if unique
* @param remoteAddress remoteAddress
* @return true if unique
*/
boolean validate(byte remoteIdentifier, SocketAddress remoteAddress);
@@ -27,15 +27,15 @@ import java.io.Serializable;
* ChronicleHashInstanceBuilder#replicatedViaChannel(ReplicationChannel)} method, to establish a channel
* replication. See <a href="https://github.com/OpenHFT/Chronicle-Map#multiple-chronicle-maps---network-distributed">
* the corresponding section in ChronicleMap manual</a> for more information.
*
* <p>
* <p>A {@code ReplicationChannel} could be used to replicate only one {@link ChronicleHash} instance.
*
* @see ReplicationHub
* @see ReplicationHub#createChannel(int)
*/
public final class ReplicationChannel implements Serializable{
private ReplicationHub hub;
public final class ReplicationChannel implements Serializable {
private final int channelId;
private ReplicationHub hub;
ReplicationChannel(ReplicationHub hub, int channelId) {
this.hub = hub;
@@ -33,7 +33,7 @@ import java.util.Arrays;
* buffers, worker threads for that, considerably reducing resources usage and increasing cumulative
* (for all replicated containers) replication throughput. See <a href="https://github.com/OpenHFT/Chronicle-Map#multiple-chronicle-maps---network-distributed">
* the corresponding section in ChronicleMap manual</a> for more information.
*
* <p>
* <p>Create instances of this class using this pattern: <pre>{@code
* ReplicationHub hub = ReplicationHub.builder()
* .tcpTransportAndNetwork(tcpConfig)
@@ -131,7 +131,7 @@ public final class ReplicationHub extends AbstractReplication {
/**
* Configures the maximum number of channels could be {@linkplain #createChannel(int)}
* created for {@code ReplicationHub}s, created by this builder.
*
* <p>
* <p>Default value is {@code 128}.
*
* @param maxNumberOfChannels {@link ReplicationHub#maxNumberOfChannels()} of {@link
@@ -20,15 +20,15 @@ import org.jetbrains.annotations.NotNull;
public class SingleChronicleHashReplication extends AbstractReplication {
public SingleChronicleHashReplication(byte localIdentifier, Builder builder) {
super(localIdentifier, builder);
}
@NotNull
public static Builder builder() {
return new Builder();
}
public SingleChronicleHashReplication(byte localIdentifier, Builder builder) {
super(localIdentifier, builder);
}
@Override
public String toString() {
return "SingleChronicleHashReplication{" + super.toString() + "}";
@@ -36,7 +36,8 @@ public class SingleChronicleHashReplication extends AbstractReplication {
public static class Builder
extends AbstractReplication.Builder<SingleChronicleHashReplication, Builder> {
private Builder() {}
private Builder() {
}
@NotNull
@Override
@@ -26,7 +26,7 @@ import java.io.Serializable;
* TimeProvider was aims to possibly later provide an optimization to
* {@link System#currentTimeMillis()} on every call to replicated {@link ChronicleMap}
* or {@link ChronicleSet}.
*
* <p>
* Subclasses should be immutable, because {@link ChronicleHashBuilder} doesn't make defensive
* copies.
*
@@ -23,7 +23,7 @@ import net.openhft.lang.model.Byteable;
* Writer for objects, which themselves are bytes sequence in some sense:
* {@link Byteable Byteables}, {@code byte[]} arrays, other primitive arrays, "flat" objects
* (with primitives fields only), particularly boxed primitive types.
*
* <p>
* <p>This interface is called "BytesInterop" because it allows to work with object as they
* are already marshalled to {@code Bytes}: {@linkplain #startsWith(Bytes, Object) compare}
* with other {@code Bytes}, i. e. interoperate objects and {@code Bytes}.
@@ -41,7 +41,7 @@ public interface BytesInterop<E> extends BytesWriter<E> {
* {@code bytes}' is positioned at the first byte to compare. {@code bytes}' limit
* is unspecified. {@code bytes}' position and limit shouldn't be altered during
* this call.
* @param e the object to serialize virtually and compare with the given {@code bytes}
* @param e the object to serialize virtually and compare with the given {@code bytes}
* @return if the given {@code bytes} starts with the given {@code e} object's serialized form
*/
boolean startsWith(Bytes bytes, E e);
@@ -26,18 +26,18 @@ import java.io.Serializable;
* Deserializer (object from {@link Bytes}, mirroring the {@link BytesWriter}, i. e. assuming the
* length of the serialized form isn't written in the beginning of the serialized form itself,
* but managed by {@link ChronicleHash} implementation and passed to the reading methods.
*
* <p>
* <p>Implementation example:<pre><code>
* class LongPair { long first, second; }
*
* <p>
* enum LongPairArrayReader implements BytesReader&lt;LongPair[]&gt; {
* INSTANCE;
*
* <p>
* &#064;Override
* public LongPair[] read(Bytes bytes, long size) {
* return read(bytes, size, null);
* }
*
* <p>
* &#064;Override
* public LongPair[] read(Bytes bytes, long size, LongPair[] toReuse) {
* if (size &gt; Integer.MAX_VALUE * 16L)
@@ -72,13 +72,13 @@ public interface BytesReader<E> extends Serializable {
/**
* Reads and returns the object from {@code [position(), position() + size]} bytes of the given
* {@link Bytes}.
*
* <p>
* <p>Implementation of this method should increment the {@code bytes}' position by the given
* size, i. e. "consume" the bytes of the deserialized object. It must not alter the
* {@code bytes}' {@link Bytes#limit() limit} and contents.
*
* @param bytes the {@code Bytes} to read the object from
* @param size the size of the serialized form of the returned object
* @param size the size of the serialized form of the returned object
* @return the object read from the bytes
* @see BytesWriter#write(Bytes, Object)
* @see #read(Bytes, long, Object)
@@ -93,8 +93,8 @@ public interface BytesReader<E> extends Serializable {
* be {@code null}, in this case this method should behave exactly the same as
* {@link #read(Bytes, long)} method does.
*
* @param bytes the {@code Bytes} to read the object from
* @param size the size of the serialized form of the returned object
* @param bytes the {@code Bytes} to read the object from
* @param size the size of the serialized form of the returned object
* @param toReuse the object to read the deserialized data into
* @return the object read from the bytes, either reused or newly created
* @see #read(Bytes, long)
@@ -26,18 +26,18 @@ import java.io.Serializable;
* of any object before actual serialization 2) doesn't include that length in the serialized
* form itself, assuming it will be passed by the {@link ChronicleHash} into
* {@link BytesReader#read(Bytes, long)} deserialization method.
*
* <p>
* <p>Implementation example: <pre><code>
* class LongPair { long first, second; }
*
* <p>
* enum LongPairArrayWriter implements BytesWriter&lt;LongPair[]&gt; {
* INSTANCE;
*
* <p>
* &#064;Override
* public long size(LongPair[] longPairs) {
* return longPairs.length * 16L;
* }
*
* <p>
* &#064;Override
* public void write(Bytes bytes, LongPair[] longPairs) {
* for (LongPair pair : longPairs) {
@@ -66,7 +66,7 @@ public interface BytesWriter<E> extends Serializable {
/**
* Serializes the given object to the given {@code bytes}, without writing the length of the
* serialized form itself.
*
* <p>
* <p>Implementation of this method should increment the {@code bytes}' {@linkplain
* Bytes#position() position} by {@link #size(Object) size(e)}. The given object should
* be written into these range between the initial {@code bytes}' position and the position
@@ -74,7 +74,7 @@ public interface BytesWriter<E> extends Serializable {
* {@code bytes}' {@linkplain Bytes#limit() limit} and contents outside of the specified range.
*
* @param bytes the {@code Bytes} to write the given object to
* @param e the object to serialize to the given bytes
* @param e the object to serialize to the given bytes
* @see BytesReader#read(Bytes, long)
*/
void write(Bytes bytes, E e);
@@ -22,10 +22,17 @@ import static net.openhft.lang.io.IOTools.stopBitLength;
public final class SizeMarshallers {
private SizeMarshallers() {
}
public static SizeMarshaller stopBit() {
return StopBit.INSTANCE;
}
public static SizeMarshaller constant(long size) {
return new ConstantSizeMarshaller(size);
}
private enum StopBit implements SizeMarshaller {
INSTANCE;
@@ -60,10 +67,6 @@ public final class SizeMarshallers {
}
}
public static SizeMarshaller constant(long size) {
return new ConstantSizeMarshaller(size);
}
private static class ConstantSizeMarshaller implements SizeMarshaller {
private static final long serialVersionUID = 0L;
@@ -103,6 +106,4 @@ public final class SizeMarshallers {
return size;
}
}
private SizeMarshallers() {}
}
@@ -22,25 +22,12 @@ import net.openhft.lang.threadlocal.Provider;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
public abstract class BasicCopyingMetaBytesInterop<E, W> implements MetaBytesInterop<E, W> {
private static final long serialVersionUID = 0L;
static final Provider<DirectBytesBuffer> provider =
Provider.of(DirectBytesBuffer.class);
static abstract class BasicCopyingMetaBytesInteropProvider<E, I,
MI extends MetaBytesInterop<E, I>> implements MetaProvider<E, I, MI> {
private static final long serialVersionUID = 0L;
@Override
public ThreadLocalCopies getCopies(ThreadLocalCopies copies) {
return provider.getCopies(copies);
}
}
private static final long serialVersionUID = 0L;
final DirectBytesBuffer buffer;
transient long size;
transient long hash;
protected BasicCopyingMetaBytesInterop(DirectBytesBuffer buffer) {
this.buffer = buffer;
}
@@ -67,4 +54,14 @@ public abstract class BasicCopyingMetaBytesInterop<E, W> implements MetaBytesInt
public void write(W writer, Bytes bytes, E e) {
bytes.write(buffer.buffer, buffer.buffer.position(), buffer.buffer.remaining());
}
static abstract class BasicCopyingMetaBytesInteropProvider<E, I,
MI extends MetaBytesInterop<E, I>> implements MetaProvider<E, I, MI> {
private static final long serialVersionUID = 0L;
@Override
public ThreadLocalCopies getCopies(ThreadLocalCopies copies) {
return provider.getCopies(copies);
}
}
}
@@ -25,6 +25,9 @@ import net.openhft.lang.io.serialization.BytesMarshaller;
*/
public final class BytesReaders {
private BytesReaders() {
}
/**
* Returns a {@link BytesReader} wrapping the given {@link BytesMarshaller}. One of the
* bridge methods between general serialization API from {@link net.openhft.lang} and
@@ -44,7 +47,7 @@ public final class BytesReaders {
* #fromBytesMarshaller(BytesMarshaller) fromBytesMarshaller(m)} call, {@code null} otherwise.
*
* @param reader reader to extract {@code BytesMarshaller} from
* @param <E> type of the objects marshalled
* @param <E> type of the objects marshalled
* @return {@code BytesMarshaller} from which the specified reader was created, or {@code null}
*/
public static <E> BytesMarshaller<E> getBytesMarshaller(BytesReader<E> reader) {
@@ -70,7 +73,4 @@ public final class BytesReaders {
return (E) marshaller.read(bytes, toReuse);
}
}
private BytesReaders() {
}
}
@@ -27,6 +27,12 @@ public abstract class CopyingMetaBytesInterop<E, W> extends BasicCopyingMetaByte
private static final long serialVersionUID = 1L;
private static final long MAX_REASONABLE_SERIALIZED_SIZE = MemoryUnit.MEGABYTES.toBytes(16L);
transient W writer;
transient E cur;
protected CopyingMetaBytesInterop(DirectBytesBuffer buffer) {
super(buffer);
}
public static void checkMaxSizeStillReasonable(long maxSize, Exception ex) {
if (maxSize > MAX_REASONABLE_SERIALIZED_SIZE) {
@@ -39,17 +45,6 @@ public abstract class CopyingMetaBytesInterop<E, W> extends BasicCopyingMetaByte
}
}
transient W writer;
transient E cur;
protected CopyingMetaBytesInterop(DirectBytesBuffer buffer) {
super(buffer);
}
DirectBytesBuffer buffer() {
return buffer;
}
public static <E, M extends BytesMarshaller<E>>
MetaBytesInterop<E, M> forBytesMarshaller(Serializable bufferIdentity) {
return new DirectBytesBuffer(bufferIdentity).forBytesMarshaller;
@@ -66,6 +61,15 @@ public abstract class CopyingMetaBytesInterop<E, W> extends BasicCopyingMetaByte
return new BytesMarshallerCopyingMetaBytesInteropProvider<>(mutable, maxSize);
}
public static <E, W extends BytesWriter<E>>
MetaProvider<E, W, CopyingMetaBytesInterop<E, W>> providerForBytesWriter(boolean mutable) {
return new BytesWriterCopyingMetaBytesInteropProvider<>(mutable);
}
DirectBytesBuffer buffer() {
return buffer;
}
private static class BytesMarshallerCopyingMetaBytesInteropProvider<E,
M extends BytesMarshaller<E>>
extends BasicCopyingMetaBytesInteropProvider<E, M, CopyingMetaBytesInterop<E, M>> {
@@ -89,11 +93,6 @@ public abstract class CopyingMetaBytesInterop<E, W> extends BasicCopyingMetaByte
}
}
public static <E, W extends BytesWriter<E>>
MetaProvider<E, W, CopyingMetaBytesInterop<E, W>> providerForBytesWriter(boolean mutable) {
return new BytesWriterCopyingMetaBytesInteropProvider<>(mutable);
}
private static class BytesWriterCopyingMetaBytesInteropProvider<E, W extends BytesWriter<E>>
extends BasicCopyingMetaBytesInteropProvider<E, W, CopyingMetaBytesInterop<E, W>> {
private static final long serialVersionUID = 0L;
@@ -105,7 +104,7 @@ public abstract class CopyingMetaBytesInterop<E, W> extends BasicCopyingMetaByte
@Override
public CopyingMetaBytesInterop<E, W> get(ThreadLocalCopies copies,
CopyingMetaBytesInterop<E, W> originalMetaWriter, W writer, E e) {
CopyingMetaBytesInterop<E, W> originalMetaWriter, W writer, E e) {
DirectBytesBuffer.ForBytesWriter forBytesWriter =
provider.get(copies, originalMetaWriter.buffer()).forBytesWriter;
forBytesWriter.init(writer, e, mutable);
@@ -33,15 +33,6 @@ public abstract class DataValueMetaBytesInterop<E>
super(buffer);
}
void init(BytesWriter<E> writer, E e, long size) {
Bytes buffer = this.buffer.obtain(size, true);
writer.write(buffer, e);
buffer.flip();
assert buffer.remaining() == size;
this.size = size;
hash = 0L;
}
public static <E> MetaBytesInterop<E, BytesWriter<E>> forIdentity(Serializable bufferIdentity) {
return new DirectBytesBuffer(bufferIdentity).forDataValueWriter;
}
@@ -51,8 +42,17 @@ public abstract class DataValueMetaBytesInterop<E>
return new InteropProvider<>(eClass);
}
void init(BytesWriter<E> writer, E e, long size) {
Bytes buffer = this.buffer.obtain(size, true);
writer.write(buffer, e);
buffer.flip();
assert buffer.remaining() == size;
this.size = size;
hash = 0L;
}
private static class InteropProvider<E> extends BasicCopyingMetaBytesInteropProvider<
E, BytesWriter<E>, MetaBytesInterop<E, BytesWriter<E>>> {
E, BytesWriter<E>, MetaBytesInterop<E, BytesWriter<E>>> {
private static final long serialVersionUID = 0L;
private final Class<E> eClass;
@@ -84,7 +84,7 @@ public abstract class DataValueMetaBytesInterop<E>
if (e instanceof Byteable)
return metaByteableInterop;
DirectBytesBuffer.ForDataValueWriter forDataValueWriter =
provider.get(copies, ((DataValueMetaBytesInterop)originalMetaWriter).buffer)
provider.get(copies, ((DataValueMetaBytesInterop) originalMetaWriter).buffer)
.forDataValueWriter;
forDataValueWriter.init(writer, e, size);
return forDataValueWriter;
@@ -510,7 +510,7 @@ abstract class AbstractChannelReplicator implements Closeable {
start = in.position();
externalizable.writeExternalEntry(entry, in, chronicleId,bootstrapTime);
externalizable.writeExternalEntry(entry, in, chronicleId, bootstrapTime);
if (in.position() == start) {
in.position(pos0);
@@ -20,9 +20,10 @@ import org.jetbrains.annotations.NotNull;
final class Asserts {
private Asserts() {
}
public static void assertNotNull(@NotNull Object obj) {
assert obj != null;
}
private Asserts() {}
}
@@ -33,7 +33,7 @@ import java.io.Serializable;
* ChronicleMapBuilder#keySizeMarshaller(SizeMarshaller)}), then (optionally) alignment (see {@link
* ChronicleMapBuilder#entryAndValueAlignment(Alignment)} ), followed by the serialized value
* itself.</li> </ul>
*
* <p>
* <p>There are helper methods {@link ChronicleMap#readKey(Bytes, long)} and {@link
* ChronicleMap#readValue(Bytes, long)} that help to deal with this.
*/
@@ -287,6 +287,7 @@ final class ChannelProvider implements Closeable {
ChannelProvider.this.close();
}
};
private ChannelProvider(ReplicationHub hub) {
localIdentifier = hub.identifier();
this.hub = hub;
@@ -31,18 +31,18 @@ import java.util.concurrent.ConcurrentMap;
/**
* Extension of {@link ConcurrentMap} interface, stores the data off-heap.
*
* <p>
* <p>For information on <ul> <li>how to construct a {@code ChronicleMap}</li> <li>{@code
* ChronicleMap} flavors and properties</li> <li>available configurations</li> </ul> see {@link
* ChronicleMapBuilder} documentation.
*
* <p>
* <p>Functionally this interface defines some methods supporting garbage-free off-heap programming:
* {@link #getUsing(Object, Object)}, {@link #acquireUsing(Object, Object)}.
*
* <p>
* <p>Roughly speaking, {@code ChronicleMap} compares keys and values by their binary serialized
* form, that shouldn't necessary be the same equality relation as defined by built-in {@link
* Object#equals(Object)} method, which is prescribed by general {@link Map} contract.
*
* <p>
* <p>Note that {@code ChronicleMap} extends {@link Closeable}, don't forget to {@linkplain #close()
* close} map when it is no longer needed.
*
@@ -61,7 +61,7 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
/**
* Returns the value to which the specified key is mapped, or {@code null} if this map contains
* no mapping for the key.
*
* <p>
* <p>If the value class allows reusing, particularly if it is a {@link Byteable} subclass,
* consider {@link #getUsing(Object, Object)} method instead of this to reduce garbage
* creation.
@@ -77,7 +77,7 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
/**
* Returns the value to which the specified key is mapped, read to the provided {@code value}
* object, if possible, or returns {@code null}, if this map contains no mapping for the key.
*
* <p>
* <p>If the specified key is present in the map, the value data is read to the provided {@code
* value} object via value marshaller's {@link BytesMarshaller#read(Bytes, Object) read(Bytes,
* value)} or value reader's {@link BytesReader#read(Bytes, long, Object) read(Bytes, size,
@@ -85,7 +85,7 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
* using which this map was constructed. If the value deserializer is able to reuse the given
* {@code value} object, calling this method instead of {@link #get(Object)} could help to
* reduce garbage creation.
*
* <p>
* <p>The provided {@code value} object is allowed to be {@code null}, in this case {@code
* map.getUsing(key, null)} call is semantically equivalent to simple {@code map.get(key)}
* call.
@@ -103,12 +103,12 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
/**
* The method is similar {@link V getUsing(K key, V usingValue);} but in addition read locks
* the map segment to operations to be performed atomically. ( see the example below )
*
* <p>
* Returns the ReadContext which holds a map segment lock and provides method to get the value
* ( to which the specified key is mapped) atomically ( see example below for an explanation ),
* read to the provided {@code value} object, if possible, or returns {@code null}, if this map
* contains no mapping for the key.
*
* <p>
* <p>If the specified key is present in the map, the readContext.value() uses the provided
* {@code usingValue} object via value marshaller's {@link BytesMarshaller#read(Bytes, Object)
* read(Bytes, value)} or value reader's {@link BytesReader#read(Bytes, long, Object)
@@ -128,14 +128,14 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
* }</pre>
* To ensure that you can read the 'issueDate' and 'symbol' can be read atomically, these values
* must be read while the segment lock is in place.
*
*
* <p>
* <p>
* <p>The provided {@code value} object is allowed to be {@code null}, in this case
*
* @param key the key whose associated value is to be returned
* @param usingValue the object to read value data in, if possible
* @return the read context containing the value to which the specified key is mapped
*
* <p>
* no mapping for the key
* @see #get(Object)
* @see #getUsing(Object, Object)
@@ -146,18 +146,18 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
/**
* Acquire a value for a key, creating if absent.
*
* <p>
* <p>If the specified key is absent in the map, {@linkplain ChronicleMapBuilder#defaultValue(Object)
* default value} is taken or {@linkplain ChronicleMapBuilder#defaultValueProvider(DefaultValueProvider)
* default value provider} is called. Then this object is put to this map for the specified
* key.
*
* <p>
* <p>Then, either if the key was initially absent in the map or already present, the value is
* deserialized just as during {@link #getUsing(Object, Object) getUsing(key, usingValue)} call,
* passed the same {@code key} and {@code usingValue} as into this method call. This means, as
* in {@link #getUsing}, {@code usingValue} could safely be {@code null}, in this case a new
* value instance is created to deserialize the data.
*
* <p>
* In code, {@code acquireUsing} is specified as :
* <pre>{@code
* V acquireUsing(K key, V usingValue) {
@@ -165,12 +165,12 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
* put(key, defaultValue(key));
* return getUsing(key, usingValue);
* }}</pre>
*
*
* <p>
* <p>
* Where {@code defaultValue(key)} returns either {@linkplain ChronicleMapBuilder#defaultValue(Object)
* default value} or {@link ChronicleMapBuilder#defaultValueProvider(DefaultValueProvider)
* defaultValueProvider.}
*
* <p>
* <p>If the {@code ChronicleMap} is off-heap updatable, i. e. created via {@link
* ChronicleMapBuilder} builder (values are {@link Byteable}), there is one more option of what
* to do if the key is absent in the map. By default, value bytes are just zeroed out, no
@@ -247,22 +247,21 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
/**
* Creates an empty value instance, which can be used with the
* following methods :
*
* <p>
* {@link ChronicleMap#getUsing(java.lang.Object, java.lang.Object) }
* {@link ChronicleMap#getUsingLocked(java.lang.Object, java.lang.Object) }
* {@link ChronicleMap#acquireUsing(java.lang.Object, java.lang.Object) }
* {@link ChronicleMap#acquireUsingLocked(java.lang.Object, java.lang.Object) }
*
* <p>
* for example like this :
*
* <pre>{@code
* <p>
* <pre>{@code
* V value = map.newValueInstance();
* try (ReadContext rc = map.getUsingLocked(key, value)) {
* // add your logic here
* } // the read lock is released here
* }</pre>
*
*
* @return a new empty instance based on the Value type
* @see ChronicleMap#getUsing(java.lang.Object, java.lang.Object)
* @see ChronicleMap#getUsingLocked(java.lang.Object, java.lang.Object)
@@ -274,15 +273,15 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
/**
* Creates an empty value instance, which can be used with the
* following methods :
*
* <p>
* {@link ChronicleMap#getUsing(java.lang.Object, java.lang.Object) }
* {@link ChronicleMap#getUsingLocked(java.lang.Object, java.lang.Object) }
* {@link ChronicleMap#acquireUsing(java.lang.Object, java.lang.Object) }
* {@link ChronicleMap#acquireUsingLocked(java.lang.Object, java.lang.Object) }
*
* <p>
* for example like this :
*
* <pre>{@code
* <p>
* <pre>{@code
* K key = map.newKeyInstance();
* key.setMyStringField("some key");
*
@@ -291,7 +290,6 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>, ChronicleHash {
* } // the read lock is released here
* }</pre>
*
*
* @return a new empty instance based on the Key type
* @see ChronicleMap#getUsing(java.lang.Object, java.lang.Object)
* @see ChronicleMap#getUsingLocked(java.lang.Object, java.lang.Object)
@@ -151,6 +151,7 @@ public class ChronicleMapBuilder<K, V> implements Cloneable,
private PrepareValueBytes<K, V> prepareValueBytes = null;
private SingleChronicleHashReplication singleHashReplication = null;
private InetSocketAddress[] pushToAddresses;
ChronicleMapBuilder(Class<K> keyClass, Class<V> valueClass) {
keyBuilder = new SerializationBuilder<>(keyClass, SerializationBuilder.Role.KEY);
valueBuilder = new SerializationBuilder<>(valueClass, SerializationBuilder.Role.VALUE);
@@ -32,10 +32,7 @@ public final class ChronicleMapStatelessClientBuilder<K, V> implements
ChronicleMap<K, V>>,
MapBuilder<ChronicleMapStatelessClientBuilder<K, V>> {
static <K, V> ChronicleMapStatelessClientBuilder<K, V> of(
InetSocketAddress serverAddress) {
return new ChronicleMapStatelessClientBuilder<>(serverAddress);
}
private final InetSocketAddress remoteAddress;
// This method is meaningful, despite you could call of().create(), because Java 7 doesn't
// infer type parameters if case of chained calls, like this; and then you couldn't omit class
@@ -44,33 +41,35 @@ public final class ChronicleMapStatelessClientBuilder<K, V> implements
// vs
// createClientOf(addr) // static import
// -- the second is really shorter.
/**
* Equivalent of {@code ChronicleMapStatelessClientBuilder.<K, V>of(serverAddress).create()}.
*
* @param serverAddress address of the server map
* @param <K> key type of the map
* @param <V> value type of the map
* @return stateless client of the ChronicleMap of server
*/
public static <K, V> ChronicleMap<K, V> createClientOf(InetSocketAddress serverAddress)
throws IOException {
return ChronicleMapStatelessClientBuilder.<K, V>of(serverAddress).create();
}
private final InetSocketAddress remoteAddress;
private final AtomicBoolean used = new AtomicBoolean(false);
private boolean putReturnsNull = false;
private boolean removeReturnsNull = false;
private long timeoutMs = TimeUnit.SECONDS.toMillis(10);
private String name;
private int tcpBufferSize = (int) MemoryUnit.KILOBYTES.toBytes(64);
private final AtomicBoolean used = new AtomicBoolean(false);
ChronicleMapStatelessClientBuilder(InetSocketAddress remoteAddress) {
this.remoteAddress = remoteAddress;
}
static <K, V> ChronicleMapStatelessClientBuilder<K, V> of(
InetSocketAddress serverAddress) {
return new ChronicleMapStatelessClientBuilder<>(serverAddress);
}
/**
* Equivalent of {@code ChronicleMapStatelessClientBuilder.<K, V>of(serverAddress).create()}.
*
* @param serverAddress address of the server map
* @param <K> key type of the map
* @param <V> value type of the map
* @return stateless client of the ChronicleMap of server
*/
public static <K, V> ChronicleMap<K, V> createClientOf(InetSocketAddress serverAddress)
throws IOException {
return ChronicleMapStatelessClientBuilder.<K, V>of(serverAddress).create();
}
InetSocketAddress remoteAddress() {
return remoteAddress;
}
@@ -24,10 +24,9 @@ import java.nio.ByteBuffer;
final class ConstantValueProvider<K, V> implements DefaultValueProvider<K, V> {
private static final long serialVersionUID = 0L;
private transient V value;
private final int size;
private final byte[] serializedValueBytes;
private transient V value;
<W> ConstantValueProvider(V value, MetaBytesWriter<V, W> metaValueWriter, W valueWriter) {
this.value = value;
@@ -24,7 +24,7 @@ import java.io.Closeable;
/**
* A simpler form of the replication interface used by Engine
*
* <p>
* *** PLEASE DON'T REFACTOR THIS WITHOUT FIRST CHANGING THE ENGINE CODE ***
*
* @author Rob Austin.
@@ -20,7 +20,7 @@ import java.io.Serializable;
/**
* Represents a function that accepts one argument and produces a result.
*
* <p>
* <p>This is a <a href="package-summary.html">functional interface</a> whose functional method is {@link
* #apply(Object)}.
*
@@ -23,18 +23,8 @@ import static net.openhft.lang.Maths.isPowerOf2;
interface HashSplitting extends Serializable {
int segmentIndex(long hash);
long segmentHash(long hash);
class Splitting {
static HashSplitting forSegments(int segments) {
assert segments > 0;
if (segments == 1)
return ForSingleSegment.INSTANCE;
if (isPowerOf2(segments))
return new ForPowerOf2Segments(segments);
return new ForNonPowerOf2Segments(segments);
}
}
long segmentHash(long hash);
enum ForSingleSegment implements HashSplitting {
INSTANCE;
@@ -50,6 +40,17 @@ interface HashSplitting extends Serializable {
}
}
class Splitting {
static HashSplitting forSegments(int segments) {
assert segments > 0;
if (segments == 1)
return ForSingleSegment.INSTANCE;
if (isPowerOf2(segments))
return new ForPowerOf2Segments(segments);
return new ForNonPowerOf2Segments(segments);
}
}
class ForPowerOf2Segments implements HashSplitting {
private static final long serialVersionUID = 0L;
@@ -302,6 +302,7 @@ class Int24Int24MultiMap implements MultiMap {
public long capacity() {
return capacity;
}
@Override
public DirectBitSet getPositions() {
return positions;
@@ -213,7 +213,7 @@ class IntIntMultiMap implements MultiMap {
@Override
public long nextPos(SearchState searchState) {
long pos = searchState.searchPos;
for(long count = capacity; count > 0; count--) {
for (long count = capacity; count > 0; count--) {
long entry = bytes.readLong(pos);
if (entry == UNSET_ENTRY) {
searchState.searchPos = pos;
@@ -31,13 +31,13 @@ public interface MapBuilder<C extends MapBuilder<C>> {
* Configures if the maps created by this {@code MapBuilder} should return {@code null}
* instead of previous mapped values on {@link ChronicleMap#put(Object, Object)
* ChornicleMap.put(key, value)} calls.
*
* <p>
* <p>{@link Map#put(Object, Object) Map.put()} returns the previous value, functionality
* which is rarely used but fairly cheap for simple in-process, on-heap implementations like
* {@link HashMap}. But an off-heap collection has to create a new object and deserialize
* the data from off-heap memory. A collection hiding remote queries over the network should
* send the value back in addition to that. It's expensive for something you probably don't use.
*
* <p>
* <p>By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract and
* returns the previous mapped value on {@code put()} calls.
*
@@ -53,13 +53,13 @@ public interface MapBuilder<C extends MapBuilder<C>> {
* Configures if the maps created by this {@code MapBuilder} should return {@code null}
* instead of the last mapped value on {@link ChronicleMap#remove(Object)
* ChronicleMap.remove(key)} calls.
*
* <p>
* <p>{@link Map#remove(Object) Map.remove()} returns the previous value, functionality which is
* rarely used but fairly cheap for simple in-process, on-heap implementations like {@link
* HashMap}. But an off-heap collection has to create a new object and deserialize the data
* from off-heap memory. A collection hiding remote queries over the network should send
* the value back in addition to that. It's expensive for something you probably don't use.
*
* <p>
* <p>By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract and
* returns the mapped value on {@code remove()} calls.
*
@@ -26,18 +26,18 @@ import java.io.Serializable;
/**
* Contains methods which are called when {@link ChronicleMap} key events occur. Typical use cases:
* <ul> <li>Map data backup / replication.</li> <li>Logging, monitoring, debugging.</li> </ul>
*
* <p>
* <p>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.
*
* <p>
* <p>To configure {@code MapEventListener} for {@code ChronicleMap}, use {@link
* ChronicleMapBuilder#eventListener(MapEventListener)} method.
*
* <p>
* <p>See {@link #logging(String)} implementation.
*
* <p>
* <p>All these calls are synchronous while a {@code ChronicleMap} lock is held so make them as
* quick as possible.
*
* <p>
* <p>The {@code entry} passed to the methods is {@code Bytes} instance positioned at meta data
* area. See {@link ChronicleHashBuilder#metaDataBytes(int)} for more information.
*
@@ -70,7 +70,7 @@ public abstract class MapEventListener<K, V> implements Serializable {
* 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.
*
* <p>
* <p>This method is called when put is already happened.
*
* @param key the key the given value is put for
@@ -30,13 +30,12 @@ final class MapInstanceBuilder<K, V>
implements ChronicleHashInstanceBuilder<ChronicleMap<K, V>>, Serializable {
final ChronicleMapBuilder<K, V> mapBuilder;
final AtomicBoolean used;
transient SingleChronicleHashReplication singleHashReplication;
transient ReplicationChannel channel;
transient File file;
String name;
final AtomicBoolean used;
MapInstanceBuilder(ChronicleMapBuilder<K, V> mapBuilder,
SingleChronicleHashReplication singleHashReplication,
ReplicationChannel channel,
@@ -27,7 +27,7 @@ import static net.openhft.lang.MemoryUnit.*;
/**
* Created by peter on 09/11/14.
*
* <p>
* In future we might support I32 -> I16 or similar.
*/
enum MultiMapFactory {
@@ -94,7 +94,7 @@ enum MultiMapFactory {
if (minCapacity < 0L)
throw new IllegalArgumentException("minCapacity should be positive");
long capacity = Maths.nextPower2(minCapacity, 16L);
if (((double) minCapacity) / capacity > 2./3.) {
if (((double) minCapacity) / capacity > 2. / 3.) {
// multi map shouldn't be too dense
capacity <<= 1L;
}
@@ -33,14 +33,13 @@ import java.io.Serializable;
* .prepareDefaultValueBytes((bytes, k) -> bytes.writeLong(1L))
* ...
* .create();}</pre>
*
* <p>
* <p>Although the value type is not used in the API, {@link PrepareValueBytes} is not intended
* to be generic by value type, because strategy should know the value layout and
* {@linkplain Byteable#maxSize() how much bytes} does it take in memory.
*
* @param <K> the key type of {@link ChronicleMap}, on which {@code acquireUsing()} is queried
* @param <V> the value type of {@link ChronicleMap}, on which {@code acquireUsing()} is queried
*/
public interface PrepareValueBytes<K, V> extends Serializable {
@@ -51,11 +50,11 @@ public interface PrepareValueBytes<K, V> extends Serializable {
* outside of this range shouldn't be altered.
*
* @param bytes the bytes, positioned at the first value byte. Bytes' {@linkplain Bytes#limit(
* long) limit} and {@linkplain Bytes#remaining()} are not specified, but it is guaranteed that
* the latter is not less than {@linkplain Byteable#maxSize() the value size}.
* @param key the key which is absent in the {@link ChronicleMap} during {@link
* ChronicleMap#acquireUsing(Object, Object) acquireUsing()} call and value bytes are prepared
* for
*long) limit} and {@linkplain Bytes#remaining()} are not specified, but it is guaranteed that
* the latter is not less than {@linkplain Byteable#maxSize() the value size}.
* @param key the key which is absent in the {@link ChronicleMap} during {@link
* ChronicleMap#acquireUsing(Object, Object) acquireUsing()} call and value bytes are prepared
* for
*/
void prepare(Bytes bytes, K key);
}
@@ -28,5 +28,6 @@ interface ReadValue<RV> {
* Updates the entry position by valueSize.
*/
RV readValue(@NotNull ThreadLocalCopies copies, Bytes entry, RV usingValue, long valueSize);
RV readNull();
}
@@ -48,7 +48,7 @@ interface Replica extends Closeable, EngineReplicationLangBytes {
* Gets (if it does not exist, creates) an instance of ModificationIterator associated with a
* remote node, this weak associated is bound using the {@code identifier}.
*
* @param remoteIdentifier the identifier of the remote node
* @param remoteIdentifier the identifier of the remote node
* @return the ModificationIterator dedicated for replication to the remote node with the given
* identifier
* @see #identifier()
@@ -152,11 +152,12 @@ interface Replica extends Closeable, EngineReplicationLangBytes {
/**
* The map implements this method to save its contents.
* @param entry the byte location of the entry to be stored
* @param destination a buffer the entry will be written to, the segment may reject this
* operation and add zeroBytes, if the identifier in the entry did not
* match the maps local
* @param chronicleId is the channel id used to identify the canonical map or queue
*
* @param entry the byte location of the entry to be stored
* @param destination a buffer the entry will be written to, the segment may reject this
* operation and add zeroBytes, if the identifier in the entry did not
* match the maps local
* @param chronicleId is the channel id used to identify the canonical map or queue
* @param bootstrapTime
*/
void writeExternalEntry(@NotNull Bytes entry,
@@ -169,7 +170,7 @@ interface Replica extends Closeable, EngineReplicationLangBytes {
* in the same sequence and with the same types as were written by {@code
* writeExternalEntry()}. This method is typically called when we receive a remote
* replication event, this event could originate from either a remote {@code put(K key, V
*value)} or {@code remove(Object key)}
* value)} or {@code remove(Object key)}
*
* @param copies
* @param segmentState
@@ -217,16 +218,14 @@ interface Replica extends Closeable, EngineReplicationLangBytes {
/**
* Called whenever a put() or remove() has occurred to a replicating map.
*
* @param entry the entry you will receive, this does not have to be locked, as
* locking is already provided from the caller.
* @param chronicleId only assigned when clustering
* @param entry the entry you will receive, this does not have to be locked, as
* locking is already provided from the caller.
* @param chronicleId only assigned when clustering
* @param bootStrapTimeStamp sent to the client on every update this is the timestamp
* that the remote client should bootstrap from when there has
* been a disconnection, this time maybe later than the message
* time as event are not send in chronological order from the
* bit set.
*
*
* @return {@code false} if this entry should be ignored because the identifier of the
* source node is not from one of our changes, WARNING even though we check the identifier
* in the ModificationIterator the entry may have been updated.
@@ -41,14 +41,14 @@ final class SelectedSelectionKeySet extends AbstractSet<SelectionKey> {
if (isA) {
int size = keysASize;
keysA[size ++] = o;
keysA[size++] = o;
keysASize = size;
if (size == keysA.length) {
doubleCapacityA();
}
} else {
int size = keysBSize;
keysB[size ++] = o;
keysB[size++] = o;
keysBSize = size;
if (size == keysB.length) {
doubleCapacityB();
@@ -49,6 +49,29 @@ final class SerializationBuilder<E> implements Cloneable, Serializable {
private static final long serialVersionUID = 0L;
private static final Bytes EMPTY_BYTES = new ByteBufferBytes(ByteBuffer.allocate(0));
private static final List<Class> knownJDKImmutableClasses = Arrays.<Class>asList(
String.class, Byte.class, Short.class, Character.class, Integer.class,
Float.class, Long.class, Double.class, BigDecimal.class, BigInteger.class, URL.class
);
final Class<E> eClass;
final boolean sizeIsStaticallyKnown;
private final Role role;
boolean serializesGeneratedClasses = false;
private boolean instancesAreMutable;
private SizeMarshaller sizeMarshaller = stopBit();
private BytesReader<E> reader;
private Object interop;
private CopyingInterop copyingInterop = null;
private MetaBytesInterop<E, ?> metaInterop;
private MetaProvider<E, ?, ?> metaInteropProvider;
private long maxSize;
@SuppressWarnings("unchecked")
SerializationBuilder(Class<E> eClass, Role role) {
this.role = role;
this.eClass = eClass;
configureByDefault(eClass, role);
sizeIsStaticallyKnown = constantSizeMarshaller();
}
private static boolean concreteClass(Class c) {
return !c.isInterface() && !Modifier.isAbstract(c.getModifiers());
@@ -60,42 +83,10 @@ final class SerializationBuilder<E> implements Cloneable, Serializable {
Externalizable.class.isAssignableFrom(c);
}
private static final List<Class> knownJDKImmutableClasses = Arrays.<Class>asList(
String.class, Byte.class, Short.class, Character.class, Integer.class,
Float.class, Long.class, Double.class, BigDecimal.class, BigInteger.class, URL.class
);
private static boolean instancesAreMutable(Class c) {
return !knownJDKImmutableClasses.contains(c);
}
enum Role {KEY, VALUE}
private enum CopyingInterop {FROM_MARSHALLER, FROM_WRITER}
private final Role role;
final Class<E> eClass;
private boolean instancesAreMutable;
private SizeMarshaller sizeMarshaller = stopBit();
private BytesReader<E> reader;
private Object interop;
private CopyingInterop copyingInterop = null;
private MetaBytesInterop<E, ?> metaInterop;
private MetaProvider<E, ?, ?> metaInteropProvider;
private long maxSize;
final boolean sizeIsStaticallyKnown;
boolean serializesGeneratedClasses = false;
@SuppressWarnings("unchecked")
SerializationBuilder(Class<E> eClass, Role role) {
this.role = role;
this.eClass = eClass;
configureByDefault(eClass, role);
sizeIsStaticallyKnown = constantSizeMarshaller();
}
private void configureByDefault(Class<E> eClass, Role role) {
instancesAreMutable = instancesAreMutable(eClass);
@@ -446,6 +437,10 @@ final class SerializationBuilder<E> implements Cloneable, Serializable {
}
}
enum Role {KEY, VALUE}
private enum CopyingInterop {FROM_MARSHALLER, FROM_WRITER}
private static class SerializableMarshaller implements BytesMarshaller {
private static final long serialVersionUID = 0L;
@@ -227,7 +227,7 @@ class ShortShortMultiMap implements MultiMap {
@Override
public long nextPos(SearchState searchState) {
int pos = (int) searchState.searchPos;
for(int count = capacity; count > 0; count--) {
for (int count = capacity; count > 0; count--) {
int entry = bytes.readInt(pos);
if (entry == UNSET_ENTRY) {
searchState.searchPos = pos;
@@ -1072,7 +1072,7 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
try {
// block until we have received all the bytes in this chunk
receiveBytesFromSocket(remainingBytes, timeoutTime);
}catch (java.nio.channels.AsynchronousCloseException e ){
} catch (java.nio.channels.AsynchronousCloseException e) {
return inBytes;
}
@@ -1153,10 +1153,10 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
if (!message.startsWith("java.io.IOException: Not enough available space for writing ")) {
throw e;
}
String substring = message.substring("java.io.IOException: Not enough available space for writing ".length(), message.length());
int i = substring.indexOf(' ');
String substring = message.substring("java.io.IOException: Not enough available space for writing ".length(), message.length());
int i = substring.indexOf(' ');
if (i == -1)
throw e;
throw e;
int size = Integer.parseInt(substring.substring(0, i));
@@ -20,11 +20,10 @@ import java.io.Serializable;
/**
* Represents a mutator that accepts one mutable argument, which it may alter and produces a result.
*
* <p>
* <p>This is not functional as it can alter an argument.
*
* @param <T> the type of the mutable input
*/
public interface UnaryOperator<T> extends Serializable {
@@ -40,7 +40,7 @@ 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.
*
* <p>
* <p>{@code ChronicleMapBuilder} is mutable, see a note in {@link
* ChronicleHashBuilder} interface documentation.
*
@@ -101,21 +101,21 @@ public final class ChronicleSetBuilder<E>
/**
* {@inheritDoc}
*
* <p>
* <p>Example: if keys in your set(s) are English words in {@link String} form, average English
* word length is 5.1, configure average key size of 6: <pre>{@code
* ChronicleSet<String> uniqueWords = ChronicleSetBuilder.of(String.class)
* .entries(50000)
* .averageKeySize(6)
* .create();}</pre>
*
* <p>
* <p>(Note that 6 is chosen as average key size in bytes despite strings in Java are UTF-16
* encoded (and each character takes 2 bytes on-heap), because default off-heap {@link String}
* encoding is UTF-8 in {@code ChronicleSet}.)
*
* @param averageKeySize
* @see #constantKeySizeBySample(Object)
* @see #actualChunkSize(int)
* @param averageKeySize
*/
@Override
public ChronicleSetBuilder<E> averageKeySize(double averageKeySize) {
@@ -125,7 +125,7 @@ public final class ChronicleSetBuilder<E>
/**
* {@inheritDoc}
*
* <p>
* <p>For example, if your keys are Git commit hashes:<pre>{@code
* Set<byte[]> gitCommitsOfInterest = ChronicleSetBuilder.of(byte[].class)
* .constantKeySizeBySample(new byte[20])
@@ -210,7 +210,7 @@ public final class ChronicleSetBuilder<E>
/**
* {@inheritDoc}
*
* <p>
* <p> Example: <pre>{@code Set<Key> set = ChronicleSetBuilder.of(Key.class)
* .entries(1_000_000)
* .keySize(100)
@@ -245,7 +245,7 @@ public final class ChronicleSetBuilder<E>
/**
* {@inheritDoc}
*
* <p>
* <p>Actually this is just a convenience method supporting key marshaller configurations, made
* initially during {@link #of(Class)} call. Because if you {@linkplain
* #keyMarshaller(BytesMarshaller) configure} own custom key marshaller, this method doesn't
@@ -28,10 +28,6 @@ public final class ChronicleSetStatelessClientBuilder<E> implements
ChronicleHashStatelessClientBuilder<
ChronicleSetStatelessClientBuilder<E>, ChronicleSet<E>> {
public static <E> ChronicleSetStatelessClientBuilder<E> of(InetSocketAddress serverAddress) {
return new ChronicleSetStatelessClientBuilder<>(serverAddress);
}
private final ChronicleMapStatelessClientBuilder<E, DummyValue> mapClientBuilder;
ChronicleSetStatelessClientBuilder(InetSocketAddress serverAddress) {
@@ -39,6 +35,10 @@ public final class ChronicleSetStatelessClientBuilder<E> implements
this.mapClientBuilder = ChronicleMapBuilder.of(eClass, DummyValue.class, serverAddress);
}
public static <E> ChronicleSetStatelessClientBuilder<E> of(InetSocketAddress serverAddress) {
return new ChronicleSetStatelessClientBuilder<>(serverAddress);
}
@Override
public ChronicleSetStatelessClientBuilder<E> timeout(long timeout, TimeUnit units) {
mapClientBuilder.timeout(timeout, units);
@@ -16,6 +16,6 @@
package net.openhft.chronicle.set;
enum DummyValue {
enum DummyValue {
DUMMY_VALUE
}
@@ -31,6 +31,7 @@ import static net.openhft.chronicle.set.DummyValue.DUMMY_VALUE;
class SetFromMap<E> extends AbstractSet<E>
implements ChronicleSet<E>, Serializable {
private static final long serialVersionUID = 2454657854757543876L;
private final ChronicleMap<E, DummyValue> m; // The backing map
private transient Set<E> s; // Its keySet
@@ -96,13 +97,11 @@ class SetFromMap<E> extends AbstractSet<E>
public boolean removeAll(Collection<?> c) {
return s.removeAll(c);
}
// addAll is the only inherited implementation
public boolean retainAll(Collection<?> c) {
return s.retainAll(c);
}
// addAll is the only inherited implementation
private static final long serialVersionUID = 2454657854757543876L;
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException {