|
|
//============== DAE: OS/2 Database Access Engine ===================
//============== fucb.h: File Use Control Block ===================
/* describes exact placement of CSR and meaning of CSR's pgno:itag
/**/ typedef INT CSRSTAT; #define csrstatOnCurNode 0 // pgno:itag == node CSR is ON
#define csrstatBeforeCurNode 1 // pgno:itag == node CSR is BEFORE
#define csrstatAfterCurNode 2 // pgno:itag == node CSR is AFTER,
#define csrstatDeferGotoBookmark 3 // valid bm
#define csrstatAfterLast 4 // no pgno:itag
#define csrstatBeforeFirst 5 // no pgno:itag
#define csrstatOnFDPNode 6 // pgno:itag == FDP root
#define csrstatDeferMoveFirst 7 // on first node
#define csrstatOnDataRoot 8 // on FCB data root node
/* Currency Stack Register
/**/ struct _csr { ULONG ulDBTime; // page time stamp
struct _csr *pcsrPath; // parent currency
PGNO pgno; // pgno of node page
SRID bm; // bookmark of node
SRID item; // item, set to sridInvisibleCSR if invisible CSR
CSRSTAT csrstat; // status of csr relative to node
INT itag; // node itag
INT isrid; // index of item in item list
INT itagFather; // itag of father
INT ibSon; // index of son in father son table
};
/* allow invisible CSRs to be identified
/**/ #define sridInvisibleCSR ((SRID)(-1))
#define CSRSetInvisible( pcsr ) ( (pcsr)->item = sridInvisibleCSR )
#define CSRResetInvisible( pcsr ) ( (pcsr)->item = sridNull )
#define FCSRInvisible( pcsr ) ( (pcsr)->item == sridInvisibleCSR )
#define PcsrMEMAlloc() (CSR*)PbMEMAlloc(iresCSR)
#ifdef DEBUG /* Debug check for illegal use of freed csr */
#define MEMReleasePcsr(pcsr) { MEMRelease(iresCSR, (BYTE*)(pcsr)); pcsr = pcsrNil; }
#else
#define MEMReleasePcsr(pcsr) { MEMRelease(iresCSR, (BYTE*)(pcsr)); }
#endif
/* CSR constants
/**/ #define itagNull (-1)
#define isridNull (-1)
#define ibSonNull (-1)
/* flags for FUCB
/*
/* fFUCBTaggedSet is set by column set, and reset by prepare replace
/* and prepare insert.
/*
/* fFUCBDeferClose is set by cursor DIRClose and reset by ErrDIROpen.
/*
/* fFUCBDeferGotoBookmark is set by non-clustered index navigation and
/* reset by record status, ErrIsamMove( 0 ), and column retrieval.
/*
/* fFUCBGetBookmark is set by get bookmark and is reset by ErrFUCBOpen.
/**/ #define fFUCBIndex (1<<0) // FUCB is for index
#define fFUCBNonClustered (1<<1) // FUCB for nonclustered index
#define fFUCBSort (1<<2) // FUCB is for sort
#define fFUCBSystemTable (1<<3) // System table cursor
#define fFUCBWrite (1<<4) // cursor can write
#define fFUCBDenyRead (1<<5) // deny read flag
#define fFUCBDenyWrite (1<<6) // deny write flag
#define fFUCBTaggedSet (1<<7) // tagged column
#define fFUCBDeferClose (1<<9) // FUCB is awaiting close
#define fFUCBDeferGotoBookmark (1<<10) // clustered cursor position
#define fFUCBGetBookmark (1<<11) // cursor got bookmark
#define fFUCBLimstat (1<<12) // range limit
#define fFUCBInclusive (1<<13) // inclusive range
#define fFUCBUpper (1<<14) // upper range limit
#define fFUCBFull (1<<15) // all CSRs including invisible CSRs
#define fFUCBUpdateSeparateLV (1<<16) // long value updated
/* the following flags need to be prevent reuse of cursor
/* after deferred closed. This is done to correctly release
/* domain flags when commit/rollback to transaction level 0.
/**/ #define fFUCBNotReuse ( fFUCBDenyRead | fFUCBDenyWrite )
#define FFUCBNotReuse( pfucb ) ( (pfucb)->wFlags & fFUCBNotReuse )
#define FFUCBIndex( pfucb ) ( (pfucb)->wFlags & fFUCBIndex )
#define FUCBSetIndex( pfucb ) ( (pfucb)->wFlags |= fFUCBIndex )
#define FUCBResetIndex( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBIndex) )
#define FFUCBNonClustered( pfucb ) ( (pfucb)->wFlags & fFUCBNonClustered )
#define FUCBSetNonClustered( pfucb ) ( (pfucb)->wFlags |= fFUCBNonClustered )
#define FUCBResetNonClustered( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBNonClustered) )
#define FFUCBSort( pfucb ) ( (pfucb)->wFlags & fFUCBSort )
#define FUCBSetSort( pfucb ) ( (pfucb)->wFlags |= fFUCBSort )
#define FUCBResetSort( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBSort) )
#define FFUCBSystemTable( pfucb ) ( (pfucb)->wFlags & fFUCBSystemTable )
#define FUCBSetSystemTable( pfucb ) ( (pfucb)->wFlags |= fFUCBSystemTable )
#define FUCBResetSystemTable( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBSystemTable) )
#define FFUCBUpdatable( pfucb ) ( (pfucb)->wFlags & fFUCBWrite )
#define FUCBSetUpdatable( pfucb ) ( (pfucb)->wFlags |= fFUCBWrite )
#define FUCBResetUpdatable( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBWrite) )
#define FFUCBDenyWrite( pfucb ) ( (pfucb)->wFlags & fFUCBDenyWrite )
#define FUCBSetDenyWrite( pfucb ) ( (pfucb)->wFlags |= fFUCBDenyWrite )
#define FUCBResetDenyWrite( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBDenyWrite) )
#define FFUCBDenyRead( pfucb ) ( (pfucb)->wFlags & fFUCBDenyRead )
#define FUCBSetDenyRead( pfucb ) ( (pfucb)->wFlags |= fFUCBDenyRead )
#define FUCBResetDenyRead( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBDenyRead) )
#define FFUCBTaggedSet( pfucb ) ( (pfucb)->wFlags & fFUCBTaggedSet )
#define FUCBSetTaggedSet( pfucb ) ( (pfucb)->wFlags |= fFUCBTaggedSet )
#define FUCBResetTaggedSet( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBTaggedSet) )
#define FFUCBUpdateSeparateLV( pfucb ) ( (pfucb)->wFlags & fFUCBUpdateSeparateLV )
#define FUCBSetUpdateSeparateLV( pfucb ) ( (pfucb)->wFlags |= fFUCBUpdateSeparateLV )
#define FUCBResetUpdateSeparateLV( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBUpdateSeparateLV) )
#define FFUCBDeferClosed( pfucb ) ( (pfucb)->wFlags & fFUCBDeferClose )
#define FUCBSetDeferClose( pfucb ) ( (pfucb)->wFlags |= fFUCBDeferClose )
#define FUCBResetDeferClose( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBDeferClose) )
#define FFUCBDeferGotoBookmark( pfucb ) \
( (pfucb)->wFlags & fFUCBDeferGotoBookmark ) #define FUCBSetDeferGotoBookmark( pfucb ) \
( (pfucb)->wFlags |= fFUCBDeferGotoBookmark ) #define FUCBResetDeferGotoBookmark( pfucb ) \
( (pfucb)->wFlags &= ~(fFUCBDeferGotoBookmark) )
#define FFUCBGetBookmark( pfucb ) \
( (pfucb)->wFlags & fFUCBGetBookmark ) #define FUCBSetGetBookmark( pfucb ) \
( (pfucb)->wFlags |= fFUCBGetBookmark ) #define FUCBResetGetBookmark( pfucb ) \
( (pfucb)->wFlags &= ~(fFUCBGetBookmark) )
#define FFUCBLimstat( pfucb ) ( (pfucb)->wFlags & fFUCBLimstat )
#define FUCBSetLimstat( pfucb ) ( (pfucb)->wFlags |= fFUCBLimstat )
#define FUCBResetLimstat( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBLimstat) )
#define FFUCBInclusive( pfucb ) ( (pfucb)->wFlags & fFUCBInclusive )
#define FUCBSetInclusive( pfucb ) ( (pfucb)->wFlags |= fFUCBInclusive )
#define FUCBResetInclusive( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBInclusive) )
#define FFUCBUpper( pfucb ) ( (pfucb)->wFlags & fFUCBUpper )
#define FUCBSetUpper( pfucb ) ( (pfucb)->wFlags |= fFUCBUpper )
#define FUCBResetUpper( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBUpper) )
#define FFUCBFull( pfucb ) ( (pfucb)->wFlags & fFUCBFull )
#define FUCBSetFull( pfucb ) ( (pfucb)->wFlags |= fFUCBFull )
#define FUCBResetFull( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBFull) )
#define FFUCBVersioned( pfucb ) ( (pfucb)->fVersioned )
#define FUCBSetVersioned( pfucb ) ( (pfucb)->fVersioned = fTrue )
#define FUCBResetVersioned( pfucb ) ( (pfucb)->fVersioned = fFalse )
/* record modification copy buffer status
/**/ typedef INT CBSTAT;
#define fCBSTATNull 0
#define fCBSTATInsert (1<<0)
#define fCBSTATReplace (1<<1)
#define fCBSTATSet (1<<2)
#define fCBSTATLock (1<<3)
#define fCBSTATAppendItem (1<<4)
#define StoreChecksum( pfucb ) \
( (pfucb)->ulChecksum = \ UlChecksum( (pfucb)->lineData.pb, (pfucb)->lineData.cb ) ) #define PrepareInsert( pfucb ) \
( (pfucb)->cbstat = fCBSTATInsert, \ (pfucb)->levelPrep = (pfucb)->ppib->level ) #define PrepareReplaceNoLock( pfucb ) \
( (pfucb)->cbstat = fCBSTATReplace, \ (pfucb)->levelPrep = (pfucb)->ppib->level ) #define PrepareReplace( pfucb ) \
( (pfucb)->cbstat = fCBSTATReplace | fCBSTATLock, \ (pfucb)->levelPrep = (pfucb)->ppib->level ) #define PrepareSet( pfucb ) \
( (pfucb)->cbstat = fCBSTATSet, \ (pfucb)->levelPrep = (pfucb)->ppib->level ) #define PrepareAppendItem( pfucb ) \
( (pfucb)->cbstat = fCBSTATAppendItem )
typedef struct { INT isrid; SRID rgsrid[(cbPage - sizeof(INT))/sizeof(SRID)]; } APPENDITEM;
#define csridAppendItemMax ((cbPage - sizeof(INT))/sizeof(SRID))
#define IsridAppendItemOfPfucb( pfucb ) (((APPENDITEM *)(pfucb)->lineWorkBuf.pb)->isrid)
#define RgsridAppendItemOfPfucb( pfucb ) (((APPENDITEM *)(pfucb)->lineWorkBuf.pb)->rgsrid)
#define FChecksum( pfucb ) \
( (pfucb)->ulChecksum == UlChecksum( (pfucb)->lineData.pb, \ (pfucb)->lineData.cb ) )
#define FFUCBReplacePrepared( pfucb ) \
( (pfucb)->cbstat & fCBSTATReplace ) #define FFUCBReplaceNoLockPrepared( pfucb ) \
( !( (pfucb)->cbstat & fCBSTATLock ) && \ FFUCBReplacePrepared( pfucb ) ) #define FFUCBInsertPrepared( pfucb ) \
( (pfucb)->cbstat & fCBSTATInsert ) #define FFUCBSetPrepared( pfucb ) \
( (pfucb)->cbstat != fCBSTATNull && \ (pfucb)->levelPrep == (pfucb)->ppib->level ) #define FFUCBRetPrepared( pfucb ) \
( (pfucb)->cbstat != fCBSTATNull ) #define FFUCBUpdatePrepared( pfucb ) ((pfucb)->cbstat != fCBSTATNull )
#define FUCBResetCbstat( pfucb ) ( (pfucb)->cbstat = fCBSTATNull )
typedef INT KS;
#define ksNull 0
#define ksPrepared (1<<0)
#define ksTooBig (1<<1)
#define KSReset( pfucb ) ( (pfucb)->ks = ksNull )
#define KSSetPrepare( pfucb ) ( (pfucb)->ks |= ksPrepared )
#define KSSetTooBig( pfucb ) ( (pfucb)->ks |= ksTooBig )
#define FKSPrepared( pfucb ) ( (pfucb)->ks & ksPrepared )
#define FKSTooBig( pfucb ) ( (pfucb)->ks & ksTooBig )
/* set bit arrary marcos
/**/ #define FUCBResetColumnSet( pfucb ) \
( memset( (pfucb)->rgbitSet, 0x00, 32 ) ) #define FUCBSetFixedColumnSet( pfucb, fid ) \
( (pfucb)->rgbitSet[(fid - fidFixedLeast)/8] |= 1 << \ (fid-fidFixedLeast) % 8 ) #define FUCBSetVarColumnSet( pfucb, fid ) \
( (pfucb)->rgbitSet[16 + (fid - fidVarLeast)/8] |= 1 << \ (fid-fidVarLeast) % 8 ) #define FFUCBColumnSet( pfucb, ibitCol ) \
( (pfucb)->rgbitSet[(ibitCol)/8] & ( 1 << ( (ibitCol) % 8 ) ) )
#define FUCBStore( pfucb ) \
{ \ (pfucb)->csrstatStore = PcsrCurrent( pfucb )->csrstat; \ (pfucb)->bmStore = PcsrCurrent( pfucb )->bm; \ (pfucb)->itemStore = PcsrCurrent( pfucb )->item; \ }
#define FUCBResetStore( pfucb ) \
{ \ (pfucb)->bmStore = 0; \ }
#define FUCBRestore( pfucb ) \
{ \ if ( (pfucb)->bmStore != isridNull && (pfucb)->bmStore != sridNull ) \ { \ PcsrCurrent( pfucb )->csrstat = (pfucb)->csrstatStore; \ Assert( (pfucb)->csrstatStore == csrstatOnDataRoot || \ (pfucb)->csrstatStore == csrstatDeferMoveFirst || \ (pfucb)->csrstatStore == csrstatBeforeFirst || \ (pfucb)->csrstatStore == csrstatAfterLast || \ (pfucb)->bmStore != sridNull ); \ PcsrCurrent( pfucb )->bm = (pfucb)->bmStore; \ PcsrCurrent( pfucb )->item = (pfucb)->itemStore; \ PcsrCurrent( pfucb )->ulDBTime = ulDBTimeNull; \ } \ }
/* file use control block
/**/ struct _fucb { // ===== chaining fields =====
struct _pib *ppib; // user that opened this FUCB
struct _fucb *pfucbNext; // Next FUCB of this user
union { struct _fcb *pfcb; // if wFlags & fFUCBIndex
struct _scb *pscb; // if wFlags & fFUCBSort
} u; struct _fucb *pfucbNextInstance; // Next Instance of this file
// ===== currency =====
struct _csr *pcsr;
// ===== stored currency =====
SRID bmStore; // stored bookmark
SRID itemStore; // stored item
SRID bmRefresh; // stored bookmark for next/prev retry
SRID sridFather; // SRID of visible father
BYTE **ppbCurrent; // (SORT) current record
ULONG ulChecksum; // checksum of record -- used only for optimistic locking
KEY keyNode; // Key of current node
LINE lineData; // Current data pointed in pcsr
CSRSTAT csrstatStore; // stored CSR status
LEVEL levelOpen;
// ===== interface to Storage System =====
SSIB ssib; // SSIB associated with this FUCB
struct _bf *pbfEmpty; // write latched empty page
UINT cpn; // next read-ahead pn
// ===== maintained by rec man =====
struct _fucb *pfucbCurIndex; // current secondary index
struct _bf *pbfWorkBuf; // working buffer for Insert/Replace
LINE lineWorkBuf; // working buffer for Insert/Replace
ULONG cbRecord; // size of original record
ULONG dbkUpdate; // dbk of record to Replace
BYTE rgbitSet[32]; CBSTAT cbstat; // copy buffer status
LEVEL levelPrep; // level copy buffer prepared
// ====== versioning work area =======
struct _rce *prceLast; // last RCE allocated (used only for Replace)
// ====== space manager work area =======
PGNO pgnoLast; // last page of extent
CPG cpgExtent; // initial extent size
CPG cpgAvail; // number of remaining pages
INT fExtent; // work area flag
// ===== misc fields =====
INT wFlags; // temporary flags
// ===== maintained by dir man =====
BYTE *pbKey; // search key buffer
DBID dbid; // database id
KS ks; // search key buffer status
UINT cbKey; // key size
BOOL fVtid : 1; // persistant flag cursor has vtid
BOOL fVersioned : 1; // persistant falg cursor made version
BOOL fCmprsLg:1; INT clineDiff; #define ilineDiffMax 3
LINE rglineDiff[ilineDiffMax]; };
#define PfucbMEMAlloc() (FUCB*)PbMEMAlloc(iresFUCB)
#ifdef DEBUG /* Debug check for illegal use of freed fucb */
#define MEMReleasePfucb(pfucb) { MEMRelease(iresFUCB, (BYTE*)(pfucb)); pfucb = pfucbNil; }
#else
#define MEMReleasePfucb(pfucb) { MEMRelease(iresFUCB, (BYTE*)(pfucb)); }
#endif
#ifdef DEBUG
#define CheckTable( ppibT, pfucb ) \
{ \ Assert( pfucb->ppib == ppibT ); \ Assert( fRecovering || FFUCBIndex( pfucb ) ); \ Assert( !( FFUCBSort( pfucb ) ) ); \ Assert( pfucb->u.pfcb != NULL ); \ } #define CheckSort( ppibT, pfucb ) \
{ \ Assert( pfucb->ppib == ppibT ); \ Assert( FFUCBSort( pfucb ) ); \ Assert( !( FFUCBIndex( pfucb ) ) ); \ Assert( pfucb->u.pscb != NULL ); \ } #define CheckFUCB( ppibT, pfucb ) \
{ \ Assert( pfucb->ppib == ppibT ); \ Assert( pfucb->u.pfcb != NULL ); \ }
#define CheckNonClustered( pfucb ) \
{ \ Assert( (pfucb)->pfucbCurIndex == pfucbNil || \ FFUCBNonClustered( (pfucb)->pfucbCurIndex ) ); \ }
#else /* !DEBUG */
#define CheckSort( ppib, pfucb )
#define CheckTable( ppib, pfucb )
#define CheckFUCB( ppib, pfucb )
#define CheckNonClustered( pfucb )
#endif /* !DEBUG */
#define PcsrCurrent( pfucb ) ( (pfucb)->pcsr )
#define BmOfPfucb( pfucb ) ( (pfucb)->pcsr->bm )
#define FUCBCheckUpdatable( pfucb ) \
( FFUCBUpdatable( pfucb ) ? JET_errSuccess : JET_errPermissionDenied ) ERR ErrFUCBAllocCSR( CSR **ppcsr ); ERR ErrFUCBNewCSR( FUCB *pfucb ); VOID FUCBFreeCSR( FUCB *pfucb ); VOID FUCBFreePath( CSR **ppcsr, CSR *pcsrMark ); ERR ErrFUCBOpen( PIB *ppib, DBID dbid, FUCB **ppfucb ); VOID FUCBClose( FUCB *pfucb ); VOID FUCBRemoveInvisible(CSR **ppcsr);
VOID FUCBSetIndexRange( FUCB *pfucb, JET_GRBIT grbit ); VOID FUCBResetIndexRange( FUCB *pfucb ); ERR ErrFUCBCheckIndexRange( FUCB *pfucb );
|