* @return number of bytes evicted.
*/
private long evictIN(IN target, boolean backgroundIO, EvictionSource source)
throws DatabaseException {
DatabaseImpl db = target.getDatabase();
/* SharedEvictor uses multiple envs, do not use superclass envImpl. */
EnvironmentImpl useEnvImpl = db.getDbEnvironment();
long evictedBytes = 0;
/*
* Non-BIN INs are evicted by detaching them from their parent. For
* BINS, the first step is to remove deleted entries by compressing
* the BIN. The evictor indicates that we shouldn't fault in
* non-resident children during compression. After compression,
* LN logging and LN stripping may be performed.
*
* If LN stripping is used, first we strip the BIN by logging any dirty
* LN children and detaching all its resident LN targets. If we make
* progress doing that, we stop and will not evict the BIN itself until
* possibly later. If it has no resident LNs then we evict the BIN
* itself using the "regular" detach-from-parent routine.
*
* If the cleaner is doing clustering, we don't do BIN stripping if we
* can write out the BIN. Specifically LN stripping is not performed
* if the BIN is dirty AND the BIN is evictable AND cleaner
* clustering is enabled. In this case the BIN is going to be written
* out soon, and with clustering we want to be sure to write out the
* LNs with the BIN; therefore we don't do stripping.
*/
/*
* Use latchNoWait because if it's latched we don't want the cleaner
* to hold up eviction while it migrates an entire BIN. Latched INs
* have a high generation value, so not evicting makes sense. Pass
* false because we don't want to change the generation during the
* eviction process.
*/
boolean inline = (source == EvictionSource.CACHEMODE);
if (inline) {
target.latch(CacheMode.UNCHANGED);
} else {
if (!target.latchNoWait(CacheMode.UNCHANGED)) {
return evictedBytes;
}
}
boolean targetIsLatched = true;
boolean success = false;
try {
if (target instanceof BIN) {
/*
* Strip any resident LN targets right now. This may dirty
* the BIN if dirty LNs were written out. Note that
* migrated BIN entries cannot be stripped.
*/
evictedBytes = ((BIN) target).evictLNs();
if (evictedBytes > 0) {
nBINsStripped.increment();
}
}
/*
* If we were able to free any memory by LN stripping above,
* then we postpone eviction of the BIN until a later pass.
* The presence of migrated entries would have inhibited LN
* stripping. In that case, the BIN can still be evicted,
* but the marked entries will have to be migrated. That would
* happen when the target is logged in evictIN.
*/
if (!inline && evictedBytes != 0) {
success = true;
return evictedBytes;
}
if (!target.isEvictable()) {
success = true;
return evictedBytes;
}
/* Regular eviction. */
Tree tree = db.getTree();
/*
* Unit testing. The target is latched and we are about to release
* that latch and search for the parent. Make sure that other
* operations, such as dirtying an LN in the target BIN, can occur