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

Matthew Swift
23.13.2014 4ef568921c23735eb9a1eafd1f048e74762c1cf7
OPENDJ-1710: NPE performing deletes and potentially other indexed updates against Persistit backend

Minor code cleanup:

* replace uses of ByteSequence.COMPARATOR with ByteSequence.compareTo()
* simplify cursoring over ranges (consequence of above change)
* remove unnecessary unnecessary loops for initial positioning of cursors.
3 files modified
105 ■■■■ changed files
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/DN2URI.java 17 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/EntryContainer.java 81 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/Index.java 7 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/DN2URI.java
@@ -580,7 +580,6 @@
    suffix.append((byte) 0x00);
    end.append((byte) 0x01);
    ByteSequence startKey = suffix;
    try
    {
      final Cursor cursor = txn.openCursor(treeName);
@@ -588,23 +587,15 @@
      {
        // Initialize the cursor very close to the starting value then
        // step forward until we pass the ending value.
        boolean success = cursor.positionToKey(startKey);
        while (success)
        boolean success = cursor.positionToKey(suffix);
        while (success && cursor.getKey().compareTo(end) < 0)
        {
          ByteString key = cursor.getKey();
          int cmp = ByteSequence.COMPARATOR.compare(key, end);
          if (cmp >= 0)
          {
            // We have gone past the ending value.
            break;
          }
          // We have found a subordinate referral.
          DN dn = JebFormat.dnFromDNKey(key, entryContainer.getBaseDN());
          DN dn = JebFormat.dnFromDNKey(cursor.getKey(), entryContainer.getBaseDN());
          // Make sure the referral is within scope.
          if (searchOp.getScope() == SearchScope.SINGLE_LEVEL
              && JebFormat.findDNKeyParent(key) != baseDN.length())
              && JebFormat.findDNKeyParent(cursor.getKey()) != baseDN.length())
          {
            continue;
          }
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/EntryContainer.java
@@ -1224,8 +1224,6 @@
      begin = suffix;
    }
    ByteSequence startKey = begin;
    int lookthroughCount = 0;
    int lookthroughLimit = searchOperation.getClientConnection().getLookthroughLimit();
@@ -1235,30 +1233,21 @@
      try
      {
        // Initialize the cursor very close to the starting value.
        boolean success = cursor.positionToKeyOrNext(startKey);
        boolean success = cursor.positionToKeyOrNext(begin);
        // Step forward until we pass the ending value.
        while (success)
        while (success && cursor.getKey().compareTo(end) < 0)
        {
          if(lookthroughLimit > 0 && lookthroughCount > lookthroughLimit)
          {
            //Lookthrough limit exceeded
            searchOperation.setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
            searchOperation.appendErrorMessage(
                NOTE_JEB_LOOKTHROUGH_LIMIT_EXCEEDED.get(lookthroughLimit));
            searchOperation.appendErrorMessage(NOTE_JEB_LOOKTHROUGH_LIMIT_EXCEEDED.get(lookthroughLimit));
            return;
          }
          int cmp = ByteSequence.COMPARATOR.compare(cursor.getKey(), end);
          if (cmp >= 0)
          {
            // We have gone past the ending value.
            break;
          }
          // We have found a subordinate entry.
          EntryID entryID = new EntryID(cursor.getValue());
          boolean isInScope =
              searchScope != SearchScope.SINGLE_LEVEL
                  // Check if this entry is an immediate child.
@@ -1728,31 +1717,13 @@
            int subordinateEntriesDeleted = 0;
            ByteSequence startKey = suffix;
            Cursor cursor = dn2id.openCursor(txn);
            try
            {
              // Initialize the cursor very close to the starting value.
              boolean success = cursor.positionToKeyOrNext(startKey);
              // Step forward until the key is greater than the starting value.
              while (success
                  && ByteSequence.COMPARATOR.compare(cursor.getKey(), suffix) <= 0)
              {
                success = cursor.next();
              }
              // Step forward until we pass the ending value.
              while (success)
              boolean success = cursor.positionToKeyOrNext(suffix);
              while (success && cursor.getKey().compareTo(end) < 0)
              {
                int cmp = ByteSequence.COMPARATOR.compare(cursor.getKey(), end);
                if (cmp >= 0)
                {
                  // We have gone past the ending value.
                  break;
                }
                // We have found a subordinate entry.
                if (!isSubtreeDelete)
                {
@@ -2030,16 +2001,17 @@
  private Entry getEntry0(ReadableStorage txn, final DN entryDN) throws StorageRuntimeException, DirectoryException
  {
    final EntryCache<?> entryCache = DirectoryServer.getEntryCache();
    Entry entry = null;
    // Try the entry cache first.
    if (entryCache != null)
    {
      entry = entryCache.getEntry(entryDN);
      final Entry entry = entryCache.getEntry(entryDN);
      if (entry != null)
      {
        return entry;
      }
    }
    if (entry == null)
    {
      try
      {
        // Read dn2id.
@@ -2053,8 +2025,8 @@
        }
        // Read id2entry.
        Entry entry2 = id2entry.get(txn, entryID, false);
        if (entry2 == null)
      final Entry entry = id2entry.get(txn, entryID, false);
      if (entry == null)
        {
          // The entryID does not exist.
          throw new DirectoryException(getServerErrorResultCode(), ERR_JEB_MISSING_ID2ENTRY_RECORD.get(entryID));
@@ -2065,20 +2037,18 @@
        // we read the cache.
        if (entryCache != null)
        {
          entryCache.putEntryIfAbsent(entry2, backend, entryID.longValue());
        entryCache.putEntryIfAbsent(entry, backend, entryID.longValue());
        }
        return entry2;
      return entry;
      }
      catch (Exception e)
      {
        // it is not very clean to specify twice the same exception but it saves me some code for now
        throwAllowedExceptionTypes(e, DirectoryException.class, DirectoryException.class);
      return null; // unreachable
      }
    }
    return entry;
  }
  /**
   * The simplest case of replacing an entry in which the entry DN has
   * not changed.
@@ -2337,32 +2307,15 @@
            suffix.append((byte) 0x00);
            end.append((byte) 0x01);
            ByteSequence startKey = suffix;
            Cursor cursor = txn.openCursor(dn2id.getName());
            try
            {
              // Initialize the cursor very close to the starting value.
              boolean success = cursor.positionToKeyOrNext(startKey);
              // Step forward until the key is greater than the starting value.
              while (success && ByteSequence.COMPARATOR.compare(cursor.getKey(), suffix) <= 0)
              {
                success = cursor.next();
              }
              // Step forward until we pass the ending value.
              while (success)
              boolean success = cursor.positionToKeyOrNext(suffix);
              while (success && cursor.getKey().compareTo(end) < 0)
              {
                int cmp = ByteSequence.COMPARATOR.compare(cursor.getKey(), end);
                if (cmp >= 0)
                {
                  // We have gone past the ending value.
                  break;
                }
                // We have found a subordinate entry.
                EntryID oldID = new EntryID(cursor.getValue());
                Entry oldEntry = id2entry.get(txn, oldID, false);
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/Index.java
@@ -519,9 +519,7 @@
          success = cursor.positionToKeyOrNext(lower);
          // Advance past the lower bound if necessary.
          if (success
              && !lowerIncluded
              && ByteSequence.COMPARATOR.compare(cursor.getKey(), lower) == 0)
          if (success && !lowerIncluded && cursor.getKey().equals(lower))
          {
            // Do not include the lower value.
            success = cursor.next();
@@ -544,12 +542,13 @@
          // Check against the upper bound if necessary
          if (upper.length() > 0)
          {
            int cmp = ByteSequence.COMPARATOR.compare(cursor.getKey(), upper);
            int cmp = cursor.getKey().compareTo(upper);
            if (cmp > 0 || (cmp == 0 && !upperIncluded))
            {
              break;
            }
          }
          EntryIDSet list = new EntryIDSet(cursor.getKey(), cursor.getValue());
          if (!list.isDefined())
          {