From 218b2a22d685fef5602021786334a4d78a2460e2 Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 25 Jun 2010 09:40:08 +0000
Subject: [PATCH] Resolves an issue in Import due to entries with multiple RDNs. This patch changes the key format used by the DN2ID database. Rebuilding the index is required.

---
 opends/src/server/org/opends/server/backends/jeb/EntryContainer.java |  110 ++++++++++++++++++------------------------------------
 1 files changed, 37 insertions(+), 73 deletions(-)

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 f991b2c..8e05b20 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -1274,7 +1274,10 @@
      * "cn=joe,ou=people,dc=example,dc=com" will appear after the entry
      * "ou=people,dc=example,dc=com".
      */
-    byte[] suffix = StaticUtils.getBytes("," + baseDN.toNormalizedString());
+    byte[] baseDNKey = JebFormat.dnToDNKey(baseDN,
+                                             this.baseDN.getNumComponents());
+    byte[] suffix = Arrays.copyOf(baseDNKey, baseDNKey.length+1);
+    suffix[suffix.length-1] = 0x00;
 
     /*
      * Set the ending value to a value of equal length but slightly
@@ -1283,7 +1286,7 @@
      * No possibility of overflow here.
      */
     byte[] end = suffix.clone();
-    end[0] = (byte) (end[0] + 1);
+    end[end.length-1] = (byte) (end[end.length-1] + 1);
 
     // Set the starting value.
     byte[] begin;
@@ -1352,14 +1355,13 @@
           // We have found a subordinate entry.
 
           EntryID entryID = new EntryID(data);
-          DN dn = DN.decode(ByteString.wrap(key.getData()));
 
           boolean isInScope = true;
           if (searchScope == SearchScope.SINGLE_LEVEL)
           {
             // Check if this entry is an immediate child.
-            if ((dn.getNumComponents() !=
-              baseDN.getNumComponents() + 1))
+            if(JebFormat.findDNKeyParent(key.getData(), 0,
+                                       key.getSize()) == baseDNKey.length)
             {
               isInScope = false;
             }
@@ -1911,15 +1913,17 @@
        * find subordinates of the target entry from the top of the tree
        * downwards.
        */
-      byte[] suffix = StaticUtils.getBytes("," +
-          entryDN.toNormalizedString());
+      byte[] entryDNKey = JebFormat.dnToDNKey(entryDN,
+                                               this.baseDN.getNumComponents());
+      byte[] suffix = Arrays.copyOf(entryDNKey, entryDNKey.length+1);
+      suffix[suffix.length-1] = 0x00;
 
       /*
        * Set the ending value to a value of equal length but slightly
        * greater than the suffix.
        */
       byte[] end = suffix.clone();
-      end[0] = (byte) (end[0] + 1);
+      end[end.length-1] = (byte) (end[end.length-1] + 1);
 
       int subordinateEntriesDeleted = 0;
 
@@ -1976,7 +1980,6 @@
            * we have been deleting from the bottom of the tree upwards.
            */
           EntryID entryID = new EntryID(data);
-          DN subordinateDN = DN.decode(ByteString.wrap(key.getData()));
 
           // Invoke any subordinate delete plugins on the entry.
           if (!deleteOperation.isSynchronizationOperation())
@@ -1993,13 +1996,14 @@
             {
               Message message =
                       ERR_JEB_DELETE_ABORTED_BY_SUBORDINATE_PLUGIN.get(
-                      subordinateDN.toString());
+                      JebFormat.dnFromDNKey(key.getData(), 0, 0, getBaseDN()).
+                          toString());
               throw new DirectoryException(
                   DirectoryServer.getServerErrorResultCode(), message);
             }
           }
 
-          deleteEntry(txn, indexBuffer, true, entryDN, subordinateDN, entryID);
+          deleteEntry(txn, indexBuffer, true, entryDN, key, entryID);
           subordinateEntriesDeleted++;
 
           if(deleteOperation != null)
@@ -2081,30 +2085,38 @@
       IndexBuffer indexBuffer,
       boolean manageDsaIT,
       DN targetDN,
-      DN leafDN,
+      DatabaseEntry leafDNKey,
       EntryID leafID)
   throws DatabaseException, DirectoryException, JebException
   {
-    if(leafID == null || leafDN == null)
+    if(leafID == null || leafDNKey == null)
     {
       // Read the entry ID from dn2id.
-      leafDN = targetDN;
-      leafID = dn2id.get(txn, leafDN, LockMode.RMW);
-      if (leafID == null)
+      if(leafDNKey == null)
+      {
+        leafDNKey =
+            new DatabaseEntry(JebFormat.dnToDNKey(
+                targetDN, this.baseDN.getNumComponents()));
+      }
+      DatabaseEntry value = new DatabaseEntry();
+      OperationStatus status;
+      status = dn2id.read(txn, leafDNKey, value, LockMode.RMW);
+      if (status != OperationStatus.SUCCESS)
       {
         Message message =
-          ERR_JEB_DELETE_NO_SUCH_OBJECT.get(leafDN.toString());
+          ERR_JEB_DELETE_NO_SUCH_OBJECT.get(leafDNKey.toString());
         DN matchedDN = getMatchedDN(baseDN);
         throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
             message, matchedDN, null);
       }
+      leafID = new EntryID(value);
     }
 
     // Remove from dn2id.
-    if (!dn2id.remove(txn, leafDN))
+    if (dn2id.delete(txn, leafDNKey) != OperationStatus.SUCCESS)
     {
       // Do not expect to ever come through here.
-      Message message = ERR_JEB_DELETE_NO_SUCH_OBJECT.get(leafDN.toString());
+      Message message = ERR_JEB_DELETE_NO_SUCH_OBJECT.get(leafDNKey.toString());
       DN matchedDN = getMatchedDN(baseDN);
       throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
           message, matchedDN, null);
@@ -2203,7 +2215,7 @@
     EntryCache<?> entryCache = DirectoryServer.getEntryCache();
     if (entryCache != null)
     {
-      entryCache.removeEntry(leafDN);
+      entryCache.removeEntry(entry.getDN());
     }
   }
 
@@ -2563,15 +2575,17 @@
        * find subordinates of the target entry from the top of the tree
        * downwards.
        */
-      byte[] suffix = StaticUtils.getBytes("," +
-          currentDN.toNormalizedString());
+      byte[] currentDNKey = JebFormat.dnToDNKey(currentDN,
+                                               this.baseDN.getNumComponents());
+      byte[] suffix = Arrays.copyOf(currentDNKey, currentDNKey.length+1);
+      suffix[suffix.length-1] = 0x00;
 
       /*
        * Set the ending value to a value of equal length but slightly
        * greater than the suffix.
        */
       byte[] end = suffix.clone();
-      end[0] = (byte) (end[0] + 1);
+      end[end.length-1] = (byte) (end[end.length-1] + 1);
 
       DatabaseEntry data = new DatabaseEntry();
       DatabaseEntry key = new DatabaseEntry(suffix);
@@ -2983,56 +2997,6 @@
   }
 
   /**
-   * A lexicographic byte array comparator that compares in
-   * reverse byte order. This is used for the dn2id database.
-   * If we want to find all the entries in a subtree dc=com we know that
-   * all subordinate entries must have ,dc=com as a common suffix. In reversing
-   * the order of comparison we turn the subtree base into a common prefix
-   * and are able to iterate through the keys having that prefix.
-   */
-  static public class KeyReverseComparator implements Comparator<byte[]>
-  {
-    /**
-     * Compares its two arguments for order.  Returns a negative integer,
-     * zero, or a positive integer as the first argument is less than, equal
-     * to, or greater than the second.
-     *
-     * @param a the first object to be compared.
-     * @param b the second object to be compared.
-     * @return a negative integer, zero, or a positive integer as the
-     *         first argument is less than, equal to, or greater than the
-     *         second.
-     */
-    public int compare(byte[] a, byte[] b)
-    {
-      for (int ai = a.length - 1, bi = b.length - 1;
-      ai >= 0 && bi >= 0; ai--, bi--)
-      {
-        if (a[ai] > b[bi])
-        {
-          return 1;
-        }
-        else if (a[ai] < b[bi])
-        {
-          return -1;
-        }
-      }
-      if (a.length == b.length)
-      {
-        return 0;
-      }
-      if (a.length > b.length)
-      {
-        return 1;
-      }
-      else
-      {
-        return -1;
-      }
-    }
-  }
-
-  /**
    * Insert a new entry into the attribute indexes.
    *
    * @param txn The database transaction to be used for the updates.

--
Gitblit v1.10.0