From 325b2ee4a27d0c24aa0a539f7bd0a8cf24905ff7 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Tue, 10 Apr 2007 20:41:27 +0000
Subject: [PATCH] Added the following capabilities to OpenDS: - Index rebuilding capabilities. All indexes including system and attribute indexes can be rebuilt. Each index will be rebuilt by a seperate thread to increase performance. A max number of rebuild threads could be set to limit the resources used by large rebuild jobs. Partial rebuilds of attribute indexes could also be done by specifying the attribute index type after the attribute type (ie. sn.approximate). - Index rebuilding standalone tool. Rebuilding of attribute indexes could be done with the backend online. However, rebuilds including system indexes must be done with the backend offline. - Index rebuilding task. Rebuilding of attribute indexes are done with the backend online. Rebuilds that include system indexes will be performed after bring the backend offline. The user must have index-rebuild privilages to rebuild indexes. - Approxitae indexing capability. The value of the attribute will be normalized using the approximate maching rule of that attribute type. This is used as the key for the index. Approximate indexes are fully supported by the index verify, rebuild, and import jobs. - Fixed bug in build.xml where weave is enabled even if a test.* property is set. - Consolidated some common tool messages. - Consolidated some JE backend methods common to all tools. - Added unit tests for rebuild job and approximate indexes.
---
opends/src/server/org/opends/server/backends/jeb/Index.java | 112 +++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 94 insertions(+), 18 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/jeb/Index.java b/opends/src/server/org/opends/server/backends/jeb/Index.java
index 4e30029..d367cdd 100644
--- a/opends/src/server/org/opends/server/backends/jeb/Index.java
+++ b/opends/src/server/org/opends/server/backends/jeb/Index.java
@@ -28,10 +28,9 @@
import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
+import static org.opends.server.loggers.debug.DebugLogger.debugInfo;
+import static org.opends.server.loggers.debug.DebugLogger.debugVerbose;
import org.opends.server.types.DebugLogLevel;
-import static org.opends.server.messages.JebMessages.
- MSGID_JEB_DATABASE_EXCEPTION;
-import static org.opends.server.messages.MessageHandler.getMessage;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.CursorConfig;
@@ -159,6 +158,12 @@
{
database = entryContainer.openDatabase(dbConfig, name);
threadLocalDatabase.set(database);
+
+ if(debugEnabled())
+ {
+ debugInfo("JE Index database %s opened with %d records.",
+ database.getDatabaseName(), database.count());
+ }
}
return database;
}
@@ -169,15 +174,19 @@
* @param txn A database transaction, or null if none is required.
* @param key The index key.
* @param entryID The entry ID.
+ * @return True if the entry ID is inserted or ignored because the entry limit
+ * count is exceeded. False if it alreadly exists in the entry ID set
+ * for the given key.
* @throws DatabaseException If an error occurs in the JE database.
*/
- public void insertID(Transaction txn, DatabaseEntry key, EntryID entryID)
+ public boolean insertID(Transaction txn, DatabaseEntry key, EntryID entryID)
throws DatabaseException
{
OperationStatus status;
LockMode lockMode = LockMode.RMW;
DatabaseEntry entryIDData = entryID.getDatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
+ boolean success = true;
status = EntryContainer.read(getDatabase(), txn, key, data, lockMode);
@@ -194,7 +203,10 @@
}
else
{
- entryIDList.add(entryID);
+ if(!entryIDList.add(entryID))
+ {
+ success = false;
+ }
}
byte[] after = entryIDList.toDatabase();
@@ -206,6 +218,8 @@
{
EntryContainer.put(getDatabase(), txn, key, entryIDData);
}
+
+ return success;
}
/**
@@ -507,25 +521,67 @@
* or null if none is required.
* @param cursorConfig The requested JE cursor configuration.
* @return A new JE cursor.
- * @throws JebException If an error occurs in the JE backend.
+ * @throws DatabaseException If an error occurs while attempting to open
+ * the cursor.
*/
public Cursor openCursor(Transaction txn, CursorConfig cursorConfig)
- throws JebException
+ throws DatabaseException
{
+ return getDatabase().openCursor(txn, cursorConfig);
+ }
+
+ /**
+ * Removes all records from the database.
+ * @param txn A JE database transaction to be used during the clear operation
+ * or null if not required. Using transactions increases the chance
+ * of lock contention.
+ * @return The number of records removed.
+ * @throws DatabaseException If an error occurs while cleaning the database.
+ */
+ public long clear(Transaction txn) throws DatabaseException
+ {
+ long deletedCount = 0;
+ Cursor cursor = openCursor(txn, null);
try
{
- return getDatabase().openCursor(txn, cursorConfig);
- }
- catch (DatabaseException e)
- {
- if (debugEnabled())
+ if(debugEnabled())
{
- debugCaught(DebugLogLevel.ERROR, e);
+ debugVerbose("%d existing records will be deleted from the " +
+ "database", getRecordCount());
}
- int msgID = MSGID_JEB_DATABASE_EXCEPTION;
- String message = getMessage(msgID, e.getMessage());
- throw new JebException(msgID, message, e);
+ DatabaseEntry data = new DatabaseEntry();
+ DatabaseEntry key = new DatabaseEntry();
+
+ OperationStatus status;
+
+ // Step forward until we deleted all records.
+ for (status = cursor.getFirst(key, data, LockMode.DEFAULT);
+ status == OperationStatus.SUCCESS;
+ status = cursor.getNext(key, data, LockMode.DEFAULT))
+ {
+ cursor.delete();
+ deletedCount++;
+ }
+ if(debugEnabled())
+ {
+ debugVerbose("%d records deleted", deletedCount);
+ }
}
+ catch(DatabaseException de)
+ {
+ if(debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, de);
+ }
+
+ throw de;
+ }
+ finally
+ {
+ cursor.close();
+ }
+
+ return deletedCount;
}
/**
@@ -534,13 +590,16 @@
* @param txn A database transaction, or null if none is required.
* @param entryID The entry ID.
* @param entry The entry to be indexed.
+ * @return True if all the indexType keys for the entry are added. False if
+ * the entry ID alreadly exists for some keys.
* @throws DatabaseException If an error occurs in the JE database.
* @throws DirectoryException If a Directory Server error occurs.
*/
- public void addEntry(Transaction txn, EntryID entryID, Entry entry)
+ public boolean addEntry(Transaction txn, EntryID entryID, Entry entry)
throws DatabaseException, DirectoryException
{
HashSet<ASN1OctetString> addKeys = new HashSet<ASN1OctetString>();
+ boolean success = true;
indexer.indexEntry(txn, entry, addKeys);
@@ -548,8 +607,13 @@
for (ASN1OctetString keyBytes : addKeys)
{
key.setData(keyBytes.value());
- insertID(txn, key, entryID);
+ if(!insertID(txn, key, entryID))
+ {
+ success = false;
+ }
}
+
+ return success;
}
@@ -615,4 +679,16 @@
}
}
+ /**
+ * Get the count of the number of entries stored.
+ *
+ * @return The number of entries stored.
+ *
+ * @throws DatabaseException If an error occurs in the JE database.
+ */
+ public long getRecordCount() throws DatabaseException
+ {
+ return EntryContainer.count(getDatabase());
+ }
+
}
--
Gitblit v1.10.0