From 47437ad525caabd5ad6331598f4945a4d240b6ca Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Wed, 10 Dec 2014 11:19:15 +0000
Subject: [PATCH] Fix OPENDJ-1665 (CR-5619) Cache backup.info files
---
opendj3-server-dev/src/server/org/opends/server/backends/BackupBackend.java | 105 ++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 80 insertions(+), 25 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/BackupBackend.java b/opendj3-server-dev/src/server/org/opends/server/backends/BackupBackend.java
index 6e4e99f..e75810c 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/BackupBackend.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/BackupBackend.java
@@ -27,6 +27,7 @@
package org.opends.server.backends;
import java.io.File;
+import java.io.IOException;
import java.util.*;
import org.forgerock.i18n.LocalizableMessage;
@@ -82,9 +83,61 @@
/** The backup base entry. */
private Entry backupBaseEntry;
- /** The set of predefined backup directories that we will use. */
- private LinkedHashSet<File> backupDirectories;
+ /** A cache of BackupDirectories. */
+ private HashMap<File,CachedBackupDirectory> backupDirectories;
+ /**
+ * To avoid parsing and reparsing the contents of backup.info files, we
+ * cache the BackupDirectory for each directory using this class.
+ */
+ private class CachedBackupDirectory
+ {
+ /** The path to the 'bak' directory. */
+ private final String directoryPath;
+
+ /** The 'backup.info' file. */
+ private final File backupInfo;
+
+ /** The last modify time of the backupInfo file */
+ private long lastModified;
+
+ /** The BackupDirectory parsed at lastModified time. */
+ private BackupDirectory backupDirectory;
+
+ /**
+ * A BackupDirectory that is cached based on the backup descriptor file.
+ *
+ * @param directory Path to the backup directory itself.
+ */
+ public CachedBackupDirectory(File directory)
+ {
+ directoryPath = directory.getPath();
+ backupInfo = new File(directoryPath + File.separator + BACKUP_DIRECTORY_DESCRIPTOR_FILE);
+ lastModified = -1;
+ backupDirectory = null;
+ }
+
+ /**
+ * Return a BackupDirectory. This will be recomputed every time the underlying descriptor (backup.info) file
+ * changes.
+ *
+ * @return An up-to-date BackupDirectory
+ * @throws IOException If a problem occurs while trying to read the contents of the descriptor file.
+ * @throws ConfigException If the contents of the descriptor file cannot be parsed to create a backup directory
+ * structure.
+ */
+ public synchronized BackupDirectory getBackupDirectory()
+ throws IOException, ConfigException
+ {
+ long currentModified = backupInfo.lastModified();
+ if (backupDirectory == null || currentModified != lastModified)
+ {
+ backupDirectory = BackupDirectory.readBackupDirectoryDescriptor(directoryPath);
+ lastModified = currentModified;
+ }
+ return backupDirectory;
+ }
+ }
/**
@@ -142,10 +195,11 @@
// Determine the set of backup directories that we will use by default.
Set<String> values = currentConfig.getBackupDirectory();
- backupDirectories = new LinkedHashSet<File>(values.size());
+ backupDirectories = new LinkedHashMap<File,CachedBackupDirectory>(values.size());
for (String s : values)
{
- backupDirectories.add(getFileForPath(s));
+ File dir = getFileForPath(s);
+ backupDirectories.put(dir, new CachedBackupDirectory(dir));
}
@@ -234,23 +288,24 @@
AttributeType backupPathType =
DirectoryServer.getAttributeType(ATTR_BACKUP_DIRECTORY_PATH, true);
- for (File f : backupDirectories)
+ for (File dir : backupDirectories.keySet())
{
try
{
// Check to see if the descriptor file exists. If not, then skip this
// backup directory.
- File descriptorFile = new File(f, BACKUP_DIRECTORY_DESCRIPTOR_FILE);
+ File descriptorFile = new File(dir, BACKUP_DIRECTORY_DESCRIPTOR_FILE);
if (! descriptorFile.exists())
{
continue;
}
DN backupDirDN = makeChildDN(backupBaseDN, backupPathType,
- f.getAbsolutePath());
+ dir.getAbsolutePath());
getBackupDirectoryEntry(backupDirDN);
numEntries++;
- } catch (Exception e) {}
+ }
+ catch (Exception e) {}
}
return numEntries;
@@ -308,11 +363,11 @@
if (backupBaseDN.equals(entryDN))
{
long count = 0;
- for (File f : backupDirectories)
+ for (File dir : backupDirectories.keySet())
{
// Check to see if the descriptor file exists. If not, then skip this
// backup directory.
- File descriptorFile = new File(f, BACKUP_DIRECTORY_DESCRIPTOR_FILE);
+ File descriptorFile = new File(dir, BACKUP_DIRECTORY_DESCRIPTOR_FILE);
if (! descriptorFile.exists())
{
continue;
@@ -324,8 +379,7 @@
{
try
{
- BackupDirectory backupDirectory =
- BackupDirectory.readBackupDirectoryDescriptor(f.getPath());
+ BackupDirectory backupDirectory = backupDirectories.get(dir).getBackupDirectory();
count += backupDirectory.getBackups().keySet().size();
}
catch (Exception e)
@@ -362,8 +416,8 @@
{
try
{
- BackupDirectory backupDirectory =
- BackupDirectory.readBackupDirectoryDescriptor(v.toString());
+ File dir = new File(v.toString());
+ BackupDirectory backupDirectory = backupDirectories.get(dir).getBackupDirectory();
count += backupDirectory.getBackups().keySet().size();
}
catch (Exception e)
@@ -468,7 +522,8 @@
BackupDirectory backupDirectory;
try
{
- backupDirectory = BackupDirectory.readBackupDirectoryDescriptor(v.toString());
+ File dir = new File(v.toString());
+ backupDirectory = backupDirectories.get(dir).getBackupDirectory();
}
catch (ConfigException ce)
{
@@ -752,11 +807,11 @@
{
AttributeType backupPathType =
DirectoryServer.getAttributeType(ATTR_BACKUP_DIRECTORY_PATH, true);
- for (File f : backupDirectories)
+ for (File dir : backupDirectories.keySet())
{
// Check to see if the descriptor file exists. If not, then skip this
// backup directory.
- File descriptorFile = new File(f, BACKUP_DIRECTORY_DESCRIPTOR_FILE);
+ File descriptorFile = new File(dir, BACKUP_DIRECTORY_DESCRIPTOR_FILE);
if (! descriptorFile.exists())
{
continue;
@@ -764,7 +819,7 @@
DN backupDirDN = makeChildDN(backupBaseDN, backupPathType,
- f.getAbsolutePath());
+ dir.getAbsolutePath());
Entry backupDirEntry;
try
@@ -793,8 +848,8 @@
{
try
{
- BackupDirectory backupDirectory =
- BackupDirectory.readBackupDirectoryDescriptor(v.toString());
+ File subtreeDir = new File(v.toString());
+ BackupDirectory backupDirectory = backupDirectories.get(subtreeDir).getBackupDirectory();
AttributeType idType =
DirectoryServer.getAttributeType(ATTR_BACKUP_ID,
true);
@@ -843,8 +898,8 @@
{
try
{
- BackupDirectory backupDirectory =
- BackupDirectory.readBackupDirectoryDescriptor(v.toString());
+ File dir = new File(v.toString());
+ BackupDirectory backupDirectory = backupDirectories.get(dir).getBackupDirectory();
AttributeType idType =
DirectoryServer.getAttributeType(ATTR_BACKUP_ID,
true);
@@ -1038,10 +1093,11 @@
Set<String> values = cfg.getBackupDirectory();
- backupDirectories = new LinkedHashSet<File>(values.size());
+ backupDirectories = new LinkedHashMap<File,CachedBackupDirectory>(values.size());
for (String s : values)
{
- backupDirectories.add(getFileForPath(s));
+ File dir = getFileForPath(s);
+ backupDirectories.put(dir, new CachedBackupDirectory(dir));
}
currentConfig = cfg;
@@ -1068,7 +1124,6 @@
/** {@inheritDoc} */
- @Override
public void preloadEntryCache() throws UnsupportedOperationException {
throw new UnsupportedOperationException("Operation not supported.");
}
--
Gitblit v1.10.0