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