DIRECTORY AlpineEnvironment USING [LockOption], DBCommon, Rope USING [ROPE]; DBSegment: CEDAR DEFINITIONS = BEGIN ROPE: TYPE = Rope.ROPE; Trans: TYPE = DBCommon.Transaction; Segment: TYPE = DBCommon.Segment; SegmentID: TYPE = DBCommon.SegmentID; SegmentIndex: TYPE = DBCommon.SegmentIndex; VersionOptions: TYPE = DBCommon.VersionOptions; DBPage: TYPE = DBCommon.DBPage; CacheHandle: TYPE = DBCommon.CacheHandle; TID: TYPE = DBCommon.TID; Initialize: PROC [nCachePages: NAT, useCacheFile: ROPE, segmentInitProc: PROC [s: Segment] RETURNS [ARRAY[0..DBCommon.systemIndexCount) OF TID]]; AttachSegment: PROC [fileName: ROPE, s: Segment, segmentIndex: SegmentIndex, lock: AlpineEnvironment.LockOption, readonly: BOOL, version: VersionOptions, nPagesInitial, nPagesPerExtent: NAT] RETURNS[newAttachement: BOOL]; EnumerateSegments: PROC [enumProc: PROC [s: Segment, segmentIndex: SegmentIndex] RETURNS [stop: BOOL]]; OpenSegment: PROC [s: Segment, trans: Trans, eraseAfterOpening: BOOL]; CloseSegment: PROC [s: Segment]; GetSegmentInfo: PROC [s: Segment] RETURNS [filePath: ROPE, readOnly: BOOL]; WriteOutCache: PROC[s: Segment]; FlushCache: PROC[s: Segment]; GetVersionStamp: PROC [segment: Segment] RETURNS[schemaVersion: INT]; SetVersionStamp: PROC [segment: Segment, to: INT]; RootIndicesFromSegment: PROC [s: Segment] RETURNS [indexTIDs: ARRAY[0..DBCommon.systemIndexCount) OF TID]; SegmentFromTID: PROC [tid: TID] RETURNS [s: Segment]; IsValidTID: PROC [tid: TID] RETURNS [valid: BOOL]; SegmentIDFromDBPage: PROC [p: DBPage] RETURNS [SegmentID]; SegmentIDFromSegment: PROC [s: Segment] RETURNS [SegmentID]; AllocPage: PROC [s: SegmentID] RETURNS [p: DBPage, pValidHint: CacheHandle, cachePage: LONG POINTER]; FreePage: PROC [s: SegmentID, freePg: DBPage, freeHint: CacheHandle]; ReadPage: PROC [p: DBPage, pHint: CacheHandle] RETURNS [pValidHint: CacheHandle, coreLoc: LONG POINTER]; WritePage: PROC [p: DBPage, pHint: CacheHandle] RETURNS [pValidHint: CacheHandle, coreLoc: LONG POINTER]; UnlockPage: PROC [pValidHint: CacheHandle]; WriteLockedPage: PROC [pValidHint: CacheHandle]; LockCount: PROC [p: DBPage, pValidHint: CacheHandle] RETURNS [lockCount: CARDINAL]; ObtainCoreLoc: PROC [p: DBPage, pValidHint: CacheHandle] RETURNS [coreLoc: LONG POINTER]; CheckState: PROC [doPrinting, printOnlyLockedPages: BOOL]; END. -- DBSegment CHANGE LOG Created by MBrown on January 4, 1980 3:31 PM Changed by MBrown on January 14, 1980 2:29 PM Changed by MBrown on February 4, 1980 3:44 PM Changed by MBrown on February 21, 1980 10:20 AM Changed by MBrown on February 21, 1980 1:38 PM Changed by MBrown on February 29, 1980 10:33 AM Changed by MBrown on March 3, 1980 1:36 PM Changed by MBrown on April 16, 1980 4:42 PM Changed by MBrown on April 18, 1980 11:34 AM Changed by MBrown on June 10, 1980 8:46 PM Changed by MBrown on August 5, 1980 8:49 PM Changed by MBrown on August 29, 1980 3:34 PM Changed by MBrown on September 12, 1980 11:07 AM Changed by MBrown on December 8, 1980 3:46 PM Changed by MBrown on December 11, 1980 6:54 PM Changed by MBrown on February 26, 1981 9:11 PM Changed by MBrown on 19-Jun-81 8:51:33 Changed by Willie-Sue on June 24, 1982 12:12 pm Changed by MBrown on November 24, 1982 4:18 pm Changed by Cattell on January 16, 1983 12:41 pm Changed by Willie-Sue on February 3, 1983 10:38 am Changed by Willie-Sue on February 15, 1985 Changed by Donahue on October 23, 1985 ŠFile DBSegment.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by MBrown on December 16, 1982 2:37 pm Willie-Sue on March 25, 1985 9:15:02 am PST Cattell, July 15, 1983 2:48 pm Widom, September 3, 1985 3:24:30 pm PDT Donahue, May 22, 1986 11:10:53 am PDT This is the interface to databases at the level of segments. A database has a uniform address space, but within this space live "segments" which are the repositories of database pages. Thus it is possible to allocate a page from a segment, or free a previously allocated page. Initialization Initializes the database system at the segment level. Use nCachePages pages for cache size. Call segmentInitProc when creating a new segment. Segment interface This may only be done for segments that are closed (a segment is closed when a FlushCache is performed on the segment) or have not been previously opened. This procedure returns TRUE iff the fileName supplied was not that of the previous AttachSegment for the same segment Open the segment using the given transaction. The transaction is used to open the file that was named by the prior AttachSegment Force out all dirty cached pages for the segment Throw away all cached (dirty or not) pages for the segment. This also closes the open file for the segment. Operations on the head page of a segment Returns the current schema version stamp for the given segment. This also sets a read lock on the schema version stamp, which will be held until the transaction for the segment is aborted or closed Called when the schema for the given segment is changed; updates the schema version stamp. "tid" is a tuple ID in an attached segment. Returns the name of the segment. "tid" is a tuple ID in an attached segment. Returns TRUE iff the segment is open. "p" is a page in an open segment. Returns the first page in the segment. s is an attached segment. Returns the first page in the segment. Page allocation PARAMETERS: s is a SegmentID (a pointer to the head page of a segment). RESULTS: p is a previously unused page within segment s, with pValidHint a cache hint and cachePage a cache pointer for it. pValidHint ha a lock count of 1. ERRORS: if s does not identify a segment, if the file representing s is full, or if the database address space is full. NOTES: AllocPage does NOT necessarily read the page p from Juniper. PARAMETERS: s is a SegmentID (result of SegmentIDFromDBPage or SegmentIDFromFile), and freePg is a page within that segment (with freeHint a cache hint for it). The lock count of freeHint is 1. EFFECTS: FreePage makes freePg unused, and freeHint becomes meaningless. ERRORS: if s is not a SegmentID, or if freePg is not in s. NOTES: If references to freePg still exist, they become "dangling". Errors of this kind may go undetected, since freed pages are reused. Page access Definition: A "valid" cache hint for a DBPage p is a DBCache.CacheHandle for p, with a positive lock count. Note that when a cache hint becomes invalid (lock count reaches zero), it is an error to use any core location derived from the hint. PARAMETERS: p is a page address in the current database, and pHint is a cache hint for it. RESULTS: pValidHint is a valid cache hint for p, and coreLoc is a pointer to the data contained on page p. The caller may read data from the page using this pointer, for as long as pValidHint has a positive lock count. EFFECTS: the lock count of pValidHint is increased by 1 (the count is implicitly zero before the first reference to the page). ERRORS: DBException.Fatal[AllCachePagesLocked] if it is necessary to read p into core, and there are no unlocked pages in the cache to read p into. The same as ReadPage, except that the caller may also write the data pointed to by coreLoc (i.e. it sets the write-dirty bit in pValidHint). ERRORS: DBException.Fatal[AccessDenied] if this page cannot be written back to the file system. EFFECTS: Decrements pValidHint's lock count by one. ERRORS: DBException.InternalBug[AlreadyUnlocked] if the count was already zero. PARAMETERS: pValidHint is a CacheHandle with a positive lock count. EFFECTS: the write-dirty bit of pValidHint is set. ERRORS: If pValidHint's lock count is 0 then DBException.InternalBug is raised. If the page is protected from writing (cannot be written back to the file system) then DBException.Fatal[AccessDenied] is raised. NOTES: The effect of WriteLockedPage is the same as WritePage; UnlockPage, except that the page must be locked beforehand. The effect of WritePage is identical to [pValidHint, coreLoc] _ ReadPage[p, pHint]; WriteLockedPage[pValidHint]. PARAMETERS: p is a page address in the current database, and pValidHint is a valid cache hint for it. RESULTS: the lock count of page p. ERRORS: DBException.BadOperaton[??] is raised if pHint is not a valid cache handle for page p. This includes pHint having a lock count of 0. NOTES: This routine is intended for use in debugging only, especially for checking assertions like "p now has lock count 1, so calling UnlockPage will release it." Programs should not intentionally lose track of the lock count of a page and then use this procedure to release the page. PARAMETERS: p is a page address in the current database, and pValidHint is a valid cache hint for it. RETURNS: The core location of the page p. ERRORS: DBException.BadOperaton[??] is raised if pHint is not a valid cache handle for page p. This includes pHint having a lock count of 0. NOTES: The parameter pHint is for efficiency, to avoid a hashed lookup when the hint is known to be valid. When the validity of the hint is uncertain, ReadPage should be used instead of ObtainCoreLoc. Debugging Checks internal consistency of segment implementation, optionally prints to the debug stream. Changed module name to conform to Cedar standard. Changed name of GetSegmentID to FileIDToSegmentID; added DBPageToSegmentID. Added procedures ReadPage, WritePage, ... ObtainFile. The intention is to make segments a true "level", i.e. the storage level will no longer communicate directly with the cache level. Also changed definition of AllocPage to return a locked page. Made AllocPage return the LONG POINTER to the locked page. Added LockCountOfPage. Added OpenDatabase, etc, to complete the isolation between the segment and storage levels. Changed CreateDatabase and OpenDatabase to allow root indexes to be created. Changed LockCountOfPage to LockCount, added ObtainCoreLoc. Worked on comments. TID now comes from DBCommon. Clarified the specifications of CloseDatabase and CloseCommunication. Responsibility for performing the former immediately before the latter is now delegated to the client. Added server parm and welcomeText result to OpenCommunication. Added Finalize, added comments about sequencing of Segment interface calls. Added nBytesInitial and nBytesPerExtent parms to CreateSegment. Flushed RegisterUser, added parms to OpenCommunication. Changed Commit to CommitTransaction. Flushed SetTransactionNotifyProcedure. Redefined OpenCommunication: server is used to decide what file system to use. Transaction is UNSPECIFIED. newTrans parm added. STRING -> Rope.Ref. Rope.Ref => Rope.ROPE Changes to enable independent segments. Added useCacheFile arg to Initialize. Added noLog arg to OpenTransaction. nBytes => nPages; added Tioga formatting, made Cedar Moved transaction management out of the interface and into DBStorage. Added WriteOutCache and FlushCache to interface (that's the only part of DBSegment that is needed to manage transactions.) Ê·˜šœ™J™<—Jšœ™Jšœ#™#Jšœ+™+Jšœ™™'Icode™%—J˜šÏk ˜ Jšœœ˜%J˜ Jšœœœ˜J˜—Jšœ œ œ˜$˜Jšœœœ˜Jšœœ˜#Jšœ œ˜!Jšœ œ˜%Jšœœ˜+Jšœœ˜/Jšœœ˜Jšœ œ˜)Jšœœ œ˜J˜J˜Jšœ–™–Ihead1šœ™J˜šÏn œœœœ˜7Jš œœœœœœ˜YJšœŽ™Ž—Lšœ™šž œœ œXœ;œœœ˜ÝJšœ‘™‘J˜—š žœœ œ*œœ˜gJ˜—šž œœ/œ˜FJšœ™J˜—Kšž œœ˜ K˜š žœœœ œ œ˜KJ˜—šž œœ ˜ Jšœ0™0—J˜šž œœ ˜Jšœm™m—L™(šžœœœœ˜EJ™ÆJ™—šžœœœ˜2J™ZJ™—Jš žœœœ œœœ˜jJ˜šžœœœœ˜5JšœM™MJ˜—š ž œœœœ œ˜2JšœR™RJ˜—šžœœ œ ˜:JšœI™IJ˜—šžœœœ ˜™>J˜Jšœ/˜1JšœK™KJ˜Jšœ,˜.Jšœ?™?J˜Jšœ-˜/Jšœ]™]Jšœ'™'J˜Jšœ-˜/Jšœ^™^Jšœ#™#J˜J˜'Jšœ™J˜J˜/Jšœ™J˜J˜.Jšœ'™'J˜J˜/Jšœ%™%J˜J˜2Jšœ#™#J™J˜*J™5J˜J˜&J™Á—…— †1Ç