/** Flush the target IN. */ private void flushIN( IN target, LogManager logManager, Map dirtyMap, boolean logProvisionally, boolean allowDeltas) throws DatabaseException { DatabaseImpl db = target.getDatabase(); Tree tree = db.getTree(); boolean targetWasRoot = false; if (target.isDbRoot()) { /* We're trying to flush the root. */ target.releaseLatch(); RootFlusher flusher = new RootFlusher(db, logManager, target); tree.withRootLatched(flusher); boolean flushed = flusher.getFlushed(); /* * We have to check if the root split between target.releaseLatch * and the execution of the root flusher. If it did split, this * target has to get handled like a regular node. */ targetWasRoot = flusher.stillRoot(); /* * Update the tree's owner, whether it's the env root or the * dbmapping tree. */ if (flushed) { DbTree dbTree = db.getDbEnvironment().getDbMapTree(); dbTree.modifyDbRoot(db); nFullINFlushThisRun++; nFullINFlush++; } if (!targetWasRoot) { /* * re-latch for another attempt, now that this is no longer * the root. */ target.latch(); } } if (!targetWasRoot) { SearchResult result = tree.getParentINForChildIN(target, true); /* * Found a parent, do the flush. If no parent found, the * compressor deleted this item before we got to processing it. */ if (result.exactParentFound) { try { ChildReference entry = result.parent.getEntry(result.index); IN renewedTarget = (IN) entry.fetchTarget(db, result.parent); renewedTarget.latch(); DbLsn newLsn = null; try { /* Still dirty? */ if (renewedTarget.getDirty()) { if (allowDeltas) { newLsn = renewedTarget.logAllowDeltas(logManager, logProvisionally); if (newLsn == null) { nDeltaINFlushThisRun++; nDeltaINFlush++; } } else { newLsn = renewedTarget.log(logManager, logProvisionally); } } } finally { renewedTarget.releaseLatch(); } /* Update parent if logging occurred */ if (newLsn != null) { nFullINFlushThisRun++; nFullINFlush++; if (renewedTarget instanceof BIN) { nFullBINFlush++; } result.parent.updateEntry(result.index, newLsn); addToDirtyMap(dirtyMap, result.parent); } } finally { result.parent.releaseLatch(); } } } }