<> <> <> <> <> <> <> <> DIRECTORY DBCommon; DBStoragePage: CEDAR DEFINITIONS IMPORTS DBCommon = BEGIN <> <> MaxWordsPerPage: CARDINAL = 512; RestOfWord: CARDINAL = 128; LengthField: TYPE = CARDINAL [0..MaxWordsPerPage); SlotIndexField: TYPE = CARDINAL [0..RestOfWord); SlotTypeField: TYPE = CARDINAL [0..RestOfWord); <> VecPage: TYPE = PRIVATE MACHINE DEPENDENT RECORD[ tag: CARDINAL [0..377B], <> unused: CARDINAL [0..1] _ NULL, highSlot: SlotIndexField, <> nFreeSlots: SlotIndexField, <> nWordsInFreeVecs: LengthField <> ];--VecPage <
> Slot: TYPE = PRIVATE MACHINE DEPENDENT RECORD[ type: SlotTypeField, <<"Type" of object stored in vec.>> vecOffset: LengthField <> ];--Slot <> FreeType: SlotTypeField = 0; <> UnFreeType: SlotTypeField = 177B; <> MaxTuplesetPerPage: SlotTypeField = 171B; <> IndTupleType: SlotTypeField = 172B; <> LStringType: SlotTypeField = 173B; <> EStringType: SlotTypeField = 174B; <> NonlocalStringExtensonType: SlotTypeField = 175B; <> TSDictType: SlotTypeField = 176B; <> VecHeader: TYPE = PRIVATE MACHINE DEPENDENT RECORD[ slotIndex: SlotIndexField, <> length: PUBLIC LengthField <> ];--VecHeader <> TupleBody: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, <> groupOffset: CARDINAL, <> fields: ARRAY[0..0) OF CARDINAL <> ];--TupleBody <<>> <> SizeOfNullTuple: CARDINAL = SIZE[TupleBody]; PageHeader: TYPE = MACHINE DEPENDENT RECORD[ pageTag: CARDINAL [0..256), dontCare: CARDINAL [0..256) ]; -- PageHeader <> <> Unused: CARDINAL = 0; -- unused page, obtained by extending Juniper file Free: CARDINAL = 1; -- page on segment or local free list AMap: CARDINAL = 2; -- page used to store segment address-map values Tuple: CARDINAL = 3; -- page used to store tuples SystemTuple: CARDINAL = 4; -- page used to store system tuples OverflowTuple: CARDINAL = 5; -- page used to store overflow tuples & long strings BTree: CARDINAL = 6; -- page used to store part of a B-tree <> IString: TYPE = MACHINE DEPENDENT RECORD[ bytesInString: LengthField, <> slotOfExtension: SlotIndexField, <> <> rest: SELECT OVERLAID * FROM word => [words: ARRAY [0..0) OF WORD _ NULL], text => [text: PACKED ARRAY [0..0) OF CHARACTER _ NULL], ENDCASE ];--IString <<>> <> SizeOfNullIString: CARDINAL = SIZE[IString]; LString: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, <> bytesInRemString: CARDINAL, <> eStringID: DBCommon.TID <> ];--LString SizeOfNullLString: CARDINAL = SIZE[LString]; EString: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, <> eStringID: DBCommon.TID, < this tuple holds tail of string.>> rest: SELECT OVERLAID * FROM word => [words: ARRAY [0..0) OF WORD _ NULL], text => [text: PACKED ARRAY [0..0) OF CHARACTER _ NULL], ENDCASE ];--EString SizeOfNullEString: CARDINAL = SIZE[EString]; <<>> <> TSDictSlotIndex: SlotIndexField = 1; <> TSDict: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, <> allocLink: DBCommon.DBPage, <> seq: ARRAY [1..1) OF TSDictEntry <> ];--TSDict TSDictEntry: TYPE = MACHINE DEPENDENT RECORD[ tuplesetID: DBCommon.TID, next: DBCommon.DBPage, prev: DBCommon.DBPage <> ];--TSDictEntry TuplesetObject: TYPE = MACHINE DEPENDENT RECORD[ wordsForTupleFields: CARDINAL [0..377B] _ 0, <> nVarFields: CARDINAL [0..377B] _ 0, <> searchList: TSDictEntry, <> allocList: DBCommon.DBPage _ DBCommon.NullDBPage, <> pageAllocator: PageAllocator <> ];--TuplesetObject <<>> <> PageAllocator: TYPE = MACHINE DEPENDENT RECORD[ segmentID: DBCommon.DBPage, <> firstPageInBlock: DBCommon.DBPage _ DBCommon.NullDBPage, <> nPagesInBlock: CARDINAL _ 0, nFreePagesInBlock: CARDINAL _ 0, <> nPagesPerExtent: CARDINAL _ 0, <> freeList: DBCommon.DBPage _ DBCommon.NullDBPage, <> nPagesOnFreeList: CARDINAL _ 0 <> ];--PageAllocator <> SizeOfInitialTSDict: CARDINAL = SIZE[TSDict] + SIZE[TSDictEntry]; SizeOfNullTSDict: CARDINAL = SIZE[TSDict]; <> InitializeVecPage: PROC[p: LONG POINTER TO VecPage, pageTag: CARDINAL]; <> TagOfPage: PROC[p: LONG POINTER TO VecPage] RETURNS[--pageTag-- CARDINAL] = TRUSTED INLINE BEGIN <> RETURN[p.tag]; END;--TagOfPage AllocVec: PROC[p: LONG POINTER TO VecPage, nWords: CARDINAL] RETURNS[--slotIndex-- CARDINAL, --success-- BOOLEAN]; <> WordsInLargestAllocableVec: PROC[p: LONG POINTER TO VecPage] RETURNS[CARDINAL]; <> FreeVec: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL]; <> ModifyVec: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL, deltaWords: INTEGER, preserveContents: BOOLEAN] RETURNS[--success-- BOOLEAN]; <0 and preserveContents, then the old contents of the vec will be found in the initial words of the new vec; the new words are not initialized. If ~success, then the call failed for lack of space. (The call cannot fail if deltaWords<0).>> VecOfSlot: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL] RETURNS[LONG POINTER TO VecHeader] = TRUSTED INLINE BEGIN <> IF slotIndex=0 OR slotIndex>HighSlotIndexOfPage[p] THEN ERROR DBCommon.InternalError -- BadSlotIndex --; RETURN[LOOPHOLE[p + LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot].vecOffset, LONG POINTER TO VecHeader]]; END;--VecOfSlot LengthOfVec: PROC[v: LONG POINTER TO VecHeader] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN <> RETURN[v.length]; END;--LengthOfVec TypeOfSlot: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN <> IF slotIndex=0 OR slotIndex>HighSlotIndexOfPage[p] THEN ERROR DBCommon.InternalError -- BadSlotIndex --; RETURN[LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot].type]; END;--TypeOfSlot SetTypeOfSlot: PROC[ p: LONG POINTER TO VecPage, slotIndex: CARDINAL, newType: CARDINAL] = TRUSTED INLINE BEGIN <> IF slotIndex=0 OR slotIndex>HighSlotIndexOfPage[p] THEN ERROR DBCommon.InternalError -- BadSlotIndex --; LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot].type _ newType; END;--SetTypeOfSlot WordsLeftOnPage: PROC[p: LONG POINTER TO VecPage] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN <> RETURN[p.nWordsInFreeVecs - SIZE[VecHeader]]; END;--WordsLeftOnPage HighSlotIndexOfPage: PROC[p: LONG POINTER TO VecPage] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN <> RETURN[p.highSlot]; END;--HighSlotIndexOfPage CheckVecPage: PROC[p: LONG POINTER TO VecPage, pageTag: CARDINAL]; <> IndexToSlot: PRIVATE PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL] RETURNS[LONG POINTER TO Slot] = TRUSTED INLINE BEGIN RETURN[LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot]]; END;--IndexToSlot IndexToOffset: PRIVATE PROC[slotIndex: CARDINAL] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN RETURN[DBCommon.WordsPerPage - SIZE[Slot] - slotIndex*SIZE[Slot]]; END;--IndexToOffset AssertVecIsLString: PROC[pagePtr: LONG POINTER TO VecPage, slotIndex: CARDINAL] = TRUSTED INLINE { SELECT TypeOfSlot[pagePtr, slotIndex] FROM LStringType => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadVecTag };--AssertVecIsLString AssertVecIsEString: PROC[pagePtr: LONG POINTER TO VecPage, slotIndex: CARDINAL] = TRUSTED INLINE { SELECT TypeOfSlot[pagePtr, slotIndex] FROM EStringType => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadVecTag };--AssertVecIsEString AssertVecIsTSDict: PROC[ pagePtr: LONG POINTER TO VecPage, slotIndex: CARDINAL] = TRUSTED INLINE { SELECT TypeOfSlot[pagePtr, slotIndex] FROM TSDictType => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadVecTag };--AssertVecIsTSDict AssertPageIsTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM Tuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsTuplePage AssertPageIsSystemTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM SystemTuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsSystemTuplePage AssertPageIsAnyTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM Tuple, SystemTuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsAnyTuplePage AssertPageIsOverflowTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM OverflowTuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsOverflowTuplePage NEntries: PROC[LONG POINTER TO TSDict] RETURNS[CARDINAL]; <> GetIndex: PROC[--p--LONG POINTER TO VecPage, --tsID--DBCommon.TID] RETURNS[--index--CARDINAL, --found it--BOOLEAN]; <> GetEntry: PROC[--p--LONG POINTER TO VecPage, --tsID--DBCommon.TID] RETURNS[LONG POINTER TO TSDictEntry]; <> <> EntryFromIndex: PROC[--p--LONG POINTER TO VecPage, --index--CARDINAL] RETURNS[LONG POINTER TO TSDictEntry]; <> <> END. -- DBStoragePage <> Created by MBrown on February 15, 1980 2:47 PM Changed by MBrown on February 15, 1980 10:31 PM <> Changed by MBrown on February 17, 1980 6:46 PM <> Changed by MBrown on February 17, 1980 8:22 PM < slot computation; added PRIVATE IndexToSlot to localize this>> <> Changed by MBrown on February 17, 1980 10:21 PM < HighSlotIndexOfPage. Added PRIVATE IndexToOffset>> <> Changed by MBrown on February 24, 1980 11:37 AM <> <> --to VecPage, and "LONG POINTER --TO Page--" to "LONG POINTER TO VecPage", to gain <> Changed by MBrown on February 24, 1980 1:01 PM <> <> <> Changed by MBrown on August 22, 1980 4:21 PM <> Changed by MBrown on September 26, 1980 11:21 AM <> <<>> Changed by Willie-Sue on February 15, 1985 <>