public IEnumerable<LogCmd> recoverLogCmds()
{
// (0) are the log segments in the right order (assume they are)
// (1) read commands from the log segments
foreach (RootBlockLogSegment seg in active_log_segments) {
// open the log segment
Stream logstream = regionmgr.readRegionAddr(seg.logsegment_start).getNewAccessStream();
BinaryReader br = new BinaryReader(logstream);
while (true) {
LogPacketHeader hdr = Util.readStruct<LogPacketHeader>(br);
if (hdr.magic != LogPacketHeader.LOG_MAGIC) {
abortCorrupt("invalid magic: " + hdr.magic);
}
if (hdr.cmddata_length == 0 && hdr.checksum == 0) {
// we reached the end-of-chunks marker, seek back
// Console.WriteLine("Seek back... pos {0}, size {1}", br.BaseStream.Position,
// Util.structSize<LogPacketHeader>(ref hdr));
br.BaseStream.Seek(-(Util.structSize<LogPacketHeader>(ref hdr)), SeekOrigin.Current);
goto next_log_segment;
}
byte[] logchunk = new byte[hdr.cmddata_length];
if (br.Read(logchunk, 0, (int)hdr.cmddata_length) != hdr.cmddata_length) {
abortCorrupt("chunksize bytes not available");
}
// CRC the chunk and verify against checksum
UInt16 nchecksum = Util.Crc16.Instance.ComputeChecksum(logchunk);
if (nchecksum != hdr.checksum) {
abortCorrupt("computed checksum: " + nchecksum + " didn't match: " + hdr.checksum);
}
// check the LWSN order
if (hdr.curLWSN < _logWaitSequenceNumber) {
abortCorrupt("out of order recovery, packet LWSN: " + hdr.curLWSN + " < " + _logWaitSequenceNumber);
}
_logWaitSequenceNumber = hdr.curLWSN;
// decode and apply the records
BinaryReader mbr = new BinaryReader(new MemoryStream(logchunk));
while (mbr.BaseStream.Position != mbr.BaseStream.Length) {
UInt32 cmdsize = mbr.ReadUInt32();
byte cmdtype = mbr.ReadByte();
byte[] cmdbytes = new byte[cmdsize];
if (mbr.Read(cmdbytes, 0, (int)cmdsize) != cmdsize) {
abortCorrupt("error reading command bytes");
}
// construct the LogCmd yield result...
yield return ( new LogCmd((LogCommands)cmdtype, cmdbytes) );
}
} // ... while there are still log records
next_log_segment:
// close this segment to move onto the next one
br = null;
logstream.Close();
} // .. foreach log segment
}