From 3f27a7ede5ca9df06137254aa32d41d023ac105d Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Tue, 16 Sep 2014 15:05:25 +0000
Subject: [PATCH] OPENDJ-1444 CR-4537 Remove previous cookie from storage of ChangeNumberIndexDB

---
 opends/src/server/org/opends/server/replication/server/changelog/file/BlockLogReader.java |  107 ++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 76 insertions(+), 31 deletions(-)

diff --git a/opends/src/server/org/opends/server/replication/server/changelog/file/BlockLogReader.java b/opends/src/server/org/opends/server/replication/server/changelog/file/BlockLogReader.java
index 38f5e6f..1b7d843 100644
--- a/opends/src/server/org/opends/server/replication/server/changelog/file/BlockLogReader.java
+++ b/opends/src/server/org/opends/server/replication/server/changelog/file/BlockLogReader.java
@@ -449,54 +449,99 @@
   }
 
   /**
-   * Position to provided key, starting from provided block start position and
-   * reading sequentially until key is found according to matching and
-   * positioning strategies.
+   * Position before, at or after provided key, starting from provided block
+   * start position and reading sequentially until key is found according to
+   * matching and positioning strategies.
    *
    * @param blockStartPosition
    *          Position of read pointer in the file, expected to be the start of
-   *          a block where a record offset is written.
+   *          a block where a record offset is written
    * @param key
-   *          The key to find.
+   *          The key to find
    * @param matchStrategy
-   *          The key matching strategy.
+   *          The key matching strategy
    * @param positionStrategy
-   *          The positioning strategy.
-   * @return The pair ({@code true}, last record read) if reader is successfully
-   *         positioned (last record may be null if end of file is reached), (
-   *         {@code false}, null) otherwise.
+   *          The positioning strategy
+   * @return The pair ({@code true}, selected record) if reader is successfully
+   *         positioned (selected record may be null if end of file is reached),
+   *         ({@code false}, null) otherwise.
    * @throws ChangelogException
    *           If an error occurs.
    */
-   Pair<Boolean, Record<K,V>> positionToKeySequentially(
-       final long blockStartPosition,
-       final K key,
-       final KeyMatchingStrategy matchStrategy,
-       final PositionStrategy positionStrategy)
-       throws ChangelogException {
+   Pair<Boolean, Record<K,V>> positionToKeySequentially(final long blockStartPosition, final K key,
+       final KeyMatchingStrategy matchStrategy, final PositionStrategy positionStrategy) throws ChangelogException
+   {
     Record<K,V> record = readRecord(blockStartPosition);
-    do {
-      if (record != null)
+    Record<K,V> previousRecord = null;
+    long previousPosition = blockStartPosition;
+    boolean matchingKeyIsLowerThanAnyRecord = true;
+    while (record != null)
+    {
+      final int keysComparison = record.getKey().compareTo(key);
+      if (keysComparison <= 0)
       {
-        final int keysComparison = record.getKey().compareTo(key);
-        final boolean matches = (matchStrategy == EQUAL_TO_KEY && keysComparison == 0)
-            || (matchStrategy == GREATER_THAN_OR_EQUAL_TO_KEY && keysComparison >= 0);
-        if (matches)
-        {
-          if (positionStrategy == AFTER_MATCHING_KEY && keysComparison == 0)
-          {
-            // skip matching key
-            record = readRecord();
-          }
-          return Pair.of(true, record);
-        }
+        matchingKeyIsLowerThanAnyRecord = false;
       }
+      if ((keysComparison == 0 && matchStrategy == EQUAL_TO_KEY)
+          || (keysComparison >= 0 && matchStrategy != EQUAL_TO_KEY))
+      {
+        return getMatchingRecord(matchStrategy, positionStrategy, keysComparison, matchingKeyIsLowerThanAnyRecord,
+            record, previousRecord, previousPosition);
+      }
+      previousRecord = record;
+      previousPosition = getFilePosition();
       record = readRecord();
     }
-    while (record != null);
+
+    if (matchStrategy == LESS_THAN_OR_EQUAL_TO_KEY)
+    {
+      return getRecordNoMatchForLessStrategy(positionStrategy, previousRecord, previousPosition);
+    }
     return Pair.of(false, null);
   }
 
+  private Pair<Boolean,Record<K,V>> getMatchingRecord(KeyMatchingStrategy matchStrategy,
+      PositionStrategy positionStrategy, int keysComparison, boolean matchKeyIsLowerThanAnyRecord,
+      Record<K, V> currentRecord, Record<K, V> previousRecord, long previousPosition)
+          throws ChangelogException
+  {
+    Record<K, V> record = currentRecord;
+
+    if (positionStrategy == AFTER_MATCHING_KEY)
+    {
+      if (matchStrategy == LESS_THAN_OR_EQUAL_TO_KEY && matchKeyIsLowerThanAnyRecord)
+      {
+        return Pair.of(false, null);
+      }
+      if (keysComparison == 0)
+      {
+        // skip matching key
+        record = readRecord();
+      }
+    }
+    else if (positionStrategy == ON_MATCHING_KEY && matchStrategy == LESS_THAN_OR_EQUAL_TO_KEY && keysComparison > 0)
+    {
+      seekToPosition(previousPosition);
+      return Pair.of(previousRecord != null, previousRecord);
+    }
+    return Pair.of(true, record);
+  }
+
+  private Pair<Boolean, Record<K, V>> getRecordNoMatchForLessStrategy(
+      final PositionStrategy positionStrategy, final Record<K, V> previousRecord, final long previousPosition)
+          throws ChangelogException
+  {
+    if (positionStrategy == ON_MATCHING_KEY)
+    {
+      seekToPosition(previousPosition);
+      return Pair.of(previousRecord != null, previousRecord);
+    }
+    else
+    {
+      return Pair.of(true, null);
+    }
+  }
+
   /**
    * Returns the closest start of block which has a position lower than or equal
    * to the provided file position.

--
Gitblit v1.10.0