<> <> <> <> <> <> <> <> <> DIRECTORY DBCommon, DBSegment, DBStorage, DBStorageInternal, DBIndex, DBIndexHandle, IO; DBIndexHandleImpl: CEDAR PROGRAM IMPORTS DBCommon, DBSegment, DBStorageInternal, IO EXPORTS DBIndexHandle = { RealIndexHandle: TYPE = DBIndex.RealIndexHandle; IndexObject: TYPE = DBIndex.IndexObject; PriorityList: RealIndexHandle; <> FinalizeIndexHandle: PUBLIC PROC[s: DBCommon.Segment] = BEGIN i: RealIndexHandle; segmentID: DBCommon.SegmentID = DBSegment.SegmentIDFromSegment[s]; FOR i _ PriorityList, i.back UNTIL i.back = PriorityList DO IF i.free AND i.depth # 0 THEN ERROR; IF NOT i.free THEN { pageSegment: DBCommon.SegmentID = DBSegment.SegmentIDFromDBPage[i.segment]; IF pageSegment = segmentID THEN { i.free _ TRUE; i.depth _ 0 } }; ENDLOOP; END; <> CreateNewRealIndexHandle: PUBLIC PROC [tid: DBStorageInternal.TID] = <> BEGIN q: RealIndexHandle; IF PriorityList.front.free THEN BEGIN PriorityList _ PriorityList.front; GOTO Initialize END ELSE BEGIN q _ NEW[IndexObject]; q.front _ PriorityList.front; q.back _ PriorityList; PriorityList.front.back _ q; PriorityList.front _ q; PriorityList _ q; GOTO Initialize END; EXITS Initialize => { PriorityList^ _ [tid, Segment[tid], DBCommon.NullDBPage, NIL, 0, PriorityList.front, PriorityList.back, FALSE]}; END; GetOldRealIndexHandle: PUBLIC PROC [x: DBStorage.IndexHandle] RETURNS [RealIndexHandle] = <> BEGIN q: RealIndexHandle _ PriorityList; tid: DBStorageInternal.TID _ DBStorageInternal.TIDOfTuple[x]; DO IF q.free THEN GOTO NotFound; IF q.tid = tid THEN { <> IF q = PriorityList THEN GOTO Found; q.front.back _ q.back; q.back.front _ q.front; q.front _ PriorityList.front; PriorityList.front.back _ q; PriorityList.front _ q; q.back _ PriorityList; PriorityList _ q; GOTO Found}; q _ q.back; IF q = PriorityList THEN GOTO NotFound; REPEAT Found => {RETURN[q]}; NotFound => { ttr: DBStorageInternal.TupleTree_ NEW[DBStorageInternal.TupleTreeRecord]; CreateNewRealIndexHandle[tid]; DBStorageInternal.ReadIndexObject[x, ttr]; PriorityList.rootDB _ ttr.rootPA; PriorityList.depth _ ttr.depth; RETURN[PriorityList]}; ENDLOOP; END; DestroyIndexHandle: PUBLIC PROC [q: RealIndexHandle] = <> <> BEGIN IF q.front = q THEN -- there is only on item NULL ELSE IF q = PriorityList THEN PriorityList _ PriorityList.back ELSE BEGIN q.front.back _ q.back; q.back.front _ q.front; q.front _ PriorityList.front; q.back _ PriorityList; q.front.back _ q; PriorityList.front _ q END; q.free _ TRUE; END; DeleteHandle: PUBLIC PROC [q: RealIndexHandle] = <> BEGIN IF q.front = q THEN -- there is only on item NULL ELSE IF q = PriorityList THEN PriorityList _ PriorityList.back ELSE BEGIN q.front.back _ q.back; q.back.front _ q.front; q.front _ PriorityList.front; q.back _ PriorityList; q.front.back _ q; PriorityList.front _ q END; q.rootDB _ DBCommon.NullDBPage; q.root _ NIL; q.depth _ 0; q.free _ TRUE; END; Segment: PROC [tid: DBStorageInternal.TID] RETURNS [DBCommon.DBPage] = <> BEGIN OPEN DBStorageInternal; segment: DBCommon.DBPage; tuple: DBStorage.TupleHandle _ MakeTupleHandle[tid, ]; segment _ SegmentIDOfTuple[tuple]; ReleaseTupleHandle[tuple]; RETURN[segment] END; PrintHandle: PROC = { q: RealIndexHandle _ PriorityList; DO DBCommon.GetDebugStream[].PutF["tid: %12bB, rootDB: %12bB, depth: %bB, %s*n", IO.card[q.tid], IO.card[q.rootDB], IO.card[q.depth], IO.rope[IF q.free THEN "free" ELSE "not free"]]; q _ q.back; IF q=PriorityList THEN EXIT; ENDLOOP; }; PriorityList _ NEW[IndexObject]; PriorityList.front _ PriorityList.back _ PriorityList; PriorityList.free _ TRUE; }. CHANGE LOG Changed by MBrown on December 15, 1980 10:15 AM <> Changed by MBrown on February 27, 1981 5:34 PM <> Changed by Cattell sometime in March 1981 <> Changed by Cattell on June 20, 1982 6:23 pm <> Changed by Willie-Sue on June 25, 1982 9:19 am < IO>> Changed by Willie-Sue on June 30, 1982 4:50 pm < DBCommon.GetDebugStream[]>> Changed by Cattell on August 6, 1982 4:48 pm <> Changed by Cattell on September 21, 1982 9:20 pm <> <<>> Changed by Willie-Sue on February 18, 1985 <> <<>>