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.

605 lines
18 KiB

  1. #ifndef __DIRAPI_H__
  2. #define __DIRAPI_H__
  3. #pragma once
  4. /**********************************************************
  5. /************** DIR STRUCTURES and CONSTANTS **************
  6. /**********************************************************
  7. /**/
  8. #include "node.h"
  9. /************** DIR API defines and types ******************
  10. /***********************************************************
  11. /**/
  12. typedef struct {
  13. ULONG ulLT;
  14. ULONG ulTotal;
  15. } FRAC;
  16. typedef INT POS;
  17. #define posFirst 0
  18. #define posLast 1
  19. #define posDown 2
  20. #define posFrac 3
  21. #define fDIRNull 0
  22. #define fDIRPurgeParent (1<<0)
  23. #define fDIRBackToFather (1<<1)
  24. #define fDIRNeighborKey (1<<2)
  25. #define fDIRPotentialNode (1<<3)
  26. #define fDIRAllNode (1<<4)
  27. #define fDIRAllPage (1<<5)
  28. #define fDIRReplace (1<<6)
  29. #define fDIRReplaceDuplicate (1<<7)
  30. #define fDIRDuplicate (1<<8)
  31. #define fDIRSpace (1<<9)
  32. #define fDIRVersion (1<<10)
  33. #ifdef INPAGE
  34. #define fDIRInPage (1<<11)
  35. #endif
  36. #define fDIRAppendItem (1<<12)
  37. #define fDIRDeleteItem (1<<13)
  38. #define fDIRNoVersion 0
  39. /* item list nodes not versioned
  40. /**/
  41. #define fDIRItemList fDIRAllNode
  42. struct _dib {
  43. POS pos;
  44. KEY *pkey;
  45. INT fFlags;
  46. };
  47. #define itagOWNEXT 1
  48. #define itagAVAILEXT 2
  49. #define itagLONG 3
  50. #define itagFIELDS 9
  51. #define PgnoFDPOfPfucb(pfucb) ((pfucb)->u.pfcb->pgnoFDP)
  52. #define PgnoRootOfPfucb(pfucb) ((pfucb)->u.pfcb->pgnoRoot)
  53. #define ItagRootOfPfucb(pfucb) ((pfucb)->u.pfcb->itagRoot)
  54. #define ErrDIRGetBookmark( pfucb, psrid ) \
  55. ( PcsrCurrent( pfucb )->csrstat == csrstatOnCurNode || \
  56. PcsrCurrent( pfucb )->csrstat == csrstatDeferGotoBookmark ? \
  57. ( *psrid = PcsrCurrent( pfucb )->bm, JET_errSuccess ) : \
  58. JET_errNoCurrentRecord )
  59. #define DIRGetBookmark( pfucb, psrid ) \
  60. ( *((SRID *)psrid) = PcsrCurrent( pfucb )->bm )
  61. #define DIRGotoBookmark DIRDeferGotoBookmark
  62. #define DIRDeferGotoBookmark( pfucb, bmT ) \
  63. { \
  64. PcsrCurrent( pfucb )->csrstat = csrstatDeferGotoBookmark; \
  65. PcsrCurrent( pfucb )->bm = bmT; \
  66. ( pfucb )->sridFather = sridNull; \
  67. DIRSetRefresh( pfucb ); \
  68. }
  69. #define DIRGotoBookmarkItem( pfucb, bmT, itemT ) \
  70. { \
  71. PcsrCurrent( pfucb )->csrstat = csrstatDeferGotoBookmark; \
  72. PcsrCurrent( pfucb )->bm = bmT; \
  73. PcsrCurrent( pfucb )->item = itemT; \
  74. ( pfucb )->sridFather = sridNull; \
  75. DIRSetRefresh( pfucb ); \
  76. }
  77. #define DIRGotoPgnoItag( pfucb, pgnoT, itagT ) \
  78. { \
  79. PcsrCurrent( pfucb )->csrstat = csrstatOnCurNode; \
  80. PcsrCurrent( pfucb )->bm = SridOfPgnoItag( (pgnoT), (itagT) ); \
  81. PcsrCurrent( pfucb )->pgno = (pgnoT); \
  82. PcsrCurrent( pfucb )->itag = (itagT); \
  83. ( pfucb )->sridFather = sridNull; \
  84. DIRSetRefresh( pfucb ); \
  85. }
  86. #define DIRGotoFDPRoot( pfucb ) \
  87. { \
  88. PcsrCurrent( pfucb )->csrstat = csrstatOnFDPNode; \
  89. PcsrCurrent( pfucb )->bm = \
  90. SridOfPgnoItag( PgnoFDPOfPfucb( pfucb ), itagFOP ); \
  91. PcsrCurrent( pfucb )->pgno = PgnoFDPOfPfucb( pfucb ); \
  92. PcsrCurrent( pfucb )->itag = itagFOP; \
  93. PcsrCurrent( pfucb )->itagFather = itagFOP; \
  94. ( pfucb )->sridFather = sridNull; \
  95. if ( !FReadAccessPage( pfucb, PcsrCurrent( pfucb )->pgno ) ) \
  96. { \
  97. if ( ErrSTReadAccessPage( pfucb, \
  98. PcsrCurrent( pfucb )->pgno ) < 0 ) \
  99. { \
  100. DIRSetRefresh( pfucb ); \
  101. } \
  102. else \
  103. { \
  104. NDGet( pfucb, PcsrCurrent( pfucb )->itag ); \
  105. DIRSetFresh( pfucb ); \
  106. } \
  107. } \
  108. }
  109. #define DIRGotoOWNEXT( pfucb, pgnoT ) \
  110. { \
  111. DIRGotoPgnoItag( pfucb, pgnoT, itagOWNEXT ); \
  112. Assert( ( pfucb )->sridFather == sridNull ); \
  113. PcsrCurrent( pfucb )->itagFather = itagFOP; \
  114. }
  115. #define DIRGotoAVAILEXT( pfucb, pgnoT ) \
  116. { \
  117. DIRGotoPgnoItag( pfucb, pgnoT, itagAVAILEXT ); \
  118. PcsrCurrent( pfucb )->itagFather = itagFOP; \
  119. }
  120. #define DIRGotoLongRoot( pfucb ) \
  121. { \
  122. PcsrCurrent( pfucb )->csrstat = csrstatOnCurNode; \
  123. PcsrCurrent( pfucb )->bm = \
  124. SridOfPgnoItag( PgnoFDPOfPfucb( pfucb ), itagLONG ); \
  125. PcsrCurrent( pfucb )->pgno = PgnoFDPOfPfucb( pfucb ); \
  126. PcsrCurrent( pfucb )->itag = itagLONG; \
  127. PcsrCurrent( pfucb )->itagFather = itagNull; \
  128. ( pfucb )->sridFather = sridNull; \
  129. if ( !FReadAccessPage( pfucb, PcsrCurrent( pfucb )->pgno ) ) \
  130. { \
  131. if ( ErrSTReadAccessPage( pfucb, \
  132. PcsrCurrent( pfucb )->pgno ) < 0 ) \
  133. { \
  134. DIRSetRefresh( pfucb ); \
  135. } \
  136. else \
  137. { \
  138. NDGet( pfucb, PcsrCurrent( pfucb )->itag ); \
  139. DIRSetFresh( pfucb ); \
  140. } \
  141. } \
  142. }
  143. #define DIRGotoDataRoot( pfucbX ) \
  144. { \
  145. PcsrCurrent( pfucbX )->csrstat = csrstatOnDataRoot; \
  146. PcsrCurrent( pfucbX )->bm = ( pfucbX )->u.pfcb->bmRoot; \
  147. PcsrCurrent( pfucbX )->pgno = PgnoRootOfPfucb( pfucbX ); \
  148. PcsrCurrent( pfucbX )->itagFather = itagNull; \
  149. ( pfucbX )->sridFather = sridNull; \
  150. DIRSetRefresh( pfucbX ); \
  151. }
  152. #define FDIRDataRootRoot( pfucb, pcsr ) \
  153. ( (pcsr)->pgno == PgnoRootOfPfucb( pfucb ) && \
  154. (pcsr)->itag == ItagRootOfPfucb( pfucb ) )
  155. #define DIRDeferMoveFirst( pfucb ) \
  156. { \
  157. PcsrCurrent( pfucb )->csrstat = csrstatDeferMoveFirst; \
  158. DIRSetRefresh( pfucb ); \
  159. }
  160. #define DIRSetIndexRange FUCBSetIndexRange
  161. #define DIRResetIndexRange FUCBResetIndexRange
  162. ERR ErrDIROpen( PIB *ppib, FCB *pfcb, DBID dbid, FUCB **ppfucb );
  163. VOID DIRClose( FUCB *pfucb );
  164. ERR ErrDIRSeekPath( FUCB *pfucb, INT ckeyPath, KEY *rgkeyPath, INT fFlags );
  165. ERR ErrDIRDown( FUCB *pfucb, DIB *pdib );
  166. ERR ErrDIRDownFromDATA( FUCB *pfucb, KEY *pkey );
  167. VOID DIRUp( FUCB *pfucb, INT ccsr );
  168. ERR ErrDIRNext( FUCB *pfucb, DIB *pdib );
  169. ERR ErrDIRPrev( FUCB *pfucb, DIB *pdib );
  170. ERR ErrDIRGet( FUCB *pfucb );
  171. ERR ErrDIRCheckIndexRange( FUCB *pfucb );
  172. ERR ErrDIRGetWriteLock( FUCB *pfucb );
  173. ERR ErrDIRInsert( FUCB *pfucb, LINE *pline, KEY *pkey, INT fFlags );
  174. ERR ErrDIRInitAppendItem( FUCB *pfucb );
  175. ERR ErrDIRAppendItem( FUCB *pfucb, LINE *pline, KEY *pkey );
  176. ERR ErrDIRTermAppendItem( FUCB *pfucb );
  177. ERR ErrDIRInsertFDP( FUCB *pfucb, LINE *pline, KEY *pkey, INT fFlags, CPG cpg );
  178. ERR ErrDIRDelete( FUCB *pfucb, INT fFlags );
  179. ERR ErrDIRReplace( FUCB *pfucb, LINE *pline, INT fFlags );
  180. ERR ErrDIRReplaceKey( FUCB *pfucb, KEY *pkeyTo, INT fFlags );
  181. ERR ErrDIRDownKeyBookmark( FUCB *pfucb, KEY *pkey, SRID srid );
  182. ERR ErrDIRGetPosition( FUCB *pfucb, ULONG *pulLT, ULONG *pulTotal );
  183. ERR ErrDIRGotoPosition( FUCB *pfucb, ULONG ulLT, ULONG ulTotal );
  184. ERR ErrDIRIndexRecordCount( FUCB *pfucb, ULONG *pulCount, ULONG ulCountMost, BOOL fNext );
  185. ERR ErrDIRComputeStats( FUCB *pfucb, INT *pcitem, INT *pckey, INT *pcpage );
  186. ERR ErrDIRDelta( FUCB *pfucb, INT iDelta, INT fFlags );
  187. ERR ErrDIRBeginTransaction( PIB *ppib );
  188. ERR ErrDIRCommitTransaction( PIB *ppib );
  189. VOID DIRPurge( PIB *ppib );
  190. ERR ErrDIRRollback( PIB *ppib );
  191. #define DIRBeforeFirst( pfucb ) ( PcsrCurrent(pfucb)->csrstat = csrstatBeforeFirst )
  192. #define DIRAfterLast( pfucb ) ( PcsrCurrent(pfucb)->csrstat = csrstatAfterLast )
  193. #define FDIRMostRecent FBTMostRecent
  194. #define FDIRDelta FVERDelta
  195. ERR ErrDIRDump( FUCB *pfucb, INT cchIndent );
  196. /**********************************************************
  197. /******************* DIR Internal *************************
  198. /**********************************************************
  199. /**/
  200. #define itagFOP 0
  201. #define cbSonMax 256
  202. #define ulDBTimeNull 0xffffffff
  203. #define itagDIRDVSplitL 1
  204. #define itagDIRDVSplitR 2
  205. /* maximum node data size for nodes which ErrNDDelta can be used on.
  206. /* Specifically this minimally supports long value root nodes.
  207. /**/
  208. #define cbMaxCounterNode 8
  209. /* Offset of data field to counter. for long field reference counter.
  210. **/
  211. #define ibCounter 0
  212. /* non-clustered index cursors already have item stored.
  213. /**/
  214. #ifdef DEBUG
  215. #define CheckCSR( pfucb ) Assert( fRecovering || \
  216. (PcsrCurrent(pfucb) == pcsrNil || \
  217. PcsrCurrent(pfucb)->pcsrPath == pcsrNil || \
  218. PcsrCurrent(pfucb)->pgno != PcsrCurrent(pfucb)->pcsrPath->pgno || \
  219. PcsrCurrent(pfucb)->itag != PcsrCurrent(pfucb)->pcsrPath->itag ) );
  220. #define DIRSetFresh( pfucb ) \
  221. { \
  222. Assert( PcsrCurrent( pfucb )->csrstat == csrstatOnCurNode || \
  223. PcsrCurrent( pfucb )->csrstat == csrstatBeforeCurNode || \
  224. PcsrCurrent( pfucb )->csrstat == csrstatAfterCurNode || \
  225. PcsrCurrent( pfucb )->csrstat == csrstatOnFDPNode ); \
  226. AssertNDGet( pfucb, PcsrCurrent( pfucb )->itag ); \
  227. PcsrCurrent( pfucb )->ulDBTime = UlSTDBTimePssib( &(pfucb)->ssib ); \
  228. }
  229. #define DIRSetRefresh( pfucb ) \
  230. { \
  231. Assert( PcsrCurrent( pfucb )->csrstat == csrstatOnCurNode || \
  232. PcsrCurrent( pfucb )->csrstat == csrstatBeforeCurNode || \
  233. PcsrCurrent( pfucb )->csrstat == csrstatAfterCurNode || \
  234. PcsrCurrent( pfucb )->csrstat == csrstatOnFDPNode || \
  235. PcsrCurrent( pfucb )->csrstat == csrstatDeferGotoBookmark || \
  236. PcsrCurrent( pfucb )->csrstat == csrstatDeferMoveFirst || \
  237. PcsrCurrent( pfucb )->csrstat == csrstatOnDataRoot ); \
  238. PcsrCurrent( pfucb )->ulDBTime = ulDBTimeNull; \
  239. }
  240. #else
  241. #define CheckCSR( pfucb )
  242. #define DIRSetFresh( pfucb ) \
  243. { \
  244. PcsrCurrent( pfucb )->ulDBTime = UlSTDBTimePssib( &(pfucb)->ssib ); \
  245. }
  246. #define DIRSetRefresh( pfucb ) \
  247. { \
  248. PcsrCurrent( pfucb )->ulDBTime = ulDBTimeNull; \
  249. }
  250. #endif
  251. /**********************************************************
  252. /********************* BTREE API **************************
  253. /**********************************************************
  254. /**/
  255. #define sridMin 0
  256. #define sridMax 0xffffffff
  257. /* must be on node, i.e. on current node, before node or after node.
  258. /* Node must be in line cache.
  259. /**/
  260. #define DIRISetBookmark( pfucb, pcsr ) \
  261. { \
  262. Assert( FReadAccessPage( (pfucb), (pcsr)->pgno ) ); \
  263. \
  264. if ( FNDBackLink( *( (pfucb)->ssib.line.pb ) ) ) \
  265. (pcsr)->bm = *(SRID UNALIGNED *)PbNDBackLink( (pfucb)->ssib.line.pb ); \
  266. else \
  267. (pcsr)->bm = SridOfPgnoItag( (pcsr)->pgno, (pcsr)->itag ); \
  268. }
  269. BOOL FBTMostRecent( FUCB *pfucb );
  270. #define ErrBTNext( pfucb, pdib ) \
  271. ( ErrBTNextPrev( pfucb, PcsrCurrent(pfucb), fTrue, pdib ) )
  272. #define ErrBTPrev( pfucb, pdib ) \
  273. ( ErrBTNextPrev( pfucb, PcsrCurrent(pfucb), fFalse, pdib ) )
  274. #define BTUp( pfucb ) FUCBFreeCSR( pfucb )
  275. ERR ErrBTGet( FUCB *pfucb, CSR *pcsr );
  276. ERR ErrBTGetNode( FUCB *pfucb, CSR *pcsr );
  277. #ifdef DEBUG
  278. VOID AssertBTGetNode( FUCB *pfucb, CSR *pcsr );
  279. #else
  280. #define AssertBTGetNode
  281. #endif
  282. ERR ErrBTSetNodeHeader( FUCB *pfucb, BYTE bHeader );
  283. ERR ErrBTReplaceKey( FUCB *pfucb, KEY *pkey, INT fFlags );
  284. ERR ErrBTDown( FUCB *pfucb, DIB *pdib );
  285. ERR ErrBTDownFromDATA( FUCB *pfucb, KEY *pkey );
  286. ERR ErrBTNextPrev( FUCB *pfucb, CSR *pcsr, INT fNext, DIB *pdib );
  287. ERR ErrBTSeekForUpdate( FUCB *pfucb, KEY *pkey, PGNO pgno, INT itag, INT fDIRFlags );
  288. ERR ErrBTInsert( FUCB *pfucb, INT fHeader, KEY *pkey, LINE *pline, INT fDIRFlags );
  289. ERR ErrBTReplace( FUCB *pfucb, LINE *pline, INT fFlags );
  290. ERR ErrBTDelete( FUCB *pfucb, INT fFlags );
  291. ERR ErrBTMakeRoom( FUCB *pfucb, CSR *pcsrRoot, INT cbReq );
  292. ERR ErrBTGetPosition( FUCB *pfucb, ULONG *pulLT, ULONG *pulTotal );
  293. ERR ErrBTGotoBookmark( FUCB *pfucb, SRID srid );
  294. ERR ErrBTGetInvisiblePagePtr( FUCB *pfucb, SRID sridFather );
  295. #ifdef DEBUG
  296. ERR ErrBTCheckInvisiblePagePtr( FUCB *pfucb, SRID sridFather );
  297. #endif
  298. /**********************************************************
  299. /*********************** BT Split *************************
  300. /**********************************************************
  301. /**/
  302. typedef enum {
  303. splittNull,
  304. splittVertical,
  305. splittDoubleVertical,
  306. splittLeft,
  307. splittRight,
  308. splittAppend
  309. } SPLITT;
  310. typedef enum {
  311. opReplace,
  312. opInsert
  313. } OPERATION;
  314. typedef struct {
  315. PN pn;
  316. ULONG ulDBTime;
  317. } LFINFO; /* leaf split info */
  318. #define BTIInitLeafSplitKey(plfinfo) memset((plfinfo), 0, sizeof(LFINFO));
  319. typedef struct
  320. {
  321. SRID sridNew;
  322. SRID sridBackLink;
  323. } BKLNK;
  324. typedef struct _split {
  325. PIB *ppib;
  326. PGNO pgnoSplit;
  327. PGNO pgnoNew;
  328. PGNO pgnoNew2;
  329. PGNO pgnoNew3;
  330. PGNO pgnoSibling;
  331. BF *pbfSplit; /* BF of page being split */
  332. BF *pbfNew; /* BF of new page of this split */
  333. BF *pbfNew2; /* BF of new page of this split */
  334. BF *pbfNew3; /* BF of new page of this split */
  335. BF *pbfSibling; /* BF of sibling page of this H split */
  336. BF *pbfPagePtr;
  337. BOOL fNoRedoNew; /* no need to redo new page */
  338. BOOL fNoRedoNew2; /* no need to redo new page 2 */
  339. BOOL fNoRedoNew3; /* no need to redo new page 3 */
  340. BF **rgpbf; /* BF of backlink page. */
  341. INT cpbf;
  342. INT cpbfMax;
  343. BKLNK *rgbklnk; /* SRID of backlinks. */
  344. INT cbklnk;
  345. INT cbklnkMax;
  346. ULONG ulDBTimeRedo; /* redo timestamp */
  347. INT itagSplit;
  348. INT ibSon;
  349. KEY key;
  350. KEY keyMac;
  351. SPLITT splitt;
  352. BOOL fLeaf;
  353. OPERATION op;
  354. BOOL fFDP;
  355. DBID dbid;
  356. INT itagNew;
  357. INT itagPagePointer;
  358. BYTE rgbSonSplit[cbSonMax];
  359. BYTE rgbSonNew[cbSonMax];
  360. BYTE rgbkeyMac[JET_cbKeyMost];
  361. BYTE rgbKey[JET_cbKeyMost];
  362. LFINFO lfinfo; /* leaf split key. HSplit only */
  363. /* mapping from old to new tags for use in MCM
  364. /**/
  365. BYTE mpitag[ctagMax];
  366. INT ipcsrMac; /* preallocated resource for csr */
  367. #define ipcsrSplitMax 4
  368. CSR *rgpcsr[ipcsrSplitMax];
  369. } SPLIT;
  370. typedef struct _rmpage {
  371. PIB *ppib;
  372. ULONG ulDBTimeRedo; /* redo timestamp */
  373. BF *pbfLeft;
  374. BF *pbfRight;
  375. BF *pbfFather;
  376. BKLNK **rgbklnk; /* latched buffers required for rmpage */
  377. INT cbklnk;
  378. INT cbklnkMax;
  379. BF **rgpbf; /* latched buffers required for rmpage */
  380. INT cpbf;
  381. INT cpbfMax;
  382. PGNO pgnoRemoved;
  383. PGNO pgnoLeft;
  384. PGNO pgnoRight;
  385. PGNO pgnoFather;
  386. INT itagPgptr;
  387. INT itagFather;
  388. INT ibSon;
  389. DBID dbid;
  390. } RMPAGE;
  391. #define CbFreeDensity(pfucb) \
  392. ( (pfucb)->u.pfcb != pfcbNil ? (pfucb)->u.pfcb->cbDensityFree : 0 )
  393. /* protypes for split used by recovery of split operations.
  394. /**/
  395. ERR ErrBTStoreBackLinkBuffer( SPLIT *psplit, BF *pbf, BOOL *pfAlreadyLatched );
  396. ERR ErrBTSplit( FUCB *pfucb, INT cbNode, INT cbReq, KEY *pkey, INT fFlags );
  397. ERR ErrBTSplitPage( FUCB *pfucb, CSR *pcsr, CSR *pcsrRoot,
  398. KEY keySplit, INT cbNode, INT cbReq, BOOL fReplace, BOOL fAppendPage, LFINFO *plfinfo );
  399. BOOL FBTSplit( SSIB *pssib, INT cbReq, INT citagReq );
  400. BOOL FBTAppendPage( FUCB *pfucb, CSR *pcsr, INT cbReq, INT cbPageAdjust, INT cbFreeDensity );
  401. INT CbBTFree( FUCB *pfucb, INT cbFreeDensity );
  402. #define fAllocBufOnly fTrue
  403. #define fDoMove fFalse
  404. ERR ErrBTSplitVMoveNodes(
  405. FUCB *pfucb,
  406. FUCB *pfucbNew,
  407. SPLIT *psplit,
  408. CSR *pcsr,
  409. BYTE *rgb,
  410. BOOL fNoMove);
  411. ERR ErrBTSplitDoubleVMoveNodes(
  412. FUCB *pfucb,
  413. FUCB *pfucbNew,
  414. FUCB *pfucbNew2,
  415. FUCB *pfucbNew3,
  416. SPLIT *psplit,
  417. CSR *pcsr,
  418. BYTE *rgb,
  419. BOOL fNoMove);
  420. ERR ErrBTSplitHMoveNodes(
  421. FUCB *pfucb,
  422. FUCB *pfucbNew,
  423. SPLIT *psplit,
  424. BYTE *rgb,
  425. BOOL fNoMove);
  426. ERR ErrBTInsertPagePointer( FUCB *pfucb, CSR *pcsrPagePointer, SPLIT *psplit, BYTE *rgb );
  427. ERR ErrBTCorrectLinks(
  428. SPLIT *psplit,
  429. FUCB *pfucb,
  430. SSIB *pssib,
  431. SSIB *pssibNew);
  432. VOID BTReleaseSplitBfs ( BOOL fRedo, SPLIT *psplit, ERR err );
  433. VOID BTReleaseRmpageBfs( BOOL fRedo, RMPAGE *prmpage );
  434. ERR ErrBTMoveSons( SPLIT *psplit,
  435. FUCB *pfucb,
  436. FUCB *pfucbNew,
  437. INT itagSonTable,
  438. BYTE *rgbSon,
  439. BOOL fVisibleSons,
  440. BOOL fNoMove );
  441. ERR ErrBTSetUpSplitPages( FUCB *pfucb, FUCB *pfucbNew,
  442. FUCB *pfucbNew2, FUCB *pfucbNew3, SPLIT *psplit,
  443. PGTYP pgtyp, BOOL fAppend, BOOL fSkipMoves );
  444. /**********************************************************
  445. /********** MCM STRUCTURES, CONSTANTS and API *************
  446. /**********************************************************
  447. /**/
  448. #define opInsertItem 0
  449. #define opDeleteItem 1
  450. #define opSplitItemList 2
  451. #define opInsertSon 0
  452. #define opReplaceSon 1
  453. #define opDeleteSon 2
  454. #define opHorizontalRightSplitPage 0
  455. #define opHorizontalLeftSplitPage 1
  456. #define opVerticalSplitPage 0
  457. VOID MCMRightHorizontalPageSplit( FUCB *pfucb,
  458. PGNO pgnoSplit, PGNO pgnoRight, INT ibSonSplit, BYTE *mpitag );
  459. VOID MCMLeftHorizontalPageSplit( FUCB *pfucb,
  460. PGNO pgnoSplit, PGNO pgnoNew, INT ibSonSplit, BYTE *mpitag );
  461. VOID MCMVerticalPageSplit(
  462. FUCB *pfucb,
  463. BYTE *mpitag,
  464. PGNO pgnoSplit,
  465. INT itagSplit,
  466. PGNO pgnoNew,
  467. SPLIT *psplit );
  468. VOID MCMDoubleVerticalPageSplit(
  469. FUCB *pfucb,
  470. BYTE *mpitag,
  471. PGNO pgnoSplit,
  472. INT itagSplit,
  473. INT ibSonDivision,
  474. PGNO pgnoNew,
  475. PGNO pgnoNew2,
  476. PGNO pgnoNew3,
  477. SPLIT *psplit );
  478. VOID MCMInsertPagePointer( FUCB *pfucb, PGNO pgnoFather, INT itagFather );
  479. VOID MCMBurstIntrinsic( FUCB *pfucb, PGNO pgnoFather, INT itagFather, PGNO pgnoNew, INT itagNew );
  480. #define FFUCBRecordCursor( pfucb ) ( \
  481. ( pfucb )->u.pfcb != pfcbNil ? \
  482. ( pfucb )->u.pfcb->wFlags & fFCBClusteredIndex : fFalse )
  483. #ifdef NOLOG /* logging disabled */
  484. #define ErrLGSplitL( ppib, pcsrPagePointer, psplit, pgtyp ) 0
  485. #define ErrLGSplitR( ppib, pcsrPagePointer, psplit, pgtyp ) 0
  486. #define ErrLGSplitV( ppib, psplit, pgtyp ) 0
  487. #define ErrLGAddendR( pfucb, pcsrPagePointer, psplit, newpagetype ) 0
  488. #else
  489. ERR ErrLGSplitL(
  490. FUCB *pfucb,
  491. CSR *pcsrPagePointer,
  492. SPLIT *psplit,
  493. PGTYP newpagetype );
  494. ERR ErrLGSplitR(
  495. FUCB *pfucb,
  496. CSR *pcsrPagePointer,
  497. SPLIT *psplit,
  498. PGTYP newpagetype );
  499. ERR ErrLGSplitV(
  500. FUCB *pfucb,
  501. SPLIT *psplit,
  502. PGTYP newpagetype );
  503. ERR ErrLGAddendR(
  504. FUCB *pfucb,
  505. CSR *pcsrPagePointer,
  506. SPLIT *psplit,
  507. PGTYP newpagetype );
  508. #endif
  509. #endif // __DIRAPI_H__