<> <> <> <> <> <> <> <> 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] = { <> 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; }; <> 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] = { <> DBSegment.OpenSegment[segment, handle.trans, eraseAfterOpening]; <> 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]; <> ENDLOOP; DBFile.FinishTransaction[handle.trans, abort, continue]; IF stopping THEN { <> 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 }; }; <> 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