boolean obsolete = false; // The LN is no longer in use.
boolean completed = false; // This method completed.
BasicLocker locker = null;
BIN bin = null;
DIN parentDIN = null;
try {
nPendingLNsProcessed.increment();
/*
* If the DB is gone, this LN is obsolete. If delete cleanup is in
* progress, put the DB into the DB pending set; this LN will be
* declared deleted after the delete cleanup is finished.
*/
if (db == null || db.isDeleted()) {
addPendingDB(db);
nLNsDead.increment();
obsolete = true;
completed = true;
return;
}
Tree tree = db.getTree();
assert tree != null;
/* Get a non-blocking lock on the original node ID. */
locker = BasicLocker.createBasicLocker(env, false /*noWait*/);
/* Don't allow this short-lived lock to be preempted/stolen. */
locker.setPreemptable(false);
LockResult lockRet = locker.nonBlockingLock
(ln.getNodeId(), LockType.READ, db);
if (lockRet.getLockGrant() == LockGrantType.DENIED) {
/* Try again later. */
nPendingLNsLocked.increment();
lockDenied = true;
completed = true;
return;
}
/*
* Search down to the bottom most level for the parent of this LN.
*
* We pass searchDupTree=true to search the dup tree by nodeID if
* necessary. This handles the case where dupKey is null because
* the pending entry was a deleted single-duplicate in a BIN.
*/
parentFound = tree.getParentBINForChildLN
(location, key, dupKey, ln,
false, // splitsAllowed
true, // findDeletedEntries
true, // searchDupTree
UPDATE_GENERATION);
bin = location.bin;
int index = location.index;
if (!parentFound) {
nLNsDead.increment();
obsolete = true;
completed = true;
return;
}
if (ln.containsDuplicates()) {
/* Migrate a DupCountLN. */
parentDIN = (DIN) bin.fetchTarget(index);
parentDIN.latch(UPDATE_GENERATION);
ChildReference dclRef = parentDIN.getDupCountLNRef();
processedHere = false;
migrateDupCountLN
(db, dclRef.getLsn(), parentDIN, dclRef,
true, // wasCleaned
true, // isPending
ln.getNodeId(), // lockedPendingNodeId
CLEAN_PENDING_LN);
} else {
/* Migrate a plain LN. */
processedHere = false;
migrateLN
(db, bin.getLsn(index), bin, index,
true, // wasCleaned
true, // isPending
ln.getNodeId(), // lockedPendingNodeId
true, // backgroundIO
CLEAN_PENDING_LN);
}
completed = true;
} catch (DatabaseException DBE) {
DBE.printStackTrace();
LoggerUtils.traceAndLogException
(env, "com.sleepycat.je.cleaner.Cleaner",
"processLN", "Exception thrown: ", DBE);
throw DBE;
} finally {
if (parentDIN != null) {
parentDIN.releaseLatch();
}
if (bin != null) {
bin.releaseLatch();
}