From de1a65414ae4e96bdddc7f94d6a0659900349de5 Mon Sep 17 00:00:00 2001
From: abobrov <abobrov@localhost>
Date: Tue, 18 Mar 2008 11:24:26 +0000
Subject: [PATCH] - make the entry cache preload backend implementation specific   moving EntryCachePreloader to JEB package and reworking it   for JEB specific preload.

---
 opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java                                   |    5 
 opendj-sdk/opends/src/messages/messages/extension.properties                                                     |   33 +
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryCachePreloader.java                             |  418 ++++++++++++++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/api/Backend.java                                                  |   25 
 opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java                                    |    5 
 opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java                        |    5 
 opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java                                       |    5 
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java                                     |   46 --
 opendj-sdk/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java                                 |   31 +
 /dev/null                                                                                                        |  386 ----------------------
 opendj-sdk/opends/src/server/org/opends/server/backends/BackupBackend.java                                       |    4 
 opendj-sdk/opends/src/server/org/opends/server/backends/LDIFBackend.java                                         |   13 
 opendj-sdk/opends/src/server/org/opends/server/backends/MonitorBackend.java                                      |    6 
 opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java                                 |    6 
 opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java                                      |    4 
 opendj-sdk/opends/src/server/org/opends/server/backends/MemoryBackend.java                                       |    8 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java |    8 
 17 files changed, 492 insertions(+), 516 deletions(-)

diff --git a/opendj-sdk/opends/src/messages/messages/extension.properties b/opendj-sdk/opends/src/messages/messages/extension.properties
index 2ba4fad..237fe2e 100644
--- a/opendj-sdk/opends/src/messages/messages/extension.properties
+++ b/opendj-sdk/opends/src/messages/messages/extension.properties
@@ -72,20 +72,18 @@
  to initialize fifo entry cache:  %s
 FATAL_ERR_SOFTREFCACHE_CANNOT_INITIALIZE_9=A fatal error occurred while \
  trying to initialize soft reference entry cache:  %s
-NOTICE_CACHE_PRELOAD_PROGRESS_START_10=Starting the entry cache preload
-NOTICE_CACHE_PRELOAD_PROGRESS_REPORT_11=The entry cache preload has processed \
- %d entries, %d MB free heap memory available
-NOTICE_CACHE_PRELOAD_PROGRESS_DONE_12=The entry cache preload is complete \
- with the total of %d entries processed
-SEVERE_WARN_CACHE_PRELOAD_INTERRUPTED_13=The entry cache preload has been \
- interrupted
-SEVERE_ERR_CACHE_PRELOAD_COLLECTOR_FAILED_14=The entry cache preload was \
- unable to complete preload processing for %s backend, and as a result \
- the entry cache preload for this backend will be incomplete
-SEVERE_WARN_CACHE_PRELOAD_BACKEND_FAILED_15=The entry cache preload is not \
+NOTICE_CACHE_PRELOAD_PROGRESS_START_10=Starting the entry cache preload for \
+ %s backend
+NOTICE_CACHE_PRELOAD_PROGRESS_REPORT_11=The entry cache preload for %s backend \
+ has processed %d entries, %d MB free heap memory available
+NOTICE_CACHE_PRELOAD_PROGRESS_DONE_12=The entry cache preload for %s backend \
+ is complete with the total of %d entries processed
+SEVERE_WARN_CACHE_PRELOAD_INTERRUPTED_13=The entry cache preload for %s \
+ backend has been interrupted
+SEVERE_WARN_CACHE_PRELOAD_BACKEND_FAILED_14=The entry cache preload is not \
  supported by %s backend, and as a result no entries from this backend will \
  be preloaded into the entry cache
-SEVERE_ERR_CACHE_PRELOAD_ENTRY_FAILED_16=Failed to preload %s entry into \
+SEVERE_ERR_CACHE_PRELOAD_ENTRY_FAILED_15=Failed to preload %s entry into \
  the entry cache:  %s
 MILD_ERR_EXTOP_PASSMOD_ILLEGAL_REQUEST_ELEMENT_TYPE_32=The password modify \
  extended request sequence included an ASN.1 element of an invalid type:  %s
@@ -1394,6 +1392,10 @@
  group %s references target group %s which is itself a virtual static group. \
  One virtual static group is not allowed to reference another as its target \
  group
+NOTICE_FSCACHE_RESTORE_484=Staring persistent entry cache state restoration, \
+ this may take awhile
+NOTICE_FSCACHE_SAVE_485=Making the entry cache state persistent, this may \
+ take awhile
 FATAL_ERR_FSCACHE_CANNOT_INITIALIZE_486=A fatal error occurred while trying \
  to initialize file system entry cache:  %s
 SEVERE_ERR_FSCACHE_CANNOT_LOAD_PERSISTENT_DATA_487=An error occurred while \
@@ -1420,10 +1422,9 @@
 SEVERE_WARN_FSCACHE_OFFLINE_STATE_FAIL_496=%s backend current offline state \
  does not match persistent cache last recorded offline state. All cached data \
  for this backend is now discarded
-NOTICE_FSCACHE_RESTORE_PROGRESS_REPORT_497=Restored %d cache entries of %d \
- total persistent cache entries found
-NOTICE_FSCACHE_SAVE_PROGRESS_REPORT_498=Made persistent %d cache entries of %d \
- total cache entries found
+NOTICE_FSCACHE_RESTORE_REPORT_497=Restored %d persistent cache entries into \
+ the entry cache
+NOTICE_FSCACHE_SAVE_REPORT_498=Made persistent %d cache entries
 NOTICE_FSCACHE_INDEX_NOT_FOUND_499=No previous persistent cache state can be \
  found. Starting with an empty cache
 SEVERE_ERR_FSCACHE_INDEX_IMPAIRED_500=The persistent cache index is \
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java b/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java
index b2a0e17..299fc2f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java
@@ -30,7 +30,6 @@
 
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -211,21 +210,18 @@
 
 
   /**
-   * Retrieves the set of all DNs that are stored within this backend.
-   * Note that this can be a slow operation depending on a particular
-   * backend implementation and might be unsupported by some backends.
+   * Attempts to pre-load all the entries stored within this backend
+   * into the entry cache. Note that the caller must ensure that the
+   * backend stays in read-only state until this method returns as
+   * no entry locking is performed during this operation. Also note
+   * that any backend implementing this method should implement pre-
+   * load progress reporting and error handling specific to its own
+   * implementation.
    *
-   * @param   storedDNs  Collection to retrieve all stored DNs into.
-   *          Note that for async operation a thread-safe collection
-   *          should be used.
-   *
-   * @return  {@code true} if all DNs stored within this backend were
-   *          successfully retrieved, or {@code false} otherwise.
-   *
-   * @throws  UnsupportedOperationException if backend implementation
-   *          does not support this operation.
+   * @throws  UnsupportedOperationException if backend does not
+   *          support this operation.
    */
-  public abstract boolean collectStoredDNs(Collection<DN> storedDNs)
+  public abstract void preloadEntryCache()
     throws UnsupportedOperationException;
 
 
@@ -1309,4 +1305,3 @@
     return false;
   }
 }
-
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/BackupBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/BackupBackend.java
index 5501c6b..c18ce9b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/BackupBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/BackupBackend.java
@@ -1303,9 +1303,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/LDIFBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/LDIFBackend.java
index f709856..dfc372f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/LDIFBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/LDIFBackend.java
@@ -29,7 +29,6 @@
 
 
 import java.io.File;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -1579,16 +1578,8 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
-    backendLock.readLock().lock();
-    try {
-      storedDNs.addAll(entryMap.keySet());
-      return true;
-    } finally {
-      backendLock.readLock().unlock();
-    }
+  public void preloadEntryCache() throws UnsupportedOperationException {
+    throw new UnsupportedOperationException("Operation not supported.");
   }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/MemoryBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/MemoryBackend.java
index a02a4b6..84d3121 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/MemoryBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/MemoryBackend.java
@@ -28,7 +28,6 @@
 
 
 
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -994,11 +993,8 @@
   /**
    * {@inheritDoc}
    */
-  public synchronized boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
-    storedDNs.addAll(entryMap.keySet());
-    return true;
+  public void preloadEntryCache() throws UnsupportedOperationException {
+    throw new UnsupportedOperationException("Operation not supported.");
   }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/MonitorBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/MonitorBackend.java
index a99d330..ee8e21a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/MonitorBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/MonitorBackend.java
@@ -29,7 +29,6 @@
 
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -1283,10 +1282,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
-
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java
index e587ff5..fb1f312 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -1535,9 +1535,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
index a6f7c1a..492f284 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -37,7 +37,6 @@
 import java.security.MessageDigest;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -5589,9 +5588,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java
index bab8485..1b712d8 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java
@@ -42,7 +42,6 @@
 import java.security.KeyStoreException;
 import java.security.cert.Certificate;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -1905,9 +1904,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
index e54ecd9..86c94fb 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -25,9 +25,6 @@
  *      Copyright 2007-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.backends.jeb;
-import com.sleepycat.je.Cursor;
-import com.sleepycat.je.CursorConfig;
-import com.sleepycat.je.DatabaseEntry;
 import org.opends.messages.Message;
 
 import java.io.IOException;
@@ -42,8 +39,6 @@
 
 import com.sleepycat.je.DatabaseException;
 import com.sleepycat.je.EnvironmentConfig;
-import com.sleepycat.je.LockMode;
-import com.sleepycat.je.OperationStatus;
 import com.sleepycat.je.RunRecoveryException;
 
 import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
@@ -72,7 +67,6 @@
 import org.opends.server.admin.std.server.LocalDBBackendCfg;
 import org.opends.server.admin.Configuration;
 import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.types.DN;
 import org.opends.server.backends.jeb.importLDIF.Importer;
 
@@ -1752,41 +1746,11 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
+  public void preloadEntryCache() throws
+    UnsupportedOperationException
   {
-    for (EntryContainer entryContainer : rootContainer.getEntryContainers()) {
-      DN2ID dn2id = entryContainer.getDN2ID();
-      Cursor cursor = null;
-      try {
-        cursor = dn2id.openCursor(null, new CursorConfig());
-        DatabaseEntry key = new DatabaseEntry();
-        DatabaseEntry data = new DatabaseEntry();
-        OperationStatus status;
-        for (status = cursor.getFirst(key, data, LockMode.DEFAULT);
-             status == OperationStatus.SUCCESS;
-             status = cursor.getNext(key, data, LockMode.DEFAULT)) {
-          DN entryDN = DN.decode(new ASN1OctetString(key.getData()));
-          storedDNs.add(entryDN);
-        }
-      } catch (Exception e) {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-        return false;
-      } finally {
-        if (cursor != null) {
-          try {
-            cursor.close();
-          } catch (DatabaseException de) {
-            if (debugEnabled()) {
-              TRACER.debugCaught(DebugLogLevel.ERROR, de);
-            }
-          }
-        }
-      }
-    }
-    return true;
+    EntryCachePreloader preloader =
+      new EntryCachePreloader(this);
+    preloader.preload();
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryCachePreloader.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryCachePreloader.java
new file mode 100644
index 0000000..081138c
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/EntryCachePreloader.java
@@ -0,0 +1,418 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2008 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.backends.jeb;
+import com.sleepycat.je.Cursor;
+import com.sleepycat.je.CursorConfig;
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.LockMode;
+import com.sleepycat.je.OperationStatus;
+import java.util.Collection;
+import org.opends.messages.Message;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import org.opends.server.api.DirectoryThread;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.DebugLogLevel;
+import org.opends.server.loggers.debug.DebugTracer;
+
+import org.opends.server.types.Entry;
+import static org.opends.server.util.StaticUtils.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.loggers.ErrorLogger.logError;
+import static org.opends.messages.ExtensionMessages.*;
+
+/**
+ * This class defines a utility that will be used to pre-load the Directory
+ * Server entry cache.  Pre-loader is multi-threaded and consist of the
+ * following threads:
+ *
+ * - The Arbiter thread which monitors overall pre-load progress and manages
+ *   pre-load worker threads by adding or removing them as deemed necessary.
+ *
+ * - The Collector thread which collects all entries stored within the
+ *   backend and places them to a blocking queue workers consume from.
+ *
+ * - Worker threads which are responsible for monitoring the collector feed
+ *   and processing the actual entries for cache storage.
+ *
+ * This implementation is self-adjusting to any system workload and does not
+ * require any configuration parameters to optimize for initial system
+ * resources availability and/or any subsequent fluctuations.
+ */
+class EntryCachePreloader
+{
+  /**
+   * The tracer object for the debug logger.
+   */
+  private static final DebugTracer TRACER = getTracer();
+
+  /**
+   * BackendImpl object.
+   */
+  private BackendImpl jeb;
+
+  /**
+   * Interrupt flag for the arbiter to terminate worker threads.
+   */
+  private AtomicBoolean interruptFlag = new AtomicBoolean(false);
+
+  /**
+   * Processed entries counter.
+   */
+  private AtomicLong processedEntries = new AtomicLong(0);
+
+  /**
+   * Progress report resolution.
+   */
+  private static final long progressInterval = 5000;
+
+  /**
+   * Default resolution time.
+   */
+  public static final long
+    PRELOAD_DEFAULT_SLEEP_TIME = 10000;
+
+  /**
+   * Effective synchronization time.
+   */
+  private static long syncSleepTime;
+
+  /**
+   * Default queue capacity.
+   */
+  public static final int
+    PRELOAD_DEFAULT_QUEUE_CAPACITY = 128;
+
+  /**
+   * Effective queue capacity.
+   */
+  private static int queueCapacity;
+
+  /**
+   * Worker threads.
+   */
+  private List<Thread> preloadThreads =
+    Collections.synchronizedList(
+    new LinkedList<Thread>());
+
+  /**
+   * Collector thread.
+   */
+  private EntryCacheCollector collector =
+    new EntryCacheCollector();
+
+  /**
+   * This queue is for workers to take from.
+   */
+  private LinkedBlockingQueue<PreloadEntry> entryQueue;
+
+  /**
+   * The number of bytes in a megabyte.
+   */
+  private static final int bytesPerMegabyte = 1024*1024;
+
+  /**
+   * Constructs the Entry Cache Pre-loader for
+   * a given JEB implementation instance.
+   *
+   * @param  jeb  The JEB instance to pre-load.
+   */
+  public EntryCachePreloader(BackendImpl jeb) {
+    // These should not be exposed as configuration
+    // parameters and are only useful for testing.
+    syncSleepTime = Long.getLong(
+      "org.opends.server.entrycache.preload.sleep",
+      PRELOAD_DEFAULT_SLEEP_TIME);
+    queueCapacity = Integer.getInteger(
+      "org.opends.server.entrycache.preload.queue",
+      PRELOAD_DEFAULT_QUEUE_CAPACITY);
+    entryQueue =
+      new LinkedBlockingQueue<PreloadEntry>(
+      queueCapacity);
+    this.jeb = jeb;
+  }
+
+  /**
+   * The Arbiter thread.
+   */
+  protected void preload()
+  {
+    logError(NOTE_CACHE_PRELOAD_PROGRESS_START.get(jeb.getBackendID()));
+    // Start collector thread first.
+    collector.start();
+    // Kick off a single worker.
+    EntryCachePreloadWorker singleWorkerThread =
+      new EntryCachePreloadWorker();
+    singleWorkerThread.start();
+    preloadThreads.add(singleWorkerThread);
+    // Progress report timer task.
+    Timer timer = new Timer();
+    TimerTask progressTask = new TimerTask() {
+      // Persistent state restore progress report.
+      public void run() {
+        if (processedEntries.get() > 0) {
+          long freeMemory =
+            Runtime.getRuntime().freeMemory() / bytesPerMegabyte;
+          Message message = NOTE_CACHE_PRELOAD_PROGRESS_REPORT.get(
+            jeb.getBackendID(), processedEntries.get(), freeMemory);
+          logError(message);
+        }
+      }
+    };
+    timer.scheduleAtFixedRate(progressTask, progressInterval,
+      progressInterval);
+    // Cycle to monitor progress and adjust workers.
+    long processedEntriesCycle = 0;
+    long processedEntriesDelta = 0;
+    long processedEntriesDeltaLow = 0;
+    long processedEntriesDeltaHigh = 0;
+    long lastKnownProcessedEntries = 0;
+    try {
+      while (!entryQueue.isEmpty() || collector.isAlive()) {
+
+        Thread.sleep(syncSleepTime);
+
+        processedEntriesCycle = processedEntries.get();
+        processedEntriesDelta =
+          processedEntriesCycle - lastKnownProcessedEntries;
+        lastKnownProcessedEntries = processedEntriesCycle;
+        // Spawn another worker if scaling up.
+        if (processedEntriesDelta > processedEntriesDeltaHigh) {
+          processedEntriesDeltaLow = processedEntriesDeltaHigh;
+          processedEntriesDeltaHigh = processedEntriesDelta;
+          EntryCachePreloadWorker workerThread =
+            new EntryCachePreloadWorker();
+          workerThread.start();
+          preloadThreads.add(workerThread);
+        }
+        // Interrupt random worker if scaling down.
+        if (processedEntriesDelta < processedEntriesDeltaLow) {
+          processedEntriesDeltaHigh = processedEntriesDeltaLow;
+          processedEntriesDeltaLow = processedEntriesDelta;
+          // Leave at least one worker to progress.
+          if (preloadThreads.size() > 1) {
+            interruptFlag.set(true);
+          }
+        }
+      }
+      // Join the collector.
+      if (collector.isAlive()) {
+        collector.join();
+      }
+      // Join all spawned workers.
+      for (Thread workerThread : preloadThreads) {
+        if (workerThread.isAlive()) {
+          workerThread.join();
+        }
+      }
+      // Cancel progress report task and report done.
+      timer.cancel();
+      Message message = NOTE_CACHE_PRELOAD_PROGRESS_DONE.get(
+        jeb.getBackendID(), processedEntries.get());
+      logError(message);
+    } catch (InterruptedException ex) {
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+      }
+      // Interrupt the collector.
+      collector.interrupt();
+      // Interrupt all preload threads.
+      for (Thread thread : preloadThreads) {
+        thread.interrupt();
+      }
+      logError(WARN_CACHE_PRELOAD_INTERRUPTED.get(
+        jeb.getBackendID()));
+    } finally {
+      // Kill the timer task.
+      timer.cancel();
+    }
+  }
+
+  /**
+   * The worker thread.
+   */
+  private class EntryCachePreloadWorker extends DirectoryThread {
+    public EntryCachePreloadWorker() {
+      super("Entry Cache Preload Worker");
+    }
+    @Override
+    public void run() {
+      while (!entryQueue.isEmpty() || collector.isAlive()) {
+        // Check if interrupted.
+        if (Thread.interrupted()) {
+          return;
+        }
+        // Check for scaling down interruption.
+        if (interruptFlag.compareAndSet(true, false)) {
+          preloadThreads.remove(Thread.currentThread());
+          break;
+        }
+        // Dequeue the next entry.
+        try {
+          PreloadEntry preloadEntry = entryQueue.poll();
+          if (preloadEntry == null) {
+            continue;
+          }
+          long entryID =
+            JebFormat.entryIDFromDatabase(preloadEntry.entryIDBytes);
+          Entry entry =
+            JebFormat.entryFromDatabase(preloadEntry.entryBytes,
+            jeb.getRootContainer().getCompressedSchema());
+          try {
+            // Even if the entry does not end up in the cache its still
+            // treated as a processed entry anyways.
+            DirectoryServer.getEntryCache().putEntry(entry, jeb, entryID);
+            processedEntries.getAndIncrement();
+          } catch (Exception ex) {
+            if (debugEnabled()) {
+              TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+            }
+            Message message = ERR_CACHE_PRELOAD_ENTRY_FAILED.get(
+              entry.getDN().toNormalizedString(),
+              (ex.getCause() != null ? ex.getCause().getMessage() :
+                stackTraceToSingleLineString(ex)));
+            logError(message);
+          }
+        } catch (Exception ex) {
+          break;
+        }
+      }
+    }
+  }
+
+  /**
+   * The Collector thread.
+   */
+  private class EntryCacheCollector extends DirectoryThread {
+    public EntryCacheCollector() {
+      super("Entry Cache Preload Collector");
+    }
+    @Override
+    public void run() {
+      Cursor cursor = null;
+      ID2Entry id2entry = null;
+      DatabaseEntry key = new DatabaseEntry();
+      DatabaseEntry data = new DatabaseEntry();
+      Collection<EntryContainer> entryContainers =
+        jeb.getRootContainer().getEntryContainers();
+      Iterator<EntryContainer> ecIterator =
+        entryContainers.iterator();
+      OperationStatus status = OperationStatus.SUCCESS;
+
+      try {
+        while (status == OperationStatus.SUCCESS) {
+          // Check if interrupted.
+          if (Thread.interrupted()) {
+            return;
+          }
+          try {
+            if (cursor == null) {
+              if (ecIterator.hasNext()) {
+                id2entry = ecIterator.next().getID2Entry();
+              } else {
+                break;
+              }
+              if (id2entry != null) {
+                cursor = id2entry.openCursor(null, new CursorConfig());
+              } else {
+                continue;
+              }
+            }
+            status = cursor.getNext(key, data, LockMode.DEFAULT);
+            if (status != OperationStatus.SUCCESS) {
+              // Reset cursor and continue.
+              if (cursor != null) {
+                try {
+                  cursor.close();
+                } catch (DatabaseException de) {
+                  if (debugEnabled()) {
+                    TRACER.debugCaught(DebugLogLevel.ERROR, de);
+                  }
+                }
+                status = OperationStatus.SUCCESS;
+                cursor = null;
+                continue;
+              }
+            } else {
+              entryQueue.put(new PreloadEntry(data.getData(),
+                key.getData()));
+              continue;
+            }
+          } catch (InterruptedException e) {
+            return;
+          } catch (Exception e) {
+            if (debugEnabled()) {
+              TRACER.debugCaught(DebugLogLevel.ERROR, e);
+            }
+          }
+        }
+      } finally {
+        // Always close cursor.
+        if (cursor != null) {
+          try {
+            cursor.close();
+          } catch (DatabaseException de) {
+            if (debugEnabled()) {
+              TRACER.debugCaught(DebugLogLevel.ERROR, de);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * This inner class represents pre-load entry object.
+   */
+  private class PreloadEntry {
+
+    // Encoded Entry.
+    public byte[] entryBytes;
+
+    // Encoded EntryID.
+    public byte[] entryIDBytes;
+
+    /**
+     * Default constructor.
+     */
+    public PreloadEntry(byte[] entryBytes, byte[] entryIDBytes) {
+      this.entryBytes = entryBytes;
+      this.entryIDBytes = entryIDBytes;
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
index f2f1d33..a40e6bf 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -31,7 +31,6 @@
 import java.io.File;
 import java.net.InetAddress;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -1551,9 +1550,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java b/opendj-sdk/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java
index c170166..12884c0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/EntryCacheConfigManager.java
@@ -32,8 +32,11 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
@@ -54,15 +57,16 @@
 import org.opends.server.types.ResultCode;
 import org.opends.messages.MessageBuilder;
 import org.opends.server.admin.std.server.EntryCacheMonitorProviderCfg;
+import org.opends.server.api.Backend;
 import org.opends.server.config.ConfigConstants;
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.extensions.DefaultEntryCache;
-import org.opends.server.extensions.EntryCachePreloader;
 import org.opends.server.monitors.EntryCacheMonitorProvider;
 import org.opends.server.types.DN;
 
 import static org.opends.server.loggers.debug.DebugLogger.*;
 import static org.opends.server.loggers.ErrorLogger.*;
+import static org.opends.messages.ExtensionMessages.*;
 import static org.opends.messages.ConfigMessages.*;
 import static org.opends.server.util.StaticUtils.*;
 
@@ -228,10 +232,27 @@
     }
 
     // If requested preload the entry cache.
-    if (rootConfiguration.getGlobalConfiguration().isEntryCachePreload()) {
-      // Kick off preload arbiter main thread.
-      EntryCachePreloader preloadThread = new EntryCachePreloader();
-      preloadThread.start();
+    if (rootConfiguration.getGlobalConfiguration().isEntryCachePreload() &&
+        !cacheOrderMap.isEmpty()) {
+      // Preload from every active public backend.
+      Map<DN, Backend> baseDNMap =
+        DirectoryServer.getPublicNamingContexts();
+      Set<Backend> proccessedBackends = new HashSet<Backend>();
+      for (Backend backend : baseDNMap.values()) {
+        if (!proccessedBackends.contains(backend)) {
+          proccessedBackends.add(backend);
+          try {
+            backend.preloadEntryCache();
+          } catch (UnsupportedOperationException ex) {
+            // Some backend implementations might not support entry
+            // cache preload. Log a warning and continue.
+            Message message = WARN_CACHE_PRELOAD_BACKEND_FAILED.get(
+              backend.getBackendID());
+            logError(message);
+            continue;
+          }
+        }
+      }
     }
   }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
index 097d79e..01020ba 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
@@ -36,7 +36,6 @@
 import java.io.OutputStream;
 import java.security.MessageDigest;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -3622,10 +3621,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
-
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/EntryCachePreloader.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/EntryCachePreloader.java
deleted file mode 100644
index a1c2f28..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/EntryCachePreloader.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- */
-
-package org.opends.server.extensions;
-import org.opends.messages.Message;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import org.opends.server.api.Backend;
-import org.opends.server.api.DirectoryThread;
-import org.opends.server.api.ServerShutdownListener;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.loggers.debug.DebugTracer;
-
-import org.opends.server.types.LockManager;
-import static org.opends.server.util.StaticUtils.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import static org.opends.server.loggers.ErrorLogger.logError;
-import static org.opends.messages.ExtensionMessages.*;
-
-/**
- * This class defines a utility that will be used to pre-load the Directory
- * Server entry cache.  Pre-loader is multi-threaded and consist of the
- * following threads:
- *
- * - The Arbiter thread which monitors overall pre-load progress and manages
- *   pre-load worker threads by adding or removing them as deemed necessary.
- *
- * - The Collector thread which collects all entry DNs stored within every
- *   configured and active backend to a shared object workers consume from.
- *
- * - Worker threads which are responsible for monitoring the collector feed
- *   and requesting the actual entries for retrieval and in cache storage.
- *
- * This implementation is entry cache and backend independent and can be
- * used to pre-load from any backend to any entry cache as long as both
- * are capable of initiating and sustaining such pre-load activity.
- *
- * This implementation is fully synchronized and safe to use with the server
- * online and pre-load activities going in parallel with server operations.
- *
- * This implementation is self-adjusting to any system workload and does not
- * require any configuration parameters to optimize for initial system
- * resources availability and/or any subsequent fluctuations.
- */
-public class EntryCachePreloader
-  extends DirectoryThread
-  implements ServerShutdownListener
-{
-  /**
-   * The tracer object for the debug logger.
-   */
-  private static final DebugTracer TRACER = getTracer();
-
-  /**
-   * Interrupt flag for the arbiter to terminate worker threads.
-   */
-  private AtomicBoolean interruptFlag = new AtomicBoolean(false);
-
-  /**
-   * Processed entries counter.
-   */
-  private AtomicLong processedEntries = new AtomicLong(0);
-
-  /**
-   * Progress report resolution.
-   */
-  private static final long progressInterval = 5000;
-
-  /**
-   * Default arbiter resolution time.
-   */
-  public static final long
-    PRELOAD_ARBITER_DEFAULT_SLEEP_TIME = 1000;
-
-  /**
-   * Effective arbiter resolution time.
-   */
-  private static long arbiterSleepTime;
-
-  /**
-   * Pre-load arbiter thread name.
-   */
-  private String preloadArbiterThreadName;
-
-  /**
-   * Pre-load arbiter thread.
-   */
-  private Thread preloadArbiterThread;
-
-  /**
-   * Worker threads.
-   */
-  private List<Thread> preloadThreads =
-    Collections.synchronizedList(
-    new LinkedList<Thread>());
-
-  /**
-   * DN Collector thread.
-   */
-  private EntryCacheDNCollector dnCollector =
-    new EntryCacheDNCollector();
-
-  /**
-   * This queue is for workers to take from.
-   */
-  private LinkedBlockingQueue<DN> dnQueue =
-      new LinkedBlockingQueue<DN>();
-
-  /**
-   * The number of bytes in a megabyte.
-   */
-  private static final int bytesPerMegabyte = 1024*1024;
-
-  /**
-   * Default constructor.
-   */
-  public EntryCachePreloader() {
-    super("Entry Cache Preload Arbiter");
-    preloadArbiterThreadName = getName();
-    DirectoryServer.registerShutdownListener(this);
-    // This should not be exposed as configuration
-    // parameter and is only useful for testing.
-    arbiterSleepTime = Long.getLong(
-      "org.opends.server.entrycache.preload.sleep",
-      PRELOAD_ARBITER_DEFAULT_SLEEP_TIME);
-  }
-
-  /**
-   * The Arbiter thread.
-   */
-  @Override
-  public void run() {
-    preloadArbiterThread = Thread.currentThread();
-    logError(NOTE_CACHE_PRELOAD_PROGRESS_START.get());
-    // Start DN collector thread first.
-    dnCollector.start();
-    // Kick off a single worker.
-    EntryCachePreloadWorker singleWorkerThread =
-      new EntryCachePreloadWorker();
-    singleWorkerThread.start();
-    preloadThreads.add(singleWorkerThread);
-    // Progress report timer task.
-    Timer timer = new Timer();
-    TimerTask progressTask = new TimerTask() {
-      // Persistent state restore progress report.
-      public void run() {
-        if (processedEntries.get() > 0) {
-          long freeMemory =
-            Runtime.getRuntime().freeMemory() / bytesPerMegabyte;
-          Message message = NOTE_CACHE_PRELOAD_PROGRESS_REPORT.get(
-            processedEntries.get(), freeMemory);
-          logError(message);
-        }
-      }
-    };
-    timer.scheduleAtFixedRate(progressTask, progressInterval,
-      progressInterval);
-    // Cycle to monitor progress and adjust workers.
-    long processedEntriesDeltaLow  = 0;
-    long processedEntriesDeltaHigh = 0;
-    long lastKnownProcessedEntries = 0;
-    try {
-      while (!dnQueue.isEmpty() || dnCollector.isAlive()) {
-        long processedEntriesCycle = processedEntries.get();
-        long processedEntriesDelta =
-          processedEntriesCycle - lastKnownProcessedEntries;
-        lastKnownProcessedEntries = processedEntriesCycle;
-        // Spawn another worker if scaling up.
-        if (processedEntriesDelta > processedEntriesDeltaHigh) {
-          processedEntriesDeltaLow = processedEntriesDeltaHigh;
-          processedEntriesDeltaHigh = processedEntriesDelta;
-          EntryCachePreloadWorker workerThread =
-            new EntryCachePreloadWorker();
-          workerThread.start();
-          preloadThreads.add(workerThread);
-        }
-        // Interrupt random worker if scaling down.
-        if (processedEntriesDelta < processedEntriesDeltaLow) {
-          processedEntriesDeltaHigh = processedEntriesDeltaLow;
-          processedEntriesDeltaLow = processedEntriesDelta;
-          // Leave at least one worker to progress.
-          if (preloadThreads.size() > 1) {
-            interruptFlag.set(true);
-          }
-        }
-        Thread.sleep(arbiterSleepTime);
-      }
-      // Join the collector.
-      dnCollector.join();
-      // Join all spawned workers.
-      for (Thread workerThread : preloadThreads) {
-        workerThread.join();
-      }
-      // Cancel progress report task and report done.
-      timer.cancel();
-      Message message = NOTE_CACHE_PRELOAD_PROGRESS_DONE.get(
-        processedEntries.get());
-      logError(message);
-    } catch (InterruptedException ex) {
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-      }
-      // Interrupt the collector.
-      dnCollector.interrupt();
-      // Interrupt all preload threads.
-      for (Thread thread : preloadThreads) {
-        thread.interrupt();
-      }
-      logError(WARN_CACHE_PRELOAD_INTERRUPTED.get());
-    } finally {
-      // Kill the task in case of exception.
-      timer.cancel();
-    }
-  }
-
-  /**
-   * The worker thread.
-   */
-  private class EntryCachePreloadWorker extends DirectoryThread {
-    public EntryCachePreloadWorker() {
-      super("Entry Cache Preload Worker");
-    }
-    @Override
-    public void run() {
-      while (!dnQueue.isEmpty() || dnCollector.isAlive()) {
-        // Check if interrupted.
-        if (Thread.interrupted()) {
-          break;
-        }
-        if (interruptFlag.compareAndSet(true, false)) {
-          break;
-        }
-        // Dequeue the next entry DN.
-        try {
-          DN entryDN = dnQueue.take();
-          Lock readLock = null;
-          try {
-            // Acquire a read lock on the entry.
-            readLock = LockManager.lockRead(entryDN);
-            if (readLock == null) {
-              // It is cheaper to put this DN back on the
-              // queue then pick it up and process later.
-              dnQueue.add(entryDN);
-              continue;
-            }
-            // Even if getEntry() below fails the entry is
-            // still treated as a processed entry anyways.
-            processedEntries.getAndIncrement();
-            // getEntry() will trigger putEntryIfAbsent() to the
-            // cache if given entry is not in the cache already.
-            DirectoryServer.getEntry(entryDN);
-          } catch (DirectoryException ex) {
-            if (debugEnabled()) {
-              TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-            }
-            Message message = ERR_CACHE_PRELOAD_ENTRY_FAILED.get(
-              entryDN.toNormalizedString(),
-              (ex.getCause() != null ? ex.getCause().getMessage() :
-                stackTraceToSingleLineString(ex)));
-            logError(message);
-          } finally {
-            LockManager.unlock(entryDN, readLock);
-          }
-        } catch (InterruptedException ex) {
-          break;
-        }
-      }
-      preloadThreads.remove(Thread.currentThread());
-    }
-  }
-
-  /**
-   * The Collector thread.
-   */
-  private class EntryCacheDNCollector extends DirectoryThread {
-    public EntryCacheDNCollector() {
-      super("Entry Cache Preload Collector");
-    }
-    @Override
-    public void run() {
-      Map<DN, Backend> baseDNMap =
-        DirectoryServer.getPublicNamingContexts();
-      Set<Backend> proccessedBackends = new HashSet<Backend>();
-      // Collect all DNs from every active public backend.
-      for (Backend backend : baseDNMap.values()) {
-        // Check if interrupted.
-        if (Thread.interrupted()) {
-          return;
-        }
-        if (!proccessedBackends.contains(backend)) {
-          proccessedBackends.add(backend);
-          try {
-            if (!backend.collectStoredDNs(dnQueue)) {
-              // DN collection is incomplete, likely
-              // due to some backend problem occured.
-              // Log an error message and carry on.
-              Message message =
-                ERR_CACHE_PRELOAD_COLLECTOR_FAILED.get(
-                backend.getBackendID());
-              logError(message);
-            }
-          } catch (UnsupportedOperationException ex) {
-            // Some backends dont have collectStoredDNs()
-            // method implemented, log a warning, skip
-            // such backend and continue.
-            if (debugEnabled()) {
-              TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-            }
-            Message message =
-              WARN_CACHE_PRELOAD_BACKEND_FAILED.get(
-              backend.getBackendID());
-            logError(message);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public String getShutdownListenerName() {
-    return preloadArbiterThreadName;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public void processServerShutdown(Message reason) {
-    if ((preloadArbiterThread != null) &&
-         preloadArbiterThread.isAlive()) {
-      // Interrupt the arbiter so it can interrupt
-      // the collector and all spawned workers.
-      preloadArbiterThread.interrupt();
-      try {
-        // This should be quick although if it
-        // gets interrupted it is no big deal.
-        preloadArbiterThread.join();
-      } catch (InterruptedException ex) {
-        if (debugEnabled()) {
-          TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-        }
-      }
-    }
-    DirectoryServer.deregisterShutdownListener(this);
-  }
-}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
index f0aff88..1209d93 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
@@ -41,7 +41,6 @@
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -1365,9 +1364,7 @@
   /**
    * {@inheritDoc}
    */
-  public boolean collectStoredDNs(Collection<DN> storedDNs)
-    throws UnsupportedOperationException
-  {
+  public void preloadEntryCache() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Operation not supported.");
   }
 }
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java
index 682275d..6f6d2ef 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java
@@ -38,6 +38,7 @@
 import org.opends.server.admin.std.meta.*;
 import org.opends.server.admin.std.server.EntryCacheCfg;
 import org.opends.server.admin.std.server.FileSystemEntryCacheCfg;
+import org.opends.server.api.Backend;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.Entry;
 import org.opends.server.util.ServerConstants;
@@ -194,10 +195,9 @@
       "Expected empty cache.  " + "Cache contents:" + ServerConstants.EOL +
       toVerboseString());
 
-    // Start pre-load and wait for it to complete.
-    EntryCachePreloader preloadThread = new EntryCachePreloader();
-    preloadThread.start();
-    preloadThread.join();
+    // Preload.
+    Backend backend = DirectoryServer.getBackend("cacheTest");
+    backend.preloadEntryCache();
 
     // Check that all test entries are preloaded.
     for(int i = 0; i < NUMTESTENTRIES; i++ ) {

--
Gitblit v1.10.0