|
|
#ifndef NODE_INCLUDED
#define NODE_INCLUDED
typedef SRID ITEM;
#define citemMost 300
#define citemMax 301
#define citagSonMax ctagMax
#define cbFOPNoSon ( sizeof(TAG) + 1 + 1 ) // 6
#define cbFOPOneSon ( cbFOPNoSon + 1 + 1 ) // 8
/* most bytes available for page subtree not including FOP son
/**/ #define cbAvailMost ( cbPage - sizeof(PGHDR) - sizeof(PGTRLR) - cbFOPNoSon - 1 )
// 4096 - 28 - 4 - 6 - 1 /* for FOP son count */ = 4057
/* most bytes for node key and data, backlink included.
/**/ #define cbNodeMost ( cbAvailMost - 1 - 1 - sizeof(TAG) - sizeof(SRID) )
// 4057 - 1 /* FOP son */ - 1 - 4 - 4 = 4047
/* bytes for Null key and no data, backlink excluded.
/**/ #define cbNullKeyData ( cbFOPOneSon - cbFOPNoSon + sizeof(TAG) + 1 + 1 )
// 8 - 6 + 4 + 1 + 1 = 8
// cbNullKeyData is for inserted nodes and
// does not have backlink
/* most bytes for long value chunk with 4 byte key.
/**/ #define cbChunkMost ( cbNodeMost - cbNullKeyData - sizeof(LONG) )
// 4047 - 8 /* node null key data */ - 4 /* key */ = 4035
#define cbItemNodeMost ( 1 + 1 + JET_cbKeyMost + 0 + 0 + sizeof(SRID) + (citemMax * sizeof(SRID)) )
// 261 + 300 * 4 = 1461
#define cbHalfItemNodeMost ( 1 + 1 + JET_cbKeyMost + 0 + 0 + sizeof(SRID) + ((((citemMax + 1) / 2) + 1 ) * sizeof(SRID)) )
// 261 + 151 * 4 = 865
#define cbFirstPagePointer ( 1 + sizeof(PGNO) )
// node header bits
#define fNDVersion 0x80
#define fNDDeleted 0x40
#define fNDBackLink 0x20
#define fNDReserved 0x10 // Reserved for future use (formerly fNDFDPPtr)
#define fNDSon 0x08
#define fNDVisibleSon 0x04
#define fNDFirstItem 0x02
#define fNDLastItem 0x01
#define FNDDeleted(b) ( (b) & fNDDeleted )
#define FNDVersion(b) ( (b) & fNDVersion )
#define FNDVerDel(b) ( (b) & (fNDDeleted | fNDVersion) )
#define FNDBackLink(b) ( (b) & fNDBackLink )
#define FNDNullSon(b) ( !( (b) & fNDSon ) )
#define FNDSon(b) ( (b) & fNDSon )
#define FNDReserved(b) ( (b) & fNDReserved )
#define FNDFDPPtr(b) FNDReserved(b)
#define FNDVisibleSons(b) ( (b) & fNDVisibleSon )
#define FNDInvisibleSons(b) ( !( (b) & fNDVisibleSon ) )
#define FNDFirstItem(b) ( (b) & fNDFirstItem )
#define FNDLastItem(b) ( (b) & fNDLastItem )
// node flag toggle macros
#define NDSetDeleted(b) ( (b) |= fNDDeleted )
#define NDResetDeleted(b) ( (b) &= ~fNDDeleted )
#define NDSetVersion(b) ( (b) |= fNDVersion )
#define NDResetVersion(b) ( (b) &= ~fNDVersion )
#define NDSetSon(b) ( (b) |= fNDSon )
#define NDResetSon(b) ( (b) &= ~fNDSon )
#define NDSetKeyLength(pb, cb) ( *(pb) = cb )
#define NDSetVisibleSons(b) ( (b) |= fNDVisibleSon )
#define NDSetInvisibleSons(b) ( (b) &= ~fNDVisibleSon )
#define NDSetBackLink(b) ( (b) |= fNDBackLink )
#define NDResetBackLink(b) ( (b) &= ~fNDBackLink )
#define NDSetFirstItem(b) ( (b) |= fNDFirstItem )
#define NDResetFirstItem(b) ( (b) &= ~fNDFirstItem )
#define NDSetLastItem(b) ( (b) |= fNDLastItem )
#define NDResetLastItem(b) ( (b) &= ~fNDLastItem )
// macros
#define StNDKey(pb) ( (pb) + 1 )
#define PbNDKeyCb(pb) ( (pb) + 1 )
#define PbNDKey(pb) ( (pb) + 2 )
#define CbNDKey(pb) ( *( (pb) + 1 ) )
#define PbNDSonTable(pb) ( (pb) + 1 + 1 + *(pb + 1) )
#define PbNDSon(pb) ( (BYTE *)PbNDSonTable(pb) + 1 )
#define CbNDSonTable(pbSonTable) ( *(BYTE *)(pbSonTable) )
#define CbNDSon(pbNode) \
( FNDNullSon(*(pbNode)) ? 0 : *PbNDSonTable(pbNode) ) #define PgnoNDOfPbSon(pb) ( *(PGNO UNALIGNED *)PbNDSon(pb) )
#define FNDNonIntrinsicSons(pbNode) ( !FNDNullSon(*pbNode) && ( FNDVisibleSons(*pbNode) || CbNDSon(pbNode) > 1 ) )
#define FNDIntrinsicSons(pbNode) ( !FNDNullSon(*pbNode) && !FNDVisibleSons(*pbNode) && CbNDSon(pbNode) == 1 )
#define PbNDBackLink(pb) \
( PbNDSonTable(pb) + ( FNDNullSon( *(pb) ) ? 0 : \ ( ( ( *PbNDSonTable(pb) == 1 ) && FNDInvisibleSons( *(pb) ) ) ? \ sizeof(PGNO) + 1 : *PbNDSonTable(pb) + 1 ) ) ) #define PbNDData(pb) \
( PbNDBackLink(pb) + ( FNDBackLink( *(pb) ) ? sizeof(SRID) : 0 ) ) #define CbNDData( pbNode, cbNode ) ( (cbNode) - (INT)( PbNDData(pbNode) - (pbNode) ) )
#define ItagSonOfPbND(pb,ib) ( PbNDSonTable(pb)[ib] )
#define ItagSonOfPbSonTable(pb,ib) ( pb[ib+1] )
#define ItagSonOfPbSon(pb,ib) ( pb[ib] )
#define NDGet( pfucb, itagT ) PMGet( &(pfucb)->ssib, itagT )
#ifdef DEBUG
#define AssertNDIntrinsicSon( pbNode, cbNode ) \
{ \ Assert( ( PbNDData( (pbNode) )) - (pbNode) <= \ (INT)(cbNode) ); \ Assert( ( PgnoNDOfPbSon( pbNode ) & 0xff000000 ) == 0 ); \ }
#define AssertNDGet( pfucb, itagT ) \
{ \ AssertPMGet( &(pfucb)->ssib, itagT ); \ }
VOID AssertNDGetKey( FUCB *pfucb, INT itag );
VOID AssertNDGetNode( FUCB *pfucb, INT itag );
#else
#define AssertNDIntrinsicSon( pbNode, cbNode )
#define AssertNDGet( pfucb, itag )
#define AssertNDGetKey( pfucb, itag )
#define AssertNDGetNode( pfucb, itag )
#endif
#define NDIGetBookmarkFromCSR( pfucb, pcsr, psrid ) \
{ \ if ( FNDBackLink( *((pfucb)->ssib.line.pb) ) ) \ { \ *(SRID *)(psrid) = *(SRID UNALIGNED *)PbNDBackLink((pfucb)->ssib.line.pb); \ Assert( PgnoOfPn(*(SRID *)psrid) != pgnoNull ); \ } \ else \ { \ *(psrid) = SridOfPgnoItag( (pcsr)->pgno, (pcsr)->itag ); \ } \ }
#define NDIGetBookmark( pfucb, psrid ) NDIGetBookmarkFromCSR( pfucb, \
PcsrCurrent( pfucb ), \ psrid )
#define NDGetBookmark( pfucb, psrid ) NDGetBookmarkFromCSR( pfucb, \
PcsrCurrent( pfucb ), \ psrid )
/* item bits and macros.
/**/ #define fNDItemDelete 0x40000000
#define fNDItemVersion 0x80000000
#define FNDItemVersion( item ) ( (item) & fNDItemVersion )
#define ITEMSetVersion( item ) ( (item) |= fNDItemVersion )
#define ITEMResetVersion( item ) ( (item) &= ~(fNDItemVersion) )
#define FNDItemDelete( item ) ( (item) & fNDItemDelete )
#define ITEMSetDelete( item ) ( (item) |= fNDItemDelete )
#define ITEMResetDelete( item ) ( (item) &= ~(fNDItemDelete) )
#define BmNDOfItem( item ) ((item) & ~( fNDItemVersion | fNDItemDelete ) )
#define CitemND(pb, cb) \
( ( cb - ( PbNDData(pb) - pb ) ) / sizeof(ITEM) )
#define CitemNDData(pb, cb, pbData) \
( ( cb - ( (pbData) - pb ) ) / sizeof(ITEM) )
#define FNDSingleItem( pfucb ) \
( ( (pfucb)->ssib.line.cb - \ ( PbNDData( (pfucb)->ssib.line.pb ) - (pfucb)->ssib.line.pb ) ) \ / sizeof(ITEM) == 1 )
// LSridCmp
// ========================================================================
// LONG LSridCmp( SRID *psrid1, SRID *psrid2 )
//
// Compare the srids.
//
// PARAMETERS psrid1 pointer to a item;
// psrid2 pointer to a item;
//
// RETURNS < 0, then the first srid is less than the second.
// = 0, then the first srid is equal to the the second.
// > 0, then the first srid is greater than the second.
//-
#define LSridCmp( srid1, srid2 ) \
((LONG) ((SRID) BmNDOfItem( srid1 ) - (SRID) BmNDOfItem( srid2 )))
#ifdef DEBUG
VOID NDCheckTreeInPage( PAGE *ppage, INT itagFather ); #define NDCheckPage( pssib ) NDCheckTreeInPage( (pssib)->pbf->ppage, itagFOP )
#else
#define NDCheckTreeInPage( ppage, itagFather )
#define NDCheckPage( pssib )
#endif
#define NDGetKey( pfucb ) \
{ \ AssertNDGet( pfucb, PcsrCurrent(pfucb)->itag ); \ (pfucb)->keyNode.cb = (INT)*((BYTE *)(pfucb)->ssib.line.pb + 1); \ (pfucb)->keyNode.pb = ( (BYTE *)(pfucb)->ssib.line.pb + 2 ); \ }
// node prototypes
ERR ErrNDNewPage( FUCB *pfucb, PGNO pgno, PGNO pgnoFDP, PGTYP pgtyp, BOOL fVisibleSons ); ERR ErrNDSetNodeHeader( FUCB *pfucb, BYTE bHeader ); VOID NDSeekSon( FUCB *pfucb, CSR *pcsr, KEY const *pkey, INT fFlags ); VOID NDMoveFirstSon( FUCB *pfucb, CSR *pcsr ); VOID NDMoveLastSon( FUCB *pfucb, CSR *pcsr ); ERR ErrNDMoveSon( FUCB *pfucb, CSR *pcsr ); VOID NDGetNode( FUCB *pfucb ); VOID NDGetBookmarkFromCSR( FUCB *pfucb, CSR *pcsr, SRID *psrid );
ERR ErrNDInsertNode( FUCB *pfucb, KEY const *pkey, LINE *plineData, INT fHeader, INT fFlags ); ERR ErrNDDeleteNode( FUCB *pfucb ); ERR ErrNDReplaceWithLink( FUCB *pfucb, SRID sridLink ); ERR ErrNDDeleteInvisibleSon( FUCB *pfucb, RMPAGE *prmpage, BOOL fCheckRemoveParentOnly, BOOL *pfRmParent ); ERR ErrNDFlagDeleteNode( FUCB *pfucb, INT fFlags ); ERR ErrNDReplaceNodeData( FUCB *pfucb, LINE *pline, INT fFlags ); VOID NDResetNodeVersion( FUCB *pfucb ); VOID NDDeferResetNodeVersion( FUCB *pfucb ); VOID NDResetNodeDeleted( FUCB *pfucb );
ERR ErrNDGetItem( FUCB *pfucb ); ERR ErrNDFirstItem( FUCB *pfucb ); ERR ErrNDLastItem( FUCB *pfucb ); ERR ErrNDNextItem( FUCB *pfucb ); ERR ErrNDPrevItem( FUCB *pfucb ); ERR ErrNDSeekItem( FUCB *pfucb, SRID srid );
#define fNDCitemAll (1<<0)
#define fNDCitemFromIsrid (1<<1)
#define fNDCitemToIsrid (1<<2)
INT CitemNDThere( FUCB *pfucb, BYTE fNDCitem, INT isrid );
ERR ErrNDInsertItemList( FUCB *pfucb, KEY *pkey, SRID srid, INT fFlags ); ERR ErrNDInsertItem( FUCB *pfucb, ITEM item, INT fFlags ); ERR ErrNDInsertItems( FUCB *pfucb, ITEM *rgitem, INT citem ); ERR ErrNDFlagInsertItem( FUCB *pfucb ); ERR ErrNDDeleteItem( FUCB *pfucb ); ERR ErrNDFlagDeleteItem( FUCB *pfucb, BOOL fNoMPLRegister ); VOID NDSetItemDelete( FUCB *pfucb ); VOID NDResetItemVersion( FUCB *pfucb ); VOID NDResetItemDelete( FUCB *pfucb ); ERR ErrNDSplitItemListNode( FUCB *pfucb, INT fFlags ); ERR ErrNDDelta( FUCB *pfucb, LONG lDelta, INT fFlags ); ERR ErrNDDeltaNoCheckLog( FUCB *pfucb, LONG lDelta, INT fFlags ); ERR ErrNDLockRecord( FUCB *pfucb );
ERR ErrNDInsertWithBackLink( FUCB *pfucb, BYTE bFlags, KEY const *pkey, LINE *plineSonTable, SRID sridBackLink, LINE *plineData ); VOID NDGetBackLink( FUCB *pfucb, PGNO *ppgno, INT *pitag ); ERR ErrNDExpungeBackLink( FUCB *pfucb ); ERR ErrNDExpungeLinkCommit( FUCB *pfucb, FUCB *pfucbSrc ); VOID NDGetItagFatherIbSon( INT *pitagFather, INT *pibSon, PAGE *ppage, INT itag );
#define FNDFreePageSpace( pssib, cbT ) \
( ((INT)(pssib)->pbf->ppage->cbFree) < cbT ? \ fFalse : \ FVERCheckUncommittedFreedSpace( (pssib)->pbf, cbT ) ) INT CbNDFreePageSpace( BF *pbf );
BOOL FNDMaxKeyInPage( FUCB *pfucb );
#endif // NODE_INCLUDED
|