keyClass();
/**
- * Returns the context to perform arbitrary operations with the given key in this map.
- * Conventionally, try-with-resources block should wrap the returned context: {@code
+ * Returns a context to perform arbitrary operations with the given key in this store.
+ * Conventionally, should be used in a try-with-resources block: {@code
* try (ExternalHashQueryContext q = hash.queryContext(key)) {
* // ... do something
* }}
- * See {@link HashQueryContext} and {@link MapMethods} for a lot of inspiration about using this
- * functionality.
+ *
+ * See documentation to {@link HashQueryContext} interface and methods in {@link MapMethods}
+ * interface for examples of using contexts. Also see
+ * Working with an entry within a context section in the Chronicle Map tutorial.
*
* @param key the queried key
* @return the context to perform operations with the key
@@ -72,9 +79,16 @@ public interface ChronicleHash, SC extends HashSegment
EQC queryContext(K key);
/**
- * Equivalent to {@link #queryContext(Object)}, but accepts {@code Data} instead of key as
- * an object. Useful, when you already have {@code Data}, calling this method instead of {@link
- * #queryContext(Object)} might help to avoid unnecessary deserialization.
+ * Returns a context to perform arbitrary operations with the given key, provided in
+ * {@link Data} form. Equivalent to {@link #queryContext(Object)}, but accepts {@code Data}
+ * instead of object key. This method is useful, when you already have {@code Data}, calling
+ * this method instead of {@link #queryContext(Object)} might help to avoid unnecessary
+ * deserialization.
+ *
+ * See documentation to {@link HashQueryContext} interface and methods in {@link MapMethods}
+ * interface for examples of using contexts. Also see
+ * Working with an entry within a context section in the Chronicle Map tutorial.
*
* @param key the queried key as {@code Data}
* @return the context to perform operations with the key
@@ -82,19 +96,19 @@ public interface ChronicleHash, SC extends HashSegment
@NotNull EQC queryContext(Data key);
/**
- * Returns the context to perform arbitrary operations with the given key, provided in the
+ * Returns a context to perform arbitrary operations with the given key, provided in the
* serialized form. See {@link #queryContext(Object)} and {@link #queryContext(Data)} for more
* information on contexts semantics and usage patterns.
*
* @param keyBytes the bytes store with the key bytes to query
* @param offset actual offset of the key bytes within the given BytesStore
- * @param size length of the key bytes sequence
+ * @param size length of the key bytes sequence within the given BytesStore
* @return the context to perform operations with the key
*/
@NotNull EQC queryContext(BytesStore keyBytes, long offset, long size);
/**
- * Returns the context of the segment with the given index. Segments are indexed from 0 to
+ * Returns a context of the segment with the given index. Segments are indexed from 0 to
* {@link #segments()}{@code - 1}.
*
* @see HashSegmentContext
@@ -150,10 +164,6 @@ public interface ChronicleHash, SC extends HashSegment
* collection. This could be a problem if, for example, you target rare garbage collections,
* but load and drop {@code ChronicleHash}es regularly.
*
- *
- * TODO what about commit guarantees, when ChronicleMap is used with memory-mapped files, if
- * {@code ChronicleMap}/{@code ChronicleSet} closed/not?
- *
*
After this method call behaviour of all methods of {@code ChronicleMap}
* or {@code ChronicleSet} is undefined. Any method call on the map might throw
* any exception, or even JVM crash. Shortly speaking, don't call use map closing.
diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java
index 513518542..62d67f4c1 100755
--- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java
+++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java
@@ -33,8 +33,8 @@ import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
/**
- * This interface defines the meaning of configurations, common to {@link ChronicleMapBuilder} and
- * {@link ChronicleSetBuilder}, i. e. Chronicle hash container configurations.
+ * Base interface for {@link ChronicleMapBuilder} and {@link ChronicleSetBuilder}, i. e. defines
+ * Chronicle hash container configurations.
*
*
{@code ChronicleHashBuilder} is mutable. Configuration methods mutate the builder and return
* the builder itself back to support chaining pattern, rather than the builder copies with
diff --git a/src/main/java/net/openhft/chronicle/hash/Data.java b/src/main/java/net/openhft/chronicle/hash/Data.java
index bc7c5de2b..4df7349e4 100644
--- a/src/main/java/net/openhft/chronicle/hash/Data.java
+++ b/src/main/java/net/openhft/chronicle/hash/Data.java
@@ -17,45 +17,63 @@
package net.openhft.chronicle.hash;
import net.openhft.chronicle.algo.hashing.LongHashFunction;
+import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.bytes.BytesUtil;
import net.openhft.chronicle.bytes.RandomDataInput;
import net.openhft.chronicle.bytes.RandomDataOutput;
+import net.openhft.chronicle.map.ChronicleMap;
+import net.openhft.chronicle.map.MapEntry;
+import net.openhft.chronicle.map.MapQueryContext;
+import net.openhft.chronicle.set.ChronicleSet;
import org.jetbrains.annotations.Nullable;
import static net.openhft.chronicle.algo.bytes.Access.checkedRandomDataInputAccess;
/**
- * Dual bytes/object access to keys/values/elements.
+ * Dual bytes/object access to keys or values (for {@link ChronicleMap}) and elements (for {@link
+ * ChronicleSet}) throughout the Chronicle Map library.
*
*
Bytes access: {@link #bytes()} + {@link #offset()} + {@link #size()}.
*
*
Object access: {@link #get()}.
*
- *
In most cases, each particular value wraps either some object or some bytes. Object
+ *
In most cases, each particular {@code Data} wraps either some object or some bytes. Object
* is marshalled to bytes lazily on demand, and bytes are lazily deserialized to object,
- * accordingly.
+ * accordingly.
*
* @param type of the accessed objects
*/
public interface Data {
/**
- * Returns the accessor object to the {@code Data}'s bytes. For safety, this interface returns
- * read-only object, because this object could expose bytes source that must be immutable, e. g.
- * an array behind {@code String} object.
+ * Returns the accessor object to the {@code Data}'s bytes.
+ *
+ * If this {@code Data} wraps some bytes, this method just returns a reference to that bytes.
+ *
+ *
If this {@code Data} wraps an object, this method performs serialization internally and
+ * returns a reference to the output buffer, caching the result for subsequent calls of this
+ * method.
+ *
+ *
For safety, this interface returns read-only object, because it could expose bytes source
+ * that must be immutable, e. g. a `char[]` array behind a {@code String}. But in cases when the
+ * {@code Data} instance wraps off-heap bytes, e. g. {@link MapEntry#value()}, it is allowed to
+ * cast the object, returned from this method, to {@link BytesStore}, and write into the
+ * off-heap memory. You should only ensure that current context (e. g. {@link MapQueryContext})
+ * is locked exclusively, in order to avoid data races.
*/
RandomDataInput bytes();
/**
- * Returns the offset to the {@code Data}'s bytes sequence, within the {@link #bytes()} object.
- * For example, the first byte of the bytes representation of this {@code Data} instance is
- * {@code data.bytes().readByte(data.offset())}.
+ * Returns the offset to the {@code Data}'s bytes sequence within the {@link RandomDataInput},
+ * returned from {@link #bytes()} method. For example, the first byte of the bytes
+ * representation of some {@code data} is {@code data.bytes().readByte(data.offset())}.
*/
long offset();
/**
* Returns the size of this {@code Data}'s bytes sequence. It spans from {@link #offset()} to
- * {@code offset() + size() - 1} bytes within the {@link #bytes()} object.
+ * {@code offset() + size() - 1} bytes within the {@link RandomDataInput}, returned from
+ * {@link #bytes()} method.
*/
long size();
@@ -76,7 +94,7 @@ public interface Data {
*
* Default implementation compares {@link #bytes()} of this {@code Data}, but custom
* implementation may only check if {@linkplain #get() object} of this {@code Data} would
- * be serialized to the same bytes sequence, if this {@code Data} is object-based and obtaining
+ * be serialized to the same bytes sequence, if this {@code Data} wraps an object and obtaining
* {@link #bytes()} requires serialization internally.
*
* @param source the bytes source, to compare this {@code Data}'s bytes with
@@ -106,16 +124,25 @@ public interface Data {
}
/**
- * Returns "cached" object, generally not eligible for using outside some context, or a block,
- * synchronized with locks, or lambda, etc.
- *
- * If the {@code Data} is object wrapper -- this method just returns this object.
+ * Returns object view of this {@code Data}.
+ *
+ *
If this {@code Data} wraps some object, this method just returns that object.
+ *
+ *
If this {@code Data} wraps some bytes, this method performs deserialization internally
+ * and returns the resulting on-heap object, caching it for subsequent calls of this method. The
+ * returned object could be reused, therefore it is generally disallowed to use the
+ * object, returned from this method, outside some context, or a block, synchronized with
+ * locks, or lambda, etc., which provided the access to this {@code Data} instance.
*/
T get();
/**
- * Reads the object from the value's bytes, trying to reuse the given object (might be {@code
- * null}).
+ * Deserialize and return an object from the {@code Data}'s bytes, trying to reuse the given
+ * {@code using} object (might be {@code null}). This method either returns the given {@code
+ * using} object back (if reuse is possible) or creates a new object, rather than some
+ * internally cached and reused one, therefore it is always allowed to use the object,
+ * returned from this method, outside some context, or a block, synchronized with locks,
+ * or lambda, etc., which provided the access to this {@code Data} instance.
*/
T getUsing(@Nullable T using);
diff --git a/src/main/java/net/openhft/chronicle/hash/locks/package-info.java b/src/main/java/net/openhft/chronicle/hash/locks/package-info.java
new file mode 100644
index 000000000..be59753b7
--- /dev/null
+++ b/src/main/java/net/openhft/chronicle/hash/locks/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * Contains abstractions of inter-process locks, used in Chronicle Map.
+ */
+package net.openhft.chronicle.hash.locks;
\ No newline at end of file
diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/ListMarshaller.java b/src/main/java/net/openhft/chronicle/hash/serialization/ListMarshaller.java
index 79bb08584..54fc5987e 100644
--- a/src/main/java/net/openhft/chronicle/hash/serialization/ListMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/hash/serialization/ListMarshaller.java
@@ -36,14 +36,12 @@ import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNe
* README section.
*
*
Usage:
{@code
- * ListMarshaller valueMarshaller = new ListMarshaller<>(
- * IntegerMarshaller.INSTANCE, IntegerMarshaller.INSTANCE);
* ChronicleMap> regNumbers = ChronicleMap
* .of(String.class, (Class>) (Class) List.class)
- * .entries(10_000)
* .averageKey("John Smith")
- * .valueMarshaller(valueMarshaller)
+ * .valueMarshaller(ListMarshaller.of(IntegerMarshaller.INSTANCE))
* .averageValue(ImmutableList.of(1, 2, 3))
+ * .entries(10_000)
* .create();
* }
*
diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/SetMarshaller.java b/src/main/java/net/openhft/chronicle/hash/serialization/SetMarshaller.java
index 7b3d0a4e3..4094763a0 100644
--- a/src/main/java/net/openhft/chronicle/hash/serialization/SetMarshaller.java
+++ b/src/main/java/net/openhft/chronicle/hash/serialization/SetMarshaller.java
@@ -38,14 +38,14 @@ import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNe
* README section.
*
* Usage:
{@code
- * SetMarshaller valueMarshaller = new SetMarshaller<>(
+ * SetMarshaller valueMarshaller = SetMarshaller.of(
* new StringBytesReader(), CharSequenceBytesWriter.INSTANCE);
* ChronicleMap> map = ChronicleMap
* .of(String.class, (Class>) (Class) Set.class)
- * .entries(10_000)
* .averageKey("fruits")
* .valueMarshaller(valueMarshaller)
* .averageValue(ImmutableSet.of("apples", "bananas", "grapes"))
+ * .entries(10_000)
* .create();
* }
*
diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/package-info.java b/src/main/java/net/openhft/chronicle/hash/serialization/package-info.java
index 30531c96b..0db3acd01 100644
--- a/src/main/java/net/openhft/chronicle/hash/serialization/package-info.java
+++ b/src/main/java/net/openhft/chronicle/hash/serialization/package-info.java
@@ -15,7 +15,7 @@
*/
/**
- * The package contains interfaces for serializing objects between Java heap and {@link
+ * Contains interfaces for serializing objects between Java heap and {@link
* net.openhft.chronicle.bytes.Bytes} or {@link net.openhft.chronicle.bytes.BytesStore}, used by
* Chronicle Map to store objects off-heap, and read them back from off-heap memory to on-heap
* objects.
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
index cf8084bb8..529da29a5 100755
--- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
+++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java
@@ -28,7 +28,8 @@ import java.util.Map;
import java.util.concurrent.ConcurrentMap;
/**
- * Extension of {@link ConcurrentMap} interface, stores the data off-heap.
+ * {@code ChronicleMap} provides concurrent access to a Chronicle Map key-value store from a
+ * JVM process.
*
* For information on
- how to construct a {@code ChronicleMap}
- {@code
* ChronicleMap} flavors and properties
- available configurations
see {@link
diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
index 4796fbf9b..f44b62d3e 100755
--- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
+++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java
@@ -1777,7 +1777,7 @@ public final class ChronicleMapBuilder implements
/**
* Inject your SPI code around basic {@code ChronicleMap}'s operations with entries:
- * removing entries, replacing the entries' value and inserting the new entry.
+ * removing entries, replacing entries' value and inserting new entries.
*
* This affects behaviour of ordinary map.put(), map.remove(), etc. calls, as well as removes
* and replacing values during iterations, remote map calls and
diff --git a/src/main/java/net/openhft/chronicle/map/MapEntryOperations.java b/src/main/java/net/openhft/chronicle/map/MapEntryOperations.java
index 0f4403272..9970066e0 100644
--- a/src/main/java/net/openhft/chronicle/map/MapEntryOperations.java
+++ b/src/main/java/net/openhft/chronicle/map/MapEntryOperations.java
@@ -108,7 +108,9 @@ public interface MapEntryOperations {
* @implNote default implementation calls {@link MapEntry#doRemove()} on the given entry
* and returns {@code null}.
*
- * @param entry the entry to remove
+ * @param entry the entry to remove
+ * @return result of operation, understandable by higher-level SPIs, e. g. custom
+ * {@link MapMethods} implementation
* @throws IllegalStateException if some locking/state conditions required to perform remove
* operation are not met
* @throws RuntimeException if removal was unconditionally unsuccessful due to any reason
@@ -125,6 +127,8 @@ public interface MapEntryOperations {
* entry.doReplaceValue(newValue)} and returns {@code null}.
*
* @param entry the entry to replace the value in
+ * @return result of operation, understandable by higher-level SPIs, e. g. custom
+ * {@link MapMethods} implementation
* @throws IllegalStateException if some locking/state conditions required to perform replace
* operation are not met
* @throws RuntimeException if value replacement was unconditionally unsuccessful due
@@ -142,6 +146,8 @@ public interface MapEntryOperations {
* @implNote default implementation calls {@link MapAbsentEntry#doInsert(Data)
* absentEntry.doInsert(value)} and returns {@code null}.
*
+ * @return result of operation, understandable by higher-level SPIs, e. g. custom
+ * {@link MapMethods} implementation
* @throws IllegalStateException if some locking/state conditions required to perform insertion
* operation are not met
* @throws RuntimeException if insertion was unconditionally unsuccessful due to any reason
diff --git a/src/main/java/net/openhft/chronicle/map/MapMethods.java b/src/main/java/net/openhft/chronicle/map/MapMethods.java
index 8c954bf7b..968f0392f 100644
--- a/src/main/java/net/openhft/chronicle/map/MapMethods.java
+++ b/src/main/java/net/openhft/chronicle/map/MapMethods.java
@@ -32,6 +32,13 @@ import static net.openhft.chronicle.map.MapMethodsSupport.tryReturnCurrentValueI
*/
public interface MapMethods {
+ /**
+ * Backing {@link ChronicleMap#containsKey(Object)} method.
+ *
+ * @implNote the default implementation is equivalent to {@code
+ * return q.entry() != null;
+ * }
+ */
default boolean containsKey(MapQueryContext q) {
return q.entry() != null;
}
diff --git a/src/main/java/net/openhft/chronicle/map/ReturnValue.java b/src/main/java/net/openhft/chronicle/map/ReturnValue.java
index 807c0a7b2..6b25960e9 100644
--- a/src/main/java/net/openhft/chronicle/map/ReturnValue.java
+++ b/src/main/java/net/openhft/chronicle/map/ReturnValue.java
@@ -19,6 +19,27 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.Data;
import org.jetbrains.annotations.NotNull;
+/**
+ * Abstracts returning a value from a query to a {@link ChronicleMap}, used in {@link MapMethods}.
+ * This interface is not supposed to be implemented in user code.
+ *
+ * @param the type of values in the {@code ChronicleMap}
+ */
public interface ReturnValue {
+ /**
+ * Calling this method on a {@code ReturnValue} object, provided as an argument in a method from
+ * {@link MapMethods}, designates that the {@code ChronicleMap}'s method (backed by this
+ * {@code MapMethods}'s method) should return the given {@code value}.
+ *
+ * It is not allowed to call {@code returnValue()} twice during a single {@code MapMethods}'s
+ * method call.
+ *
+ *
Not calling {@code returnValue()} during {@code MapMethods}'s method call will make the
+ * backed {@code ChronicleMap}'s method to return {@code null}.
+ *
+ * @param value a {@code Data} object wrapping a value, which should be returned from a
+ * {@code ChronicleMap}'s method, backed by the {@code MapMethods}'s method, to
+ * which this {@code ReturnValue} instance was passed as an argument
+ */
void returnValue(@NotNull Data value);
}
diff --git a/src/main/java/net/openhft/chronicle/map/package-info.java b/src/main/java/net/openhft/chronicle/map/package-info.java
new file mode 100644
index 000000000..e83c5da63
--- /dev/null
+++ b/src/main/java/net/openhft/chronicle/map/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * Contains {@link net.openhft.chronicle.map.ChronicleMap} interface, {@code ChronicleMap} context
+ * interfaces, {@link net.openhft.chronicle.map.ChronicleMapBuilder} class and related stuff.
+ */
+package net.openhft.chronicle.map;
\ No newline at end of file
diff --git a/src/main/java/net/openhft/chronicle/set/ChronicleSet.java b/src/main/java/net/openhft/chronicle/set/ChronicleSet.java
index 974afe6cf..ebdf3cf61 100644
--- a/src/main/java/net/openhft/chronicle/set/ChronicleSet.java
+++ b/src/main/java/net/openhft/chronicle/set/ChronicleSet.java
@@ -20,10 +20,24 @@ import net.openhft.chronicle.hash.ChronicleHash;
import java.util.Set;
+/**
+ * {@code ChronicleSet} provides concurrent access to a Chronicle Map key-value store with
+ * zero-sized values from a JVM process, wrapped as an extension of {@link Set} interface.
+ *
+ * @param the set key type
+ * @see net.openhft.chronicle.map.ChronicleMap
+ */
public interface ChronicleSet
extends Set, ChronicleHash, SetSegmentContext,
ExternalSetQueryContext> {
+ /**
+ * Delegates to {@link ChronicleSetBuilder#of(Class)} for convenience.
+ *
+ * @param keyClass class of the key type of the {@code ChronicleSet} to create
+ * @param the key type of the {@code ChronicleSet} to create
+ * @return a new {@code ChronicleSetBuilder} for the given key class
+ */
static ChronicleSetBuilder of(Class keyClass) {
return ChronicleSetBuilder.of(keyClass);
}
diff --git a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java
index dca82d590..c49904ca5 100755
--- a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java
+++ b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java
@@ -55,6 +55,15 @@ public final class ChronicleSetBuilder
chronicleMapBuilder.privateAPI());
}
+ /**
+ * Returns a new {@code ChronicleSetBuilder} instance which is able to {@linkplain #create()
+ * create} sets with the specified key class.
+ *
+ * @param keyClass class object used to infer key type and discover it's properties via
+ * reflection
+ * @param key type of the sets, created by the returned builder
+ * @return a new builder for the given key class
+ */
public static ChronicleSetBuilder of(Class keyClass) {
return new ChronicleSetBuilder<>(keyClass);
}
@@ -250,6 +259,14 @@ public final class ChronicleSetBuilder
return this;
}
+ /**
+ * Inject your SPI code around basic {@code ChronicleSet}'s operations with entries:
+ * removing entries and inserting new entries.
+ *
+ * This affects behaviour of ordinary set.add(), set.remove(), calls, as well as removes
+ * during iterations, updates during remote calls and
+ * internal replication operations.
+ */
public ChronicleSetBuilder entryOperations(SetEntryOperations entryOperations) {
chronicleMapBuilder.entryOperations(new MapEntryOperations() {
@Override
diff --git a/src/main/java/net/openhft/chronicle/set/SetEntryOperations.java b/src/main/java/net/openhft/chronicle/set/SetEntryOperations.java
index 05dc6013f..468605e13 100644
--- a/src/main/java/net/openhft/chronicle/set/SetEntryOperations.java
+++ b/src/main/java/net/openhft/chronicle/set/SetEntryOperations.java
@@ -18,15 +18,47 @@ package net.openhft.chronicle.set;
import org.jetbrains.annotations.NotNull;
+/**
+ * SPI interface fro customizing "low-level" modification operations on {@link ChronicleSet}
+ * entries.
+ *
+ * @param the set key type
+ * @param methods return type, used for communication between lower- and higher-level SPI
+ * @see ChronicleSetBuilder#entryOperations(SetEntryOperations)
+ */
public interface SetEntryOperations {
-
+
+ /**
+ * Removes the given entry from the set.
+ *
+ * @implNote default implementation calls {@link SetEntry#doRemove()} on the given entry and
+ * returns {@code null}.
+ *
+ * @param entry the entry to remove
+ * @return result of operation, understandable by higher-level SPIs
+ * @throws IllegalStateException if some locking/state conditions required to perform remove
+ * operation are not met
+ * @throws RuntimeException if removal was unconditionally unsuccessful due to any reason
+ */
default R remove(@NotNull SetEntry entry) {
entry.doRemove();
return null;
}
-
- default R insert(@NotNull SetAbsentEntry entry) {
- entry.doInsert();
+
+ /**
+ * Inserts the new entry into the set, of {@link SetAbsentEntry#absentKey() the key} from
+ * the given insertion context (absentEntry).
+ *
+ * @implNote default implementation calls {@link SetAbsentEntry#doInsert()} and returns
+ * {@code null}.
+ *
+ * @return result of operation, understandable by higher-level SPIs
+ * @throws IllegalStateException if some locking/state conditions required to perform insertion
+ * operation are not met
+ * @throws RuntimeException if insertion was unconditionally unsuccessful due to any reason
+ */
+ default R insert(@NotNull SetAbsentEntry absentEntry) {
+ absentEntry.doInsert();
return null;
}
}
diff --git a/src/main/java/net/openhft/chronicle/set/package-info.java b/src/main/java/net/openhft/chronicle/set/package-info.java
index 15f493723..48eebcad8 100644
--- a/src/main/java/net/openhft/chronicle/set/package-info.java
+++ b/src/main/java/net/openhft/chronicle/set/package-info.java
@@ -15,7 +15,7 @@
*/
/**
- * Contains {@link net.openhft.chronicle.set.ChronicleSet} interface and
- * {@link net.openhft.chronicle.set.ChronicleSetBuilder} class.
+ * Contains {@link net.openhft.chronicle.set.ChronicleSet} interface, {@code ChronicleSet} context
+ * interfaces and {@link net.openhft.chronicle.set.ChronicleSetBuilder} class.
*/
package net.openhft.chronicle.set;
\ No newline at end of file
diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/ChecksumEntryTest.java b/src/test/java/net/openhft/chronicle/map/fromdocs/ChecksumEntryTest.java
new file mode 100644
index 000000000..7d5bc3a8c
--- /dev/null
+++ b/src/test/java/net/openhft/chronicle/map/fromdocs/ChecksumEntryTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package net.openhft.chronicle.map.fromdocs;
+
+import net.openhft.chronicle.core.values.LongValue;
+import net.openhft.chronicle.hash.ChecksumEntry;
+import net.openhft.chronicle.map.ChronicleMap;
+import net.openhft.chronicle.map.ExternalMapQueryContext;
+import net.openhft.chronicle.map.MapEntry;
+import net.openhft.chronicle.set.Builder;
+import net.openhft.chronicle.values.Values;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ChecksumEntryTest {
+
+ @Test
+ public void testChecksumEntriesWithValueInterface() throws IOException {
+ File file = Builder.getPersistenceFile();
+
+ try (ChronicleMap map = ChronicleMap
+ .of(Integer.class, LongValue.class)
+ .entries(1)
+ // Entry checksums make sense only for persisted Chronicle Maps, and are ON by
+ // default for such maps
+ .createPersistedTo(file)) {
+
+ LongValue value = Values.newHeapInstance(LongValue.class);
+ value.setValue(42);
+ map.put(1, value);
+
+ try (ExternalMapQueryContext c = map.queryContext(1)) {
+ // Update lock required for calling ChecksumEntry.checkSum()
+ c.updateLock().lock();
+ MapEntry entry = c.entry();
+ Assert.assertNotNull(entry);
+ ChecksumEntry checksumEntry = (ChecksumEntry) entry;
+ Assert.assertTrue(checksumEntry.checkSum());
+
+ // to access off-heap bytes, should call value().getUsing() with Native value
+ // provided. Simple get() return Heap value by default
+ LongValue nativeValue =
+ entry.value().getUsing(Values.newNativeReference(LongValue.class));
+ // This value bytes update bypass Chronicle Map internals, so checksum is not
+ // updated automatically
+ nativeValue.setValue(43);
+ Assert.assertFalse(checksumEntry.checkSum());
+
+ // Restore correct checksum
+ checksumEntry.updateChecksum();
+ Assert.assertTrue(checksumEntry.checkSum());
+ }
+ }
+ }
+}
diff --git a/src/test/java/net/openhft/chronicle/set/SetEntryOperationsTest.java b/src/test/java/net/openhft/chronicle/set/SetEntryOperationsTest.java
index 9d979f6d9..f0cc6b3a2 100644
--- a/src/test/java/net/openhft/chronicle/set/SetEntryOperationsTest.java
+++ b/src/test/java/net/openhft/chronicle/set/SetEntryOperationsTest.java
@@ -41,9 +41,9 @@ public class SetEntryOperationsTest {
}
@Override
- public Void insert(@NotNull SetAbsentEntry entry) {
+ public Void insert(@NotNull SetAbsentEntry absentEntry) {
insertCounter.addAndGet(1);
- entry.doInsert();
+ absentEntry.doInsert();
return null;
}
})