From d5fe21a29008eb42516ab2519029e65b252e6e2e Mon Sep 17 00:00:00 2001 From: leventov Date: Tue, 24 Nov 2015 23:44:51 +0300 Subject: [PATCH] Fix a bug -- incorrect entry size computation in replace(), checksum bytes forgotten --- .../map/impl/stage/entry/MapEntryStages.java | 19 +++++++++++++++---- .../impl/stage/query/QueryMapEntryStages.java | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java index b14c6d2a7..316156340 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java @@ -155,7 +155,7 @@ public abstract class MapEntryStages extends HashEntryStages VanillaChronicleMap m = mh.m(); long newValueOffset = alignAddr(entryStartOffset + newSizeOfEverythingBeforeValue, mh.m().alignment); - long newEntrySize = newValueOffset + newValue.size() - entryStartOffset; + long newEntrySize = newEntrySize(newValue, entryStartOffset, newValueOffset); int newSizeInChunks = m.inChunks(newEntrySize); newValueDoesNotFit: if (newSizeInChunks > entrySizeInChunks) { @@ -209,8 +209,15 @@ public abstract class MapEntryStages extends HashEntryStages } } + public long newEntrySize(Data newValue, long entryStartOffset, long newValueOffset) { + return checksumStrategy.extraEntryBytes() + + newValueOffset + newValue.size() - entryStartOffset; + } + protected void relocation(Data newValue, long newSizeOfEverythingBeforeValue) { s.innerWriteLock.lock(); + // TODO free bits only after another range is allocated, to ensure they doesn't overlap, + // because overlapping copy is dangerous, platform dependent s.free(pos, entrySizeInChunks); long entrySize = innerEntrySize(newSizeOfEverythingBeforeValue, newValue.size()); // need to copy, because in initEntryAndKeyCopying(), in alloc(), nextTier() called -> @@ -246,13 +253,17 @@ public abstract class MapEntryStages extends HashEntryStages } public long innerEntrySize(long sizeOfEverythingBeforeValue, long valueSize) { + long sizeWithoutChecksum; if (mh.m().constantlySizedEntry) { - return alignAddr(sizeOfEverythingBeforeValue + valueSize, mh.m().alignment); + sizeWithoutChecksum = + alignAddr(sizeOfEverythingBeforeValue + valueSize, mh.m().alignment); } else if (mh.m().couldNotDetermineAlignmentBeforeAllocation) { - return sizeOfEverythingBeforeValue + mh.m().worstAlignment + valueSize; + sizeWithoutChecksum = sizeOfEverythingBeforeValue + mh.m().worstAlignment + valueSize; } else { - return alignAddr(sizeOfEverythingBeforeValue, mh.m().alignment) + valueSize; + sizeWithoutChecksum = + alignAddr(sizeOfEverythingBeforeValue, mh.m().alignment) + valueSize; } + return sizeWithoutChecksum + checksumStrategy.extraEntryBytes(); } long sizeOfEverythingBeforeValue(long keySize, long valueSize) { diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/query/QueryMapEntryStages.java b/src/main/java/net/openhft/chronicle/map/impl/stage/query/QueryMapEntryStages.java index 767894569..9b1f1dc78 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/query/QueryMapEntryStages.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/query/QueryMapEntryStages.java @@ -42,7 +42,7 @@ public abstract class QueryMapEntryStages extends MapEntryStages { newSizeOfEverythingBeforeValue = newSizeOfEverythingBeforeValue(newValue); long newValueOffset = alignAddr(entryStartOffset + newSizeOfEverythingBeforeValue, mh.m().alignment); - long newEntrySize = newValueOffset + newValue.size() - entryStartOffset; + long newEntrySize = newEntrySize(newValue, entryStartOffset, newValueOffset); newSizeInChunks = mh.m().inChunks(newEntrySize); } else { newSizeInChunks = entrySizeInChunks;