<> <> <> <> <> <> <> <> <> DIRECTORY DBCommon, DBSegment USING[AllocPage, FreePage, ReadPage, SegmentIDFromDBPage, SegmentIDFromSegment, UnlockPage, WriteLockedPage], DBStoragePagetags USING [BTree], DBIndex, DBIndexPage; DBIndexPageImpl: CEDAR PROGRAM IMPORTS DBSegment EXPORTS DBIndexPage = BEGIN Core: TYPE = DBIndex.Core; Page: TYPE = DBIndex.Page; PageObject: TYPE = DBIndex.PageObject; RealIndexHandle: TYPE = DBIndex.RealIndexHandle; <> PageList: Page; TakeALookAtThis: SIGNAL = CODE; BadPage: PUBLIC SIGNAL = CODE; <> DestroyPageList: PUBLIC PROC [s: DBCommon.Segment] = BEGIN p: Page; segID: DBCommon.SegmentID = DBSegment.SegmentIDFromSegment[s]; p _ PageList; DO IF DBSegment.SegmentIDFromDBPage[p.db] = segID THEN { IF NOT p.free THEN UnlockPage[p]; -- unlock page p.tree_ NIL; p.cache_ NIL; p.db_ 0; p.pointer_ NIL; p.depth_ 0 }; -- erase invalid data p _ p.front; IF p=PageList THEN EXIT; ENDLOOP; END; DestroyPage: PUBLIC PROC [ segment: DBCommon.DBPage, p: Page, db: DBCommon.DBPage] = <> BEGIN DBSegment.FreePage[segment, db, p.cache]; p.free _ TRUE; END; UnlockPage: PUBLIC PROC [p: Page] = BEGIN CheckTag[p.pointer]; DBSegment.UnlockPage[p.cache]; p.free _ TRUE; END; WriteAndUnlockPage: PUBLIC PROC [p: Page] = BEGIN CheckTag[p.pointer]; DBSegment.WriteLockedPage[p.cache]; DBSegment.UnlockPage[p.cache]; p.free _ TRUE; END; WritePage: PUBLIC PROC [p: DBIndex.Page] = <> BEGIN CheckTag[p.pointer]; DBSegment.WriteLockedPage[p.cache]; END; AllocatePage: PROC RETURNS [Page] = <> <> BEGIN ret: Page; p: Page _ PageList; UNTIL p.free = TRUE DO p _ p.front; IF p=PageList THEN GOTO NoFreePage; REPEAT NoFreePage => {ret _ NEW[PageObject]; PageList.front.back _ ret; ret^ _ [NIL, DBCommon.NullDBPage, NIL, 0, NIL, TRUE, PageList.front, PageList]; PageList.front _ ret; RETURN[ret]}; FINISHED => {RETURN[p]} ENDLOOP; END; CreateEmptyPage: PUBLIC PROC [ tree: RealIndexHandle, level: CARDINAL, s: DBCommon.DBPage] RETURNS [Page] = TRUSTED <> BEGIN cache: DBCommon.CacheHandle; db: DBCommon.DBPage; h: Page; p: LONG POINTER TO Core; [db, cache, p] _ DBSegment.AllocPage[s]; p.tag.pageTag _ DBStoragePagetags.BTree; p.left _ p.right _ DBCommon.NullDBPage; p.size _ 0; h _ AllocatePage[]; h.tree _ tree; h.db _ db; h.cache _ cache; h.depth _ level; h.pointer _ p; h.free _ FALSE; RETURN[h]; END; GetPage: PUBLIC PROC [ tree: RealIndexHandle, db: DBCommon.DBPage, level: CARDINAL] RETURNS [Page] = TRUSTED BEGIN p: Page _ AllocatePage[]; cache: DBCommon.CacheHandle; pointer: LONG POINTER TO Core; [cache, pointer] _ DBSegment.ReadPage[db, p.cache]; CheckTag[pointer]; p.tree _ tree; p.db _ db; p.cache _ cache; p.depth _ level; p.pointer _ pointer; p.free _ FALSE; RETURN[p] END; CheckTag: PUBLIC PROC[p: LONG POINTER TO Core] = TRUSTED { IF p.tag.pageTag#DBStoragePagetags.BTree THEN SIGNAL BadPage}; <
> PageList _ NEW[PageObject]; PageList.front _ PageList.back _ PageList; PageList.free _ TRUE; END. Change Log: Added to check page tag in CreateOldPage by Suzuki November 24, 1980 9:06 AM Changed FreePage. Now Unlocks the page by Suzuki November 24, 1980 1:33 PM Changed AllocatePage. Now initializes the page if it was obtained via AllocateHeapNode by MBrown December 13, 1980 12:41 AM Allocate storage from heap storage mdsZone by MBrown February 27, 1981 6:18 PM Convert to Cedar by Cattell 7-Jun-81 11:24:59 Fixed bug in DestroyPageList: it didn't deallocate the PageObjects, and later code was trying to treat the cache hints to non-existent storage as real! by Cattell June 24, 1982 11:18 am Changed PageObjects from POINTERs to REFs. by Cattell August 6, 1982 5:10 pm Eliminated import of heap storage allocator. by MBrown August 7, 1982 9:38 pm Added BadPage signal. by Cattell August 25, 1982 5:21 pm The following invariant of the "page" data structure was getting messed up: NOT p.free iff DBSegment.LockCount[p.db, p.cache] > 0. The problem was that p.free was assigned FALSE, then a DBSegment call was made that can raise transaction aborted, then p.cache was assigned. Fix is to have AllocatePage return a page with p.free = TRUE, then make DBSegment call. by MBrown May 23, 1983 10:58 am Changed by Willie-Sue on February 18, 1985 <>