From 6b030ab44e73479e61280abb043ea0d51b8fc77c Mon Sep 17 00:00:00 2001 From: leventov Date: Wed, 10 Feb 2016 22:59:38 +0700 Subject: [PATCH] Refactor VanillaChronicleHash.allocateTier() method --- .../hash/impl/VanillaChronicleHash.java | 54 +++++++++---------- .../hash/impl/stage/entry/SegmentStages.java | 14 +++-- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java index 7d779bb91..f875a2929 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java @@ -728,14 +728,13 @@ public abstract class VanillaChronicleHash= 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 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(); } diff --git a/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java b/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java index 831a77ac2..7329d2c0d 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java @@ -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); }