Bend.LogSegmentsHandler.recoverLogCmds C# (CSharp) Method

recoverLogCmds() public method

public recoverLogCmds ( ) : IEnumerable
return IEnumerable
        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
        }

Usage Example

Example #1
0
        private void _InitResume(IRegionManager regionmgr)
        {
            this.rootblockstream = regionmgr.readRegionAddr(0).getNewAccessStream();
            root = Util.readStruct<RootBlockHeader>(rootblockstream);
            if (!root.IsValid()) {
                throw new Exception("invalid root block");
            }
            RootBlockLogSegment[] log_segments = new RootBlockLogSegment[root.num_logsegments];
            for (int i=0;i<root.num_logsegments;i++) {
                log_segments[i] = Util.readStruct<RootBlockLogSegment>(rootblockstream);
            }

            // setup the log segment handler
            this.log_handler = new LogSegmentsHandler(this,regionmgr, log_segments);

            foreach (LogCmd cmd in log_handler.recoverLogCmds()) {
                 receiver.handleCommand(cmd.cmd, cmd.cmddata);
            }
        }