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 ΌFile: DBIndexPageImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by: Suzuki: December 16, 1980 5:15 PM MBrown: May 23, 1983 10:58 am Cattell: September 21, 1982 9:27 pm Willie-Sue, February 18, 1985 1:43:21 pm PST Widom, September 4, 1985 9:41:49 pm PDT Donahue, November 13, 1985 11:54:25 am PST global vars Public procs Deallocates the Page and DBPage; it should have a lock count of 1 Mark page p as having been written, but keep locked. Just allocates the DBIndex.Page, i.e. the HANDLE for the DBCommon.Page returns a "free" page; caller is responsible for marking it not free. level = 1 if it is a leaf Main part made Cedar, added tioga formatting ΚF˜šœ™Icodešœ Οmœ1™<—Jšœ™Jšœ#™#Jšœ™šœ%™%K™,K™'K™*—J˜šΟk ˜ J˜ Jšœ žœh˜wJšœžœ ˜ J˜J˜ J˜—šœžœž˜šž˜J˜ —šž˜J˜ —Jšœž˜J˜Jšœžœ˜Jšœžœ˜Jšœ žœ˜&Jšœžœ˜0J˜Jšœ ™ J˜J˜Jšœžœžœ˜J˜Jšœ žœžœžœ˜J˜Jšœ ™ J˜šΟnœžœžœ˜4Jšž˜J˜Jšœ>˜>J˜ šž˜šžœ-žœ˜5JšžœžœžœΟc˜0Jšœžœ žœžœ ˜X—J˜ Jšžœ žœžœ˜Jšžœ˜—Jšžœ˜J˜—šŸ œžœžœ˜J˜9JšœA™AJšž˜J˜)Jšœ žœ˜Jšžœ˜J˜—šŸ œžœžœ ˜#šžœ˜J˜J˜ Jšœ žœ˜—Jšžœ˜J˜—šŸœžœžœ ˜+šžœ˜J˜J˜#J˜ Jšœ žœ˜—Jšžœ˜J˜—šŸ œžœžœ˜*Jšœ4™4šžœ˜J˜J˜#—Jšžœ˜J˜—šŸ œžœžœ ˜$JšœF™FJšœE™EJšž˜J˜ J˜šžœ žœž˜J˜ Jšžœ žœžœ ˜#—šž˜šœžœ ˜%J˜Jš œžœžœžœžœ˜OJ˜Jšžœ˜ —Jšžœžœ˜—Jšžœ˜Jšžœ˜J˜—šŸœžœžœ˜Jšœžœ˜;Jšžœ ž˜Jšœ™Jšž˜Jšœ˜J˜J˜Jšœžœžœžœ˜J˜(J˜(J˜'J˜ J˜J˜NJšœ žœ˜Jšžœ˜ Jšžœ˜J˜—šŸœžœžœ˜Jšœ3žœžœ ˜MJšžœž˜ J˜Jšœ˜Jšœ žœžœžœ˜J˜3J˜J˜TJšœ žœ˜Jšžœ˜ Jšžœ˜J˜—šŸœžœžœžœžœžœ žœ˜:Jšžœ'žœžœ ˜>J˜——Jšœ ™ ˜Jšœ žœ ˜J˜*Jšœžœ˜J˜Jšžœ˜J˜—J˜ J˜˜(Jšœ"ž˜$J˜—˜'Jšœ"ž˜$J˜—˜WJšœ#ž˜%J˜—˜*Jšœ"ž˜$J˜—˜J˜J˜—˜—J˜!J˜—˜*J˜!J˜—˜,J˜ J˜—˜J˜"J˜—šœLžœ^žœ™žœ˜κJ˜—J˜˜*J™"——…—FH