* add them to the cache if their corresponding log file exists. But
* delete those records that have no corresponding log file.
*/
Long[] existingFiles = env.getFileManager().getAllFileNumbers();
Locker locker = null;
CursorImpl cursor = null;
try {
locker = new BasicLocker(env);
cursor = new CursorImpl(fileSummaryDb, locker);
DatabaseEntry keyEntry = new DatabaseEntry();
DatabaseEntry dataEntry = new DatabaseEntry();
if (cursor.positionFirstOrLast(true, null)) {
/* Retrieve the first record. */
OperationStatus status =
cursor.getCurrentAlreadyLatched(keyEntry, dataEntry,
LockType.NONE, true);
if (status != OperationStatus.SUCCESS) {
/* The record we're pointing at may be deleted. */
status = cursor.getNext(keyEntry, dataEntry, LockType.NONE,
true, // go forward
false); // do need to latch
}
while (status == OperationStatus.SUCCESS) {
/* Perform eviction once per operation. */
env.getEvictor().doCriticalEviction();
FileSummaryLN ln = (FileSummaryLN)
cursor.getCurrentLN(LockType.NONE);
if (ln == null) {
/* Advance past a cleaned record. */
status = cursor.getNext
(keyEntry, dataEntry, LockType.NONE,
true, // go forward
false); // do need to latch
continue;
}
byte[] keyBytes = keyEntry.getData();
boolean isOldVersion = ln.hasStringKey(keyBytes);
long fileNum = ln.getFileNumber(keyBytes);
Long fileNumLong = new Long(fileNum);
if (Arrays.binarySearch(existingFiles, fileNumLong) >= 0) {
/* File exists, cache the FileSummaryLN. */
fileSummaryMap.put(fileNumLong, ln.getBaseSummary());
/*
* Update old version records to the new version. A
* zero sequence number is used to distinguish the
* converted records and to ensure that later records
* will have a greater sequence number.
*/
if (isOldVersion) {
insertFileSummary(ln, fileNum, 0);
cursor.latchBIN();
cursor.delete();
cursor.releaseBIN();
} else {
/* Always evict after using a file summary LN. */
cursor.evict();
}
} else {
/*
* File does not exist, remove the summary from the map
* and delete all FileSummaryLN records.
*/
fileSummaryMap.remove(fileNumLong);
if (isOldVersion) {
cursor.latchBIN();
cursor.delete();
cursor.releaseBIN();
} else {
deleteFileSummary(fileNumLong);
}
/*
* Do not evict after deleting since the compressor
* would have to fetch it again.
*/
}
/* Go on to the next entry. */
if (isOldVersion) {
/* Advance past the single old version record. */
status = cursor.getNext
(keyEntry, dataEntry, LockType.NONE,
true, // go forward
false); // do need to latch
} else {
/*
* Skip over other records for this file by adding one
* to the file number and doing a range search.
*/
if (!getFirstFSLN
(cursor,
fileNum + 1,
keyEntry, dataEntry,
LockType.NONE)) {
status = OperationStatus.NOTFOUND;
}
}
}
}
} finally {
if (cursor != null) {
cursor.releaseBINs();
cursor.close();
}
if (locker != null) {
locker.operationEnd();
}