Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

539 lines
19 KiB

  1. /* describes exact placement of CSR and meaning of CSR's pgno:itag
  2. /**/
  3. typedef INT CSRSTAT;
  4. #define csrstatOnCurNode 0 // pgno:itag == node CSR is ON
  5. #define csrstatBeforeCurNode 1 // pgno:itag == node CSR is BEFORE
  6. #define csrstatAfterCurNode 2 // pgno:itag == node CSR is AFTER,
  7. #define csrstatDeferGotoBookmark 3 // valid bm
  8. #define csrstatAfterLast 4 // no pgno:itag
  9. #define csrstatBeforeFirst 5 // no pgno:itag
  10. #define csrstatOnFDPNode 6 // pgno:itag == FDP root
  11. #define csrstatDeferMoveFirst 7 // on first node
  12. #define csrstatOnDataRoot 8 // on FCB data root node
  13. /* Currency Stack Register
  14. /**/
  15. struct _csr
  16. {
  17. QWORD qwDBTime; // page time stamp
  18. SRID bmRefresh; // for BTNextPrev
  19. PGNO pgno; // pgno of current page
  20. SRID bm; // bookmark of current node
  21. SRID item; // item, set to sridInvisibleCSR if invisible CSR
  22. CSRSTAT csrstat; // status relative to current node
  23. #ifdef PCACHE_OPTIMIZATION
  24. SHORT itag; // current node itag
  25. SHORT isrid; // index of item in item list
  26. SHORT itagFather; // itag of father node
  27. SHORT ibSon; // index of son node in father son table
  28. #else
  29. INT itag; // current node itag
  30. INT isrid; // index of item in item list
  31. INT itagFather; // itag of father node
  32. INT ibSon; // index of son node in father son table
  33. #endif
  34. struct _csr *pcsrPath; // parent currency stack register
  35. #ifdef PCACHE_OPTIMIZATION
  36. BYTE rgbFiller[24];
  37. #endif
  38. };
  39. /* allow invisible CSRs to be identified
  40. /**/
  41. #define sridInvisibleCSR ((SRID)(-1))
  42. #define CSRSetInvisible( pcsr ) ( (pcsr)->item = sridInvisibleCSR )
  43. #define CSRResetInvisible( pcsr ) ( (pcsr)->item = sridNull )
  44. #define FCSRInvisible( pcsr ) ( (pcsr)->item == sridInvisibleCSR )
  45. #define CSRInvalidate( pcsr ) \
  46. { \
  47. (pcsr)->itag = itagNil; \
  48. (pcsr)->itagFather = itagNil; \
  49. (pcsr)->pgno = pgnoNull; \
  50. }
  51. #define PcsrMEMAlloc() (CSR*)PbMEMAlloc(iresCSR)
  52. #ifdef DEBUG /* Debug check for illegal use of freed csr */
  53. #define MEMReleasePcsr(pcsr) { MEMRelease(iresCSR, (BYTE*)(pcsr)); pcsr = pcsrNil; }
  54. #else
  55. #define MEMReleasePcsr(pcsr) { MEMRelease(iresCSR, (BYTE*)(pcsr)); }
  56. #endif
  57. /* CSR constants
  58. /**/
  59. #define itagNull (-1)
  60. #define isridNull (-1)
  61. #define ibSonNull (-1)
  62. /* the following flags need to be prevent reuse of cursor
  63. /* after deferred closed. This is done to correctly release
  64. /* domain flags when commit/rollback to transaction level 0.
  65. /**/
  66. #define FFUCBNotReuse( pfucb ) ( (pfucb)->fDenyRead || (pfucb)->fDenyWrite )
  67. #define FFUCBIndex( pfucb ) ( (pfucb)->fIndex )
  68. #define FUCBSetIndex( pfucb ) ( (pfucb)->fIndex = 1 )
  69. #define FUCBResetIndex( pfucb ) ( (pfucb)->fIndex = 0 )
  70. #define FFUCBNonClustered( pfucb ) ( (pfucb)->fNonClustered )
  71. #define FUCBSetNonClustered( pfucb ) ( (pfucb)->fNonClustered = 1 )
  72. #define FUCBResetNonClustered( pfucb ) ( (pfucb)->fNonClustered = 0 )
  73. #define FFUCBSort( pfucb ) ( (pfucb)->fSort )
  74. #define FUCBSetSort( pfucb ) ( (pfucb)->fSort = 1 )
  75. #define FUCBResetSort( pfucb ) ( (pfucb)->fSort = 0 )
  76. #define FFUCBSystemTable( pfucb ) ( (pfucb)->fSystemTable )
  77. #define FUCBSetSystemTable( pfucb ) ( (pfucb)->fSystemTable = 1 )
  78. #define FUCBResetSystemTable( pfucb ) ( (pfucb)->fSystemTable = 0 )
  79. #define FFUCBUpdatable( pfucb ) ( (pfucb)->fWrite )
  80. #define FUCBSetUpdatable( pfucb ) ( (pfucb)->fWrite = 1 )
  81. #define FUCBResetUpdatable( pfucb ) ( (pfucb)->fWrite = 0 )
  82. #define FFUCBDenyWrite( pfucb ) ( (pfucb)->fDenyWrite )
  83. #define FUCBSetDenyWrite( pfucb ) ( (pfucb)->fDenyWrite = 1 )
  84. #define FUCBResetDenyWrite( pfucb ) ( (pfucb)->fDenyWrite = 0 )
  85. #define FFUCBDenyRead( pfucb ) ( (pfucb)->fDenyRead )
  86. #define FUCBSetDenyRead( pfucb ) ( (pfucb)->fDenyRead = 1 )
  87. #define FUCBResetDenyRead( pfucb ) ( (pfucb)->fDenyRead = 0 )
  88. #define FFUCBDeferClosed( pfucb ) ( (pfucb)->fDeferClose )
  89. #define FUCBSetDeferClose( pfucb ) \
  90. { \
  91. Assert( (pfucb)->ppib->level > 0 ); \
  92. (pfucb)->fDeferClose = 1; \
  93. }
  94. #define FUCBResetDeferClose( pfucb ) ( (pfucb)->fDeferClose = 0 )
  95. #define FFUCBDeferGotoBookmark( pfucb ) \
  96. ( (pfucb)->fDeferGotoBookmark )
  97. #define FUCBSetDeferGotoBookmark( pfucb ) \
  98. ( (pfucb)->fDeferGotoBookmark = 1 )
  99. #define FUCBResetDeferGotoBookmark( pfucb ) \
  100. ( (pfucb)->fDeferGotoBookmark = 0 )
  101. #define FFUCBGetBookmark( pfucb ) \
  102. ( (pfucb)->fGetBookmark )
  103. #define FUCBSetGetBookmark( pfucb ) \
  104. ( (pfucb)->fGetBookmark = 1 )
  105. #define FUCBResetGetBookmark( pfucb ) \
  106. ( (pfucb)->fGetBookmark = 0 )
  107. #define FFUCBLimstat( pfucb ) ( (pfucb)->fLimstat )
  108. #define FUCBSetLimstat( pfucb ) ( (pfucb)->fLimstat = 1 )
  109. #define FUCBResetLimstat( pfucb ) ( (pfucb)->fLimstat = 0 )
  110. #define FFUCBInclusive( pfucb ) ( (pfucb)->fInclusive )
  111. #define FUCBSetInclusive( pfucb ) ( (pfucb)->fInclusive = 1 )
  112. #define FUCBResetInclusive( pfucb ) ( (pfucb)->fInclusive = 0 )
  113. #define FFUCBUpper( pfucb ) ( (pfucb)->fUpper )
  114. #define FUCBSetUpper( pfucb ) ( (pfucb)->fUpper = 1 )
  115. #define FUCBResetUpper( pfucb ) ( (pfucb)->fUpper = 0 )
  116. #define FFUCBFull( pfucb ) ( (pfucb)->fFull )
  117. #define FUCBSetFull( pfucb ) ( (pfucb)->fFull = 1 )
  118. #define FUCBResetFull( pfucb ) ( (pfucb)->fFull = 0 )
  119. #define FFUCBUpdateSeparateLV( pfucb ) ( (pfucb)->fUpdateSeparateLV )
  120. #define FUCBSetUpdateSeparateLV( pfucb ) ( (pfucb)->fUpdateSeparateLV = 1 )
  121. #define FUCBResetUpdateSeparateLV( pfucb ) ( (pfucb)->fUpdateSeparateLV = 0 )
  122. #define FFUCBVersioned( pfucb ) ( (pfucb)->fVersioned )
  123. #define FUCBSetVersioned( pfucb ) ( (pfucb)->fVersioned = 1 )
  124. #define FUCBResetVersioned( pfucb ) ( (pfucb)->fVersioned = 0 )
  125. #define FFUCBDeferredChecksum( pfucb ) ( (pfucb)->fDeferredChecksum )
  126. #define FUCBSetDeferredChecksum( pfucb ) ( (pfucb)->fDeferredChecksum = 1 )
  127. #define FUCBResetDeferredChecksum( pfucb ) ( (pfucb)->fDeferredChecksum = 0 )
  128. #define FFUCBSequential( pfucb ) ( (pfucb)->fSequential )
  129. #define FUCBSetSequential( pfucb ) ( (pfucb)->fSequential = 1 )
  130. #define FUCBResetSequential( pfucb ) ( (pfucb)->fSequential = 0 )
  131. /* record modification copy buffer status
  132. /**/
  133. typedef INT CBSTAT;
  134. #define fCBSTATNull 0
  135. #define fCBSTATInsert (1<<0)
  136. #define fCBSTATReplace (1<<1)
  137. #define fCBSTATLock (1<<3)
  138. #define fCBSTATAppendItem (1<<4)
  139. #define fCBSTATDeferredUpdate (1<<5)
  140. #define StoreChecksum( pfucb ) \
  141. ( (pfucb)->ulChecksum = \
  142. UlChecksum( (pfucb)->lineData.pb, (pfucb)->lineData.cb ) )
  143. #define PrepareInsert( pfucb ) \
  144. ( (pfucb)->cbstat = fCBSTATInsert, \
  145. (pfucb)->levelPrep = (pfucb)->ppib->level )
  146. #define PrepareReplaceNoLock( pfucb ) \
  147. ( (pfucb)->cbstat = fCBSTATReplace, \
  148. (pfucb)->levelPrep = (pfucb)->ppib->level )
  149. #define PrepareReplace( pfucb ) \
  150. ( (pfucb)->cbstat = fCBSTATReplace | fCBSTATLock, \
  151. (pfucb)->levelPrep = (pfucb)->ppib->level )
  152. #define PrepareAppendItem( pfucb ) \
  153. ( (pfucb)->cbstat = fCBSTATAppendItem )
  154. typedef struct {
  155. INT isrid;
  156. SRID rgsrid[(cbPage - sizeof(INT))/sizeof(SRID)];
  157. } APPENDITEM;
  158. #define csridAppendItemMax ((cbPage - sizeof(INT))/sizeof(SRID))
  159. #define IsridAppendItemOfPfucb( pfucb ) (((APPENDITEM *)(pfucb)->lineWorkBuf.pb)->isrid)
  160. #define RgsridAppendItemOfPfucb( pfucb ) (((APPENDITEM *)(pfucb)->lineWorkBuf.pb)->rgsrid)
  161. #define FFUCBCheckChecksum( pfucbT ) \
  162. ( (pfucbT)->ulChecksum == UlChecksum( (pfucbT)->lineData.pb, \
  163. (pfucbT)->lineData.cb ) )
  164. #define FFUCBReplacePrepared( pfucb ) \
  165. ( (pfucb)->cbstat & fCBSTATReplace )
  166. #define FFUCBReplaceNoLockPrepared( pfucb ) \
  167. ( !( (pfucb)->cbstat & fCBSTATLock ) && \
  168. FFUCBReplacePrepared( pfucb ) )
  169. #define FFUCBInsertPrepared( pfucb ) \
  170. ( (pfucb)->cbstat & fCBSTATInsert )
  171. #define FFUCBSetPrepared( pfucb ) \
  172. ( ( (pfucb)->cbstat & (fCBSTATInsert|fCBSTATReplace) ) && \
  173. ( (pfucb)->levelPrep <= (pfucb)->ppib->level ) )
  174. #define FFUCBRetPrepared( pfucb ) \
  175. ( (pfucb)->cbstat & (fCBSTATInsert|fCBSTATReplace) )
  176. #define FFUCBUpdatePreparedLevel( pfucb, levelT ) \
  177. ( ( (pfucb)->cbstat & (fCBSTATInsert|fCBSTATReplace) ) && \
  178. (pfucb)->levelPrep > (levelT) )
  179. #define FFUCBUpdatePrepared( pfucb ) \
  180. ( (pfucb)->cbstat & (fCBSTATInsert|fCBSTATReplace) )
  181. #define FUCBResetCbstat( pfucb ) \
  182. ( (pfucb)->cbstat = fCBSTATNull )
  183. #define FFUCBAtPrepareLevel( pfucb ) \
  184. ( (pfucb)->levelPrep == (pfucb)->ppib->level )
  185. #define FUCBDeferUpdate( pfucb ) \
  186. ( (pfucb)->cbstatPrev = (pfucb)->cbstat, \
  187. (pfucb)->cbstat = fCBSTATDeferredUpdate )
  188. #define FFUCBDeferredUpdate( pfucb ) \
  189. ( (pfucb)->cbstat == fCBSTATDeferredUpdate )
  190. #define FUCBRollbackDeferredUpdate( pfucb ) \
  191. ( (pfucb)->cbstat = (pfucb)->cbstatPrev )
  192. typedef INT KS;
  193. #define ksNull 0
  194. #define ksPrepared (1<<0)
  195. #define ksTooBig (1<<1)
  196. #define KSReset( pfucb ) ( (pfucb)->ks = ksNull )
  197. #define KSSetPrepare( pfucb ) ( (pfucb)->ks |= ksPrepared )
  198. #define KSSetTooBig( pfucb ) ( (pfucb)->ks |= ksTooBig )
  199. #define FKSPrepared( pfucb ) ( (pfucb)->ks & ksPrepared )
  200. #define FKSTooBig( pfucb ) ( (pfucb)->ks & ksTooBig )
  201. /* Setup vdbid back pointer.
  202. **/
  203. #define FUCBSetVdbid( pfucb ) \
  204. if ( (pfucb)->dbid == dbidTemp ) \
  205. (pfucb)->vdbid = NULL; \
  206. else { \
  207. for ( (pfucb)->vdbid = (pfucb)->ppib->pdabList; \
  208. (pfucb)->vdbid != NULL && \
  209. (pfucb)->vdbid->dbid != (pfucb)->dbid; \
  210. (pfucb)->vdbid = (pfucb)->vdbid->pdabNext ) \
  211. ; /* NULL */ \
  212. }
  213. #define FUCBStore( pfucb ) \
  214. { \
  215. (pfucb)->csrstatStore = PcsrCurrent( pfucb )->csrstat; \
  216. (pfucb)->bmStore = PcsrCurrent( pfucb )->bm; \
  217. (pfucb)->itemStore = PcsrCurrent( pfucb )->item; \
  218. }
  219. #define FUCBResetStore( pfucb ) \
  220. { \
  221. (pfucb)->bmStore = 0; \
  222. }
  223. #define FUCBRestore( pfucb ) \
  224. { \
  225. if ( (pfucb)->bmStore != isridNull && (pfucb)->bmStore != sridNull ) \
  226. { \
  227. PcsrCurrent( pfucb )->csrstat = (pfucb)->csrstatStore; \
  228. Assert( (pfucb)->csrstatStore == csrstatOnDataRoot || \
  229. (pfucb)->csrstatStore == csrstatDeferMoveFirst || \
  230. (pfucb)->csrstatStore == csrstatBeforeFirst || \
  231. (pfucb)->csrstatStore == csrstatAfterLast || \
  232. (pfucb)->bmStore != sridNull ); \
  233. PcsrCurrent( pfucb )->bm = (pfucb)->bmStore; \
  234. PcsrCurrent( pfucb )->item = (pfucb)->itemStore; \
  235. PcsrCurrent( pfucb )->qwDBTime = qwDBTimeNull; \
  236. } \
  237. }
  238. #ifdef PREREAD
  239. /* Preread flag
  240. /**/
  241. #define FFUCBPreread( pfucb ) ( (pfucb)->fPreread )
  242. #define FUCBSetPreread( pfucb ) ( (pfucb)->fPreread = 1 )
  243. #define FUCBResetPreread( pfucb ) ( (pfucb)->fPreread = 0 )
  244. /* Preread direction flag
  245. /**/
  246. #define FFUCBPrereadDir( pfucb ) ( (pfucb)->fPrereadDir )
  247. /* a bit field is not guaranteed to be signed or unsigned. we use double negation
  248. /* to ensure that we will get a '1' or a '0'
  249. /**/
  250. #define FFUCBPrereadForward( pfucb ) ( !!(pfucb)->fPrereadDir)
  251. #define FFUCBPrereadBackward( pfucb ) ( (pfucb)->fPrereadDir == 0)
  252. #define FUCBSetPrereadForward( pfucb ) ( (pfucb)->fPrereadDir = 1 )
  253. #define FUCBSetPrereadBackward( pfucb ) ( (pfucb)->fPrereadDir = 0 )
  254. /* Preread counter
  255. /**/
  256. #define IFUCBPrereadCount( pfucb ) ( (pfucb)->cbPrereadCount )
  257. #define FUCBResetPrereadCount( pfucb ) ( (pfucb)->cbPrereadCount = 0, (pfucb)->cpgnoLastPreread = 0 )
  258. #define FUCBIncrementPrereadCount( pfucb, cb ) ( ((pfucb)->cbPrereadCount) += cb )
  259. #endif // PREREAD
  260. /* navigate level support
  261. /**/
  262. #define LevelFUCBNavigate( pfucbT ) ((pfucbT)->levelNavigate)
  263. #define FUCBSetLevelNavigate( pfucbT, levelT ) \
  264. { \
  265. Assert( fRecovering || ( (levelT) >= levelMin && \
  266. (levelT) <= (pfucbT)->ppib->level ) ); \
  267. Assert( fRecovering || ( (pfucbT)->levelNavigate >= levelMin && \
  268. (pfucbT)->levelNavigate <= (pfucbT)->ppib->level + 1 ) ); \
  269. (pfucbT)->levelNavigate = (levelT); \
  270. }
  271. typedef struct tagLVBuf
  272. {
  273. LONG lid;
  274. BYTE *pLV;
  275. LONG cbLVSize;
  276. struct tagLVBuf *pLVBufNext;
  277. } LVBUF;
  278. /* file use control block
  279. /**/
  280. struct _fucb
  281. {
  282. // ===== chaining fields =====
  283. struct _pib *ppib; // user that opened this FUCB
  284. struct _fucb *pfucbNext; // Next FUCB of this user
  285. union
  286. {
  287. FCB *pfcb; // if wFlags & fFUCBIndex
  288. struct _scb *pscb; // if wFlags & fFUCBSort
  289. } u;
  290. struct _fucb *pfucbNextInstance; // Next Instance of this file
  291. // ===== currency =====
  292. struct _csr *pcsr;
  293. // ===== stored currency =====
  294. SRID bmStore; // stored bookmark
  295. SRID itemStore; // stored item
  296. SRID sridFather; // SRID of visible father
  297. LONG ispairCurr; // (SORT) current record
  298. ULONG ulChecksum; // checksum of record -- used only for optimistic locking
  299. KEY keyNode; // key of current node
  300. LINE lineData; // current data pointed in pcsr
  301. CSRSTAT csrstatStore; // stored CSR status
  302. LEVEL levelOpen; // transaction level of open
  303. LEVEL levelNavigate; // transaction level of navigation
  304. // ===== interface to Storage System =====
  305. SSIB ssib; // SSIB associated with this FUCB
  306. struct _bf *pbfEmpty; // write latched empty page
  307. INT cpgnoLastPreread; // last read-ahead number of pages
  308. PGNO pgnoLastPreread; // last read-ahead pn
  309. // ===== maintained by rec man =====
  310. JET_TABLEID tableid; // JET tableid for dispatched cursors
  311. struct _fucb *pfucbCurIndex; // current secondary index
  312. struct _bf *pbfWorkBuf; // working buffer for Insert/Replace
  313. LINE lineWorkBuf; // working buffer for Insert/Replace
  314. BYTE rgbitSet[32];
  315. CBSTAT cbstat; // copy buffer status
  316. LEVEL levelPrep; // level copy buffer prepared
  317. CBSTAT cbstatPrev; // previous copy buffer status for rollback
  318. LVBUF *pLVBuf;
  319. // ====== space manager work area =======
  320. PGNO pgnoLast; // last page of extent
  321. CPG cpgAvail; // number of remaining pages
  322. INT fExtent; // work area flag
  323. // ===== flags for FUCB =====
  324. /*
  325. /* fFUCBDeferClose is set by cursor DIRClose and reset by ErrDIROpen.
  326. /*
  327. /* fFUCBDeferGotoBookmark is set by non-clustered index navigation and
  328. /* reset by record status, ErrIsamMove( 0 ), and column retrieval.
  329. /*
  330. /* fFUCBGetBookmark is set by get bookmark and is reset by ErrFUCBOpen.
  331. /**/
  332. union {
  333. ULONG ulFlags;
  334. struct {
  335. INT fIndex:1; // FUCB is for index
  336. INT fNonClustered:1; // FUCB for nonclustered index
  337. INT fSort:1; // FUCB is for sort
  338. INT fSystemTable:1; // System table cursor
  339. INT fWrite:1; // cursor can write
  340. INT fDenyRead:1; // deny read flag
  341. INT fDenyWrite:1; // deny write flag
  342. INT fUnused:1; // no longer used
  343. INT fDeferClose:1; // FUCB is awaiting close
  344. INT fDeferGotoBookmark:1; // clustered cursor position
  345. INT fGetBookmark:1; // cursor got bookmark
  346. INT fLimstat:1; // range limit
  347. INT fInclusive:1; // inclusive range
  348. INT fUpper:1; // upper range limit
  349. INT fFull:1; // all CSRs including invisible CSRs
  350. INT fUpdateSeparateLV:1;// long value updated
  351. INT fDeferredChecksum:1;// checksum calculation deferred.
  352. INT fSequential:1; // will traverse sequentially
  353. #ifdef PREREAD
  354. INT fPreread:1; // we are currently reading ahead
  355. INT fPrereadDir:1; // TRUE if we are prereading forward, FALSE if we are prereading backwards
  356. #endif // PREREAD
  357. };
  358. };
  359. // ===== maintained by dir man =====
  360. BYTE *pbKey; // search key buffer
  361. DBID dbid; // database id
  362. #ifdef DISPATCHING
  363. VDBID vdbid; // Virtual DBID back pointer.
  364. #endif
  365. KS ks; // search key buffer status
  366. UINT cbKey; // key size
  367. INT fVtid : 1; // persistant flag cursor has vtid
  368. INT fVersioned : 1; // persistant falg cursor made version
  369. #ifdef PREREAD
  370. ULONG cbPrereadCount; // count of bytes read sequentially
  371. #endif PREREAD
  372. #ifdef PCACHE_OPTIMIZATION
  373. /* pad to multiple of 32 bytes
  374. /**/
  375. #ifdef PREREAD
  376. BYTE rgbFiller[16];
  377. #else // !PREREAD
  378. BYTE rgbFiller[20];
  379. #endif // PREREAD
  380. #endif
  381. };
  382. #define PfucbMEMAlloc() (FUCB*)PbMEMAlloc(iresFUCB)
  383. #ifdef DEBUG /* Debug check for illegal use of freed fucb */
  384. #define MEMReleasePfucb(pfucb) { MEMRelease(iresFUCB, (BYTE*)(pfucb)); pfucb = pfucbNil; }
  385. #else
  386. #define MEMReleasePfucb(pfucb) { MEMRelease(iresFUCB, (BYTE*)(pfucb)); }
  387. #endif
  388. #ifdef DEBUG
  389. #define CheckTable( ppibT, pfucb ) \
  390. { \
  391. Assert( pfucb->ppib == ppibT ); \
  392. Assert( fRecovering || FFUCBIndex( pfucb ) ); \
  393. Assert( !( FFUCBSort( pfucb ) ) ); \
  394. Assert( pfucb->u.pfcb != NULL ); \
  395. }
  396. #define CheckSort( ppibT, pfucb ) \
  397. { \
  398. Assert( pfucb->ppib == ppibT ); \
  399. Assert( FFUCBSort( pfucb ) ); \
  400. Assert( !( FFUCBIndex( pfucb ) ) ); \
  401. Assert( pfucb->u.pscb != NULL ); \
  402. }
  403. #define CheckFUCB( ppibT, pfucb ) \
  404. { \
  405. Assert( pfucb->ppib == ppibT ); \
  406. Assert( pfucb->u.pfcb != NULL ); \
  407. }
  408. #define CheckNonClustered( pfucb ) \
  409. { \
  410. Assert( (pfucb)->pfucbCurIndex == pfucbNil || \
  411. FFUCBNonClustered( (pfucb)->pfucbCurIndex ) ); \
  412. }
  413. #else /* !DEBUG */
  414. #define CheckSort( ppib, pfucb )
  415. #define CheckTable( ppib, pfucb )
  416. #define CheckFUCB( ppib, pfucb )
  417. #define CheckNonClustered( pfucb )
  418. #endif /* !DEBUG */
  419. #define PcsrCurrent( pfucb ) ( (pfucb)->pcsr )
  420. #define BmOfPfucb( pfucb ) ( (pfucb)->pcsr->bm )
  421. #define FUCBCheckUpdatable( pfucb ) \
  422. ( FFUCBUpdatable( pfucb ) ? JET_errSuccess : \
  423. ErrERRCheck( JET_errPermissionDenied ) )
  424. /* set column bit array macros
  425. /**/
  426. #define FUCBResetColumnSet( pfucb ) \
  427. memset( pfucb->rgbitSet, 0x00, 32 )
  428. STATIC INLINE VOID FUCBSetColumnSet( FUCB * pfucb, FID fid )
  429. {
  430. pfucb->rgbitSet[IbFromFid( fid )] |= IbitFromFid( fid );
  431. }
  432. STATIC INLINE BOOL FFUCBColumnSet( const FUCB * pfucb, FID fid )
  433. {
  434. return (pfucb->rgbitSet[IbFromFid( fid )] & IbitFromFid( fid ));
  435. }
  436. STATIC INLINE BOOL FFUCBTaggedColumnSet( const FUCB * pfucb )
  437. {
  438. INT ib;
  439. for ( ib = cbitFixedVariable/8 ; ib < (cbitTagged+cbitFixedVariable)/8; ib++ )
  440. {
  441. if ( pfucb->rgbitSet[ib] )
  442. return fTrue;
  443. }
  444. return fFalse;
  445. }
  446. ERR ErrFUCBAllocCSR( CSR **ppcsr );
  447. ERR ErrFUCBNewCSR( FUCB *pfucb );
  448. VOID FUCBFreeCSR( FUCB *pfucb );
  449. VOID FUCBFreePath( CSR **ppcsr, CSR *pcsrMark );
  450. ERR ErrFUCBOpen( PIB *ppib, DBID dbid, FUCB **ppfucb );
  451. VOID FUCBClose( FUCB *pfucb );
  452. VOID FUCBRemoveInvisible(CSR **ppcsr);
  453. VOID FUCBSetIndexRange( FUCB *pfucb, JET_GRBIT grbit );
  454. VOID FUCBResetIndexRange( FUCB *pfucb );
  455. ERR ErrFUCBCheckIndexRange( FUCB *pfucb );
  456.