DIRECTORY BasicTime USING [GMT, nullGMT], FS USING [nullOpenFile, OpenFile], IO USING [STREAM], Rope USING [ROPE], WalnutDefs USING [CheckReportProc, WalnutOpsHandle], WalnutKernelDefs USING [WhichTempLog]; WalnutRoot: CEDAR DEFINITIONS = BEGIN GMT: TYPE = BasicTime.GMT; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; TransactionHandle: TYPE = REF; AlpTHandle: TYPE = TransactionHandle; WhichTempLog: TYPE = WalnutKernelDefs.WhichTempLog; WalnutOpsHandle: TYPE = WalnutDefs.WalnutOpsHandle; CheckReportProc: TYPE = WalnutDefs.CheckReportProc; TransInfo: TYPE = REF; nullTransInfo: TransInfo = NIL; RootHandle: TYPE = REF RootHandleRec; RootHandleRec: PUBLIC TYPE = RECORD [ -- clients are to consider this readOnly baseName: ROPE ¬ NIL, -- full name through directories createDate: GMT ¬ BasicTime.nullGMT, expungeInProgress: BOOL ¬ FALSE, transInfo: TransInfo ¬ nullTransInfo, alpTH: AlpTHandle ¬ NIL, -- current transaction dbTransH: TransactionHandle ¬ NIL, -- form needed by cypress rootOpenFileForLogs: FS.OpenFile ¬ FS.nullOpenFile, currentLog: InternalLogInfo ¬ NIL, -- only one log for now expungeLog: InternalLogInfo ¬ NIL, newMailLog: MiscLogInfo ¬ NIL, readArchiveLog: MiscLogInfo ¬ NIL, statsProc: CheckReportProc ]; TransID: TYPE = REF; InternalLogInfo: TYPE = REF InternalLogInfoObject; InternalLogInfoObject: TYPE = RECORD [ readStream: STREAM, -- not used for expungeLog writeStream: STREAM, name: ROPE ¬ NIL, -- full path name of this log (minus version) shortName: ROPE ¬ NIL, -- short name without server, etc internalFileID: INT ¬ -1, logSeqNo: INT ¬ -1, logSeqNoPos: INT ¬ -1 -- position in rootLog of logSeqNo ]; MiscLogInfo: TYPE = REF MiscLogInfoRec; MiscLogInfoRec: TYPE = RECORD [ stream: STREAM, name: ROPE ¬ NIL, trans: AlpTHandle ¬ NIL, rootOpenFile: FS.OpenFile ¬ FS.nullOpenFile -- may have its own transaction ]; Open: PROC[opsH: WalnutOpsHandle, newSegmentOk: BOOL ¬ FALSE, masquerade: BOOL ¬ FALSE, newHandle: BOOL ¬ FALSE] RETURNS[ok: BOOL]; Shutdown: PROC[opsH: WalnutOpsHandle]; GetOpsHandleList: PROC RETURNS[LIST OF WalnutOpsHandle]; ExamineHandleList: PROC[proc: PROC[ohL: LIST OF WalnutOpsHandle] RETURNS[LIST OF WalnutOpsHandle] ]; StartTransaction: PROC[opsH: WalnutOpsHandle, openDB: BOOL ¬ TRUE] RETURNS[schemaInvalid: BOOL]; CloseTransaction: PROC[opsH: WalnutOpsHandle]; CommitAndContinue: PROC[opsH: WalnutOpsHandle]; AbortTransaction: PROC[opsH: WalnutOpsHandle]; FlushMailStream: PROC[opsH: WalnutOpsHandle]; EraseDB: PROC[opsH: WalnutOpsHandle]; AcquireWriteLock: PROC[opsH: WalnutOpsHandle]; OpenLogStreams: PROC[opsH: WalnutOpsHandle]; ReleaseWriteLock: PROC[opsH: WalnutOpsHandle]; CloseLogStreams: PROC[opsH: WalnutOpsHandle]; GetQuota: PROC[opsH: WalnutOpsHandle] RETURNS[spaceInUse, quota: INT]; GetStreamsForExpunge: PROC[opsH: WalnutOpsHandle, starting: BOOL, pagesWanted: INT]; SwapLogs: PROC[opsH: WalnutOpsHandle, expungeFileID: INT, newRootStamp: GMT] RETURNS[newLogLen: INT]; StopExpunge: PROC[opsH: WalnutOpsHandle]; PrepareToCopyTempLog: PROC[opsH: WalnutOpsHandle, which: WhichTempLog, pagesAlreadyCopied: INT, reportProc: WalnutDefs.CheckReportProc] RETURNS[ok: BOOL]; GetStreamsForCopy: PROC[opsH: WalnutOpsHandle, which: WhichTempLog] RETURNS[tempStream: STREAM]; FinishCopy: PROC[opsH: WalnutOpsHandle, which: WhichTempLog]; AbortTempCopy: PROC[opsH: WalnutOpsHandle, which: WhichTempLog]; GetNewMailStream: PROC[opsH: WalnutOpsHandle, lengthRequired: INT, pagesWanted: INT ¬ 200] RETURNS[ok: BOOL, actualLen: INT]; ReturnNewMailStream: PROC[opsH: WalnutOpsHandle]; GetReadArchiveStream: PROC[opsH: WalnutOpsHandle, pagesWanted: INT ¬ -1] RETURNS[STREAM]; ReturnReadArchiveStream: PROC[opsH: WalnutOpsHandle]; RegisterStatsProc: PROC[opsH: WalnutOpsHandle, proc: CheckReportProc]; UnregisterStatsProc: PROC[opsH: WalnutOpsHandle, proc: CheckReportProc]; StatsReport: CheckReportProc; END. Τ WalnutRoot.Mesa Copyright Σ 1985, 1987, 1988, 1992 by Xerox Corporation. All rights reserved. Willie-Sue, August 9, 1988 12:55:44 pm PDT Doug Terry, August 28, 1990 4:15:33 pm PDT Contents: types and procedures, take the root file as en explicit parameter Parses the root file and sets up the Log objects; dispenses the various streams and values parsed from the rootFile Types Root file Information opens wH.rootName as the current root file; finds out the name of the various logs, and who may retrieve mail into this database (one user only). if newHandle then opsH will be added to the list of handles, assuming no duplicate names or segment names or segment ids. Shutdown the connection to the root. Must do an Open after this. WalnutRoot is the keeper of the list of WalnutOpsHandles, but the higher level decides what goes on the list - WalnutRoot needs to be able to look at the list used if the caller may want to change the list Transaction Management WalnutRoot does all of the transaction management in Walnut. It will set up the necessary coordinator and worker transactions to handle logs and databases stored on different machines (although currently this is not the generally accepted method of usage!). Start a transaction to handle the logs and the database -- this may be either the coordinator transaction, if everything is on the same machine, or a new worker transaction if not. In the case of doing an EraseDB, we must not start a transaction on the database at this time To allow closing of the currentLog streams and database file when there is no activity Commits and continues the current transaction Aborts the DBCache and aborts the transaction WalnutRoot handles all the transactions for the streams it gives out Erases the database segment Managing the CurrentLog upgrades the lock on the lastLog to write Closes the log streams and re-opens, to release the write lock; is careful to use the same transaction as before, so the database is not affected closes any open streams; does a commitAndContinue of the transaction; may raise WalnutDefs.Error Managing the ExpungeLog to decide if there is enough space to write the expunge log, before really starting all the necessary information is returned within RootHandle Swaps the current log and expunge log so that they are interchanged and rewrites the time stamps in the root file for the logs Used if there was an error during GetExpungeLog; closes the log being expunged Managing the TempLogs makes sure there is enough space to copy the WhichTempLog onto lastLog; returns FALSE if there is not enough space used during restart, when a copy was in progress; the same trans is used for both the currentStream and the tempStream sets the pagecount of the tempLog to something reasonable and closes the tempStream returns tempLog if the copy of a temp log was not successful Access to streams for the various logs the newMailStream must be at least lenExpected bytes long (it is truncated to that length if longer); if the number of pages in the file not equal to sizeWanted, then page count is changed; is sizeWanted = -1, the pageCount is not changed called when finished getting newMail from grapevine If pagesWanted is -1 then don't change the length Utilities Κ»•NewlineDelimiter –(cedarcode) style™codešΟn™Kšœ ΟeœC™NK™*K™*K™KšœL™LK™sK™—K˜šΟk ˜ Kšœ ŸœŸœ ˜KšŸœŸœ˜"KšŸœŸœŸœ˜KšœŸœŸœ˜Kšœ Ÿœ$˜4KšœŸœ˜&K˜—Kš œŸœŸ œŸ˜%K™šΟb™KšŸœŸœ Ÿœ˜KšŸœŸœŸœ˜KšŸœŸœŸœŸœ˜KšœŸœŸœ˜Kšœ Ÿœ˜%K˜KšœŸœ!˜3KšœŸœ˜3KšœŸœ˜3K˜Kšœ ŸœŸœ˜KšœŸœ˜K˜Kšœ ŸœŸœ˜%šœŸœŸœŸœΟc(˜NKšœ ŸœŸœ‘ ˜6Kšœ Ÿœ˜$KšœŸœŸœ˜ K˜K˜%KšœŸœ‘˜1KšœŸœ‘˜=KšœŸœ Ÿœ˜3K˜KšœŸœ‘˜