diff --git a/pom.xml b/pom.xml
index 1222f61ad..cc7f90f96 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,7 @@
net.openhft
lang
- 6.4.21
+ 6.4.22-SNAPSHOT
diff --git a/src/main/java/net/openhft/chronicle/map/Int24Int24MultiMap.java b/src/main/java/net/openhft/chronicle/map/Int24Int24MultiMap.java
index f98287d68..a097181c6 100644
--- a/src/main/java/net/openhft/chronicle/map/Int24Int24MultiMap.java
+++ b/src/main/java/net/openhft/chronicle/map/Int24Int24MultiMap.java
@@ -239,9 +239,12 @@ class Int24Int24MultiMap implements MultiMap {
@Override
public void replacePrevPos(SearchState searchState, long newValue) {
checkValueForPut(newValue);
- long prevPos = stepBack(searchState.searchPos);
+ long prevPos = searchState.searchPos;
+ if (!searchState.putAfterFailedSearch)
+ prevPos = stepBack(prevPos);
long oldEntry = bytes.readInt48(prevPos);
long oldValue = value(oldEntry);
+ checkValueForRemove(oldValue);
positions.clear(oldValue);
positions.set(newValue);
bytes.writeInt48(prevPos, entry(searchState.searchHash, newValue));
diff --git a/src/main/java/net/openhft/chronicle/map/IntIntMultiMap.java b/src/main/java/net/openhft/chronicle/map/IntIntMultiMap.java
index c92c1f8fc..46be5e7cc 100644
--- a/src/main/java/net/openhft/chronicle/map/IntIntMultiMap.java
+++ b/src/main/java/net/openhft/chronicle/map/IntIntMultiMap.java
@@ -240,9 +240,12 @@ class IntIntMultiMap implements MultiMap {
@Override
public void replacePrevPos(SearchState searchState, long newValue) {
checkValueForPut(newValue);
- long prevPos = stepBack(searchState.searchPos);
+ long prevPos = searchState.searchPos;
+ if (!searchState.putAfterFailedSearch)
+ prevPos = stepBack(prevPos);
long oldEntry = bytes.readLong(prevPos);
long oldValue = value(oldEntry);
+ checkValueForRemove(oldValue);
positions.clear(oldValue);
positions.set(newValue);
bytes.writeLong(prevPos, entry(searchState.searchHash, newValue));
diff --git a/src/main/java/net/openhft/chronicle/map/SearchState.java b/src/main/java/net/openhft/chronicle/map/SearchState.java
index 954b3a88e..1669e74c7 100644
--- a/src/main/java/net/openhft/chronicle/map/SearchState.java
+++ b/src/main/java/net/openhft/chronicle/map/SearchState.java
@@ -19,4 +19,5 @@ package net.openhft.chronicle.map;
final class SearchState {
long searchHash = -1L;
long searchPos = -1L;
+ boolean putAfterFailedSearch = false;
}
diff --git a/src/main/java/net/openhft/chronicle/map/ShortShortMultiMap.java b/src/main/java/net/openhft/chronicle/map/ShortShortMultiMap.java
index 9055a5d3a..27dfe119a 100755
--- a/src/main/java/net/openhft/chronicle/map/ShortShortMultiMap.java
+++ b/src/main/java/net/openhft/chronicle/map/ShortShortMultiMap.java
@@ -206,6 +206,7 @@ class ShortShortMultiMap implements MultiMap {
key = maskUnsetKey(key);
searchStateToReuse.searchPos = pos(key);
searchStateToReuse.searchHash = key;
+ searchStateToReuse.putAfterFailedSearch = false;
}
@Override
@@ -237,9 +238,12 @@ class ShortShortMultiMap implements MultiMap {
@Override
public void replacePrevPos(SearchState searchState, long newValue) {
checkValueForPut(newValue);
- long prevPos = stepBack(searchState.searchPos);
+ long prevPos = searchState.searchPos;
+ if (!searchState.putAfterFailedSearch)
+ prevPos = stepBack(prevPos);
int oldEntry = bytes.readInt(prevPos);
long oldValue = value(oldEntry);
+ checkValueForRemove(oldValue);
positions.clear(oldValue);
positions.set(newValue);
bytes.writeInt(prevPos, entry(searchState.searchHash, newValue));
@@ -250,6 +254,7 @@ class ShortShortMultiMap implements MultiMap {
checkValueForPut(value);
positions.set(value);
bytes.writeInt(searchState.searchPos, entry(searchState.searchHash, value));
+ searchState.putAfterFailedSearch = true;
}
@Override
diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java
index 58a0d4571..89cb3b2c9 100755
--- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java
+++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java
@@ -2348,26 +2348,26 @@ class VanillaChronicleMap,
onRelocation(this, pos);
int allocatedChunks =
inChunks(innerEntrySize(sizeOfEverythingBeforeValue, newElemSize));
- pos = alloc(allocatedChunks);
+ long newPos = alloc(allocatedChunks);
// putValue() is called from put() and replace()
// after successful search by key
- searchedHashLookup.replacePrevPos(segmentState.searchState, pos);
- offset = offsetFromPos(pos);
+ searchedHashLookup.replacePrevPos(segmentState.searchState, newPos);
+ long newOffset = offsetFromPos(newPos);
+ reuse(entry, newOffset);
// Moving metadata, key size and key.
// Don't want to fiddle with pseudo-buffers for this,
// since we already have all absolute addresses.
long newEntryStartAddr = entry.address();
NativeBytes.UNSAFE.copyMemory(entryStartAddr,
newEntryStartAddr, valueSizeAddr - entryStartAddr);
- entry = reuse(entry, offset);
entry.position(valueSizePos);
valueSizeMarshaller.writeSize(entry, newElemSize);
alignment.alignPositionAddr(entry);
metaElemWriter.write(elemWriter, entry, newElem);
- freeExtraAllocatedChunks(pos, allocatedChunks, entry);
+ freeExtraAllocatedChunks(newPos, allocatedChunks, entry);
- segmentState.pos = pos;
+ segmentState.pos = newPos;
return offset;
// END OF RELOCATION
} else if (newSizeInChunks < oldSizeInChunks) {
diff --git a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java
index 2184a3322..5fd7f995f 100755
--- a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java
+++ b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java
@@ -664,7 +664,7 @@ public class ChronicleMapTest {
}
@Test
- @Ignore("HCOLL-277")
+ @Ignore("Performance test")
public void testAcquirePerf256()
throws IOException, ClassNotFoundException, IllegalAccessException,
InstantiationException, InterruptedException, ExecutionException {
@@ -690,7 +690,8 @@ public class ChronicleMapTest {
// File tmpFile = File.createTempFile("testAcquirePerf", ".deleteme");
// tmpFile.deleteOnExit();
- final ChronicleMap map = builder.create(); //createPersistedTo(tmpFile);
+ //createPersistedTo(tmpFile);
+ final ChronicleMap map = builder.create();
int count = runs > 500 ? 2 : 3;
System.out.println("\nKey size: " + runs + " Million entries. " + builder);
@@ -734,7 +735,8 @@ public class ChronicleMapTest {
}
long time = System.currentTimeMillis() - start;
- System.out.printf("EntrySize: %,d Entries: %,d M Segments: %,d Throughput %.1f M ops/sec%n",
+ System.out.printf("EntrySize: %,d Entries: %,d M Segments: " +
+ "%,d Throughput %.1f M ops/sec%n",
entrySize, runs, segments,
threads * entries / 1000.0 / time);
}