diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java index e25dfb498..dabcf472b 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java @@ -30,21 +30,16 @@ import java.util.Map; import java.util.concurrent.ConcurrentMap; /** - * Extension of {@link ConcurrentMap} interface, stores the data off-heap. - *
- *
For information on
- *
Functionally this interface defines some methods supporting garbage-free off-heap programming: - * {@link #getUsing(Object, Object)}, {@link #acquireUsing(Object, Object)}. - *
- *
Roughly speaking, {@code ChronicleMap} compares keys and values by their binary serialized + * Extension of {@link ConcurrentMap} interface, stores the data off-heap.
For information on + *
Functionally this interface defines some methods supporting garbage-free + * off-heap programming: {@link #getUsing(Object, Object)}, {@link #acquireUsing(Object, Object)}. + *
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. - *
- *
Note that {@code ChronicleMap} extends {@link Closeable}, don't forget to {@linkplain #close() - * close} map when it is no longer needed. + * Object#equals(Object)} method, which is prescribed by general {@link Map} contract.
Note
+ * that {@code ChronicleMap} extends {@link Closeable}, don't forget to {@linkplain #close() close}
+ * map when it is no longer needed.
*
* @param
- * 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.
+ * no mapping for the key. 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.
*
* @param key the key whose associated value is to be returned
* @return the value to which the specified key is mapped after this method call, or {@code
@@ -77,18 +70,15 @@ public interface ChronicleMap
- * 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,
- * value)} method, depending on what deserialization strategy is configured on the builder,
- * 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.
- *
- * 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.
+ * 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, value)} method, depending on what deserialization strategy is configured on
+ * the builder, 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. 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.
*
* @param key the key whose associated value is to be returned
* @param usingValue the object to read value data in, if possible
@@ -102,20 +92,17 @@ public interface ChronicleMap
+ * the map segment to operations to be performed atomically. ( see the example below )
* 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.
- *
- * 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)
- * read(Bytes, size, value)} method, depending on what deserialization strategy is configured on
- * the builder, using which this map was constructed. If the value deserializer is able to reuse
- * the given {@code usingValue} object, calling this method instead of {@link #get(Object)}
- * could help to reduce garbage creation.
+ * contains no mapping for the key. 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) read(Bytes, size, value)} method, depending on what
+ * deserialization strategy is configured on the builder, using which this map was constructed.
+ * If the value deserializer is able to reuse the given {@code usingValue} object, calling this
+ * method instead of {@link #get(Object)} could help to reduce garbage creation.
*
- *
- * The provided {@code value} object is allowed to be {@code null}, in this case
+ * must be read while the segment lock is in place. 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
- *
- * no mapping for the key
+ * @return the read context containing the value to which the specified key is mapped no
+ * mapping for the key
* @see #get(Object)
* @see #getUsing(Object, Object)
* @see ChronicleMapBuilder#valueMarshaller(BytesMarshaller)
@@ -145,32 +129,25 @@ public interface ChronicleMap
- * 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.
- *
- * Then, either if the key was initially absent in the map or already present, the value is
+ * Acquire a value for a key, creating if absent. 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. 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.
- *
- * In code, {@code acquireUsing} is specified as :
+ * value instance is created to deserialize the data. In code, {@code acquireUsing} is
+ * specified as :
*
- *
- * Where {@code defaultValue(key)} returns either {@linkplain ChronicleMapBuilder#defaultValue(Object)
- * default value} or {@link ChronicleMapBuilder#defaultValueProvider(DefaultValueProvider)
- * defaultValueProvider.}
- *
+ * Where {@code defaultValue(key)} returns either {@linkplain
+ * ChronicleMapBuilder#defaultValue(Object) default value} or {@link
+ * ChronicleMapBuilder#defaultValueProvider(DefaultValueProvider) defaultValueProvider.}
* 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
@@ -207,8 +184,8 @@ public interface ChronicleMap
- * {@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) }
- *
- * for example like this :
- *
+ * Creates an empty value instance, which can be used with the following methods : {@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) } for example like
+ * this :
*
- * {@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) }
- *
- * for example like this :
- *
+ * Creates an empty value instance, which can be used with the following methods : {@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) } for example like
+ * this :
*
* ChronicleMap
- * {@code ChronicleMapBuilder} is mutable, see a note in {@link ChronicleHashBuilder} interface
- * documentation.
- *
- * Later in this documentation, "ChronicleMap" means "ChronicleMaps, created by {@code
- * ChronicleMapBuilder}", unless specified different, because theoretically someone might provide
- * {@code ChronicleMap} implementations with completely different properties.
- *
- * {@code ChronicleMap} ("ChronicleMaps, created by {@code ChronicleMapBuilder}") currently
- * doesn't support resizing. That is why you must configure {@linkplain #entries(long) number
- * of entries} you are going to insert into the created map at most. See {@link
- * #entries(long)} method documentation for more information on this.
- *
- * If you key or value type is not constantly sized and known to {@code ChronicleHashBuilder}, i.
- * e. it is not a boxed primitive, data value generated interface, {@link Byteable}, etc. (see the
- * complete list TODO insert the link to the complete list), you must provide the {@code
- * ChronicleHashBuilder} with some information about you keys or values: if they are
- * constantly-sized, call {@link #constantKeySizeBySample(Object)}, otherwise {@link
- * ChronicleHashBuilder#averageKeySize(double)} method, accordingly for values.
+ * i. e. created {@code ChronicleMap} instances don't depend on the builder. {@code
+ * ChronicleMapBuilder} is mutable, see a note in {@link ChronicleHashBuilder} interface
+ * documentation. Later in this documentation, "ChronicleMap" means "ChronicleMaps, created
+ * by {@code ChronicleMapBuilder}", unless specified different, because theoretically someone might
+ * provide {@code ChronicleMap} implementations with completely different properties. {@code
+ * ChronicleMap} ("ChronicleMaps, created by {@code ChronicleMapBuilder}") currently doesn't support
+ * resizing. That is why you must configure {@linkplain #entries(long) number of entries} you
+ * are going to insert into the created map at most. See {@link #entries(long)} method
+ * documentation for more information on this. If you key or value type is not constantly
+ * sized and known to {@code ChronicleHashBuilder}, i. e. it is not a boxed primitive, data value
+ * generated interface, {@link Byteable}, etc. (see the complete list TODO insert the link to the
+ * complete list), you must provide the {@code ChronicleHashBuilder} with some information
+ * about you keys or values: if they are constantly-sized, call {@link
+ * #constantKeySizeBySample(Object)}, otherwise {@link ChronicleHashBuilder#averageKeySize(double)}
+ * method, accordingly for values.
*
* @param
- * Example: if keys in your map(s) are English words in {@link String} form, average English
+ * {@inheritDoc} Example: if keys in your map(s) are English words in {@link String}
+ * form, average English
* word length is 5.1, configure average key size of 6:
+ * {@inheritDoc}
* For example, if your keys are Git commit hashes:
- * {@code ChronicleHashBuilder} implementation heuristically chooses {@linkplain
- * #actualChunkSize(int) the actual chunk size} based on this configuration and the key size,
- * 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 value size
- * configuration, which is anyway needed.
- *
- * If values are of boxed primitive type or {@link Byteable} subclass, i. e. if value size is
- * known statically, it is automatically accounted and shouldn't be specified by user.
+ * #constantValueSizeBySample(Object)} method instead of this one. {@code
+ * ChronicleHashBuilder} implementation heuristically chooses {@linkplain #actualChunkSize(int)
+ * the actual chunk size} based on this configuration and the key size, 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 value size configuration, which
+ * is anyway needed. If values are of boxed primitive type or {@link Byteable} subclass,
+ * i. e. if value size is known statically, it is automatically accounted and shouldn't be
+ * specified by user.
*
* @param averageValueSize number of bytes, taken by serialized form of values
* @return this builder back
@@ -410,13 +410,11 @@ public class ChronicleMapBuilder
- * If values are of boxed primitive type or {@link Byteable} subclass, i. e. if value size is
- * known statically, it is automatically accounted and this method shouldn't be called.
- *
- * If value size varies, method {@link #averageValueSize(double)} should be called instead of
- * this one.
+ * take the same number of bytes in serialized form, as this sample object. If values are
+ * of boxed primitive type or {@link Byteable} subclass, i. e. if value size is known
+ * statically, it is automatically accounted and this method shouldn't be called. If
+ * value size varies, method {@link #averageValueSize(double)} should be called instead of this
+ * one.
*
* @param sampleValue the sample value
* @return this builder back
@@ -600,18 +598,14 @@ public class ChronicleMapBuilder
- * Useful when values of the map are updated intensively, particularly fields with volatile
- * access, because it doesn't work well if the value crosses cache lines. Also, on some
- * (nowadays rare) architectures any misaligned memory access is more expensive than aligned.
- *
- * If values couldn't reference off-heap memory (i. e. it is not {@link Byteable} or "data
- * value generated"), alignment configuration makes no sense and forbidden.
- *
- * Default is {@link Alignment#NO_ALIGNMENT} if values couldn't reference off-heap memory,
- * otherwise chosen heuristically (configure explicitly for being sure and to compare
- * performance in your case).
+ * memory of values within entries in ChronicleMaps, created by this builder. Useful when
+ * values of the map are updated intensively, particularly fields with volatile access, because
+ * it doesn't work well if the value crosses cache lines. Also, on some (nowadays rare)
+ * architectures any misaligned memory access is more expensive than aligned. If values
+ * couldn't reference off-heap memory (i. e. it is not {@link Byteable} or "data value
+ * generated"), alignment configuration makes no sense and forbidden. Default is {@link
+ * Alignment#NO_ALIGNMENT} if values couldn't reference off-heap memory, otherwise chosen
+ * heuristically (configure explicitly for being sure and to compare performance in your case).
*
* @param alignment the new alignment of the maps constructed by this builder
* @return this {@code ChronicleMapOnHeapUpdatableBuilder} back
diff --git a/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java
index c48b4d5ae..69b554c21 100755
--- a/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java
+++ b/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java
@@ -174,6 +174,11 @@ class ReplicatedChronicleMap{@code
* try (ReadContext rc = map.getUsingLocked(key, bond)) {
* if (rc.present ()) { // check whether the key was present
@@ -127,16 +114,13 @@ public interface ChronicleMap
* 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.
- * {@code
* V acquireUsing(K key, V usingValue) {
* if (!containsKey(key))
* put(key, defaultValue(key));
* return getUsing(key, usingValue);
* }}
- * {@code
* V value = map.newValueInstance();
* try (ReadContext rc = map.getUsingLocked(key, value)) {
@@ -271,16 +244,12 @@ public interface ChronicleMap{@code
* K key = map.newKeyInstance();
* key.setMyStringField("some key");
@@ -311,5 +280,10 @@ public interface ChronicleMap
- * i. e. created {@code ChronicleMap} instances don't depend on the builder.
- * {@code
* ChronicleMap{@code
* Map