Source code of Windows XP (NT5)
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.

407 lines
16 KiB

  1. //============== DAE: OS/2 Database Access Engine ===================
  2. //============== fucb.h: File Use Control Block ===================
  3. /* describes exact placement of CSR and meaning of CSR's pgno:itag
  4. /**/
  5. typedef INT CSRSTAT;
  6. #define csrstatOnCurNode 0 // pgno:itag == node CSR is ON
  7. #define csrstatBeforeCurNode 1 // pgno:itag == node CSR is BEFORE
  8. #define csrstatAfterCurNode 2 // pgno:itag == node CSR is AFTER,
  9. #define csrstatDeferGotoBookmark 3 // valid bm
  10. #define csrstatAfterLast 4 // no pgno:itag
  11. #define csrstatBeforeFirst 5 // no pgno:itag
  12. #define csrstatOnFDPNode 6 // pgno:itag == FDP root
  13. #define csrstatDeferMoveFirst 7 // on first node
  14. #define csrstatOnDataRoot 8 // on FCB data root node
  15. /* Currency Stack Register
  16. /**/
  17. struct _csr
  18. {
  19. ULONG ulDBTime; // page time stamp
  20. struct _csr *pcsrPath; // parent currency
  21. PGNO pgno; // pgno of node page
  22. SRID bm; // bookmark of node
  23. SRID item; // item, set to sridInvisibleCSR if invisible CSR
  24. CSRSTAT csrstat; // status of csr relative to node
  25. INT itag; // node itag
  26. INT isrid; // index of item in item list
  27. INT itagFather; // itag of father
  28. INT ibSon; // index of son in father son table
  29. };
  30. /* allow invisible CSRs to be identified
  31. /**/
  32. #define sridInvisibleCSR ((SRID)(-1))
  33. #define CSRSetInvisible( pcsr ) ( (pcsr)->item = sridInvisibleCSR )
  34. #define CSRResetInvisible( pcsr ) ( (pcsr)->item = sridNull )
  35. #define FCSRInvisible( pcsr ) ( (pcsr)->item == sridInvisibleCSR )
  36. #define PcsrMEMAlloc() (CSR*)PbMEMAlloc(iresCSR)
  37. #ifdef DEBUG /* Debug check for illegal use of freed csr */
  38. #define MEMReleasePcsr(pcsr) { MEMRelease(iresCSR, (BYTE*)(pcsr)); pcsr = pcsrNil; }
  39. #else
  40. #define MEMReleasePcsr(pcsr) { MEMRelease(iresCSR, (BYTE*)(pcsr)); }
  41. #endif
  42. /* CSR constants
  43. /**/
  44. #define itagNull (-1)
  45. #define isridNull (-1)
  46. #define ibSonNull (-1)
  47. /* flags for FUCB
  48. /*
  49. /* fFUCBTaggedSet is set by column set, and reset by prepare replace
  50. /* and prepare insert.
  51. /*
  52. /* fFUCBDeferClose is set by cursor DIRClose and reset by ErrDIROpen.
  53. /*
  54. /* fFUCBDeferGotoBookmark is set by non-clustered index navigation and
  55. /* reset by record status, ErrIsamMove( 0 ), and column retrieval.
  56. /*
  57. /* fFUCBGetBookmark is set by get bookmark and is reset by ErrFUCBOpen.
  58. /**/
  59. #define fFUCBIndex (1<<0) // FUCB is for index
  60. #define fFUCBNonClustered (1<<1) // FUCB for nonclustered index
  61. #define fFUCBSort (1<<2) // FUCB is for sort
  62. #define fFUCBSystemTable (1<<3) // System table cursor
  63. #define fFUCBWrite (1<<4) // cursor can write
  64. #define fFUCBDenyRead (1<<5) // deny read flag
  65. #define fFUCBDenyWrite (1<<6) // deny write flag
  66. #define fFUCBTaggedSet (1<<7) // tagged column
  67. #define fFUCBDeferClose (1<<9) // FUCB is awaiting close
  68. #define fFUCBDeferGotoBookmark (1<<10) // clustered cursor position
  69. #define fFUCBGetBookmark (1<<11) // cursor got bookmark
  70. #define fFUCBLimstat (1<<12) // range limit
  71. #define fFUCBInclusive (1<<13) // inclusive range
  72. #define fFUCBUpper (1<<14) // upper range limit
  73. #define fFUCBFull (1<<15) // all CSRs including invisible CSRs
  74. #define fFUCBUpdateSeparateLV (1<<16) // long value updated
  75. /* the following flags need to be prevent reuse of cursor
  76. /* after deferred closed. This is done to correctly release
  77. /* domain flags when commit/rollback to transaction level 0.
  78. /**/
  79. #define fFUCBNotReuse ( fFUCBDenyRead | fFUCBDenyWrite )
  80. #define FFUCBNotReuse( pfucb ) ( (pfucb)->wFlags & fFUCBNotReuse )
  81. #define FFUCBIndex( pfucb ) ( (pfucb)->wFlags & fFUCBIndex )
  82. #define FUCBSetIndex( pfucb ) ( (pfucb)->wFlags |= fFUCBIndex )
  83. #define FUCBResetIndex( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBIndex) )
  84. #define FFUCBNonClustered( pfucb ) ( (pfucb)->wFlags & fFUCBNonClustered )
  85. #define FUCBSetNonClustered( pfucb ) ( (pfucb)->wFlags |= fFUCBNonClustered )
  86. #define FUCBResetNonClustered( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBNonClustered) )
  87. #define FFUCBSort( pfucb ) ( (pfucb)->wFlags & fFUCBSort )
  88. #define FUCBSetSort( pfucb ) ( (pfucb)->wFlags |= fFUCBSort )
  89. #define FUCBResetSort( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBSort) )
  90. #define FFUCBSystemTable( pfucb ) ( (pfucb)->wFlags & fFUCBSystemTable )
  91. #define FUCBSetSystemTable( pfucb ) ( (pfucb)->wFlags |= fFUCBSystemTable )
  92. #define FUCBResetSystemTable( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBSystemTable) )
  93. #define FFUCBUpdatable( pfucb ) ( (pfucb)->wFlags & fFUCBWrite )
  94. #define FUCBSetUpdatable( pfucb ) ( (pfucb)->wFlags |= fFUCBWrite )
  95. #define FUCBResetUpdatable( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBWrite) )
  96. #define FFUCBDenyWrite( pfucb ) ( (pfucb)->wFlags & fFUCBDenyWrite )
  97. #define FUCBSetDenyWrite( pfucb ) ( (pfucb)->wFlags |= fFUCBDenyWrite )
  98. #define FUCBResetDenyWrite( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBDenyWrite) )
  99. #define FFUCBDenyRead( pfucb ) ( (pfucb)->wFlags & fFUCBDenyRead )
  100. #define FUCBSetDenyRead( pfucb ) ( (pfucb)->wFlags |= fFUCBDenyRead )
  101. #define FUCBResetDenyRead( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBDenyRead) )
  102. #define FFUCBTaggedSet( pfucb ) ( (pfucb)->wFlags & fFUCBTaggedSet )
  103. #define FUCBSetTaggedSet( pfucb ) ( (pfucb)->wFlags |= fFUCBTaggedSet )
  104. #define FUCBResetTaggedSet( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBTaggedSet) )
  105. #define FFUCBUpdateSeparateLV( pfucb ) ( (pfucb)->wFlags & fFUCBUpdateSeparateLV )
  106. #define FUCBSetUpdateSeparateLV( pfucb ) ( (pfucb)->wFlags |= fFUCBUpdateSeparateLV )
  107. #define FUCBResetUpdateSeparateLV( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBUpdateSeparateLV) )
  108. #define FFUCBDeferClosed( pfucb ) ( (pfucb)->wFlags & fFUCBDeferClose )
  109. #define FUCBSetDeferClose( pfucb ) ( (pfucb)->wFlags |= fFUCBDeferClose )
  110. #define FUCBResetDeferClose( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBDeferClose) )
  111. #define FFUCBDeferGotoBookmark( pfucb ) \
  112. ( (pfucb)->wFlags & fFUCBDeferGotoBookmark )
  113. #define FUCBSetDeferGotoBookmark( pfucb ) \
  114. ( (pfucb)->wFlags |= fFUCBDeferGotoBookmark )
  115. #define FUCBResetDeferGotoBookmark( pfucb ) \
  116. ( (pfucb)->wFlags &= ~(fFUCBDeferGotoBookmark) )
  117. #define FFUCBGetBookmark( pfucb ) \
  118. ( (pfucb)->wFlags & fFUCBGetBookmark )
  119. #define FUCBSetGetBookmark( pfucb ) \
  120. ( (pfucb)->wFlags |= fFUCBGetBookmark )
  121. #define FUCBResetGetBookmark( pfucb ) \
  122. ( (pfucb)->wFlags &= ~(fFUCBGetBookmark) )
  123. #define FFUCBLimstat( pfucb ) ( (pfucb)->wFlags & fFUCBLimstat )
  124. #define FUCBSetLimstat( pfucb ) ( (pfucb)->wFlags |= fFUCBLimstat )
  125. #define FUCBResetLimstat( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBLimstat) )
  126. #define FFUCBInclusive( pfucb ) ( (pfucb)->wFlags & fFUCBInclusive )
  127. #define FUCBSetInclusive( pfucb ) ( (pfucb)->wFlags |= fFUCBInclusive )
  128. #define FUCBResetInclusive( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBInclusive) )
  129. #define FFUCBUpper( pfucb ) ( (pfucb)->wFlags & fFUCBUpper )
  130. #define FUCBSetUpper( pfucb ) ( (pfucb)->wFlags |= fFUCBUpper )
  131. #define FUCBResetUpper( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBUpper) )
  132. #define FFUCBFull( pfucb ) ( (pfucb)->wFlags & fFUCBFull )
  133. #define FUCBSetFull( pfucb ) ( (pfucb)->wFlags |= fFUCBFull )
  134. #define FUCBResetFull( pfucb ) ( (pfucb)->wFlags &= ~(fFUCBFull) )
  135. #define FFUCBVersioned( pfucb ) ( (pfucb)->fVersioned )
  136. #define FUCBSetVersioned( pfucb ) ( (pfucb)->fVersioned = fTrue )
  137. #define FUCBResetVersioned( pfucb ) ( (pfucb)->fVersioned = fFalse )
  138. /* record modification copy buffer status
  139. /**/
  140. typedef INT CBSTAT;
  141. #define fCBSTATNull 0
  142. #define fCBSTATInsert (1<<0)
  143. #define fCBSTATReplace (1<<1)
  144. #define fCBSTATSet (1<<2)
  145. #define fCBSTATLock (1<<3)
  146. #define fCBSTATAppendItem (1<<4)
  147. #define StoreChecksum( pfucb ) \
  148. ( (pfucb)->ulChecksum = \
  149. UlChecksum( (pfucb)->lineData.pb, (pfucb)->lineData.cb ) )
  150. #define PrepareInsert( pfucb ) \
  151. ( (pfucb)->cbstat = fCBSTATInsert, \
  152. (pfucb)->levelPrep = (pfucb)->ppib->level )
  153. #define PrepareReplaceNoLock( pfucb ) \
  154. ( (pfucb)->cbstat = fCBSTATReplace, \
  155. (pfucb)->levelPrep = (pfucb)->ppib->level )
  156. #define PrepareReplace( pfucb ) \
  157. ( (pfucb)->cbstat = fCBSTATReplace | fCBSTATLock, \
  158. (pfucb)->levelPrep = (pfucb)->ppib->level )
  159. #define PrepareSet( pfucb ) \
  160. ( (pfucb)->cbstat = fCBSTATSet, \
  161. (pfucb)->levelPrep = (pfucb)->ppib->level )
  162. #define PrepareAppendItem( pfucb ) \
  163. ( (pfucb)->cbstat = fCBSTATAppendItem )
  164. typedef struct {
  165. INT isrid;
  166. SRID rgsrid[(cbPage - sizeof(INT))/sizeof(SRID)];
  167. } APPENDITEM;
  168. #define csridAppendItemMax ((cbPage - sizeof(INT))/sizeof(SRID))
  169. #define IsridAppendItemOfPfucb( pfucb ) (((APPENDITEM *)(pfucb)->lineWorkBuf.pb)->isrid)
  170. #define RgsridAppendItemOfPfucb( pfucb ) (((APPENDITEM *)(pfucb)->lineWorkBuf.pb)->rgsrid)
  171. #define FChecksum( pfucb ) \
  172. ( (pfucb)->ulChecksum == UlChecksum( (pfucb)->lineData.pb, \
  173. (pfucb)->lineData.cb ) )
  174. #define FFUCBReplacePrepared( pfucb ) \
  175. ( (pfucb)->cbstat & fCBSTATReplace )
  176. #define FFUCBReplaceNoLockPrepared( pfucb ) \
  177. ( !( (pfucb)->cbstat & fCBSTATLock ) && \
  178. FFUCBReplacePrepared( pfucb ) )
  179. #define FFUCBInsertPrepared( pfucb ) \
  180. ( (pfucb)->cbstat & fCBSTATInsert )
  181. #define FFUCBSetPrepared( pfucb ) \
  182. ( (pfucb)->cbstat != fCBSTATNull && \
  183. (pfucb)->levelPrep == (pfucb)->ppib->level )
  184. #define FFUCBRetPrepared( pfucb ) \
  185. ( (pfucb)->cbstat != fCBSTATNull )
  186. #define FFUCBUpdatePrepared( pfucb ) ((pfucb)->cbstat != fCBSTATNull )
  187. #define FUCBResetCbstat( pfucb ) ( (pfucb)->cbstat = fCBSTATNull )
  188. typedef INT KS;
  189. #define ksNull 0
  190. #define ksPrepared (1<<0)
  191. #define ksTooBig (1<<1)
  192. #define KSReset( pfucb ) ( (pfucb)->ks = ksNull )
  193. #define KSSetPrepare( pfucb ) ( (pfucb)->ks |= ksPrepared )
  194. #define KSSetTooBig( pfucb ) ( (pfucb)->ks |= ksTooBig )
  195. #define FKSPrepared( pfucb ) ( (pfucb)->ks & ksPrepared )
  196. #define FKSTooBig( pfucb ) ( (pfucb)->ks & ksTooBig )
  197. /* set bit arrary marcos
  198. /**/
  199. #define FUCBResetColumnSet( pfucb ) \
  200. ( memset( (pfucb)->rgbitSet, 0x00, 32 ) )
  201. #define FUCBSetFixedColumnSet( pfucb, fid ) \
  202. ( (pfucb)->rgbitSet[(fid - fidFixedLeast)/8] |= 1 << \
  203. (fid-fidFixedLeast) % 8 )
  204. #define FUCBSetVarColumnSet( pfucb, fid ) \
  205. ( (pfucb)->rgbitSet[16 + (fid - fidVarLeast)/8] |= 1 << \
  206. (fid-fidVarLeast) % 8 )
  207. #define FFUCBColumnSet( pfucb, ibitCol ) \
  208. ( (pfucb)->rgbitSet[(ibitCol)/8] & ( 1 << ( (ibitCol) % 8 ) ) )
  209. #define FUCBStore( pfucb ) \
  210. { \
  211. (pfucb)->csrstatStore = PcsrCurrent( pfucb )->csrstat; \
  212. (pfucb)->bmStore = PcsrCurrent( pfucb )->bm; \
  213. (pfucb)->itemStore = PcsrCurrent( pfucb )->item; \
  214. }
  215. #define FUCBResetStore( pfucb ) \
  216. { \
  217. (pfucb)->bmStore = 0; \
  218. }
  219. #define FUCBRestore( pfucb ) \
  220. { \
  221. if ( (pfucb)->bmStore != isridNull && (pfucb)->bmStore != sridNull ) \
  222. { \
  223. PcsrCurrent( pfucb )->csrstat = (pfucb)->csrstatStore; \
  224. Assert( (pfucb)->csrstatStore == csrstatOnDataRoot || \
  225. (pfucb)->csrstatStore == csrstatDeferMoveFirst || \
  226. (pfucb)->csrstatStore == csrstatBeforeFirst || \
  227. (pfucb)->csrstatStore == csrstatAfterLast || \
  228. (pfucb)->bmStore != sridNull ); \
  229. PcsrCurrent( pfucb )->bm = (pfucb)->bmStore; \
  230. PcsrCurrent( pfucb )->item = (pfucb)->itemStore; \
  231. PcsrCurrent( pfucb )->ulDBTime = ulDBTimeNull; \
  232. } \
  233. }
  234. /* file use control block
  235. /**/
  236. struct _fucb
  237. {
  238. // ===== chaining fields =====
  239. struct _pib *ppib; // user that opened this FUCB
  240. struct _fucb *pfucbNext; // Next FUCB of this user
  241. union
  242. {
  243. struct _fcb *pfcb; // if wFlags & fFUCBIndex
  244. struct _scb *pscb; // if wFlags & fFUCBSort
  245. } u;
  246. struct _fucb *pfucbNextInstance; // Next Instance of this file
  247. // ===== currency =====
  248. struct _csr *pcsr;
  249. // ===== stored currency =====
  250. SRID bmStore; // stored bookmark
  251. SRID itemStore; // stored item
  252. SRID bmRefresh; // stored bookmark for next/prev retry
  253. SRID sridFather; // SRID of visible father
  254. BYTE **ppbCurrent; // (SORT) current record
  255. ULONG ulChecksum; // checksum of record -- used only for optimistic locking
  256. KEY keyNode; // Key of current node
  257. LINE lineData; // Current data pointed in pcsr
  258. CSRSTAT csrstatStore; // stored CSR status
  259. LEVEL levelOpen;
  260. // ===== interface to Storage System =====
  261. SSIB ssib; // SSIB associated with this FUCB
  262. struct _bf *pbfEmpty; // write latched empty page
  263. UINT cpn; // next read-ahead pn
  264. // ===== maintained by rec man =====
  265. struct _fucb *pfucbCurIndex; // current secondary index
  266. struct _bf *pbfWorkBuf; // working buffer for Insert/Replace
  267. LINE lineWorkBuf; // working buffer for Insert/Replace
  268. ULONG cbRecord; // size of original record
  269. ULONG dbkUpdate; // dbk of record to Replace
  270. BYTE rgbitSet[32];
  271. CBSTAT cbstat; // copy buffer status
  272. LEVEL levelPrep; // level copy buffer prepared
  273. // ====== versioning work area =======
  274. struct _rce *prceLast; // last RCE allocated (used only for Replace)
  275. // ====== space manager work area =======
  276. PGNO pgnoLast; // last page of extent
  277. CPG cpgExtent; // initial extent size
  278. CPG cpgAvail; // number of remaining pages
  279. INT fExtent; // work area flag
  280. // ===== misc fields =====
  281. INT wFlags; // temporary flags
  282. // ===== maintained by dir man =====
  283. BYTE *pbKey; // search key buffer
  284. DBID dbid; // database id
  285. KS ks; // search key buffer status
  286. UINT cbKey; // key size
  287. BOOL fVtid : 1; // persistant flag cursor has vtid
  288. BOOL fVersioned : 1; // persistant falg cursor made version
  289. BOOL fCmprsLg:1;
  290. INT clineDiff;
  291. #define ilineDiffMax 3
  292. LINE rglineDiff[ilineDiffMax];
  293. };
  294. #define PfucbMEMAlloc() (FUCB*)PbMEMAlloc(iresFUCB)
  295. #ifdef DEBUG /* Debug check for illegal use of freed fucb */
  296. #define MEMReleasePfucb(pfucb) { MEMRelease(iresFUCB, (BYTE*)(pfucb)); pfucb = pfucbNil; }
  297. #else
  298. #define MEMReleasePfucb(pfucb) { MEMRelease(iresFUCB, (BYTE*)(pfucb)); }
  299. #endif
  300. #ifdef DEBUG
  301. #define CheckTable( ppibT, pfucb ) \
  302. { \
  303. Assert( pfucb->ppib == ppibT ); \
  304. Assert( fRecovering || FFUCBIndex( pfucb ) ); \
  305. Assert( !( FFUCBSort( pfucb ) ) ); \
  306. Assert( pfucb->u.pfcb != NULL ); \
  307. }
  308. #define CheckSort( ppibT, pfucb ) \
  309. { \
  310. Assert( pfucb->ppib == ppibT ); \
  311. Assert( FFUCBSort( pfucb ) ); \
  312. Assert( !( FFUCBIndex( pfucb ) ) ); \
  313. Assert( pfucb->u.pscb != NULL ); \
  314. }
  315. #define CheckFUCB( ppibT, pfucb ) \
  316. { \
  317. Assert( pfucb->ppib == ppibT ); \
  318. Assert( pfucb->u.pfcb != NULL ); \
  319. }
  320. #define CheckNonClustered( pfucb ) \
  321. { \
  322. Assert( (pfucb)->pfucbCurIndex == pfucbNil || \
  323. FFUCBNonClustered( (pfucb)->pfucbCurIndex ) ); \
  324. }
  325. #else /* !DEBUG */
  326. #define CheckSort( ppib, pfucb )
  327. #define CheckTable( ppib, pfucb )
  328. #define CheckFUCB( ppib, pfucb )
  329. #define CheckNonClustered( pfucb )
  330. #endif /* !DEBUG */
  331. #define PcsrCurrent( pfucb ) ( (pfucb)->pcsr )
  332. #define BmOfPfucb( pfucb ) ( (pfucb)->pcsr->bm )
  333. #define FUCBCheckUpdatable( pfucb ) \
  334. ( FFUCBUpdatable( pfucb ) ? JET_errSuccess : JET_errPermissionDenied )
  335. ERR ErrFUCBAllocCSR( CSR **ppcsr );
  336. ERR ErrFUCBNewCSR( FUCB *pfucb );
  337. VOID FUCBFreeCSR( FUCB *pfucb );
  338. VOID FUCBFreePath( CSR **ppcsr, CSR *pcsrMark );
  339. ERR ErrFUCBOpen( PIB *ppib, DBID dbid, FUCB **ppfucb );
  340. VOID FUCBClose( FUCB *pfucb );
  341. VOID FUCBRemoveInvisible(CSR **ppcsr);
  342. VOID FUCBSetIndexRange( FUCB *pfucb, JET_GRBIT grbit );
  343. VOID FUCBResetIndexRange( FUCB *pfucb );
  344. ERR ErrFUCBCheckIndexRange( FUCB *pfucb );
  345.