DIRECTORY DB USING[Failure, Error], DBCommon USING[CacheHandle, DBPage, NullDBPage, WordsPerPage, TID, DecomposeTID, InternalError], DBSegment USING[SegmentIDFromDBPage, UnlockPage, WriteLockedPage], DBStorage, DBStorageConcrete USING[SystemTuplesetObject, FieldObject, FieldType], DBStoragePage USING[SizeOfNullTuple, TuplesetObject], DBStorageField USING[], DBStoragePrivate USING[GetNWordBase], DBStorageTuple USING[TIDOfTuple]; DBStorageFieldImpl: CEDAR PROGRAM IMPORTS DB, DBCommon, DBSegment, DBStoragePrivate, DBStorageTuple EXPORTS DBStorage, DBStorageField = BEGIN OPEN DBCommon; FieldObject: PUBLIC TYPE = DBStorageConcrete.FieldObject; FieldHandle: TYPE = REF FieldObject; ListofFieldHandle: TYPE = LIST OF FieldHandle; SystemTuplesetObject: PUBLIC TYPE = DBStorageConcrete.SystemTuplesetObject; SystemTuplesetHandle: TYPE = REF SystemTuplesetObject; tuplesetFieldHandle: FieldHandle; indexFieldHandle: FieldHandle; TuplesetFieldHandle: PUBLIC PROC RETURNS[FieldHandle] = { RETURN[tuplesetFieldHandle] };--TuplesetFieldHandle IndexFieldHandle: PUBLIC PROC RETURNS[FieldHandle] = { RETURN[indexFieldHandle] };--IndexFieldHandle CheckFieldHandleType: PUBLIC PROC[fh: FieldHandle, t: DBStorageConcrete.FieldType] = { IF fh.fieldType # t THEN ERROR DBCommon.InternalError; -- [Unknown]; };--CheckFieldHandleType FieldOffset: PUBLIC PROC[fh: FieldHandle] RETURNS[CARDINAL] = { RETURN[fh.offset]; };--FieldOffset NWordsInField: PUBLIC PROC[fh: FieldHandle] RETURNS[CARDINAL] = { RETURN[fh.nWords]; };--NWordsInField GroupIDOfField: PUBLIC PROC[fh: FieldHandle] RETURNS[TID] = { IF fh.fieldType # Group THEN ERROR DBCommon.InternalError; -- [Unknown]; RETURN[fh.groupID]; };--GroupIDOfField CreateTupleset: PUBLIC PROC[x: DBStorage.TuplesetHandle] = TRUSTED { tsObjPtr: LONG POINTER TO DBStoragePage.TuplesetObject; cacheHint: DBCommon.CacheHandle; dbPage: DBPage; [dbPage,] _ DecomposeTID[DBStorageTuple.TIDOfTuple[x]]; [tsObjPtr, cacheHint] _ DBStoragePrivate.GetNWordBase[x, TuplesetFieldHandle[]]; DBSegment.WriteLockedPage[cacheHint]; tsObjPtr^ _ [ wordsForTupleFields: 0, nVarFields: 0, searchList: [tuplesetID: DBStorageTuple.TIDOfTuple[x], next: NullDBPage, prev: NullDBPage], pageAllocator: [segmentID: DBSegment.SegmentIDFromDBPage[dbPage]] ]; DBSegment.UnlockPage[cacheHint]; };--CreateTupleset CreateSystemTupleset: PUBLIC PROC[x: DBStorage.SystemTupleID] RETURNS[SystemTuplesetHandle] = { IF x NOT IN [1..DBStorage.MaxSystemTupleID] THEN ERROR DBCommon.InternalError; -- [Unknown]; RETURN[NEW[SystemTuplesetObject _ [tuplesetID: x, wordsForTupleFields: 0]]]; };--CreateSystemTupleset CreateFieldHandle: PUBLIC PROC RETURNS [FieldHandle] = {RETURN[NEW[DBStorageConcrete.FieldObject _ [typeDependent: group[]]]]}; MaxWordsPerTuple: CARDINAL = 3*(DBCommon.WordsPerPage/4); MakeFieldHandle: PROC[y: DBStorage.FieldDescriptor, wordsForTupleFields: CARDINAL] RETURNS[--fh-- FieldHandle, --newWordsInTuple-- CARDINAL] = TRUSTED { fh: FieldHandle _ NEW[DBStorageConcrete.FieldObject_ [typeDependent: group[]]]; fieldInfo: RECORD[code: DBStorageConcrete.FieldType, length: CARDINAL] _ WITH fd: y SELECT FROM OneWord => [OneWord, 1], TwoWord => [TwoWord, 2], NWord => [NWord, fd.length], VarWord => [VarWord, 1 + fd.lengthHint], VarByte => [VarByte, 1 + (fd.lengthHint+1)/2], Group => [Group, 3*SIZE[TID]], ENDCASE => ERROR DBCommon.InternalError; -- [Unknown]; fh.fieldType _ fieldInfo.code; fh.offset _ DBStoragePage.SizeOfNullTuple + wordsForTupleFields; fh.nWords _ fieldInfo.length; WITH fd: y SELECT FROM Group => fh.groupID _ DBStorageTuple.TIDOfTuple[fd.groupID]; ENDCASE => fh.fill1 _ 0; IF wordsForTupleFields + fieldInfo.length > MaxWordsPerTuple THEN ERROR DB.Failure[$tupleTooLong, "can't make tuple this big"]; RETURN[fh, wordsForTupleFields + fieldInfo.length]; };--MakeFieldHandle AddField: PUBLIC PROC[x: DBStorage.TuplesetHandle, y: DBStorage.FieldDescriptor] RETURNS[FieldHandle] = TRUSTED { fh: FieldHandle; tsObjPtr: LONG POINTER TO DBStoragePage.TuplesetObject; cacheHint: DBCommon.CacheHandle; [tsObjPtr, cacheHint] _ DBStoragePrivate.GetNWordBase[x, TuplesetFieldHandle[]]; IF tsObjPtr.allocList#NullDBPage OR tsObjPtr.searchList.next#NullDBPage THEN ERROR DB.Error[NotImplemented]; -- Adding field to existing relation! DBSegment.WriteLockedPage[cacheHint]; [fh, tsObjPtr.wordsForTupleFields] _ MakeFieldHandle[y, tsObjPtr.wordsForTupleFields]; SELECT fh.fieldType FROM VarWord, VarByte => {tsObjPtr.nVarFields _ tsObjPtr.nVarFields + 1; }; ENDCASE => {}; DBSegment.UnlockPage[cacheHint]; RETURN[fh]; };--AddField AddSystemField: PUBLIC PROC[x: SystemTuplesetHandle, y: DBStorage.FieldDescriptor] RETURNS[FieldHandle] = { fh: FieldHandle; [fh, x.wordsForTupleFields] _ MakeFieldHandle[y, x.wordsForTupleFields]; RETURN[fh]; };--AddSystemField IF DBStorage.FieldObjectSize < SIZE[DBStorageConcrete.FieldObject] OR DBStorage.TuplesetObjectSize < SIZE[DBStoragePage.TuplesetObject] THEN ERROR DBCommon.InternalError; -- [Unknown]; [tuplesetFieldHandle,] _ MakeFieldHandle[[NWord[DBStorage.TuplesetObjectSize]], 0]; [indexFieldHandle,] _ MakeFieldHandle[[NWord[DBStorage.IndexObjectSize]], 0]; END.--DBStorageFieldImpl CHANGE LOG Created by MBrown on 2-Feb-80 16:07 Changed by MBrown on February 3, 1980 3:07 PM Changed by MBrown on February 10, 1980 11:41 PM Changed by MBrown on February 16, 1980 12:15 AM Changed by MBrown on February 16, 1980 9:11 PM Changed by MBrown on February 16, 1980 11:04 PM Changed by MBrown on 17-Feb-80 13:59 Changed by MBrown on February 25, 1980 7:45 PM Changed by MBrown on April 9, 1980 10:11 AM Changed by MBrown on April 17, 1980 11:02 PM Changed by MBrown on June 8, 1980 9:25 PM Changed by MBrown on June 8, 1980 10:19 PM Changed by MBrown on June 10, 1980 8:39 PM Changed by MBrown on June 24, 1980 11:26 AM Changed by MBrown on July 31, 1980 3:11 PM Changed by MBrown on August 13, 1980 11:59 AM Changed by MBrown on August 25, 1980 1:37 PM Changed by MBrown on September 26, 1980 12:28 PM Changed by MBrown on February 27, 1981 3:58 PM Changed by MBrown on 18-Jun-81 14:47:11 Changed by Cattell on November 4, 1983 2:21 am Changed by Willie-Sue February 15, 1985 File: DBStorageFieldImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by MBrown on 18-Jun-81 14:40:28 Last Edited by: Willie-Sue, February 15, 1985 12:35:06 pm PST Last Edited by: Cattell, January 18, 1984 11:13 am Last Edited by: Widom, July 19, 1985 2:25:29 pm PDT Donahue, May 23, 1986 10:23:04 am PDT This module exports the following procedures of DBStorage: CreateTupleset, CreateSystemTupleset, AddField, AddSystemField, DeleteField. This module exports all of DBStorageField. Types exported to DBStorage Procs exported to DBStorageField Generates an ERROR if fh's fieldType is not t. Procs exported to DBStorage Creates a new tupleset whose tuples have no fields. The parameter x is anexisting tuple whose first-created field is an NWord field, TuplesetObjectLengthwords long. Information describing the new tupleset is placed in this field, andtuples in the new tupleset are placed in the same segment as tuple x . Tuple x isreturned by a ReadTuplesetID call on any tuple in this tupleset.Note that the TuplesetHandle is used primarily by CreateTuple, but is alsomodified by AddField/DeleteField. Creates a new system tupleset (system tuplesets do not live in a single segment and the pages containing their tuples are not chained together by the storage level). Since the FieldObject type is opaque, this procedure is needed to allocate a FieldHandle, to be passed to ReadNWord when retrieving a FieldHandle stored in the data schema. If AddField would make a tuple type with more than this many words per tuple, BadOperation is raised. Creates a new field handle, for a tupleset whose tuples contain wordsInTuple words, in fh based on the description of the field in y. Returns the new number of words in a tuple. If this number of words is uncomfortably large (see MaxWordsPerTuple above), raise BadOperation. Called from: AddField, AddSystemField, module init code. In effect this procedure modifies each tuple of set x, adding a new field of type y. It returns a FieldHandle for the new field. For now, die if user tries to add a field after a tuple has been created. This procedure adds to x the length of y. It returns a FieldHandle for the new field. Mainline code (start trap on first TuplesetFieldHandle[] or IndexFieldHandle[] will do this required initialization) AllocVec, CompactPage, and related inlines {~1 to paper-sketch AllocVec, 3:15 to code, :10 to compile}. CreateTupleset, CreateSystemTupleset, AddField, AddSystemField, FreeTupleHandle. Read1Word, Read2Word, ReadNWord (except overflow page reads). Major restructuring of storage impl. Moved everything but tupleset creation/field creation out of this module. Moved heap storage allocation to DBStorageHeap. Invented MakeFieldHandle to reduce some duplication. Eliminated use of @ from CreateTupleset. Added checks for inconsistent sizes of objects, making the "true" size be the one in DBStorage. (This can be larger than the actual size with no ill effect, but smaller is a no-no). Changed length to wordsPerTuple in SystemTuplesetObject. Added procs exported to DBStoragePrivateA (TuplesetFieldHandle, IndexFieldHandle). Made tupleset creation and field creation consistent with DBStoragePrivateB's TupleBody structure. Made CreateTupleset convert the TSID to a DBPage before converting THAT to a segmentID. Changed SystemTuplesetID to SystemTupleID. Scattered minor changes in introducing FieldObject as an opaque type. The module now contains only 2 LOOPHOLEs. Changed MakeFieldHandle to do storage allocation for the field handle it produces. Compiler insists on an exported version of DBStorage.ListofFieldHandle. Renamed to be StorageFieldImpl from StorageImplA. Made SystemTuplesetObject be opaque in DBStorage. Added expectedNGroups to CreateTupleset. DBStoragePrivateB.SizeOfNullTuple became DBStoragePage.SizeOfNullTuple. Added nVarFields to TuplesetObject. Converted to new DBException. Use zone for storage allocation. Use counted zone for allocation of system tupleset objects. Removed tuple object zone, just do vanilla NEWs for Cedar 5.0 made Cedar, added tioga formatting Κλ˜šœ™Jšœ Οmœ1™<—Jšœ+™+Jšœ=™=Jšœ2™2™3Icode™%—J˜J˜šΟk ˜ Jšžœžœ˜Jšœ žœR˜`Jšœ žœ3˜BJ˜ Jšœžœ/˜FJšœžœ"˜5Jšœžœ˜Jšœžœ˜%Jšœžœ ˜!J˜—šœžœž˜!šž˜J˜J˜ J˜ J˜J˜—šž˜Jšœ ˜ J˜—Jšœžœžœ ˜J˜Jšœ:™:JšœL™LJšœ*™*J˜Jšœ™J˜Jšœ žœžœ!˜9Jšœ žœžœ ˜$Jšœžœžœžœ ˜.J˜Jšœžœžœ*˜KJšœžœžœ˜6J˜Jšœ ™ J˜J˜!J˜J˜šΟnœžœžœžœ˜:Jšžœ˜JšœΟc˜—J˜šŸœžœžœžœ˜7Jšžœ˜Jšœ ˜—J˜šŸœžœžœ5˜VJšœ.™.šžœž˜Jšžœžœ  ˜+—Jšœ ˜J˜—š Ÿ œžœžœžœžœ˜?Jšžœ ˜Jšœ  ˜—J˜š Ÿ œžœžœžœžœ˜AJšžœ ˜Jšœ ˜—J˜š Ÿœžœžœžœžœ˜=šžœž˜Jšžœžœ  ˜+—Jšžœ ˜Jšœ ˜—Ihead1šœ™šŸœžœžœ žœ˜DJšœκ™κJ˜Jšœ žœžœžœ˜7Jšœ ˜ J˜J˜7J˜PJ˜%˜ J˜J˜˜6J˜$—J˜D—J˜ Jšœ ˜—J˜J˜šŸœžœžœžœ˜_šœ₯™₯šžœžœžœ!ž˜0Jšžœžœ  ˜+—JšžœžœB˜L—Jšœ ˜—J˜šŸœžœžœžœ˜6JšœY™YJšœR™RJšœžœžœ=˜H—J˜šœžœ˜9Jšœ]™]Jšœ™J˜—šŸœžœ4žœžœ œ œžœžœ˜˜šœ“™“Jšœ8™8J˜Jšœžœ:˜Ošœ žœ,žœ˜Hšžœžœž˜J˜J˜J˜ J˜(J˜.Jšœžœžœ˜"——Jšžœžœžœ  ˜6J˜Jšœ@˜@J˜šžœžœž˜˜J˜4——Jšžœ˜šžœ;ž˜AJšžœžœ5˜=—Jšžœ-˜3—Jšœ ˜—J˜š Ÿœžœžœ;žœžœ˜qšœ€™€J˜J˜Jšœ žœžœžœ˜7Jšœ ˜ J˜PJšœI™Išžœžœ$˜GJšžœžœžœ %˜J—J˜%J˜Všžœž˜J˜F—Jšžœ˜J˜ Jšžœ˜ —Jšœ  ˜ —J˜J˜šŸœžœžœ7žœ˜kšœU™UJ˜J˜HJšžœ˜ —Jšœ ˜—J˜Jšœ[™[Jšœ™J˜šžœžœ ž˜EJšœžœž˜FJšžœžœ  ˜+—J˜SJ˜MJ˜—Jšžœ ˜J˜J˜Jšžœž˜ J˜J˜#JšœP™PJšœ™J˜Jšœ,ž˜.JšœP™PJ˜Jšœ.ž˜0Jšœ=™=J˜Jšœ.ž˜0JšœR™RJšœ™J˜Jšœ-ž˜/Jšœ/™/J˜Jšœ.ž˜0Jšœ4™4J˜J˜$JšœP™PJšœR™RJšœO™OJšœ&™&J˜Jšœ-ž˜/JšœR™RJšœW™WJšœ ™ J˜Jšœ*ž˜,JšœW™WJ˜Jšœ+ž˜-Jšœ*™*J˜Jšœ(ž˜*Jšœ^™^Jšœ[™[Jšœ ™ J˜Jšœ)ž˜+JšœG™GJ˜Jšœ)ž˜+Jšœ1™1J˜Jšœ*ž˜,Jšœ1™1J˜Jšœ)ž˜+Jšœ(™(J˜Jšœ,ž˜.JšœG™GJ˜Jšœ+ž˜-Jšœ#™#J˜Jšœ/ž˜1Jšœ™J˜Jšœ-ž˜/Jšœ ™ J˜J˜'Jšœ;™;J˜J˜.Jšœ=™=J™J˜'J™"—…—F0O