mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
29.57.2016 97cafe6c9cfa077690c61c22ee3fdc8d4501d150
OPENDJ-2709 Reduce lock contention in SubentryManager for modify/delete requests

For modify operations return immediately if the operation does not
target a sub-entry (lock-free). For delete operations return immediately
if the targeted entry is not a sub-tree containing sub-entries (requires
shared lock). This change improves modify throughput by over 50% against
an in-memory backend.

In DITCacheMap: make DITSubtreeSet.isEmpty() O(1) instead of O(N).
2 files modified
27 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/api/DITCacheMap.java 6 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/SubentryManager.java 21 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/api/DITCacheMap.java
@@ -737,6 +737,12 @@
    }
    @Override
    public boolean isEmpty()
    {
      return !(new SubtreeSetIterator(this.key).hasNext());
    }
    @Override
    public int size()
    {
      int size = 0;
opendj-server-legacy/src/main/java/org/opends/server/core/SubentryManager.java
@@ -607,6 +607,22 @@
  private void doPostDelete(Entry entry)
  {
    // Fast-path for deleted entries which do not have subordinate sub-entries.
    lock.readLock().lock();
    try
    {
      final Collection<SubEntry> subtree = dit2SubEntry.getSubtree(entry.getName());
      if (subtree.isEmpty())
      {
        return;
      }
    }
    finally
    {
      lock.readLock().unlock();
    }
    // Slow-path.
    lock.writeLock().lock();
    try
    {
@@ -626,6 +642,11 @@
  {
    final boolean oldEntryIsSubentry = isSubEntry(oldEntry);
    final boolean newEntryIsSubentry = isSubEntry(newEntry);
    if (!oldEntryIsSubentry && !newEntryIsSubentry)
    {
      return; // Nothing to do.
    }
    boolean notify = false;
    lock.writeLock().lock();
    try