From cd865cbe3527a26276410ecf6de14df2c6bcf1b1 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Mon, 06 Jan 2014 15:04:36 +0000
Subject: [PATCH] Fix OPENDJ-1266 State index is not updated when an index is deleted

---
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java |   86 +++++++++------------
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/State.java          |   97 ++++++------------------
 2 files changed, 60 insertions(+), 123 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
index eb19fae..2305812 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2006-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2013 ForgeRock AS
+ *      Portions Copyright 2011-2014 ForgeRock AS
  *      Portions copyright 2013 Manuel Gaupp
  */
 package org.opends.server.backends.jeb;
@@ -3391,71 +3391,57 @@
   throws DatabaseException
   {
     index.close();
-    if(env.getConfig().getTransactional())
-    {
-      Transaction txn = beginTransaction();
-      try
-      {
-        if(index.equalityIndex != null)
-        {
-          env.removeDatabase(txn, index.equalityIndex.getName());
-          state.removeIndexTrustState(txn, index.equalityIndex);
-        }
-        if(index.presenceIndex != null)
-        {
-          env.removeDatabase(txn, index.presenceIndex.getName());
-          state.removeIndexTrustState(txn, index.presenceIndex);
-        }
-        if(index.substringIndex != null)
-        {
-          env.removeDatabase(txn, index.substringIndex.getName());
-          state.removeIndexTrustState(txn, index.substringIndex);
-        }
-        if(index.orderingIndex != null)
-        {
-          env.removeDatabase(txn, index.orderingIndex.getName());
-          state.removeIndexTrustState(txn, index.orderingIndex);
-        }
-        if(index.approximateIndex != null)
-        {
-          env.removeDatabase(txn, index.approximateIndex.getName());
-          state.removeIndexTrustState(txn, index.approximateIndex);
-        }
-        transactionCommit(txn);
-      }
-      catch(DatabaseException de)
-      {
-        transactionAbort(txn);
-        throw de;
-      }
-    }
-    else
+    Transaction txn = env.getConfig().getTransactional()
+      ? beginTransaction() : null;
+    try
     {
       if(index.equalityIndex != null)
       {
-        env.removeDatabase(null, index.equalityIndex.getName());
-        state.removeIndexTrustState(null, index.equalityIndex);
+        env.removeDatabase(txn, index.equalityIndex.getName());
+        state.removeIndexTrustState(txn, index.equalityIndex);
       }
       if(index.presenceIndex != null)
       {
-        env.removeDatabase(null, index.presenceIndex.getName());
-        state.removeIndexTrustState(null, index.presenceIndex);
+        env.removeDatabase(txn, index.presenceIndex.getName());
+        state.removeIndexTrustState(txn, index.presenceIndex);
       }
       if(index.substringIndex != null)
       {
-        env.removeDatabase(null, index.substringIndex.getName());
-        state.removeIndexTrustState(null, index.substringIndex);
+        env.removeDatabase(txn, index.substringIndex.getName());
+        state.removeIndexTrustState(txn, index.substringIndex);
       }
       if(index.orderingIndex != null)
       {
-        env.removeDatabase(null, index.orderingIndex.getName());
-        state.removeIndexTrustState(null, index.orderingIndex);
+        env.removeDatabase(txn, index.orderingIndex.getName());
+        state.removeIndexTrustState(txn, index.orderingIndex);
       }
       if(index.approximateIndex != null)
       {
-        env.removeDatabase(null, index.approximateIndex.getName());
-        state.removeIndexTrustState(null, index.approximateIndex);
+        env.removeDatabase(txn, index.approximateIndex.getName());
+        state.removeIndexTrustState(txn, index.approximateIndex);
       }
+      Map <String,Collection<Index>> extensibleIndexes =
+        index.getExtensibleIndexes();
+      for (String name : extensibleIndexes.keySet())
+      {
+        for (Index extensibleIndex : extensibleIndexes.get(name))
+        {
+          env.removeDatabase(txn, extensibleIndex.getName());
+          state.removeIndexTrustState(txn, extensibleIndex);
+        }
+      }
+      if (txn != null)
+      {
+        transactionCommit(txn);
+      }
+    }
+    catch(DatabaseException de)
+    {
+      if (txn != null)
+      {
+        transactionAbort(txn);
+      }
+      throw de;
     }
   }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/State.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/State.java
index 41d061f..2029315 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/State.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/State.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS
+ *      Portions copyright 2011-2014 ForgeRock AS
  */
 package org.opends.server.backends.jeb;
 
@@ -79,6 +79,23 @@
   }
 
   /**
+   * Return the key associated with the index in the state database.
+   *
+   * @param index The index we need the key for.
+   * @return the key
+   * @throws DatabaseException If an error occurs in the JE database.
+   */
+  private DatabaseEntry keyForIndex(DatabaseContainer index)
+    throws DatabaseException
+  {
+    String shortName =
+      index.getName().replace(entryContainer.getDatabasePrefix(), "");
+    DatabaseEntry key =
+      new DatabaseEntry(StaticUtils.getBytes(shortName));
+    return key;
+  }
+
+  /**
    * Remove a record from the entry database.
    *
    * @param txn The database transaction or null if none.
@@ -86,11 +103,10 @@
    * @return true if the entry was removed, false if it was not.
    * @throws DatabaseException If an error occurs in the JE database.
    */
-  public boolean removeIndexTrustState(Transaction txn, Index index)
+  public boolean removeIndexTrustState(Transaction txn, DatabaseContainer index)
        throws DatabaseException
   {
-    DatabaseEntry key =
-        new DatabaseEntry(StaticUtils.getBytes(index.getName()));
+    DatabaseEntry key = keyForIndex(index);
 
     OperationStatus status = delete(txn, key);
     if (status != OperationStatus.SUCCESS)
@@ -107,41 +123,10 @@
    * @return The trusted state of the index in the database.
    * @throws DatabaseException If an error occurs in the JE database.
    */
-  public boolean getIndexTrustState(Transaction txn, Index index)
+  public boolean getIndexTrustState(Transaction txn, DatabaseContainer index)
       throws DatabaseException
   {
-    String sortName =
-        index.getName().replace(entryContainer.getDatabasePrefix(), "");
-    DatabaseEntry key =
-        new DatabaseEntry(StaticUtils.getBytes(sortName));
-    DatabaseEntry data = new DatabaseEntry();
-
-    OperationStatus status;
-    status = read(txn, key, data, LockMode.DEFAULT);
-
-    if (status != OperationStatus.SUCCESS)
-    {
-      return false;
-    }
-
-    byte[] bytes = data.getData();
-    return Arrays.equals(bytes, trueBytes);
-  }
-
-  /**
-   * Fetch index state from the database.
-   * @param txn The database transaction or null if none.
-   * @param vlvIndex The index storing the trusted state info.
-   * @return The trusted state of the index in the database.
-   * @throws DatabaseException If an error occurs in the JE database.
-   */
-  public boolean getIndexTrustState(Transaction txn, VLVIndex vlvIndex)
-      throws DatabaseException
-  {
-    String shortName =
-        vlvIndex.getName().replace(entryContainer.getDatabasePrefix(), "");
-    DatabaseEntry key =
-        new DatabaseEntry(StaticUtils.getBytes(shortName));
+    DatabaseEntry key = keyForIndex(index);
     DatabaseEntry data = new DatabaseEntry();
 
     OperationStatus status;
@@ -164,14 +149,11 @@
    * @return true if the entry was written, false if it was not.
    * @throws DatabaseException If an error occurs in the JE database.
    */
-  public boolean putIndexTrustState(Transaction txn, Index index,
+  public boolean putIndexTrustState(Transaction txn, DatabaseContainer index,
                                     boolean trusted)
        throws DatabaseException
   {
-    String shortName =
-        index.getName().replace(entryContainer.getDatabasePrefix(), "");
-    DatabaseEntry key =
-        new DatabaseEntry(StaticUtils.getBytes(shortName));
+    DatabaseEntry key = keyForIndex(index);
     DatabaseEntry data = new DatabaseEntry();
 
     if(trusted)
@@ -188,35 +170,4 @@
     return true;
   }
 
-  /**
-   * Put VLV index state to database.
-   * @param txn The database transaction or null if none.
-   * @param vlvIndex The VLV index storing the trusted state info.
-   * @param trusted The state value to put into the database.
-   * @return true if the entry was written, false if it was not.
-   * @throws DatabaseException If an error occurs in the JE database.
-   */
-  public boolean putIndexTrustState(Transaction txn, VLVIndex vlvIndex,
-                                    boolean trusted)
-       throws DatabaseException
-  {
-    String shortName =
-        vlvIndex.getName().replace(entryContainer.getDatabasePrefix(), "");
-    DatabaseEntry key =
-        new DatabaseEntry(StaticUtils.getBytes(shortName));
-    DatabaseEntry data = new DatabaseEntry();
-
-    if(trusted)
-      data.setData(trueBytes);
-    else
-      data.setData(falseBytes);
-
-    OperationStatus status;
-    status = put(txn, key, data);
-    if (status != OperationStatus.SUCCESS)
-    {
-      return false;
-    }
-    return true;
-  }
 }

--
Gitblit v1.10.0