mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Improve lock handling.
This commit is contained in:
@@ -668,71 +668,14 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
private MultiMap hashLookup;
|
||||
private long nextPosToSearchFrom = 0L;
|
||||
|
||||
final ReadLocked<K, V, MKI, KI> readUnlock = new ReadLocked<K, V, MKI, KI>() {
|
||||
@Override
|
||||
public void close() {
|
||||
Segment.this.readUnlock();
|
||||
}
|
||||
};
|
||||
final ThreadLocal<ReadLocked<K, V, MKI, KI>> readUnlockTL = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* close for native values does not call put on close
|
||||
*/
|
||||
final MutableLockedEntry<K, V, MKI, KI> nativeWriteUnlock = new WriteLocked<K, V, MKI, KI>() {
|
||||
@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<K, V, MKI, KI>
|
||||
heapWriteUnlock = new WriteLocked<K, V, MKI, KI>() {
|
||||
|
||||
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<K, V, MKI, KI> writeUnlock = isNativeValueClass
|
||||
? new NativeWriteLocked()
|
||||
: new HeapWriteLocked();
|
||||
|
||||
|
||||
/**
|
||||
@@ -819,7 +762,12 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
public MutableLockedEntry<K, V, MKI, KI> readLock() throws IllegalStateException {
|
||||
while (true) {
|
||||
final boolean success = segmentHeader.tryRWReadLock(LOCK_OFFSET, lockTimeOutNS);
|
||||
if (success) return readUnlock;
|
||||
if (success) {
|
||||
ReadLocked<K, V, MKI, KI> 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<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
public MutableLockedEntry<K, V, MKI, KI> 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<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
if (this.pos == pos) count++;
|
||||
}
|
||||
}
|
||||
|
||||
class NativeWriteLocked extends VanillaChronicleMap.WriteLocked<K, V, MKI, KI> {
|
||||
@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<K, V, MKI, KI> {
|
||||
|
||||
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<K, V, MKI, KI> {
|
||||
@Override
|
||||
public void close() {
|
||||
Segment.this.readUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EntryIterator implements Iterator<Entry<K, V>> {
|
||||
@@ -1551,7 +1558,6 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
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));
|
||||
|
||||
Reference in New Issue
Block a user