IndexRebuildThread.java revision a395dd575518d9e5280fc5d5d5ef47c61b174647
/*
* 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 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.backends.jeb;
import org.opends.messages.Message;
import org.opends.server.api.DirectoryThread;
import com.sleepycat.je.*;
import org.opends.server.types.*;
import static org.opends.messages.JebMessages.
ERR_JEB_MISSING_DN2ID_RECORD;
import static org.opends.messages.JebMessages.
ERR_JEB_REBUILD_INDEX_FAILED;
import static org.opends.messages.JebMessages.
ERR_JEB_REBUILD_INSERT_ENTRY_FAILED;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
/**
* A thread to do the actual work of rebuilding an index.
*/
public class IndexRebuildThread extends DirectoryThread
{
/**
* The tracer object for the debug logger.
*/
private static final DebugTracer TRACER = getTracer();
/**
* The entry container.
*/
EntryContainer ec = null;
/**
* The internal database/indexType to rebuild.
*/
IndexType indexType = null;
/**
* The attribute indexType to rebuild.
*/
AttributeIndex attrIndex = null;
/**
* The VLV index to rebuild.
*/
VLVIndex vlvIndex = null;
/**
* The indexType to rebuild.
*/
Index index = null;
/**
* The ID2ENTRY database.
*/
ID2Entry id2entry = null;
/**
* The number of total entries to rebuild. An negative value indicates this
* value is not yet known.
*/
long totalEntries = -1;
/**
* The number of entries processed.
*/
long processedEntries = 0;
/**
* The number of entries rebuilt successfully.
*/
long rebuiltEntries = 0;
/**
* The number of entries rebuilt with possible duplicates.
*/
long duplicatedEntries = 0;
/**
* The number of entries that were skipped because they were not applicable
* for the indexType or because an error occurred.
*/
long skippedEntries = 0;
/**
* The types of internal indexes that are rebuildable.
*/
enum IndexType
{
DN2ID, DN2URI, ID2CHILDREN, ID2SUBTREE, INDEX, ATTRIBUTEINDEX, VLVINDEX
}
/**
* Construct a new index rebuild thread to rebuild a system index.
*
* @param ec The entry container to rebuild in.
* @param index The index type to rebuild.
*/
IndexRebuildThread(EntryContainer ec, IndexType index)
{
super("Index Rebuild Thread " + ec.getDatabasePrefix() + "_" +
index.toString());
this.ec = ec;
this.indexType = index;
this.id2entry = ec.getID2Entry();
}
/**
* Construct a new index rebuild thread to rebuild an index.
*
* @param ec The entry container to rebuild in.
* @param index The index to rebuild.
*/
IndexRebuildThread(EntryContainer ec, Index index)
{
super("Index Rebuild Thread " + index.getName());
this.ec = ec;
this.indexType = IndexType.INDEX;
this.index = index;
this.id2entry = ec.getID2Entry();
}
/**
* Construct a new index rebuild thread to rebuild an attribute index.
*
* @param ec The entry container to rebuild in.
* @param index The attribute index to rebuild.
*/
IndexRebuildThread(EntryContainer ec, AttributeIndex index)
{
super("Index Rebuild Thread " + index.getName());
this.ec = ec;
this.indexType = IndexType.ATTRIBUTEINDEX;
this.attrIndex = index;
this.id2entry = ec.getID2Entry();
}
/**
* Construct a new index rebuild thread to rebuild an VLV index.
*
* @param ec The entry container to rebuild in.
* @param vlvIndex The VLV index to rebuild.
*/
IndexRebuildThread(EntryContainer ec, VLVIndex vlvIndex)
{
super("Index Rebuild Thread " + vlvIndex.getName());
this.ec = ec;
this.indexType = IndexType.VLVINDEX;
this.vlvIndex = vlvIndex;
this.id2entry = ec.getID2Entry();
}
/**
* Clear the database and prep it for the rebuild.
*
* @throws DatabaseException if a JE databse error occurs while clearing
* the database being rebuilt.
*/
public void clearDatabase() throws DatabaseException
{
if(indexType == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No index type specified. Rebuild process " +
"terminated.");
}
return;
}
if(indexType == IndexType.ATTRIBUTEINDEX && attrIndex == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No attribute index specified. Rebuild process " +
"terminated.");
}
return;
}
if(indexType == IndexType.INDEX && index == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No index specified. Rebuild process terminated.");
}
return;
}
if(indexType == IndexType.VLVINDEX && vlvIndex == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No VLV index specified. Rebuild process " +
"terminated.");
}
return;
}
switch(indexType)
{
case DN2ID :
ec.clearDatabase(ec.getDN2ID());
break;
case DN2URI :
ec.clearDatabase(ec.getDN2URI());
break;
case ID2CHILDREN :
ec.clearDatabase(ec.getID2Children());
ec.getID2Children().setRebuildStatus(true);
break;
case ID2SUBTREE :
ec.clearDatabase(ec.getID2Subtree());
ec.getID2Subtree().setRebuildStatus(true);
break;
case ATTRIBUTEINDEX :
ec.clearAttributeIndex(attrIndex);
attrIndex.setRebuildStatus(true);
break;
case VLVINDEX :
ec.clearDatabase(vlvIndex);
vlvIndex.setRebuildStatus(true);
break;
case INDEX :
ec.clearDatabase(index);
index.setRebuildStatus(true);
}
}
/**
* Start the rebuild process.
*/
public void run()
{
if(indexType == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No index type specified. Rebuild process " +
"terminated.");
}
return;
}
if(indexType == IndexType.ATTRIBUTEINDEX && attrIndex == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No attribute index specified. Rebuild process " +
"terminated.");
}
return;
}
if(indexType == IndexType.INDEX && index == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No index specified. Rebuild process terminated.");
}
return;
}
if(indexType == IndexType.VLVINDEX && vlvIndex == null)
{
//TODO: throw error
if(debugEnabled())
{
TRACER.debugError("No VLV index specified. Rebuild process " +
"terminated.");
}
return;
}
try
{
totalEntries = getTotalEntries();
switch(indexType)
{
case DN2ID : rebuildDN2ID();
break;
case DN2URI : rebuildDN2URI();
break;
case ID2CHILDREN : rebuildID2Children();
break;
case ID2SUBTREE : rebuildID2Subtree();
break;
case ATTRIBUTEINDEX : rebuildAttributeIndex(attrIndex);
break;
case VLVINDEX : rebuildVLVIndex(vlvIndex);
break;
case INDEX : rebuildAttributeIndex(index);
}
if(debugEnabled())
{
TRACER.debugVerbose("Rebuilt %d entries", rebuiltEntries);
}
}
catch(Exception e)
{
Message message = ERR_JEB_REBUILD_INDEX_FAILED.get(
this.getName(), stackTraceToSingleLineString(e));
logError(message);
if(debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
/**
* Rebuild an interal DN2ID database.
*
* @throws DatabaseException If an error occurs during the rebuild.
*/
private void rebuildDN2ID() throws DatabaseException
{
DN2ID dn2id = ec.getDN2ID();
if(debugEnabled())
{
TRACER.debugInfo("Initiating rebuild of the %s database",
dn2id.getName());
TRACER.debugVerbose("%d entries will be rebuilt", totalEntries);
}
//Iterate through the id2entry database and insert associated dn2id
//records.
Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
try
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
LockMode lockMode = LockMode.DEFAULT;
OperationStatus status;
for (status = cursor.getFirst(key, data, lockMode);
status == OperationStatus.SUCCESS;
status = cursor.getNext(key, data, lockMode))
{
Transaction txn = ec.beginTransaction();
try
{
EntryID entryID = new EntryID(key);
Entry entry = JebFormat.entryFromDatabase(data.getData(),
ec.getRootContainer().getCompressedSchema());
// Insert into dn2id.
if (dn2id.insert(txn, entry.getDN(), entryID))
{
rebuiltEntries++;
}
else
{
// The entry ID already exists in the database.
// This could happen if some other process got to this entry
// before we did. Since the backend should be offline, this
// might be a problem.
duplicatedEntries++;
if(debugEnabled())
{
TRACER.debugInfo("Unable to insert entry with DN %s and ID %d " +
"into the DN2ID database because it already exists.",
entry.getDN().toString(), entryID.longValue());
}
}
EntryContainer.transactionCommit(txn);
processedEntries++;
}
catch (Exception e)
{
EntryContainer.transactionAbort(txn);
skippedEntries++;
Message message = ERR_JEB_REBUILD_INSERT_ENTRY_FAILED.get(
dn2id.getName(), stackTraceToSingleLineString(e));
logError(message);
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
}
finally
{
cursor.close();
}
}
/**
* Rebuild the ID2URI internal database.
*
* @throws DatabaseException if an error occurs during rebuild.
*/
private void rebuildDN2URI() throws DatabaseException
{
DN2URI dn2uri = ec.getDN2URI();
if(debugEnabled())
{
TRACER.debugInfo("Initiating rebuild of the %s database",
dn2uri.getName());
TRACER.debugVerbose("%d entries will be rebuilt", totalEntries);
}
//Iterate through the id2entry database and insert associated dn2uri
//records.
Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
try
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
LockMode lockMode = LockMode.DEFAULT;
OperationStatus status;
for (status = cursor.getFirst(key, data, lockMode);
status == OperationStatus.SUCCESS;
status = cursor.getNext(key, data, lockMode))
{
Transaction txn = ec.beginTransaction();
try
{
EntryID entryID = new EntryID(key);
Entry entry = JebFormat.entryFromDatabase(data.getData(),
ec.getRootContainer().getCompressedSchema());
// Insert into dn2uri.
if (dn2uri.addEntry(txn, entry))
{
rebuiltEntries++;
}
else
{
// The entry DN and URIs already exists in the database.
// This could happen if some other process got to this entry
// before we did. Since the backend should be offline, this
// might be a problem.
duplicatedEntries++;
if(debugEnabled())
{
TRACER.debugInfo("Unable to insert entry with DN %s and ID %d " +
"into the DN2URI database because it already exists.",
entry.getDN().toString(), entryID.longValue());
}
}
EntryContainer.transactionCommit(txn);
processedEntries++;
}
catch (Exception e)
{
EntryContainer.transactionAbort(txn);
skippedEntries++;
Message message = ERR_JEB_REBUILD_INSERT_ENTRY_FAILED.get(
dn2uri.getName(), stackTraceToSingleLineString(e));
logError(message);
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
}
finally
{
cursor.close();
}
}
/**
* Rebuild the ID2Subtree internal index. This depends on the DN2ID and DN2URI
* databases being complete.
*
* @throws DatabaseException if an error occurs during rebuild.
*/
private void rebuildID2Children() throws DatabaseException
{
Index id2children = ec.getID2Children();
if(debugEnabled())
{
TRACER.debugInfo("Initiating rebuild of the %s index",
id2children.getName());
TRACER.debugVerbose("%d entries will be rebuilt", totalEntries);
}
DN2ID dn2id = ec.getDN2ID();
DN2URI dn2uri = ec.getDN2URI();
//Iterate through the id2entry database and insert associated dn2children
//records.
Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
try
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
LockMode lockMode = LockMode.DEFAULT;
OperationStatus status;
for (status = cursor.getFirst(key, data, lockMode);
status == OperationStatus.SUCCESS;
status = cursor.getNext(key, data, lockMode))
{
Transaction txn = ec.beginTransaction();
try
{
EntryID entryID = new EntryID(key);
Entry entry = JebFormat.entryFromDatabase(data.getData(),
ec.getRootContainer().getCompressedSchema());
// Check that the parent entry exists.
DN parentDN = ec.getParentWithinBase(entry.getDN());
if (parentDN != null)
{
// Check for referral entries above the target.
dn2uri.targetEntryReferrals(entry.getDN(), null);
// Read the parent ID from dn2id.
EntryID parentID = dn2id.get(txn, parentDN);
if (parentID != null)
{
// Insert into id2children for parent ID.
if(id2children.insertID(txn, parentID.getDatabaseEntry(),
entryID))
{
rebuiltEntries++;
}
else
{
// The entry already exists in the database.
// This could happen if some other process got to this entry
// before we did. Since the backend should be offline, this
// might be a problem.
if(debugEnabled())
{
duplicatedEntries++;
TRACER.debugInfo("Unable to insert entry with DN %s and " +
"ID %d into the DN2Subtree database because it already " +
"exists.",
entry.getDN().toString(), entryID.longValue());
}
}
}
else
{
Message msg = ERR_JEB_MISSING_DN2ID_RECORD.get(
parentDN.toNormalizedString());
throw new JebException(msg);
}
}
else
{
skippedEntries++;
}
EntryContainer.transactionCommit(txn);
processedEntries++;
}
catch (Exception e)
{
EntryContainer.transactionAbort(txn);
skippedEntries++;
Message message = ERR_JEB_REBUILD_INSERT_ENTRY_FAILED.get(
id2children.getName(), stackTraceToSingleLineString(e));
logError(message);
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
id2children.setRebuildStatus(false);
id2children.setTrusted(null, true);
}
finally
{
cursor.close();
}
}
/**
* Rebuild the ID2Subtree internal index. This depends on the DN2ID and DN2URI
* databases being complete.
*
* @throws DatabaseException if an error occurs during rebuild.
*/
private void rebuildID2Subtree() throws DatabaseException
{
Index id2subtree = ec.getID2Subtree();
if(debugEnabled())
{
TRACER.debugInfo("Initiating rebuild of the %s index",
id2subtree.getName());
TRACER.debugVerbose("%d entries will be rebuilt", totalEntries);
}
DN2ID dn2id = ec.getDN2ID();
DN2URI dn2uri = ec.getDN2URI();
//Iterate through the id2entry database and insert associated dn2subtree
//records.
Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
try
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
LockMode lockMode = LockMode.DEFAULT;
OperationStatus status;
for (status = cursor.getFirst(key, data, lockMode);
status == OperationStatus.SUCCESS;
status = cursor.getNext(key, data, lockMode))
{
Transaction txn = ec.beginTransaction();
try
{
EntryID entryID = new EntryID(key);
Entry entry = JebFormat.entryFromDatabase(data.getData(),
ec.getRootContainer().getCompressedSchema());
// Check that the parent entry exists.
DN parentDN = ec.getParentWithinBase(entry.getDN());
if (parentDN != null)
{
boolean success = true;
// Check for referral entries above the target.
dn2uri.targetEntryReferrals(entry.getDN(), null);
// Read the parent ID from dn2id.
EntryID parentID = dn2id.get(txn, parentDN);
if (parentID != null)
{
// Insert into id2subtree for parent ID.
if(!id2subtree.insertID(txn, parentID.getDatabaseEntry(),
entryID))
{
success = false;
}
// Iterate up through the superior entries, starting above the
// parent.
for (DN dn = ec.getParentWithinBase(parentDN); dn != null;
dn = ec.getParentWithinBase(dn))
{
// Read the ID from dn2id.
EntryID nodeID = dn2id.get(null, dn);
if (nodeID != null)
{
// Insert into id2subtree for this node.
if(!id2subtree.insertID(null, nodeID.getDatabaseEntry(),
entryID))
{
success = false;
}
}
else
{
Message msg =
ERR_JEB_MISSING_DN2ID_RECORD.get(dn.toNormalizedString());
throw new JebException(msg);
}
}
}
else
{
Message msg = ERR_JEB_MISSING_DN2ID_RECORD.get(
parentDN.toNormalizedString());
throw new JebException(msg);
}
if(success)
{
rebuiltEntries++;
}
else
{
// The entry already exists in the database.
// This could happen if some other process got to this entry
// before we did. Since the backend should be offline, this
// might be a problem.
if(debugEnabled())
{
duplicatedEntries++;
TRACER.debugInfo("Unable to insert entry with DN %s and ID " +
"%d into the DN2Subtree database because it already " +
"exists.", entry.getDN().toString(), entryID.longValue());
}
}
}
else
{
skippedEntries++;
}
EntryContainer.transactionCommit(txn);
processedEntries++;
}
catch (Exception e)
{
EntryContainer.transactionAbort(txn);
skippedEntries++;
Message message = ERR_JEB_REBUILD_INSERT_ENTRY_FAILED.get(
id2subtree.getName(), stackTraceToSingleLineString(e));
logError(message);
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
id2subtree.setRebuildStatus(false);
id2subtree.setTrusted(null, true);
}
finally
{
cursor.close();
}
}
/**
* Rebuild the attribute index.
*
* @param index The indexType to rebuild.
* @throws DatabaseException if an error occurs during rebuild.
*/
private void rebuildAttributeIndex(AttributeIndex index)
throws DatabaseException
{
if(debugEnabled())
{
TRACER.debugInfo("Initiating rebuild of the %s index",
index.getName());
TRACER.debugVerbose("%d entries will be rebuilt", totalEntries);
}
//Iterate through the id2entry database and insert associated indexType
//records.
Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
try
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
LockMode lockMode = LockMode.DEFAULT;
OperationStatus status;
for (status = cursor.getFirst(key, data, lockMode);
status == OperationStatus.SUCCESS;
status = cursor.getNext(key, data, lockMode))
{
Transaction txn = ec.beginTransaction();
try
{
EntryID entryID = new EntryID(key);
Entry entry = JebFormat.entryFromDatabase(data.getData(),
ec.getRootContainer().getCompressedSchema());
// Insert into attribute indexType.
if(index.addEntry(txn, entryID, entry))
{
rebuiltEntries++;
}
else
{
// The entry already exists in one or more entry sets.
// This could happen if some other process got to this entry
// before we did. Since the backend should be offline, this
// might be a problem.
if(debugEnabled())
{
duplicatedEntries++;
TRACER.debugInfo("Unable to insert entry with DN %s and ID %d " +
"into the DN2Subtree database because it already " +
"exists.",
entry.getDN().toString(), entryID.longValue());
}
}
EntryContainer.transactionCommit(txn);
processedEntries++;
}
catch (Exception e)
{
EntryContainer.transactionAbort(txn);
skippedEntries++;
Message message = ERR_JEB_REBUILD_INSERT_ENTRY_FAILED.get(
index.getName(), stackTraceToSingleLineString(e));
logError(message);
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
index.setRebuildStatus(false);
index.setTrusted(null, true);
}
finally
{
cursor.close();
}
}
/**
* Rebuild the VLV index.
*
* @param vlvIndex The VLV index to rebuild.
* @throws DatabaseException if an error occurs during rebuild.
*/
private void rebuildVLVIndex(VLVIndex vlvIndex)
throws DatabaseException
{
//Iterate through the id2entry database and insert associated indexType
//records.
Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
try
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
LockMode lockMode = LockMode.DEFAULT;
OperationStatus status;
for (status = cursor.getFirst(key, data, lockMode);
status == OperationStatus.SUCCESS;
status = cursor.getNext(key, data, lockMode))
{
Transaction txn = ec.beginTransaction();
try
{
EntryID entryID = new EntryID(key);
Entry entry = JebFormat.entryFromDatabase(data.getData(),
ec.getRootContainer().getCompressedSchema());
// Insert into attribute indexType.
if(vlvIndex.addEntry(txn, entryID, entry))
{
rebuiltEntries++;
}
else
{
// The entry already exists in one or more entry sets.
// This could happen if some other process got to this entry
// before we did. Since the backend should be offline, this
// might be a problem.
if(debugEnabled())
{
duplicatedEntries++;
TRACER.debugInfo("Unable to insert entry with DN %s and ID %d " +
"into the VLV index %s because it already " +
"exists.",
entry.getDN().toString(), entryID.longValue(),
vlvIndex.getName());
}
}
EntryContainer.transactionCommit(txn);
processedEntries++;
}
catch (Exception e)
{
EntryContainer.transactionAbort(txn);
skippedEntries++;
Message message = ERR_JEB_REBUILD_INSERT_ENTRY_FAILED.get(
index.getName(), stackTraceToSingleLineString(e));
logError(message);
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
vlvIndex.setRebuildStatus(false);
vlvIndex.setTrusted(null, true);
}
finally
{
cursor.close();
}
}
/**
* Rebuild the partial attribute index.
*
* @param index The indexType to rebuild.
* @throws DatabaseException if an error occurs during rebuild.
*/
private void rebuildAttributeIndex(Index index)
throws DatabaseException
{
if(debugEnabled())
{
TRACER.debugInfo("Initiating rebuild of the %s attribute index",
index.getName());
TRACER.debugVerbose("%d entries will be rebuilt", totalEntries);
}
//Iterate through the id2entry database and insert associated indexType
//records.
Cursor cursor = id2entry.openCursor(null, CursorConfig.READ_COMMITTED);
try
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
LockMode lockMode = LockMode.DEFAULT;
OperationStatus status;
for (status = cursor.getFirst(key, data, lockMode);
status == OperationStatus.SUCCESS;
status = cursor.getNext(key, data, lockMode))
{
Transaction txn = ec.beginTransaction();
try
{
EntryID entryID = new EntryID(key);
Entry entry = JebFormat.entryFromDatabase(data.getData(),
ec.getRootContainer().getCompressedSchema());
// Insert into attribute indexType.
if(index.addEntry(txn, entryID, entry))
{
rebuiltEntries++;
}
else
{
// The entry already exists in one or more entry sets.
// This could happen if some other process got to this entry
// before we did. Since the backend should be offline, this
// might be a problem.
if(debugEnabled())
{
duplicatedEntries++;
TRACER.debugInfo("Unable to insert entry with DN %s and ID %d " +
"into the DN2Subtree database because it already " +
"exists.",
entry.getDN().toString(), entryID.longValue());
}
}
EntryContainer.transactionCommit(txn);
processedEntries++;
}
catch (Exception e)
{
EntryContainer.transactionAbort(txn);
skippedEntries++;
Message message = ERR_JEB_REBUILD_INSERT_ENTRY_FAILED.get(
index.getName(), stackTraceToSingleLineString(e));
logError(message);
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
}
index.setRebuildStatus(false);
index.setTrusted(null, true);
}
finally
{
cursor.close();
}
}
/**
* Get the total entries to process in the rebuild.
*
* @return The total entries to process.
* @throws DatabaseException if an error occurs while getting the total
* number of entries to process.
*/
public long getTotalEntries() throws DatabaseException
{
//If total entries is not calculated yet, do it now.
if(totalEntries < 0)
{
totalEntries = id2entry.getRecordCount();
}
return totalEntries;
}
/**
* Get the number of entries processed in the rebuild.
*
* @return The total entries processed.
*/
public long getProcessedEntries()
{
return processedEntries;
}
/**
* Get the number of entries successfully rebuilt.
*
* @return The number of entries successfully rebuilt.
*/
public long getRebuiltEntries()
{
return rebuiltEntries;
}
/**
* Get the number of entries that encountered duplicated indexType values in
* the rebuild process.
*
* @return The number of entries that encountered duplicated indexType values
* in the rebuild process.
*/
public long getDuplicatedEntries()
{
return duplicatedEntries;
}
/**
* Get the number of entries skipped because they were either not applicable
* or an error occurred during the process.
*
* @return The number of entries skipped.
*/
public long getSkippedEntries()
{
return skippedEntries;
}
/**
* Get the index type being rebuilt by this thread.
*
* @return The index type being rebuilt by this thread.
*/
public IndexType getIndexType()
{
return indexType;
}
}