243 lines
7.6 KiB
C
243 lines
7.6 KiB
C
//
|
||
//------ Page Structure ---------------------------------------------------
|
||
//
|
||
|
||
#define cbPage 4096 // database logical page size
|
||
|
||
#define cbSec 4096 // minimum disk Read/Write unit. It
|
||
// should be 512, but MIPS NT cache
|
||
// bug force it be 1024.
|
||
|
||
#define ctagMax 256 // default limit on number of tags
|
||
|
||
#define fNoTagLimit (1<<0) // ignore limit on number of tags
|
||
#define fUseNewTag (1<<1) // don't reuse tags
|
||
|
||
typedef BYTE PGTYP;
|
||
|
||
// the pragma is bad for efficiency, but we need it here so that the
|
||
// THREEBYTES will not be aligned on 4-byte boundary
|
||
#pragma pack(1)
|
||
|
||
typedef struct _pghdr
|
||
{
|
||
ULONG ulChecksum; // checksum of page, always 1st byte
|
||
ULONG ulDBTime; // dbCounter when page was dirtied
|
||
PGNO pgnoFDP; // pgno of FDP which owns this page
|
||
SHORT cbFreeTotal; // total free bytes
|
||
SHORT ibLastUsed; // lower bound on used bytes
|
||
SHORT ctagMac; // upper bound on used tags
|
||
SHORT itagFree; // start of tag free tags
|
||
SHORT cVersion; // count of nodes with fVersion flag set
|
||
THREEBYTES pgnoPrev; // pgno of previous page
|
||
THREEBYTES pgnoNext; // pgno of next page
|
||
} PGHDR;
|
||
|
||
typedef struct _pgtrlr
|
||
{
|
||
PGTYP pgtyp;
|
||
THREEBYTES pgnoThisPage;
|
||
} PGTRLR;
|
||
|
||
typedef struct _tag
|
||
{
|
||
SHORT cb;
|
||
SHORT ib;
|
||
} TAG;
|
||
|
||
/* tag status
|
||
/**/
|
||
typedef enum { tsLine, tsVacant, tsLink } TS;
|
||
|
||
typedef struct _page
|
||
{
|
||
PGHDR pghdr;
|
||
TAG rgtag[1];
|
||
BYTE rgbFiller[ cbPage -
|
||
sizeof(PGHDR) - // pghdr
|
||
sizeof(TAG) - // rgtag[1]
|
||
sizeof(BYTE) - // rgbData[1]
|
||
sizeof(PGTYP) - // pgtyp
|
||
sizeof(THREEBYTES) ]; // pgnoThisPage
|
||
BYTE rgbData[1];
|
||
PGTYP pgtyp;
|
||
THREEBYTES pgnoThisPage;
|
||
} PAGE;
|
||
|
||
#pragma pack()
|
||
|
||
#define bitModified (1<<7)
|
||
#define bitLink (1L<<31)
|
||
|
||
#define pgtypFDP ((PGTYP) 0)
|
||
#define pgtypRecord ((PGTYP) 1)
|
||
// #define pgtypLong ((PGTYP) 2)
|
||
// #define pgtypNonrecord ((PGTYP) 3)
|
||
#define pgtypSort ((PGTYP) 4)
|
||
|
||
#define PMSetPageType( ppage, pgtypT ) ( (ppage)->pgtyp = pgtypT )
|
||
#define PgtypPMPageTypeOfPage( ppage ) ((PGTYP)((ppage)->pgtyp & ~(bitModified)))
|
||
|
||
#ifdef DEBUG
|
||
VOID PMSetModified( SSIB *ssib );
|
||
VOID PMResetModified( SSIB *pssib );
|
||
VOID CheckPgno( PAGE *ppage, PN pn );
|
||
#else
|
||
#define CheckPgno( ppage, pn )
|
||
#define PMSetModified( pssib ) ( (pssib)->pbf->ppage->pgtyp |= bitModified )
|
||
#define PMResetModified( pssib ) ( (pssib)->pbf->ppage->pgtyp &= ~(bitModified) )
|
||
#endif
|
||
|
||
#define PgtypPMSetModified( ppage ) ( (ppage)->pgtyp | bitModified )
|
||
#define FPMModified( ppage ) ( (ppage)->pgtyp & bitModified )
|
||
|
||
#define PMSetPgnoFDP( ppage, pgnoT ) ( (ppage)->pghdr.pgnoFDP = pgnoT )
|
||
#define PgnoPMPgnoFDPOfPage( ppage ) ( (ppage)->pghdr.pgnoFDP )
|
||
|
||
#define PMIncVersion( ppage ) ( (ppage)->pghdr.cVersion++ )
|
||
#if 0
|
||
#define PMDecVersion( ppage ) \
|
||
{ \
|
||
Assert( (ppage)->pghdr.cVersion > 0 ); \
|
||
(ppage)->pghdr.cVersion--; \
|
||
}
|
||
#else
|
||
#define PMDecVersion( ppage ) \
|
||
{ \
|
||
if ( (ppage)->pghdr.cVersion > 0 ) \
|
||
--(ppage)->pghdr.cVersion; \
|
||
}
|
||
#endif
|
||
|
||
#define SetPgno( ppage, pgno ) \
|
||
ThreeBytesFromL( (ppage)->pgnoThisPage, (pgno) )
|
||
#define SetPgnoNext( ppage, pgno ) \
|
||
ThreeBytesFromL( (ppage)->pghdr.pgnoNext, (pgno) )
|
||
#define SetPgnoPrev( ppage, pgno ) \
|
||
ThreeBytesFromL( (ppage)->pghdr.pgnoPrev, (pgno) )
|
||
|
||
#define PgnoFromPage( ppage, ppgno ) \
|
||
LFromThreeBytes( *(ppgno), (ppage)->pgnoThisPage )
|
||
|
||
#ifdef DEBUG
|
||
#define PgnoNextFromPage( pssib, ppgno ) \
|
||
{ CheckSSIB( pssib ); LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoNext ); }
|
||
#define PgnoPrevFromPage( pssib, ppgno ) \
|
||
{ CheckSSIB( (pssib) ); LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoPrev ) }
|
||
#else
|
||
#define PgnoNextFromPage( pssib, ppgno ) \
|
||
LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoNext )
|
||
#define PgnoPrevFromPage( pssib, ppgno ) \
|
||
LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoPrev )
|
||
#endif
|
||
|
||
#define absdiff( x, y ) ( (x) > (y) ? (x)-(y) : (y)-(x) )
|
||
#define pgdiscont( pgno1, pgno2 ) \
|
||
( ( (pgno1) == 0 ) || ( (pgno2) == 0 ) ? 0 \
|
||
: absdiff( (pgno1), (pgno2) ) / cpgDiscont )
|
||
|
||
#define ibPgnoPrevPage ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.pgnoPrev )
|
||
#define ibPgnoNextPage ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.pgnoNext )
|
||
#define ibCbFreeTotal ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.cbFreeTotal )
|
||
#define ibCtagMac ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.ctagMac )
|
||
#define ibPgtyp ( (INT) (ULONG_PTR)&((PAGE *)0)->pgtyp )
|
||
|
||
#define CbLastFreeSpace(ppage) \
|
||
((ppage)->pghdr.ibLastUsed \
|
||
- sizeof(PGHDR) \
|
||
- sizeof(TAG) * (ppage)->pghdr.ctagMac)
|
||
|
||
#define IbCbFromPtag( ibP, cbP, ptagP ) \
|
||
{ TAG *_ptagT = ptagP; \
|
||
(ibP) = _ptagT->ib; \
|
||
(cbP) = _ptagT->cb; \
|
||
}
|
||
|
||
#define PtagFromIbCb( ptagP, ibP, cbP ) \
|
||
{ TAG *_ptagT = ptagP; \
|
||
_ptagT->ib = (SHORT)(ibP); \
|
||
_ptagT->cb = (SHORT)(cbP); \
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
#define PMGet( pssib, itagT ) CallS( ErrPMGet( pssib, itagT ) )
|
||
#else
|
||
#define PMGet( pssib, itagT ) \
|
||
{ \
|
||
PAGE *ppageT_ = (pssib)->pbf->ppage; \
|
||
TAG *ptagT_ = &(ppageT_->rgtag[itagT]); \
|
||
Assert( itagT >= 0 ); \
|
||
Assert( itagT < (pssib)->pbf->ppage->pghdr.ctagMac ); \
|
||
(pssib)->line.pb = (BYTE *)ppageT_ + ptagT_->ib; \
|
||
(pssib)->line.cb = ptagT_->cb; \
|
||
}
|
||
#endif
|
||
|
||
#define ItagPMMost( ppage ) ((ppage)->pghdr.ctagMac - 1)
|
||
|
||
BOOL FPMFreeTag( SSIB *pssib, INT citagReq );
|
||
|
||
#ifdef DEBUG
|
||
#define CbPMFreeSpace( pssib ) ( CheckSSIB(pssib), \
|
||
((INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal) )
|
||
#else
|
||
#define CbPMFreeSpace( pssib ) ( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal )
|
||
#endif
|
||
|
||
#define ErrPMCheckFreeSpace( pssib, cbT ) \
|
||
( ((INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal) < cbT ? \
|
||
errPMOutOfPageSpace : JET_errSuccess )
|
||
|
||
#define PMAllocFreeSpace( pssib, cb ) \
|
||
{ \
|
||
Assert( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal >= cb ); \
|
||
(pssib)->pbf->ppage->pghdr.cbFreeTotal -= cb; \
|
||
}
|
||
|
||
#define PMFreeFreeSpace( pssib, cb ) \
|
||
{ \
|
||
Assert( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal >= 0 ); \
|
||
(pssib)->pbf->ppage->pghdr.cbFreeTotal += (SHORT)cb; \
|
||
Assert( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal < cbPage ); \
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
#define AssertBTFOP(pssib) \
|
||
Assert( PgtypPMPageTypeOfPage((pssib)->pbf->ppage) == pgtypSort || \
|
||
PgtypPMPageTypeOfPage((pssib)->pbf->ppage) == pgtypFDP || \
|
||
(pssib)->itag != 0 || \
|
||
( CbNDKey( (pssib)->line.pb ) == 0 && \
|
||
!FNDBackLink( *(pssib)->line.pb ) ) \
|
||
)
|
||
#else
|
||
#define AssertBTFOP( pssib )
|
||
#endif
|
||
|
||
#define PbPMGetChunk(pssib, ib) &(((BYTE *)((pssib)->pbf->ppage))[ib])
|
||
|
||
INT CbPMLinkSpace( SSIB *pssib );
|
||
TS TsPMTagstatus( PAGE *ppage, INT itag );
|
||
VOID PMNewPage( PAGE *ppage, PGNO pgno, PGTYP pgtyp, PGNO pgnoFDP );
|
||
INT ItagPMQueryNextItag( SSIB *pssib );
|
||
ERR ErrPMInsert( SSIB *pssib, LINE *rgline, INT cline );
|
||
VOID PMDelete( SSIB *ssib );
|
||
ERR ErrPMReplace( SSIB *pssib, LINE *rgline, INT cline );
|
||
ERR ErrPMGet( SSIB *pssib, INT itag );
|
||
VOID PMGetLink( SSIB *pssib, INT itag, LINK *plink );
|
||
VOID PMExpungeLink( SSIB *pssib );
|
||
VOID PMReplaceWithLink( SSIB *pssib, SRID srid );
|
||
VOID PMReplaceLink( SSIB *pssib, SRID srid );
|
||
INT CPMIFreeTag( PAGE *ppage );
|
||
BOOL FPMEmptyPage( SSIB *pssib );
|
||
BOOL FPMLastNodeToDelete( SSIB *pssib );
|
||
|
||
VOID PMDirty( SSIB *pssib );
|
||
VOID PMReadAsync( PIB *ppib, PN pn );
|
||
ERR ErrPMAccessPage( FUCB *pfucb, PGNO pgno );
|
||
|
||
#ifdef DEBUG
|
||
VOID PageConsistent( PAGE *ppage );
|
||
#endif
|
||
|
||
|