void scanLoadTransactionMap(final long from, final long timestamp, final int recordSize)
throws PersistitIOException {
read(from, TM.OVERHEAD);
final int count = TM.getEntryCount(_readBuffer);
if (count * TM.ENTRY_SIZE + TM.OVERHEAD != recordSize) {
throw new CorruptJournalException("Invalid record size " + recordSize + " for TM record at "
+ addressToString(from, timestamp));
}
long address = from + TM.OVERHEAD;
int index = 0;
int loaded = 0;
for (int remaining = count; remaining > 0; remaining--) {
if (index == loaded) {
final int loadedSize = Math.min(_readBuffer.capacity() / TM.ENTRY_SIZE, remaining) * TM.ENTRY_SIZE;
read(address, loadedSize);
address += loadedSize;
index = 0;
loaded = loadedSize / TM.ENTRY_SIZE;
if (loaded <= 0) {
throw new CorruptJournalException("Could not load TramsactionMap segment in entry "
+ (count - remaining + 1) + " at " + addressToString(from, timestamp));
}
}
final long startTimestamp = TM.getEntryStartTimestamp(_readBuffer, index);
final long commitTimestamp = TM.getEntryCommitTimestamp(_readBuffer, index);
final long journalAddress = TM.getEntryJournalAddress(_readBuffer, index);
final long lastRecordAddress = TM.getLastRecordAddress(_readBuffer, index);
if (!isZombieTransaction(journalAddress)) {
final TransactionMapItem ts = new TransactionMapItem(startTimestamp, journalAddress);
final Long key = Long.valueOf(startTimestamp);
ts.setCommitTimestamp(commitTimestamp);
ts.setLastRecordAddress(lastRecordAddress);
if (_recoveredTransactionMap.put(key, ts) != null) {
throw new CorruptJournalException("Redundant record in TransactionMap record " + ts + " entry "
+ (count - remaining + 1) + " at " + addressToString(address, startTimestamp));
}
_persistit.getTimestampAllocator().updateTimestamp(commitTimestamp);
}