From ddfb6e5c119b5a6cd89e088cc185e2c4d77ef0f8 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Thu, 30 Aug 2007 22:52:47 +0000
Subject: [PATCH] Fixed a issue where closing the JE backend may cause memory leaks. With this fix, only one database handle is opened per database container.

---
 opends/src/server/org/opends/server/backends/jeb/DatabaseContainer.java |   78 +++++---------------------------------
 1 files changed, 11 insertions(+), 67 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/jeb/DatabaseContainer.java b/opends/src/server/org/opends/server/backends/jeb/DatabaseContainer.java
index 131bbaf..d96822c 100644
--- a/opends/src/server/org/opends/server/backends/jeb/DatabaseContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/DatabaseContainer.java
@@ -28,8 +28,6 @@
 
 import com.sleepycat.je.*;
 
-import java.util.concurrent.CopyOnWriteArrayList;
-
 import static org.opends.server.loggers.debug.DebugLogger.*;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.DebugLogLevel;
@@ -66,16 +64,10 @@
   private Environment env;
 
   /**
-   * A list of JE database handles opened through this database
+   * A JE database handle opened through this database
    * container.
    */
-  private CopyOnWriteArrayList<Database> databases;
-
-  /**
-   * A cached per-thread JE database handle.
-   */
-  private ThreadLocal<Database> threadLocalDatabase =
-      new ThreadLocal<Database>();
+  private Database database;
 
   /**
    * Create a new DatabaseContainer object.
@@ -91,7 +83,6 @@
   {
     this.env = env;
     this.entryContainer = entryContainer;
-    this.databases = new CopyOnWriteArrayList<Database>();
     this.name = name;
   }
 
@@ -99,20 +90,12 @@
    * Opens a JE database in this database container. If the provided
    * database configuration is transactional, a transaction will be
    * created and used to perform the open.
-   * <p>
-   * Note that a database can be opened multiple times and will result in
-   * multiple unique handles to the database.  This is used for example to
-   * give each server thread its own database handle to eliminate contention
-   * that could occur on a single handle.
    *
-   * @return A new JE database handle.
-   * @throws DatabaseException If an error occurs while attempting to open the
-   * database.
+   * @throws DatabaseException if a JE database error occurs while
+   * openning the index.
    */
-  private Database openDatabase() throws DatabaseException
+  public void open() throws DatabaseException
   {
-    Database database;
-
     if (dbConfig.getTransactional())
     {
       // Open the database under a transaction.
@@ -144,31 +127,6 @@
                             database.getDatabaseName(), database.count());
       }
     }
-
-    return database;
-  }
-
-  private Database getDatabase() throws DatabaseException
-  {
-    Database database = threadLocalDatabase.get();
-    if (database == null)
-    {
-      database = openDatabase();
-      databases.add(database);
-      threadLocalDatabase.set(database);
-    }
-    return database;
-  }
-
-  /**
-   * Open the database container.
-   *
-   * @throws DatabaseException if a JE database error occurs while
-   * openning the index.
-   */
-  public void open() throws DatabaseException
-  {
-    getDatabase();
   }
 
   /**
@@ -188,25 +146,17 @@
    */
   synchronized void close() throws DatabaseException
   {
-    // Close each database handle that has been opened.
-    for (Database database : databases)
+    if(dbConfig.getDeferredWrite())
     {
-      if (database.getConfig().getDeferredWrite())
-      {
-        database.sync();
-      }
-
-      database.close();
+      database.sync();
     }
+    database.close();
+    database = null;
 
     if(debugEnabled())
     {
-      TRACER.debugInfo("Closed database %s (%d handles)", name,
-                       databases.size());
+      TRACER.debugInfo("Closed database %s", name);
     }
-
-    databases.clear();
-    threadLocalDatabase = new ThreadLocal<Database>();
   }
 
   /**
@@ -222,7 +172,6 @@
                                 DatabaseEntry data)
       throws DatabaseException
   {
-    Database database = getDatabase();
     OperationStatus status = database.put(txn, key, data);
     if (debugEnabled())
     {
@@ -248,7 +197,6 @@
                                  LockMode lockMode)
       throws DatabaseException
   {
-    Database database = getDatabase();
     OperationStatus status = database.get(txn, key, data, lockMode);
     if (debugEnabled())
     {
@@ -271,7 +219,6 @@
                                    DatabaseEntry key, DatabaseEntry data)
       throws DatabaseException
   {
-    Database database = getDatabase();
     OperationStatus status = database.putNoOverwrite(txn, key, data);
     if (debugEnabled())
     {
@@ -293,7 +240,6 @@
                                    DatabaseEntry key)
       throws DatabaseException
   {
-    Database database = getDatabase();
     OperationStatus status = database.delete(txn, key);
     if (debugEnabled())
     {
@@ -315,7 +261,6 @@
   public Cursor openCursor(Transaction txn, CursorConfig cursorConfig)
        throws DatabaseException
   {
-    Database database = getDatabase();
     return database.openCursor(txn, cursorConfig);
   }
 
@@ -327,7 +272,6 @@
    */
   public long getRecordCount() throws DatabaseException
   {
-    Database database = getDatabase();
     long count = database.count();
     if (debugEnabled())
     {
@@ -367,7 +311,7 @@
   public PreloadStats preload(PreloadConfig config)
       throws DatabaseException
   {
-    return getDatabase().preload(config);
+    return database.preload(config);
   }
 
   /**

--
Gitblit v1.10.0