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

Matthew Swift
22.19.2014 ceef9042e3c54251caa60f0a86677725f1830255
Fix OPENDJ-1709: Persistit: ldapsearch returns second entry twice

Manually reviewed by Jean-Noel.

* fix Persistit storage cursor iteration. Application code which uses the cursor API assumes that calling next() after a call to positionXXX() moves the cursor forward
* fix various places where we were using stale key/value references
* fix a couple of minor bugs when checking the result of cursoring in VLV indexing.
4 files modified
57 ■■■■ changed files
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/persistit/PersistItStorage.java 22 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/EntryContainer.java 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/Index.java 18 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java 14 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/persistit/PersistItStorage.java
@@ -286,7 +286,6 @@
    private final class CursorImpl implements Cursor {
        private final Exchange ex;
        private boolean useCurrentKeyForNext = false;
        private ByteString currentKey;
        private ByteString currentValue;
@@ -305,10 +304,8 @@
            bytesToKey(ex.getKey(), key);
            try {
                ex.fetch();
                useCurrentKeyForNext = ex.getValue().isDefined();
                return useCurrentKeyForNext;
        return ex.getValue().isDefined();
            } catch (PersistitException e) {
                useCurrentKeyForNext = false;
                throw new StorageRuntimeException(e);
            }
        }
@@ -319,15 +316,8 @@
            bytesToKey(ex.getKey(), key);
            try {
                ex.fetch();
                if (ex.getValue().isDefined()) {
                    useCurrentKeyForNext = true;
                } else {
                    // provided key does not exist, look for next key
                    useCurrentKeyForNext = ex.next();
                }
                return useCurrentKeyForNext;
        return ex.getValue().isDefined() || ex.next();
            } catch (PersistitException e) {
                useCurrentKeyForNext = false;
                throw new StorageRuntimeException(e);
            }
        }
@@ -337,10 +327,8 @@
            try {
                clearCurrentKeyAndValue();
                ex.getKey().to(Key.AFTER);
                useCurrentKeyForNext = ex.previous() && ex.getValue().isDefined();
                return useCurrentKeyForNext;
        return ex.previous();
            } catch (PersistitException e) {
                useCurrentKeyForNext = false;
                throw new StorageRuntimeException(e);
            }
        }
@@ -348,10 +336,6 @@
        @Override
        public boolean next() {
            clearCurrentKeyAndValue();
            if (useCurrentKeyForNext) {
                useCurrentKeyForNext = false;
                return true;
            }
            try {
                return ex.next();
            } catch (PersistitException e) {
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/EntryContainer.java
@@ -1737,7 +1737,8 @@
              boolean success = cursor.positionToKeyOrNext(startKey);
              // Step forward until the key is greater than the starting value.
              while (success && ByteSequence.COMPARATOR.compare(startKey, suffix) <= 0)
              while (success
                  && ByteSequence.COMPARATOR.compare(cursor.getKey(), suffix) <= 0)
              {
                success = cursor.next();
              }
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/Index.java
@@ -511,41 +511,31 @@
      Cursor cursor = txn.openCursor(treeName);
      try
      {
        ByteSequence key = ByteString.empty();
        boolean success;
        // Set the lower bound if necessary.
        if (lower.length() > 0)
        {
          // Initialize the cursor to the lower bound.
          key = lower;
          success = cursor.positionToKeyOrNext(key);
          success = cursor.positionToKeyOrNext(lower);
          // Advance past the lower bound if necessary.
          if (success
              && !lowerIncluded
              && ByteSequence.COMPARATOR.compare(key, lower) == 0)
              && ByteSequence.COMPARATOR.compare(cursor.getKey(), lower) == 0)
          {
            // Do not include the lower value.
            success = cursor.next();
            if (success)
            {
              key = cursor.getKey();
            }
          }
        }
        else
        {
          success = cursor.next();
          if (success)
          {
            key = cursor.getKey();
          }
        }
        if (!success)
        {
          // There are no values.
          return new EntryIDSet(key, null);
          return new EntryIDSet(lowerIncluded ? lower : null, null);
        }
        // Step through the keys until we hit the upper bound or the last key.
@@ -560,7 +550,7 @@
              break;
            }
          }
          EntryIDSet list = new EntryIDSet(key, cursor.getValue());
          EntryIDSet list = new EntryIDSet(cursor.getKey(), cursor.getValue());
          if (!list.isDefined())
          {
            // There is no point continuing.
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java
@@ -781,8 +781,7 @@
          keyBytes.appendBERLength(vBytes.length());
          vBytes.copyTo(keyBytes);
          boolean success = cursor.positionToKeyOrNext(keyBytes);
          if (success)
          if (cursor.positionToKeyOrNext(keyBytes))
          {
            if(logger.isTraceEnabled())
            {
@@ -814,8 +813,7 @@
                includedBeforeCount++;
              }
              success = cursor.previous();
              if (success)
              if (!cursor.previous())
              {
                break;
              }
@@ -850,13 +848,7 @@
                includedAfterCount++;
              }
              if(includedAfterCount >= afterCount + 1)
              {
                break;
              }
              success = cursor.next();
              if (success)
              if (includedAfterCount >= afterCount + 1 || !cursor.next())
              {
                break;
              }