boolean processedHere = true; // The LN was cleaned here.
boolean obsolete = false; // The LN is no longer in use.
boolean completed = false; // This method completed.
BIN bin = null;
DIN parentDIN = null; // for DupCountLNs
try {
/*
* 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()) {
cleaner.addPendingDB(db);
nLNsDeadThisRun++;
obsolete = true;
completed = true;
return;
}
Tree tree = db.getTree();
assert tree != null;
/*
* Search down to the bottom most level for the parent of this LN.
*/
boolean parentFound = tree.getParentBINForChildLN
(location, key, dupKey, ln,
false, // splitsAllowed
true, // findDeletedEntries
false, // searchDupTree
Cleaner.UPDATE_GENERATION);
bin = location.bin;
int index = location.index;
if (!parentFound) {
nLNsDeadThisRun++;
obsolete = true;
completed = true;
return;
}
/*
* Now we're at the parent for this LN, whether BIN, DBIN or DIN.
* If knownDeleted, LN is deleted and can be purged.
*/
if (bin.isEntryKnownDeleted(index)) {
nLNsDeadThisRun++;
obsolete = true;
completed = true;
return;
}
/*
* Determine whether the parent is the current BIN, or in the case
* of a DupCountLN, a DIN. Get the tree LSN in either case.
*/
boolean isDupCountLN = ln.containsDuplicates();
long treeLsn;
if (isDupCountLN) {
parentDIN = (DIN) bin.fetchTarget(index);
parentDIN.latch(Cleaner.UPDATE_GENERATION);
ChildReference dclRef = parentDIN.getDupCountLNRef();
treeLsn = dclRef.getLsn();
} else {
treeLsn = bin.getLsn(index);
}
/* Process this LN that was found in the tree. */
processedHere = false;
processFoundLN(info, logLsn, treeLsn, bin, index, parentDIN);
completed = true;
/*
* For all other non-deleted LNs in this BIN, lookup their LSN
* in the LN queue and process any matches.
*/
if (!isDupCountLN) {
/*
* For deferred write DBs with duplicates, the entry for an LSN
* that matches may contain a DIN, and should not be processed.
* This occurs when the LN has been moved from the BIN into a
* duplicate subtree and the DIN has not been logged. [#16039]
*/
boolean isBinInDupDwDb = db.isDeferredWriteMode() &&
db.getSortedDuplicates() &&
!bin.containsDuplicates();
for (int i = 0; i < bin.getNEntries(); i += 1) {
long binLsn = bin.getLsn(i);
if (i != index &&
!bin.isEntryKnownDeleted(i) &&
!bin.isEntryPendingDeleted(i) &&
DbLsn.getFileNumber(binLsn) == fileNum.longValue()) {
Long myOffset =
Long.valueOf(DbLsn.getFileOffset(binLsn));
LNInfo myInfo;
if (isBinInDupDwDb &&
bin.getTarget(i) instanceof DIN) {
/* LN is in the dup subtree, it's not a match. */
myInfo = null;
} else {
/* If the offset is in the cache, it's a match. */
myInfo = lookAheadCache.remove(myOffset);
}
if (myInfo != null) {
nLNQueueHitsThisRun++;
nLNsCleanedThisRun++;
processFoundLN
(myInfo, binLsn, binLsn, bin, i, null);
}
}
}
}
return;
} finally {
if (parentDIN != null) {
parentDIN.releaseLatch();
}
if (bin != null) {
bin.releaseLatch();
}