283 lines
10 KiB
C
283 lines
10 KiB
C
#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
|