From d8a0693ee610f39d28ccaf139869578b08c307ec Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Wed, 11 May 2016 08:40:02 +0000
Subject: [PATCH] OPENDJ-2969 OPENDJ-2978 OPENDJ-2991 Fix BlockLogReader#getNewestRecord() method

---
 opendj-server-legacy/src/main/java/org/opends/server/replication/server/changelog/file/BlockLogReader.java           |   10 ++++++++--
 opendj-server-legacy/src/test/java/org/opends/server/replication/server/changelog/file/BlockLogReaderWriterTest.java |   31 +++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/replication/server/changelog/file/BlockLogReader.java b/opendj-server-legacy/src/main/java/org/opends/server/replication/server/changelog/file/BlockLogReader.java
index 2437651..7f8df32 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/replication/server/changelog/file/BlockLogReader.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/replication/server/changelog/file/BlockLogReader.java
@@ -11,7 +11,7 @@
  * Header, with the fields enclosed by brackets [] replaced by your own identifying
  * information: "Portions Copyright [year] [name of copyright owner]".
  *
- * Copyright 2014-2015 ForgeRock AS.
+ * Copyright 2014-2016 ForgeRock AS.
  */
 package org.opends.server.replication.server.changelog.file;
 
@@ -613,7 +613,13 @@
 Record<K, V> getNewestRecord() throws ChangelogException
  {
    try {
-     final long lastBlockStart = getClosestBlockStartBeforeOrAtPosition(getFileLength());
+     final long fileLength = getFileLength();
+     long lastBlockStart = getClosestBlockStartBeforeOrAtPosition(fileLength);
+     if (lastBlockStart == fileLength)
+     {
+       // this is not a valid block start, find the previous block start
+       lastBlockStart = getClosestBlockStartBeforeOrAtPosition(fileLength-1);
+     }
      positionToRecordFromBlockStart(lastBlockStart);
      ByteString candidate = readNextRecord();
      ByteString record = candidate;
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/replication/server/changelog/file/BlockLogReaderWriterTest.java b/opendj-server-legacy/src/test/java/org/opends/server/replication/server/changelog/file/BlockLogReaderWriterTest.java
index be57032..c473aa2 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/replication/server/changelog/file/BlockLogReaderWriterTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/replication/server/changelog/file/BlockLogReaderWriterTest.java
@@ -264,6 +264,37 @@
     assertThat(reader.getClosestBlockStartBeforeOrAtPosition(20)).isEqualTo(20);
   }
 
+  @DataProvider
+  Object[][] recordsForNewest()
+  {
+    return new Object[][]
+    {
+      // raw size taken by each record is: 4 (record size) + 4 (key) + 4 (value) = 12 bytes
+
+      // size of block, records to write
+      { 12, records(1) }, // zero block marker
+      { 10, records(1) }, // one block marker
+      { 8, records(1) },  // one block marker
+      { 7, records(1) },  // two block markers
+      { 6, records(1) },  // three block markers
+      { 5, records(1) },  // seven block markers
+      { 16, records(1,2) }, // one block marker
+      { 12, records(1,2) }, // two block markers
+      { 10, records(1,2) }, // three block markers
+    };
+  }
+
+  @Test(dataProvider="recordsForNewest")
+  public void testGetNewestRecord(int blockSize, List<Record<Integer, Integer>> records) throws Exception
+  {
+    writeRecords(blockSize, records);
+
+    try(BlockLogReader<Integer, Integer> reader = newReader(blockSize))
+    {
+      assertThat(reader.getNewestRecord()).isEqualTo(records.get(records.size()-1));
+    }
+  }
+
   @Test
   public void testGetClosestMarkerStrictlyAfterPosition() throws Exception
   {

--
Gitblit v1.10.0