mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Refactor VanillaChronicleHash.allocateTier() method
This commit is contained in:
@@ -728,14 +728,13 @@ public abstract class VanillaChronicleHash<K,
|
||||
globalMutableStateAddress() + GLOBAL_MUTABLE_STATE_LOCK_OFFSET);
|
||||
}
|
||||
|
||||
public long allocateTier(int forSegmentIndex, int tier) {
|
||||
LOG.debug("Allocate tier for segment # {}, tier {}", forSegmentIndex, tier);
|
||||
public long allocateTier() {
|
||||
globalMutableStateLock();
|
||||
try {
|
||||
long tiersInUse = globalMutableState.getExtraTiersInUse();
|
||||
if (tiersInUse == maxExtraTiers) {
|
||||
throw new IllegalStateException("Attempt to allocate " + (maxExtraTiers + 1) +
|
||||
"th extra segment tier, " + maxExtraTiers + " is maximum.\n" +
|
||||
if (tiersInUse >= maxExtraTiers) {
|
||||
throw new IllegalStateException("Attempt to allocate #" + (tiersInUse + 1) +
|
||||
" extra segment tier, " + maxExtraTiers + " is maximum.\n" +
|
||||
"Possible reasons include:\n" +
|
||||
" - you have forgotten to configure (or configured wrong) " +
|
||||
"builder.entries() number\n" +
|
||||
@@ -744,30 +743,31 @@ public abstract class VanillaChronicleHash<K,
|
||||
" - keys, inserted into the ChronicleHash, are distributed suspiciously " +
|
||||
"bad. This might be a DOS attack");
|
||||
}
|
||||
while (true) {
|
||||
long firstFreeTierIndex = globalMutableState.getFirstFreeTierIndex();
|
||||
if (firstFreeTierIndex > 0) {
|
||||
globalMutableState.setExtraTiersInUse(tiersInUse + 1);
|
||||
BytesStore allocatedTierBytes = tierBytesStore(firstFreeTierIndex);
|
||||
long allocatedTierOffset = tierBytesOffset(firstFreeTierIndex);
|
||||
long tierBaseAddr = allocatedTierBytes.address(0) + allocatedTierOffset;
|
||||
long tierCountersAreaAddr = tierBaseAddr + tierHashLookupOuterSize;
|
||||
long nextFreeTierIndex = TierCountersArea.nextTierIndex(tierCountersAreaAddr);
|
||||
// now, when this tier will be a part of the map, the next tier designates
|
||||
// the next tier in the data store, should be 0
|
||||
TierCountersArea.nextTierIndex(tierCountersAreaAddr, 0);
|
||||
TierCountersArea.segmentIndex(tierCountersAreaAddr, forSegmentIndex);
|
||||
TierCountersArea.tier(tierCountersAreaAddr, tier);
|
||||
globalMutableState.setFirstFreeTierIndex(nextFreeTierIndex);
|
||||
return firstFreeTierIndex;
|
||||
} else {
|
||||
try {
|
||||
allocateTierBulk();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
long firstFreeTierIndex = globalMutableState.getFirstFreeTierIndex();
|
||||
if (firstFreeTierIndex < 0) {
|
||||
throw new RuntimeException("unexpected firstFreeTierIndex value " +
|
||||
firstFreeTierIndex);
|
||||
}
|
||||
if (firstFreeTierIndex == 0) {
|
||||
try {
|
||||
allocateTierBulk();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
firstFreeTierIndex = globalMutableState.getFirstFreeTierIndex();
|
||||
if (firstFreeTierIndex <= 0) {
|
||||
throw new RuntimeException("unexpected firstFreeTierIndex value " +
|
||||
firstFreeTierIndex);
|
||||
}
|
||||
}
|
||||
globalMutableState.setExtraTiersInUse(tiersInUse + 1);
|
||||
BytesStore allocatedTierBytes = tierBytesStore(firstFreeTierIndex);
|
||||
long allocatedTierOffset = tierBytesOffset(firstFreeTierIndex);
|
||||
long tierBaseAddr = allocatedTierBytes.address(0) + allocatedTierOffset;
|
||||
long tierCountersAreaAddr = tierBaseAddr + tierHashLookupOuterSize;
|
||||
long nextFreeTierIndex = TierCountersArea.nextTierIndex(tierCountersAreaAddr);
|
||||
globalMutableState.setFirstFreeTierIndex(nextFreeTierIndex);
|
||||
return firstFreeTierIndex;
|
||||
} finally {
|
||||
globalMutableStateUnlock();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import net.openhft.chronicle.hash.SegmentLock;
|
||||
import net.openhft.chronicle.hash.impl.*;
|
||||
import net.openhft.chronicle.hash.impl.stage.hash.Chaining;
|
||||
import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation;
|
||||
import net.openhft.chronicle.hash.impl.stage.hash.LogHolder;
|
||||
import net.openhft.chronicle.hash.impl.stage.query.KeySearch;
|
||||
import net.openhft.chronicle.hash.locks.InterProcessLock;
|
||||
import net.openhft.chronicle.map.impl.IterationContext;
|
||||
@@ -46,6 +47,7 @@ import static net.openhft.chronicle.hash.impl.VanillaChronicleHash.TIER_COUNTERS
|
||||
@Staged
|
||||
public abstract class SegmentStages implements SegmentLock, LocksInterface {
|
||||
|
||||
@StageRef LogHolder log;
|
||||
@StageRef Chaining chaining;
|
||||
@StageRef public VanillaChronicleHashHolder<?> hh;
|
||||
@StageRef public CheckOnEachPublicOperation checkOnEachPublicOperation;
|
||||
@@ -558,11 +560,17 @@ public abstract class SegmentStages implements SegmentLock, LocksInterface {
|
||||
VanillaChronicleHash<?, ?, ?, ?> h = hh.h();
|
||||
long nextTierIndex = nextTierIndex();
|
||||
if (nextTierIndex == 0) {
|
||||
nextTierIndex = h.allocateTier(segmentIndex, tier + 1);
|
||||
log.LOG.debug("Allocate tier for segment # {}, tier {}", segmentIndex, tier + 1);
|
||||
nextTierIndex = h.allocateTier();
|
||||
nextTierIndex(nextTierIndex);
|
||||
long currentTierIndex = tierIndex;
|
||||
long prevTierIndex = tierIndex;
|
||||
|
||||
initSegmentTier(tier + 1, nextTierIndex);
|
||||
prevTierIndex(currentTierIndex);
|
||||
|
||||
TierCountersArea.segmentIndex(tierCountersAreaAddr(), segmentIndex);
|
||||
TierCountersArea.tier(tierCountersAreaAddr(), tier);
|
||||
nextTierIndex(0);
|
||||
prevTierIndex(prevTierIndex);
|
||||
} else {
|
||||
initSegmentTier(tier + 1, nextTierIndex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user