From 3259fdc435a6ed8687e9572f7f05285caa47da2a Mon Sep 17 00:00:00 2001
From: Yannick Lecaillez <yannick.lecaillez@forgerock.com>
Date: Mon, 14 Mar 2016 14:05:08 +0000
Subject: [PATCH] OPENDJ-2719: PDB entries cannot be larger than 4MB.

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java |   56 ++++++++++++++++++++++----------------------------------
 1 files changed, 22 insertions(+), 34 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java
index 1096953..9dda8be 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java
@@ -39,9 +39,7 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
-import java.util.Queue;
 import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedDeque;
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
@@ -106,7 +104,7 @@
   private static final int BUFFER_SIZE = 16 * 1024;
 
   /** PersistIt implementation of the {@link Cursor} interface. */
-  private static final class CursorImpl implements Cursor<ByteString, ByteString>
+  private final class CursorImpl implements Cursor<ByteString, ByteString>
   {
     private ByteString currentKey;
     private ByteString currentValue;
@@ -121,7 +119,7 @@
     public void close()
     {
       // Release immediately because this exchange did not come from the txn cache
-      exchange.getPersistitInstance().releaseExchange(exchange);
+      releaseExchange(exchange);
     }
 
     @Override
@@ -268,29 +266,18 @@
   /** PersistIt implementation of the {@link Importer} interface. */
   private final class ImporterImpl implements Importer
   {
-    private final Queue<Map<TreeName, Exchange>> allExchanges = new ConcurrentLinkedDeque<>();
     private final ThreadLocal<Map<TreeName, Exchange>> exchanges = new ThreadLocal<Map<TreeName, Exchange>>()
     {
       @Override
       protected Map<TreeName, Exchange> initialValue()
       {
-        final Map<TreeName, Exchange> value = new HashMap<>();
-        allExchanges.add(value);
-        return value;
+        return new HashMap<>();
       }
     };
 
     @Override
     public void close()
     {
-      for (Map<TreeName, Exchange> map : allExchanges)
-      {
-        for (Exchange exchange : map.values())
-        {
-          db.releaseExchange(exchange);
-        }
-        map.clear();
-      }
       PDBStorage.this.close();
     }
 
@@ -304,11 +291,10 @@
 
     private void createTree(final Transaction txn, final TreeName treeName)
     {
-      Exchange ex = null;
       try
       {
         txn.begin();
-        ex = getNewExchange(treeName, true);
+        getNewExchange(treeName, true);
         txn.commit();
       }
       catch (PersistitException e)
@@ -318,7 +304,6 @@
       finally
       {
         txn.end();
-        releaseExchangeSilenty(ex);
       }
     }
 
@@ -339,15 +324,6 @@
       finally
       {
         txn.end();
-        releaseExchangeSilenty(ex);
-      }
-    }
-
-    private void releaseExchangeSilenty(Exchange ex)
-    {
-      if ( ex != null)
-      {
-        db.releaseExchange(ex);
       }
     }
 
@@ -466,7 +442,7 @@
       finally
       {
         exchanges.values().remove(ex);
-        db.releaseExchange(ex);
+        releaseExchange(ex);
       }
     }
 
@@ -588,7 +564,7 @@
       }
       finally
       {
-        db.releaseExchange(ex);
+        releaseExchange(ex);
       }
     }
 
@@ -608,7 +584,7 @@
     {
       for (final Exchange ex : exchanges.values())
       {
-        db.releaseExchange(ex);
+        releaseExchange(ex);
       }
       exchanges.clear();
     }
@@ -663,7 +639,7 @@
       }
       finally
       {
-        db.releaseExchange(ex);
+        releaseExchange(ex);
       }
     }
 
@@ -698,9 +674,21 @@
     }
   }
 
-  private Exchange getNewExchange(final TreeName treeName, final boolean create) throws PersistitException
+  Exchange getNewExchange(final TreeName treeName, final boolean create) throws PersistitException
   {
-    return db.getExchange(volume, treeName.toString(), create);
+    final Exchange ex = db.getExchange(volume, treeName.toString(), create);
+    ex.setMaximumValueSize(Value.MAXIMUM_SIZE);
+    return ex;
+  }
+
+  void releaseExchange(Exchange ex)
+  {
+    // Don't keep exchanges with enlarged value - let them be GC'd.
+    // This is also done internally by Persistit in TransactionPlayer line 197.
+    if (ex.getValue().getEncodedBytes().length < Value.DEFAULT_MAXIMUM_SIZE)
+    {
+      db.releaseExchange(ex);
+    }
   }
 
   private StorageImpl newStorageImpl() {

--
Gitblit v1.10.0