From f09c069e92d051036af2a969fe5289cb7c4826ba Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Mon, 26 Oct 2015 08:22:49 +0000
Subject: [PATCH] OPENDJ-2349: fix deadlocks during subtree deletes and moddn
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ID2Count.java | 45 ++++++++++++++++++++++++++++-----------------
1 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ID2Count.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ID2Count.java
index 68613d6..04164c0 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ID2Count.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ID2Count.java
@@ -79,16 +79,30 @@
}
/**
- * Add a value to the counter associated to the given key
- * @param txn Database transaction
- * @param entryID The entryID identifying to the counter
+ * Updates the counter associated with the given key, but does not update the total count.
+ * <p>
+ * Implementation note: this method accepts a {@code null} entryID in order to eliminate null checks in client code.
+ * In particular, client code has to deal with the special case where a target entry does not have a parent because
+ * the target entry is a base entry within the backend.
+ *
+ * @param txn storage transaction
+ * @param entryID The entryID identifying to the counter, which may be
+ * {@code null} in which case calling this method has no effect.
* @param delta The value to add. Can be negative to decrease counter value.
*/
- void addDelta(WriteableTransaction txn, EntryID entryID, final long delta)
- {
- Reject.ifTrue(entryID.longValue() >= TOTAL_COUNT_ENTRY_ID.longValue(), "EntryID overflow.");
+ void updateCount(final WriteableTransaction txn, final EntryID entryID, final long delta) {
+ if (entryID != null)
+ {
+ addToCounter(txn, entryID, delta);
+ }
+ }
- addToCounter(txn, entryID, delta);
+ /**
+ * Updates the total count which should be the sum of all counters.
+ * @param txn storage transaction
+ * @param delta The value to add. Can be negative to decrease counter value.
+ */
+ void updateTotalCount(final WriteableTransaction txn, final long delta) {
addToCounter(txn, TOTAL_COUNT_ENTRY_ID, delta);
}
@@ -209,27 +223,24 @@
}
/**
- * Delete the counter associated to the given key
- * @param txn The transaction
+ * Removes the counter associated to the given key, but does not update the total count.
+ * @param txn storage transaction
* @param entryID The entryID identifying the counter
* @return Value of the counter before it's deletion.
*/
- long deleteCount(WriteableTransaction txn, EntryID entryID)
- {
+ long removeCount(final WriteableTransaction txn, final EntryID entryID) {
long counterValue = 0;
- try(final Cursor<ByteString, ByteString> cursor = txn.openCursor(getName())) {
+ try (final Cursor<ByteString, ByteString> cursor = txn.openCursor(getName())) {
final ByteSequence encodedEntryID = getKeyFromEntryID(entryID);
if (cursor.positionToKeyOrNext(encodedEntryID)) {
- while (cursor.getKey().startsWith(encodedEntryID))
- {
+ // Iterate over and remove all the thread local shards
+ while (cursor.isDefined() && cursor.getKey().startsWith(encodedEntryID)) {
counterValue += cursor.getValue().asReader().getLong();
- txn.delete(getName(), cursor.getKey());
+ cursor.delete();
cursor.next();
}
}
}
- addToCounter(txn, TOTAL_COUNT_ENTRY_ID, -counterValue);
-
return counterValue;
}
}
--
Gitblit v1.10.0