DIRECTORY AlpineEnvironment USING[bytesPerPage, Conversation, LockOption, OpenFileID, Outcome, PageCount, PageNumber, TransID, UniversalFile, wordsPerPage, PropertyValuePair], AlpFile USING[Close, GetSize, Handle, ReadPages, SetSize, PropertySet, WritePages, ReadProperties, WriteProperties, Unknown], AlpineDirectory USING[Error, OpenFile, CreateOptions], AlpInstance USING[AccessFailed, Create, Failed, Handle, Unknown], AlpTransaction USING[Create, Handle, Finish, OperationFailed], DB USING[Aborted, Failure, Error], DBCommon USING[VersionOptions], DBFileAlpine, DBStats USING[Starting, Stopping], RPC USING[CallFailed], Rope USING[ROPE, Text]; DBFileAlpineImpl: CEDAR PROGRAM IMPORTS AlpFile, AlpineDirectory, AlpInstance, AlpTransaction, DB, 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; AlpineOpenFileHandle: TYPE = REF ANY; CreateTransaction: PUBLIC PROC [server: ROPE] RETURNS [t: AlpineTrans] = { needRetry: BOOL _ FALSE; haveRetried: BOOL _ FALSE; transHandle: AlpTransaction.Handle; DBStats.Starting[AlpineFileCreateTransaction]; DO instance: AlpInstance.Handle _ AlpInstance.Create[fileStore: server ! AlpInstance.Failed => IF why = authenticateFailed THEN ERROR DB.Error[BadUserPassword] ELSE ERROR DB.Failure[$communication, server] ]; transHandle _ AlpTransaction.Create[instance ! AlpTransaction.OperationFailed => IF why = busy THEN ERROR DB.Failure[$serverBusy, server]; RPC.CallFailed => TRUSTED { IF why = unbound THEN {needRetry _ TRUE; CONTINUE} ELSE IF why IN [timeout .. busy] THEN ERROR DB.Failure[$communication, server]} ]; IF NOT needRetry THEN EXIT; IF haveRetried THEN ERROR DB.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: AlpTransaction.Handle = NARROW[t]; DBStats.Starting[AlpineFileFinishTransaction]; outcome _ transHandle.Finish[ requestedOutcome: IF abort THEN abort ELSE commit, continue: continue ! RPC.CallFailed => TRUSTED { IF why IN [timeout .. busy] THEN IF abort THEN {outcome _ abort; CONTINUE} -- so can escape when no communication! ELSE ERROR DB.Failure[$communication, transHandle.inst.fileStore]} ]; DBStats.Stopping[AlpineFileFinishTransaction]; IF NOT abort AND outcome = abort THEN ERROR DB.Aborted; }; CreateOptionsFromVersionOptions: ARRAY VersionOptions OF AlpineDirectory.CreateOptions = [NewFileOnly: newOnly, OldFileOnly: oldOnly, None: none]; VersionNumberFromOpenFile: PUBLIC PROC [f: AlpineOpenFileHandle] RETURNS [versionNumber: INT] = { fileHandle: AlpFile.Handle = NARROW[f]; BEGIN ENABLE BEGIN AlpInstance.Unknown => SELECT what FROM transID, openFileID => ERROR DB.Aborted; ENDCASE => REJECT; RPC.CallFailed => TRUSTED { IF why IN [timeout .. busy] THEN ERROR DB.Failure[$communications, fileHandle.trans.inst.fileStore]}; END; versionList: LIST OF AlpineEnvironment.PropertyValuePair; versionProp: AlpFile.PropertySet; IF fileHandle = NIL THEN RETURN[versionNumber: 0]; versionProp[version] _ TRUE; versionList _ fileHandle.ReadProperties[versionProp]; versionNumber _ NARROW[versionList.first, AlpineEnvironment.PropertyValuePair[version]].version; END; }; OpenFile: PUBLIC PROC [t: AlpineTrans, file: Rope.Text, version: VersionOptions, discardFileContents: BOOL, nPagesInitial: INT, lock: AlpineEnvironment.LockOption, readOnly: BOOL] RETURNS [f: AlpineOpenFileHandle, createdFile: BOOL] = { ENABLE AlpInstance.Unknown => SELECT what FROM transID, openFileID => ERROR DB.Aborted; ENDCASE => REJECT; transHandle: AlpTransaction.Handle = NARROW[t]; fileHandle: AlpFile.Handle; refUniversalFile: REF AE.UniversalFile _ NIL; DBStats.Starting[AlpineFileOpen]; TRUSTED BEGIN ENABLE { AlpineDirectory.Error => SELECT type FROM authenticateFailed => ERROR DB.Error[BadUserPassword]; damaged, ownerRecordFull => REJECT; fileAlreadyExists => ERROR DB.Error[AlreadyExists]; fileNotFound, ownerNotFound => ERROR DB.Error[FileNotFound]; illegalFileName => ERROR DB.Error[IllegalFileName]; insufficientPermission => ERROR DB.Error[ProtectionViolation]; lockFailed, transAborted => ERROR DB.Failure[$lockConflict, transHandle.inst.fileStore]; quota => ERROR DB.Error[QuotaExceeded]; remoteCallFailed, regServersUnavailable, serverNotFound => ERROR DB.Failure[$communication, transHandle.inst.fileStore]; serverBusy => ERROR DB.Failure[$serverBusy, transHandle.inst.fileStore]; ENDCASE => REJECT; -- DirectoryInconsistent {ownerRootFileNotFound} RPC.CallFailed => IF why IN [timeout .. busy] THEN ERROR DB.Failure[$communications, transHandle.inst.fileStore]; }; [fileHandle, createdFile, ] _ AlpineDirectory.OpenFile[trans: transHandle, name: file, access: IF readOnly THEN readOnly ELSE readWrite, lock: lock, recoveryOption: $log, createOptions: CreateOptionsFromVersionOptions[version], referencePattern: $random ! AlpInstance.AccessFailed => DB.Error[ProtectionViolation] ] END; IF NOT createdFile AND discardFileContents THEN fileHandle.WriteProperties[properties: LIST[[highWaterMark[highWaterMark: 0]]]]; DBStats.Stopping[AlpineFileOpen]; RETURN [fileHandle, createdFile]; }; Close: PUBLIC PROC [f: AlpineOpenFileHandle] ~ { fileHandle: AlpFile.Handle = NARROW[f]; AlpFile.Close[fileHandle ! AlpFile.Unknown => CONTINUE] }; ReadFilePage: PUBLIC PROC [f: AlpineOpenFileHandle, p: CARDINAL, corePage: LONG POINTER] = { fileHandle: AlpFile.Handle = NARROW[f]; DBStats.Starting[AlpineFileReadPage]; { ENABLE BEGIN AlpInstance.Unknown => SELECT what FROM transID, openFileID => ERROR DB.Aborted; ENDCASE => REJECT; RPC.CallFailed => TRUSTED { IF why IN [timeout .. busy] THEN ERROR DB.Failure[$communications, fileHandle.trans.inst.fileStore]}; END; TRUSTED { fileHandle.ReadPages[ pageRun: [firstPage: p], pageBuffer: DESCRIPTOR [corePage, AE.wordsPerPage]]; }; }; DBStats.Stopping[AlpineFileReadPage]; }; WriteFilePage: PUBLIC PROC [ f: AlpineOpenFileHandle, p: CARDINAL, corePage: LONG POINTER] = { fileHandle: AlpFile.Handle = NARROW[f]; DBStats.Starting[AlpineFileWritePage]; { ENABLE BEGIN AlpInstance.Unknown => SELECT what FROM transID, openFileID => TRUSTED {ERROR DB.Aborted}; ENDCASE => REJECT; RPC.CallFailed => TRUSTED {IF why IN [timeout .. busy] THEN ERROR DB.Failure[$communications, fileHandle.trans.inst.fileStore]}; END; TRUSTED { fileHandle.WritePages[ pageRun: [firstPage: p], pageBuffer: DESCRIPTOR [corePage, AE.wordsPerPage]]; }; }; DBStats.Stopping[AlpineFileWritePage]; }; GetSize: PUBLIC PROC [f: AlpineOpenFileHandle] RETURNS [nPages: CARDINAL] = { size: INT; fileHandle: AlpFile.Handle = NARROW[f]; DBStats.Starting[AlpineFileGetSize]; { ENABLE BEGIN AlpInstance.Unknown => SELECT what FROM transID, openFileID => ERROR DB.Aborted; ENDCASE => REJECT; RPC.CallFailed => TRUSTED { IF why IN [timeout .. busy] THEN ERROR DB.Failure[$communications, fileHandle.trans.inst.fileStore]}; END; size _ fileHandle.GetSize[]; }; DBStats.Stopping[AlpineFileGetSize]; RETURN [size]; }; SetSize: PUBLIC PROC [f: AlpineOpenFileHandle, nPages: CARDINAL] = { fileHandle: AlpFile.Handle = NARROW[f]; DBStats.Starting[AlpineFileSetSize]; { ENABLE BEGIN AlpInstance.Unknown => SELECT what FROM transID, openFileID => TRUSTED {ERROR DB.Aborted}; ENDCASE => REJECT; RPC.CallFailed => TRUSTED { IF why IN [timeout .. busy] THEN ERROR DB.Failure[$communications, fileHandle.trans.inst.fileStore]}; END; fileHandle.SetSize[size: nPages]; fileHandle.WriteProperties[properties: LIST[[byteLength[byteLength: nPages*bytesPerPage]]]]; }; DBStats.Stopping[AlpineFileSetSize]; }; END. Changed by wert on July 26, 1984 4:35:07 pm PDT Changed by wert on August 9, 1984 2:16:26 pm PDT Changed by Willie-Sue on February 15, 1985 Changed by Willie-Sue on April 25, 1985 άDBFileAlpineImpl.mesa - Alpine implementation of file level of Cypress Copyright c 1985 by Xerox Corporation. All rights reserved. MBrown on June 7, 1983 4:40 pm Kolling on May 12, 1983 3:35 pm Cattell on May 10, 1984 7:13:38 pm PDT Wert, August 9, 1984 2:18:42 pm PDT Willie-Sue, April 25, 1985 12:52:32 pm PST Russ Atkinson (RRA) March 20, 1985 9:35:05 pm PST Carl Hauser, May 14, 1985 1:50:01 pm PDT Widom, July 22, 1985 2:29:32 pm PDT Donahue, March 21, 1986 8:17:00 am PST must narrow to AlpTransaction.Handle must narrow to AlpFile.Handle a moderately likely failure, due to the instance cache added VersionNumberFromOpenFile[] hacked VersionNumberFromOpenFile[] to check for a NIL fileHandle made Cedar, added tioga formatting, took out VersionNumberFromOpenFile[]; added trans argument to DB.Failure put back in VersionNumberFromOpenFile[openFile] Carl Hauser, May 14, 1985 1:49:02 pm PDT changes to: DBFileAlpineImpl AlpineDirectory rather than AlpineInterimDirectory Κ ½˜codešΟnœ1™FKšœ Οmœ1™KšŸœŸœ˜"KšœŸœ˜K˜ KšœŸœ˜"KšŸ œ ˜šœŸœŸœ˜K˜———šœŸœŸ˜KšŸœ8Ÿœ Ÿ˜OK˜KšŸœ ˜K˜KšœŸœŸœŸœ˜#K˜KšŸœŸœŸœ˜KšœŸœ˜/KšœŸœŸœ˜$KšœŸœŸœ˜%Kšœ ŸœŸœ ˜!Kšœ ŸœŸœ ˜Kšœ ŸœŸœ ˜!Kšœ ŸœŸœ ˜K˜šœ ŸœŸœŸœ˜Kšœ$™$—šœŸœŸœŸœ˜%Kšœ™K˜—š œŸœŸœ ŸœŸœ˜KKšœ ŸœŸœ˜Kšœ ŸœŸœ˜K˜#K˜.šŸ˜˜[KšŸœŸœŸœ˜@KšŸœŸœ#˜-K˜—˜.šœ!Ÿœ Ÿ˜4KšŸœ!˜&—šŸœŸœ˜šŸœŸœŸœŸœ˜2Kšœ6™6—šŸœŸœŸœŸ˜%KšŸœ$˜)——K˜—KšŸœŸœ ŸœŸœ˜šŸœ Ÿ˜KšŸœ8˜=—Kšœ ŸœŸœ˜'KšŸœ˜—K˜.KšŸœ ˜K˜K˜—š œŸœŸœŸœ Ÿœ˜PKšœ Ÿœ ˜Kšœ%Ÿœ˜/K˜.˜KšœŸœŸœŸœ˜2šœŸœŸœ˜0šŸœŸœŸ˜ KšŸœŸœŸœΟc'˜QšŸœŸ˜ Kšœ7˜7———K˜—K˜.Kš ŸœŸœŸœŸœŸœ ˜7K˜K˜—˜ šŸœŸœ ˜7K˜9——K˜š œŸœŸœŸœŸœ˜aJšœŸœ˜'šŸ˜šœŸœŸ˜'JšœŸœ ˜(JšŸœŸœ˜—J˜šŸœŸœ˜šŸœŸœŸ˜ JšŸœ?˜D——JšŸœ˜—J˜Jšœ Ÿœ%˜9Jšœ Ÿ˜!JšŸœŸœŸœŸœ˜2JšœŸœ˜Jšœ5˜5šœ˜JšŸœJ˜P—JšŸœ˜Jšœ˜—K˜šœŸœŸœQŸœŸœ0ŸœŸœ(Ÿœ˜μšŸ˜šœŸœŸ˜'KšœŸœ ˜(KšŸœŸœ˜——Kšœ%Ÿœ˜/K˜KšœŸœŸœŸœ˜-K˜K˜!šŸ ˜ •StartOfExpansion[]šŸ˜˜šŸœŸ˜KšœŸœ˜6KšœŸœ˜#KšœŸœ˜3KšœŸœ˜šœ˜KšŸœ7˜<—Kšœ Ÿœ˜'˜:KšŸœ8˜=—šœ ˜ KšŸœ5˜:—KšŸœŸœ 0˜C——š ŸœŸœŸœŸœŸ˜8Kšœ8˜8—K˜K˜—Kšœ_Ÿœ Ÿœ Ÿœΐ˜½JšŸœ˜—šŸœŸœ ŸœŸ˜/Kšœ'Ÿœ%˜P—K˜!KšŸœ˜!K˜K˜šœŸ œ˜0KšœŸœ˜'Kšœ.Ÿœ˜7K˜—K˜š  œŸœŸœŸœ ŸœŸœ˜\KšœŸœ˜'K˜%šœŸœŸ˜šœŸœŸ˜'KšœŸœ ˜(KšŸœŸœ˜—šŸœŸœ˜šŸœŸœŸ˜ KšŸœ?˜D——KšŸœ˜šŸœ˜ ˜Kšœ%Ÿ œ Ÿœ˜M—K˜—K˜—K˜%K˜K˜—š œŸœŸœ˜KšœŸœ ŸœŸœ˜AKšœŸœ˜'K˜&šœŸœŸ˜šœŸœŸ˜'KšœŸœŸœ ˜2KšŸœŸœ˜—š ŸœŸœŸœŸœŸœ˜