blob: 3c59fd8c2c6893ce40ba21e165c23d668b8b24ee [file] [log] [blame]
/*-
* Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
package com.sleepycat.je.cleaner;
import java.util.HashMap;
import java.util.Map;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.log.LogEntryType;
import com.sleepycat.je.utilint.DbLsn;
/**
* Accumulates changes to the utilization profile during recovery.
*
* <p>Per-database information is keyed by DatabaseId because the DatabaseImpl
* is not always available during recovery. In fact this is the only reason
* that a "local" tracker is used during recovery -- to avoid requiring that
* the DatabaseImpl is available, which is necessary to use the "global"
* UtilizationTracker. There is no requirement to accumulate totals locally,
* since recovery is single threaded.</p>
*
* <p>When finished with this object, its information should be added to the
* Environment's UtilizationTracker and DatabaseImpl objects by calling
* transferToUtilizationTracker. This is done at the end of recovery, just
* prior to the checkpoint. It does not have to be done under the log write
* latch, since recovery is single threaded.</p>
*/
public class RecoveryUtilizationTracker extends BaseUtilizationTracker {
/* File number -> LSN of FileSummaryLN */
private final Map<Long, Long> fileSummaryLsns;
public RecoveryUtilizationTracker(EnvironmentImpl env) {
super(env);
fileSummaryLsns = new HashMap<>();
}
/**
* Saves the LSN of the last logged FileSummaryLN.
*/
public void saveLastLoggedFileSummaryLN(long fileNum, long lsn) {
fileSummaryLsns.put(fileNum, lsn);
}
/**
* Counts the addition of all new log entries including LNs.
*/
public void countNewLogEntry(
long lsn,
LogEntryType type,
int size) {
countNew(lsn, type, size);
}
/**
* Counts the LSN of a node obsolete unconditionally.
*
* Even when trackOffset is true, duplicate offsets are not checked (no
* assertion is fired) because recovery is known to count the same LSN
* offset twice in certain circumstances.
*/
public void countObsoleteUnconditional(
long lsn,
LogEntryType type,
int size,
boolean trackOffset) {
countObsolete(
lsn, type, size,
trackOffset,
false); // checkDupOffsets
}
/**
* Counts the oldLsn of a node obsolete if it has not already been counted
* at the point of lsn in the log.
*
* Even when trackOffset is true, duplicate offsets are not checked (no
* assertion is fired) because recovery is known to count the same LSN
* offset twice in certain circumstances.
*/
public void countObsoleteIfUncounted(
long oldLsn,
long newLsn,
LogEntryType type,
int size,
boolean trackOffset) {
Long fileNum = DbLsn.getFileNumber(oldLsn);
if (!isFileUncounted(fileNum, newLsn)) {
return;
}
countObsolete(
oldLsn, type, size,
trackOffset,
false); // checkDupOffsets
}
/**
* Overrides this method for recovery and returns whether the most recently
* seen FileSummaryLN for the given file is prior to the given LSN.
*/
@Override
boolean isFileUncounted(Long fileNum, long lsn) {
long fsLsn = DbLsn.longToLsn(fileSummaryLsns.get(fileNum));
int cmpFsLsnToNewLsn = (fsLsn != DbLsn.NULL_LSN ?
DbLsn.compareTo(fsLsn, lsn) : -1);
return cmpFsLsnToNewLsn < 0;
}
/**
* Clears all accmulated utilization info for the given file.
*/
public void resetFileInfo(long fileNum) {
TrackedFileSummary trackedSummary = getTrackedFile(fileNum);
if (trackedSummary != null) {
trackedSummary.reset();
}
}
}