-- File: DBFileAlpineImpl.mesa -- Last edited by: -- MBrown on June 7, 1983 4:40 pm -- Kolling on May 12, 1983 3:35 pm -- Cattell, July 11, 1983 12:02 pm DIRECTORY AlpineEnvironment USING[bytesPerPage, Conversation, OpenFileID, Outcome, PageCount, PageNumber, TransID, UniversalFile, wordsPerPage], AlpFile USING[GetSize, Handle, Open, ReadPages, SetSize, WritePages, WriteProperties], AlpineInterimDirectory USING[Error, Open], AlpInstance USING[AccessFailed, Create, Failed, Handle, Unknown], AlpTransaction USING[Create, Handle, Finish, OperationFailed], DBEnvironment USING[Aborted, Failure, Error], DBCommon USING[VersionOptions], DBFileAlpine, DBStats USING[Starting, Stopping], FileIO USING[CreateOptions], RPC USING[CallFailed], Rope USING[ROPE, Text]; DBFileAlpineImpl: PROGRAM IMPORTS AlpF: AlpFile, AlpineInterimDirectory, AlpI: AlpInstance, AlpT: AlpTransaction, DBEnvironment, DBStats, RPC EXPORTS DBFileAlpine = BEGIN OPEN AE: AlpineEnvironment; ROPE: TYPE = Rope.ROPE; VersionOptions: TYPE = DBCommon.VersionOptions; bytesPerPage: INT = AE.bytesPerPage; Conversation: TYPE = AE.Conversation; OpenFileID: TYPE = AE.OpenFileID; PageCount: TYPE = AE.PageCount; PageNumber: TYPE = AE.PageNumber; TransID: TYPE = AE.TransID; AlpineTrans: TYPE = REF ANY; -- must narrow to AlpTransaction.Handle AlpineOpenFileHandle: TYPE = REF ANY; -- must narrow to AlpFile.Handle CreateTransaction: PUBLIC PROC [server: ROPE] RETURNS [t: AlpineTrans] = { needRetry: BOOL _ FALSE; haveRetried: BOOL _ FALSE; transHandle: AlpT.Handle; DBStats.Starting[AlpineFileCreateTransaction]; DO instance: AlpI.Handle _ AlpI.Create[fileStore: server ! AlpI.Failed => ERROR DBEnvironment.Failure[IF why = authenticateFailed THEN $authentication ELSE $communication, server] ]; transHandle _ AlpT.Create[instance ! AlpT.OperationFailed => IF why = busy THEN ERROR DBEnvironment.Failure[ $serverBusy, server]; RPC.CallFailed => IF why = unbound THEN needRetry _ TRUE -- a moderately likely failure, due to the instance cache ELSE IF why IN [timeout .. busy] THEN ERROR DBEnvironment.Failure[ $communication, server] ]; IF NOT needRetry THEN EXIT; IF haveRetried THEN ERROR DBEnvironment.Failure[ $communication, transHandle.inst.fileStore]; needRetry _ FALSE; haveRetried _ TRUE; ENDLOOP; DBStats.Stopping[AlpineFileCreateTransaction]; RETURN[transHandle] }; FinishTransaction: PUBLIC PROC [t: AlpineTrans, abort: BOOL, continue: BOOL] = { outcome: AE.Outcome; transHandle: AlpT.Handle = NARROW[t]; DBStats.Starting[AlpineFileFinishTransaction]; outcome _ transHandle.Finish[ requestedOutcome: IF abort THEN abort ELSE commit, continue: continue ! RPC.CallFailed => IF why IN [timeout .. busy] THEN ERROR DBEnvironment.Failure[$communication, transHandle.inst.fileStore] ]; IF NOT abort AND outcome = abort THEN ERROR DBEnvironment.Aborted[t]; DBStats.Stopping[AlpineFileFinishTransaction]; }; CreateOptionsFromVersionOptions: ARRAY VersionOptions OF FileIO.CreateOptions = [NewFileOnly: newOnly, OldFileOnly: oldOnly, None: none]; OpenFile: PUBLIC PROC [t: AlpineTrans, file: Rope.Text, version: VersionOptions, discardFileContents: BOOL, nPagesInitial: INT, readOnly: BOOL, noLog: BOOL] RETURNS [f: AlpineOpenFileHandle, createdFile: BOOL] = { ENABLE AlpI.Unknown => SELECT what FROM transID, openFileID => ERROR DBEnvironment.Aborted[t]; ENDCASE => REJECT; transHandle: AlpT.Handle = NARROW[t]; fileHandle: AlpF.Handle; refUniversalFile: REF AE.UniversalFile _ NIL; needRetry: BOOL _ FALSE; haveRetried: BOOL _ FALSE; DBStats.Starting[AlpineFileOpen]; DO [, refUniversalFile, createdFile] _ AlpineInterimDirectory.Open[ file, CreateOptionsFromVersionOptions[version], nPagesInitial*bytesPerPage ! AlpineInterimDirectory.Error => SELECT why FROM authenticateFailed => ERROR DBEnvironment.Failure[ $authentication, transHandle.inst.fileStore]; -- will change to Error[BadUserPassword] damaged, ownerRecordFull => REJECT; fileAlreadyExists => ERROR DBEnvironment.Error[AlreadyExists]; fileNotFound, ownerNotFound => ERROR DBEnvironment.Error[FileNotFound]; illegalFileName => ERROR DBEnvironment.Error[IllegalFileName]; insufficientPermission => ERROR DBEnvironment.Error[ProtectionViolation]; lockFailed, transAborted => needRetry _ TRUE; quota => ERROR DBEnvironment.Failure[ $quotaExceeded, transHandle.inst.fileStore]; remoteCallFailed, regServersUnavailable, serverNotFound => ERROR DBEnvironment.Failure[$communication, transHandle.inst.fileStore]; serverBusy => ERROR DBEnvironment.Failure[ $serverBusy, transHandle.inst.fileStore]; ENDCASE => REJECT]; -- DirectoryInconsistent {ownerRootFileNotFound} IF NOT needRetry THEN EXIT; IF haveRetried THEN ERROR DBEnvironment.Failure[ $lockConflict, transHandle.inst.fileStore]; needRetry _ FALSE; haveRetried _ TRUE; ENDLOOP; { ENABLE BEGIN AlpI.Unknown => SELECT what FROM transID, openFileID => ERROR DBEnvironment.Aborted[t]; ENDCASE => REJECT; RPC.CallFailed => IF why IN [timeout .. busy] THEN ERROR DBEnvironment.Failure[ $communications, transHandle.inst.fileStore]; END; fileHandle _ AlpF.Open[ transHandle: transHandle, universalFile: refUniversalFile^, access: IF readOnly THEN readOnly ELSE readWrite, lock: [$write, $wait], recoveryOption: IF noLog THEN $noLog ELSE $log, referencePattern: $random ! AlpI.AccessFailed => DBEnvironment.Error[ProtectionViolation] ].handle; IF NOT createdFile AND discardFileContents THEN fileHandle.WriteProperties[properties: LIST[[highWaterMark[highWaterMark: 0]]]]; }; DBStats.Stopping[AlpineFileOpen]; RETURN [fileHandle, createdFile]; }; ReadFilePage: PUBLIC PROC [ f: AlpineOpenFileHandle, p: CARDINAL, corePage: LONG POINTER] = { fileHandle: AlpF.Handle = NARROW[f]; DBStats.Starting[AlpineFileReadPage]; { ENABLE BEGIN AlpI.Unknown => SELECT what FROM transID, openFileID => ERROR DBEnvironment.Aborted[fileHandle.trans]; ENDCASE => REJECT; RPC.CallFailed => IF why IN [timeout .. busy] THEN ERROR DBEnvironment.Failure[ $communications, fileHandle.trans.inst.fileStore]; END; fileHandle.ReadPages[ pageRun: [firstPage: p], pageBuffer: DESCRIPTOR [corePage, AE.wordsPerPage]]; }; DBStats.Stopping[AlpineFileReadPage]; }; WriteFilePage: PUBLIC PROC [ f: AlpineOpenFileHandle, p: CARDINAL, corePage: LONG POINTER] = { fileHandle: AlpF.Handle = NARROW[f]; DBStats.Starting[AlpineFileWritePage]; { ENABLE BEGIN AlpI.Unknown => SELECT what FROM transID, openFileID => ERROR DBEnvironment.Aborted[fileHandle.trans]; ENDCASE => REJECT; RPC.CallFailed => IF why IN [timeout .. busy] THEN ERROR DBEnvironment.Failure[ $communications, fileHandle.trans.inst.fileStore]; END; fileHandle.WritePages[ pageRun: [firstPage: p], pageBuffer: DESCRIPTOR [corePage, AE.wordsPerPage]]; }; DBStats.Stopping[AlpineFileWritePage]; }; GetSize: PUBLIC PROC [f: AlpineOpenFileHandle] RETURNS [nPages: CARDINAL] = { size: INT; fileHandle: AlpF.Handle = NARROW[f]; DBStats.Starting[AlpineFileGetSize]; { ENABLE BEGIN AlpI.Unknown => SELECT what FROM transID, openFileID => ERROR DBEnvironment.Aborted[fileHandle.trans]; ENDCASE => REJECT; RPC.CallFailed => IF why IN [timeout .. busy] THEN ERROR DBEnvironment.Failure[ $communications, fileHandle.trans.inst.fileStore]; END; size _ fileHandle.GetSize[]; }; DBStats.Stopping[AlpineFileGetSize]; RETURN [size]; }; SetSize: PUBLIC PROC [f: AlpineOpenFileHandle, nPages: CARDINAL] = { fileHandle: AlpF.Handle = NARROW[f]; DBStats.Starting[AlpineFileSetSize]; { ENABLE BEGIN AlpI.Unknown => SELECT what FROM transID, openFileID => ERROR DBEnvironment.Aborted[fileHandle.trans]; ENDCASE => REJECT; RPC.CallFailed => IF why IN [timeout .. busy] THEN ERROR DBEnvironment.Failure[ $communications, fileHandle.trans.inst.fileStore]; END; fileHandle.SetSize[size: nPages]; fileHandle.WriteProperties[properties: LIST[[byteLength[byteLength: nPages*bytesPerPage]]]]; }; DBStats.Stopping[AlpineFileSetSize]; }; END. ÊK˜JšÏc œÏk œžœžœlžœ&žœKžœDžœ/žœ7žœ(žœžœžœžœžœ Ðblœžœžœnžœžœžœžœžœžœžœžœžœ,žœžœžœžœžœžœžœžœžœžœžœžœžœžœžœ(œžœžœžœ!œÏnœžœžœ žœžœ%žœžœžœžœWžœVžœžœ$žœžœožœ žœžœ@žœžœžœ žœOžœžœžœžœžœMžœžœ žœžœžœ žœžœ_žœžœžœ9žœ œžœžœžœ žœžœ)žœržœžœžœ$žœžœžœžœ žœPžœžœžœžœžœ}žœžœ[ œžœžœUžœžœžœ žœžœ(žœ žœžœžœ žœ#žœžœ!žœ8žœžœžœžœžœžœžœ,žœÇžœžœ!žœ¡žœ!žœNžœAžœKžœ]žœžœ¢žœ\žœXžœžœ1œžœžœ žœžœžœ žœžœ^žœžœžœž œžœžœ!žœ$žœžœ žœžœžœžœžœVžœxžœ žœ žœAžœžœžœ…žœžœ žœžœ/žœXžœ&  œžœžœ#žœ žœžœ$žœ5žœžœžœžœ"žœ4žœžœ žœžœžœžœžœ]žœKž œ žœN  œžœžœ#žœ žœžœ$žœ6žœžœžœžœ"žœ4žœžœ žœžœžœžœžœ]žœLž œ žœO œžœžœžœ žœžœ žœ4žœžœžœžœ"žœ4žœžœ žœžœžœžœžœ]žœ[žœ œžœžœ#žœ$žœ4žœžœžœžœ"žœ4žœžœ žœžœžœžœžœ]žœWžœnžœ˜øF—…—#z'Ë