<> <> <> <> <> <> <> <> DIRECTORY AlpineEnvironment USING [LockOption], DBCommon, Rope USING [ROPE]; DBStorage: CEDAR DEFINITIONS = BEGIN ROPE: TYPE = Rope.ROPE; SegmentID: TYPE = DBCommon.SegmentID; VersionOptions: TYPE = DBCommon.VersionOptions; Segment: TYPE = DBCommon.Segment; SegmentIndex: TYPE = DBCommon.SegmentIndex; <> <> <> TuplesetObjectSize: CARDINAL = 20; IndexObjectSize: CARDINAL = 20; FieldObjectSize: CARDINAL = 5; <> TupleHandle: TYPE = DBCommon.TupleHandle; TupleObject: TYPE = DBCommon.TupleObject; TuplesetHandle: TYPE = TupleHandle; <> SystemTuplesetHandle: TYPE = REF SystemTuplesetObject; SystemTuplesetObject: TYPE; <> SystemTupleID: TYPE = LONG CARDINAL; -- Really [1..MaxSystemTupleID] MaxSystemTupleID: CARDINAL = 128; <> FieldDescriptor: TYPE = RECORD[ variantPart: SELECT basicType: FieldClass FROM OneWord,TwoWord => NULL, NWord => [length: CARDINAL], <> VarWord,VarByte => [lengthHint: CARDINAL], <> Group => [groupID: GroupID], <> ENDCASE ];--FieldDescriptor <> FieldClass: TYPE = {OneWord, TwoWord, NWord, VarWord, VarByte, Group}; FieldHandle: TYPE = REF FieldObject; FieldObject: TYPE; ListOfFieldHandle: TYPE = LIST OF FieldHandle; <> TuplesetScanHandle: TYPE = REF TuplesetScanObject; TuplesetScanObject: TYPE; <> GroupID: TYPE = TupleHandle; GroupScanHandle: TYPE = REF GroupScanObject; GroupScanObject: TYPE; <> IndexHandle: TYPE = TupleHandle; <> IndexScanHandle: TYPE = REF IndexScanObject; IndexScanObject: TYPE; <> Selection: TYPE = RECORD[lowerBound, upperBound: Rope.ROPE, includeLowerBound, includeUpperBound: BOOLEAN, lowerBoundInfinity, upperBoundInfinity: BOOLEAN _ FALSE]; <> <> <> << Initialization>> Initialize: PROC [nCachePages: NAT, cacheFileName: ROPE]; <> <> AttachSegment: PROC [fileName: ROPE, s: Segment, segmentIndex: SegmentIndex, lock: AlpineEnvironment.LockOption, readonly: BOOL, version: VersionOptions, nPagesInitial, nPagesPerExtent: NAT] RETURNS[newAttachment: BOOL]; <> <> <> MakeTransaction: PROC[server: Rope.ROPE] RETURNS[t: DBCommon.Transaction]; <> OpenTransaction: PROC [segment: Segment, handle: DBCommon.TransactionHandle, eraseAfterOpening: BOOL _ FALSE]; <> FinishTransaction: PROC [handle: DBCommon.TransactionHandle, abort: BOOL, continue: BOOL]; <> <> <> <<>> <<1) Definition.>> CreateTupleset: PROC [x: TuplesetHandle]; <> CreateSystemTupleset: PROC [x: SystemTupleID] RETURNS [SystemTuplesetHandle]; <> SetSystemTupleTable: PROC [REF ARRAY [1..MaxSystemTupleID] OF TupleHandle]; <> AddField: PROC [x: TuplesetHandle, y: FieldDescriptor] RETURNS [FieldHandle]; <> AddSystemField: PROC [x: SystemTuplesetHandle, y: FieldDescriptor] RETURNS [FieldHandle]; <> CreateFieldHandle: PROC RETURNS [FieldHandle]; <> <<2) Navigation.>> <> FirstLast: TYPE = DBCommon.FirstLast; OpenScanTupleset: PROC [x: TuplesetHandle, start: FirstLast] RETURNS [TuplesetScanHandle]; <> NextScanTupleset: PROC [x: TuplesetScanHandle] RETURNS [TupleHandle]; <> PrevScanTupleset: PROC [x: TuplesetScanHandle] RETURNS [TupleHandle]; <> CloseScanTupleset: PROC [x: TuplesetScanHandle]; <> FirstTuple: PROC[x: TuplesetHandle] RETURNS[TupleHandle]; <> EmptyTupleSet: PROC [x: TuplesetHandle] RETURNS[yes: BOOL]; <> <> <> <> <> <<1) Creation and destruction.>> CreateTuple: PROC [x: TuplesetHandle] RETURNS [newTuple: TupleHandle]; <> CreateSystemPageTuple: PROC [x: SystemTuplesetHandle, y: TupleHandle, s: Segment] RETURNS [newTuple: TupleHandle]; <> DestroyTuple: PROC [x: TupleHandle]; <> FreeTupleHandle: PROC [x: TupleHandle]; <> NullTuple: PROC[t: TupleHandle] RETURNS[yes: BOOL]; <> ConsSystemTupleObject: PROC [] RETURNS [TupleHandle]; <> <<2) Field access.>> <> ReadTupleset: PROC [x: TupleHandle] RETURNS [TuplesetHandle]; <> Read1Word: PROC [x: TupleHandle, f: FieldHandle] RETURNS [CARDINAL]; Read2Word: PROC [x: TupleHandle, f: FieldHandle] RETURNS [LONG CARDINAL]; ReadNWord: PROC [x: TupleHandle, f: FieldHandle, space: REF ANY]; <> ReadVarByte: PROC [x: TupleHandle, f: FieldHandle] RETURNS [Rope.ROPE]; Write1Word: PROC [x: TupleHandle, f: FieldHandle, val: CARDINAL]; Write2Word: PROC [x: TupleHandle, f: FieldHandle, val: LONG CARDINAL]; WriteNWord: PROC [x: TupleHandle, f: FieldHandle, val: REF ANY]; <> WriteVarByte: PROC [x: TupleHandle, f: FieldHandle, val: Rope.ROPE]; << Group interface>> <> <> <> ReadTID: PROC [--x-- TupleHandle, --f-- FieldHandle] RETURNS [--z-- TupleHandle]; <> GetGroupIDs: PROC [--z-- TupleHandle] RETURNS [LIST OF GroupID]; <> OpenScanGroup: PROC [--z-- TupleHandle, --f-- FieldHandle, --start-- FirstLast] RETURNS [--r-- GroupScanHandle]; <> WriteTID: PROC [--x-- TupleHandle, --r-- GroupScanHandle]; <> <<>> WriteTIDNil: PROC [--x-- TupleHandle, --f-- FieldHandle]; <> NextInGroup: PROC [--r-- GroupScanHandle] RETURNS [--x-- TupleHandle]; <> PrevInGroup: PROC [--r-- GroupScanHandle] RETURNS [--x-- TupleHandle]; <> CloseScanGroup: PROC [--r-- GroupScanHandle]; TupleForField: PROC[x: TupleHandle, f: FieldHandle] RETURNS[handle: TupleHandle]; <> SetTupleField: PROC[x: TupleHandle, f: FieldHandle, val: TupleHandle]; <> <> <> <> <<>> <> << Index interface>> <<1) Definition. An index implements a map from byte string keys to doubleword values. The byte strings are ordered in the obvious way, and the index allows efficient range queries on key values.>> <> RootIndicesFromSegment: PROC [s: Segment] RETURNS [indices: ARRAY[0..DBCommon.systemIndexCount) OF IndexHandle]; <> CreateIndex: PROC [x: IndexHandle]; <> DestroyIndex: PROC [x: IndexHandle]; <> <<2) Maintainance. These routines allow insertion and deletion of associations in an index.>> InsertIntoIndex: PROC [x: IndexHandle, k: Rope.ROPE, v: TupleHandle]; <> DeleteFromIndex: PROC [x: IndexHandle, k: Rope.ROPE, v: TupleHandle]; < is not present in the index x.>> <<3) Navigation. Two means of navigating through indices are provided, either by using the Next and Previous operators to return tuple handles or by enumerating all of the keys in a certain range and then selecting those tuples that are of interest.>> OpenScanIndex: PROC [x: IndexHandle, y: Selection, startPosition: FirstLast] RETURNS [IndexScanHandle]; NextScanIndex: PROC [x: IndexScanHandle] RETURNS [tuple: TupleHandle]; PrevScanIndex: PROC [x: IndexScanHandle] RETURNS [tuple: TupleHandle]; PrevScanKey: PROC[x: IndexScanHandle] RETURNS [key: DBCommon.IndexKey]; NextScanKey: PROC[x: IndexScanHandle] RETURNS [key: DBCommon.IndexKey]; ThisScanTuple: PROC[x: IndexScanHandle] RETURNS [tuple: TupleHandle]; IgnoreEntry: PROC[x: IndexScanHandle]; TupleForKey: PROC [x: IndexHandle, key: Rope.ROPE] RETURNS[tuple: TupleHandle]; <> CloseScanIndex: PROC [x: IndexScanHandle]; END. -- DBStorage