-- Log.mesa -- Last edited by -- MBrown on January 30, 1984 10:10:04 am PST -- Taft on 16-Feb-82 18:29:44 DIRECTORY AlpineEnvironment, AlpineInternal, Basics; Log: DEFINITIONS = BEGIN TransID: TYPE = AlpineEnvironment.TransID; Comparison: TYPE = Basics.Comparison; RecordType: TYPE = AlpineInternal.LogRecordType; -- A tag of type RecordType is associated with each log record as it is written. This is --used to identify the recovery procedure responsible for the record. RecordID: TYPE = AlpineInternal.LogRecordID; -- Uniquely identifies a record within a log. The 48 bit address space allows for --several hundred years of log writing. nullRecordID: RecordID = AlpineInternal.nullLogRecordID; -- No log record is identified by this value. Compare: PROC [a, b: RecordID] RETURNS [Comparison]; -- The record with the smaller RecordID was written earlier in time. -- An inline version of Log.Compare is LogInline.Compare. firstRecordID: RecordID = AlpineInternal.firstRecordID; -- for all r, Compare[firstRecordID, r] # greater lastRecordID: RecordID = AlpineInternal.lastRecordID; -- for all r, Compare[lastRecordID, r] # less Block: TYPE = RECORD [ base: LONG POINTER, length: CARDINAL, rest: BlockPtr ← NIL ]; BlockPtr: TYPE = LONG POINTER TO Block; nullBlock: Block = [base: NIL, length: 0, rest: NIL]; -- Essentially a list of descriptor for array of word. -- Used both for gather writing (e.g. system puts a header onto each log record) --and for scatter reading (e.g. pages that are written contiguously in the log may --be buffered in discontiguous virtual memory.) minBlockLen: INT = 1; maxBlockLen: INT = LAST[CARDINAL] - 512; -- an underestimate of the true upper bound; no reasonable application should approach this. RecoveryProc: TYPE = PROC [ record: RecordID, type: RecordType, trans: AlpineInternal.TransHandle, outcome: TransState]; -- A recovery proc should call ReadForRecovery, not Read, to access the log --record whose ID is passed to it. Attempting to read any other log record --with ReadForRecovery will result in an error. TransState: TYPE = AlpineInternal.TransState; -- {committed, aborted, ready} RegisterRecoveryProc: PROC [recordType: RecordType, recoveryProc: RecoveryProc]; -- Any program that writes log records of a particular type is responsible for recovery --of those records. As part of its PROGRAM proc (called by STARTing the module), --the program should call RegisterRecoveryProc once for each type of record it --writes. It is an error to call RegisterRecoveryProc after the update pass of recovery --begins. ReadForRecovery: ReadProc; -- Should be called only from a RecoveryProc, as explained above. -- See below for definition of type ReadProc. -- Note: Perform recovery before calling any of the procedures below. -- Log writing Write: PROC [ trans: AlpineInternal.TransHandle, recordType: RecordType, recordData: Block, force: BOOL ← FALSE] RETURNS [thisRecord, followingRecord: RecordID]; -- ! WriteFailed (online log is full - server should restart). CoordinatorWrite: PROC [ trans: AlpineInternal.CoordinatorHandle, recordType: RecordType, recordData: Block, force: BOOL ← FALSE] RETURNS [thisRecord, followingRecord: RecordID]; -- ! WriteFailed (online log is full - server should restart). WriteFailed: ERROR; Force: PROC [followingRecord: RecordID]; -- Force all records prior to (not including) followingRecord to be recorded --stably in the online log. -- Log reading ReadProc: TYPE = PROC [thisRecord: RecordID, wordsToSkip: CARDINAL ← 0, to: Block] RETURNS [status: ReadProcStatus, wordsRead: CARDINAL]; ReadProcStatus: TYPE = {normal, destinationFull, sourceExhausted}; -- normal means destinationFull and sourceExhausted (normal termination for reading --a fixed-length log record). Read: ReadProc; -- Extracts all or part of the contents of a log record whose type and transaction are --known, placing it in "to". Should be called during normal operation of the server --to carry out intentions. END. CHANGE LOG Created by MBrown on 2-Dec-81 Changed by MBrown on 16-Dec-81 15:06:20 -- Initialize takes a File.Capability, not the name of a server. Changed by MBrown on 1-Feb-82 15:10:32 -- 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. Changed by MBrown on 2-Feb-82 11:09:06 -- Add workerComplete to RecordType enumeration. Changed by MBrown on June 23, 1982 4:16 pm -- Use AlpineEnvironment.FileID, not File.Capability; introduce Error and LogFailure. Changed by MBrown on September 14, 1982 12:34 pm -- Move "Initialization and recovery" section to LogBasic. Changed by MBrown on September 15, 1982 8:39 pm -- Added RegisterRecoveryProc, merged various forms of invalidRecordID, eliminated Release --(still in LogBasic). Changed by MBrown on October 2, 1982 8:25 pm -- Moved Format and Recover to LogControl. next ← NIL in Log.Block. Changed by MBrown on October 3, 1982 10:42 pm -- Error -> LogFull (all other errors are really caller programming errors). --recordExhausted: BOOL -> status: ReadProcStatus. Changed by MBrown on October 7, 1982 5:09 pm -- ReadForRecovery introduced, and the readProc parm to RecoveryProc dropped. Changed by MBrown on October 11, 1982 3:21 pm -- Added largestRecordID. Changed by MBrown on November 3, 1982 11:59 am -- Changed trans arg to Write from TransID to TransHandle; added CoordinatorWrite. Changed by MBrown on January 30, 1984 10:10:13 am PST -- Changed Environment -> Basics for Cedar 5.0.