[freenet-cvs] r14749 - in trunk/contrib/bdb: . dist src/com/sleepycat/bind/serial src/com/sleepycat/bind/tuple src/com/sleepycat/collections src/com/sleepycat/je src/com/sleepycat/je/cleaner src/com/sleepycat/je/config src/com/sleepycat/je/dbi src/com/sleepycat/je/evictor src/com/sleepycat/je/incomp src/com/sleepycat/je/jca/ra src/com/sleepycat/je/log src/com/sleepycat/je/recovery src/com/sleepycat/je/tree src/com/sleepycat/je/txn src/com/sleepycat/je/util src/com/sleepycat/je/utilint src/com/sleepycat/persist src/com/sleepycat/persist/impl src/com/sleepycat/persist/model test test/com/sleepycat/collections/test test/com/sleepycat/je test/com/sleepycat/je/cleaner test/com/sleepycat/je/dbi test/com/sleepycat/je/evictor test/com/sleepycat/je/test test/com/sleepycat/je/tree test/com/sleepycat/je/txn test/com/sleepycat/persist/test
nextgens at freenetproject.org
nextgens at freenetproject.org
Fri Aug 17 14:14:29 UTC 2007
Author: nextgens
Date: 2007-08-17 14:14:29 +0000 (Fri, 17 Aug 2007)
New Revision: 14749
Modified:
trunk/contrib/bdb/README
trunk/contrib/bdb/build.properties
trunk/contrib/bdb/build.xml
trunk/contrib/bdb/dist/build.properties
trunk/contrib/bdb/example.properties
trunk/contrib/bdb/src/com/sleepycat/bind/serial/SerialBinding.java
trunk/contrib/bdb/src/com/sleepycat/bind/tuple/TupleTupleMarshalledKeyCreator.java
trunk/contrib/bdb/src/com/sleepycat/collections/CurrentTransaction.java
trunk/contrib/bdb/src/com/sleepycat/collections/TransactionRunner.java
trunk/contrib/bdb/src/com/sleepycat/je/Cursor.java
trunk/contrib/bdb/src/com/sleepycat/je/Database.java
trunk/contrib/bdb/src/com/sleepycat/je/Environment.java
trunk/contrib/bdb/src/com/sleepycat/je/EnvironmentStats.java
trunk/contrib/bdb/src/com/sleepycat/je/JEVersion.java
trunk/contrib/bdb/src/com/sleepycat/je/SecondaryCursor.java
trunk/contrib/bdb/src/com/sleepycat/je/cleaner/Cleaner.java
trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileProcessor.java
trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileSelector.java
trunk/contrib/bdb/src/com/sleepycat/je/cleaner/TrackedFileSummary.java
trunk/contrib/bdb/src/com/sleepycat/je/cleaner/UtilizationProfile.java
trunk/contrib/bdb/src/com/sleepycat/je/config/BooleanConfigParam.java
trunk/contrib/bdb/src/com/sleepycat/je/config/EnvironmentParams.java
trunk/contrib/bdb/src/com/sleepycat/je/dbi/CursorImpl.java
trunk/contrib/bdb/src/com/sleepycat/je/dbi/DatabaseImpl.java
trunk/contrib/bdb/src/com/sleepycat/je/dbi/DbTree.java
trunk/contrib/bdb/src/com/sleepycat/je/dbi/EnvironmentImpl.java
trunk/contrib/bdb/src/com/sleepycat/je/dbi/GetMode.java
trunk/contrib/bdb/src/com/sleepycat/je/dbi/MemoryBudget.java
trunk/contrib/bdb/src/com/sleepycat/je/dbi/SortedLSNTreeWalker.java
trunk/contrib/bdb/src/com/sleepycat/je/evictor/Evictor.java
trunk/contrib/bdb/src/com/sleepycat/je/incomp/INCompressor.java
trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEConnection.java
trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnection.java
trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnectionFactory.java
trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/ra.xml
trunk/contrib/bdb/src/com/sleepycat/je/log/FileReader.java
trunk/contrib/bdb/src/com/sleepycat/je/log/INFileReader.java
trunk/contrib/bdb/src/com/sleepycat/je/log/LatchedLogManager.java
trunk/contrib/bdb/src/com/sleepycat/je/log/LogManager.java
trunk/contrib/bdb/src/com/sleepycat/je/log/StatsFileReader.java
trunk/contrib/bdb/src/com/sleepycat/je/log/SyncedLogManager.java
trunk/contrib/bdb/src/com/sleepycat/je/recovery/Checkpointer.java
trunk/contrib/bdb/src/com/sleepycat/je/recovery/RecoveryManager.java
trunk/contrib/bdb/src/com/sleepycat/je/tree/BIN.java
trunk/contrib/bdb/src/com/sleepycat/je/tree/BINDelta.java
trunk/contrib/bdb/src/com/sleepycat/je/tree/DBIN.java
trunk/contrib/bdb/src/com/sleepycat/je/tree/IN.java
trunk/contrib/bdb/src/com/sleepycat/je/tree/LN.java
trunk/contrib/bdb/src/com/sleepycat/je/tree/MapLN.java
trunk/contrib/bdb/src/com/sleepycat/je/tree/Tree.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/BasicLocker.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/DummyLockManager.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/LatchedLockManager.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/Lock.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/LockInfo.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/LockManager.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/Locker.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/ReadCommittedLocker.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/SyncedLockManager.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/ThreadLocker.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/Txn.java
trunk/contrib/bdb/src/com/sleepycat/je/txn/WriteLockInfo.java
trunk/contrib/bdb/src/com/sleepycat/je/util/DbVerify.java
trunk/contrib/bdb/src/com/sleepycat/je/utilint/VLSN.java
trunk/contrib/bdb/src/com/sleepycat/persist/StoreConfig.java
trunk/contrib/bdb/src/com/sleepycat/persist/impl/PersistCatalog.java
trunk/contrib/bdb/src/com/sleepycat/persist/impl/PersistEntityBinding.java
trunk/contrib/bdb/src/com/sleepycat/persist/impl/SimpleCatalog.java
trunk/contrib/bdb/src/com/sleepycat/persist/impl/Store.java
trunk/contrib/bdb/src/com/sleepycat/persist/model/AnnotationModel.java
trunk/contrib/bdb/src/com/sleepycat/persist/model/EntityModel.java
trunk/contrib/bdb/test/com/sleepycat/collections/test/TransactionTest.java
trunk/contrib/bdb/test/com/sleepycat/je/DatabaseTest.java
trunk/contrib/bdb/test/com/sleepycat/je/EnvironmentTest.java
trunk/contrib/bdb/test/com/sleepycat/je/RunRecoveryFailureTest.java
trunk/contrib/bdb/test/com/sleepycat/je/cleaner/CleanerTest.java
trunk/contrib/bdb/test/com/sleepycat/je/cleaner/TruncateAndRemoveTest.java
trunk/contrib/bdb/test/com/sleepycat/je/dbi/DbCursorDuplicateTest.java
trunk/contrib/bdb/test/com/sleepycat/je/dbi/DbCursorTestBase.java
trunk/contrib/bdb/test/com/sleepycat/je/evictor/EvictActionTest.java
trunk/contrib/bdb/test/com/sleepycat/je/evictor/EvictSelectionTest.java
trunk/contrib/bdb/test/com/sleepycat/je/test/DeferredWriteTest.java
trunk/contrib/bdb/test/com/sleepycat/je/test/SecondaryTest.java
trunk/contrib/bdb/test/com/sleepycat/je/tree/MemorySizeTest.java
trunk/contrib/bdb/test/com/sleepycat/je/txn/LockManagerTest.java
trunk/contrib/bdb/test/com/sleepycat/je/txn/LockTest.java
trunk/contrib/bdb/test/com/sleepycat/persist/test/EvolveClasses.java
trunk/contrib/bdb/test/com/sleepycat/persist/test/OperationTest.java
trunk/contrib/bdb/test/je.properties
Log:
freenet-ext: update bdb : je-3.2.23 -> je-3.2.42 (http://download.oracle.com/berkeley-db/je-3.2.42.tar.gz)
Modified: trunk/contrib/bdb/README
===================================================================
--- trunk/contrib/bdb/README 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/README 2007-08-17 14:14:29 UTC (rev 14749)
@@ -1,5 +1,5 @@
-Oracle: Berkeley DB, Java Edition 3.2.23: April 06, 2007
+Oracle: Berkeley DB, Java Edition 3.2.42: August 08, 2007
-This is Berkeley DB, Java Edition, version 3.2.23 from
+This is Berkeley DB, Java Edition, version 3.2.42 from
Oracle. To view the release and installation documentation, load
the distribution file docs/index.html into your web browser.
\ No newline at end of file
Modified: trunk/contrib/bdb/build.properties
===================================================================
--- trunk/contrib/bdb/build.properties 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/build.properties 2007-08-17 14:14:29 UTC (rev 14749)
@@ -8,6 +8,9 @@
# Typical j2ee jar for Sun Java Application Server
#j2ee.jarfile = c:/j2ee1.4AppServer/lib/j2ee.jar
+# Typical j2ee jar for OC4J
+#j2ee.jarfile = <OC4J-HOME>/oc4j/j2ee/home/lib/ejb.jar:<OC4J-HOME>/oc4j/j2ee/home/lib/connector.jar:<OC4J-HOME>/oc4j/j2ee/home/lib/oc4j-internal.jar
+
##########################################################################
# Set example.resources to run the JCA examples.
##########################################################################
@@ -15,6 +18,8 @@
#example.resources = c:/j2ee1.4AppServer/lib/appserv-rt.jar
# JBOSS
#example.resources = <jehome>/examples/resources/jboss
+# OC4J
+#example.resources = <OC4J-HOME>/je/examples/resources/oc4j/oc4j.jar
##########################################################################
# Set example.jca.srcdir to run the JCA examples.
@@ -23,6 +28,8 @@
#example.jca.srcdir = <jehome>/examples/jca/jboss
# SJSAS
#example.jca.srcdir = <jehome>/examples/jca/sjsas8_1
+# OC4J
+#example.jca.srcdir = <OC4J-HOME>/je/examples/jca/oc4j
##########################################################################
# Set example.jca.descriptorname to run the JCA examples.
@@ -31,3 +38,5 @@
#example.jca.descriptorname = jboss.xml
# SJSAS
#example.jca.descriptorname = sun-ejb-jar.xml
+# OC4J
+#example.jca.descriptorname = orion-ejb-jar.xml
Modified: trunk/contrib/bdb/build.xml
===================================================================
--- trunk/contrib/bdb/build.xml 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/build.xml 2007-08-17 14:14:29 UTC (rev 14749)
@@ -391,7 +391,7 @@
includes="bin/**,lib/**,dist/build.properties"/>
<zip basedir="${basedir}"
destfile="src.zip"
- excludes="test/rpcserver/**,test/experiments/**,test/regress/*/**,test/**/MiniStress.java,test/**/AbortStress.java,dist/,**/jca/README.txt,examples/com/**,src/com/sleepycat/je/rep/**,examples/je/rep/**,test/com/sleepycat/je/rep/**"
+ excludes="test/rpcserver/**,test/experiments/**,test/standalone/**,test/regress/*/**,test/**/MiniStress.java,test/**/AbortStress.java,dist/,**/jca/README.txt,examples/com/**,src/com/sleepycat/je/rep/**,examples/je/rep/**,test/com/sleepycat/je/rep/**"
includes="src/**,examples/**,test/**,docs/**,ant/**,regress/,build.xml,build.properties,example.properties,README,LICENSE,FindBugsExclude.xml"/>
<zip basedir="${basedir}"
destfile="${zipfile}"
Modified: trunk/contrib/bdb/dist/build.properties
===================================================================
--- trunk/contrib/bdb/dist/build.properties 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/dist/build.properties 2007-08-17 14:14:29 UTC (rev 14749)
@@ -1,4 +1,4 @@
-release.version=3.2.23
-release.numeric.version=3.2.23
+release.version=3.2.42
+release.numeric.version=3.2.42
release.major=3
release.minor=2
Modified: trunk/contrib/bdb/example.properties
===================================================================
--- trunk/contrib/bdb/example.properties 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/example.properties 2007-08-17 14:14:29 UTC (rev 14749)
@@ -297,6 +297,13 @@
# je.env.checkLeaks=true
# (mutable at run time: false)
+# *** Experimental and not fully tested in 3.2.x. ***
+# If true, enable eviction of metadata for closed databases.
+# The default for JE 3.2.x is false but will be changed to true
+# in JE 3.3 and above.
+# je.env.dbEviction=false
+# (mutable at run time: false)
+
# If true, use latches instead of synchronized blocks to
# implement the lock table and log write mutexes. Latches require
# that threads queue to obtain the mutex in question and
Modified: trunk/contrib/bdb/src/com/sleepycat/bind/serial/SerialBinding.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/bind/serial/SerialBinding.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/bind/serial/SerialBinding.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000,2007 Oracle. All rights reserved.
*
- * $Id: SerialBinding.java,v 1.28.2.1 2007/02/01 14:49:38 cwl Exp $
+ * $Id: SerialBinding.java,v 1.28.2.3 2007/06/13 23:01:40 mark Exp $
*/
package com.sleepycat.bind.serial;
@@ -76,15 +76,14 @@
/**
* Returns the class loader to be used during deserialization, or null if
* a default class loader should be used. The default implementation of
- * this method returns null.
+ * this method returns
+ * <code>Thread.currentThread().getContextClassLoader()</code> to use the
+ * context class loader for the current thread.
*
* <p>This method may be overriden to return a dynamically determined class
- * loader. For example,
- * <code>Thread.currentThread().getContextClassLoader()</code> could be
- * called to use the context class loader for the curren thread. Or
- * <code>getBaseClass().getClassLoader()</code> could be called to use the
- * class loader for the base class, assuming that a base class has been
- * specified.</p>
+ * loader. For example, <code>getBaseClass().getClassLoader()</code> could
+ * be called to use the class loader for the base class, assuming that a
+ * base class has been specified.</p>
*
* <p>If this method returns null, a default class loader will be used as
* determined by the <code>java.io.ObjectInputStream.resolveClass</code>
@@ -92,7 +91,7 @@
*/
public ClassLoader getClassLoader() {
- return null;
+ return Thread.currentThread().getContextClassLoader();
}
/**
Modified: trunk/contrib/bdb/src/com/sleepycat/bind/tuple/TupleTupleMarshalledKeyCreator.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/bind/tuple/TupleTupleMarshalledKeyCreator.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/bind/tuple/TupleTupleMarshalledKeyCreator.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000,2007 Oracle. All rights reserved.
*
- * $Id: TupleTupleMarshalledKeyCreator.java,v 1.27.2.1 2007/02/01 14:49:39 cwl Exp $
+ * $Id: TupleTupleMarshalledKeyCreator.java,v 1.27.2.2 2007/06/01 21:32:54 mark Exp $
*/
package com.sleepycat.bind.tuple;
@@ -61,7 +61,6 @@
public boolean nullifyForeignKey(TupleInput dataInput,
TupleOutput dataOutput) {
- // XXX null primary key input below may be unexpected by the binding
MarshalledTupleKeyEntity entity = (MarshalledTupleKeyEntity)
binding.entryToObject(null, dataInput);
if (entity.nullifyForeignKey(keyName)) {
Modified: trunk/contrib/bdb/src/com/sleepycat/collections/CurrentTransaction.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/collections/CurrentTransaction.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/collections/CurrentTransaction.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,11 +3,12 @@
*
* Copyright (c) 2000,2007 Oracle. All rights reserved.
*
- * $Id: CurrentTransaction.java,v 1.46.2.1 2007/02/01 14:49:39 cwl Exp $
+ * $Id: CurrentTransaction.java,v 1.46.2.2 2007/04/12 16:13:16 mark Exp $
*/
package com.sleepycat.collections;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
@@ -71,10 +72,14 @@
*/
static CurrentTransaction getInstanceInternal(Environment env) {
synchronized (envMap) {
- CurrentTransaction myEnv = (CurrentTransaction) envMap.get(env);
+ CurrentTransaction myEnv = null;
+ WeakReference myEnvRef = (WeakReference) envMap.get(env);
+ if (myEnvRef != null) {
+ myEnv = (CurrentTransaction) myEnvRef.get();
+ }
if (myEnv == null) {
myEnv = new CurrentTransaction(env);
- envMap.put(env, myEnv);
+ envMap.put(env, new WeakReference(myEnv));
}
return myEnv;
}
Modified: trunk/contrib/bdb/src/com/sleepycat/collections/TransactionRunner.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/collections/TransactionRunner.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/collections/TransactionRunner.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000,2007 Oracle. All rights reserved.
*
- * $Id: TransactionRunner.java,v 1.44.2.1 2007/02/01 14:49:40 cwl Exp $
+ * $Id: TransactionRunner.java,v 1.44.2.3 2007/06/01 22:26:53 mark Exp $
*/
package com.sleepycat.collections;
@@ -239,9 +239,9 @@
} catch (Throwable e2) {
/*
- * XXX We should really throw a 3rd exception that
- * wraps both e and e2, to give the user a complete
- * set of error information.
+ * We print this stack trace so that the
+ * information is not lost when we throw the
+ * original exception.
*/
if (DbCompat.TRANSACTION_RUNNER_PRINT_STACK_TRACES) {
e2.printStackTrace();
Modified: trunk/contrib/bdb/src/com/sleepycat/je/Cursor.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/Cursor.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/Cursor.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: Cursor.java,v 1.202.2.1 2007/02/01 14:49:41 cwl Exp $
+ * $Id: Cursor.java,v 1.202.2.2 2007/06/13 21:22:17 mark Exp $
*/
package com.sleepycat.je;
@@ -244,12 +244,22 @@
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
- public synchronized void close()
+ public void close()
throws DatabaseException {
+ close(true /*releaseNonTxnLocks*/);
+ }
+
+ /**
+ * @param releaseNonTxnLocks should normally be true. See
+ * CursorImpl.close(boolean) [#15573]
+ */
+ synchronized void close(boolean releaseNonTxnLocks)
+ throws DatabaseException {
+
try {
checkState(false);
- cursorImpl.close();
+ cursorImpl.close(releaseNonTxnLocks);
if (dbHandle != null) {
dbHandle.removeCursor(this);
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/Database.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/Database.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/Database.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: Database.java,v 1.216.2.1 2007/02/01 14:49:41 cwl Exp $
+ * $Id: Database.java,v 1.216.2.2 2007/07/02 19:54:48 mark Exp $
*/
package com.sleepycat.je;
@@ -280,6 +280,7 @@
if (databaseImpl != null) {
databaseImpl.removeReferringHandle(this);
+ envHandle.getEnvironmentImpl().releaseDb(databaseImpl);
databaseImpl = null;
/*
@@ -1105,6 +1106,14 @@
envHandle.removeReferringHandle(this);
if (databaseImpl != null) {
databaseImpl.removeReferringHandle(this);
+ envHandle.getEnvironmentImpl().releaseDb(databaseImpl);
+
+ /*
+ * Database.close may be called after an abort. By setting the
+ * databaseImpl field to null we ensure that close won't call
+ * releaseDb or endOperation. [#13415]
+ */
+ databaseImpl = null;
}
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/Environment.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/Environment.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/Environment.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: Environment.java,v 1.179.2.1 2007/02/01 14:49:41 cwl Exp $
+ * $Id: Environment.java,v 1.179.2.2 2007/07/02 19:54:48 mark Exp $
*/
package com.sleepycat.je;
@@ -402,6 +402,7 @@
validateDbConfigAgainstEnv(dbConfig, databaseName);
Locker locker = null;
+ DatabaseImpl database = null;
boolean operationOk = false;
boolean dbIsClosing = false;
try {
@@ -434,12 +435,9 @@
locker.isTransactional();
}
- DatabaseImpl database = environmentImpl.getDb(locker,
- databaseName,
- newDb);
+ database = environmentImpl.getDb(locker, databaseName, newDb);
boolean databaseExists =
- (database == null) ? false :
- ((database.isDeleted()) ? false : true);
+ (database != null) && !database.isDeleted();
if (databaseExists) {
if (dbConfig.getAllowCreate() &&
@@ -452,6 +450,10 @@
newDb.initExisting(this, locker, database, dbConfig);
} else {
+ /* Release deleted DB. [#13415] */
+ environmentImpl.releaseDb(database);
+ database = null;
+
/* No database. Create if we're allowed to. */
if (dbConfig.getAllowCreate()) {
@@ -493,6 +495,18 @@
locker.setHandleLockOwner(operationOk, newDb, dbIsClosing);
locker.operationEnd(operationOk);
}
+
+ /*
+ * Normally releaseDb will be called when the DB is closed, or by
+ * abort if a transaction is used, or by setHandleLockOwner if a
+ * non-transactional locker is used. But when the open operation
+ * fails and the Database.databaseImpl field was not initialized,
+ * we must call releaseDb here. [#13415]
+ */
+ if ((!operationOk || dbIsClosing) &&
+ newDb.getDatabaseImpl() == null) {
+ environmentImpl.releaseDb(database);
+ }
}
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/EnvironmentStats.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/EnvironmentStats.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/EnvironmentStats.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,12 +3,13 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: EnvironmentStats.java,v 1.43.2.1 2007/02/01 14:49:41 cwl Exp $
+ * $Id: EnvironmentStats.java,v 1.43.2.3 2007/05/23 20:31:05 mark Exp $
*/
package com.sleepycat.je;
import java.io.Serializable;
+import java.text.DecimalFormat;
import com.sleepycat.je.utilint.DbLsn;
@@ -241,6 +242,10 @@
private int nLogBuffers; // number of existing log buffers
private long bufferBytes; // cache consumed by the log buffers,
// in bytes
+ private long adminBytes; // part of cache used by transactions,
+ // log cleaning metadata, and other
+ // administrative structures
+ private long lockBytes; // part of cache used by locks
/*
* Log activity
@@ -271,6 +276,11 @@
* chunk size controlled by je.log.iteratorReadSize is too small.
*/
private long nRepeatIteratorReads;
+
+ /*
+ * Approximation of the total log size in bytes.
+ */
+ private long totalLogSize;
/**
* Internal use only.
@@ -344,6 +354,7 @@
nRepeatFaultReads = 0;
nTempBufferWrites = 0;
nRepeatIteratorReads = 0;
+ totalLogSize = 0;
}
/**
@@ -699,6 +710,23 @@
}
/**
+ * The number of bytes of JE cache used for holding transaction objects,
+ * log cleaning metadata, and other administrative structures. This is a
+ * subset of cacheDataBytes.
+ */
+ public long getAdminBytes() {
+ return adminBytes;
+ }
+
+ /**
+ * The number of bytes of JE cache used for holding lock objects.
+ * This is a subset of cacheDataBytes.
+ */
+ public long getLockBytes() {
+ return lockBytes;
+ }
+
+ /**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
@@ -750,6 +778,14 @@
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
+ public long getTotalLogSize() {
+ return totalLogSize;
+ }
+
+ /**
+ * Javadoc for this public method is generated via
+ * the doc templates in the doc_src directory.
+ */
public int getSplitBins() {
return splitBins;
}
@@ -764,6 +800,20 @@
/**
* Internal use only.
*/
+ public void setAdminBytes(long adminBytes) {
+ this.adminBytes = adminBytes;
+ }
+
+ /**
+ * Internal use only.
+ */
+ public void setLockBytes(long lockBytes) {
+ this.lockBytes = lockBytes;
+ }
+
+ /**
+ * Internal use only.
+ */
public void setNNotResident(long nNotResident) {
this.nNotResident = nNotResident;
}
@@ -1100,6 +1150,13 @@
/**
* Internal use only.
*/
+ public void setTotalLogSize(long val) {
+ totalLogSize = val;
+ }
+
+ /**
+ * Internal use only.
+ */
public void setSplitBins(int val) {
splitBins = val;
}
@@ -1109,79 +1166,109 @@
* the doc templates in the doc_src directory.
*/
public String toString() {
+ DecimalFormat f = new DecimalFormat("###,###,###,###,###,###,###");
+
StringBuffer sb = new StringBuffer();
- sb.append("splitBins=").append(splitBins).append('\n');
- sb.append("dbClosedBins=").append(dbClosedBins).append('\n');
- sb.append("cursorsBins=").append(cursorsBins).append('\n');
- sb.append("nonEmptyBins=").append(nonEmptyBins).append('\n');
- sb.append("processedBins=").append(processedBins).append('\n');
- sb.append("inCompQueueSize=").append(inCompQueueSize).append('\n');
+ sb.append("\nCompression stats\n");
+ sb.append("splitBins=").append(f.format(splitBins)).append('\n');
+ sb.append("dbClosedBins=").append(f.format(dbClosedBins)).append('\n');
+ sb.append("cursorsBins=").append(f.format(cursorsBins)).append('\n');
+ sb.append("nonEmptyBins=").append(f.format(nonEmptyBins)).append('\n');
+ sb.append("processedBins=").
+ append(f.format(processedBins)).append('\n');
+ sb.append("inCompQueueSize=").
+ append(f.format(inCompQueueSize)).append('\n');
// Evictor
- sb.append("nEvictPasses=").append(nEvictPasses).append('\n');
- sb.append("nNodesSelected=").append(nNodesSelected).append('\n');
- sb.append("nNodesScanned=").append(nNodesScanned).append('\n');
+ sb.append("\nEviction stats\n");
+ sb.append("nEvictPasses=").append(f.format(nEvictPasses)).append('\n');
+ sb.append("nNodesSelected=").
+ append(f.format(nNodesSelected)).append('\n');
+ sb.append("nNodesScanned=").
+ append(f.format(nNodesScanned)).append('\n');
sb.append("nNodesExplicitlyEvicted=").
- append(nNodesExplicitlyEvicted).append('\n');
- sb.append("nBINsStripped=").append(nBINsStripped).append('\n');
- sb.append("requiredEvictBytes=").append(requiredEvictBytes).
- append('\n');
+ append(f.format(nNodesExplicitlyEvicted)).append('\n');
+ sb.append("nBINsStripped=").
+ append(f.format(nBINsStripped)).append('\n');
+ sb.append("requiredEvictBytes=").
+ append(f.format(requiredEvictBytes)).append('\n');
// Checkpointer
- sb.append("nCheckpoints=").append(nCheckpoints).append('\n');
- sb.append("lastCheckpointId=").append(lastCheckpointId).append('\n');
- sb.append("nFullINFlush=").append(nFullINFlush).append('\n');
- sb.append("nFullBINFlush=").append(nFullBINFlush).append('\n');
- sb.append("nDeltaINFlush=").append(nDeltaINFlush).append('\n');
+ sb.append("\nCheckpoint stats\n");
+ sb.append("nCheckpoints=").append(f.format(nCheckpoints)).append('\n');
+ sb.append("lastCheckpointId=").
+ append(f.format(lastCheckpointId)).append('\n');
+ sb.append("nFullINFlush=").append(f.format(nFullINFlush)).append('\n');
+ sb.append("nFullBINFlush=").
+ append(f.format(nFullBINFlush)).append('\n');
+ sb.append("nDeltaINFlush=").
+ append(f.format(nDeltaINFlush)).append('\n');
sb.append("lastCheckpointStart=").
append(DbLsn.getNoFormatString(lastCheckpointStart)).append('\n');
sb.append("lastCheckpointEnd=").
append(DbLsn.getNoFormatString(lastCheckpointEnd)).append('\n');
// Cleaner
- sb.append("cleanerBacklog=").append(cleanerBacklog).append('\n');
- sb.append("nCleanerRuns=").append(nCleanerRuns).append('\n');
- sb.append("nCleanerDeletions=").append(nCleanerDeletions).append('\n');
- sb.append("nINsObsolete=").append(nINsObsolete).append('\n');
- sb.append("nINsCleaned=").append(nINsCleaned).append('\n');
- sb.append("nINsDead=").append(nINsDead).append('\n');
- sb.append("nINsMigrated=").append(nINsMigrated).append('\n');
- sb.append("nLNsObsolete=").append(nLNsObsolete).append('\n');
- sb.append("nLNsCleaned=").append(nLNsCleaned).append('\n');
- sb.append("nLNsDead=").append(nLNsDead).append('\n');
- sb.append("nLNsLocked=").append(nLNsLocked).append('\n');
- sb.append("nLNsMigrated=").append(nLNsMigrated).append('\n');
- sb.append("nLNsMarked=").append(nLNsMarked).append('\n');
+ sb.append("\nCleaner stats\n");
+ sb.append("cleanerBacklog=").
+ append(f.format(cleanerBacklog)).append('\n');
+ sb.append("nCleanerRuns=").
+ append(f.format(nCleanerRuns)).append('\n');
+ sb.append("nCleanerDeletions=").
+ append(f.format(nCleanerDeletions)).append('\n');
+ sb.append("nINsObsolete=").append(f.format(nINsObsolete)).append('\n');
+ sb.append("nINsCleaned=").append(f.format(nINsCleaned)).append('\n');
+ sb.append("nINsDead=").append(f.format(nINsDead)).append('\n');
+ sb.append("nINsMigrated=").append(f.format(nINsMigrated)).append('\n');
+ sb.append("nLNsObsolete=").append(f.format(nLNsObsolete)).append('\n');
+ sb.append("nLNsCleaned=").append(f.format(nLNsCleaned)).append('\n');
+ sb.append("nLNsDead=").append(f.format(nLNsDead)).append('\n');
+ sb.append("nLNsLocked=").append(f.format(nLNsLocked)).append('\n');
+ sb.append("nLNsMigrated=").append(f.format(nLNsMigrated)).append('\n');
+ sb.append("nLNsMarked=").append(f.format(nLNsMarked)).append('\n');
sb.append("nLNQueueHits=").
- append(nLNQueueHits).append('\n');
+ append(f.format(nLNQueueHits)).append('\n');
sb.append("nPendingLNsProcessed=").
- append(nPendingLNsProcessed).append('\n');
+ append(f.format(nPendingLNsProcessed)).append('\n');
sb.append("nMarkedLNsProcessed=").
- append(nMarkedLNsProcessed).append('\n');
+ append(f.format(nMarkedLNsProcessed)).append('\n');
sb.append("nToBeCleanedLNsProcessed=").
- append(nToBeCleanedLNsProcessed).append('\n');
+ append(f.format(nToBeCleanedLNsProcessed)).append('\n');
sb.append("nClusterLNsProcessed=").
- append(nClusterLNsProcessed).append('\n');
+ append(f.format(nClusterLNsProcessed)).append('\n');
sb.append("nPendingLNsLocked=").
- append(nPendingLNsLocked).append('\n');
+ append(f.format(nPendingLNsLocked)).append('\n');
sb.append("nCleanerEntriesRead=").
- append(nCleanerEntriesRead).append('\n');
+ append(f.format(nCleanerEntriesRead)).append('\n');
// Cache
- sb.append("nNotResident=").append(nNotResident).append('\n');
- sb.append("nCacheMiss=").append(nCacheMiss).append('\n');
- sb.append("nLogBuffers=").append(nLogBuffers).append('\n');
- sb.append("bufferBytes=").append(bufferBytes).append('\n');
- sb.append("cacheDataBytes=").append(cacheDataBytes).append('\n');
- sb.append("cacheTotalBytes=").append(getCacheTotalBytes()).
- append('\n');
- sb.append("nFSyncs=").append(nFSyncs).append('\n');
- sb.append("nFSyncRequests=").append(nFSyncRequests).append('\n');
- sb.append("nFSyncTimeouts=").append(nFSyncTimeouts).append('\n');
- sb.append("nRepeatFaultReads=").append(nRepeatFaultReads).append('\n');
- sb.append("nTempBufferWrite=").append(nTempBufferWrites).append('\n');
+ sb.append("\nCache stats\n");
+ sb.append("nNotResident=").append(f.format(nNotResident)).append('\n');
+ sb.append("nCacheMiss=").append(f.format(nCacheMiss)).append('\n');
+ sb.append("nLogBuffers=").append(f.format(nLogBuffers)).append('\n');
+ sb.append("bufferBytes=").append(f.format(bufferBytes)).append('\n');
+ sb.append("cacheDataBytes=").
+ append(f.format(cacheDataBytes)).append('\n');
+ sb.append("adminBytes=").append(f.format(adminBytes)).append('\n');
+ sb.append("lockBytes=").append(f.format(lockBytes)).append('\n');
+ sb.append("cacheTotalBytes=").
+ append(f.format(getCacheTotalBytes())).append('\n');
+
+ // Logging
+ sb.append("\nLogging stats\n");
+ sb.append("nFSyncs=").append(f.format(nFSyncs)).append('\n');
+ sb.append("nFSyncRequests=").
+ append(f.format(nFSyncRequests)).append('\n');
+ sb.append("nFSyncTimeouts=").
+ append(f.format(nFSyncTimeouts)).append('\n');
+ sb.append("nRepeatFaultReads=").
+ append(f.format(nRepeatFaultReads)).append('\n');
+ sb.append("nTempBufferWrite=").
+ append(f.format(nTempBufferWrites)).append('\n');
sb.append("nRepeatIteratorReads=").
- append(nRepeatIteratorReads).append('\n');
+ append(f.format(nRepeatIteratorReads)).append('\n');
+ sb.append("totalLogSize=").
+ append(f.format(totalLogSize)).append('\n');
return sb.toString();
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/JEVersion.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/JEVersion.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/JEVersion.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: JEVersion.java,v 1.93.2.9 2007/04/04 14:27:33 cwl Exp $
+ * $Id: JEVersion.java,v 1.93.2.20 2007/08/06 16:43:22 cwl Exp $
*/
package com.sleepycat.je;
@@ -19,7 +19,7 @@
* the doc templates in the doc_src directory.
*/
public static final JEVersion CURRENT_VERSION =
- new JEVersion(3, 2, 23, null);
+ new JEVersion(3, 2, 42, null);
private int majorNum;
private int minorNum;
Modified: trunk/contrib/bdb/src/com/sleepycat/je/SecondaryCursor.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/SecondaryCursor.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/SecondaryCursor.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: SecondaryCursor.java,v 1.35.2.1 2007/02/01 14:49:41 cwl Exp $
+ * $Id: SecondaryCursor.java,v 1.35.2.2 2007/06/13 21:22:17 mark Exp $
*/
package com.sleepycat.je;
@@ -704,7 +704,12 @@
Locker locker = cursorImpl.getLocker();
Cursor cursor = null;
try {
- cursor = new Cursor(primaryDb, locker, null);
+
+ /*
+ * Use Cursor constructor with DatabaseImpl parameter so that the
+ * non-transactional locker is used in the primary cursor. [#15573]
+ */
+ cursor = new Cursor(primaryDb.getDatabaseImpl(), locker, null);
OperationStatus status =
cursor.search(pKey, data, lockMode, SearchMode.SET);
if (status != OperationStatus.SUCCESS) {
@@ -779,8 +784,14 @@
}
return OperationStatus.SUCCESS;
} finally {
+
+ /*
+ * Do not release non-transactional locks when closing the primary
+ * cursor. They are held until all locks for this operation are
+ * released by the secondary cursor. [#15573]
+ */
if (cursor != null) {
- cursor.close();
+ cursor.close(false /*releaseNonTxnLocks*/);
}
}
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/cleaner/Cleaner.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/cleaner/Cleaner.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/cleaner/Cleaner.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: Cleaner.java,v 1.183.2.2 2007/03/08 22:32:53 mark Exp $
+ * $Id: Cleaner.java,v 1.183.2.5 2007/07/02 19:54:48 mark Exp $
*/
package com.sleepycat.je.cleaner;
@@ -405,6 +405,7 @@
stat.setNPendingLNsLocked(nPendingLNsLocked);
stat.setNCleanerEntriesRead(nEntriesRead);
stat.setNRepeatIteratorReads(nRepeatIteratorReads);
+ stat.setTotalLogSize(profile.getTotalLogSize());
if (config.getClear()) {
nCleanerRuns = 0;
@@ -430,6 +431,13 @@
}
}
+ /**
+ * For unit testing.
+ */
+ void injectFileForCleaning(Long fileNum) {
+ fileSelector.putBackFileForCleaning(fileNum);
+ }
+
/**
* Deletes all files that are safe-to-delete, if there are no read/only
* processes and concurrent backups.
@@ -632,19 +640,23 @@
DatabaseId dbId = info.getDbId();
DatabaseImpl db = dbMapTree.getDb(dbId, lockTimeout);
+ try {
+ byte[] key = info.getKey();
+ byte[] dupKey = info.getDupKey();
+ LN ln = info.getLN();
- byte[] key = info.getKey();
- byte[] dupKey = info.getDupKey();
- LN ln = info.getLN();
+ /* Evict before processing each entry. */
+ if (DO_CRITICAL_EVICTION) {
+ env.getEvictor().
+ doCriticalEviction(true); // backgroundIO
+ }
- /* Evict before processing each entry. */
- if (DO_CRITICAL_EVICTION) {
- env.getEvictor().doCriticalEviction(true); // backgroundIO
+ processPendingLN
+ (ln, db, key, dupKey, location);
+ } finally {
+ dbMapTree.releaseDb(db);
}
- processPendingLN
- (ln, db, key, dupKey, location);
-
/* Sleep if background read/write limit was exceeded. */
env.sleepAfterBackgroundIO();
}
@@ -655,8 +667,12 @@
for (int i = 0; i < pendingDBs.length; i += 1) {
DatabaseId dbId = pendingDBs[i];
DatabaseImpl db = dbMapTree.getDb(dbId, lockTimeout);
- if (db == null || db.isDeleteFinished()) {
- fileSelector.removePendingDB(dbId);
+ try {
+ if (db == null || db.isDeleteFinished()) {
+ fileSelector.removePendingDB(dbId);
+ }
+ } finally {
+ dbMapTree.releaseDb(db);
}
}
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileProcessor.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileProcessor.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileProcessor.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: FileProcessor.java,v 1.17.2.1 2007/02/01 14:49:42 cwl Exp $
+ * $Id: FileProcessor.java,v 1.17.2.6 2007/07/02 19:54:48 mark Exp $
*/
package com.sleepycat.je.cleaner;
@@ -25,6 +25,7 @@
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.dbi.MemoryBudget;
import com.sleepycat.je.log.CleanerFileReader;
+import com.sleepycat.je.log.LogFileNotFoundException;
import com.sleepycat.je.tree.BIN;
import com.sleepycat.je.tree.ChildReference;
import com.sleepycat.je.tree.DIN;
@@ -239,6 +240,7 @@
*/
resetPerRunCounters();
boolean finished = false;
+ boolean fileDeleted = false;
long fileNumValue = fileNum.longValue();
int runId = ++cleaner.nCleanerRuns;
try {
@@ -261,11 +263,28 @@
accumulatePerRunCounters();
finished = true;
}
- } catch (IOException IOE) {
- Tracer.trace(env, "Cleaner", "doClean", "", IOE);
- throw new DatabaseException(IOE);
+ } catch (LogFileNotFoundException e) {
+
+ /*
+ * File was deleted. Although it is possible that the file was
+ * deleted externally it is much more likely that the file was
+ * deleted normally after being cleaned earlier (this was
+ * observed prior to JE 3.2.29), and that we are mistakedly
+ * processing the file repeatedly. Since the file does not
+ * exist, ignore the error so that the cleaner will continue.
+ * The tracing below will indicate that the file was deleted.
+ * Remove the file completely from the FileSelector and
+ * UtilizationProfile so that we don't repeatedly attempt to
+ * process it. [#15528]
+ */
+ fileDeleted = true;
+ profile.removeFile(fileNum);
+ fileSelector.removeAllFileReferences(fileNum);
+ } catch (IOException e) {
+ Tracer.trace(env, "Cleaner", "doClean", "", e);
+ throw new DatabaseException(e);
} finally {
- if (!finished) {
+ if (!finished && !fileDeleted) {
fileSelector.putBackFileForCleaning(fileNum);
}
String traceMsg =
@@ -273,6 +292,7 @@
" on file 0x" + Long.toHexString(fileNumValue) +
" invokedFromDaemon=" + invokedFromDaemon +
" finished=" + finished +
+ " fileDeleted=" + fileDeleted +
" nEntriesRead=" + nEntriesReadThisRun +
" nINsObsolete=" + nINsObsoleteThisRun +
" nINsCleaned=" + nINsCleanedThisRun +
@@ -370,8 +390,13 @@
*/
Set checkPendingDbSet = new HashSet();
- /* Use local caching to reduce DbTree.getDb overhead. */
+ /*
+ * Use local caching to reduce DbTree.getDb overhead. Do not call
+ * releaseDb after getDb with the dbCache, since the entire dbCache
+ * will be released at the end of thie method.
+ */
Map dbCache = new HashMap();
+ DbTree dbMapTree = env.getDbMapTree();
try {
/* Create the file reader. */
@@ -380,7 +405,6 @@
/* Validate all entries before ever deleting a file. */
reader.setAlwaysValidateChecksum(true);
- DbTree dbMapTree = env.getDbMapTree();
TreeLocation location = new TreeLocation();
int nProcessedLNs = 0;
@@ -507,7 +531,6 @@
DatabaseImpl db = dbMapTree.getDb
(dbId, cleaner.lockTimeout, dbCache);
targetIN.setDatabase(db);
-
processIN(targetIN, db, logLsn, deferredWriteDbs);
} else if (isRoot) {
@@ -545,6 +568,9 @@
/* Subtract the overhead of this method from the budget. */
budget.updateMiscMemoryUsage(0 - adjustMem);
+ /* Release all cached DBs. */
+ dbMapTree.releaseDbs(dbCache);
+
/* Allow flushing of TFS when cleaning is complete. */
if (tfs != null) {
tfs.setAllowFlush(true);
@@ -579,6 +605,10 @@
long logLsn = DbLsn.makeLsn
(fileNum.longValue(), offset.longValue());
+ /*
+ * Do not call releaseDb after this getDb, since the entire dbCache
+ * will be released later.
+ */
DatabaseImpl db = env.getDbMapTree().getDb
(info.getDbId(), cleaner.lockTimeout, dbCache);
@@ -1010,15 +1040,11 @@
long treeLsn = result.parent.getLsn(result.index);
/*
- * Any entry that is in the log should not have a NULL_LSN in the
- * in-memory tree, even for a deferred write database. The
- * in-memory tree should always have a lsn that shows the last
- * on-disk version.
+ * The IN in the tree is a never-written IN for a DW db so the IN
+ * in the file is obsolete. [#15588]
*/
if (treeLsn == DbLsn.NULL_LSN) {
- throw new DatabaseException
- ("Deferred Write IN should not have a NULL_LSN " +
- " logLsn=" + DbLsn.getNoFormatString(logLsn));
+ return null;
}
int compareVal = DbLsn.compareTo(treeLsn, logLsn);
@@ -1106,10 +1132,12 @@
return null;
}
- /* bozo, how can the root's lsn be less that the logLsn?
- This may have been an artifact of when we didn't properly
- propagate the logging of the rootIN up to the root
- ChildReference. Remove? */
+ /*
+ * A root LSN less than the log LSN must be an artifact of when we
+ * didn't properly propagate the logging of the rootIN up to the
+ * root ChildReference. We still do this for compatibility with
+ * old log versions but may be able to remove it in the future.
+ */
if (DbLsn.compareTo(root.getLsn(), logLsn) <= 0) {
IN rootIN = (IN) root.fetchTarget(db, null);
rootIN.latch(Cleaner.UPDATE_GENERATION);
@@ -1171,16 +1199,6 @@
}
/**
- * XXX: Was this intended to override Thread.toString()? If so it no
- * longer does, because we separated Thread from DaemonThread.
- */
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("<Cleaner name=\"").append(name).append("\"/>");
- return sb.toString();
- }
-
- /**
* A cache of LNInfo by LSN offset. Used to hold a set of LNs that are
* to be processed. Keeps track of memory used, and when full (over
* budget) the next offset should be queried and removed.
Modified: trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileSelector.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileSelector.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/cleaner/FileSelector.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: FileSelector.java,v 1.15.2.1 2007/02/01 14:49:42 cwl Exp $
+ * $Id: FileSelector.java,v 1.15.2.2 2007/05/31 21:55:32 mark Exp $
*/
package com.sleepycat.je.cleaner;
@@ -253,6 +253,18 @@
}
/**
+ * Removes all references to a file.
+ */
+ synchronized void removeAllFileReferences(Long file) {
+ toBeCleanedFiles.remove(file);
+ beingCleanedFiles.remove(file);
+ cleanedFiles.remove(file);
+ checkpointedFiles.remove(file);
+ fullyProcessedFiles.remove(file);
+ safeToDeleteFiles.remove(file);
+ }
+
+ /**
* When file cleaning is aborted, move the file back from the being-cleaned
* set to the to-be-cleaned set.
*/
Modified: trunk/contrib/bdb/src/com/sleepycat/je/cleaner/TrackedFileSummary.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/cleaner/TrackedFileSummary.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/cleaner/TrackedFileSummary.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: TrackedFileSummary.java,v 1.9.2.1 2007/02/01 14:49:42 cwl Exp $
+ * $Id: TrackedFileSummary.java,v 1.9.2.2 2007/05/15 14:48:39 mark Exp $
*/
package com.sleepycat.je.cleaner;
@@ -124,10 +124,12 @@
add(other);
/*
- * Add the offsets. The memory budget has already been updated for the
- * offsets to be added, so we only need to account for a difference
- * when we merge them.
+ * Add the offsets and the memory used [#15505] by the other tracker.
+ * The memory budget has already been updated for the offsets to be
+ * added, so we only need to account for a possible difference of one
+ * segment when we merge them.
*/
+ memSize += other.memSize;
if (other.obsoleteOffsets != null) {
if (obsoleteOffsets != null) {
/* Merge the other offsets into our list. */
Modified: trunk/contrib/bdb/src/com/sleepycat/je/cleaner/UtilizationProfile.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/cleaner/UtilizationProfile.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/cleaner/UtilizationProfile.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: UtilizationProfile.java,v 1.52.2.2 2007/03/07 00:40:24 mark Exp $
+ * $Id: UtilizationProfile.java,v 1.52.2.7 2007/07/02 19:54:48 mark Exp $
*/
package com.sleepycat.je.cleaner;
@@ -95,6 +95,7 @@
private SortedMap fileSummaryMap; // cached fileNum -> FileSummary
private boolean cachePopulated;
private boolean rmwFixEnabled;
+ private long totalLogSize;
/**
* Minimum overall utilization threshold that triggers cleaning. Is
@@ -176,6 +177,29 @@
}
/**
+ * Returns an approximation of the total log size. Used for stats.
+ */
+ long getTotalLogSize() {
+
+ /* Start with the size known to the profile. */
+ long size = totalLogSize;
+
+ /*
+ * Add sizes that are known to the tracker but are not yet in the
+ * profile. The FileSummary.totalSize field is the delta for new
+ * log entries added. Typically the last log file is only one that
+ * will have a delta, but previous files may also not have been added
+ * to the profile yet.
+ */
+ TrackedFileSummary[] trackedFiles = tracker.getTrackedFiles();
+ for (int i = 0; i < trackedFiles.length; i += 1) {
+ size += trackedFiles[i].totalSize;
+ }
+
+ return size;
+ }
+
+ /**
* Returns the cheapest file to clean from the given list of files. This
* method is used to select the first file to be cleaned in the batch of
* to-be-cleaned files.
@@ -582,10 +606,13 @@
assert cachePopulated;
/* Remove from the cache. */
- if (fileSummaryMap.remove(fileNum) != null) {
+ FileSummary oldSummary =
+ (FileSummary) fileSummaryMap.remove(fileNum);
+ if (oldSummary != null) {
MemoryBudget mb = env.getMemoryBudget();
mb.updateMiscMemoryUsage
(0 - MemoryBudget.UTILIZATION_PROFILE_ENTRY);
+ totalLogSize -= oldSummary.totalSize;
}
}
@@ -711,14 +738,29 @@
/*
* An obsolete node may have been counted after its file was
- * deleted, for example, when compressing a BIN. Do not insert
- * a new profile record if no corresponding log file exists.
+ * deleted, for example, when compressing a BIN. Do not insert a
+ * new profile record if no corresponding log file exists. But if
+ * the file number is greater than the last known file, this is a
+ * new file that has been buffered but not yet flushed to disk; in
+ * that case we should insert a new profile record.
*/
- File file = new File
- (env.getFileManager().getFullFileName
- (fileNum, FileManager.JE_SUFFIX));
- if (!file.exists()) {
- return null;
+ if (!fileSummaryMap.isEmpty() &&
+ fileNum < ((Long) fileSummaryMap.lastKey()).longValue()) {
+ File file = new File
+ (env.getFileManager().getFullFileName
+ (fileNum, FileManager.JE_SUFFIX));
+ if (!file.exists()) {
+
+ /*
+ * File was deleted by the cleaner. Remove it from the
+ * UtilizationTracker and return. Note that a file is
+ * normally removed from the tracker by
+ * FileSummaryLN.writeToLog method when it is called via
+ * insertFileSummary below. [#15512]
+ */
+ env.getLogManager().removeTrackedFile(tfs);
+ return null;
+ }
}
summary = new FileSummary();
@@ -732,6 +774,7 @@
FileSummary tmp = new FileSummary();
tmp.add(summary);
tmp.add(tfs);
+ totalLogSize += tfs.totalSize;
int sequence = tmp.getEntriesCounted();
/* Insert an LN with the existing and tracked summary info. */
@@ -898,6 +941,8 @@
int oldMemorySize = fileSummaryMap.size() *
MemoryBudget.UTILIZATION_PROFILE_ENTRY;
+ totalLogSize = 0;
+
/*
* It is possible to have an undeleted FileSummaryLN in the database
* for a deleted log file if we crash after deleting a file but before
@@ -959,7 +1004,9 @@
if (Arrays.binarySearch(existingFiles, fileNumLong) >= 0) {
/* File exists, cache the FileSummaryLN. */
- fileSummaryMap.put(fileNumLong, ln.getBaseSummary());
+ FileSummary summary = ln.getBaseSummary();
+ fileSummaryMap.put(fileNumLong, summary);
+ totalLogSize += summary.totalSize;
/*
* Update old version records to the new version. A
@@ -1101,6 +1148,12 @@
boolean operationOk = false;
try {
autoTxn = new AutoTxn(env, new TransactionConfig());
+
+ /*
+ * releaseDb is not called after this getDb or createDb because we
+ * want to prohibit eviction of this database until the environment
+ * is closed.
+ */
DatabaseImpl db = dbTree.getDb
(autoTxn, DbTree.UTILIZATION_DB_NAME, null);
if (db == null) {
@@ -1256,20 +1309,21 @@
DatabaseId dbId = entry.getDbId();
DatabaseImpl db = env.getDbMapTree().getDb(dbId);
- /*
- * The whole database is gone, so this LN is obsolete. No need
- * to worry about delete cleanup; this is just verification and
- * no cleaning is done.
- */
- if (db == null || db.isDeleted()) {
- return true;
- }
-
/*
* Search down to the bottom most level for the parent of this LN.
*/
BIN bin = null;
try {
+
+ /*
+ * The whole database is gone, so this LN is obsolete. No need
+ * to worry about delete cleanup; this is just verification and
+ * no cleaning is done.
+ */
+ if (db == null || db.isDeleted()) {
+ return true;
+ }
+
Tree tree = db.getTree();
TreeLocation location = new TreeLocation();
boolean parentFound = tree.getParentBINForChildLN
@@ -1307,6 +1361,7 @@
" was found in tree.");
return false;
} finally {
+ env.getDbMapTree().releaseDb(db);
if (bin != null) {
bin.releaseLatch();
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/config/BooleanConfigParam.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/config/BooleanConfigParam.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/config/BooleanConfigParam.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: BooleanConfigParam.java,v 1.25.2.1 2007/02/01 14:49:43 cwl Exp $
+ * $Id: BooleanConfigParam.java,v 1.25.2.2 2007/06/04 17:03:30 linda Exp $
*/
package com.sleepycat.je.config;
@@ -20,7 +20,7 @@
* Set a boolean parameter w/default.
* @param configName
* @param defaultValue
- * @param forReplication TODO
+ * @param forReplication true if param is only used for replication
*/
BooleanConfigParam(String configName,
boolean defaultValue,
Modified: trunk/contrib/bdb/src/com/sleepycat/je/config/EnvironmentParams.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/config/EnvironmentParams.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/config/EnvironmentParams.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: EnvironmentParams.java,v 1.84.2.3 2007/03/07 01:24:35 mark Exp $
+ * $Id: EnvironmentParams.java,v 1.84.2.4 2007/07/02 19:54:49 mark Exp $
*/
package com.sleepycat.je.config;
@@ -207,6 +207,16 @@
false, // mutable
false, // forReplication
"# If true, use shared latches for Internal Nodes (INs).\n");
+
+ public static final BooleanConfigParam ENV_DB_EVICTION =
+ new BooleanConfigParam("je.env.dbEviction",
+ false, // default
+ false, // mutable
+ false, // forReplication
+ "# *** Experimental and not fully tested in 3.2.x. ***\n" +
+ "# If true, enable eviction of metadata for closed databases.\n" +
+ "# The default for JE 3.2.x is false but will be changed to true\n" +
+ "# in JE 3.3 and above.");
public static final IntConfigParam ADLER32_CHUNK_SIZE =
new IntConfigParam("je.adler32.chunkSize",
Modified: trunk/contrib/bdb/src/com/sleepycat/je/dbi/CursorImpl.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/dbi/CursorImpl.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/dbi/CursorImpl.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: CursorImpl.java,v 1.320.2.1 2007/02/01 14:49:44 cwl Exp $
+ * $Id: CursorImpl.java,v 1.320.2.3 2007/06/13 21:22:17 mark Exp $
*/
package com.sleepycat.je.dbi;
@@ -646,10 +646,26 @@
}
/**
+ * Close a cursor with releaseNonTxnLocks=true.
+ */
+ public void close()
+ throws DatabaseException {
+
+ close(true /*releaseNonTxnLocks*/);
+ }
+
+ /**
* Close a cursor.
+ *
+ * @param releaseNonTxnLocks should normally be true to release
+ * non-transactional locks when a cursor is closed. However, some
+ * operations may wish to hold non-transactional locks if the locker is
+ * re-used in another cursor. For example, see
+ * SecondaryCursor.readPrimaryAfterGet. [#15573]
+ *
* @throws DatabaseException if the cursor was previously closed.
*/
- public void close()
+ public void close(boolean releaseNonTxnLocks)
throws DatabaseException {
assert assertCursorState(false) : dumpToString(true);
@@ -657,7 +673,7 @@
removeCursor();
locker.unRegisterCursor(this);
- if (!retainNonTxnLocks) {
+ if (releaseNonTxnLocks && !retainNonTxnLocks) {
locker.releaseNonTxnLocks();
}
@@ -1178,10 +1194,16 @@
/* Check that data compares equal before replacing it. */
boolean keysEqual = false;
+ /*
+ * Do not use a custom duplicate comaprator here because we do
+ * not support replacing the data if it is different, even if
+ * the custom comparator considers it equal. If we were to
+ * support this we would have to update the key in the BIN
+ * slot. [#15527]
+ */
if (foundDataBytes != null) {
- keysEqual = Key.compareKeys
- (foundDataBytes, newData,
- database.getDuplicateComparator()) == 0;
+ keysEqual =
+ Key.compareKeys(foundDataBytes, newData, null) == 0;
}
if (!keysEqual) {
Modified: trunk/contrib/bdb/src/com/sleepycat/je/dbi/DatabaseImpl.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/dbi/DatabaseImpl.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/dbi/DatabaseImpl.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: DatabaseImpl.java,v 1.157.2.5 2007/03/09 17:37:09 linda Exp $
+ * $Id: DatabaseImpl.java,v 1.157.2.7 2007/07/02 19:54:49 mark Exp $
*/
package com.sleepycat.je.dbi;
@@ -92,6 +92,7 @@
private BtreeStats stats; // most recent btree stats w/ !DB_FAST_STAT
private long eofNodeId; // Logical EOF node for range locking
private short deleteState; // one of four delete states.
+ private int useCount = 0; // If non-zero, eviction is prohibited
/*
* The user defined Btree and duplicate comparison functions, if specified.
@@ -220,13 +221,20 @@
}
/**
- * Clone. For now just pass off to the super class for a field-by-field
- * copy.
+ * Clone. For the most part, just pass off to the super class for a
+ * field-by-field copy.
*/
- public Object clone()
- throws CloneNotSupportedException {
+ public DatabaseImpl cloneDb()
+ throws DatabaseException {
- return super.clone();
+ try {
+ DatabaseImpl newDb = (DatabaseImpl) clone();
+ /* The cloned DB could have a non-zero use count. [#13415] */
+ newDb.useCount = 0;
+ return newDb;
+ } catch (CloneNotSupportedException e) {
+ throw new DatabaseException(e);
+ }
}
/**
@@ -436,6 +444,69 @@
}
/**
+ * Increments the use count of this DB to prevent it from being
+ * evicted. Called by the DbTree.createDb/getDb methods that return a
+ * DatabaseImpl. Must be called while holding a lock on the MapLN. See
+ * isInUse. [#13415]
+ */
+ void incrementUseCount() {
+ if (envImpl.getDbEviction()) {
+ /* Synchronize to update useCount atomically. */
+ synchronized (this) {
+ useCount += 1;
+ }
+ }
+ }
+
+ /**
+ * Decrements the use count of this DB, allowing it to be evicted if the
+ * use count reaches zero. Called via DbTree.releaseDb to release a
+ * DatabaseImpl that was returned by a DbTree.createDb/getDb method. See
+ * isInUse. [#13415]
+ */
+ void decrementUseCount() {
+ if (envImpl.getDbEviction()) {
+ /* Synchronize to update useCount atomically. */
+ synchronized (this) {
+ assert useCount > 0;
+ useCount -= 1;
+ }
+ }
+ }
+
+ /**
+ * Returns whether this DB is in use and cannot be evicted. Called by
+ * MapLN.isEvictable while holding a write-lock on the MapLN and a latch on
+ * its parent BIN. [#13415]
+ *
+ * When isInUse returns false (while holding a write-lock on the MapLN and
+ * a latch on the parent BIN), it guarantees that the database object
+ * is not in use and cannot be acquired by another thread (via
+ * DbTree.createDb/getDb) until both the MapLN lock and BIN latch are
+ * released. This guarantee is due to the fact that DbTree.createDb/getDb
+ * only increment the use count while holding a read-lock on the MapLN.
+ * Therefore, it is safe to evict the MapLN when isInUse returns false.
+ *
+ * When isInUse returns true, it is possible that another thread may
+ * decrement the use count at any time, since no locking or latching is
+ * performed when calling DbTree.releaseDb (which calls decrementUseCount).
+ * Therefore, it is not guaranteed that the MapLN is in use when isInUse
+ * returns true. A true result means: the DB may be in use, so it is not
+ * safe to evict it.
+ */
+ public boolean isInUse() {
+ if (envImpl.getDbEviction()) {
+ /* Synchronize to read the up-to-date value of useCount. */
+ synchronized (this) {
+ return (useCount > 0);
+ }
+ } else {
+ /* Always prohibit eviction when je.env.dbEviction=false. */
+ return true;
+ }
+ }
+
+ /**
* Flush all dirty nodes for this database to disk.
*/
public synchronized void sync(boolean flushLog)
@@ -592,6 +663,8 @@
(snapshot.getTrackedFiles());
} finally {
deleteState = DELETED;
+ /* releaseDb to balance getDb called by truncate/remove. */
+ envImpl.releaseDb(this);
}
}
@@ -1209,10 +1282,16 @@
in.latch();
try {
int index = inEntry.index;
- if (in.isEntryKnownDeleted(index) ||
- in.getLsn(index) != lsn) {
- return null;
- }
+ if (index < 0) {
+ /* Negative index signifies a DupCountLN. */
+ DIN din = (DIN) in;
+ return din.getDupCountLN();
+ } else {
+ if (in.isEntryKnownDeleted(index) ||
+ in.getLsn(index) != lsn) {
+ return null;
+ }
+ }
return in.fetchTarget(index);
} finally {
in.releaseLatch();
Modified: trunk/contrib/bdb/src/com/sleepycat/je/dbi/DbTree.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/dbi/DbTree.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/dbi/DbTree.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: DbTree.java,v 1.170.2.1 2007/02/01 14:49:44 cwl Exp $
+ * $Id: DbTree.java,v 1.170.2.2 2007/07/02 19:54:49 mark Exp $
*/
package com.sleepycat.je.dbi;
@@ -12,6 +12,7 @@
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -42,7 +43,69 @@
import com.sleepycat.je.txn.Locker;
/**
- * Represents the DatabaseImpl Naming Tree.
+ * DbTree represents the database directory for this environment. DbTree is
+ * itself implemented through two databases. The nameDatabase maps
+ * databaseName-> an internal databaseId. The idDatabase maps
+ * databaseId->DatabaseImpl.
+ *
+ * For example, suppose we have two databases, foo and bar. We have the
+ * following structure:
+ *
+ * nameDatabase idDatabase
+ * IN IN
+ * | |
+ * BIN BIN
+ * +-------------+--------+ +---------------+--------+
+ * . | | . | |
+ * NameLNs NameLN NameLN MapLNs for MapLN MapLN
+ * for internal key=bar key=foo internal dbs key=53 key=79
+ * dbs data= data= data= data=
+ * dbId79 dbId53 DatabaseImpl DatabaseImpl
+ * | |
+ * Tree for foo Tree for bar
+ * | |
+ * root IN root IN
+ *
+ * Databases, Cursors, the cleaner, compressor, and other entities have
+ * references to DatabaseImpls. It's important that object identity is properly
+ * maintained, and that all constituents reference the same DatabaseImpl for
+ * the same db, lest they develop disparate views of the in-memory database;
+ * corruption would ensue. To ensure that, all entities must obtain their
+ * DatabaseImpl by going through the idDatabase.
+ *
+ * DDL type operations such as create, rename, remove and truncate get their
+ * transactional semantics by transactionally locking the NameLN appropriately.
+ * A read-lock on the NameLN, called a handle lock, is maintained for all DBs
+ * opened via the public API (openDatabase). This prevents them from being
+ * renamed or removed while open.
+ *
+ * However, for internal database operations, no handle lock on the NameLN is
+ * acacuiqred and MapLNs are locked with short-lived non-transactional Lockers.
+ * An entity that is trying to get a reference to the DatabaseImpl gets a short
+ * lived read lock just for the fetch of the MapLN. A write lock on the MapLN
+ * is taken when the database is created, deleted, or when the MapLN is
+ * evicted. (see DatabaseImpl.isInUse())
+ *
+ * The nameDatabase operates pretty much as a regular application database in
+ * terms of eviction and recovery. The idDatabase requires special treatment
+ * for both eviction and recovery.
+ *
+ * The issues around eviction of the idDatabase center on the need to ensure
+ * that there are no other current references to the DatabaseImpl other than
+ * that held by the mapLN. The presence of a current reference would both make
+ * the DatabaseImpl not GC'able, and more importantly, would lead to object
+ * identify confusion later on. For example, if the MapLN is evicted while
+ * there is a current reference to its DatabaseImpl, and then refetched, there
+ * will be two in-memory versions of the DatabaseImpl. Since locks on the
+ * idDatabase are short lived, DatabaseImpl.useCount acts as a reference count
+ * of active current references. DatabaseImpl.useCount must be modified and
+ * read in conjunction with appropropriate locking on the MapLN. See
+ * DatabaseImpl.isInUse() for details.
+ *
+ * This reference count checking is only needed when the entire MapLN is
+ * evicted. It's possible to evict only the root IN of the database in
+ * question, since that doesn't interfere with the DatabaseImpl object
+ * identity.
*/
public class DbTree implements Loggable {
@@ -151,6 +214,10 @@
/**
* Create a database.
*
+ * Increments the use count of the new DB to prevent it from being evicted.
+ * releaseDb should be called when the returned object is no longer used,
+ * to allow it to be evicted. See DatabaseImpl.isInUse. [#13415]
+ *
* Do not evict (do not call CursorImpl.setAllowEviction(true)) during low
* level DbTree operation. [#15176]
*
@@ -193,6 +260,8 @@
idDbLocker = new BasicLocker(envImpl);
idCursor = new CursorImpl(idDatabase, idDbLocker);
idCursor.putLN(newId.getBytes(), new MapLN(newDb), false);
+ /* Increment DB use count with lock held. */
+ newDb.incrementUseCount();
operationOk = true;
} catch (UnsupportedEncodingException UEE) {
throw new DatabaseException(UEE);
@@ -212,6 +281,7 @@
return newDb;
}
+
/**
* Called by the Tree to propagate a root change. If the tree is a data
* database, we will write the MapLn that represents this db to the log. If
@@ -341,9 +411,10 @@
("Attempted to " + action + " non-existent database " +
databaseName);
}
- result.nameCursor = new CursorImpl(nameDatabase, locker);
+ boolean success = false;
+ try {
+ result.nameCursor = new CursorImpl(nameDatabase, locker);
- try {
/* Position the cursor at the specified NameLN. */
DatabaseEntry key =
new DatabaseEntry(databaseName.getBytes("UTF-8"));
@@ -374,14 +445,17 @@
databaseName + "," + handleCount +
" open Dbs exist");
}
+ success = true;
} catch (UnsupportedEncodingException UEE) {
- result.nameCursor.releaseBIN();
- result.nameCursor.close();
throw new DatabaseException(UEE);
- } catch (DatabaseException e) {
- result.nameCursor.releaseBIN();
- result.nameCursor.close();
- throw e;
+ } finally {
+ if (!success) {
+ releaseDb(result.dbImpl);
+ if (result.nameCursor != null) {
+ result.nameCursor.releaseBIN();
+ result.nameCursor.close();
+ }
+ }
}
return result;
@@ -400,8 +474,8 @@
throws DatabaseException {
CursorImpl nameCursor = null;
+ NameLockResult result = lockNameLN(locker, databaseName, "rename");
try {
- NameLockResult result = lockNameLN(locker, databaseName, "rename");
nameCursor = result.nameCursor;
if (nameCursor == null) {
return false;
@@ -422,6 +496,7 @@
} catch (UnsupportedEncodingException UEE) {
throw new DatabaseException(UEE);
} finally {
+ releaseDb(result.dbImpl);
if (nameCursor != null) {
nameCursor.releaseBIN();
nameCursor.close();
@@ -436,8 +511,8 @@
throws DatabaseException {
CursorImpl nameCursor = null;
+ NameLockResult result = lockNameLN(locker, databaseName, "remove");
try {
- NameLockResult result = lockNameLN(locker, databaseName, "remove");
nameCursor = result.nameCursor;
if (nameCursor == null) {
return;
@@ -456,6 +531,9 @@
* Schedule database for final deletion during commit. This
* should be the last action taken, since this will take
* effect immediately for non-txnal lockers.
+ *
+ * Do not call releaseDb here on result.dbImpl, since that is
+ * taken care of by markDeleteAtTxnEnd.
*/
locker.markDeleteAtTxnEnd(result.dbImpl, true);
}
@@ -484,9 +562,8 @@
CursorImpl nameCursor = null;
Locker idDbLocker = null;
+ NameLockResult result = lockNameLN(locker, databaseName, "truncate");
try {
- NameLockResult result = lockNameLN(locker, databaseName,
- "truncate");
nameCursor = result.nameCursor;
if (nameCursor == null) {
return 0;
@@ -497,7 +574,8 @@
* nameLN refer to the id of the new database.
*/
DatabaseId newId = new DatabaseId(getNextDbId());
- DatabaseImpl newDb = (DatabaseImpl) result.dbImpl.clone();
+ DatabaseImpl newDb = result.dbImpl.cloneDb();
+ newDb.incrementUseCount();
newDb.setId(newId);
newDb.setTree(new Tree(newDb));
@@ -538,6 +616,9 @@
/*
* Marking the lockers should be the last action, since
* it takes effect immediately for non-txnal lockers.
+ *
+ * Do not call releaseDb here on result.dbImpl or newDb, since
+ * that is taken care of by markDeleteAtTxnEnd.
*/
/* Schedule old database for deletion if txn commits. */
@@ -548,9 +629,6 @@
return recordCount;
}
-
- } catch (CloneNotSupportedException CNSE) {
- throw new DatabaseException(CNSE);
} finally {
if (nameCursor != null) {
nameCursor.releaseBIN();
@@ -655,9 +733,18 @@
*/
DatabaseImpl newDb;
DatabaseId newId = new DatabaseId(getNextDbId());
- newDb = (DatabaseImpl) oldDatabase.clone();
+ newDb = oldDatabase.cloneDb();
+ newDb.incrementUseCount();
newDb.setId(newId);
newDb.setTree(new Tree(newDb));
+
+ /*
+ * The non-deprecated truncate starts with an old database with a
+ * incremented use count because lockNameLN is called, which calls
+ * getDb. To normalize the situation here we must increment it,
+ * since we don't call lockNameLN/getDb.
+ */
+ oldDatabase.incrementUseCount();
/* Insert the new db into id -> name map */
CursorImpl idCursor = null;
@@ -694,8 +781,6 @@
nameCursor.putCurrent(dataDbt, null, null);
return new TruncateResult(newDb, (int) count);
- } catch (CloneNotSupportedException CNSE) {
- throw new DatabaseException(CNSE);
} catch (UnsupportedEncodingException UEE) {
throw new DatabaseException(UEE);
} finally {
@@ -721,6 +806,7 @@
throws DatabaseException {
try {
+ /* Use count is not incremented for idDatabase and nameDatabase. */
if (databaseName.equals(ID_DB_NAME)) {
return idDatabase;
} else if (databaseName.equals(NAME_DB_NAME)) {
@@ -734,7 +820,6 @@
CursorImpl nameCursor = null;
DatabaseId id = null;
try {
-
nameCursor = new CursorImpl(nameDatabase, nameLocker);
DatabaseEntry keyDbt =
new DatabaseEntry(databaseName.getBytes("UTF-8"));
@@ -824,6 +909,11 @@
* be specified by daemons with their own timeout configuration. public
* for unit tests.
*
+ * Increments the use count of the given DB to prevent it from being
+ * evicted. releaseDb should be called when the returned object is no
+ * longer used, to allow it to be evicted. See DatabaseImpl.isInUse.
+ * [#13415]
+ *
* Do not evict (do not call CursorImpl.setAllowEviction(true)) during low
* level DbTree operation. [#15176]
*/
@@ -866,6 +956,8 @@
idCursor.getCurrentLNAlreadyLatched(LockType.READ);
assert mapLN != null; /* Should be locked. */
foundDbImpl = mapLN.getDatabase();
+ /* Increment DB use count with lock held. */
+ foundDbImpl.incrementUseCount();
}
break;
} catch (DeadlockException DE) {
@@ -896,6 +988,33 @@
}
}
+ /**
+ * Decrements the use count of the given DB, allowing it to be evicted if
+ * the use count reaches zero. Must be called to release a DatabaseImpl
+ * that was returned by a method in this class. See DatabaseImpl.isInUse.
+ * [#13415]
+ */
+ public void releaseDb(DatabaseImpl db) {
+ /* Use count is not incremented for idDatabase and nameDatabase. */
+ if (db != null &&
+ db != idDatabase &&
+ db != nameDatabase) {
+ db.decrementUseCount();
+ }
+ }
+
+ /**
+ * Calls releaseDb for all DBs in the given map of DatabaseId to
+ * DatabaseImpl. See getDb(DatabaseId, long, Map). [#13415]
+ */
+ public void releaseDbs(Map dbCache) {
+ if (dbCache != null) {
+ for (Iterator i = dbCache.values().iterator(); i.hasNext();) {
+ releaseDb((DatabaseImpl) i.next());
+ }
+ }
+ }
+
/*
* We need to cache a database name in the dbImpl for later use in error
* messages, when it may be unsafe to walk the mapping tree. Finding a
Modified: trunk/contrib/bdb/src/com/sleepycat/je/dbi/EnvironmentImpl.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/dbi/EnvironmentImpl.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/dbi/EnvironmentImpl.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: EnvironmentImpl.java,v 1.256.2.6 2007/04/04 18:36:07 cwl Exp $
+ * $Id: EnvironmentImpl.java,v 1.256.2.7 2007/07/02 19:54:49 mark Exp $
*/
package com.sleepycat.je.dbi;
@@ -97,6 +97,7 @@
private static boolean useSharedLatchesForINs;
/* true if offset tracking should be used for deferred write dbs. */
private boolean deferredWriteTemp;
+ private boolean dbEviction;
private MemoryBudget memoryBudget;
private static int adler32ChunkSize;
@@ -277,9 +278,10 @@
configManager.getBoolean(EnvironmentParams.LOG_MEMORY_ONLY);
useSharedLatchesForINs =
configManager.getBoolean(EnvironmentParams.ENV_SHARED_LATCHES);
+ dbEviction =
+ configManager.getBoolean(EnvironmentParams.ENV_DB_EVICTION);
adler32ChunkSize =
configManager.getInt(EnvironmentParams.ADLER32_CHUNK_SIZE);
-
exceptionListener = envConfig.getExceptionListener();
/*
@@ -1343,6 +1345,13 @@
return useSharedLatchesForINs;
}
+ /**
+ * Returns whether DB/MapLN eviction is enabled.
+ */
+ boolean getDbEviction() {
+ return dbEviction;
+ }
+
public boolean getDeferredWriteTemp() {
return deferredWriteTemp;
}
@@ -1355,7 +1364,13 @@
return adler32ChunkSize;
}
- /* DatabaseImpl access. */
+ /**
+ * Creates a new database object given a database name.
+ *
+ * Increments the use count of the new DB to prevent it from being evicted.
+ * releaseDb should be called when the returned object is no longer used,
+ * to allow it to be evicted. See DatabaseImpl.isInUse. [#13415]
+ */
public DatabaseImpl createDb(Locker locker,
String databaseName,
DatabaseConfig dbConfig,
@@ -1371,6 +1386,11 @@
/**
* Get a database object given a database name.
*
+ * Increments the use count of the given DB to prevent it from being
+ * evicted. releaseDb should be called when the returned object is no
+ * longer used, to allow it to be evicted. See DatabaseImpl.isInUse.
+ * [#13415]
+ *
* @param databaseName target database.
*
* @return null if database doesn't exist.
@@ -1383,6 +1403,16 @@
return dbMapTree.getDb(locker, databaseName, databaseHandle);
}
+ /**
+ * Decrements the use count of the given DB, allowing it to be evicted if
+ * the use count reaches zero. Must be called to release a DatabaseImpl
+ * that was returned by createDb or getDb. See DatabaseImpl.isInUse.
+ * [#13415]
+ */
+ public void releaseDb(DatabaseImpl db) {
+ dbMapTree.releaseDb(db);
+ }
+
public List getDbNames()
throws DatabaseException {
Modified: trunk/contrib/bdb/src/com/sleepycat/je/dbi/GetMode.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/dbi/GetMode.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/dbi/GetMode.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: GetMode.java,v 1.7.2.1 2007/02/01 14:49:44 cwl Exp $
+ * $Id: GetMode.java,v 1.7.2.2 2007/08/06 16:00:06 cwl Exp $
*/
package com.sleepycat.je.dbi;
@@ -21,12 +21,12 @@
this.forward = forward;
}
- public static final GetMode NEXT = new GetMode("NEXT", true);
- public static final GetMode PREV = new GetMode("PREV", false);
- public static final GetMode NEXT_DUP = new GetMode("NEXT_DUP", true);
- public static final GetMode PREV_DUP = new GetMode("PREV_DUP", false);
- public static final GetMode NEXT_NODUP = new GetMode("NEXT_NODUP", true);
- public static final GetMode PREV_NODUP = new GetMode("PREV_NODUP", false);
+ public static final GetMode NEXT = new GetMode("NEXT", true);
+ public static final GetMode PREV = new GetMode("PREV", false);
+ public static final GetMode NEXT_DUP = new GetMode("NEXT_DUP", true);
+ public static final GetMode PREV_DUP = new GetMode("PREV_DUP", false);
+ public static final GetMode NEXT_NODUP = new GetMode("NEXT_NODUP", true);
+ public static final GetMode PREV_NODUP = new GetMode("PREV_NODUP", false);
public final boolean isForward() {
return forward;
Modified: trunk/contrib/bdb/src/com/sleepycat/je/dbi/MemoryBudget.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/dbi/MemoryBudget.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/dbi/MemoryBudget.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: MemoryBudget.java,v 1.54.2.2 2007/02/14 19:46:42 linda Exp $
+ * $Id: MemoryBudget.java,v 1.54.2.6 2007/07/13 02:32:05 cwl Exp $
*/
package com.sleepycat.je.dbi;
@@ -131,16 +131,16 @@
private final static int KEY_OVERHEAD_64 = 24;
// 24
- private final static int LOCK_OVERHEAD_32 = 32;
- private final static int LOCK_OVERHEAD_64 = 56;
+ private final static int LOCK_OVERHEAD_32 = 24;
+ private final static int LOCK_OVERHEAD_64 = 48;
// 25
private final static int LOCKINFO_OVERHEAD_32 = 16;
private final static int LOCKINFO_OVERHEAD_64 = 32;
// 37
- private final static int WRITE_LOCKINFO_OVERHEAD_32 = 32;
- private final static int WRITE_LOCKINFO_OVERHEAD_64 = 40;
+ private final static int WRITE_LOCKINFO_OVERHEAD_32 = 24;
+ private final static int WRITE_LOCKINFO_OVERHEAD_64 = 32;
/*
* Txn memory is the size for the Txn + a hashmap entry
@@ -347,8 +347,7 @@
/*
* Amount of memory cached for locks. Protected by the
- * LockManager.lockTableLatches[lockTableIndex]. Individual elements of
- * array may be negative, but the sum will be >= 0.
+ * LockManager.lockTableLatches[lockTableIndex].
*/
private long[] lockMemoryUsage;
@@ -391,7 +390,7 @@
envImpl.addConfigObserver(this);
/* Peform first time budget initialization. */
- reset(configManager);
+ reset(configManager, true);
/*
* Calculate IN and BIN overheads, which are a function of
@@ -418,7 +417,7 @@
* hasn't changed, since that is expensive and may cause I/O.
*/
long oldLogBufferBudget = logBufferBudget;
- reset(configManager);
+ reset(configManager, false);
if (oldLogBufferBudget != logBufferBudget) {
envImpl.getLogManager().resetPool(configManager);
}
@@ -427,7 +426,8 @@
/**
* Initialize at construction time and when the cache is resized.
*/
- private void reset(DbConfigManager configManager)
+ private void reset(DbConfigManager configManager,
+ boolean resetLockMemoryUsage)
throws DatabaseException {
/*
@@ -530,9 +530,11 @@
logBufferBudget = newLogBufferBudget;
trackerBudget = newTrackerBudget;
cacheBudget = newMaxMemory - newLogBufferBudget;
- nLockTables =
- configManager.getInt(EnvironmentParams.N_LOCK_TABLES);
- lockMemoryUsage = new long[nLockTables];
+ if (resetLockMemoryUsage) {
+ nLockTables =
+ configManager.getInt(EnvironmentParams.N_LOCK_TABLES);
+ lockMemoryUsage = new long[nLockTables];
+ }
}
/**
@@ -644,6 +646,12 @@
}
public long getCacheMemoryUsage() {
+ long accLockMemoryUsage = accumulateLockUsage();
+
+ return treeMemoryUsage + miscMemoryUsage + accLockMemoryUsage;
+ }
+
+ private long accumulateLockUsage() {
long accLockMemoryUsage = 0;
if (nLockTables == 1) {
accLockMemoryUsage = lockMemoryUsage[0];
@@ -652,7 +660,7 @@
accLockMemoryUsage += lockMemoryUsage[i];
}
}
- return treeMemoryUsage + miscMemoryUsage + accLockMemoryUsage;
+ return accLockMemoryUsage;
}
/**
@@ -662,6 +670,13 @@
return treeMemoryUsage;
}
+ /**
+ * Used for unit testing.
+ */
+ public long getMiscMemoryUsage() {
+ return miscMemoryUsage;
+ }
+
public long getLogBufferBudget() {
return logBufferBudget;
}
@@ -717,5 +732,7 @@
void loadStats(StatsConfig config, EnvironmentStats stats) {
stats.setCacheDataBytes(getCacheMemoryUsage());
+ stats.setAdminBytes(miscMemoryUsage);
+ stats.setLockBytes(accumulateLockUsage());
}
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/dbi/SortedLSNTreeWalker.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/dbi/SortedLSNTreeWalker.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/dbi/SortedLSNTreeWalker.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: SortedLSNTreeWalker.java,v 1.17.2.2 2007/03/07 01:24:36 mark Exp $
+ * $Id: SortedLSNTreeWalker.java,v 1.17.2.3 2007/05/01 19:27:23 mark Exp $
*/
package com.sleepycat.je.dbi;
@@ -209,7 +209,7 @@
MemoryBudget mb = envImpl.getMemoryBudget();
inList.latchMajor();
try {
- /* consolidate the INList first. */
+ /* Consolidate the INList first. */
inList.latchMinorAndDumpAddedINs();
Iterator iter = inList.iterator();
@@ -419,6 +419,8 @@
DupCountLN dcl = (DupCountLN) din.getDupCountLN();
callback.processDupCount(dcl.getDupCount());
} else {
+ /* Negative index signifies a DupCountLN. */
+ addToLsnINMap(new Long(lsn), in, -1);
Node node = fetchLSN(lsn, lnKeyEntry);
callback.processLSN
(lsn, LogEntryType.LOG_DUPCOUNTLN, node,
@@ -481,6 +483,9 @@
*/
}
+ /**
+ * @param index a negative index signifies a DupCountLN.
+ */
protected void addToLsnINMap(Long lsn, IN in, int index) {
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/evictor/Evictor.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/evictor/Evictor.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/evictor/Evictor.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: Evictor.java,v 1.86.2.4 2007/03/07 01:24:37 mark Exp $
+ * $Id: Evictor.java,v 1.86.2.6 2007/07/02 19:54:50 mark Exp $
*/
package com.sleepycat.je.evictor;
@@ -31,10 +31,12 @@
import com.sleepycat.je.log.LogManager;
import com.sleepycat.je.recovery.Checkpointer;
import com.sleepycat.je.tree.BIN;
+import com.sleepycat.je.tree.ChildReference;
import com.sleepycat.je.tree.IN;
import com.sleepycat.je.tree.Node;
import com.sleepycat.je.tree.SearchResult;
import com.sleepycat.je.tree.Tree;
+import com.sleepycat.je.tree.WithRootLatched;
import com.sleepycat.je.utilint.DaemonThread;
import com.sleepycat.je.utilint.DbLsn;
import com.sleepycat.je.utilint.TestHook;
@@ -133,12 +135,6 @@
active = false;
}
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("<Evictor name=\"").append(name).append("\"/>");
- return sb.toString();
- }
-
/**
* Evictor doesn't have a work queue so just throw an exception if it's
* ever called.
@@ -361,8 +357,13 @@
break;
} else {
assert evictProfile.count(target);//intentional side effect
- evictBytes += evict
- (inList, target, scanIter, backgroundIO, tracker);
+ if (target.isDbRoot()) {
+ evictBytes += evictRoot
+ (inList, target, scanIter, backgroundIO);
+ } else {
+ evictBytes += evict
+ (inList, target, scanIter, backgroundIO, tracker);
+ }
}
nBatchSets++;
}
@@ -516,15 +517,6 @@
}
/*
- * Don't evict the DatabaseImpl Id Mapping Tree (db 0), both
- * for object identity reasons and because the id mapping tree
- * should stay cached.
- */
- if (db.getId().equals(DbTree.ID_DB_ID)) {
- continue;
- }
-
- /*
* If this is a read only database and we have at least one
* target, skip any dirty INs (recovery dirties INs even in a
* read-only environment). We take at least one target so we
@@ -619,6 +611,18 @@
* in a non-duplicate tree. This isn't always optimimal, but is the best
* we can do considering that BINs in duplicate trees may contain a mix of
* LNs and DINs.
+ *
+ * BINs in the mapping tree are also assigned the same level as user DB
+ * BINs. When doing by-level eviction (lruOnly=false), this seems
+ * counter-intuitive since we should evict user DB nodes before mapping DB
+ * nodes. But that does occur because mapping DB INs referencing an open
+ * DB are unevictable. The level is only used for selecting among
+ * evictable nodes.
+ *
+ * If we did NOT normalize the level for the mapping DB, then INs for
+ * closed evictable DBs would not be evicted until after all nodes in all
+ * user DBs were evicted. If there were large numbers of closed DBs, this
+ * would have a negative performance impact.
*/
public int normalizeLevel(IN in, int evictType) {
@@ -632,6 +636,75 @@
}
/**
+ * Evict this DB root node. [#13415]
+ * @return number of bytes evicted.
+ */
+ private long evictRoot(final INList inList,
+ final IN target,
+ final ScanIterator scanIter,
+ final boolean backgroundIO)
+ throws DatabaseException {
+
+ final DatabaseImpl db = target.getDatabase();
+
+ class RootEvictor implements WithRootLatched {
+
+ boolean flushed = false;
+ long evictBytes = 0;
+
+ public IN doWork(ChildReference root)
+ throws DatabaseException {
+
+ IN rootIN = (IN) root.fetchTarget(db, null);
+ rootIN.latch(false);
+ try {
+ /* Re-check that all conditions still hold. */
+ if (rootIN == target &&
+ rootIN.isDbRoot() &&
+ rootIN.isEvictable()) {
+
+ /* Flush if dirty. */
+ if (!envImpl.isReadOnly() && rootIN.getDirty()) {
+ long newLsn = rootIN.log
+ (envImpl.getLogManager(),
+ false, // allowDeltas
+ isProvisionalRequired(rootIN),
+ true, // proactiveMigration
+ backgroundIO,
+ null); // parent
+ root.setLsn(newLsn);
+ flushed = true;
+ }
+
+ /* Take off the INList and adjust memory budget. */
+ scanIter.mark();
+ inList.removeLatchAlreadyHeld(rootIN);
+ scanIter.resetToMark();
+ evictBytes = rootIN.getInMemorySize();
+
+ /* Evict IN. */
+ root.clearTarget();
+ }
+ } finally {
+ rootIN.releaseLatch();
+ }
+ return null;
+ }
+ }
+
+ /* Attempt to evict the DB root IN. */
+ RootEvictor evictor = new RootEvictor();
+ db.getTree().withRootLatchedExclusive(evictor);
+
+ /* If the root IN was flushed, write the dirtied MapLN. */
+ if (evictor.flushed) {
+ envImpl.getDbMapTree().modifyDbRoot(db);
+ }
+
+ return evictor.evictBytes;
+ }
+
+ /**
* Strip or evict this node.
* @return number of bytes evicted.
*/
Modified: trunk/contrib/bdb/src/com/sleepycat/je/incomp/INCompressor.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/incomp/INCompressor.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/incomp/INCompressor.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: INCompressor.java,v 1.125.2.2 2007/03/07 01:24:37 mark Exp $
+ * $Id: INCompressor.java,v 1.125.2.5 2007/07/02 19:54:50 mark Exp $
*/
package com.sleepycat.je.incomp;
@@ -97,12 +97,6 @@
binRefQueueSync = new Object();
}
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("<INCompressor name=\"").append(name).append("\"/>");
- return sb.toString();
- }
-
synchronized public void clearEnv() {
env = null;
}
@@ -126,20 +120,28 @@
queueSnapshot = new ArrayList(binRefQueue.values());
}
- /* Use local caching to reduce DbTree.getDb overhead. */
+ /*
+ * Use local caching to reduce DbTree.getDb overhead. Do not call
+ * releaseDb after each getDb, since the entire dbCache will be
+ * released at the end.
+ */
+ DbTree dbTree = env.getDbMapTree();
Map dbCache = new HashMap();
-
- Iterator it = queueSnapshot.iterator();
- while (it.hasNext()) {
- BINReference binRef = (BINReference) it.next();
- DatabaseImpl db = env.getDbMapTree().getDb
- (binRef.getDatabaseId(), lockTimeout, dbCache);
- BIN bin = searchForBIN(db, binRef);
- if (bin != null) {
- bin.verifyCursors();
- bin.releaseLatch();
- }
- }
+ try {
+ Iterator it = queueSnapshot.iterator();
+ while (it.hasNext()) {
+ BINReference binRef = (BINReference) it.next();
+ DatabaseImpl db = dbTree.getDb
+ (binRef.getDatabaseId(), lockTimeout, dbCache);
+ BIN bin = searchForBIN(db, binRef);
+ if (bin != null) {
+ bin.verifyCursors();
+ bin.releaseLatch();
+ }
+ }
+ } finally {
+ dbTree.releaseDbs(dbCache);
+ }
}
/**
@@ -462,8 +464,9 @@
env.getUtilizationProfile().countAndLogSummaries
(summaries);
}
-
+
} finally {
+ dbTree.releaseDbs(dbCache);
assert LatchSupport.countLatchesHeld() == 0;
accumulatePerRunCounters();
}
@@ -790,7 +793,10 @@
Map dbCache)
throws DatabaseException {
- /* Find the database. */
+ /*
+ * Find the database. Do not call releaseDb after this getDb, since
+ * the entire dbCache will be released later.
+ */
binSearch.db = dbTree.getDb
(binRef.getDatabaseId(), lockTimeout, dbCache);
if ((binSearch.db == null) ||(binSearch.db.isDeleted())) {
Modified: trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEConnection.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEConnection.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEConnection.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: JEConnection.java,v 1.13.2.1 2007/02/01 14:49:45 cwl Exp $
+ * $Id: JEConnection.java,v 1.13.2.2 2007/05/22 20:36:39 cwl Exp $
*/
package com.sleepycat.je.jca.ra;
@@ -24,82 +24,35 @@
* <JEHOME>/examples/jca/simple/SimpleBean.java for more information on
* how to build the resource adaptor and use a JEConnection.
*/
-public class JEConnection {
+public interface JEConnection {
- private JEManagedConnection mc;
- private JELocalTransaction txn;
+ public void setManagedConnection(JEManagedConnection mc,
+ JELocalTransaction lt);
- public JEConnection(JEManagedConnection mc) {
- this.mc = mc;
- }
+ public JELocalTransaction getLocalTransaction();
- protected void setManagedConnection(JEManagedConnection mc,
- JELocalTransaction lt) {
- this.mc = mc;
- if (txn == null) {
- txn = lt;
- }
- }
+ public void setLocalTransaction(JELocalTransaction txn);
- JELocalTransaction getLocalTransaction() {
- return txn;
- }
-
- void setLocalTransaction(JELocalTransaction txn) {
- this.txn = txn;
- }
-
public Environment getEnvironment()
- throws ResourceException {
+ throws ResourceException;
- return mc.getEnvironment();
- }
-
public Database openDatabase(String name, DatabaseConfig config)
- throws DatabaseException {
+ throws DatabaseException;
- return mc.openDatabase(name, config);
- }
-
public SecondaryDatabase openSecondaryDatabase(String name,
Database primaryDatabase,
SecondaryConfig config)
- throws DatabaseException {
+ throws DatabaseException;
- return mc.openSecondaryDatabase(name, primaryDatabase, config);
- }
-
public void removeDatabase(String databaseName)
- throws DatabaseException {
+ throws DatabaseException;
- mc.removeDatabase(databaseName);
- }
-
public long truncateDatabase(String databaseName, boolean returnCount)
- throws DatabaseException {
+ throws DatabaseException;
- return mc.truncateDatabase(databaseName, returnCount);
- }
-
public Transaction getTransaction()
- throws ResourceException {
+ throws ResourceException;
- if (txn == null) {
- return null;
- }
-
- try {
- return txn.getTransaction();
- } catch (DatabaseException DE) {
- ResourceException ret = new ResourceException(DE.toString());
- ret.initCause(DE);
- throw ret;
- }
- }
-
public void close()
- throws JEException {
-
- mc.close();
- }
+ throws JEException;
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnection.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnection.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnection.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: JEManagedConnection.java,v 1.13.2.1 2007/02/01 14:49:45 cwl Exp $
+ * $Id: JEManagedConnection.java,v 1.13.2.2 2007/05/22 20:36:39 cwl Exp $
*/
package com.sleepycat.je.jca.ra;
@@ -67,7 +67,7 @@
throws ResourceException {
if (conn == null) {
- conn = new JEConnection(this);
+ conn = new JEConnectionImpl(this);
}
return conn;
}
@@ -115,7 +115,7 @@
public void associateConnection(Object connection)
throws ResourceException {
- conn = (JEConnection) connection;
+ conn = (JEConnectionImpl) connection;
conn.setManagedConnection(this, savedLT);
savedLT = null;
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnectionFactory.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnectionFactory.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/JEManagedConnectionFactory.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: JEManagedConnectionFactory.java,v 1.9.2.1 2007/02/01 14:49:45 cwl Exp $
+ * $Id: JEManagedConnectionFactory.java,v 1.9.2.2 2007/05/22 20:36:39 cwl Exp $
*/
package com.sleepycat.je.jca.ra;
@@ -26,6 +26,9 @@
public class JEManagedConnectionFactory
implements ManagedConnectionFactory, Serializable {
+ private String userName;
+ private String password;
+
public JEManagedConnectionFactory() {
}
@@ -76,6 +79,22 @@
return null;
}
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
public void setLogWriter(PrintWriter out)
throws ResourceException {
Modified: trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/ra.xml
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/ra.xml 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/jca/ra/ra.xml 2007-08-17 14:14:29 UTC (rev 14749)
@@ -24,7 +24,7 @@
</connectionfactory-impl-class>
<connection-interface>com.sleepycat.je.jca.ra.JEConnection
</connection-interface>
- <connection-impl-class>com.sleepycat.je.jca.ra.JEConnection
+ <connection-impl-class>com.sleepycat.je.jca.ra.JEConnectionImpl
</connection-impl-class>
<transaction-support>LocalTransaction</transaction-support>
<!--
Modified: trunk/contrib/bdb/src/com/sleepycat/je/log/FileReader.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/log/FileReader.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/log/FileReader.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: FileReader.java,v 1.99.2.3 2007/04/04 14:28:22 cwl Exp $
+ * $Id: FileReader.java,v 1.99.2.4 2007/05/31 21:55:32 mark Exp $
*/
package com.sleepycat.je.log;
@@ -267,7 +267,8 @@
readBasicHeader(dataBuffer);
if (currentEntryHeader.getReplicate()) {
- dataBuffer = readData(currentEntryHeader.getVariablePortionSize(), true);
+ dataBuffer = readData
+ (currentEntryHeader.getVariablePortionSize(), true);
currentEntryHeader.readVariablePortion(dataBuffer);
}
@@ -338,26 +339,38 @@
} catch (DatabaseException e) {
eof = true;
/* Report on error. */
- LogEntryType problemType =
- LogEntryType.findType(currentEntryHeader.getType(),
- currentEntryHeader.getVersion());
- Tracer.trace(envImpl, "FileReader", "readNextEntry",
- "Halted log file reading at file 0x" +
- Long.toHexString(readBufferFileNum) +
- " offset 0x" +
- Long.toHexString(nextEntryOffset) +
- " offset(decimal)=" + nextEntryOffset +
- ":\nentry="+ problemType +
- "(typeNum=" + currentEntryHeader.getType() +
- ",version=" + currentEntryHeader.getVersion() +
- ")\nprev=0x" +
- Long.toHexString(currentEntryPrevOffset) +
- "\nsize=" + currentEntryHeader.getItemSize() +
- "\nNext entry should be at 0x" +
- Long.toHexString((nextEntryOffset +
+ if (currentEntryHeader != null) {
+ LogEntryType problemType =
+ LogEntryType.findType(currentEntryHeader.getType(),
+ currentEntryHeader.getVersion());
+ Tracer.trace(envImpl, "FileReader", "readNextEntry",
+ "Halted log file reading at file 0x" +
+ Long.toHexString(readBufferFileNum) +
+ " offset 0x" +
+ Long.toHexString(nextEntryOffset) +
+ " offset(decimal)=" + nextEntryOffset +
+ ":\nentry="+ problemType +
+ "(typeNum=" + currentEntryHeader.getType() +
+ ",version=" + currentEntryHeader.getVersion() +
+ ")\nprev=0x" +
+ Long.toHexString(currentEntryPrevOffset) +
+ "\nsize=" + currentEntryHeader.getItemSize() +
+ "\nNext entry should be at 0x" +
+ Long.toHexString((nextEntryOffset +
currentEntryHeader.getSize() +
currentEntryHeader.getItemSize())) +
- "\n:", e);
+ "\n:", e);
+ } else {
+ Tracer.trace(envImpl, "FileReader", "readNextEntry",
+ "Halted log file reading at file 0x" +
+ Long.toHexString(readBufferFileNum) +
+ " offset 0x" +
+ Long.toHexString(nextEntryOffset) +
+ " offset(decimal)=" + nextEntryOffset +
+ " prev=0x" +
+ Long.toHexString(currentEntryPrevOffset),
+ e);
+ }
throw e;
}
return foundEntry;
Modified: trunk/contrib/bdb/src/com/sleepycat/je/log/INFileReader.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/log/INFileReader.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/log/INFileReader.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: INFileReader.java,v 1.52.2.2 2007/03/08 22:32:54 mark Exp $
+ * $Id: INFileReader.java,v 1.52.2.3 2007/08/06 16:00:20 cwl Exp $
*/
package com.sleepycat.je.log;
@@ -293,8 +293,8 @@
* Do partial load of db and txn id tracking entries if necessary.
* Note that these entries do not overlap with targetLogEntry.
*
- * XXX We're doing a full load for now, since LNLogEntry does not
- * read the db and txn id in a partial load, only the node id.
+ * We're doing a full load for now, since LNLogEntry does not read
+ * the db and txn id in a partial load, only the node id.
*/
LNLogEntry lnEntry = null;
if (dbIdTrackingEntry != null) {
Modified: trunk/contrib/bdb/src/com/sleepycat/je/log/LatchedLogManager.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/log/LatchedLogManager.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/log/LatchedLogManager.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: LatchedLogManager.java,v 1.17.2.1 2007/02/01 14:49:47 cwl Exp $
+ * $Id: LatchedLogManager.java,v 1.17.2.2 2007/06/13 03:55:37 mark Exp $
*/
package com.sleepycat.je.log;
@@ -83,7 +83,21 @@
logWriteLatch.release();
}
}
+
+ /**
+ * @see LogManager#removeTrackedFile
+ */
+ public void removeTrackedFile(TrackedFileSummary tfs)
+ throws DatabaseException {
+ logWriteLatch.acquire();
+ try {
+ removeTrackedFileInternal(tfs);
+ } finally {
+ logWriteLatch.release();
+ }
+ }
+
/**
* @see LogManager#countObsoleteLNs
*/
Modified: trunk/contrib/bdb/src/com/sleepycat/je/log/LogManager.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/log/LogManager.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/log/LogManager.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: LogManager.java,v 1.163.2.3 2007/03/09 21:04:12 mark Exp $
+ * $Id: LogManager.java,v 1.163.2.4 2007/06/13 03:55:37 mark Exp $
*/
package com.sleepycat.je.log;
@@ -821,6 +821,16 @@
}
/**
+ * Removes the tracked summary for the given file.
+ */
+ abstract public void removeTrackedFile(TrackedFileSummary tfs)
+ throws DatabaseException;
+
+ protected void removeTrackedFileInternal(TrackedFileSummary tfs) {
+ tfs.reset();
+ }
+
+ /**
* Count node as obsolete under the log write latch. This is done here
* because the log write latch is managed here, and all utilization
* counting must be performed under the log write latch.
Modified: trunk/contrib/bdb/src/com/sleepycat/je/log/StatsFileReader.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/log/StatsFileReader.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/log/StatsFileReader.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: StatsFileReader.java,v 1.15.2.1 2007/02/01 14:49:47 cwl Exp $
+ * $Id: StatsFileReader.java,v 1.15.2.2 2007/06/04 17:03:30 linda Exp $
*/
package com.sleepycat.je.log;
@@ -187,7 +187,7 @@
8 bytes txn id
8 bytes lastlogged LSN (backpointer for txn)
*/
- /** BOZO -- the header size is undercounted for replication */
+
int overhead = (info.count*46) + info.headerBytes;
realTotalBytes += (info.totalBytes-overhead);
}
Modified: trunk/contrib/bdb/src/com/sleepycat/je/log/SyncedLogManager.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/log/SyncedLogManager.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/log/SyncedLogManager.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: SyncedLogManager.java,v 1.18.2.1 2007/02/01 14:49:47 cwl Exp $
+ * $Id: SyncedLogManager.java,v 1.18.2.2 2007/06/13 03:55:37 mark Exp $
*/
package com.sleepycat.je.log;
@@ -77,7 +77,18 @@
return getUnflushableTrackedSummaryInternal(file);
}
}
+
+ /**
+ * @see LogManager#removeTrackedFile
+ */
+ public void removeTrackedFile(TrackedFileSummary tfs)
+ throws DatabaseException {
+ synchronized (logWriteLatch) {
+ removeTrackedFileInternal(tfs);
+ }
+ }
+
/**
* @see LogManager#countObsoleteLNs
*/
Modified: trunk/contrib/bdb/src/com/sleepycat/je/recovery/Checkpointer.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/recovery/Checkpointer.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/recovery/Checkpointer.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: Checkpointer.java,v 1.140.2.2 2007/03/07 01:24:39 mark Exp $
+ * $Id: Checkpointer.java,v 1.140.2.3 2007/06/01 21:32:56 mark Exp $
*/
package com.sleepycat.je.recovery;
@@ -146,12 +146,6 @@
checkpointId = lastCheckpointId;
}
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("<Checkpointer name=\"").append(name).append("\"/>");
- return sb.toString();
- }
-
/**
* Load stats.
*/
Modified: trunk/contrib/bdb/src/com/sleepycat/je/recovery/RecoveryManager.java
===================================================================
--- trunk/contrib/bdb/src/com/sleepycat/je/recovery/RecoveryManager.java 2007-08-17 14:09:41 UTC (rev 14748)
+++ trunk/contrib/bdb/src/com/sleepycat/je/recovery/RecoveryManager.java 2007-08-17 14:14:29 UTC (rev 14749)
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: RecoveryManager.java,v 1.211.2.3 2007/03/28 15:53:44 cwl Exp $
+ * $Id: RecoveryManager.java,v 1.211.2.4 2007/07/02 19:54:51 mark Exp $
*/
package com.sleepycat.je.recovery;
@@ -651,8 +651,12 @@
DatabaseId dbId = reader.getDatabaseId();
if (dbId.equals(DbTree.ID_DB_ID)) {
DatabaseImpl db = dbMapTree.getDb(dbId);
- replayOneIN(reader, db, false, recorder);
- info.numMapINs++;
+ try {
+ replayOneIN(reader, db, false, recorder);
+ info.numMapINs++;
+ } finally {
+ dbMapTree.releaseDb(db);
+ }
}
}
@@ -731,18 +735,24 @@
}
if (isTarget) {
DatabaseImpl db = dbMapTree.getDb(dbId);
- if (db == null) {
- // This db has been deleted, ignore the entry.
- } else {
- replayOneIN(reader, db, requireExactMatch, recorder);
- numINsSeen++;
+ try {
+ if (db == null) {
+ // This db has been deleted, ignore the entry.
+ } else {
+ replayOneIN(reader, db, requireExactMatch,
+ recorder);
+ numINsSeen++;
- /*
- * Add any db that we encounter IN's for because
- * they'll be part of the in-memory tree and therefore
- * should be included in the INList rebuild.
- */
- inListRebuildDbIds.add(dbId);
+ /*
+ * Add any db that we encounter IN's for because
+ * they'll be part of the in-memory tree and
+ * therefore should be included in the INList
+ * rebuild.
+ */
+ inListRebuildDbIds.add(dbId);
+ }
+ } finally {
+ dbMapTree.releaseDb(db);
}
}
}
@@ -787,13 +797,17 @@
DatabaseId dbId = reader.getDatabaseId();
if (targetDbs.contains(dbId)) {
DatabaseImpl db = dbMapTree.getDb(dbId);
- if (db == null) {
- // This db has been deleted, ignore the entry.
- } else {
- replayOneIN(reader,
- db,
- true, // requireExactMatch,
- null); // level recorder
+ try {
+ if (db == null) {
+ // This db has been deleted, ignore the entry.
+ } else {
+ replayOneIN(reader,
+ db,
+ true, // requireExactMatch,
+ null); // level recorder
+ }
+ } finally {
+ dbMapTree.releaseDb(db);
}
}
}
@@ -934,46 +948,49 @@
reader.getAbortKnownDeleted();
DatabaseId dbId = reader.getDatabaseId();
DatabaseImpl db = dbMapTree.getDb(dbId);
-
- /* Database may be null if it's been deleted. */
- if (db != null) {
- ln.postFetchInit(db, logLsn);
- try {
- undo(detailedTraceLevel,
- db,
- location,
- ln,
- reader.getKey(),
- reader.getDupTreeKey(),
- logLsn,
-