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.

648 lines
20 KiB

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