diff --git a/src/main/java/net/openhft/chronicle/hash/impl/stage/query/HashQuery.java b/src/main/java/net/openhft/chronicle/hash/impl/stage/query/HashQuery.java index 25497b177..0bda55f0e 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/stage/query/HashQuery.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/stage/query/HashQuery.java @@ -131,12 +131,13 @@ public abstract class HashQuery implements SetEntry { checkOnEachPublicOperation.checkOnEachPublicOperation(); s.innerUpdateLock.lock(); if (ks.searchStatePresent()) { - // TODO optimize: if shift-deletion is trivial, updateLock.lock() - s.innerWriteLock.lock(); - hashLookupSearch.remove(); entry.innerRemoveEntryExceptHashLookupUpdate(); ks.setSearchState(ABSENT); initPresenceOfEntry(EntryPresence.ABSENT); + + // write lock scope is reduced as much as possible + s.innerWriteLock.lock(); + hashLookupSearch.remove(); } else { throw new IllegalStateException("Entry is absent when doRemove() is called"); } 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 bd44de4a6..f9ba6be6d 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 @@ -184,7 +184,6 @@ public abstract class MapEntryStages extends HashEntryStages } protected void relocation(Data newValue, long newSizeOfEverythingBeforeValue) { - s.innerWriteLock.lock(); long entrySize = innerEntrySize(newSizeOfEverythingBeforeValue, newValue.size()); // need to copy, because in initEntryAndKeyCopying(), in alloc(), nextTier() called -> // hashLookupPos cleared, as a dependant @@ -207,8 +206,10 @@ public abstract class MapEntryStages extends HashEntryStages CompactOffHeapLinearHashTable hl = hh.h().hashLookup; long hashLookupKey = hl.key(hl.readEntry(oldHashLookupAddr, oldHashLookupPos)); hl.checkValueForPut(pos); - // volatile not needed, because we are in write lock context - hl.writeEntry(s.tierBaseAddr, hlp.hashLookupPos, hl.entry(hashLookupKey, pos)); + hl.writeEntryVolatile(s.tierBaseAddr, hlp.hashLookupPos, hashLookupKey, pos); + // write lock is needed anyway (see testPutShouldBeWriteLocked()) but the scope is reduced + // as much as possible + s.innerWriteLock.lock(); if (tierHasChanged) hl.remove(oldHashLookupAddr, oldHashLookupPos); }