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

Matthew Swift
01.15.2016 fd33962f8ed2a8d57e61624f3523adde2b25e974
OPENDJ-2709 Reduce lock contention in AuthenticatedUsers for modify/delete requests

Added a fast-path check using the read-lock which checks to see if the
targeted entry, or any subordinates, exist in the DITCacheMap.
2 files modified
39 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/api/DITCacheMap.java 12 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/AuthenticatedUsers.java 27 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/api/DITCacheMap.java
@@ -347,6 +347,18 @@
  /**
   * Returns {@code true} if there are stored objects subordinate to subtree DN.
   * @param key subtree DN.
   * @return {@code true} if there are stored objects subordinate to subtree DN.
   */
  public boolean containsSubtree(DN key)
  {
    return ditCacheMap.containsKey(key);
  }
  /**
   * Removes a set of stored objects subordinate to subtree DN.
   * @param key subtree DN.
   * @param values collection for removed objects subordinate
opendj-server-legacy/src/main/java/org/opends/server/core/AuthenticatedUsers.java
@@ -172,11 +172,12 @@
  @Override
  public PostResponse doPostResponse(PostResponseDeleteOperation op)
  {
    if (op.getResultCode() != ResultCode.SUCCESS) {
    final DN entryDN = op.getEntryDN();
    if (op.getResultCode() != ResultCode.SUCCESS || operationDoesNotTargetAuthenticatedUser(entryDN))
    {
      return PostResponse.continueOperationProcessing();
    }
    final DN entryDN = op.getEntryDN();
    // Identify any client connections that may be authenticated
    // or authorized as the user whose entry has been deleted and terminate them
    Set<CopyOnWriteArraySet<ClientConnection>> arraySet = new HashSet<>();
@@ -201,12 +202,25 @@
    return PostResponse.continueOperationProcessing();
  }
  private boolean operationDoesNotTargetAuthenticatedUser(final DN entryDN)
  {
    lock.readLock().lock();
    try
    {
      return !userMap.containsSubtree(entryDN);
    }
    finally
    {
      lock.readLock().unlock();
    }
  }
  @Override
  public PostResponse doPostResponse(PostResponseModifyOperation op)
  {
    final Entry oldEntry = op.getCurrentEntry();
    if (op.getResultCode() != ResultCode.SUCCESS || oldEntry == null)
    if (op.getResultCode() != ResultCode.SUCCESS || oldEntry == null
            ||  operationDoesNotTargetAuthenticatedUser(oldEntry.getName()))
    {
      return PostResponse.continueOperationProcessing();
    }
@@ -244,8 +258,9 @@
  {
    final Entry oldEntry = op.getOriginalEntry();
    final Entry newEntry = op.getUpdatedEntry();
    if (op.getResultCode() != ResultCode.SUCCESS || oldEntry == null || newEntry == null) {
    if (op.getResultCode() != ResultCode.SUCCESS || oldEntry == null || newEntry == null
            || operationDoesNotTargetAuthenticatedUser(oldEntry.getName()))
    {
      return PostResponse.continueOperationProcessing();
    }