Last edited by:
MBrown on May 22, 1983 10:27 pm,
Cattell on November 4, 1983 2:28 am
Willie-Sue on March 25, 1985 9:25:59 am PST
Widom, September 4, 1985 9:00:43 pm PDT
Donahue, March 10, 1986 8:44:03 am PST
DIRECTORY
AlpineEnvironment USING [LockOption],
DBCommon,
DBFile,
DBSegment,
DBIndex USING [InitializeIndex, CallAfterFinishTransaction],
DBStorage USING[AddSystemField, CreateIndex, CreateSystemPageTuple, CreateSystemTupleset, FieldHandle, IndexHandle, IndexObjectSize, SystemTuplesetHandle, TupleHandle],
DBStorageGroupScan USING [Init, CallAfterFinishTransaction],
DBStorageTID USING[TID],
DBStorageTuple USING[InitSegmentTuples, ConsTupleObject, CallAfterFinishTransaction, TIDOfTuple],
DBStorageTuplesetScan USING[Init, CallAfterFinishTransaction],
Rope USING [ROPE];
DBStorageImplD:
CEDAR
PROGRAM IMPORTS DBFile, DBIndex, DBSegment, DBStorage, DBStorageGroupScan, DBStorageTuple, DBStorageTuplesetScan
EXPORTS DBStorage =
BEGIN
Segment: TYPE = DBCommon.Segment;
SegmentIndex: TYPE = DBCommon.SegmentIndex;
SegmentID: TYPE = DBCommon.SegmentID;
VersionOptions: TYPE = DBCommon.VersionOptions;
Trans: TYPE = DBCommon.Transaction;
TID: TYPE = DBStorageTID.TID;
TupleHandle: TYPE = DBStorage.TupleHandle;
ROPE: TYPE = Rope.ROPE;
Initialize:
PUBLIC
PROC [nCachePages:
NAT, cacheFileName:
ROPE] = {
DBSegment.Initialize[nCachePages, cacheFileName, CreateIndexes];
DBStorageGroupScan.Init[];
DBStorageTuplesetScan.Init[];
DBIndex.InitializeIndex[];
};
CreateIndexes:
PROC [s: Segment]
RETURNS [indices:
ARRAY [0..DBCommon.systemIndexCount)
OF
TID] = {
Called from DBSegmentImpl for the initialization of a segment.
indexTS: DBStorage.SystemTuplesetHandle = DBStorage.CreateSystemTupleset[1];
indexFH: DBStorage.FieldHandle =
DBStorage.AddSystemField[indexTS, [NWord[DBStorage.IndexObjectSize]]];
handles: ARRAY [0..DBCommon.systemIndexCount) OF TupleHandle;
FOR i:
CARDINAL
IN [0..DBCommon.systemIndexCount)
DO
handles[i] ← DBStorage.CreateSystemPageTuple[indexTS, IF i=0 THEN NIL ELSE handles[0], s];
DBStorage.CreateIndex[handles[i]];
indices[i] ← DBStorageTuple.TIDOfTuple[handles[i]]
ENDLOOP;
};
Transaction interface
MakeTransaction:
PUBLIC PROC[server: Rope.
ROPE]
RETURNS[t: DBCommon.Transaction] = {
t ← DBFile.CreateTransaction[server] };
OpenTransaction:
PUBLIC
PROC[segment: Segment, handle: DBCommon.TransactionHandle, eraseAfterOpening:
BOOL ←
FALSE] = {
Opens a transaction on the segment.
DBSegment.OpenSegment[segment, handle.trans, eraseAfterOpening];
Make sure that s is in the list
FOR segments: DBCommon.SegmentList ← handle.segments, segments.next
UNTIL segments =
NIL
DO
IF segment = segments.segment THEN RETURN
ENDLOOP;
handle.segments ← NEW[DBCommon.SegmentListObject ← [segment: segment, next: handle.segments]];
};
FinishTransaction:
PUBLIC
PROC [handle: DBCommon.TransactionHandle, abort:
BOOL, continue:
BOOL] = {
stopping: BOOL = abort OR NOT continue;
FOR segs: DBCommon.SegmentList ← handle.segments, segs.next
UNTIL segs=
NIL
DO
DBSegment.WriteOutCache[segs.segment];
IF stopping
THEN DBSegment.CloseSegment[segs.segment];
you can drop the open file here too! After doing this, all of the tuples that refer to the segment will be invalid.
ENDLOOP;
DBFile.FinishTransaction[handle.trans, abort, continue];
IF stopping
THEN {
All volatile state referring to nonexistent segments must now be discarded.
DBStorageTuplesetScan.CallAfterFinishTransaction[];
DBStorageGroupScan.CallAfterFinishTransaction[];
FOR segs: DBCommon.SegmentList ← handle.segments, segs.next
UNTIL segs=
NIL
DO
DBIndex.CallAfterFinishTransaction[segs.segment];
DBStorageTuple.CallAfterFinishTransaction[segs.segment];
DBSegment.FlushCache[segs.segment];
ENDLOOP };
};
Segment interface
AttachSegment:
PUBLIC
PROC [fileName:
ROPE, s: Segment, segmentIndex: SegmentIndex, lock: AlpineEnvironment.LockOption, readonly:
BOOL, version: VersionOptions, nPagesInitial, nPagesPerExtent:
NAT] = {
DBSegment.AttachSegment[fileName, s, segmentIndex, lock, readonly, version, nPagesInitial, nPagesPerExtent];
DBStorageTuple.InitSegmentTuples[s];
};
RootIndicesFromSegment:
PUBLIC
PROC[s: Segment]
RETURNS [indices:
ARRAY[0..DBCommon.systemIndexCount)
OF DBStorage.IndexHandle] = {
indexTIDs: ARRAY[0..DBCommon.systemIndexCount) OF TID = DBSegment.RootIndicesFromSegment[s];
FOR i:
CARDINAL
IN [0..DBCommon.systemIndexCount)
DO
indices[i] ← DBStorageTuple.ConsTupleObject[tid: indexTIDs[i]]
ENDLOOP
};