From 90b5a1ce685dc1aaad65067d8bea7b3a6d9ad0fc Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Thu, 30 Aug 2007 23:03:00 +0000
Subject: [PATCH] Fixed an issue where contention on a index key might cause the index to become corrupt. The index now uses the useNoOverwrite method to insert a  new key to prevent the race condition.

---
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/Index.java |   69 ++++++++++++++++++++--------------
 1 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/Index.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/Index.java
index e2a8b11..4d71de9 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/Index.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/Index.java
@@ -187,44 +187,57 @@
     DatabaseEntry entryIDData = entryID.getDatabaseEntry();
     DatabaseEntry data = new DatabaseEntry();
     boolean success = true;
+    boolean done = false;
 
-    status = read(txn, key, data, lockMode);
-
-    if (status == OperationStatus.SUCCESS)
+    while(!done)
     {
-      EntryIDSet entryIDList =
-           new EntryIDSet(key.getData(), data.getData());
-      if (entryIDList.isDefined())
+      status = read(txn, key, data, lockMode);
+
+      if (status == OperationStatus.SUCCESS)
       {
-        if (indexEntryLimit > 0 && entryIDList.size() >= indexEntryLimit)
+        EntryIDSet entryIDList =
+            new EntryIDSet(key.getData(), data.getData());
+        if (entryIDList.isDefined())
         {
-          entryIDList = new EntryIDSet(entryIDList.size());
-          entryLimitExceededCount++;
-
-          if(debugEnabled())
+          if (indexEntryLimit > 0 && entryIDList.size() >= indexEntryLimit)
           {
-            StringBuilder builder = new StringBuilder();
-            StaticUtils.byteArrayToHexPlusAscii(builder, key.getData(), 4);
-            TRACER.debugInfo("Index entry exceeded in index %s. " +
-                "Limit: %d. ID list size: %d.\nKey:",
-                             name, indexEntryLimit, entryIDList.size(),
-                             builder);
+            entryIDList = new EntryIDSet(entryIDList.size());
+            entryLimitExceededCount++;
 
+            if(debugEnabled())
+            {
+              StringBuilder builder = new StringBuilder();
+              StaticUtils.byteArrayToHexPlusAscii(builder, key.getData(), 4);
+              TRACER.debugInfo("Index entry exceeded in index %s. " +
+                  "Limit: %d. ID list size: %d.\nKey:",
+                               name, indexEntryLimit, entryIDList.size(),
+                               builder);
+
+            }
           }
         }
+
+        success = entryIDList.add(entryID);
+
+        byte[] after = entryIDList.toDatabase();
+        data.setData(after);
+        put(txn, key, data);
+        done = true;
       }
-
-      success = entryIDList.add(entryID);
-
-      byte[] after = entryIDList.toDatabase();
-      data.setData(after);
-      put(txn, key, data);
-    }
-    else
-    {
-      if(rebuildRunning || trusted)
+      else
       {
-        put(txn, key, entryIDData);
+        if(rebuildRunning || trusted)
+        {
+          status = insert(txn, key, entryIDData);
+          if(status == OperationStatus.SUCCESS)
+          {
+            done = true;
+          }
+        }
+        else
+        {
+          done = true;
+        }
       }
     }
 

--
Gitblit v1.10.0