mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Fix a bug in VanillaChronicleMap.putValue() -- avoid allocation of overlapping areas
This commit is contained in:
@@ -1476,9 +1476,8 @@ final class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? supe
|
||||
// key is found
|
||||
entry.skip(keySize);
|
||||
long timestampPos = entry.position();
|
||||
long replacedTimestamp = entry.readLong();
|
||||
byte replacedIdentifier = entry.readByte();
|
||||
entry.position(timestampPos);
|
||||
long replacedTimestamp = entry.readLong(timestampPos);
|
||||
byte replacedIdentifier = entry.readByte(timestampPos + 8);
|
||||
if (shouldIgnore(entry, timestamp, identifier)) {
|
||||
// the following assert should be enabled, but TimeBasedReplicationTest
|
||||
// intentionally violates the explained invariant, => assertion fails.
|
||||
|
||||
@@ -2376,10 +2376,10 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
|
||||
prevValueInstance = readValue(copies, entry, null, prevValueSize);
|
||||
}
|
||||
|
||||
entry.positionAddr(valueAddr);
|
||||
boolean doPutValue;
|
||||
boolean hasValueChanged = false;
|
||||
if (eventListener != null) {
|
||||
entry.positionAddr(valueAddr);
|
||||
hasValueChanged = prevValueSize != valueSize ||
|
||||
!metaValueInterop.startsWith(valueInterop, entry, value);
|
||||
doPutValue = hasValueChanged;
|
||||
@@ -2783,10 +2783,10 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
|
||||
MVBI metaValueInterop = getNewValueInterops.getMetaValueInterop(
|
||||
copies, valueInterop, newValue);
|
||||
long newValueSize = metaValueInterop.size(valueInterop, newValue);
|
||||
entry.positionAddr(valueAddr);
|
||||
boolean doPutValue;
|
||||
boolean hasValueChanged = false;
|
||||
if (eventListener != null) {
|
||||
entry.positionAddr(valueAddr);
|
||||
hasValueChanged = valueSize != newValueSize ||
|
||||
!metaValueInterop.startsWith(valueInterop, entry, newValue);
|
||||
doPutValue = hasValueChanged;
|
||||
@@ -2856,11 +2856,13 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
|
||||
if (realloc(pos, oldSizeInChunks, newSizeInChunks))
|
||||
break newValueDoesNotFit;
|
||||
// RELOCATION
|
||||
free(pos, oldSizeInChunks);
|
||||
onRelocation(this, pos);
|
||||
int allocatedChunks =
|
||||
inChunks(innerEntrySize(sizeOfEverythingBeforeValue, newElemSize));
|
||||
long newPos = alloc(allocatedChunks);
|
||||
// free after new alloc, to avoid overlapping allocation => undef. behaviour
|
||||
// on unsafe.copyMemory
|
||||
free(pos, oldSizeInChunks);
|
||||
// putValue() is called from put() and replace()
|
||||
// after successful search by key
|
||||
searchedHashLookup.replacePrevPos(segmentState.searchState, newPos,
|
||||
|
||||
Reference in New Issue
Block a user