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); }