request.getStart().getSequenceNo());
final LSN end = new LSN(request.getEnd().getViewId(),
request.getEnd().getSequenceNo());
LogEntries.Builder result = LogEntries.newBuilder();
ReusableBuffer resultPayLoad = BufferPool.allocate(0);
Logging.logMessage(Logging.LEVEL_INFO, this, "REQUEST received " +
"(start: %s, end: %s) from %s", start.toString(),
end.toString(), rq.getSenderAddress().toString());
// enhancement to prevent slaves from loading the DB from the master unnecessarily
if (start.equals(lastOnView.get())) {
Logging.logMessage(Logging.LEVEL_INFO, this,
"REQUEST answer is empty (there has been a failover only).");
rq.sendSuccess(result.build());
return;
}
final LSN firstEntry = new LSN(start.getViewId(),
start.getSequenceNo() + 1L);
assert (firstEntry.compareTo(end) < 0) :
"At least one LogEntry has to be requested!";
DiskLogIterator it = null;
LogEntry le = null;
synchronized (babuInterface.getCheckpointerLock()) {
try {
// wait, if there is a checkpoint in proceeding
babuInterface.waitForCheckpoint();
it = fileIO.getLogEntryIterator(start);
while (it.hasNext() &&
result.getLogEntriesCount() <
MAX_LOGENTRIES_PER_REQUEST && (le = it.next())
.getLSN().compareTo(end) < 0) {
try {
// we are not at the right position yet -> skip
if (le.getLSN().compareTo(firstEntry) < 0) continue;
// the first entry was not available ... bad
if (le.getLSN().compareTo(firstEntry) > 0 &&
result.getLogEntriesCount() == 0) {
break;
}
// add the logEntry to result list
assert (le.getPayload().array().length > 0) :
"Empty log-entries are not allowed!";
ReusableBuffer buf = le.serialize(checksum);
result.addLogEntries(
org.xtreemfs.babudb.pbrpc.GlobalTypes.LogEntry
.newBuilder().setLength(buf.remaining()));
int newSize = resultPayLoad.remaining() +
buf.remaining();
if (!resultPayLoad.enlarge(newSize)) {
ReusableBuffer tmp = BufferPool.allocate(newSize);
tmp.put(resultPayLoad);
BufferPool.free(resultPayLoad);
resultPayLoad = tmp;
}
resultPayLoad.put(buf);
BufferPool.free(buf);