From 5c3196a7dc35588f22aa086e4e5cf6a563ec0de0 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Wed, 08 Nov 2006 20:19:03 +0000
Subject: [PATCH] This fix removes the static nextId property as well as the getters and setters for it out of the EntryID class. The nextId property is now a non static property in the RootContainer class. Each RootContainer is responsible for keeping track of the next ID and assigning new entry IDs to all entries in its EntryContainers. 

---
 opends/src/server/org/opends/server/backends/jeb/RootContainer.java       |   67 +++++++++++++
 opends/src/server/org/opends/server/backends/jeb/EntryContainer.java      |   62 ++++++++---
 opends/src/server/org/opends/server/messages/JebMessages.java             |   10 ++
 opends/src/server/org/opends/server/backends/jeb/BackendImpl.java         |   43 +++-----
 opends/src/server/org/opends/server/backends/jeb/ImportJob.java           |   13 --
 opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java          |    4 
 opends/src/server/org/opends/server/backends/jeb/EntryID.java             |   43 --------
 opends/src/server/org/opends/server/backends/jeb/IndexIteratorAllIds.java |    7 +
 8 files changed, 143 insertions(+), 106 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
index aab7133..a1b3094 100644
--- a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -344,35 +344,23 @@
     // Preload the database cache.
     rootContainer.preload();
 
-    // Determine the next entry ID and the total number of entries.
-    EntryID highestID = null;
-    long entryCount = 0;
-    for (EntryContainer ec : rootContainer.getEntryContainers())
+    try
     {
-      try
-      {
-        EntryID id = ec.getHighestEntryID();
-        if (highestID == null || id.compareTo(highestID) > 0)
-        {
-          highestID = id;
-        }
-        entryCount += ec.getEntryCount();
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeBackend", e);
-        String message = getMessage(MSGID_JEB_HIGHEST_ID_FAIL);
-        throw new InitializationException(MSGID_JEB_HIGHEST_ID_FAIL,
-                                          message, e);
-      }
+      // Log an informational message about the number of entries.
+      int msgID = MSGID_JEB_BACKEND_STARTED;
+      String message = getMessage(msgID, rootContainer.getEntryCount());
+      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.NOTICE, message,
+               msgID);
     }
-    EntryID.initialize(highestID);
-
-    // Log an informational message about the number of entries.
-    int msgID = MSGID_JEB_BACKEND_STARTED;
-    String message = getMessage(msgID, entryCount);
-    logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.NOTICE, message,
-             msgID);
+    catch(DatabaseException databaseException)
+    {
+      assert debugException(CLASS_NAME, "initializeBackend",
+                            databaseException);
+      String message = getMessage(MSGID_JEB_GET_ENTRY_COUNT_FAILED,
+                                  databaseException.getMessage());
+      throw new InitializationException(MSGID_JEB_GET_ENTRY_COUNT_FAILED,
+                                        message, databaseException);
+    }
 
     // Register this backend as a configurable component.
     DirectoryServer.registerConfigurableComponent(this);
@@ -400,6 +388,7 @@
     assert debugEnter(CLASS_NAME, "finalizeBackend");
 
     // Deregister our configurable components.
+    // TODO: configurableEnv is always null and will not be deregistered.
     if (configurableEnv != null)
     {
       DirectoryServer.deregisterConfigurableComponent(configurableEnv);
diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
index 9363442..97388e7 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -125,6 +125,11 @@
   private Backend backend;
 
   /**
+   * The root container in which this entryContainer belongs.
+   */
+  private RootContainer rootContainer;
+
+  /**
    * The baseDN this entry container is responsible for.
    */
   private DN baseDN;
@@ -194,15 +199,17 @@
    *                container. It is needed by the Directory Server entry cache
    *                methods.
    * @param config The configuration of the JE backend.
-   * @param env The JE environment to create this entryContainer in
+   * @param env The JE environment to create this entryContainer in.
+   * @param rootContainer The root container this entry container is in.
    */
   public EntryContainer(DN baseDN, Backend backend, Config config,
-                        Environment env)
+                        Environment env, RootContainer rootContainer)
   {
     this.backend = backend;
     this.baseDN = baseDN;
     this.config = config;
     this.env = env;
+    this.rootContainer = rootContainer;
 
     // Instantiate the list of database handles.
     databases = new ArrayList<Database>();
@@ -493,10 +500,9 @@
    * The entryContainer must already be open.
    *
    * @return The highest entry ID.
-   * @throws JebException If an error occurs in the JE backend.
    * @throws DatabaseException If an error occurs in the JE database.
    */
-  public EntryID getHighestEntryID() throws JebException, DatabaseException
+  public EntryID getHighestEntryID() throws DatabaseException
   {
     EntryID entryID = new EntryID(0);
     Cursor cursor = id2entry.openCursor(null, null);
@@ -1455,7 +1461,7 @@
       // First time through, assign the next entryID.
       if (entryID == null)
       {
-        entryID = EntryID.assignNext();
+        entryID = rootContainer.getNextEntryID();
       }
 
       // Insert into dn2id.
@@ -2573,7 +2579,12 @@
                                                         DirectoryException,
                                                         JebException
     {
-      DN requestedNewSuperiorDN = modifyDNOperation.getNewSuperior();
+      DN requestedNewSuperiorDN = null;
+
+      if(modifyDNOperation != null)
+      {
+        requestedNewSuperiorDN = modifyDNOperation.getNewSuperior();
+      }
 
       // Check whether the renamed entry already exists.
       if (dn2id.get(txn, newApexEntry.getDN()) != null)
@@ -2634,7 +2645,7 @@
           // renumber every entry that moves. This is even more
           // expensive since every entry has to be deleted from
           // and added back into the attribute indexes.
-          newApexID = EntryID.assignNext();
+          newApexID = rootContainer.getNextEntryID();
         }
       }
 
@@ -2710,7 +2721,7 @@
             EntryID newID = oldID;
             if (!newApexID.equals(oldApexID))
             {
-              newID = EntryID.assignNext();
+              newID = rootContainer.getNextEntryID();
             }
 
             // Move this entry.
@@ -2786,7 +2797,7 @@
       dn2uri.replaceEntry(txn, oldEntry, newEntry);
 
       // Remove the old ID from id2entry.
-      if (!newID.equals(oldID))
+      if (!newID.equals(oldID) || modifyDNOperation == null)
       {
         id2entry.remove(txn, oldID);
 
@@ -2866,10 +2877,11 @@
      * @param newEntry The new contents of the target entry.
      * @throws DirectoryException If a Directory Server error occurs.
      * @throws DatabaseException If an error occurs in the JE database.
+     * @throws JebException if an error occurs in the JE database.
      */
     private void renameApexEntry(Transaction txn, EntryID entryID,
                                  Entry oldEntry, Entry newEntry)
-         throws DirectoryException, DatabaseException
+         throws DirectoryException, DatabaseException, JebException
     {
       DN oldDN = oldEntry.getDN();
       DN newDN = newEntry.getDN();
@@ -2892,9 +2904,20 @@
       // Replace the entry in id2entry.
       id2entry.put(txn, entryID, newEntry);
 
-      // Update indexes only for those attributes that changed.
-      indexModifications(txn, oldEntry, newEntry, entryID,
-                         modifyDNOperation.getModifications());
+      if(modifyDNOperation == null)
+      {
+        // Remove the old ID from the indexes.
+        indexRemoveEntry(txn, oldEntry, entryID);
+
+        // Insert the new ID into the indexes.
+        indexInsertEntry(txn, newEntry, entryID);
+      }
+      else
+      {
+        // Update indexes only for those attributes that changed.
+        indexModifications(txn, oldEntry, newEntry, entryID,
+                           modifyDNOperation.getModifications());
+      }
 
       // Remove the entry from the entry cache.
       EntryCache entryCache = DirectoryServer.getEntryCache();
@@ -3326,14 +3349,17 @@
    */
   public static boolean isManageDsaITOperation(Operation operation)
   {
-    List<Control> controls = operation.getRequestControls();
-    if (controls != null)
+    if(operation != null)
     {
-      for (Control control : controls)
+      List<Control> controls = operation.getRequestControls();
+      if (controls != null)
       {
-        if (control.getOID().equals(ServerConstants.OID_MANAGE_DSAIT_CONTROL))
+        for (Control control : controls)
         {
-          return true;
+          if (control.getOID().equals(ServerConstants.OID_MANAGE_DSAIT_CONTROL))
+          {
+            return true;
+          }
         }
       }
     }
diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryID.java b/opends/src/server/org/opends/server/backends/jeb/EntryID.java
index 5d5c99d..95ab922 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryID.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryID.java
@@ -28,8 +28,6 @@
 
 import com.sleepycat.je.DatabaseEntry;
 
-import java.util.concurrent.atomic.AtomicLong;
-
 /**
  * An integer identifier assigned to each entry in the JE backend.
  * An entry ID is implemented by this class as a long.
@@ -39,11 +37,6 @@
 public class EntryID implements Comparable<EntryID>
 {
   /**
-   * The cached value of the next identifier to be assigned.
-   */
-  private static AtomicLong nextid = new AtomicLong(1);
-
-  /**
    * The identifier integer value.
    */
   private final Long id;
@@ -105,42 +98,6 @@
   }
 
   /**
-   * Initialize the next ID counter from the previous highest value.
-   * @param highestID The previous highest entry ID.
-   */
-  public static void initialize(EntryID highestID)
-  {
-    nextid = new AtomicLong(highestID.id + 1);
-  }
-
-  /**
-   * Assign the next entry ID.
-   * @return The assigned entry ID.
-   */
-  public static EntryID assignNext()
-  {
-    return new EntryID(nextid.getAndIncrement());
-  }
-
-  /**
-   * Return the lowest entry ID assigned.
-   * @return The lowest entry ID assigned.
-   */
-  public static Long getLowest()
-  {
-    return 1L;
-  }
-
-  /**
-   * Return the highest entry ID assigned.
-   * @return The highest entry ID assigned.
-   */
-  public static Long getHighest()
-  {
-    return (nextid.get() - 1);
-  }
-
-  /**
    * Compares this object with the specified object for order.  Returns a
    * negative integer, zero, or a positive integer as this object is less
    * than, equal to, or greater than the specified object.<p>
diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java b/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java
index 4721d14..267f7e3 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java
@@ -598,7 +598,7 @@
   }
 
   /**
-   * Create an iterator over the set, or over the entire database
+   * Create an iterator over the set or an empty iterator
    * if the set is not defined.
    *
    * @return An EntryID iterator.
@@ -608,7 +608,7 @@
     if (values == null)
     {
       // The set is not defined.
-      return new IndexIteratorAllIds();
+      return new IDSetIterator(new long[0]);
     }
     else
     {
diff --git a/opends/src/server/org/opends/server/backends/jeb/ImportJob.java b/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
index ae9fc55..c8ae959 100644
--- a/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
+++ b/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
@@ -215,20 +215,12 @@
     rootContainer.openEntryContainers(config.getBaseDNs());
 
     // Create the import contexts for each base DN.
-    EntryID highestID = null;
     DN baseDN;
 
     for (EntryContainer entryContainer : rootContainer.getEntryContainers())
     {
       baseDN = entryContainer.getBaseDN();
 
-      // Keep track of the highest entry ID.
-      EntryID id = entryContainer.getHighestEntryID();
-      if (highestID == null || id.compareTo(highestID) > 0)
-      {
-        highestID = id;
-      }
-
       // Create an import context.
       ImportContext importContext = new ImportContext();
       importContext.setBufferSize(bufferSize);
@@ -248,9 +240,6 @@
       importMap.put(baseDN, importContext);
     }
 
-    // Initialize the entry ID generator.
-    EntryID.initialize(highestID);
-
     // Make a note of the time we started.
     long startTime = System.currentTimeMillis();
 
@@ -691,7 +680,7 @@
         }
 
         // Assign a new entry identifier and write the new DN.
-        entryID = EntryID.assignNext();
+        entryID = rootContainer.getNextEntryID();
         dn2id.insert(txn, entryDN, entryID);
 
         // Construct a list of IDs up the DIT.
diff --git a/opends/src/server/org/opends/server/backends/jeb/IndexIteratorAllIds.java b/opends/src/server/org/opends/server/backends/jeb/IndexIteratorAllIds.java
index c682658..29cb318 100644
--- a/opends/src/server/org/opends/server/backends/jeb/IndexIteratorAllIds.java
+++ b/opends/src/server/org/opends/server/backends/jeb/IndexIteratorAllIds.java
@@ -35,9 +35,12 @@
 {
   /**
    * Create a new iterator over all the entry IDs in the backend.
+   *
+   * @param rootContainer The root container where IDs from this
+   *                     iterator will cover.
    */
-  public IndexIteratorAllIds()
+  public IndexIteratorAllIds(RootContainer rootContainer)
   {
-    super(EntryID.getLowest(), EntryID.getHighest());
+    super(rootContainer.getLowestEntryID(), rootContainer.getHighestEntryID());
   }
 }
diff --git a/opends/src/server/org/opends/server/backends/jeb/RootContainer.java b/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
index efeb9d3..e184040 100644
--- a/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
@@ -40,6 +40,7 @@
 import com.sleepycat.je.CheckpointConfig;
 
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.*;
 import java.io.File;
 import java.io.FilenameFilter;
@@ -108,6 +109,11 @@
   private ConcurrentHashMap<DN, EntryContainer> entryContainers;
 
   /**
+   * The cached value of the next entry identifier to be assigned.
+   */
+  private AtomicLong nextid = new AtomicLong(1);
+
+  /**
    * Creates a new RootContainer object. Each root container represents a JE
    * environment.
    *
@@ -238,7 +244,7 @@
    */
   public EntryContainer openEntryContainer(DN baseDN) throws DatabaseException
   {
-    EntryContainer ec = new EntryContainer(baseDN, backend, config, env);
+    EntryContainer ec = new EntryContainer(baseDN, backend, config, env, this);
     EntryContainer ec1=this.entryContainers.get(baseDN);
     //If an entry container for this baseDN is already open we don't allow
     //another to be opened.
@@ -271,10 +277,19 @@
    */
   public void openEntryContainers(DN[] baseDNs) throws DatabaseException
   {
+    EntryID id = null;
+    EntryID highestID = null;
     for(DN baseDN : baseDNs)
     {
-      openEntryContainer(baseDN);
+      EntryContainer ec = openEntryContainer(baseDN);
+      id = ec.getHighestEntryID();
+      if(highestID == null || id.compareTo(highestID) > 0)
+      {
+        highestID = id;
+      }
     }
+
+    nextid = new AtomicLong(highestID.longValue() + 1);
   }
 
   /**
@@ -625,4 +640,52 @@
   {
     return env.getConfig();
   }
+
+  /**
+   * Get the total number of entries in this root container.
+   *
+   * @return The number of entries in this root container
+   * @throws DatabaseException If an error occurs while retriving the entry
+   *                           count.
+   */
+  public long getEntryCount() throws DatabaseException
+  {
+    long entryCount = 0;
+    for(EntryContainer ec : this.entryContainers.values())
+    {
+      entryCount += ec.getEntryCount();
+    }
+
+    return entryCount;
+  }
+
+  /**
+   * Assign the next entry ID.
+   *
+   * @return The assigned entry ID.
+   */
+  public EntryID getNextEntryID()
+  {
+    return new EntryID(nextid.getAndIncrement());
+  }
+
+  /**
+   * Return the lowest entry ID assigned.
+   *
+   * @return The lowest entry ID assigned.
+   */
+  public Long getLowestEntryID()
+  {
+    return 1L;
+  }
+
+  /**
+   * Return the highest entry ID assigned.
+   *
+   * @return The highest entry ID assigned.
+   */
+  public Long getHighestEntryID()
+  {
+    return (nextid.get() - 1);
+  }
 }
diff --git a/opends/src/server/org/opends/server/messages/JebMessages.java b/opends/src/server/org/opends/server/messages/JebMessages.java
index da326f4..11c516d 100644
--- a/opends/src/server/org/opends/server/messages/JebMessages.java
+++ b/opends/src/server/org/opends/server/messages/JebMessages.java
@@ -1249,6 +1249,13 @@
       CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_WARNING | 128;
 
   /**
+   * The message ID of an error indicating the entry count of a container can
+   * not be determined.
+   */
+  public static final int MSGID_JEB_GET_ENTRY_COUNT_FAILED =
+      CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_WARNING | 129;
+
+  /**
    * Associates a set of generic messages with the message IDs defined in this
    * class.
    */
@@ -1743,5 +1750,8 @@
     registerMessage(MSGID_JEB_SET_PERMISSIONS_FAILED,
                     "Unable to set file permissions for the backend database " +
                     "directory %s.");
+    registerMessage(MSGID_JEB_GET_ENTRY_COUNT_FAILED,
+                    "Unable to determine the total number of entries in the " +
+                    "container: %s");
   }
 }

--
Gitblit v1.10.0