diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index 56bf65003..f827a5e8f 100644 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -761,7 +761,12 @@ class VanillaChronicleMap, public MutableLockedEntry readLock() throws IllegalStateException { while (true) { final boolean success = segmentHeader.tryRWReadLock(LOCK_OFFSET, lockTimeOutNS); - if (success) return readUnlock; + if (success) { + ReadLocked readLocked = readUnlockTL.get(); + if (readLocked == null) + readUnlockTL.set(readLocked = new TLReadLocked()); + return readLocked; + } if (currentThread().isInterrupted()) { throw new IllegalStateException(new InterruptedException("Unable to obtain lock, interrupted")); } else { @@ -774,7 +779,7 @@ class VanillaChronicleMap, public MutableLockedEntry writeLock() throws IllegalStateException { while (true) { final boolean success = segmentHeader.tryRWWriteLock(LOCK_OFFSET, lockTimeOutNS); - if (success) return isNativeValueClass ? nativeWriteUnlock : heapWriteUnlock; + if (success) return writeUnlock; if (currentThread().isInterrupted()) { throw new IllegalStateException(new InterruptedException("Unable to obtain lock, interrupted")); @@ -1382,7 +1387,7 @@ class VanillaChronicleMap, return hashLookup; } - private class PosPresentOnce implements MultiMap.EntryConsumer { + class PosPresentOnce implements MultiMap.EntryConsumer { long pos; int count = 0; @@ -1395,6 +1400,60 @@ class VanillaChronicleMap, if (this.pos == pos) count++; } } + + class NativeWriteLocked extends VanillaChronicleMap.WriteLocked { + @Override + public void close() { + Segment.this.writeUnlock(); + } + + @Override + public void dontPutOnClose() { + throw new IllegalStateException( + "This method is not supported for native value classes"); + } + + @Override + public void removeEntry() { + if (copies != null) + removeWithoutLock(copies, metaKeyInterop, keyInterop, key(), null, segmentHash); + } + } + + class HeapWriteLocked extends VanillaChronicleMap.WriteLocked { + + private boolean putOnClose = true; + + @Override + public void close() { + if (putOnClose) + putWithoutLock(copies, metaKeyInterop, keyInterop, key(), value(), + segmentHash, true); + + copies = null; + putOnClose = true; + + Segment.this.writeUnlock(); + } + + @Override + public void dontPutOnClose() { + putOnClose = false; + } + + @Override + public void removeEntry() { + putOnClose = false; + removeWithoutLock(copies, metaKeyInterop, keyInterop, key(), null, segmentHash); + } + } + + class TLReadLocked extends VanillaChronicleMap.ReadLocked { + @Override + public void close() { + Segment.this.readUnlock(); + } + } } class EntryIterator implements Iterator> { @@ -1493,7 +1552,6 @@ class VanillaChronicleMap, final long offset = segment.offsetFromPos(pos); final NativeBytes entry = segment.entry(offset); - final long limit = entry.limit(); final long keySize = keySizeMarshaller.readSize(entry); long position = entry.position(); final long segmentHash = segmentHash(Hasher.hash(entry, position, position + keySize)); @@ -1614,8 +1672,6 @@ class VanillaChronicleMap, public boolean present() { return present; } - - } private static abstract class WriteLocked extends MutableLockedEntry