From 7bcb81dd86201dc52b82ce18cfa00af463683a8f Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 11 Jun 2013 15:38:13 +0000
Subject: [PATCH] Partial fix for OPENDJ-885: Replication replay may lose changes if it can't acquire a writeLock
---
opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java | 63 ++++++++++++-------------------
1 files changed, 25 insertions(+), 38 deletions(-)
diff --git a/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java b/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java
index 4ce044a..f182ed6 100644
--- a/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java
+++ b/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java
@@ -23,7 +23,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
- * Portions Copyright 2011-2012 ForgeRock AS
+ * Portions Copyright 2011-2013 ForgeRock AS
*/
package org.opends.server.extensions;
@@ -169,7 +169,7 @@
// Class database, catalog and binding for serialization.
private Database entryCacheClassDB;
private StoredClassCatalog classCatalog;
- private EntryBinding entryCacheDataBinding;
+ private EntryBinding<FileSystemEntryCacheIndex> entryCacheDataBinding;
// JE naming constants.
private static final String ENTRYCACHEDBNAME = "EntryCacheDB";
@@ -187,6 +187,10 @@
// Currently registered configuration object.
private FileSystemEntryCacheCfg registeredConfiguration;
+ // The maximum length of time to try to obtain a lock before giving
+ // up.
+ private long lockTimeout = LockManager.DEFAULT_TIMEOUT;
+
/**
* Creates a new instance of this entry cache.
*/
@@ -207,7 +211,6 @@
* {@inheritDoc}
*/
@Override
- @SuppressWarnings("unchecked")
public void initializeEntryCache(FileSystemEntryCacheCfg configuration)
throws ConfigException, InitializationException {
@@ -304,9 +307,8 @@
classCatalog = new StoredClassCatalog(entryCacheClassDB);
//This line causes an unchecked call error if the SuppressWarnings
//annotation is removed at the beginning of this method.
- entryCacheDataBinding =
- new SerialBinding(classCatalog,
- FileSystemEntryCacheIndex.class);
+ entryCacheDataBinding = new SerialBinding<FileSystemEntryCacheIndex>(
+ classCatalog, FileSystemEntryCacheIndex.class);
// Get the root configuration object.
ServerManagementContext managementContext =
@@ -336,9 +338,7 @@
if (OperationStatus.SUCCESS ==
entryCacheDB.get(null, indexKey, indexData, LockMode.DEFAULT)) {
- entryCacheIndex =
- (FileSystemEntryCacheIndex)
- entryCacheDataBinding.entryToObject(indexData);
+ entryCacheIndex = entryCacheDataBinding.entryToObject(indexData);
} else {
throw new CacheIndexNotFoundException();
}
@@ -434,7 +434,6 @@
* {@inheritDoc}
*/
@Override
- @SuppressWarnings("unchecked")
public void finalizeEntryCache() {
cacheWriteLock.lock();
@@ -590,17 +589,18 @@
*/
@Override
public DN getEntryDN(Backend backend, long entryID) {
-
DN entryDN = null;
cacheReadLock.lock();
try {
// Get the map for the provided backend. If it isn't present, then
// return null.
- Map map = entryCacheIndex.backendMap.get(backend.getBackendID());
- if ( !(map == null) ) {
+ Map<Long, String> map = entryCacheIndex.backendMap.get(backend
+ .getBackendID());
+ if (map != null)
+ {
// Get the entry DN from the map by its ID. If it isn't present,
// then return null.
- entryDN = DN.decode((String) map.get(entryID));
+ entryDN = DN.decode(map.get(entryID));
}
} catch (Exception e) {
// Ignore.
@@ -706,7 +706,6 @@
* {@inheritDoc}
*/
@Override
- @SuppressWarnings("unchecked")
public void clear() {
cacheWriteLock.lock();
@@ -732,8 +731,8 @@
classCatalog = new StoredClassCatalog(entryCacheClassDB);
//This line causes an unchecked call error if the SuppressWarnings
//annotation is removed at the beginning of this method.
- entryCacheDataBinding = new SerialBinding(classCatalog,
- FileSystemEntryCacheIndex.class);
+ entryCacheDataBinding = new SerialBinding<FileSystemEntryCacheIndex>(
+ classCatalog, FileSystemEntryCacheIndex.class);
}
} catch (Exception e) {
if (debugEnabled()) {
@@ -1142,7 +1141,7 @@
);
// Iterate through native JE properties.
try {
- Map paramsMap = EnvironmentParams.SUPPORTED_PARAMS;
+ Map<String, ConfigParam> paramsMap = EnvironmentParams.SUPPORTED_PARAMS;
// If this entry cache is disabled then there is no open JE
// environment to check against, skip mutable check if so.
if (configuration.isEnabled()) {
@@ -1156,7 +1155,7 @@
if (st.countTokens() == 2) {
String jePropertyName = st.nextToken();
String jePropertyValue = st.nextToken();
- ConfigParam param = (ConfigParam) paramsMap.get(jePropertyName);
+ ConfigParam param = paramsMap.get(jePropertyName);
if (!param.isMutable()) {
String oldValue = oldEnvConfig.getConfigParam(param.getName());
String newValue = jePropertyValue;
@@ -1262,7 +1261,7 @@
encodeConfig = new EntryEncodeConfig(true,
newCompactEncoding, newCompactEncoding);
- setLockTimeout(newLockTimeout);
+ lockTimeout = newLockTimeout;
setIncludeFilters(newIncludeFilters);
setExcludeFilters(newExcludeFilters);
@@ -1368,7 +1367,7 @@
ByteStringBuilder entryBytes) {
try {
// Obtain a lock on the cache. If this fails, then don't do anything.
- if (!cacheWriteLock.tryLock(getLockTimeout(), TimeUnit.MILLISECONDS)) {
+ if (!cacheWriteLock.tryLock(lockTimeout, TimeUnit.MILLISECONDS)) {
return false;
}
// See if the current fs space usage is within acceptable constraints. If
@@ -1488,15 +1487,9 @@
}
/**
- * Return a verbose string representation of the current cache maps.
- * This is useful primary for debugging and diagnostic purposes such
- * as in the entry cache unit tests.
- * @return String verbose string representation of the current cache
- * maps in the following format: dn:id:backend
- * one cache entry map representation per line
- * or <CODE>null</CODE> if all maps are empty.
+ * {@inheritDoc}
*/
- private String toVerboseString()
+ public String toVerboseString()
{
StringBuilder sb = new StringBuilder();
@@ -1580,7 +1573,7 @@
* @return boolean {@code true} if the eldest entry should be removed
* from the map; {@code false} if it should be retained.
*/
- protected boolean removeEldestEntry(Map.Entry eldest) {
+ protected boolean removeEldestEntry(Map.Entry<String, Long> eldest) {
// Check if we hit the limit on max entries and if so remove
// the eldest entry otherwise do nothing.
if (entryCacheIndex.dnMap.size() > maxEntries.longValue()) {
@@ -1588,8 +1581,8 @@
cacheWriteLock.lock();
try {
// Remove the the eldest entry from supporting maps.
- String entryStringDN = (String) eldest.getKey();
- long entryID = ((Long) eldest.getValue()).longValue();
+ String entryStringDN = eldest.getKey();
+ long entryID = eldest.getValue();
cacheEntryKey.setData(entryStringDN.getBytes("UTF-8"));
Set<String> backendSet = entryCacheIndex.backendMap.keySet();
Iterator<String> backendIterator = backendSet.iterator();
@@ -1630,9 +1623,6 @@
private class CacheIndexNotFoundException extends OpenDsException {
static final long serialVersionUID = 6444756053577853869L;
public CacheIndexNotFoundException() {}
- public CacheIndexNotFoundException(Message message) {
- super(message);
- }
}
/**
@@ -1643,9 +1633,6 @@
private class CacheIndexImpairedException extends OpenDsException {
static final long serialVersionUID = -369455697709478407L;
public CacheIndexImpairedException() {}
- public CacheIndexImpairedException(Message message) {
- super(message);
- }
}
}
--
Gitblit v1.10.0