@Stage("Segment") public long allocReturnCode(int chunks) { VanillaChronicleHash<?, ?, ?, ?> h = hh.h(); if (chunks > h.maxChunksPerEntry) { throw new IllegalArgumentException( "Entry is too large: requires " + chunks + " chucks, " + h.maxChunksPerEntry + " is maximum."); } long lowestPossiblyFreeChunk = lowestPossiblyFreeChunk(); if (lowestPossiblyFreeChunk + chunks > h.actualChunksPerSegmentTier) return -1; if (tierEntries() >= h.maxEntriesPerHashLookup) return -1; assert lowestPossiblyFreeChunk < h.actualChunksPerSegmentTier; long ret = freeList.setNextNContinuousClearBits(lowestPossiblyFreeChunk, chunks); if (ret == NOT_FOUND || ret + chunks > h.actualChunksPerSegmentTier) { if (ret + chunks > h.actualChunksPerSegmentTier) { assert ret != NOT_FOUND; freeList.clearRange(ret, ret + chunks); } return -1; } else { tierEntries(tierEntries() + 1); // if bit at lowestPossiblyFreeChunk is clear, it was skipped because // more than 1 chunk was requested. Don't move lowestPossiblyFreeChunk // in this case. chunks == 1 clause is just a fast path. if (chunks == 1 || freeList.isSet(lowestPossiblyFreeChunk)) { lowestPossiblyFreeChunk(ret + chunks); } return ret; } }
@Stage("Segment") public boolean realloc(long fromPos, int oldChunks, int newChunks) { if (fromPos + newChunks < hh.h().actualChunksPerSegmentTier && freeList.isRangeClear(fromPos + oldChunks, fromPos + newChunks)) { freeList.setRange(fromPos + oldChunks, fromPos + newChunks); // checking and updating lowestPossiblyFreeChunk is omitted because adds computational // complexity for seemingly very small gain return true; } else { return false; } }
void initSegment() { VanillaChronicleHash<?, ?, ?, ?> h = hh.h(); long segmentBaseAddr = this.tierBaseAddr; segmentBS.set(segmentBaseAddr, h.tierSize); segmentBytes.clear(); long freeListOffset = h.tierHashLookupOuterSize + TIER_COUNTERS_AREA_SIZE; freeList.setOffset(segmentBaseAddr + freeListOffset); entrySpaceOffset = freeListOffset + h.tierFreeListOuterSize + h.tierEntrySpaceInnerOffset; }
@Stage("Segment") public void freeExtra(long pos, int oldChunks, int newChunks) { long from = pos + newChunks; freeList.clearRange(from, pos + oldChunks); if (from < lowestPossiblyFreeChunk()) lowestPossiblyFreeChunk(from); }
@Stage("Segment") public void free(long fromPos, int chunks) { tierEntries(tierEntries() - 1); freeList.clearRange(fromPos, fromPos + chunks); if (fromPos < lowestPossiblyFreeChunk()) lowestPossiblyFreeChunk(fromPos); }