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.

242 lines
7.6 KiB

  1. //
  2. //------ Page Structure ---------------------------------------------------
  3. //
  4. #define cbPage 4096 // database logical page size
  5. #define cbSec 4096 // minimum disk Read/Write unit. It
  6. // should be 512, but MIPS NT cache
  7. // bug force it be 1024.
  8. #define ctagMax 256 // default limit on number of tags
  9. #define fNoTagLimit (1<<0) // ignore limit on number of tags
  10. #define fUseNewTag (1<<1) // don't reuse tags
  11. typedef BYTE PGTYP;
  12. // the pragma is bad for efficiency, but we need it here so that the
  13. // THREEBYTES will not be aligned on 4-byte boundary
  14. #pragma pack(1)
  15. typedef struct _pghdr
  16. {
  17. ULONG ulChecksum; // checksum of page, always 1st byte
  18. ULONG ulDBTime; // dbCounter when page was dirtied
  19. PGNO pgnoFDP; // pgno of FDP which owns this page
  20. SHORT cbFreeTotal; // total free bytes
  21. SHORT ibLastUsed; // lower bound on used bytes
  22. SHORT ctagMac; // upper bound on used tags
  23. SHORT itagFree; // start of tag free tags
  24. SHORT cVersion; // count of nodes with fVersion flag set
  25. THREEBYTES pgnoPrev; // pgno of previous page
  26. THREEBYTES pgnoNext; // pgno of next page
  27. } PGHDR;
  28. typedef struct _pgtrlr
  29. {
  30. PGTYP pgtyp;
  31. THREEBYTES pgnoThisPage;
  32. } PGTRLR;
  33. typedef struct _tag
  34. {
  35. SHORT cb;
  36. SHORT ib;
  37. } TAG;
  38. /* tag status
  39. /**/
  40. typedef enum { tsLine, tsVacant, tsLink } TS;
  41. typedef struct _page
  42. {
  43. PGHDR pghdr;
  44. TAG rgtag[1];
  45. BYTE rgbFiller[ cbPage -
  46. sizeof(PGHDR) - // pghdr
  47. sizeof(TAG) - // rgtag[1]
  48. sizeof(BYTE) - // rgbData[1]
  49. sizeof(PGTYP) - // pgtyp
  50. sizeof(THREEBYTES) ]; // pgnoThisPage
  51. BYTE rgbData[1];
  52. PGTYP pgtyp;
  53. THREEBYTES pgnoThisPage;
  54. } PAGE;
  55. #pragma pack()
  56. #define bitModified (1<<7)
  57. #define bitLink (1L<<31)
  58. #define pgtypFDP ((PGTYP) 0)
  59. #define pgtypRecord ((PGTYP) 1)
  60. // #define pgtypLong ((PGTYP) 2)
  61. // #define pgtypNonrecord ((PGTYP) 3)
  62. #define pgtypSort ((PGTYP) 4)
  63. #define PMSetPageType( ppage, pgtypT ) ( (ppage)->pgtyp = pgtypT )
  64. #define PgtypPMPageTypeOfPage( ppage ) ((PGTYP)((ppage)->pgtyp & ~(bitModified)))
  65. #ifdef DEBUG
  66. VOID PMSetModified( SSIB *ssib );
  67. VOID PMResetModified( SSIB *pssib );
  68. VOID CheckPgno( PAGE *ppage, PN pn );
  69. #else
  70. #define CheckPgno( ppage, pn )
  71. #define PMSetModified( pssib ) ( (pssib)->pbf->ppage->pgtyp |= bitModified )
  72. #define PMResetModified( pssib ) ( (pssib)->pbf->ppage->pgtyp &= ~(bitModified) )
  73. #endif
  74. #define PgtypPMSetModified( ppage ) ( (ppage)->pgtyp | bitModified )
  75. #define FPMModified( ppage ) ( (ppage)->pgtyp & bitModified )
  76. #define PMSetPgnoFDP( ppage, pgnoT ) ( (ppage)->pghdr.pgnoFDP = pgnoT )
  77. #define PgnoPMPgnoFDPOfPage( ppage ) ( (ppage)->pghdr.pgnoFDP )
  78. #define PMIncVersion( ppage ) ( (ppage)->pghdr.cVersion++ )
  79. #if 0
  80. #define PMDecVersion( ppage ) \
  81. { \
  82. Assert( (ppage)->pghdr.cVersion > 0 ); \
  83. (ppage)->pghdr.cVersion--; \
  84. }
  85. #else
  86. #define PMDecVersion( ppage ) \
  87. { \
  88. if ( (ppage)->pghdr.cVersion > 0 ) \
  89. --(ppage)->pghdr.cVersion; \
  90. }
  91. #endif
  92. #define SetPgno( ppage, pgno ) \
  93. ThreeBytesFromL( (ppage)->pgnoThisPage, (pgno) )
  94. #define SetPgnoNext( ppage, pgno ) \
  95. ThreeBytesFromL( (ppage)->pghdr.pgnoNext, (pgno) )
  96. #define SetPgnoPrev( ppage, pgno ) \
  97. ThreeBytesFromL( (ppage)->pghdr.pgnoPrev, (pgno) )
  98. #define PgnoFromPage( ppage, ppgno ) \
  99. LFromThreeBytes( *(ppgno), (ppage)->pgnoThisPage )
  100. #ifdef DEBUG
  101. #define PgnoNextFromPage( pssib, ppgno ) \
  102. { CheckSSIB( pssib ); LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoNext ); }
  103. #define PgnoPrevFromPage( pssib, ppgno ) \
  104. { CheckSSIB( (pssib) ); LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoPrev ) }
  105. #else
  106. #define PgnoNextFromPage( pssib, ppgno ) \
  107. LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoNext )
  108. #define PgnoPrevFromPage( pssib, ppgno ) \
  109. LFromThreeBytes( *(ppgno), (pssib)->pbf->ppage->pghdr.pgnoPrev )
  110. #endif
  111. #define absdiff( x, y ) ( (x) > (y) ? (x)-(y) : (y)-(x) )
  112. #define pgdiscont( pgno1, pgno2 ) \
  113. ( ( (pgno1) == 0 ) || ( (pgno2) == 0 ) ? 0 \
  114. : absdiff( (pgno1), (pgno2) ) / cpgDiscont )
  115. #define ibPgnoPrevPage ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.pgnoPrev )
  116. #define ibPgnoNextPage ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.pgnoNext )
  117. #define ibCbFreeTotal ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.cbFreeTotal )
  118. #define ibCtagMac ( (INT) (ULONG_PTR)&((PAGE *)0)->pghdr.ctagMac )
  119. #define ibPgtyp ( (INT) (ULONG_PTR)&((PAGE *)0)->pgtyp )
  120. #define CbLastFreeSpace(ppage) \
  121. ((ppage)->pghdr.ibLastUsed \
  122. - sizeof(PGHDR) \
  123. - sizeof(TAG) * (ppage)->pghdr.ctagMac)
  124. #define IbCbFromPtag( ibP, cbP, ptagP ) \
  125. { TAG *_ptagT = ptagP; \
  126. (ibP) = _ptagT->ib; \
  127. (cbP) = _ptagT->cb; \
  128. }
  129. #define PtagFromIbCb( ptagP, ibP, cbP ) \
  130. { TAG *_ptagT = ptagP; \
  131. _ptagT->ib = (SHORT)(ibP); \
  132. _ptagT->cb = (SHORT)(cbP); \
  133. }
  134. #ifdef DEBUG
  135. #define PMGet( pssib, itagT ) CallS( ErrPMGet( pssib, itagT ) )
  136. #else
  137. #define PMGet( pssib, itagT ) \
  138. { \
  139. PAGE *ppageT_ = (pssib)->pbf->ppage; \
  140. TAG *ptagT_ = &(ppageT_->rgtag[itagT]); \
  141. Assert( itagT >= 0 ); \
  142. Assert( itagT < (pssib)->pbf->ppage->pghdr.ctagMac ); \
  143. (pssib)->line.pb = (BYTE *)ppageT_ + ptagT_->ib; \
  144. (pssib)->line.cb = ptagT_->cb; \
  145. }
  146. #endif
  147. #define ItagPMMost( ppage ) ((ppage)->pghdr.ctagMac - 1)
  148. BOOL FPMFreeTag( SSIB *pssib, INT citagReq );
  149. #ifdef DEBUG
  150. #define CbPMFreeSpace( pssib ) ( CheckSSIB(pssib), \
  151. ((INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal) )
  152. #else
  153. #define CbPMFreeSpace( pssib ) ( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal )
  154. #endif
  155. #define ErrPMCheckFreeSpace( pssib, cbT ) \
  156. ( ((INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal) < cbT ? \
  157. errPMOutOfPageSpace : JET_errSuccess )
  158. #define PMAllocFreeSpace( pssib, cb ) \
  159. { \
  160. Assert( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal >= cb ); \
  161. (pssib)->pbf->ppage->pghdr.cbFreeTotal -= cb; \
  162. }
  163. #define PMFreeFreeSpace( pssib, cb ) \
  164. { \
  165. Assert( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal >= 0 ); \
  166. (pssib)->pbf->ppage->pghdr.cbFreeTotal += (SHORT)cb; \
  167. Assert( (INT)(pssib)->pbf->ppage->pghdr.cbFreeTotal < cbPage ); \
  168. }
  169. #ifdef DEBUG
  170. #define AssertBTFOP(pssib) \
  171. Assert( PgtypPMPageTypeOfPage((pssib)->pbf->ppage) == pgtypSort || \
  172. PgtypPMPageTypeOfPage((pssib)->pbf->ppage) == pgtypFDP || \
  173. (pssib)->itag != 0 || \
  174. ( CbNDKey( (pssib)->line.pb ) == 0 && \
  175. !FNDBackLink( *(pssib)->line.pb ) ) \
  176. )
  177. #else
  178. #define AssertBTFOP( pssib )
  179. #endif
  180. #define PbPMGetChunk(pssib, ib) &(((BYTE *)((pssib)->pbf->ppage))[ib])
  181. INT CbPMLinkSpace( SSIB *pssib );
  182. TS TsPMTagstatus( PAGE *ppage, INT itag );
  183. VOID PMNewPage( PAGE *ppage, PGNO pgno, PGTYP pgtyp, PGNO pgnoFDP );
  184. INT ItagPMQueryNextItag( SSIB *pssib );
  185. ERR ErrPMInsert( SSIB *pssib, LINE *rgline, INT cline );
  186. VOID PMDelete( SSIB *ssib );
  187. ERR ErrPMReplace( SSIB *pssib, LINE *rgline, INT cline );
  188. ERR ErrPMGet( SSIB *pssib, INT itag );
  189. VOID PMGetLink( SSIB *pssib, INT itag, LINK *plink );
  190. VOID PMExpungeLink( SSIB *pssib );
  191. VOID PMReplaceWithLink( SSIB *pssib, SRID srid );
  192. VOID PMReplaceLink( SSIB *pssib, SRID srid );
  193. INT CPMIFreeTag( PAGE *ppage );
  194. BOOL FPMEmptyPage( SSIB *pssib );
  195. BOOL FPMLastNodeToDelete( SSIB *pssib );
  196. VOID PMDirty( SSIB *pssib );
  197. VOID PMReadAsync( PIB *ppib, PN pn );
  198. ERR ErrPMAccessPage( FUCB *pfucb, PGNO pgno );
  199. #ifdef DEBUG
  200. VOID PageConsistent( PAGE *ppage );
  201. #endif
  202.