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