/********************************************************** /************** DIR STRUCTURES and CONSTANTS ************** /********************************************************** /**/ #include "node.h" /************** DIR API defines and types ****************** /*********************************************************** /**/ typedef struct { ULONG ulLT; ULONG ulTotal; } FRAC; typedef INT POS; #define posFirst 0 #define posLast 1 #define posDown 2 #define posFrac 3 #define fDIRNull 0 #define fDIRPurgeParent (1<<0) #define fDIRBackToFather (1<<1) #define fDIRNeighborKey (1<<2) #define fDIRPotentialNode (1<<3) #define fDIRAllNode (1<<4) #define fDIRAllPage (1<<5) #define fDIRReplace (1<<6) #define fDIRReplaceDuplicate (1<<7) #define fDIRDuplicate (1<<8) #define fDIRSpace (1<<9) #define fDIRVersion (1<<10) #define fDIRAppendItem (1<<12) #define fDIRDeleteItem (1<<13) #define fDIRLogColumnDiffs (1<<14) #define fDIRLogChunkDiffs (1<<15) #define fDIRNoLog (1<<16) #define fDIRNoVersion 0 #define fDIRNoMPLRegister (1<<17) /* item list nodes not versioned /**/ #define fDIRItemList fDIRPotentialNode struct _dib { POS pos; KEY *pkey; INT fFlags; }; #define itagOWNEXT 1 #define itagAVAILEXT 2 #define itagDATA 3 #define itagLONG 4 #define itagAUTOINC 5 #define PgnoFDPOfPfucb(pfucb) ((pfucb)->u.pfcb->pgnoFDP) #define PgnoRootOfPfucb(pfucb) ((pfucb)->u.pfcb->pgnoFDP) #define ItagRootOfPfucb(pfucb) itagDATA #define ErrDIRGetBookmark( pfucb, psrid ) \ ( PcsrCurrent( pfucb )->csrstat == csrstatOnCurNode || \ PcsrCurrent( pfucb )->csrstat == csrstatDeferGotoBookmark ? \ ( *psrid = PcsrCurrent( pfucb )->bm, JET_errSuccess ) : \ ErrERRCheck( JET_errNoCurrentRecord ) ) #define DIRGetBookmark( pfucb, psrid ) \ ( *((SRID *)psrid) = PcsrCurrent( pfucb )->bm ) #define DIRGotoBookmark DIRDeferGotoBookmark #ifdef PREREAD #define DIRDeferGotoBookmark( pfucb, bmT ) \ { \ FUCBResetPreread( pfucb ); \ PcsrCurrent( pfucb )->csrstat = csrstatDeferGotoBookmark; \ PcsrCurrent( pfucb )->bm = bmT; \ ( pfucb )->sridFather = sridNull; \ DIRSetRefresh( pfucb ); \ } #else #define DIRDeferGotoBookmark( pfucb, bmT ) \ { \ PcsrCurrent( pfucb )->csrstat = csrstatDeferGotoBookmark; \ PcsrCurrent( pfucb )->bm = bmT; \ ( pfucb )->sridFather = sridNull; \ DIRSetRefresh( pfucb ); \ } #endif // PREREAD #define DIRGotoBookmarkItem( pfucb, bmT, itemT ) \ { \ PcsrCurrent( pfucb )->csrstat = csrstatDeferGotoBookmark; \ PcsrCurrent( pfucb )->bm = bmT; \ PcsrCurrent( pfucb )->item = itemT; \ ( pfucb )->sridFather = sridNull; \ DIRSetRefresh( pfucb ); \ } #define DIRGotoPgnoItag( pfucb, pgnoT, itagT ) \ { \ PcsrCurrent( pfucb )->csrstat = csrstatOnCurNode; \ PcsrCurrent( pfucb )->bm = SridOfPgnoItag( (pgnoT), (itagT) ); \ PcsrCurrent( pfucb )->pgno = (pgnoT); \ PcsrCurrent( pfucb )->itag = (itagT); \ ( pfucb )->sridFather = sridNull; \ DIRSetRefresh( pfucb ); \ } #define DIRGotoFDPRoot( pfucb ) \ { \ PcsrCurrent( pfucb )->csrstat = csrstatOnFDPNode; \ PcsrCurrent( pfucb )->bm = \ SridOfPgnoItag( PgnoFDPOfPfucb( pfucb ), itagFOP ); \ PcsrCurrent( pfucb )->pgno = PgnoFDPOfPfucb( pfucb ); \ PcsrCurrent( pfucb )->itag = itagFOP; \ PcsrCurrent( pfucb )->itagFather = itagFOP; \ ( pfucb )->sridFather = sridNull; \ if ( !FBFReadAccessPage( pfucb, PcsrCurrent( pfucb )->pgno ) ) \ { \ if ( ErrBFReadAccessPage( pfucb, \ PcsrCurrent( pfucb )->pgno ) < 0 ) \ { \ DIRSetRefresh( pfucb ); \ } \ else \ { \ NDGet( pfucb, PcsrCurrent( pfucb )->itag ); \ DIRSetFresh( pfucb ); \ } \ } \ } #define DIRGotoOWNEXT( pfucb, pgnoT ) \ { \ DIRGotoPgnoItag( pfucb, pgnoT, itagOWNEXT ); \ Assert( ( pfucb )->sridFather == sridNull ); \ PcsrCurrent( pfucb )->itagFather = itagFOP; \ } #define DIRGotoAVAILEXT( pfucb, pgnoT ) \ { \ DIRGotoPgnoItag( pfucb, pgnoT, itagAVAILEXT ); \ PcsrCurrent( pfucb )->itagFather = itagFOP; \ } #define DIRGotoLongRoot( pfucb ) \ { \ PcsrCurrent( pfucb )->csrstat = csrstatOnCurNode; \ PcsrCurrent( pfucb )->bm = \ SridOfPgnoItag( PgnoFDPOfPfucb( pfucb ), itagLONG ); \ PcsrCurrent( pfucb )->pgno = PgnoFDPOfPfucb( pfucb ); \ PcsrCurrent( pfucb )->itag = itagLONG; \ PcsrCurrent( pfucb )->itagFather = itagNull; \ ( pfucb )->sridFather = sridNull; \ if ( !FBFReadAccessPage( pfucb, PcsrCurrent( pfucb )->pgno ) ) \ { \ if ( ErrBFReadAccessPage( pfucb, \ PcsrCurrent( pfucb )->pgno ) < 0 ) \ { \ DIRSetRefresh( pfucb ); \ } \ else \ { \ NDGet( pfucb, PcsrCurrent( pfucb )->itag ); \ DIRSetFresh( pfucb ); \ } \ } \ } #define DIRGotoDataRoot( pfucb ) \ { \ PcsrCurrent( pfucb )->csrstat = csrstatOnCurNode; \ PcsrCurrent( pfucb )->bm = \ SridOfPgnoItag( PgnoFDPOfPfucb( pfucb ), itagDATA ); \ PcsrCurrent( pfucb )->pgno = PgnoFDPOfPfucb( pfucb ); \ PcsrCurrent( pfucb )->itag = itagDATA; \ PcsrCurrent( pfucb )->itagFather = itagNull; \ ( pfucb )->sridFather = sridNull; \ if ( !FBFReadAccessPage( pfucb, PcsrCurrent( pfucb )->pgno ) ) \ { \ if ( ErrBFReadAccessPage( pfucb, \ PcsrCurrent( pfucb )->pgno ) < 0 ) \ { \ DIRSetRefresh( pfucb ); \ } \ else \ { \ NDGet( pfucb, PcsrCurrent( pfucb )->itag ); \ DIRSetFresh( pfucb ); \ } \ } \ } #define FDIRDataRootRoot( pfucb, pcsr ) \ ( (pcsr)->pgno == PgnoFDPOfPfucb( pfucb ) && \ (pcsr)->itag == ItagRootOfPfucb( pfucb ) ) #define DIRDeferMoveFirst( pfucb ) \ { \ PcsrCurrent( pfucb )->csrstat = csrstatDeferMoveFirst; \ DIRSetRefresh( pfucb ); \ } #define DIRSetIndexRange FUCBSetIndexRange #define DIRResetIndexRange FUCBResetIndexRange ERR ErrDIROpen( PIB *ppib, FCB *pfcb, DBID dbid, FUCB **ppfucb ); VOID DIRClose( FUCB *pfucb ); ERR ErrDIRDown( FUCB *pfucb, DIB *pdib ); ERR ErrDIRDownFromDATA( FUCB *pfucb, KEY *pkey ); VOID DIRUp( FUCB *pfucb, INT ccsr ); ERR ErrDIRNext( FUCB *pfucb, DIB *pdib ); ERR ErrDIRPrev( FUCB *pfucb, DIB *pdib ); ERR ErrDIRGet( FUCB *pfucb ); ERR ErrDIRCheckIndexRange( FUCB *pfucb ); ERR ErrDIRGetBMOfItemList( FUCB *pfucb, SRID *pbmItemList ); ERR ErrDIRGetWriteLock( FUCB *pfucb ); ERR ErrDIRInsert( FUCB *pfucb, LINE *pline, KEY *pkey, INT fFlags ); ERR ErrDIRInitAppendItem( FUCB *pfucb ); ERR ErrDIRAppendItem( FUCB *pfucb, LINE *pline, KEY *pkey, SRID sridPrev ); ERR ErrDIRTermAppendItem( FUCB *pfucb ); ERR ErrDIRCreateDirectory( FUCB *pfucb, CPG cpgMin, PGNO *ppgnoFDP ); #define ErrDIRDeleteDirectory( pfucb, pgnoFDP ) ErrSPFreeFDP( pfucb, pgnoFDP ) ERR ErrDIRDelete( FUCB *pfucb, INT fFlags ); ERR ErrDIRReplace( FUCB *pfucb, LINE *pline, INT fFlags ); ERR ErrDIRReplaceKey( FUCB *pfucb, KEY *pkeyTo, INT fFlags ); ERR ErrDIRDownKeyBookmark( FUCB *pfucb, KEY *pkey, SRID srid ); ERR ErrDIRGetPosition( FUCB *pfucb, ULONG *pulLT, ULONG *pulTotal ); ERR ErrDIRGotoPosition( FUCB *pfucb, ULONG ulLT, ULONG ulTotal ); ERR ErrDIRIndexRecordCount( FUCB *pfucb, ULONG *pulCount, ULONG ulCountMost, BOOL fNext ); ERR ErrDIRComputeStats( FUCB *pfucb, INT *pcitem, INT *pckey, INT *pcpage ); ERR ErrDIRDelta( FUCB *pfucb, INT iDelta, INT fFlags ); ERR ErrDIRBeginTransaction( PIB *ppib ); ERR ErrDIRRefreshTransaction( PIB *ppib ); ERR ErrDIRCommitTransaction( PIB *ppib, JET_GRBIT grbit ); VOID DIRPurge( PIB *ppib ); ERR ErrDIRRollback( PIB *ppib ); #define DIRBeforeFirst( pfucb ) ( PcsrCurrent(pfucb)->csrstat = csrstatBeforeFirst ) #define DIRAfterLast( pfucb ) ( PcsrCurrent(pfucb)->csrstat = csrstatAfterLast ) #define FDIRMostRecent FBTMostRecent #define FDIRDelta FVERDelta ERR ErrDIRDump( FUCB *pfucb, INT cchIndent ); /********************************************************** /******************* DIR Internal ************************* /********************************************************** /**/ #define itagFOP 0 #define cbSonMax 256 #define qwDBTimeNull 0xffffffffffffffff #define itagDIRDVSplitL 1 #define itagDIRDVSplitR 2 /* maximum node data size for nodes which ErrNDDelta can be used on. /* Specifically this minimally supports long value root nodes. /**/ #define cbMaxCounterNode 8 /* Offset of data field to counter. for long field reference counter. **/ #define ibCounter 0 /* non-clustered index cursors already have item stored. /**/ #ifdef DEBUG #define CheckCSR( pfucb ) Assert( fRecovering || \ (PcsrCurrent(pfucb) == pcsrNil || \ PcsrCurrent(pfucb)->pcsrPath == pcsrNil || \ PcsrCurrent(pfucb)->pgno != PcsrCurrent(pfucb)->pcsrPath->pgno || \ PcsrCurrent(pfucb)->itag != PcsrCurrent(pfucb)->pcsrPath->itag ) ); #define DIRSetFresh( pfucb ) \ { \ Assert( PcsrCurrent( pfucb )->csrstat == csrstatOnCurNode || \ PcsrCurrent( pfucb )->csrstat == csrstatBeforeCurNode || \ PcsrCurrent( pfucb )->csrstat == csrstatAfterCurNode || \ PcsrCurrent( pfucb )->csrstat == csrstatOnFDPNode ); \ AssertNDGet( pfucb, PcsrCurrent( pfucb )->itag ); \ PcsrCurrent( pfucb )->qwDBTime = QwSTDBTimePssib( &(pfucb)->ssib ); \ } #define DIRSetRefresh( pfucb ) \ { \ Assert( PcsrCurrent( pfucb )->csrstat == csrstatOnCurNode || \ PcsrCurrent( pfucb )->csrstat == csrstatBeforeCurNode || \ PcsrCurrent( pfucb )->csrstat == csrstatAfterCurNode || \ PcsrCurrent( pfucb )->csrstat == csrstatOnFDPNode || \ PcsrCurrent( pfucb )->csrstat == csrstatDeferGotoBookmark || \ PcsrCurrent( pfucb )->csrstat == csrstatDeferMoveFirst || \ PcsrCurrent( pfucb )->csrstat == csrstatOnDataRoot ); \ PcsrCurrent( pfucb )->qwDBTime = qwDBTimeNull; \ } #else #define CheckCSR( pfucb ) #define DIRSetFresh( pfucb ) \ { \ PcsrCurrent( pfucb )->qwDBTime = QwSTDBTimePssib( &(pfucb)->ssib ); \ } #define DIRSetRefresh( pfucb ) \ { \ PcsrCurrent( pfucb )->qwDBTime = qwDBTimeNull; \ } #endif /********************************************************** /********************* BTREE API ************************** /********************************************************** /**/ #define sridMin 0 #define sridMax 0xffffffff /* must be on node, i.e. on current node, before node or after node. /* Node must be in line cache. /**/ #define DIRISetBookmark( pfucb, pcsr ) \ { \ AssertFBFReadAccessPage( (pfucb), (pcsr)->pgno ); \ \ if ( FNDBackLink( *( (pfucb)->ssib.line.pb ) ) ) \ (pcsr)->bm = *(SRID UNALIGNED *)PbNDBackLink( (pfucb)->ssib.line.pb ); \ else \ (pcsr)->bm = SridOfPgnoItag( (pcsr)->pgno, (pcsr)->itag ); \ } BOOL FBTMostRecent( FUCB *pfucb ); #define ErrBTNext( pfucb, pdib ) \ ( ErrBTNextPrev( pfucb, PcsrCurrent(pfucb), fTrue, pdib, NULL ) ) #define ErrBTPrev( pfucb, pdib ) \ ( ErrBTNextPrev( pfucb, PcsrCurrent(pfucb), fFalse, pdib, NULL ) ) #define BTUp( pfucb ) FUCBFreeCSR( pfucb ) ERR ErrBTGet( FUCB *pfucb, CSR *pcsr ); ERR ErrBTGetNode( FUCB *pfucb, CSR *pcsr ); #ifdef DEBUG VOID AssertBTGetNode( FUCB *pfucb, CSR *pcsr ); #else #define AssertBTGetNode #endif ERR ErrBTSetNodeHeader( FUCB *pfucb, BYTE bHeader ); ERR ErrBTReplaceKey( FUCB *pfucb, KEY *pkey, INT fFlags ); ERR ErrBTDown( FUCB *pfucb, DIB *pdib ); ERR ErrBTDownFromDATA( FUCB *pfucb, KEY *pkey ); ERR ErrBTNextPrev( FUCB *pfucb, CSR *pcsr, INT fNext, DIB *pdib, BOOL *pfEmptyPage ); ERR ErrBTSeekForUpdate( FUCB *pfucb, KEY *pkey, PGNO pgno, INT itag, INT fDIRFlags ); ERR ErrBTInsert( FUCB *pfucb, INT fHeader, KEY *pkey, LINE *pline, INT fDIRFlags, BOOL *pfCleaned ); ERR ErrBTReplace( FUCB *pfucb, LINE *pline, INT fFlags, BOOL *pfCleaned ); ERR ErrBTDelete( FUCB *pfucb, INT fFlags ); ERR ErrBTMakeRoom( FUCB *pfucb, CSR *pcsrRoot, INT cbReq ); ERR ErrBTGetPosition( FUCB *pfucb, ULONG *pulLT, ULONG *pulTotal ); ERR ErrBTGotoBookmark( FUCB *pfucb, SRID srid ); ERR ErrBTGetInvisiblePagePtr( FUCB *pfucb, SRID sridFather ); #ifdef DEBUG ERR ErrBTCheckInvisiblePagePtr( FUCB *pfucb, SRID sridFather ); #endif #ifdef DEBUG VOID BTCheckSplit( FUCB *pfucb, CSR *pcsr ); #else #define BTCheckSplit( pfucb, pcsr ) #endif /********************************************************** /*********************** BT Split ************************* /********************************************************** /**/ typedef enum { splittNull, splittVertical, splittDoubleVertical, splittLeft, splittRight, splittAppend } SPLITT; typedef enum { opReplace, opInsert } OPERATION; typedef struct { PN pn; QWORD qwDBTime; } LFINFO; /* leaf split info */ typedef struct { SRID sridNew; SRID sridBackLink; } BKLNK; typedef struct _split { PIB *ppib; PGNO pgnoSplit; PGNO pgnoNew; PGNO pgnoNew2; PGNO pgnoNew3; PGNO pgnoSibling; BF *pbfSplit; /* BF of page being split */ BF *pbfNew; /* BF of new page of this split */ BF *pbfNew2; /* BF of new page of this split */ BF *pbfNew3; /* BF of new page of this split */ BF *pbfSibling; /* BF of sibling page of this H split */ BF *pbfPagePtr; BOOL fNoRedoNew; /* no need to redo new page */ BOOL fNoRedoNew2; /* no need to redo new page 2 */ BOOL fNoRedoNew3; /* no need to redo new page 3 */ BF **rgpbf; /* BF of backlink page. */ INT cpbf; INT cpbfMax; BKLNK *rgbklnk; /* SRID of backlinks. */ INT cbklnk; INT cbklnkAlloc; INT cbklnkMax; QWORD qwDBTimeRedo; /* redo timestamp */ INT itagSplit; INT ibSon; KEY key; KEY keyMac; SPLITT splitt; BOOL fLeaf; OPERATION op; BOOL fFDP; DBID dbid; INT itagNew; INT itagPagePointer; BYTE rgbSonSplit[cbSonMax]; BYTE rgbSonNew[cbSonMax]; BYTE rgbkeyMac[JET_cbKeyMost]; BYTE rgbKey[JET_cbKeyMost]; /* mapping from old to new tags for use in MCM /**/ BYTE mpitag[ctagMax]; INT ipcsrMac; /* preallocated resource for csr */ #define ipcsrSplitMax 4 CSR *rgpcsr[ipcsrSplitMax]; } SPLIT; typedef struct _rmpage { PIB *ppib; QWORD qwDBTimeRedo; /* redo timestamp */ BF *pbfLeft; BF *pbfRight; BF *pbfFather; BKLNK **rgbklnk; /* latched buffers required for rmpage */ INT cbklnk; INT cbklnkMax; BF **rgpbf; /* latched buffers required for rmpage */ INT cpbf; INT cpbfMax; PGNO pgnoRemoved; PGNO pgnoLeft; PGNO pgnoRight; PGNO pgnoFather; INT itagPgptr; INT itagFather; INT ibSon; DBID dbid; } RMPAGE; #define CbFreeDensity(pfucb) \ ( (pfucb)->u.pfcb != pfcbNil ? (INT)(pfucb)->u.pfcb->cbDensityFree : 0 ) /* protypes for split used by recovery of split operations. /**/ ERR ErrBTStoreBackLinkBuffer( SPLIT *psplit, BF *pbf, BOOL *pfAlreadyLatched ); ERR ErrBTSplit( FUCB *pfucb, INT cbNode, INT cbReq, KEY *pkey, INT fFlags ); ERR ErrBTSplitPage( FUCB *pfucb, CSR *pcsr, CSR *pcsrRoot, KEY keySplit, INT cbNode, INT cbReq, BOOL fReplace, BOOL fAppendPage ); BOOL FBTSplit( SSIB *pssib, INT cbReq, INT citagReq ); BOOL FBTAppendPage( FUCB *pfucb, CSR *pcsr, INT cbReq, INT cbPageAdjust, INT cbFreeDensity, INT citagReq ); INT CbBTFree( FUCB *pfucb, INT cbFreeDensity ); #define fAllocBufOnly fTrue #define fDoMove fFalse ERR ErrBTSplitVMoveNodes( FUCB *pfucb, FUCB *pfucbNew, SPLIT *psplit, CSR *pcsr, BYTE *rgb, BOOL fNoMove); ERR ErrBTSplitDoubleVMoveNodes( FUCB *pfucb, FUCB *pfucbNew, FUCB *pfucbNew2, FUCB *pfucbNew3, SPLIT *psplit, CSR *pcsr, BYTE *rgb, BOOL fNoMove); ERR ErrBTSplitHMoveNodes( FUCB *pfucb, FUCB *pfucbNew, SPLIT *psplit, BYTE *rgb, BOOL fNoMove); ERR ErrBTInsertPagePointer( FUCB *pfucb, CSR *pcsrPagePointer, SPLIT *psplit, BYTE *rgb ); ERR ErrBTCorrectLinks( SPLIT *psplit, FUCB *pfucb, SSIB *pssib, SSIB *pssibNew); VOID BTReleaseSplitBfs ( BOOL fRedo, SPLIT *psplit, ERR err ); VOID BTReleaseRmpageBfs( BOOL fRedo, RMPAGE *prmpage ); ERR ErrBTMoveSons( SPLIT *psplit, FUCB *pfucb, FUCB *pfucbNew, INT itagSonTable, BYTE *rgbSon, BOOL fVisibleSons, BOOL fNoMove, BKLNK *pbklnk, INT cbklnk ); ERR ErrBTSetUpSplitPages( FUCB *pfucb, FUCB *pfucbNew, FUCB *pfucbNew2, FUCB *pfucbNew3, SPLIT *psplit, PGTYP pgtyp, BOOL fAppend, BOOL fSkipMoves ); ERR ErrBTAbandonEmptyPage( FUCB *pfucb, KEY *pkey ); /********************************************************** /********** MCM STRUCTURES, CONSTANTS and API ************* /********************************************************** /**/ #define opInsertItem 0 #define opDeleteItem 1 #define opSplitItemList 2 #define opInsertSon 0 #define opReplaceSon 1 #define opDeleteSon 2 #define opHorizontalRightSplitPage 0 #define opHorizontalLeftSplitPage 1 #define opVerticalSplitPage 0 VOID MCMRightHorizontalPageSplit( FUCB *pfucb, PGNO pgnoSplit, PGNO pgnoRight, INT ibSonSplit, BYTE *mpitag ); VOID MCMLeftHorizontalPageSplit( FUCB *pfucb, PGNO pgnoSplit, PGNO pgnoNew, INT ibSonSplit, BYTE *mpitag ); VOID MCMVerticalPageSplit( FUCB *pfucb, BYTE *mpitag, PGNO pgnoSplit, INT itagSplit, PGNO pgnoNew, SPLIT *psplit ); VOID MCMDoubleVerticalPageSplit( FUCB *pfucb, BYTE *mpitag, PGNO pgnoSplit, INT itagSplit, INT ibSonDivision, PGNO pgnoNew, PGNO pgnoNew2, PGNO pgnoNew3, SPLIT *psplit ); VOID MCMInsertPagePointer( FUCB *pfucb, PGNO pgnoFather, INT itagFather ); VOID MCMBurstIntrinsic( FUCB *pfucb, PGNO pgnoFather, INT itagFather, PGNO pgnoNew, INT itagNew ); #define FFUCBRecordCursor( pfucb ) ( \ ( pfucb )->u.pfcb != pfcbNil ? \ FFCBClusteredIndex( ( pfucb )->u.pfcb ) : fFalse ) #ifdef NOLOG /* logging disabled */ #define ErrLGSplitL( ppib, pcsrPagePointer, psplit, pgtyp ) 0 #define ErrLGSplitR( ppib, pcsrPagePointer, psplit, pgtyp ) 0 #define ErrLGSplitV( ppib, psplit, pgtyp ) 0 #define ErrLGAddendR( pfucb, pcsrPagePointer, psplit, newpagetype ) 0 #else ERR ErrLGSplitL( FUCB *pfucb, CSR *pcsrPagePointer, SPLIT *psplit, PGTYP newpagetype ); ERR ErrLGSplitR( FUCB *pfucb, CSR *pcsrPagePointer, SPLIT *psplit, PGTYP newpagetype ); ERR ErrLGSplitV( FUCB *pfucb, SPLIT *psplit, PGTYP newpagetype ); ERR ErrLGAddendR( FUCB *pfucb, CSR *pcsrPagePointer, SPLIT *psplit, PGTYP newpagetype ); #endif