From 4e0231d95ce73b8354afa7827cba077b9b105c85 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Tue, 29 Apr 2008 20:45:32 +0000
Subject: [PATCH] This patch resolves potential deadlocks in the JE backend when performing modify operations. This is done by ensuring the indexer orders the keys to add and delete together before DB accesses are performed. This patch also removes passing the JE transaction object into the indexer methods since it is not needed.
---
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ApproximateIndexer.java | 147 ++++++++++++++++++++++++------------------------
1 files changed, 73 insertions(+), 74 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ApproximateIndexer.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ApproximateIndexer.java
index c5ec5df..11d9874 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ApproximateIndexer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ApproximateIndexer.java
@@ -26,8 +26,6 @@
*/
package org.opends.server.backends.jeb;
-import com.sleepycat.je.Transaction;
-
import java.util.*;
import org.opends.server.types.*;
@@ -99,13 +97,10 @@
/**
* Generate the set of index keys for an entry.
*
- * @param txn A database transaction to be used if the database need to be
- * accessed in the course of generating the index keys.
* @param entry The entry.
* @param keys The set into which the generated keys will be inserted.
*/
- public void indexEntry(Transaction txn, Entry entry,
- Set<byte[]> keys)
+ public void indexEntry(Entry entry, Set<byte[]> keys)
{
List<Attribute> attrList =
entry.getAttribute(attributeType);
@@ -115,51 +110,22 @@
}
}
- /**
+ /**
* Generate the set of index keys to be added and the set of index keys
* to be deleted for an entry that has been replaced.
*
- * @param txn A database transaction to be used if the database need to be
- * accessed in the course of generating the index keys.
* @param oldEntry The original entry contents.
* @param newEntry The new entry contents.
- * @param addKeys The set into which the keys to be added will be inserted.
- * @param delKeys The set into which the keys to be deleted will be inserted.
+ * @param modifiedKeys The map into which the modified keys will be inserted.
*/
- public void replaceEntry(Transaction txn,
- Entry oldEntry, Entry newEntry,
- Set<byte[]> addKeys,
- Set<byte[]> delKeys)
+ public void replaceEntry(Entry oldEntry, Entry newEntry,
+ Map<byte[], Boolean> modifiedKeys)
{
List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true);
List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true);
- if(newAttributes == null)
- {
- indexAttribute(oldAttributes, delKeys);
- }
- else
- {
- if(oldAttributes == null)
- {
- indexAttribute(newAttributes, addKeys);
- }
- else
- {
- TreeSet<byte[]> newKeys =
- new TreeSet<byte[]>(comparator);
- TreeSet<byte[]> oldKeys =
- new TreeSet<byte[]>(comparator);
- indexAttribute(newAttributes, newKeys);
- indexAttribute(oldAttributes, oldKeys);
-
- addKeys.addAll(newKeys);
- addKeys.removeAll(oldKeys);
-
- delKeys.addAll(oldKeys);
- delKeys.removeAll(newKeys);
- }
- }
+ indexAttribute(oldAttributes, modifiedKeys, false);
+ indexAttribute(newAttributes, modifiedKeys, true);
}
@@ -168,48 +134,20 @@
* Generate the set of index keys to be added and the set of index keys
* to be deleted for an entry that was modified.
*
- * @param txn A database transaction to be used if the database need to be
- * accessed in the course of generating the index keys.
* @param oldEntry The original entry contents.
* @param newEntry The new entry contents.
* @param mods The set of modifications that were applied to the entry.
- * @param addKeys The set into which the keys to be added will be inserted.
- * @param delKeys The set into which the keys to be deleted will be inserted.
+ * @param modifiedKeys The map into which the modified keys will be inserted.
*/
- public void modifyEntry(Transaction txn, Entry oldEntry, Entry newEntry,
+ public void modifyEntry(Entry oldEntry, Entry newEntry,
List<Modification> mods,
- Set<byte[]> addKeys,
- Set<byte[]> delKeys)
+ Map<byte[], Boolean> modifiedKeys)
{
List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true);
List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true);
- if(newAttributes == null)
- {
- indexAttribute(oldAttributes, delKeys);
- }
- else
- {
- if(oldAttributes == null)
- {
- indexAttribute(newAttributes, addKeys);
- }
- else
- {
- TreeSet<byte[]> newKeys =
- new TreeSet<byte[]>(comparator);
- TreeSet<byte[]> oldKeys =
- new TreeSet<byte[]>(comparator);
- indexAttribute(newAttributes, newKeys);
- indexAttribute(oldAttributes, oldKeys);
-
- addKeys.addAll(newKeys);
- addKeys.removeAll(oldKeys);
-
- delKeys.addAll(oldKeys);
- delKeys.removeAll(newKeys);
- }
- }
+ indexAttribute(oldAttributes, modifiedKeys, false);
+ indexAttribute(newAttributes, modifiedKeys, true);
}
/**
@@ -256,4 +194,65 @@
}
}
}
+
+ /**
+ * Generate the set of index keys for an attribute.
+ * @param attrList The attribute to be indexed.
+ * @param modifiedKeys The map into which the modified
+ * keys will be inserted.
+ * @param insert <code>true</code> if generated keys should
+ * be inserted or <code>false</code> otherwise.
+ */
+ private void indexAttribute(List<Attribute> attrList,
+ Map<byte[], Boolean> modifiedKeys,
+ Boolean insert)
+ {
+ if (attrList == null) return;
+
+ for (Attribute attr : attrList)
+ {
+ indexValues(attr.getValues(), modifiedKeys, insert);
+ }
+ }
+
+ /**
+ * Generate the set of index keys for a set of attribute values.
+ * @param values The set of attribute values to be indexed.
+ * @param modifiedKeys The map into which the modified
+ * keys will be inserted.
+ * @param insert <code>true</code> if generated keys should
+ * be inserted or <code>false</code> otherwise.
+ */
+ private void indexValues(Set<AttributeValue> values,
+ Map<byte[], Boolean> modifiedKeys,
+ Boolean insert)
+ {
+ if (values == null) return;
+
+ for (AttributeValue value : values)
+ {
+ try
+ {
+ byte[] keyBytes =
+ approximateRule.normalizeValue(value.getValue()).value();
+
+ Boolean cInsert = modifiedKeys.get(keyBytes);
+ if(cInsert == null)
+ {
+ modifiedKeys.put(keyBytes, insert);
+ }
+ else if(!cInsert.equals(insert))
+ {
+ modifiedKeys.remove(keyBytes);
+ }
+ }
+ catch (DirectoryException e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+ }
+ }
+ }
}
--
Gitblit v1.10.0