Lock ordering made right

This commit is contained in:
leventov
2015-07-23 21:55:49 +03:00
parent 6e269323f8
commit 6580017b9c
6 changed files with 100 additions and 59 deletions
@@ -7,6 +7,7 @@ import net.openhft.chronicle.map.MapMethods;
import net.openhft.chronicle.map.MapQueryContext;
import net.openhft.chronicle.set.SetEntryOperations;
import net.openhft.chronicle.set.SetQueryContext;
import org.jetbrains.annotations.Nullable;
/**
* Context of {@link ChronicleHash} operations with <i>individual keys</i>.
@@ -137,7 +138,17 @@ import net.openhft.chronicle.set.SetQueryContext;
* @param <K> the hash key type
* @see ChronicleHash#queryContext(Object)
*/
public interface HashQueryContext<K> extends HashContext<K>, InterProcessReadWriteUpdateLock {
public interface HashQueryContext<K> extends HashContext<K>, SegmentLock {
/**
* Returns the index of the accessed segment, where the queried key is located (or to which
* the key is going to be put).
*
* <p>This index might also be used as the {@code InterProcessReadWriteUpdateLock} identifier,
* because {@code ChronicleHashes} has per-segment locks.
*/
@Override
int segmentIndex();
/**
* Returns the queried key as a {@code Data}.
@@ -160,5 +171,6 @@ public interface HashQueryContext<K> extends HashContext<K>, InterProcessReadWri
* @implNote Might acquire {@link #readLock} before searching for the key, if the context
* is not locked yet.
*/
@Nullable
HashAbsentEntry<K> absentEntry();
}
@@ -1,5 +1,7 @@
/*
* Copyright 2014 Higher Frequency Trading http://www.higherfrequencytrading.com
* Copyright 2015 Higher Frequency Trading
*
* http://www.higherfrequencytrading.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,11 +19,19 @@
package net.openhft.chronicle.hash;
import net.openhft.chronicle.hash.locks.InterProcessReadWriteUpdateLock;
import org.jetbrains.annotations.NotNull;
public interface Segment {
long index();
@NotNull
InterProcessReadWriteUpdateLock lock();
/**
* {@link InterProcessReadWriteUpdateLock} of a segment in {@code ChronicleHash}.
*
* <p>In Chronicle-Map off-heap design, locks (and concurrency) are per-segment.
*
* @see ChronicleHashBuilder#minSegments(int)
* @see ChronicleHashBuilder#actualSegments(int)
*/
public interface SegmentLock extends InterProcessReadWriteUpdateLock {
/**
* Returns the index of the accessed segment.
*/
int segmentIndex();
}
@@ -18,6 +18,7 @@
package net.openhft.chronicle.hash.impl.stage.entry;
import net.openhft.chronicle.hash.SegmentLock;
import net.openhft.chronicle.hash.impl.BigSegmentHeader;
import net.openhft.chronicle.hash.impl.LocalLockState;
import net.openhft.chronicle.hash.impl.SegmentHeader;
@@ -38,7 +39,7 @@ import org.jetbrains.annotations.NotNull;
import static net.openhft.chronicle.hash.impl.LocalLockState.UNLOCKED;
@Staged
public abstract class SegmentStages implements InterProcessReadWriteUpdateLock {
public abstract class SegmentStages implements SegmentLock {
@StageRef Chaining chaining;
@StageRef public VanillaChronicleHashHolder<?, ?, ?> hh;
@@ -48,7 +49,6 @@ public abstract class SegmentStages implements InterProcessReadWriteUpdateLock {
public void initTheSegmentIndex(int segmentIndex) {
this.segmentIndex = segmentIndex;
}
// "SegHeader" because stage-generator doesn't support stage names - one is a prefix of another
@@ -27,8 +27,6 @@ import org.jetbrains.annotations.Nullable;
* (like during {@code get()}, {@code put()}, etc., opposed to <i>bulk</i> operations).
* This is the main context type of {@link MapMethods} and {@link MapRemoteOperations}.
*
*
*
* @param <K> the map key type
* @param <V> the map value type
* @param <R> the return type of {@link MapEntryOperations} specialized for the queried map