From 21e188d6ae36425c2c01c3fe7fcf15241cc725c1 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Fri, 27 Jul 2007 21:06:35 +0000
Subject: [PATCH] These set of changes implement VLV and filter capability to OpenDS:

---
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexRebuildThread.java |  193 +++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 164 insertions(+), 29 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexRebuildThread.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexRebuildThread.java
index 2937a90..61400bf 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexRebuildThread.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexRebuildThread.java
@@ -71,6 +71,11 @@
   AttributeIndex attrIndex = null;
 
   /**
+   * The VLV index to rebuild.
+   */
+  VLVIndex vlvIndex = null;
+
+  /**
    * The indexType to rebuild.
    */
   Index index = null;
@@ -112,7 +117,7 @@
    */
   enum IndexType
   {
-    DN2ID, DN2URI, ID2CHILDREN, ID2SUBTREE, INDEX, ATTRIBUTEINDEX
+    DN2ID, DN2URI, ID2CHILDREN, ID2SUBTREE, INDEX, ATTRIBUTEINDEX, VLVINDEX
   }
 
   /**
@@ -161,6 +166,21 @@
   }
 
   /**
+   * Construct a new index rebuild thread to rebuild an VLV index.
+   *
+   * @param ec The entry container to rebuild in.
+   * @param vlvIndex The VLV index to rebuild.
+   */
+  IndexRebuildThread(EntryContainer ec, VLVIndex vlvIndex)
+  {
+    super("Index Rebuild Thread " + vlvIndex.getName());
+    this.ec = ec;
+    this.indexType = IndexType.VLVINDEX;
+    this.vlvIndex = vlvIndex;
+    this.id2entry = ec.getID2Entry();
+  }
+
+  /**
    * Clear the database and prep it for the rebuild.
    *
    * @throws DatabaseException if a JE databse error occurs while clearing
@@ -202,6 +222,18 @@
       return;
     }
 
+    if(indexType == IndexType.VLVINDEX && vlvIndex == null)
+    {
+      //TODO: throw error
+      if(debugEnabled())
+      {
+        TRACER.debugError("No VLV index specified. Rebuild process " +
+            "terminated.");
+      }
+
+      return;
+    }
+
     switch(indexType)
     {
       case DN2ID :
@@ -222,6 +254,10 @@
         ec.clearAttributeIndex(attrIndex);
         attrIndex.setRebuildStatus(true);
         break;
+      case VLVINDEX :
+        ec.clearDatabase(vlvIndex);
+        vlvIndex.setRebuildStatus(true);
+        break;
       case INDEX :
         ec.clearDatabase(index);
         index.setRebuildStatus(true);
@@ -267,6 +303,18 @@
       return;
     }
 
+    if(indexType == IndexType.VLVINDEX && vlvIndex == null)
+    {
+      //TODO: throw error
+      if(debugEnabled())
+      {
+        TRACER.debugError("No VLV index specified. Rebuild process " +
+            "terminated.");
+      }
+
+      return;
+    }
+
     try
     {
       totalEntries = getTotalEntries();
@@ -283,6 +331,8 @@
           break;
         case ATTRIBUTEINDEX : rebuildAttributeIndex(attrIndex);
           break;
+        case VLVINDEX : rebuildVLVIndex(vlvIndex);
+          break;
         case INDEX : rebuildAttributeIndex(index);
       }
 
@@ -325,7 +375,7 @@
 
     //Iterate through the id2entry database and insert associated dn2id
     //records.
-    Cursor cursor = id2entry.openCursor(null, null);
+    Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
     try
     {
       DatabaseEntry key = new DatabaseEntry();
@@ -337,15 +387,14 @@
            status == OperationStatus.SUCCESS;
            status = cursor.getNext(key, data, lockMode))
       {
+        Transaction txn = ec.beginTransaction();
         try
         {
           EntryID entryID = new EntryID(key);
           Entry entry = JebFormat.entryFromDatabase(data.getData());
 
-          //TODO: Should we add all records in a big transaction?
-          //TODO: Should we make each insert a transaction?
           // Insert into dn2id.
-          if (dn2id.insert(null, entry.getDN(), entryID))
+          if (dn2id.insert(txn, entry.getDN(), entryID))
           {
             rebuiltEntries++;
           }
@@ -363,13 +412,12 @@
                         entry.getDN().toString(), entryID.longValue());
             }
           }
+          EntryContainer.transactionCommit(txn);
           processedEntries++;
         }
         catch (Exception e)
         {
-          //TODO: throw error stating that the indexType could be in an
-          // inconsistant state.
-          //TODO: Should we continue on or stop right now?
+          EntryContainer.transactionAbort(txn);
           skippedEntries++;
 
           int    msgID   = MSGID_JEB_REBUILD_INSERT_ENTRY_FAILED;
@@ -410,7 +458,7 @@
 
     //Iterate through the id2entry database and insert associated dn2uri
     //records.
-    Cursor cursor = id2entry.openCursor(null, null);
+    Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
     try
     {
       DatabaseEntry key = new DatabaseEntry();
@@ -423,15 +471,14 @@
            status == OperationStatus.SUCCESS;
            status = cursor.getNext(key, data, lockMode))
       {
+        Transaction txn = ec.beginTransaction();
         try
         {
           EntryID entryID = new EntryID(key);
           Entry entry = JebFormat.entryFromDatabase(data.getData());
 
-          //TODO: Should we add all records in a big transaction?
-          //TODO: Should we make each insert a transaction?
           // Insert into dn2uri.
-          if (dn2uri.addEntry(null, entry))
+          if (dn2uri.addEntry(txn, entry))
           {
             rebuiltEntries++;
           }
@@ -449,13 +496,12 @@
                         entry.getDN().toString(), entryID.longValue());
             }
           }
+          EntryContainer.transactionCommit(txn);
           processedEntries++;
         }
         catch (Exception e)
         {
-          //TODO: throw error stating that the indexType could be in an
-          // inconsistant state.
-          //TODO: Should we continue on or stop right now?
+          EntryContainer.transactionAbort(txn);
           skippedEntries++;
 
           int    msgID   = MSGID_JEB_REBUILD_INSERT_ENTRY_FAILED;
@@ -500,7 +546,7 @@
 
     //Iterate through the id2entry database and insert associated dn2children
     //records.
-    Cursor cursor = id2entry.openCursor(null, null);
+    Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
     try
     {
       DatabaseEntry key = new DatabaseEntry();
@@ -512,6 +558,7 @@
            status == OperationStatus.SUCCESS;
            status = cursor.getNext(key, data, lockMode))
       {
+        Transaction txn = ec.beginTransaction();
         try
         {
           EntryID entryID = new EntryID(key);
@@ -525,11 +572,11 @@
             dn2uri.targetEntryReferrals(entry.getDN(), null);
 
             // Read the parent ID from dn2id.
-            EntryID parentID = dn2id.get(null, parentDN);
+            EntryID parentID = dn2id.get(txn, parentDN);
             if (parentID != null)
             {
               // Insert into id2children for parent ID.
-              if(id2children.insertID(null, parentID.getDatabaseEntry(),
+              if(id2children.insertID(txn, parentID.getDatabaseEntry(),
                                       entryID))
               {
                 rebuiltEntries++;
@@ -561,11 +608,12 @@
           {
             skippedEntries++;
           }
+          EntryContainer.transactionCommit(txn);
           processedEntries++;
         }
         catch (Exception e)
         {
-          //TODO: Should we continue on or stop right now?
+          EntryContainer.transactionAbort(txn);
           skippedEntries++;
 
           int    msgID   = MSGID_JEB_REBUILD_INSERT_ENTRY_FAILED;
@@ -612,7 +660,7 @@
 
     //Iterate through the id2entry database and insert associated dn2subtree
     //records.
-    Cursor cursor = id2entry.openCursor(null, null);
+    Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
     try
     {
       DatabaseEntry key = new DatabaseEntry();
@@ -624,6 +672,7 @@
            status == OperationStatus.SUCCESS;
            status = cursor.getNext(key, data, lockMode))
       {
+        Transaction txn = ec.beginTransaction();
         try
         {
           EntryID entryID = new EntryID(key);
@@ -639,11 +688,11 @@
             dn2uri.targetEntryReferrals(entry.getDN(), null);
 
             // Read the parent ID from dn2id.
-            EntryID parentID = dn2id.get(null, parentDN);
+            EntryID parentID = dn2id.get(txn, parentDN);
             if (parentID != null)
             {
               // Insert into id2subtree for parent ID.
-              if(!id2subtree.insertID(null, parentID.getDatabaseEntry(),
+              if(!id2subtree.insertID(txn, parentID.getDatabaseEntry(),
                                       entryID))
               {
                 success = false;
@@ -703,11 +752,12 @@
           {
             skippedEntries++;
           }
+          EntryContainer.transactionCommit(txn);
           processedEntries++;
         }
         catch (Exception e)
         {
-          //TODO: Should we continue on or stop right now?
+          EntryContainer.transactionAbort(txn);
           skippedEntries++;
 
           int    msgID   = MSGID_JEB_REBUILD_INSERT_ENTRY_FAILED;
@@ -749,7 +799,7 @@
 
     //Iterate through the id2entry database and insert associated indexType
     //records.
-    Cursor cursor = id2entry.openCursor(null, null);
+    Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
     try
     {
       DatabaseEntry key = new DatabaseEntry();
@@ -761,13 +811,14 @@
            status == OperationStatus.SUCCESS;
            status = cursor.getNext(key, data, lockMode))
       {
+        Transaction txn = ec.beginTransaction();
         try
         {
           EntryID entryID = new EntryID(key);
           Entry entry = JebFormat.entryFromDatabase(data.getData());
 
           // Insert into attribute indexType.
-          if(index.addEntry(null, entryID, entry))
+          if(index.addEntry(txn, entryID, entry))
           {
             rebuiltEntries++;
           }
@@ -786,11 +837,12 @@
                         entry.getDN().toString(), entryID.longValue());
             }
           }
+          EntryContainer.transactionCommit(txn);
           processedEntries++;
         }
         catch (Exception e)
         {
-          //TODO: Should we continue on or stop right now?
+          EntryContainer.transactionAbort(txn);
           skippedEntries++;
 
           int    msgID   = MSGID_JEB_REBUILD_INSERT_ENTRY_FAILED;
@@ -815,6 +867,87 @@
   }
 
   /**
+   * Rebuild the VLV index.
+   *
+   * @param vlvIndex The VLV index to rebuild.
+   * @throws DatabaseException if an error occurs during rebuild.
+   */
+  private void rebuildVLVIndex(VLVIndex vlvIndex)
+      throws DatabaseException
+  {
+
+    //Iterate through the id2entry database and insert associated indexType
+    //records.
+    Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
+    try
+    {
+      DatabaseEntry key = new DatabaseEntry();
+      DatabaseEntry data = new DatabaseEntry();
+      LockMode lockMode = LockMode.DEFAULT;
+
+      OperationStatus status;
+      for (status = cursor.getFirst(key, data, lockMode);
+           status == OperationStatus.SUCCESS;
+           status = cursor.getNext(key, data, lockMode))
+      {
+        Transaction txn = ec.beginTransaction();
+        try
+        {
+          EntryID entryID = new EntryID(key);
+          Entry entry = JebFormat.entryFromDatabase(data.getData());
+
+          // Insert into attribute indexType.
+          if(vlvIndex.addEntry(txn, entryID, entry))
+          {
+            rebuiltEntries++;
+          }
+          else
+          {
+            // The entry already exists in one or more entry sets.
+            // This could happen if some other process got to this entry
+            // before we did. Since the backend should be offline, this
+            // might be a problem.
+            if(debugEnabled())
+            {
+              duplicatedEntries++;
+              TRACER.debugInfo("Unable to insert entry with DN %s and ID %d " +
+                  "into the VLV index %s because it already " +
+                  "exists.",
+                        entry.getDN().toString(), entryID.longValue(),
+                        vlvIndex.getName());
+            }
+          }
+
+          EntryContainer.transactionCommit(txn);
+          processedEntries++;
+        }
+        catch (Exception e)
+        {
+          EntryContainer.transactionAbort(txn);
+          skippedEntries++;
+
+          int    msgID   = MSGID_JEB_REBUILD_INSERT_ENTRY_FAILED;
+          String message = getMessage(msgID, index.getName(),
+                                      stackTraceToSingleLineString(e));
+          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.MILD_ERROR,
+                   message, msgID);
+
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
+        }
+      }
+      vlvIndex.setRebuildStatus(false);
+      vlvIndex.setTrusted(null, true);
+    }
+    finally
+    {
+      cursor.close();
+    }
+  }
+
+  /**
    * Rebuild the partial attribute index.
    *
    * @param index The indexType to rebuild.
@@ -832,7 +965,7 @@
 
     //Iterate through the id2entry database and insert associated indexType
     //records.
-    Cursor cursor = id2entry.openCursor(null, null);
+    Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
     try
     {
       DatabaseEntry key = new DatabaseEntry();
@@ -844,13 +977,14 @@
            status == OperationStatus.SUCCESS;
            status = cursor.getNext(key, data, lockMode))
       {
+        Transaction txn = ec.beginTransaction();
         try
         {
           EntryID entryID = new EntryID(key);
           Entry entry = JebFormat.entryFromDatabase(data.getData());
 
           // Insert into attribute indexType.
-          if(index.addEntry(null, entryID, entry))
+          if(index.addEntry(txn, entryID, entry))
           {
             rebuiltEntries++;
           }
@@ -869,11 +1003,12 @@
                         entry.getDN().toString(), entryID.longValue());
             }
           }
+          EntryContainer.transactionCommit(txn);
           processedEntries++;
         }
         catch (Exception e)
         {
-          //TODO: Should we continue on or stop right now?
+          EntryContainer.transactionAbort(txn);
           skippedEntries++;
 
           int    msgID   = MSGID_JEB_REBUILD_INSERT_ENTRY_FAILED;

--
Gitblit v1.10.0