Improved documentation

This commit is contained in:
leventov
2015-05-27 04:30:58 +01:00
parent b4c8554b77
commit 4fb73bb821
28 changed files with 319 additions and 42 deletions
@@ -20,13 +20,31 @@ package net.openhft.chronicle.hash;
import net.openhft.chronicle.algo.hashing.LongHashFunction;
/**
* Defines reasonable defaults for {@code Value}'s {@code equals()}, {@code hashCode()} and
* {@code toString()}. They should be default implementations in the {@code Value} interface itself,
* but Java 8 doesn't allow to override {@code Object}'s methods by default implementations
* in interfaces.
*/
public abstract class AbstractValue<V, T> implements Value<V, T> {
/**
* Constructor for use by subclasses.
*/
protected AbstractValue() {}
/**
* Computes value's hash code by applying a hash function to {@code Value}'s <i>bytes</i>
* representation.
*/
@Override
public int hashCode() {
return (int) hash(LongHashFunction.city_1_1());
}
/**
* Compares {@code Value}s' <i>bytes</i> representations.
*/
@Override
public boolean equals(Object obj) {
return obj != null &&
@@ -34,6 +52,9 @@ public abstract class AbstractValue<V, T> implements Value<V, T> {
Value.bytesEquivalent(this, (Value<?, ?>) obj);
}
/**
* Delegates to {@code Value}'s <i>object</i> {@code toString()}.
*/
@Override
public String toString() {
return get().toString();
@@ -18,6 +18,28 @@
package net.openhft.chronicle.hash;
import net.openhft.chronicle.map.replication.MapRemoteOperations;
import net.openhft.chronicle.set.replication.SetRemoteOperations;
/**
* Decision, if {@link MapRemoteOperations remote modification operation} should be accepted
* or discarded.
* *
* @see MapRemoteOperations
* @see SetRemoteOperations
*/
public enum AcceptanceDecision {
ACCEPT, DISCARD
/**
* Acceptance decision -- the remote modification operation is applied to the local
* {@link ChronicleHash} state. This decision should also been returned, when the actual
* state modification is not needed (for example, remote {@code remove entry} operation, while
* the entry is not present in the ChronicleHash locally), but the operation is generally
* considered acceptable.
*/
ACCEPT,
/**
* Discard decision -- the remote modification operation is rejected.
*/
DISCARD
}
@@ -1,7 +1,17 @@
package net.openhft.chronicle.hash;
/**
* {@link HashQueryContext} + {@link AutoCloseable}, for external {@link ChronicleHash} queries
* in <i>try-with-resources</i> blocks.
*
* @param <K> the hash key type
* @see ChronicleHash#queryContext(Object)
*/
public interface ExternalHashQueryContext<K> extends HashQueryContext<K>, AutoCloseable {
/**
* Could throw only unchecked exception.
*/
@Override
void close();
}
@@ -1,7 +1,19 @@
package net.openhft.chronicle.hash;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.set.SetAbsentEntry;
import org.jetbrains.annotations.NotNull;
/**
* Low-level operational context for the situations, when the new entry is going to be inserted
* into the {@link ChronicleHash}.
*
* <p>This interface is not usable by itself; it merely defines the common base for {@link
* MapAbsentEntry} and {@link SetAbsentEntry}.
*
* @param <K> the hash key type
* @see HashQueryContext#absentEntry()
*/
public interface HashAbsentEntry<K> {
/**
@@ -18,14 +18,19 @@
package net.openhft.chronicle.hash;
import net.openhft.chronicle.map.MapEntry;
import net.openhft.chronicle.map.MapEntryOperations;
import net.openhft.chronicle.set.SetEntry;
import org.jetbrains.annotations.NotNull;
/**
* Access to the <i>present</i> {@code ChronicleHash} entry.
* The <i>present</i> {@code ChronicleHash} entry context.
*
* <p>This interface is not usable by itself; it merely defines the common base for {@link MapEntry}
* and {@link SetEntry}.
*
* @param <K> type of the key in {@code ChronicleHash}
* @see MapEntryOperations
* @see HashQueryContext#entry()
*/
public interface HashEntry<K> {
/**
@@ -2,6 +2,12 @@ package net.openhft.chronicle.hash;
import net.openhft.chronicle.hash.locks.InterProcessReadWriteUpdateLock;
/**
* Context of {@link ChronicleHash} operations with <i>individual keys</i>.
*
* @param <K> the hash key type
* @see ChronicleHash#queryContext(Object)
*/
public interface HashQueryContext<K> extends HashContext<K>, InterProcessReadWriteUpdateLock {
/**
@@ -10,16 +16,20 @@ public interface HashQueryContext<K> extends HashContext<K>, InterProcessReadWri
Value<K, ?> queriedKey();
/**
* Returns the entry access object, if the entry with the queried key is <i>present</i>
* in the hash, returns {@code null} is the entry is <i>absent</i>. Might acquire
* {@link #readLock} before searching for the key, if the context is not locked yet.
* Returns the entry context, if the entry with the queried key is <i>present</i>
* in the {@code ChronicleHash}, returns {@code null} is the entry is <i>absent</i>.
*
* @implNote Might acquire {@link #readLock} before searching for the key, if the context
* is not locked yet.
*/
HashEntry<K> entry();
/**
* Returns the special <i>absent entry</i> object, if the entry with the queried key
* is <i>absent</i> in the hash, returns {@code null}, if the entry is <i>present</i>. Might
* acquire {@link #readLock} before searching for the key, if the context is not locked yet.
* is <i>absent</i> in the hash, returns {@code null}, if the entry is <i>present</i>.
*
* @implNote Might acquire {@link #readLock} before searching for the key, if the context
* is not locked yet.
*/
HashAbsentEntry<K> absentEntry();
}
@@ -35,6 +35,7 @@ import java.util.ConcurrentModificationException;
* </ul>
*
* @param <K> key type
* @deprecated incoherent abstraction. Replaced by {@link HashQueryContext} and {@link HashEntry}
*/
@Deprecated
public interface KeyContext<K> extends AutoCloseable, InterProcessReadWriteUpdateLock {
@@ -29,20 +29,33 @@ import org.jetbrains.annotations.Nullable;
*
* <p>Object access: {@link #get()}.
*
* In most cases, each particular value wraps either some object or some bytes. Object is marshalled
* to bytes lazily on demand, and bytes are lazily deserialized to object, accordingly.
* <p>In most cases, each particular value wraps either some object or some bytes. Object
* is marshalled to bytes lazily on demand, and bytes are lazily deserialized to object,
* accordingly.
*
* @param <V> type of the accessed objects
* @param <T> type of the handle for bytes access
*/
public interface Value<V, T> {
/**
* Returns access to the value's bytes.
*/
ReadAccess<T> access();
/**
* Returns a handle to access the value's bytes.
*/
T handle();
/**
* Returns the offset to the value's bytes.
*/
long offset();
/**
* Returns the size of the value's bytes.
*/
long size();
default long hash(LongHashFunction f) {
@@ -55,7 +55,9 @@ import static java.nio.ByteOrder.LITTLE_ENDIAN;
*
* @param <T> the type of the object to access
* @see LongHashFunction#hash(Object, Access, long, long)
* @deprecated moved to Chronicle-Bytes: {@link net.openhft.chronicle.bytes.Access}
*/
@Deprecated
public abstract class Access<T> {
/**
@@ -20,6 +20,7 @@ import net.openhft.lang.io.Bytes;
import java.nio.ByteOrder;
@Deprecated
public final class BytesAccess extends Access<Bytes> {
public static final BytesAccess INSTANCE = new BytesAccess();
@@ -49,7 +49,10 @@ import static net.openhft.chronicle.hash.hashing.UnsafeAccess.*;
* </ul>
*
* @see BytesInterop#hash(LongHashFunction, Object)
* @deprecated moved to Chronicle-Algorithms:
* {@link net.openhft.chronicle.algo.hashing.LongHashFunction}
*/
@Deprecated
public abstract class LongHashFunction implements Serializable {
private static final long serialVersionUID = 0L;
@@ -19,12 +19,36 @@
package net.openhft.chronicle.hash.replication;
import net.openhft.chronicle.hash.AcceptanceDecision;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.ChronicleHashBuilder;
import net.openhft.chronicle.map.replication.MapRemoteOperations;
import net.openhft.chronicle.set.replication.SetRemoteOperations;
import static net.openhft.chronicle.hash.AcceptanceDecision.ACCEPT;
import static net.openhft.chronicle.hash.AcceptanceDecision.DISCARD;
/**
* Specifies the default eventual consistency strategy for {@link ChronicleHashBuilder#replication(
* byte) replicated} {@link ChronicleHash}es:
* <i>last write wins</i>. If two writes to a single entry occurred simultaneously on different
* nodes, the write on the node with lower identifier wins.
*
* @see MapRemoteOperations
* @see SetRemoteOperations
*/
public final class DefaultEventualConsistencyStrategy {
/**
* Returns the acceptance decision, should be made about the modification operation in the
* given {@code context}, aiming to modify the given {@code entry}. This method doesn't do any
* changes to {@code entry} nor {@code context} state. {@link MapRemoteOperations} and
* {@link SetRemoteOperations} method implementations should guide the result of calling this
* method to do something to <i>actually</i> apply the remote operation.
*
* @param entry the entry to be modified
* @param context the remote operation context
* @return if the remote operation should be accepted or discarded
*/
public static AcceptanceDecision decideOnRemoteModification(
HashReplicableEntry<?> entry, RemoteOperationContext<?> context) {
long remoteTimestamp = context.remoteTimestamp();
@@ -28,7 +28,9 @@ import java.io.Serializable;
*
* @param <K> map key class
* @param <V> map value class
* @deprecated specialize {@link MapEntryOperations#defaultValue(MapAbsentEntry)} instead
*/
@Deprecated
public interface DefaultValueProvider<K, V> extends Serializable {
/**
* Returns a value to be put during {@link ChronicleMap#acquireUsing(Object, Object)} call
@@ -20,6 +20,17 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.ExternalHashQueryContext;
/**
* {@link MapQueryContext} + {@link AutoCloseable}, for external {@link ChronicleMap} queries
* in <i>try-with-resources</i> blocks.
*
* @param <K> the map key type
* @param <V> the map value type
* @param <R> the return type of {@link MapEntryOperations}, {@link
* ChronicleMapBuilder#entryOperations(MapEntryOperations) specified} for the queried {@code
* ChronicleMap}
* @see ChronicleMap#queryContext(Object)
*/
public interface ExternalMapQueryContext<K, V, R>
extends MapQueryContext<K, V, R>, ExternalHashQueryContext<K> {
}
@@ -38,20 +38,29 @@ public interface MapAbsentEntry<K, V> extends HashAbsentEntry<K> {
@NotNull MapContext<K, V, ?> context();
/**
* Inserts the new entry into the map, of {@link #absentKey() the key} and the given value.
* Inserts the new entry into the map, of {@linkplain #absentKey() the key} and the given {@code
* value}.
*
* <p>This method is the default implementation for {@link MapEntryOperations#insert(
* MapAbsentEntry, Value)}, which might be customized over the default.
*
* @param value the value to insert into the map along with {@link #absentKey() the key}
* @throws IllegalStateException if some locking/state conditions required to perform insertion
* operation are not met
* @see MapEntryOperations#insert(MapAbsentEntry, Value)
*/
void doInsert(Value<V, ?> value);
/**
* Returns the "nil" value, which should be inserted into the map in this context. This
* is primarily used in {@link ChronicleMap#acquireUsing} operation implementation, i. e. {@link
* MapMethods#acquireUsing}.
* Returns the <i>default</i> (or <i>nil</i>) value, that should be inserted into the map in
* this context. This is primarily used in {@link ChronicleMap#acquireUsing} operation
* implementation, i. e. {@link MapMethods#acquireUsing}.
*
* <p>This method if the default implementation for {@link
* MapEntryOperations#defaultValue}, which might be customized over the default.
*
* @return the default value to be inserted into the map
* @see MapEntryOperations#defaultValue(MapAbsentEntry)
*/
@NotNull Value<V, ?> defaultValue();
}
@@ -24,12 +24,13 @@ import net.openhft.chronicle.hash.Value;
/**
* Context, in which {@link MapEntry MapEntries} are accessed.
*
* @param <K> the key type of accessed {@link ChronicleMap}
* @param <V> the value type of accessed {@code ChronicleMap}
* @param <K> the map key type
* @param <V> the map value type
* @param <R> the return type of {@link MapEntryOperations} specialized for the queried map
*/
public interface MapContext<K, V, R> extends HashContext<K>, MapEntryOperations<K, V, R> {
/**
* Returns the accessed {@code ChronicleMap}.
* Returns the accessed {@code ChronicleMap}. Synonym to {@link #map()}.
*/
@Override
default ChronicleMap<K, V> hash() {
@@ -37,9 +38,19 @@ public interface MapContext<K, V, R> extends HashContext<K>, MapEntryOperations<
}
/**
* Synonym to {@link #hash()}.
* Returns the accessed {@code ChronicleMap}. Synonym to {@link #hash()}.
*/
ChronicleMap<K, V> map();
/**
* Wraps the given value as a {@code Value}. Useful when you need to pass a value
* to some method accepting {@code Value}, for example, {@link MapEntryOperations#replaceValue(
* MapEntry, Value)}, without allocating new objects (i. e. garbage) and {@code ThreadLocals}.
*
* <p>The returned {@code Value} object shouldn't outlive this {@code MapContext}.
*
* @param value the value object to wrap
* @return the value as {@code Value}
*/
Value<V, ?> wrapValueAsValue(V value);
}
@@ -1,5 +1,3 @@
/*
* Copyright 2015 Higher Frequency Trading
*
@@ -25,12 +23,12 @@ import net.openhft.chronicle.hash.Value;
import org.jetbrains.annotations.NotNull;
/**
* Access to the <i>present</i> {@link ChronicleMap} entry.
* The <i>present</i> {@code ChronicleHash} entry context.
*
* @param <K> type of the key in {@code ChronicleMap}
* @param <V> type of the value in {@code ChronicleMap}
*
* @param <K> the map key type
* @param <V> the map value type
* @see MapEntryOperations
* @see MapQueryContext#entry()
*/
public interface MapEntry<K, V> extends HashEntry<K> {
@Override
@@ -42,10 +40,24 @@ public interface MapEntry<K, V> extends HashEntry<K> {
@NotNull Value<V, ?> value();
/**
* Replaces the entry's value with the new one.
* Replaces the entry's value with the given {@code newValue}.
*
* <p>This method is the default implementation for {@link MapEntryOperations#replaceValue(
* MapEntry, Value)}, which might be customized over the default.
*
* @param newValue the value to be put into the map instead of the {@linkplain #value() current
* value}
* @throws IllegalStateException if some locking/state conditions required to perform replace
* operation are not met
*/
void doReplaceValue(Value<V, ?> newValue);
/**
* Removes the entry from the map.
*
* <p>This method is the default implementation for {@link MapEntryOperations#remove(MapEntry)},
* which might be customized over the default.
*/
@Override
void doRemove();
}
@@ -22,16 +22,20 @@ import net.openhft.chronicle.hash.Value;
import org.jetbrains.annotations.NotNull;
/**
* SPI interface for customizing "low-level" modification operations on {@link ChronicleMap} entry.
* SPI interface for customizing "low-level" modification operations on {@link ChronicleMap}
* entries.
*
* @param <K> type of the key in {@code ChronicleMap}
* @param <V> type of the value in {@code ChronicleMap}
* @param <K> the map key type
* @param <V> the map value type
* @see ChronicleMapBuilder#entryOperations(MapEntryOperations)
*/
public interface MapEntryOperations<K, V, R> {
/**
* Removes the given entry from the {@code ChronicleHash}. Returns {@code true} if the remove
* was successful, {@code false} if it was discarded for any reason.
* Removes the given entry from the map.
*
* @implNote default implementation calls {@link MapEntry#doRemove()} on the given entry
* and returns {@code null}.
*
* @param entry the entry to remove
* @throws IllegalStateException if some locking/state conditions required to perform remove
@@ -18,6 +18,11 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.KeyContext;
/**
* @param <K> the map key type
* @param <V> the map value type
* @deprecated incoherent abstraction. Replaced by {@link MapQueryContext} and {@link MapEntry}
*/
@Deprecated
public interface MapKeyContext<K, V> extends KeyContext<K> {
@@ -19,14 +19,18 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.HashQueryContext;
import net.openhft.chronicle.map.replication.MapRemoteOperations;
import org.jetbrains.annotations.Nullable;
/**
* The context of Map operations with <i>individual keys</i> (most: get(), put(), etc., opposed
* to bulk operations).
*
* @param <K>
* @param <V>
* The context of {@link ChronicleMap} operations with <i>individual keys</i>
* (most: {@code get()}, {@code put()}, etc., opposed to <i>bulk</i> operations). This is the main
* context type of {@link MapMethods} and {@link MapRemoteOperations}.
*
* @param <K> the map key type
* @param <V> the map value type
* @param <R> the return type of {@link MapEntryOperations} specialized for the queried map
* @see ChronicleMap#queryContext(Object)
*/
public interface MapQueryContext<K, V, R> extends HashQueryContext<K>, MapContext<K, V, R> {
@@ -20,9 +20,19 @@ package net.openhft.chronicle.map.replication;
import net.openhft.chronicle.hash.replication.HashRemoteQueryContext;
import net.openhft.chronicle.hash.replication.RemoteOperationContext;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.MapEntryOperations;
import net.openhft.chronicle.map.MapQueryContext;
import org.jetbrains.annotations.Nullable;
/**
* Context of remote {@link ChronicleMap} queries and internal replication operations.
*
* @param <K> the map key type
* @param <V> the map value type
* @param <R> the return type of {@link MapEntryOperations} specialized for the queried map
* @see MapRemoteOperations
*/
public interface MapRemoteQueryContext<K, V, R> extends MapQueryContext<K, V, R>,
HashRemoteQueryContext<K> {
@Nullable
@@ -2,6 +2,15 @@ package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.ExternalHashQueryContext;
/**
* {@link SetQueryContext} + {@link AutoCloseable}, for external {@link ChronicleSet} queries
* in <i>try-with-resources</i> blocks.
*
* @param <K> the set key type
* @param <R> the return type of {@link SetEntryOperations}, specified for the queried {@code
* ChronicleSet}
* @see ChronicleSet#queryContext(Object)
*/
public interface ExternalSetQueryContext<K, R>
extends SetQueryContext<K, R>, ExternalHashQueryContext<K> {
}
@@ -2,9 +2,28 @@ package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.HashAbsentEntry;
/**
* Low-level operational context for the situations, when the new key is going to be inserted
* into the {@link ChronicleSet}.
*
* @param <K> the set key type
*
* @see SetEntryOperations
* @see SetQueryContext#absentEntry()
*/
public interface SetAbsentEntry<K> extends HashAbsentEntry<K> {
@Override
SetContext<K, ?> context();
/**
* Inserts {@link #absentKey() the new key} into the set.
*
* <p>This method is the default implementation for {@link SetEntryOperations#insert(
* SetAbsentEntry)}, which might be customized over the default.
*
* @throws IllegalStateException if some locking/state conditions required to perform insertion
* operation are not met
* @see SetEntryOperations#insert(SetAbsentEntry)
*/
void doInsert();
}
@@ -1,14 +1,25 @@
package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.HashContext;
/**
* Context, in which {@link SetEntry SetEntries} are accessed.
*
* @param <K> the set key type
* @param <R> the return type of {@link SetEntryOperations} specialized for the queried set
*/
public interface SetContext<K, R> extends HashContext<K>, SetEntryOperations<K, R> {
/**
* Returns the accessed {@code ChronicleSet}. Synonym to {@link #set()}.
*/
@Override
default ChronicleHash<K, ?, ?> hash() {
default ChronicleSet<K> hash() {
return set();
}
/**
* Returns the accessed {@code ChronicleSet}. Synonym to {@link #hash()}.
*/
ChronicleSet<K> set();
}
@@ -2,7 +2,23 @@ package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.HashEntry;
/**
* The <i>present</i> {@link ChronicleSet} entry context.
*
* @param <K> the set key type
* @see SetEntryOperations
* @see SetQueryContext#entry()
*/
public interface SetEntry<K> extends HashEntry<K> {
@Override
SetContext<K, ?> context();
/**
* Removes the entry from the {@code ChronicleSet}.
*
* <p>This method is the default implementation for {@link SetEntryOperations#remove(SetEntry)},
* which might be customized over the default.
*/
@Override
void doRemove();
}
@@ -1,8 +1,21 @@
package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.HashQueryContext;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.MapEntryOperations;
import net.openhft.chronicle.map.MapMethods;
import net.openhft.chronicle.map.replication.MapRemoteOperations;
import net.openhft.chronicle.set.replication.SetRemoteOperations;
import org.jetbrains.annotations.Nullable;
/**
* The context of {@link ChronicleSet} operations with <i>individual keys</i>
* (most: {@code contains()}, {@code add()}, etc., opposed to <i>bulk</i> operations).
*
* @param <K> the set key type
* @param <R> the return type of {@link SetEntryOperations} specialized for the queried set
* @see ChronicleSet#queryContext(Object)
*/
public interface SetQueryContext<K, R> extends HashQueryContext<K>, SetContext<K, R> {
@Override
@@ -1,9 +1,18 @@
package net.openhft.chronicle.set.replication;
import net.openhft.chronicle.hash.replication.HashRemoteQueryContext;
import net.openhft.chronicle.set.ChronicleSet;
import net.openhft.chronicle.set.SetEntryOperations;
import net.openhft.chronicle.set.SetQueryContext;
import org.jetbrains.annotations.Nullable;
/**
* Context of remote {@link ChronicleSet} queries and internal replication operations.
*
* @param <K> the set key type
* @param <R> the return type of {@link SetEntryOperations} specialized for the queried set
* @see SetRemoteOperations
*/
public interface SetRemoteQueryContext<K, R>
extends SetQueryContext<K, R>, HashRemoteQueryContext<K> {
@Override