/** Preload all dup DBs to be converted. */ private void preloadAllDatabases() { final ArrayList<DatabaseImpl> dbsToConvert = new ArrayList<DatabaseImpl>(); try { for (DatabaseId dbId : dbTree.getDbNamesAndIds().keySet()) { final DatabaseImpl dbImpl = dbTree.getDb(dbId); boolean releaseDbImpl = true; try { if (!needsConversion(dbImpl)) { continue; } dbsToConvert.add(dbImpl); releaseDbImpl = false; } finally { if (releaseDbImpl) { dbTree.releaseDb(dbImpl); } } } if (dbsToConvert.size() == 0) { return; } final DatabaseImpl[] dbArray = new DatabaseImpl[dbsToConvert.size()]; dbsToConvert.toArray(dbArray); envImpl.preload(dbArray, preloadConfig); } finally { for (DatabaseImpl dbImpl : dbsToConvert) { dbTree.releaseDb(dbImpl); } } }
/** Set the mapping tree from the log. Called during recovery. */ public void readMapTreeFromLog(long rootLsn) throws DatabaseException { dbMapTree = (DbTree) logManager.get(rootLsn); dbMapTree.setEnvironmentImpl(this); /* Set the map tree root */ mapTreeRootLsn = rootLsn; }
/** Converts all dup DBs that need conversion. */ public void convertDatabases() { if (DEBUG) { System.out.println("DupConvert.convertDatabases"); } if (preloadAll) { preloadAllDatabases(); } for (DatabaseId dbId : dbTree.getDbNamesAndIds().keySet()) { final DatabaseImpl dbImpl = dbTree.getDb(dbId); try { if (!needsConversion(dbImpl)) { continue; } convertDatabase(dbImpl); } finally { dbTree.releaseDb(dbImpl); } } assert noDupNodesPresent(); }
/** Rename a database. */ public void dbRename(Locker locker, String databaseName, String newName) throws DatabaseException { dbMapTree.dbRename(locker, databaseName, newName); }
/** For debugging. */ public void dumpMapTree() throws DatabaseException { dbMapTree.dump(); }
public List getDbNames() throws DatabaseException { return dbMapTree.getDbNames(); }
/** * Get a database object given a database name. * * @param databaseName target database. * @return null if database doesn't exist. */ public DatabaseImpl getDb(Locker locker, String databaseName, Database databaseHandle) throws DatabaseException { return dbMapTree.getDb(locker, databaseName, databaseHandle); }
/* DatabaseImpl access. */ public DatabaseImpl createDb( Locker locker, String databaseName, DatabaseConfig dbConfig, Database databaseHandle) throws DatabaseException { return dbMapTree.createDb(locker, databaseName, dbConfig, databaseHandle); }
/** 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(); } } } }