PatriciaTreeMutable( @NotNull final Log log, final int structureId, final long treeSize, @NotNull final ImmutableNode immutableRoot) { super(log, structureId); size = treeSize; root = new MutableRoot(immutableRoot); expiredLoggables = null; addExpiredLoggable(immutableRoot.getAddress()); // TODO: don't re-read }
@Override public boolean reclaim( @NotNull RandomAccessLoggable loggable, @NotNull final Iterator<RandomAccessLoggable> loggables) { long minAddress = loggable.getAddress(); while (true) { final byte type = loggable.getType(); if (type < NODE_WO_KEY_WO_VALUE_WO_CHILDREN || type > MAX_VALID_LOGGABLE_TYPE) { if (type != NullLoggable.TYPE) { // skip null loggable throw new ExodusException("Unexpected loggable type " + loggable.getType()); } } else { if (loggable.getStructureId() != structureId) { throw new ExodusException("Unexpected structure id " + loggable.getStructureId()); } if (PatriciaTreeBase.nodeIsRoot(type)) { break; } } if (!loggables.hasNext()) { return false; } loggable = loggables.next(); } final long maxAddress = loggable.getAddress(); final PatriciaTreeForReclaim sourceTree = new PatriciaTreeForReclaim(log, maxAddress, structureId); final ImmutableNode sourceRoot = sourceTree.getRoot(); final long backRef = sourceTree.getBackRef(); if (backRef > 0) { final long treeStartAddress = sourceTree.getRootAddress() - backRef; if (treeStartAddress > minAddress) { throw new IllegalStateException("Wrong back reference!"); } if (!log.hasAddressRange(treeStartAddress, maxAddress)) { return false; } minAddress = treeStartAddress; } final PatriciaReclaimActualTraverser actual = new PatriciaReclaimActualTraverser(this); reclaim(new PatriciaReclaimSourceTraverser(sourceTree, sourceRoot, minAddress), actual); return actual.wasReclaim || sourceRoot.getAddress() == root.sourceAddress; }
MutableNode mutateNode(@NotNull final ImmutableNode node) { addExpiredLoggable(node.getAddress()); // TODO: don't re-read return new MutableNode(node); }