/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.github.geophile.erdo.map.diskmap.tree; import com.github.geophile.erdo.map.LazyRecord; import com.github.geophile.erdo.map.diskmap.IndexRecord; import com.github.geophile.erdo.segmentfilemanager.AbstractSegmentFileManager; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; class WriteableTreeLevel extends TreeLevel { IndexRecord append(LazyRecord record) throws IOException, InterruptedException { WriteableTreeSegment lastSegment = (WriteableTreeSegment) lastSegment(); IndexRecord indexRecord = lastSegment.append(record); if (indexRecord != null && lastSegment.isLastPage(indexRecord.childPageAddress())) { lastSegment = newSegment(); segments.add(lastSegment); IndexRecord newSegmentIndexRecord = lastSegment.append(record); assert newSegmentIndexRecord == null : record; } return indexRecord; } public IndexRecord finalizeRightEdge() throws IOException, InterruptedException { return finalizeLastSegment(); } public IndexRecord closeCurrentLeafSegment() throws IOException, InterruptedException { assert level == 0 : this; return finalizeLastSegment(); } public void startNewLeafSegment() { assert level == 0 : this; segments.add(newSegment()); } public int linkIn(LevelOneMultiRecord multiRecord) { LOG.log(Level.INFO, "{0}: Linking in {1}", new Object[]{this, multiRecord}); TreeSegment lastSegment = super.lastSegment(); TreeSegment sharedSegmentOriginal = multiRecord.leafSegment(); int segmentNumber; if (lastSegment.leafRecords() == 0) { // We're linking in a segment, but the current last segment is empty. // Remove the last segment so that it will be replaced by the shared segment. segmentNumber = lastSegment.segmentNumber(); segments.remove(segmentNumber); } else { segmentNumber = segments(); } TreeSegment sharedSegmentCopy = TreeSegment.share(this, segmentNumber, sharedSegmentOriginal); segments.add(sharedSegmentCopy); AbstractSegmentFileManager segmentFileManager = tree.factory().segmentFileManager(); long segmentId = sharedSegmentCopy.segmentId(); long treeId = tree.treeId(); segmentFileManager.register(tree.dbStructure().segmentFile(segmentId), treeId, segmentId); return tree.pageAddress(sharedSegmentCopy.segmentNumber(), 0); } public static WriteableTreeLevel create(Tree tree, int levelNumber) { WriteableTreeLevel level = new WriteableTreeLevel(tree, levelNumber); level.segments.add(level.newSegment()); return level; } // For use by this package WriteableTreeSegment newSegment() { return new WriteableTreeSegment(this, segments.size(), tree.factory().segmentFileManager().newSegmentId()); } // For use by this class private IndexRecord finalizeLastSegment() throws IOException, InterruptedException { TreeSegment lastSegment = lastSegment(); return lastSegment.isOpen() ? ((WriteableTreeSegment) lastSegment).finalizeRightEdge() : null; } private WriteableTreeLevel(Tree tree, int level) { super(tree, level); } // Class state private static final Logger LOG = Logger.getLogger(WriteableTreeLevel.class.getName()); }