mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Add ability to configure name for all ChronicleMaps and ChronicleSets via ChronicleHashBuilder.name(). Add ChronicleHash.toIdentityString()
This commit is contained in:
@@ -26,6 +26,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -45,6 +47,34 @@ public interface ChronicleHash<K, E extends HashEntry<K>, SC extends HashSegment
|
||||
*/
|
||||
File file();
|
||||
|
||||
/**
|
||||
* Returns the name of this {@code ChronicleHash}, configured by {@link
|
||||
* ChronicleHashBuilder#name(String)}, or {@code null}, if not configured.
|
||||
*
|
||||
* @return the name of this this {@link ChronicleMap} or {@link ChronicleSet}
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Returns a {@code String}, useful for identifying this {@code ChronicleHash} in debugging,
|
||||
* logging, and error reporting. {@link #toString()} of concrete {@code ChronicleHash}
|
||||
* subinterfaces, {@link ChronicleMap} and {@link ChronicleSet}, has to follow {@link
|
||||
* Map#toString()} and {@link Set#toString()} contracts respectively, making it not always
|
||||
* useful (or even impossible to use, if this {@code ChronicleHash} contains a lot of entries)
|
||||
* for the purposes listed above.
|
||||
*
|
||||
* <p>This method return a string of the form:<br><br>
|
||||
* [ChronicleMap|ChronicleSet]{name={@link #name()}, file={@link #file()},
|
||||
* identityHashCode={@link System#identityHashCode System.identityHashCode(thisChronicleHash)}}
|
||||
* <br><br>
|
||||
* This form could be changed in any subsequent Chronicle Map library release (including patch
|
||||
* release). The user code shouldn't depend on this form.
|
||||
*
|
||||
* @return a {@code String}, useful for identifying this {@code ChronicleHash} in debugging,
|
||||
* logging, and error reporting
|
||||
*/
|
||||
String toIdentityString();
|
||||
|
||||
/**
|
||||
* Returns the number of entries in this store.
|
||||
*
|
||||
|
||||
@@ -68,12 +68,32 @@ public interface ChronicleHashBuilder<K, H extends ChronicleHash<K, ?, ?, ?>,
|
||||
*/
|
||||
B clone();
|
||||
|
||||
/**
|
||||
* Specify the name which will be given to a ChronicleHash, created by this builder. It is
|
||||
* recommended to give some distinctive name to each created {@code ChronicleHash}, because this
|
||||
* name is used when logging errors and warnings inside Chronicle Map library itself, so having
|
||||
* the concrete {@code ChronicleHash} name in logs may help to debug.
|
||||
*
|
||||
* <p>{@code name()} is a JVM-level configuration, it is not stored in the persistence file (or
|
||||
* the other way to say this: they are not parts of <a
|
||||
* href="https://github.com/OpenHFT/Chronicle-Map/tree/master/spec">the Chronicle Map data store
|
||||
* specification</a>) and have to be configured explicitly for each created on-heap {@code
|
||||
* ChronicleHash} instance, even if it is a view of an existing Chronicle Map data store. On the
|
||||
* other hand, {@code name()} could be different for different views of the same Chronicle
|
||||
* Map data store.
|
||||
*
|
||||
* @param name the name for a ChronicleHash, created by this builder
|
||||
* @return this builder back
|
||||
* @see ChronicleHash#name()
|
||||
*/
|
||||
B name(String name);
|
||||
|
||||
/**
|
||||
* Set minimum number of segments in hash containers, constructed by this builder. See
|
||||
* concurrencyLevel in {@link ConcurrentHashMap}.
|
||||
*
|
||||
* @param minSegments the minimum number of segments in containers, constructed by this builder
|
||||
* @return this builder object back
|
||||
* @return this builder back
|
||||
*/
|
||||
B minSegments(int minSegments);
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public interface ChronicleHashBuilderPrivateAPI<K, RO> {
|
||||
|
||||
String name();
|
||||
|
||||
SerializationBuilder<K> keyBuilder();
|
||||
|
||||
int segmentEntrySpaceInnerOffset();
|
||||
|
||||
@@ -22,7 +22,6 @@ import net.openhft.chronicle.bytes.BytesStore;
|
||||
import net.openhft.chronicle.bytes.MappedBytesStoreFactory;
|
||||
import net.openhft.chronicle.bytes.NativeBytesStore;
|
||||
import net.openhft.chronicle.core.Maths;
|
||||
import net.openhft.chronicle.core.Memory;
|
||||
import net.openhft.chronicle.core.OS;
|
||||
import net.openhft.chronicle.hash.*;
|
||||
import net.openhft.chronicle.hash.impl.stage.hash.ChainingInterface;
|
||||
@@ -73,7 +72,6 @@ public abstract class VanillaChronicleHash<K,
|
||||
// --- Start of instance fields ---
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Version
|
||||
private String dataFileVersion;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
@@ -88,7 +86,6 @@ public abstract class VanillaChronicleHash<K,
|
||||
public DataAccess<K> keyDataAccess;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Checksum entries
|
||||
public boolean checksumEntries;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
@@ -90,7 +90,7 @@ public class TierRecovery {
|
||||
// the slot cleared at (*) should be clear, if it is dirty, only
|
||||
// a concurrent modification thread could occupy it
|
||||
throw new ChronicleHashRecoveryFailedException(
|
||||
"Concurrent modification of ChronicleMap at " + h.file() +
|
||||
"Concurrent modification of " + h.toIdentityString() +
|
||||
" while recovery procedure is in progress");
|
||||
}
|
||||
checkDuplicateKeys:
|
||||
@@ -124,8 +124,8 @@ public class TierRecovery {
|
||||
} while (insertPos != startInsertPos);
|
||||
throw new ChronicleHashRecoveryFailedException(
|
||||
"HashLookup overflow should never occur. " +
|
||||
"It might also be concurrent access to ChronicleMap at " +
|
||||
h.file() + " while recovery procedure is in progress");
|
||||
"It might also be concurrent access to " + h.toIdentityString() +
|
||||
" while recovery procedure is in progress");
|
||||
}
|
||||
hlPos = hl.step(hlPos);
|
||||
} while (hlPos != 0);
|
||||
|
||||
@@ -105,6 +105,23 @@ import static net.openhft.chronicle.map.VanillaChronicleMap.alignAddr;
|
||||
* #constantKeySizeBySample(Object)}, otherwise {@link #averageKey(Object)} or {@link
|
||||
* #averageKeySize(double)} method, and accordingly for values.
|
||||
*
|
||||
* <p><a name="jvm-configurations"></a>
|
||||
* There are some JVM-level configurations, which are not stored in the ChronicleMap's persistence
|
||||
* file (or the other way to say this: they are not parts of <a
|
||||
* href="https://github.com/OpenHFT/Chronicle-Map/tree/master/spec">the Chronicle Map data store
|
||||
* specification</a>) and have to be configured explicitly for each created on-heap {@code
|
||||
* ChronicleMap} instance, even if it is a view of an existing Chronicle Map data store. On the
|
||||
* other hand, JVM-level configurations could be different for different views of the same Chronicle
|
||||
* Map data store. The list of JVM-level configurations:
|
||||
* <ul>
|
||||
* <li>{@link #name(String)}</li>
|
||||
* <li>{@link #putReturnsNull(boolean)}</li>
|
||||
* <li>{@link #removeReturnsNull(boolean)}</li>
|
||||
* <li>{@link #entryOperations(MapEntryOperations)}</li>
|
||||
* <li>{@link #mapMethods(MapMethods)}</li>
|
||||
* <li>{@link #defaultValueProvider(DefaultValueProvider)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param <K> key type of the maps, produced by this builder
|
||||
* @param <V> value type of the maps, produced by this builder
|
||||
* @see ChronicleHashBuilder
|
||||
@@ -133,6 +150,9 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
private static final ConcurrentHashMap<File, Void> fileLockingControl =
|
||||
new ConcurrentHashMap<>(128);
|
||||
private static int MAX_BOOTSTRAPPING_HEADER_SIZE = (int) MemoryUnit.KILOBYTES.toBytes(16);
|
||||
|
||||
|
||||
private String name;
|
||||
SerializationBuilder<K> keyBuilder;
|
||||
SerializationBuilder<V> valueBuilder;
|
||||
K averageKey;
|
||||
@@ -413,6 +433,20 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return privateAPI;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <a href="#jvm-configurations">Read more about JVM-level configurations</a>.
|
||||
*/
|
||||
@Override
|
||||
public ChronicleMapBuilder<K, V> name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -812,7 +846,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
* 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
|
||||
* @return this builder back
|
||||
* @throws IllegalStateException if values of maps, created by this builder, couldn't reference
|
||||
* off-heap memory
|
||||
*/
|
||||
@@ -1112,8 +1146,10 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
* 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>By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract and
|
||||
* returns the previous mapped value on {@code put()} calls.
|
||||
* <p>This is a <a href="#jvm-configurations">JVM-level configuration</a>.
|
||||
*
|
||||
* <p>By default, {@code ChronicleMap} conforms the general {@code Map} contract and returns the
|
||||
* previous mapped value on {@code put()} calls.
|
||||
*
|
||||
* @param putReturnsNull {@code true} if you want {@link ChronicleMap#put(Object, Object)
|
||||
* ChronicleMap.put()} to not return the value that was replaced but
|
||||
@@ -1141,8 +1177,10 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
* 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>By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract and
|
||||
* returns the mapped value on {@code remove()} calls.
|
||||
* <p>This is a <a href="#jvm-configurations">JVM-level configuration</a>.
|
||||
*
|
||||
* <p>By default, {@code ChronicleMap} conforms the general {@code Map} contract and returns the
|
||||
* mapped value on {@code remove()} calls.
|
||||
*
|
||||
* @param removeReturnsNull {@code true} if you want {@link ChronicleMap#remove(Object)
|
||||
* ChronicleMap.remove()} to not return the value of the removed entry
|
||||
@@ -1408,8 +1446,10 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
* Specifies the function to obtain a value for the key during {@link ChronicleMap#acquireUsing
|
||||
* acquireUsing()} calls, if the key is absent in the map, created by this builder.
|
||||
*
|
||||
* <p>This is a <a href="#jvm-configurations">JVM-level configuration</a>.
|
||||
*
|
||||
* @param defaultValueProvider the strategy to obtain a default value by the absent key
|
||||
* @return this builder object back
|
||||
* @return this builder back
|
||||
*/
|
||||
public ChronicleMapBuilder<K, V> defaultValueProvider(
|
||||
@NotNull DefaultValueProvider<K, V> defaultValueProvider) {
|
||||
@@ -1771,6 +1811,10 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
* <p>This affects behaviour of ordinary map.put(), map.remove(), etc. calls, as well as removes
|
||||
* and replacing values <i>during iterations</i>, <i>remote map calls</i> and
|
||||
* <i>internal replication operations</i>.
|
||||
*
|
||||
* <p>This is a <a href="#jvm-configurations">JVM-level configuration</a>.
|
||||
*
|
||||
* @return this builder back
|
||||
*/
|
||||
public ChronicleMapBuilder<K, V> entryOperations(MapEntryOperations<K, V, ?> entryOperations) {
|
||||
Objects.requireNonNull(entryOperations);
|
||||
@@ -1784,6 +1828,10 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
* {@link ChronicleMap#merge}.
|
||||
*
|
||||
* <p>This affects behaviour of ordinary map calls, as well as <i>remote calls</i>.
|
||||
*
|
||||
* <p>This is a <a href="#jvm-configurations">JVM-level configuration</a>.
|
||||
*
|
||||
* @return this builder back
|
||||
*/
|
||||
public ChronicleMapBuilder<K, V> mapMethods(MapMethods<K, V, ?> mapMethods) {
|
||||
Objects.requireNonNull(mapMethods);
|
||||
|
||||
@@ -32,6 +32,11 @@ class ChronicleMapBuilderPrivateAPI<K, V>
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return b.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializationBuilder<K> keyBuilder() {
|
||||
return b.keyBuilder();
|
||||
|
||||
@@ -75,7 +75,7 @@ class OldDeletedEntriesCleanupThread extends Thread
|
||||
private long removedCompletely;
|
||||
|
||||
OldDeletedEntriesCleanupThread(ReplicatedChronicleMap<?, ?, ?> map) {
|
||||
super("Cleanup Thread for ReplicatedChronicleMap persisted to " + map.file());
|
||||
super("Cleanup Thread for " + map.toIdentityString());
|
||||
this.mapRef = new WeakReference<>(map);
|
||||
cleanupTimeout = map.cleanupTimeout;
|
||||
cleanupTimeoutUnit = map.cleanupTimeoutUnit;
|
||||
|
||||
@@ -66,6 +66,9 @@ public class VanillaChronicleMap<K, V, R>
|
||||
public int alignment;
|
||||
public int worstAlignment;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
private transient String name;
|
||||
|
||||
public transient boolean couldNotDetermineAlignmentBeforeAllocation;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
@@ -134,6 +137,7 @@ public class VanillaChronicleMap<K, V, R>
|
||||
}
|
||||
|
||||
void initTransientsFromBuilder(ChronicleMapBuilder<K, V> builder) {
|
||||
name = builder.name();
|
||||
putReturnsNull = builder.putReturnsNull();
|
||||
removeReturnsNull = builder.removeReturnsNull();
|
||||
|
||||
@@ -239,6 +243,22 @@ public class VanillaChronicleMap<K, V, R>
|
||||
public String toString() {
|
||||
return mapToString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toIdentityString() {
|
||||
if (chronicleSet != null)
|
||||
return chronicleSet.toIdentityString();
|
||||
return "ChronicleMap{" +
|
||||
"name=" + name() +
|
||||
", file=" + file() +
|
||||
", identityHashCode=" + System.identityHashCode(this) +
|
||||
"}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
@@ -81,6 +81,12 @@ public final class ChronicleSetBuilder<K>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChronicleSetBuilder<K> name(String name) {
|
||||
chronicleMapBuilder.name(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChronicleSetBuilder<K> actualSegments(int actualSegments) {
|
||||
chronicleMapBuilder.actualSegments(actualSegments);
|
||||
|
||||
@@ -37,6 +37,11 @@ class ChronicleSetBuilderPrivateAPI<K>
|
||||
this.mapB = mapB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return mapB.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializationBuilder<K> keyBuilder() {
|
||||
return mapB.keyBuilder();
|
||||
|
||||
@@ -90,6 +90,15 @@ class SetFromMap<E> extends AbstractSet<E> implements ChronicleSet<E> {
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toIdentityString() {
|
||||
return "ChronicleSet{" +
|
||||
"name=" + name() +
|
||||
", file=" + file() +
|
||||
", identityHashCode=" + System.identityHashCode(this) +
|
||||
"}";
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return s.hashCode();
|
||||
}
|
||||
@@ -179,6 +188,11 @@ class SetFromMap<E> extends AbstractSet<E> implements ChronicleSet<E> {
|
||||
return m.file();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return m.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
m.close();
|
||||
|
||||
Reference in New Issue
Block a user