mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Add a fix for enums being written as marshallables.
This commit is contained in:
@@ -71,112 +71,83 @@ public abstract class VanillaChronicleHash<K,
|
||||
public static final long RESERVED_GLOBAL_MUTABLE_STATE_BYTES = 1024;
|
||||
|
||||
// --- Start of instance fields ---
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
private String dataFileVersion;
|
||||
|
||||
/**
|
||||
* Global mutable state lock doesn't yet need read-write levels and waits;
|
||||
* Used the same locking strategy as in segment locks
|
||||
* (VanillaReadWriteUpdateWithWaitsLockingStrategy) in order to simplify Chronicle Map
|
||||
* specification (having only one kind of locks to specify and implement).
|
||||
*/
|
||||
static final LockingStrategy globalMutableStateLockingStrategy =
|
||||
VanillaReadWriteUpdateWithWaitsLockingStrategy.instance();
|
||||
static final TryAcquireOperation<LockingStrategy> globalMutableStateLockTryAcquireOperation =
|
||||
TryAcquireOperations.lock();
|
||||
static final
|
||||
AcquisitionStrategy<LockingStrategy, RuntimeException>
|
||||
globalMutableStateLockAcquisitionStrategy =
|
||||
AcquisitionStrategies.spinLoopOrFail(2, TimeUnit.SECONDS);
|
||||
private static final long GLOBAL_MUTABLE_STATE_LOCK_OFFSET = 0L;
|
||||
private static final long GLOBAL_MUTABLE_STATE_VALUE_OFFSET = 8L;
|
||||
/////////////////////////////////////////////////
|
||||
// If the hash was created in the first place, or read from disk
|
||||
public transient boolean createdOrInMemory;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Key Data model
|
||||
public Class<K> keyClass;
|
||||
public SizeMarshaller keySizeMarshaller;
|
||||
public SizedReader<K> keyReader;
|
||||
public DataAccess<K> keyDataAccess;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
public boolean checksumEntries;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Concurrency (number of segments), memory management and dependent fields
|
||||
public int actualSegments;
|
||||
public HashSplitting hashSplitting;
|
||||
|
||||
public long chunkSize;
|
||||
public int maxChunksPerEntry;
|
||||
public long actualChunksPerSegmentTier;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Precomputed offsets and sizes for fast Context init
|
||||
int segmentHeaderSize;
|
||||
|
||||
public int tierHashLookupValueBits;
|
||||
public int tierHashLookupKeyBits;
|
||||
public int tierHashLookupSlotSize;
|
||||
public long tierHashLookupCapacity;
|
||||
public long maxEntriesPerHashLookup;
|
||||
long tierHashLookupInnerSize;
|
||||
public long tierHashLookupOuterSize;
|
||||
|
||||
public long tierFreeListInnerSize;
|
||||
public long tierFreeListOuterSize;
|
||||
|
||||
long tierEntrySpaceInnerSize;
|
||||
public int tierEntrySpaceInnerOffset;
|
||||
long tierEntrySpaceOuterSize;
|
||||
|
||||
public long tierSize;
|
||||
|
||||
public long tiersInBulk;
|
||||
public transient List<TierBulkData> tierBulkOffsets;
|
||||
public transient long headerSize;
|
||||
public transient long segmentHeadersOffset;
|
||||
/////////////////////////////////////////////////
|
||||
// Miscellaneous fields
|
||||
public transient CompactOffHeapLinearHashTable hashLookup;
|
||||
public transient Identity identity;
|
||||
protected int log2TiersInBulk;
|
||||
/////////////////////////////////////////////////
|
||||
// Bytes Store (essentially, the base address) and serialization-dependent offsets
|
||||
protected transient BytesStore bs;
|
||||
/////////////////////////////////////////////////
|
||||
// Precomputed offsets and sizes for fast Context init
|
||||
int segmentHeaderSize;
|
||||
long tierHashLookupInnerSize;
|
||||
long tierEntrySpaceInnerSize;
|
||||
long tierEntrySpaceOuterSize;
|
||||
long maxExtraTiers;
|
||||
long tierBulkSizeInBytes;
|
||||
long tierBulkInnerOffsetToTiers;
|
||||
public long tiersInBulk;
|
||||
protected int log2TiersInBulk;
|
||||
|
||||
transient long segmentsOffset;
|
||||
/////////////////////////////////////////////////
|
||||
private String dataFileVersion;
|
||||
/////////////////////////////////////////////////
|
||||
// Resources
|
||||
private transient File file;
|
||||
private transient RandomAccessFile raf;
|
||||
private transient ChronicleHashResources resources;
|
||||
private transient Cleaner cleaner;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Bytes Store (essentially, the base address) and serialization-dependent offsets
|
||||
protected transient BytesStore bs;
|
||||
|
||||
public static class TierBulkData {
|
||||
public final BytesStore bytesStore;
|
||||
public final long offset;
|
||||
|
||||
public TierBulkData(BytesStore bytesStore, long offset) {
|
||||
this.bytesStore = bytesStore;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public TierBulkData(TierBulkData data, long offset) {
|
||||
this.bytesStore = data.bytesStore;
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
public transient List<TierBulkData> tierBulkOffsets;
|
||||
|
||||
public transient long headerSize;
|
||||
public transient long segmentHeadersOffset;
|
||||
transient long segmentsOffset;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Miscellaneous fields
|
||||
public transient CompactOffHeapLinearHashTable hashLookup;
|
||||
|
||||
private transient VanillaGlobalMutableState globalMutableState;
|
||||
|
||||
/**
|
||||
* {@link ChronicleHashCloseOnExitHook} needs to use {@code VanillaChronicleHash}es as
|
||||
* WeakHashMap keys, but with identity comparison, not Map's equals() and hashCode().
|
||||
*/
|
||||
public class Identity {
|
||||
public VanillaChronicleHash hash() {
|
||||
return VanillaChronicleHash.this;
|
||||
}
|
||||
}
|
||||
|
||||
public transient Identity identity;
|
||||
|
||||
// --- End of instance fields ---
|
||||
|
||||
private transient ChronicleHashResources resources;
|
||||
private transient Cleaner cleaner;
|
||||
private transient VanillaGlobalMutableState globalMutableState;
|
||||
|
||||
public VanillaChronicleHash(ChronicleMapBuilder<K, ?> builder) {
|
||||
// Version
|
||||
@@ -238,6 +209,20 @@ public abstract class VanillaChronicleHash<K,
|
||||
checksumEntries = privateAPI.checksumEntries();
|
||||
}
|
||||
|
||||
public static IOException throwRecoveryOrReturnIOException(
|
||||
File file, String message, boolean recover) {
|
||||
message = "file=" + file + " " + message;
|
||||
if (recover) {
|
||||
throw new ChronicleHashRecoveryFailedException(message);
|
||||
} else {
|
||||
return new IOException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static long roundUpMapHeaderSize(long headerSize) {
|
||||
return CACHE_LINES.align(headerSize, BYTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readMarshallable(@NotNull WireIn wire) {
|
||||
readMarshallableFields(wire);
|
||||
@@ -253,9 +238,9 @@ public abstract class VanillaChronicleHash<K,
|
||||
createdOrInMemory = false;
|
||||
|
||||
keyClass = wireIn.read(() -> "keyClass").typeLiteral();
|
||||
keySizeMarshaller = wireIn.read(() -> "keySizeMarshaller").typedMarshallable();
|
||||
keyReader = wireIn.read(() -> "keyReader").typedMarshallable();
|
||||
keyDataAccess = wireIn.read(() -> "keyDataAccess").typedMarshallable();
|
||||
keySizeMarshaller = wireIn.read(() -> "keySizeMarshaller").object(SizeMarshaller.class);
|
||||
keyReader = wireIn.read(() -> "keyReader").object(SizedReader.class);
|
||||
keyDataAccess = wireIn.read(() -> "keyDataAccess").object(DataAccess.class);
|
||||
|
||||
checksumEntries = wireIn.read(() -> "checksumEntries").bool();
|
||||
|
||||
@@ -297,14 +282,14 @@ public abstract class VanillaChronicleHash<K,
|
||||
wireOut.write(() -> "dataFileVersion").text(dataFileVersion);
|
||||
|
||||
wireOut.write(() -> "keyClass").typeLiteral(keyClass);
|
||||
wireOut.write(() -> "keySizeMarshaller").typedMarshallable(keySizeMarshaller);
|
||||
wireOut.write(() -> "keyReader").typedMarshallable(keyReader);
|
||||
wireOut.write(() -> "keyDataAccess").typedMarshallable(keyDataAccess);
|
||||
wireOut.write(() -> "keySizeMarshaller").object(keySizeMarshaller);
|
||||
wireOut.write(() -> "keyReader").object(keyReader);
|
||||
wireOut.write(() -> "keyDataAccess").object(keyDataAccess);
|
||||
|
||||
wireOut.write(() -> "checksumEntries").bool(checksumEntries);
|
||||
|
||||
wireOut.write(() -> "actualSegments").int32(actualSegments);
|
||||
wireOut.write(() -> "hashSplitting").typedMarshallable(hashSplitting);
|
||||
wireOut.write(() -> "hashSplitting").object(hashSplitting);
|
||||
|
||||
wireOut.write(() -> "chunkSize").int64(chunkSize);
|
||||
wireOut.write(() -> "maxChunksPerEntry").int32(maxChunksPerEntry);
|
||||
@@ -424,20 +409,6 @@ public abstract class VanillaChronicleHash<K,
|
||||
}
|
||||
}
|
||||
|
||||
public static IOException throwRecoveryOrReturnIOException(
|
||||
File file, String message, boolean recover) {
|
||||
message = "file=" + file + " " + message;
|
||||
if (recover) {
|
||||
throw new ChronicleHashRecoveryFailedException(message);
|
||||
} else {
|
||||
return new IOException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static long roundUpMapHeaderSize(long headerSize) {
|
||||
return CACHE_LINES.align(headerSize, BYTES);
|
||||
}
|
||||
|
||||
public final void createInMemoryStoreAndSegments(ChronicleHashResources resources)
|
||||
throws IOException {
|
||||
this.resources = resources;
|
||||
@@ -739,24 +710,6 @@ public abstract class VanillaChronicleHash<K,
|
||||
return actualSegments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Global mutable state lock doesn't yet need read-write levels and waits;
|
||||
* Used the same locking strategy as in segment locks
|
||||
* (VanillaReadWriteUpdateWithWaitsLockingStrategy) in order to simplify Chronicle Map
|
||||
* specification (having only one kind of locks to specify and implement).
|
||||
*/
|
||||
static final LockingStrategy globalMutableStateLockingStrategy =
|
||||
VanillaReadWriteUpdateWithWaitsLockingStrategy.instance();
|
||||
static final TryAcquireOperation<LockingStrategy> globalMutableStateLockTryAcquireOperation =
|
||||
TryAcquireOperations.lock();
|
||||
static final
|
||||
AcquisitionStrategy<LockingStrategy, RuntimeException>
|
||||
globalMutableStateLockAcquisitionStrategy =
|
||||
AcquisitionStrategies.spinLoopOrFail(2, TimeUnit.SECONDS);
|
||||
|
||||
private static final long GLOBAL_MUTABLE_STATE_LOCK_OFFSET = 0L;
|
||||
private static final long GLOBAL_MUTABLE_STATE_VALUE_OFFSET = 8L;
|
||||
|
||||
private long globalMutableStateAddress() {
|
||||
return bsAddress() + headerSize;
|
||||
}
|
||||
@@ -1045,4 +998,29 @@ public abstract class VanillaChronicleHash<K,
|
||||
public List<WeakReference<ContextHolder>> allContexts() {
|
||||
return Collections.unmodifiableList(resources.contexts());
|
||||
}
|
||||
|
||||
public static class TierBulkData {
|
||||
public final BytesStore bytesStore;
|
||||
public final long offset;
|
||||
|
||||
public TierBulkData(BytesStore bytesStore, long offset) {
|
||||
this.bytesStore = bytesStore;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public TierBulkData(TierBulkData data, long offset) {
|
||||
this.bytesStore = data.bytesStore;
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ChronicleHashCloseOnExitHook} needs to use {@code VanillaChronicleHash}es as
|
||||
* WeakHashMap keys, but with identity comparison, not Map's equals() and hashCode().
|
||||
*/
|
||||
public class Identity {
|
||||
public VanillaChronicleHash hash() {
|
||||
return VanillaChronicleHash.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user