File: DBStorageFieldImpl.mesa
Copyright © 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
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;
This module exports the following procedures of DBStorage:
CreateTupleset, CreateSystemTupleset, AddField, AddSystemField, DeleteField.
This module exports all of DBStorageField.
Types exported to DBStorage
FieldObject: PUBLIC TYPE = DBStorageConcrete.FieldObject;
FieldHandle: TYPE = REF FieldObject;
ListofFieldHandle: TYPE = LIST OF FieldHandle;
SystemTuplesetObject: PUBLIC TYPE = DBStorageConcrete.SystemTuplesetObject;
SystemTuplesetHandle: TYPE = REF SystemTuplesetObject;
Procs exported to DBStorageField
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] = {
Generates an ERROR if fh's fieldType is not t.
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
Procs exported to DBStorage
CreateTupleset: PUBLIC PROC[x: DBStorage.TuplesetHandle] = TRUSTED {
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.
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] = {
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).
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] =
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.
{RETURN[NEW[DBStorageConcrete.FieldObject ← [typeDependent: group[]]]]};
MaxWordsPerTuple: CARDINAL = 3*(DBCommon.WordsPerPage/4);
If AddField would make a tuple type with more than this many words per tuple, BadOperation is
raised.
MakeFieldHandle: PROC[y: DBStorage.FieldDescriptor, wordsForTupleFields: CARDINAL] RETURNS[--fh-- FieldHandle, --newWordsInTuple-- CARDINAL] = TRUSTED {
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.
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 {
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.
fh: FieldHandle;
tsObjPtr: LONG POINTER TO DBStoragePage.TuplesetObject;
cacheHint: DBCommon.CacheHandle;
[tsObjPtr, cacheHint] ← DBStoragePrivate.GetNWordBase[x, TuplesetFieldHandle[]];
For now, die if user tries to add a field after a tuple has been created.
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] = {
This procedure adds to x the length of y. It returns a FieldHandle for the new field.
fh: FieldHandle;
[fh, x.wordsForTupleFields] ← MakeFieldHandle[y, x.wordsForTupleFields];
RETURN[fh];
};--AddSystemField
Mainline code (start trap on first TuplesetFieldHandle[] or IndexFieldHandle[] will do this
required initialization)
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
AllocVec, CompactPage, and related inlines {~1 to paper-sketch AllocVec, 3:15 to
code, :10 to compile}.
Changed by MBrown on February 3, 1980 3:07 PM
CreateTupleset, CreateSystemTupleset, AddField, AddSystemField, FreeTupleHandle.
Changed by MBrown on February 10, 1980 11:41 PM
Read1Word, Read2Word, ReadNWord (except overflow page reads).
Changed by MBrown on February 16, 1980 12:15 AM
Major restructuring of storage impl. Moved everything but tupleset creation/field
creation out of this module.
Changed by MBrown on February 16, 1980 9:11 PM
Moved heap storage allocation to DBStorageHeap.
Changed by MBrown on February 16, 1980 11:04 PM
Invented MakeFieldHandle to reduce some duplication.
Changed by MBrown on 17-Feb-80 13:59
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.
Changed by MBrown on February 25, 1980 7:45 PM
Added procs exported to DBStoragePrivateA (TuplesetFieldHandle, IndexFieldHandle).
Made tupleset creation and field creation consistent with DBStoragePrivateB's TupleBody
structure.
Changed by MBrown on April 9, 1980 10:11 AM
Made CreateTupleset convert the TSID to a DBPage before converting THAT to a segmentID.
Changed by MBrown on April 17, 1980 11:02 PM
Changed SystemTuplesetID to SystemTupleID.
Changed by MBrown on June 8, 1980 9:25 PM
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.
Changed by MBrown on June 8, 1980 10:19 PM
Compiler insists on an exported version of DBStorage.ListofFieldHandle.
Changed by MBrown on June 10, 1980 8:39 PM
Renamed to be StorageFieldImpl from StorageImplA.
Changed by MBrown on June 24, 1980 11:26 AM
Made SystemTuplesetObject be opaque in DBStorage.
Changed by MBrown on July 31, 1980 3:11 PM
Added expectedNGroups to CreateTupleset.
Changed by MBrown on August 13, 1980 11:59 AM
DBStoragePrivateB.SizeOfNullTuple became DBStoragePage.SizeOfNullTuple.
Changed by MBrown on August 25, 1980 1:37 PM
Added nVarFields to TuplesetObject.
Changed by MBrown on September 26, 1980 12:28 PM
Converted to new DBException.
Changed by MBrown on February 27, 1981 3:58 PM
Use zone for storage allocation.
Changed by MBrown on 18-Jun-81 14:47:11
Use counted zone for allocation of system tupleset objects.
Changed by Cattell on November 4, 1983 2:21 am
Removed tuple object zone, just do vanilla NEWs for Cedar 5.0
Changed by Willie-Sue February 15, 1985
made Cedar, added tioga formatting