From 8c65daf79d1c7fbe47f556c4d4bba2c2859851d1 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Mon, 21 Apr 2008 21:08:12 +0000
Subject: [PATCH] This patch adds index buffering capabilities to the JE backend as to avoid using a fixed lock timeout for subtree delete and mod DN operations. Previously, any index modifications to subordinate entries of the affected operations will be performed with dn2id and id2entry modifications. This creates multiple random access to index database keys which could cause deadlocks in face of multiple parallel operations. With this fix, all index modifications are buffered up until the end of the operation so that each key of each index will be accessed once and in order. This maintains the DB access ordering in the JE backend of dn2id, id2entry, dn2uri, indexes in config order, VLV indexes in config order, and finally id2children and id2subtree. Since deadlocks should no longer occur in the JE backend, JE lock timeouts are now disabled at the JE environment level instead of the txn level. With this change, the performance of subtree deletes and mod DN operations have increased dramatically.
---
opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java | 184 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 184 insertions(+), 0 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java b/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
index 451e58d..5795edf 100644
--- a/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -334,6 +334,68 @@
/**
* Update the attribute index for a new entry.
*
+ * @param buffer The index buffer to use to store the added keys
+ * @param entryID The entry ID.
+ * @param entry The contents of the new entry.
+ * @return True if all the index keys for the entry are added. False if the
+ * entry ID already exists for some keys.
+ * @throws DatabaseException If an error occurs in the JE database.
+ * @throws DirectoryException If a Directory Server error occurs.
+ * @throws JebException If an error occurs in the JE backend.
+ */
+ public boolean addEntry(IndexBuffer buffer, EntryID entryID,
+ Entry entry)
+ throws DatabaseException, DirectoryException, JebException
+ {
+ boolean success = true;
+
+ if (equalityIndex != null)
+ {
+ if(!equalityIndex.addEntry(buffer, entryID, entry))
+ {
+ success = false;
+ }
+ }
+
+ if (presenceIndex != null)
+ {
+ if(!presenceIndex.addEntry(buffer, entryID, entry))
+ {
+ success = false;
+ }
+ }
+
+ if (substringIndex != null)
+ {
+ if(!substringIndex.addEntry(buffer, entryID, entry))
+ {
+ success = false;
+ }
+ }
+
+ if (orderingIndex != null)
+ {
+ if(!orderingIndex.addEntry(buffer, entryID, entry))
+ {
+ success = false;
+ }
+ }
+
+ if (approximateIndex != null)
+ {
+ if(!approximateIndex.addEntry(buffer, entryID, entry))
+ {
+ success = false;
+ }
+ }
+
+ return success;
+ }
+
+
+ /**
+ * Update the attribute index for a new entry.
+ *
* @param txn The database transaction to be used for the insertions.
* @param entryID The entry ID.
* @param entry The contents of the new entry.
@@ -394,6 +456,46 @@
/**
* Update the attribute index for a deleted entry.
*
+ * @param buffer The index buffer to use to store the deleted keys
+ * @param entryID The entry ID
+ * @param entry The contents of the deleted entry.
+ * @throws DatabaseException If an error occurs in the JE database.
+ * @throws DirectoryException If a Directory Server error occurs.
+ * @throws JebException If an error occurs in the JE backend.
+ */
+ public void removeEntry(IndexBuffer buffer, EntryID entryID,
+ Entry entry)
+ throws DatabaseException, DirectoryException, JebException
+ {
+ if (equalityIndex != null)
+ {
+ equalityIndex.removeEntry(buffer, entryID, entry);
+ }
+
+ if (presenceIndex != null)
+ {
+ presenceIndex.removeEntry(buffer, entryID, entry);
+ }
+
+ if (substringIndex != null)
+ {
+ substringIndex.removeEntry(buffer, entryID, entry);
+ }
+
+ if (orderingIndex != null)
+ {
+ orderingIndex.removeEntry(buffer, entryID, entry);
+ }
+
+ if(approximateIndex != null)
+ {
+ approximateIndex.removeEntry(buffer, entryID, entry);
+ }
+ }
+
+ /**
+ * Update the attribute index for a deleted entry.
+ *
* @param txn The database transaction to be used for the deletions
* @param entryID The entry ID
* @param entry The contents of the deleted entry.
@@ -476,6 +578,51 @@
}
/**
+ * Update the index to reflect a sequence of modifications in a Modify
+ * operation.
+ *
+ * @param buffer The index buffer used to buffer up the index changes.
+ * @param entryID The ID of the entry that was modified.
+ * @param oldEntry The entry before the modifications were applied.
+ * @param newEntry The entry after the modifications were applied.
+ * @param mods The sequence of modifications in the Modify operation.
+ * @throws DatabaseException If an error occurs during an operation on a
+ * JE database.
+ */
+ public void modifyEntry(IndexBuffer buffer,
+ EntryID entryID,
+ Entry oldEntry,
+ Entry newEntry,
+ List<Modification> mods)
+ throws DatabaseException
+ {
+ if (equalityIndex != null)
+ {
+ equalityIndex.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
+ }
+
+ if (presenceIndex != null)
+ {
+ presenceIndex.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
+ }
+
+ if (substringIndex != null)
+ {
+ substringIndex.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
+ }
+
+ if (orderingIndex != null)
+ {
+ orderingIndex.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
+ }
+
+ if (approximateIndex != null)
+ {
+ approximateIndex.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
+ }
+ }
+
+ /**
* Makes a byte array representing a substring index key for
* one substring of a value.
*
@@ -1676,4 +1823,41 @@
public Index getPresenceIndex() {
return presenceIndex;
}
+
+ /**
+ * Retrieves all the indexes used by this attribute index.
+ *
+ * @return A collection of all indexes in use by this attribute
+ * index.
+ */
+ public Collection<Index> getAllIndexes() {
+ LinkedHashSet<Index> indexes = new LinkedHashSet<Index>();
+
+ if (equalityIndex != null)
+ {
+ indexes.add(equalityIndex);
+ }
+
+ if (presenceIndex != null)
+ {
+ indexes.add(presenceIndex);
+ }
+
+ if (substringIndex != null)
+ {
+ indexes.add(substringIndex);
+ }
+
+ if (orderingIndex != null)
+ {
+ indexes.add(orderingIndex);
+ }
+
+ if (approximateIndex != null)
+ {
+ indexes.add(approximateIndex);
+ }
+
+ return indexes;
+ }
}
--
Gitblit v1.10.0