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); } }
// special "init" of a region private void _InitNewRegion(IRegionManager regionmgr, out int system_reserved_space) { // test to see if there is already a root record there { try { Stream testrootblockstream = regionmgr.readRegionAddr(0).getNewAccessStream(); RootBlockHeader nroot = Util.readStruct<RootBlockHeader>(testrootblockstream); long rtblksz = testrootblockstream.Position; if (nroot.IsValid()) { // TODO: we should be careful not to overwrite an existing root record... // throw new Exception("existing root record present! Can't re-init."); } testrootblockstream.Close(); } catch (RegionExposedFiles.RegionMissingException) { } } // (1) initialize the log segments... RootBlockLogSegment[] log_segments = new RootBlockLogSegment[LogWriter.DEFAULT_LOG_SEGMENTS]; uint nextFreeAddress = RootBlockHeader.ROOTBLOCK_SIZE; for (int i=0;i<log_segments.Length;i++) { // calculate the segment start and length log_segments[i].logsegment_size = LogWriter.DEFAULT_LOG_SEGMENT_SIZE; log_segments[i].logsegment_start = nextFreeAddress; nextFreeAddress += LogWriter.DEFAULT_LOG_SEGMENT_SIZE; // open the segment Stream logstream = regionmgr.writeFreshRegionAddr(log_segments[i].logsegment_start, log_segments[i].logsegment_size).getNewAccessStream(); // write to the end of the log to be sure the file/stream has enough space logstream.Seek(log_segments[i].logsegment_size - 1, SeekOrigin.Begin); logstream.WriteByte(0x00); logstream.Flush(); logstream.Seek(0, SeekOrigin.Begin); LogSegmentsHandler.InitLogSegmentStream(logstream); // write the initial "log-end" record at the beginning of the segment logstream.Close(); } root.magic = RootBlockHeader.ROOTMAGIC; root.root_checksum = 0; byte[] root_block_data = root.constructRootBlock(log_segments); // open the streams... Stream rootblockwritestream = regionmgr.writeFreshRegionAddr(0, (long)RootBlockHeader.ROOTBLOCK_SIZE).getNewAccessStream(); // this.logstream = logwritestream; this.rootblockstream = rootblockwritestream; // now write the root record rootblockstream.Seek(0, SeekOrigin.Begin); rootblockstream.Write(root_block_data,0,root_block_data.Length); rootblockstream.Flush(); rootblockstream.Close(); // must close the stream so resume can operate system_reserved_space = (int)nextFreeAddress; }