From a489c74cf9fc460264b171ad1c3a00a138f895dd Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Sun, 2 Nov 2014 23:29:30 +0000 Subject: [PATCH] Improve lock handling. --- .../chronicle/map/VanillaChronicleMap.java | 134 +++++++++--------- 1 file changed, 70 insertions(+), 64 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index 8ecd5accf..12291349c 100644 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -668,71 +668,14 @@ class VanillaChronicleMap, private MultiMap hashLookup; private long nextPosToSearchFrom = 0L; - final ReadLocked readUnlock = new ReadLocked() { - @Override - public void close() { - Segment.this.readUnlock(); - } - }; + final ThreadLocal> readUnlockTL = new ThreadLocal<>(); /** * close for native values does not call put on close */ - final MutableLockedEntry nativeWriteUnlock = new 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); - } - - - }; - - /** - * close for heap values calls put on close - */ - final MutableLockedEntry - heapWriteUnlock = new WriteLocked() { - - boolean dontPutOnClose; - - @Override - public void close() { - if (copies != null && !dontPutOnClose) - putWithoutLock(copies, metaKeyInterop, keyInterop, key(), value(), - segmentHash, true); - - copies = null; - dontPutOnClose = false; - Segment.this.writeUnlock(); - } - - @Override - public void dontPutOnClose() { - dontPutOnClose = true; - } - - @Override - public void removeEntry() { - dontPutOnClose = true; - if (copies != null) - removeWithoutLock(copies, metaKeyInterop, keyInterop, key(), null, segmentHash); - - } - - - }; + final MutableLockedEntry writeUnlock = isNativeValueClass + ? new NativeWriteLocked() + : new HeapWriteLocked(); /** @@ -819,7 +762,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 { @@ -832,7 +780,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")); @@ -1453,6 +1401,65 @@ 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 { + + boolean dontPutOnClose; + + @Override + public void close() { + if (copies != null && !dontPutOnClose) + putWithoutLock(copies, metaKeyInterop, keyInterop, key(), value(), + segmentHash, true); + + copies = null; + dontPutOnClose = false; + Segment.this.writeUnlock(); + } + + @Override + public void dontPutOnClose() { + dontPutOnClose = true; + } + + @Override + public void removeEntry() { + dontPutOnClose = true; + if (copies != null) + removeWithoutLock(copies, metaKeyInterop, keyInterop, key(), null, segmentHash); + + } + + + } + + class TLReadLocked extends VanillaChronicleMap.ReadLocked { + @Override + public void close() { + Segment.this.readUnlock(); + } + } } class EntryIterator implements Iterator> { @@ -1551,7 +1558,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));