-- File: DBFilePilotImpl.mesa -- Last edited by: -- Rick Cattell on January 14, 1983 5:37 pm -- MBrown on February 22, 1983 5:51 pm -- Willie-Sue on February 22, 1983 5:51 pm -- Last Edited by: Donahue, January 20, 1983 2:53 pm DIRECTORY DBCommon, DBEnvironment, DBFile, DBFilePilot, DBStats, DCSFileTypes USING [tLeaderPage], Directory USING [Lookup, ignore, CreateFile, Error, PutProperty], Environment USING [bytesPerPage], File USING [Capability, nullCapability, GetSize, grow, PageCount, Permissions, read, SetSize, shrink, write], Inline, PropertyTypes USING [tByteLength], Rope, Space, Transaction USING [Handle, nullHandle, Begin, Commit, Abort]; DBFilePilotImpl: PROGRAM IMPORTS DBEnvironment, DBStats, Directory, File, Inline, Rope, Space, Transaction EXPORTS DBFilePilot SHARES File = BEGIN VersionOptions: TYPE = DBCommon.VersionOptions; -- Work around Space.CopyIn/CopyOut and uniform swap units crock ... space: Space.Handle; longPointer: LONG POINTER; PilotTrans: TYPE = DBFilePilot.PilotTrans; PilotTransRecord: TYPE = DBFilePilot.PilotTransRecord; PilotOpenFileHandle: TYPE = DBFilePilot.PilotOpenFileHandle; PilotOpenFileRecord: TYPE = DBFilePilot.PilotOpenFileRecord; CreateTransaction: PUBLIC PROC [] RETURNS [t: PilotTrans] = { DBStats.Starting[PilotFileCreateTransaction]; t ← NEW[PilotTransRecord ← [trans: Transaction.Begin[]]]; DBStats.Stopping[PilotFileCreateTransaction]; RETURN[t] }; FinishTransaction: PUBLIC PROC [t: PilotTrans, abort: BOOL, continue: BOOL] = { IF t.trans = Transaction.nullHandle THEN RETURN; DBStats.Starting[PilotFileFinishTransaction]; IF abort THEN Transaction.Abort[t.trans] ELSE Transaction.Commit[t.trans]; IF NOT abort AND continue THEN t.trans ← Transaction.Begin[]; DBStats.Stopping[PilotFileFinishTransaction]; }; RightBracket: Rope.ROPE = Rope.FromChar[']]; StripDirectory: PROC [name: Rope.ROPE] RETURNS [result: Rope.Text] = { -- removes everything preceding the last '] in name, returns a TEXT rope. currentIndex: LONG INTEGER ← 0; nextIndex: LONG INTEGER ← -1; size: LONG INTEGER = Rope.Size[name]; UNTIL (nextIndex ← Rope.Index[s1: name, pos1: currentIndex, s2: RightBracket]) = size DO currentIndex← nextIndex+1 ENDLOOP; RETURN [Rope.Flatten[base: name, start: currentIndex]] }; OpenFile: PUBLIC PROC [ t: PilotTrans, file: Rope.Text, version: VersionOptions, nPagesInitial: INT] RETURNS [f: PilotOpenFileHandle, createdFile: BOOL] = { nameWithoutDirectory: Rope.Text; DBStats.Starting[PilotFileOpen]; f ← NEW[PilotOpenFileRecord ← [trans: t, file: File.nullCapability]]; createdFile ← FALSE; nameWithoutDirectory ← StripDirectory[file]; f.file ← Directory.Lookup[ fileName: LOOPHOLE[nameWithoutDirectory], permissions: Directory.ignore ! Directory.Error => SELECT type FROM fileNotFound => { createdFile ← TRUE; CONTINUE }; invalidFileName, fileIsSD => ERROR DBEnvironment.Error[IllegalFileName]; volumeNotFound => ERROR DBEnvironment.Fatal[Unknown]; ENDCASE => ERROR ]; IF version = OldFileOnly AND createdFile THEN ERROR DBEnvironment.Error[FileNotFound]; IF version = NewFileOnly AND NOT createdFile THEN ERROR DBEnvironment.InternalError; -- Model level never uses NewFileOnly IF createdFile THEN { f.file ← Directory.CreateFile[ fileName: LOOPHOLE[nameWithoutDirectory], fileType: DCSFileTypes.tLeaderPage, size: nPagesInitial]; }; f.file.permissions ← File.read+File.write+File.grow+File.shrink; DBStats.Stopping[PilotFileOpen]; }; ReadFilePage: PUBLIC PROC [ f: PilotOpenFileHandle, p: CARDINAL, corePage: LONG POINTER] = { DBStats.Starting[PilotFileReadPage]; Space.CopyIn[ space: space, window: [f.file, LONG[p]+1], transaction: Transaction.nullHandle]; Inline.LongCOPY[from: longPointer, to: corePage, nwords: DBCommon.WordsPerPage]; DBStats.Stopping[PilotFileReadPage]; }; WriteFilePage: PUBLIC PROC [ f: PilotOpenFileHandle, p: CARDINAL, corePage: LONG POINTER] = { DBStats.Starting[PilotFileWritePage]; Inline.LongCOPY[to: longPointer, from: corePage, nwords: DBCommon.WordsPerPage]; Space.CopyOut[ space: space, window: [f.file, LONG[p]+1], transaction: f.trans.trans]; DBStats.Stopping[PilotFileWritePage]; }; GetSize: PUBLIC PROC [f: PilotOpenFileHandle] RETURNS [nPages: CARDINAL] = { len: LONG CARDINAL; DBStats.Starting[PilotFileGetSize]; len ← File.GetSize[file: f.file, transaction: f.trans.trans]; IF len = 0 THEN ERROR DBEnvironment.InternalError; --leader page DBStats.Stopping[PilotFileGetSize]; RETURN [len-1]; }; SetSize: PUBLIC PROC [f: PilotOpenFileHandle, nPages: CARDINAL] = { newLength: LONG CARDINAL; DBStats.Starting[PilotFileSetSize]; File.SetSize[file: f.file, size: LONG[nPages]+1, transaction: f.trans.trans]; newLength ← LONG[nPages] * Environment.bytesPerPage; Directory.PutProperty[file: f.file, property: PropertyTypes.tByteLength, propertyValue: DESCRIPTOR[@newLength, SIZE[LONG CARDINAL]]]; DBStats.Stopping[PilotFileSetSize]; }; space ← Space.Create[size: DBCommon.PagesPerDBPage, parent: Space.virtualMemory]; Space.Map[space]; longPointer ← Space.LongPointer[space]; END. CHANGE LOG Created by MBrown on February 28, 1981 3:08 PM Changed by MBrown on 2-Mar-81 10:44:37 -- Forgot to CONTINUE out of a catch phrase, and didn't have the necessary symbols on my disk --to figure it out. A multi-hour waste of time. Changed by MBrown on 2-Mar-81 11:21:27 -- Added a level of indirection in the representation of transaction. This is to allow --commit without losing the transaction, like Juniper does. Changed by MBrown on 1-Apr-81 20:26:22 -- CopyIn takes a nullHandle for a transaction, since we don't care about the state of the --buffer pool after a crash(!) Changed by MBrown on 19-Jun-81 21:06:23 -- STRING -> Rope.Ref. Changed by MBrown on 15-Jul-81 13:10:23 -- Bug in StripDirectory: indexed to position -1 in string instead of 0. Changed by Cattell on 4-Aug-81 20:35:54 -- Bug in Mark's fix above: StripDirectory now lost first character if no directory in name. Changed by Willie-Sue on June 25, 1982 9:30 am -- Rope.Ref => Rope.ROPE Changed by Cattell on July 15, 1982 7:47 pm -- Widespread changes due to changes to FileHandle, Transaction representation. Using DBCommon.Transaction, DBFile.FileHandles which are REFs to variants. The former is identical to FileIO.TransHandle. No longer need any FREEs. Changed by MBrown on August 7, 1982 9:45 pm -- Eliminate import of heap storage allocator. Changed by MBrown on November 29, 1982 1:58 pm -- New DBFilePilot interface. Changed by Rick on January 4, 1983 3:18 pm -- Bug in StripDirectory: local file names are normally of form "[Local]foo", so should strip -- everything from either "]" onward, not ">". May change this again later, so didn't change -- name of StripDirectory, etc. Changed by Rick and Willie-Sue on January 7, 1983 10:28 am -- test in FinishTransaction for Transaction.nullHandle Changed by Rick January 20, 1983 2:53 pm --Refixed change lost by Mark's fix to update file size! (to error generation) Changed by MBrown on February 22, 1983 3:45 pm -- Work around Space.CopyIn/CopyOut and uniform swap units crock by introducing --global 1 DB page buffer, and Inline.LongCOPY on each page transfer.