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

Jean-Noel Rouvignac
02.47.2014 d9b412170996aa617f6303104b7fc5ea0892de0a
opendj-sdk/opends/src/server/org/opends/server/replication/server/changelog/je/JEChangeNumberIndexDB.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.replication.server.changelog.je;
@@ -71,17 +71,25 @@
  private static int NO_KEY = 0;
  private DraftCNDB db;
  /**
   * FIXME Is this field that useful? {@link #getOldestChangeNumber()} does not
   * even use it!
   */
  /** FIXME What is this field used for? */
  private volatile long oldestChangeNumber = NO_KEY;
  /**
   * FIXME Is this field that useful? {@link #getNewestChangeNumber()} does not
   * even use it!
   * The newest changenumber stored in the DB. It is used to avoid trimming the
   * record with the newest changenumber. The newest record in the changenumber
   * index DB is used to persist the {@link #lastGeneratedChangeNumber} which is
   * then retrieved on server startup.
   */
  private volatile long newestChangeNumber = NO_KEY;
  /** The last generated value for the change number. */
  /**
   * The last generated value for the change number. It is kept separate from
   * the {@link #newestChangeNumber} because there is an opportunity for a race
   * condition between:
   * <ol>
   * <li>this atomic long being incremented for a new record ('recordB')</li>
   * <li>the current newest record ('recordA') being trimmed from the DB</li>
   * <li>'recordB' failing to be inserted in the DB</li>
   * </ol>
   */
  private final AtomicLong lastGeneratedChangeNumber;
  private DbMonitorProvider dbMonitor = new DbMonitorProvider();
  private final AtomicBoolean shutdown = new AtomicBoolean(false);
@@ -124,10 +132,10 @@
    final ChangeNumberIndexRecord oldestRecord = db.readFirstRecord();
    final ChangeNumberIndexRecord newestRecord = db.readLastRecord();
    oldestChangeNumber = getChangeNumber(oldestRecord);
    newestChangeNumber = getChangeNumber(newestRecord);
    final long newestCN = getChangeNumber(newestRecord);
    newestChangeNumber = newestCN;
    // initialization of the lastGeneratedChangeNumber from the DB content
    // if DB is empty => last record does not exist => default to 0
    long newestCN = (newestRecord != null) ? newestRecord.getChangeNumber() : 0;
    lastGeneratedChangeNumber = new AtomicLong(newestCN);
    // Monitoring registration
@@ -165,6 +173,7 @@
        new ChangeNumberIndexRecord(changeNumber, record.getPreviousCookie(),
            record.getBaseDN(), record.getCSN());
    db.addRecord(newRecord);
    newestChangeNumber = changeNumber;
    if (debugEnabled())
      TRACER.debugInfo("In JEChangeNumberIndexDB.add, added: " + newRecord);
@@ -383,6 +392,18 @@
          }
          final ChangeNumberIndexRecord record = cursor.currentRecord();
          if (record.getChangeNumber() != oldestChangeNumber)
          {
            oldestChangeNumber = record.getChangeNumber();
          }
          if (record.getChangeNumber() == newestChangeNumber)
          {
            // do not trim the newest record to avoid having the last generated
            // changenumber dropping back to 0 if the server restarts
            cursor.close();
            return;
          }
          if (baseDNToClear != null && baseDNToClear.equals(record.getBaseDN()))
          {
            cursor.delete();
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/changelog/je/JEChangeNumberIndexDBTest.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.replication.server.changelog.je;
@@ -219,9 +219,20 @@
      cursor = cnIndexDB.getCursorFrom(cn3);
      assertCursorReadsInOrder(cursor, cn3);
      cnIndexDB.clear();
      // check only the last record is left
      cnIndexDB.clear(null);
      final ChangeNumberIndexRecord oldest = cnIndexDB.getOldestRecord();
      final ChangeNumberIndexRecord newest = cnIndexDB.getNewestRecord();
      assertEquals(oldest.getChangeNumber(), 3);
      assertEquals(oldest.getChangeNumber(), newest.getChangeNumber());
      assertEquals(oldest.getPreviousCookie(), newest.getPreviousCookie());
      assertEquals(oldest.getBaseDN(), newest.getBaseDN());
      assertEquals(oldest.getCSN(), newest.getCSN());
      assertEquals(cnIndexDB.count(), 1);
      assertFalse(cnIndexDB.isEmpty());
      // Check the db is cleared.
      cnIndexDB.clear();
      assertNull(cnIndexDB.getOldestRecord());
      assertNull(cnIndexDB.getNewestRecord());
      assertEquals(cnIndexDB.count(), 0);