*/
private boolean fillFromLogBuffer(long windowFileNum,
long targetOffset)
throws DatabaseException {
LogBuffer logBuffer = null;
try {
long fileLocation = DbLsn.makeLsn(windowFileNum, targetOffset);
logBuffer = logManager.getReadBufferByLsn(fileLocation);
if (logBuffer == null) {
return false;
}
/*
* Copy at much as we can of the logBuffer into the window's
* readBuffer. We don't call ByteBuffer.put(ByteBuffer) because
* the logBuffer may be larger than the window readBuffer, and
* we don't want to get an overflow. Instead, we convert to an
* array and carefully size the copy. A LogBuffer is positioned
* for writing, and hasn't yet been flipped. LogManager.get()
* does an absolute retrieval of bytes from the buffer, because
* it knows that the log entry exists, and is only reading one
* entry. We need to flip the buffer, because we don't know
* apriori how much is in the buffer, and we want to scan it.
*/
/*
* Put the logBuffer's contents into wholeContents, and
* position wholeContents at the desired target offset. If
* this logBuffer had been the currentWriteBuffer, it's
* positioned for writing and must be flipped for reading.
*/
ByteBuffer wholeContents =
logBuffer.getDataBuffer().duplicate();
if (wholeContents.position() != 0) {
wholeContents.flip();
}
long firstOffset =
DbLsn.getFileOffset(logBuffer.getFirstLsn());
wholeContents.position((int) (targetOffset - firstOffset));
/* Make a buffer which starts at target. */
ByteBuffer startAtTarget = wholeContents.slice();
byte[] data = startAtTarget.array();
int availableContentLen = startAtTarget.limit();
int copyLength =
(availableContentLen > readBuffer.capacity()) ?
readBuffer.capacity() : availableContentLen;
readBuffer.clear();
readBuffer.put(data, startAtTarget.arrayOffset(), copyLength);
readBuffer.flip();
/* LogBuffers were just written and use the current version. */
setFileNum(windowFileNum, LogEntryType.LOG_VERSION);
startOffset = targetOffset;
endOffset = startOffset + readBuffer.limit();
readBuffer.position(0);
return true;
} finally {
if (logBuffer != null) {
logBuffer.release();
}
}
}