DIRECTORY Basics, Camelot, ConstArith, PBasics, YggEnvironment, YggLog, YggLogRep; YggLogBasic: CEDAR DEFINITIONS IMPORTS ConstArith = BEGIN PageNumber: TYPE = YggEnvironment.PageNumber; PageCount: TYPE = YggEnvironment.PageNumber; Block: TYPE = YggLog.Block; RecordID: TYPE = YggLog.RecordID; WordNumber: TYPE = YggEnvironment.WordNumber; WordCount: TYPE = YggEnvironment.WordCount; EstablishLogFile: PROC []; LogFileSize: PROC [] RETURNS [PageCount]; LogUsage: PROC [] RETURNS [PageCount]; LocateFirstRecord: PROC [] RETURNS [WordNumber]; OpenRecordStreamFromWord: PROC [firstWord: WordNumber] RETURNS [notStartOfRecord: BOOL, currentRecord: RecordID]; OpenRecordStreamFromCheckpoint: PROC [ checkpointWord: WordNumber, checkpointRecord, firstRecord: RecordID] RETURNS [notStartOfRecord: BOOL, currentRecord: RecordID]; InvalidPage: ERROR; CheckCurrentRecord: PROC [] RETURNS [truncated: BOOL]; GetCurrentRecord: UNSAFE PROC [currentRecord: RecordID, to: Block] RETURNS [status: YggLog.ReadProcStatus, wordsRead: CARDINAL]; GetCurrentPageAndVersion: PROC [] RETURNS [PageNumber, YggLogRep.PageVersion]; AdvanceRecordStream: PROC [] RETURNS [endOfLog, truncatedRecord: BOOL, currentRecord: RecordID]; CloseRecordStream: PROC []; OpenForPut: PROC [nextPage: PageNumber, version: YggLogRep.PageVersion, nextRecord: RecordID]; AssertNormalOperation: PROC []; Put: UNSAFE PROC [from: YggLog.Block, optr: Camelot.optrT, force: BOOL _ FALSE, writeID: BOOL _ FALSE] RETURNS [thisRecord, followingRecord: RecordID, thisWordNumber: YggEnvironment.WordNumber]; minBlockLen: INT = 1; maxBlockLen: INT = 1060000; -- a megaword plus change WordNumberFromRecordID: PROC [thisRecord: RecordID] RETURNS [WordNumber]; Force: PROC [followingRecord: RecordID]; RecordIDOfNextPut: PROC [] RETURNS [RecordID]; CloseForPut: PROC []; maxInvalidLogPages: PageCount = 16; Release: PROC [beforeRecord: RecordID]; Get: UNSAFE PROC [thisRecord: RecordID, to: YggLog.Block] RETURNS [status: YggLog.ReadProcStatus, wordsRead: CARDINAL]; Compare: PROC [a, b: WordCount] RETURNS [Basics.Comparison] = TRUSTED INLINE { comp: PBasics.Comparison; comp _ ConstArith.Compare[a, b]; SELECT comp FROM less => RETURN[less]; equal => RETURN[equal]; greater => RETURN[greater]; ENDCASE => ERROR; }; END. CHANGE LOG Created by MBrown on 2-Dec-81 Changed by MBrown on 16-Dec-81 15:06:20 Changed by MBrown on 1-Feb-82 15:10:32 Changed by MBrown on August 10, 1982 11:26 pm Changed by MBrown on August 16, 1982 3:29 pm Changed by MBrown on September 16, 1982 12:42 pm Changed by MBrown on September 23, 1982 1:52 pm Changed by MBrown on June 27, 1983 9:48 am šYggLogBasic.mesa Copyright Σ 1987, 1989 by Xerox Corporation. All rights reserved. Bob Hagmann May 23, 1989 9:32:10 am PDT The LogBasic interface is lower-level than the YggLog interface. The YggLog interface "knows" about transactions, while YggLogBasic does not. The YggLogBasic interface therefore allows logging an event that is not associated with a single transaction (e.g. a log checkpoint). Data types This represents a difference of two WordNumbers, the length of an online log file, etc. Initialization. Must be called before any of the procs below. The total space available for the log. The space actually used by the log at the time of the call. Reads the log file determined by EstablishLogFile. Returns the WordNumber of a record near the start of the log. The intended use of this proc is in recovery from the loss of the restart file. This proc takes a long time, but is seldom used. Sequential reading. There is a single stream for reading the log. This stream is used only during recovery. There is no monitor protection, so the client is responsible for serializing stream calls. Sequential reading of the log is more primitive than random access. It knows how to deal gracefully with the raggedness that defines the end of log. It can be performed even if the logical addressing structure of the log has not been established (as on the first step of recovery.) ! InvalidPage Creates a stream using physical log addressing. RecordIDs returned by Advance will be based on the assumption that the RecordID of record found at firstWord is firstWord. ! InvalidPage Creates a stream using logical log addressing. The logical-physical correspondence is defined by checkpointWord and checkpointRecord. firstRecord must be less than checkpointRecord. OpenRecordStreamFromXXX was pointed to a page with random garbage in it. After this error, the caller should CloseRecordStream[] immediately. ! YggLog.Error{ invalidRecordID, invalidRecord } This proc may be called before calling GetCurrentRecord, in order to detect errors that would otherwise be raised by the GetCurrentRecord call. This proc has the same type as Get below. This call does not change the state of the stream. ! (none) A somewhat peculiar operation, provided for purposes of recovery. ! (none) Positions to next log record, returns its ID. If endOfLog, then "currentRecord" is past the end of log. If truncatedRecord, then the record before "currentRecord" was incomplete. There is no guarantee that "currentRecord" exists in its entirety, only that some prefix exists. Shuts down the stream. Must be called before opening the stream again. Writing. There is a single output stream, created by the call to OpenForPut. The stream is protected by monitors so it is ok for several processes to call Put without other synchronization. (Note that OpenForPut is done implicitly by EraseLogFile.) No non-fatal errors are possible in the basic log writing primitives. An attempt to write when the online log is (nearly) full causes a wait; another process must free some online log pages. Sets up the output stream for writing to file page nextPage, naming the first record that it writes there nextRecord. Uses YggLog.wordsPerPage (which must be initialized before calling this procedure). If normalOperation, then perform more stringent checking for log full. ! YggLog.Error {writeID, totalLen, logFull} Caller need not ensure that all pages of "from" are in main store; Put will touch each page before entering the log tail monitor. If writeID and a log record ID won't fit in the first block, Error[writeID]. If total lenth of write request is not IN [minBlockLen .. maxBlockLen], Error[totalLen]. Error[logFull] is a server crash; it does not release the log tail monitor or log core monitor. ! YggLog.Error {recordNonexistent, recordNotOnline} (thisRecord is not valid.) If thisRecord is represented in the online log, returns its location. Intended for use by the proc that writes checkpointComplete records. ! (none) Force all records prior to (not including) followingRecord to be recorded stably in the online log. ! (none) Returns the RecordID that would have been assigned if this call had been a Put. ! (none) Flushes all log buffers to disk, and returns log writing component to initial state. This many pages past end of log do not have well-defined values. On restart, these pages need to be reinitialized. Purging. ! YggLog.Error {recordNonexistent, recordNotOnline} (beforeRecord is not valid to release.) The caller certifies that all records prior to (not including) beforeRecord may be purged from the online log. Random reading. Intended to be used only for carrying out intentions, not during recovery. Extracts all or part of the contents of a log record. wordsRead is the number of words of log record touched by the Get call (bounded above by the total length of the block "to"). WordNumber utilities. Initialize takes a File.Capability, not the name of a server. Define interface that is decoupled from handles defined in other parts of Alpine. Change from stream to stateless style reading. Use 48 bit log record ids throughout. Move Put here from LogPrivate; define realistic Get. Added sequential reading back in, and simplified random reading correspondingly. Changes to make recovery implementable. Added WordNumberFromRecordID. Added AssertNormalOperation. Hauser, March 8, 1985 10:42:28 am PST Nodified, added copyright. Carl Hauser, October 4, 1985 1:28:14 pm PDT Change "Log" to "AlpineLog" Κ½˜šœ™IcodešœB™BK™'K™—Jšœ•™•˜šΟk ˜ J˜J˜J˜ J˜Jšœ˜Jšœ˜Jšœ ˜ J˜——šœ ˜Jšœ ˜J˜Jšœ˜—head™ Jšœ œ˜-Jšœ œ˜,Jšœœ˜Jšœ œ˜!Jšœ œ˜-šœ œ˜+JšœW™W——šœ™J˜šΟnœœ˜Jšœ-™-J˜—šž œœœ ˜)J™&—šžœœœ ˜&K™<—K˜šžœœœ˜0Jšœq™qJšœ™——šœ™Jšœ΄™΄J˜Jšœ›™›J˜šžœœ˜6Jšœœ˜:Jšœ ™ JšœV™VJšœT™TJ˜—šžœœ˜&J˜DJšœœ˜:Jšœ ™ JšœV™VJšœI™IJšœ™J˜—šœ œ˜JšœH™HJšœE™EJ˜—šžœœœ œ˜6Jšœ0™0JšœR™RJšœ<™