File: DBStorageImplD.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
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: BOOLFALSE] = {
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
};
END.--DBStorageImplD