package com.sleepycat.je.txn; public class Txn { private Set deletedDatabases; /** * @param dbImpl databaseImpl to remove * @param deleteAtCommit true if this databaseImpl should be cleaned on * commit, false if it should be cleaned on abort. * @param mb environment memory budget. */ public void markDeleteAtTxnEnd( DatabaseImpl dbImpl, boolean deleteAtCommit) throws DatabaseException { new Txn_markDeleteAtTxnEnd(this,dbImpl,deleteAtCommit).execute(); } private void setDeletedDatabaseState( boolean isCommit) throws DatabaseException { if (deletedDatabases != null) { Iterator iter=deletedDatabases.iterator(); while (iter.hasNext()) { DatabaseCleanupInfo info=(DatabaseCleanupInfo)iter.next(); if (info.deleteAtCommit == isCommit) { info.dbImpl.startDeleteProcessing(); } } } } /** * Cleanup leftover databaseImpls that are a by-product of database * operations like removeDatabase(), truncateDatabase(). * This method must be called outside the synchronization on this txn, * because it calls deleteAndReleaseINs, which gets the TxnManager's * allTxns latch. The checkpointer also gets the allTxns latch, and within * that latch, needs to synchronize on individual txns, so we must avoid a * latching hiearchy conflict. */ private void cleanupDatabaseImpls( boolean isCommit) throws DatabaseException { if (deletedDatabases != null) { DatabaseCleanupInfo[] infoArray; synchronized (this) { infoArray=new DatabaseCleanupInfo[deletedDatabases.size()]; deletedDatabases.toArray(infoArray); } for (int i=0; i < infoArray.length; i+=1) { DatabaseCleanupInfo info=infoArray[i]; if (info.deleteAtCommit == isCommit) { info.dbImpl.releaseDeletedINs(); } } deletedDatabases=null; } } protected void hook805() throws DatabaseException, RunRecoveryException, Throwable { cleanupDatabaseImpls(true); original(); } protected void hook806() throws DatabaseException, RunRecoveryException, Throwable { setDeletedDatabaseState(true); original(); } protected void hook807() throws DatabaseException { cleanupDatabaseImpls(false); original(); } protected void hook808() throws DatabaseException { setDeletedDatabaseState(false); original(); } @MethodObject static class Txn_markDeleteAtTxnEnd { Txn_markDeleteAtTxnEnd( Txn _this, DatabaseImpl dbImpl, boolean deleteAtCommit){ this._this=_this; this.dbImpl=dbImpl; this.deleteAtCommit=deleteAtCommit; } void execute() throws DatabaseException { synchronized (_this) { this.hook797(); if (_this.deletedDatabases == null) { _this.deletedDatabases=new HashSet(); this.hook798(); } _this.deletedDatabases.add(new DatabaseCleanupInfo(dbImpl,deleteAtCommit)); this.hook796(); } } protected Txn _this; protected DatabaseImpl dbImpl; protected boolean deleteAtCommit; protected int delta; protected void hook796() throws DatabaseException { } protected void hook797() throws DatabaseException { } protected void hook798() throws DatabaseException { } } }