DbaccMain.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:575k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1.   }//for
  2.   signal->theData[fragrecptr.p->activeDataPage + 6] = fragrecptr.p->activeDataFilePage;
  3.   signal->theData[0] = fsConnectptr.p->fsPtr;
  4.   signal->theData[1] = cownBlockref;
  5.   signal->theData[2] = fsOpptr.i;
  6.   signal->theData[3] = 0x2;
  7.   signal->theData[4] = ZPAGE8_BASE_ADD;
  8.   signal->theData[5] = fragrecptr.p->activeDataPage;
  9.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 15, JBA);
  10.   return;
  11. }//Dbacc::senddatapagesLab()
  12. void Dbacc::endsavepageLab(Signal* signal) 
  13. {
  14.   Page8Ptr espPageidptr;
  15.   espPageidptr.i = fragrecptr.p->zeroPagePtr;
  16.   ptrCheckGuard(espPageidptr, cpagesize, page8);
  17.   dbgWord32(espPageidptr, ZPAGEZERO_NO_PAGES, fragrecptr.p->lcpDirIndex);
  18.   espPageidptr.p->word32[ZPAGEZERO_NO_PAGES] = fragrecptr.p->lcpDirIndex;
  19.   fragrecptr.p->fragState = LCP_SEND_OVER_PAGES;
  20.   fragrecptr.p->noOfStoredOverPages = 0;
  21.   fragrecptr.p->lcpDirIndex = 0;
  22.   saveOverPagesLab(signal);
  23.   return;
  24. }//Dbacc::endsavepageLab()
  25. /* ******************--------------------------------------------------------------- */
  26. /* ACC_SAVE_OVER_PAGES                   CONTINUE SAVING THE LEFT OVERPAGES.         */
  27. /* ******************--------------------------------------------------------------- */
  28. void Dbacc::saveOverPagesLab(Signal* signal) 
  29. {
  30.   DirRangePtr sopDirRangePtr;
  31.   DirectoryarrayPtr sopOverflowDirptr;
  32.   Page8Ptr sopPageptr;
  33.   Page8Ptr sopCopyPageptr;
  34.   Uint32 tsopDirindex;
  35.   Uint32 tsopDirInd;
  36.   Uint32 tsopIndex;
  37.   if ((fragrecptr.p->lcpDirIndex >= fragrecptr.p->lastOverIndex) ||
  38.       (fragrecptr.p->lcpDirIndex >= fragrecptr.p->lcpMaxOverDirIndex)) {
  39.     jam();
  40.     endsaveoverpageLab(signal);
  41.     return;
  42.   }//if
  43.   arrGuard(fragrecptr.p->activeDataPage, 8);
  44.   sopCopyPageptr.i = fragrecptr.p->datapages[fragrecptr.p->activeDataPage];
  45.   ptrCheckGuard(sopCopyPageptr, cpagesize, page8);
  46.   tsopDirindex = fragrecptr.p->lcpDirIndex;
  47.   sopDirRangePtr.i = fragrecptr.p->overflowdir;
  48.   tsopDirInd = tsopDirindex >> 8;
  49.   tsopIndex = tsopDirindex & 0xff;
  50.   ptrCheckGuard(sopDirRangePtr, cdirrangesize, dirRange);
  51.   arrGuard(tsopDirInd, 256);
  52.   sopOverflowDirptr.i = sopDirRangePtr.p->dirArray[tsopDirInd];
  53.   ptrCheckGuard(sopOverflowDirptr, cdirarraysize, directoryarray);
  54.   sopPageptr.i = sopOverflowDirptr.p->pagep[tsopIndex];
  55.   fragrecptr.p->lcpDirIndex++;
  56.   if (sopPageptr.i != RNIL) {
  57.     jam();
  58.     ptrCheckGuard(sopPageptr, cpagesize, page8);
  59.     ndbrequire(sopPageptr.p->word32[ZPOS_PAGE_ID] == tsopDirindex);
  60.     ndbrequire(((sopPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) != ZNORMAL_PAGE_TYPE);
  61.     lcnPageptr = sopPageptr;
  62.     lcnCopyPageptr = sopCopyPageptr;
  63.     lcpCopyPage(signal);
  64.     fragrecptr.p->noOfStoredOverPages++;
  65.     fragrecptr.p->activeDataPage++;
  66.     if ((sopPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] == 0)) {
  67.       //ndbrequire(((sopPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) == ZOVERFLOW_PAGE_TYPE);
  68.       if (((sopPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) == 
  69.   ZOVERFLOW_PAGE_TYPE) {
  70. /*--------------------------------------------------------------------------------*/
  71. /*       THE PAGE IS EMPTY AND WAITING TO BE RELEASED. IT COULD NOT BE RELEASED   */
  72. /*       EARLIER SINCE IT WAS PART OF A LOCAL CHECKPOINT.                         */
  73. /*--------------------------------------------------------------------------------*/
  74. jam();
  75. ropPageptr = sopPageptr;
  76. releaseOverpage(signal);
  77.       } else if (((sopPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) == 
  78.  ZLONG_PAGE_TYPE)  {
  79. //----------------------------------------------------------------------
  80. // The long key page is empty, release it.
  81. //----------------------------------------------------------------------
  82. jam();
  83. rlopPageptr = sopPageptr;
  84. releaseLongPage(signal);
  85.       } else {
  86.         jam();
  87. sendSystemerror(signal);
  88.       }
  89.     }//if
  90.   }
  91.   if (fragrecptr.p->activeDataPage == ZWRITEPAGESIZE) {
  92.     jam();
  93.     senddatapagesLab(signal);
  94.     return;
  95.   }//if
  96.   signal->theData[0] = lcpConnectptr.i;
  97.   signal->theData[1] = fragrecptr.i;
  98.   sendSignal(cownBlockref, GSN_ACC_SAVE_PAGES, signal, 2, JBB);
  99.   return;
  100. }//Dbacc::saveOverPagesLab()
  101. void Dbacc::endsaveoverpageLab(Signal* signal) 
  102. {
  103.   Page8Ptr esoPageidptr;
  104.   esoPageidptr.i = fragrecptr.p->zeroPagePtr;
  105.   ptrCheckGuard(esoPageidptr, cpagesize, page8);
  106.   dbgWord32(esoPageidptr, ZPAGEZERO_NO_OVER_PAGE, fragrecptr.p->noOfStoredOverPages);
  107.   esoPageidptr.p->word32[ZPAGEZERO_NO_OVER_PAGE] = fragrecptr.p->noOfStoredOverPages;
  108.   fragrecptr.p->fragState = LCP_SEND_ZERO_PAGE;
  109.   if (fragrecptr.p->activeDataPage != 0) {
  110.     jam();
  111.     senddatapagesLab(signal); /* SEND LEFT PAGES TO DISK */
  112.     return;
  113.   }//if
  114.   saveZeroPageLab(signal);
  115.   return;
  116. }//Dbacc::endsaveoverpageLab()
  117. /* ******************--------------------------------------------------------------- */
  118. /* ACC_SAVE_ZERO_PAGE      PAGE ZERO IS SENT TO DISK.IT IS THE LAST STAGE AT  THE    */
  119. /*                         CREATION LCP. ACC_LCPCONF IS RETURND.                     */
  120. /* ******************--------------------------------------------------------------- */
  121. void Dbacc::saveZeroPageLab(Signal* signal) 
  122. {
  123.   Page8Ptr szpPageidptr;
  124.   Uint32 Tchs;
  125.   Uint32 Ti;
  126.   fragrecptr.p->createLcp = ZFALSE;
  127.   fsConnectptr.i = fragrecptr.p->fsConnPtr;
  128.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  129.   szpPageidptr.i = fragrecptr.p->zeroPagePtr;
  130.   ptrCheckGuard(szpPageidptr, cpagesize, page8);
  131.   dbgWord32(szpPageidptr, ZPAGEZERO_PREV_UNDOP, fragrecptr.p->prevUndoposition);
  132.   szpPageidptr.p->word32[ZPAGEZERO_PREV_UNDOP] = fragrecptr.p->prevUndoposition;
  133.   dbgWord32(szpPageidptr, ZPAGEZERO_NEXT_UNDO_FILE, cactiveUndoFileVersion);
  134.   szpPageidptr.p->word32[ZPAGEZERO_NEXT_UNDO_FILE] = cactiveUndoFileVersion;
  135.   fragrecptr.p->fragState = WAIT_ZERO_PAGE_STORED;
  136.   /* --------------------------------------------------------------------------------- */
  137.   // Calculate the checksum and store it for the zero page of the fragment.
  138.   /* --------------------------------------------------------------------------------- */
  139.   szpPageidptr.p->word32[ZPOS_CHECKSUM] = 0;
  140.   Tchs = 0;
  141.   for (Ti = 0; Ti < 2048; Ti++) {
  142.     Tchs = Tchs ^ szpPageidptr.p->word32[Ti];
  143.   }//for
  144.   szpPageidptr.p->word32[ZPOS_CHECKSUM] = Tchs;
  145.   dbgWord32(szpPageidptr, ZPOS_CHECKSUM, Tchs);
  146.   seizeFsOpRec(signal);
  147.   initFsOpRec(signal);
  148.   fsOpptr.p->fsOpstate = WAIT_WRITE_DATA;
  149.   if (clblPageCounter > 0) {
  150.     jam();
  151.     clblPageCounter = clblPageCounter - 1;
  152.   } else {
  153.     jam();
  154.     clblPageOver = clblPageOver + 1;
  155.   }//if
  156.   /* ************************ */
  157.   /* FSWRITEREQ               */
  158.   /* ************************ */
  159.   signal->theData[0] = fsConnectptr.p->fsPtr;
  160.   signal->theData[1] = cownBlockref;
  161.   signal->theData[2] = fsOpptr.i;
  162.   signal->theData[3] = 0x10;
  163.   /* FLAG = LIST MEM PAGES, LIST FILE PAGES */
  164.   /* SYNC FILE AFTER WRITING */
  165.   signal->theData[4] = ZPAGE8_BASE_ADD;
  166.   signal->theData[5] = 1;
  167.   /* NO OF  PAGES */
  168.   signal->theData[6] = fragrecptr.p->zeroPagePtr;
  169.   /* ZERO PAGE */
  170.   signal->theData[7] = 0;
  171.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
  172.   /* ZERO PAGE AT DATA FILE */
  173.   return;
  174. }//Dbacc::saveZeroPageLab()
  175. /* ******************--------------------------------------------------------------- */
  176. /* FSWRITECONF                                         OPENFILE CONF                 */
  177. /*              ENTER FSWRITECONF WITH                 SENDER: FS,     LEVEL B       */
  178. /*                    FS_OPPTR                         FS_CONNECTION PTR             */
  179. /* ******************--------------------------------------------------------------- */
  180. void Dbacc::lcpCloseDataFileLab(Signal* signal) 
  181. {
  182.   rootfragrecptr.i = fragrecptr.p->myroot;
  183.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  184.   lcpConnectptr.i = rootfragrecptr.p->lcpPtr;
  185.   ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  186.   fsConnectptr.p->fsState = LCP_CLOSE_DATA;
  187.   /* ************************ */
  188.   /* FSCLOSEREQ               */
  189.   /* ************************ */
  190.   /* CLOSE DATA FILE */
  191.   signal->theData[0] = fsConnectptr.p->fsPtr;
  192.   signal->theData[1] = cownBlockref;
  193.   signal->theData[2] = fsConnectptr.i;
  194.   signal->theData[3] = ZFALSE;
  195.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  196.   /* FLAG = 0, DO NOT DELETE FILE */
  197.   return;
  198. }//Dbacc::lcpCloseDataFileLab()
  199. void Dbacc::checkSyncUndoPagesLab(Signal* signal) 
  200. {
  201.   fragrecptr.i = fsConnectptr.p->fragrecPtr;
  202.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  203.   releaseFsConnRec(signal);
  204.   rootfragrecptr.i = fragrecptr.p->myroot;
  205.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  206.   lcpConnectptr.i = rootfragrecptr.p->lcpPtr;
  207.   ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  208.   switch (lcpConnectptr.p->syncUndopageState) {
  209.   case WAIT_NOTHING:
  210.     jam();
  211.     lcpConnectptr.p->syncUndopageState = WAIT_ONE_CONF;
  212.     break;
  213.   case WAIT_ONE_CONF:
  214.     jam();
  215.     lcpConnectptr.p->syncUndopageState = WAIT_TWO_CONF;
  216.     break;
  217.   default:
  218.     jam();
  219.     sendSystemerror(signal);
  220.     return;
  221.     break;
  222.   }//switch
  223.   /* ACTIVE UNDO PAGE ID */
  224.   Uint32 tundoPageId = cundoposition >> ZUNDOPAGEINDEXBITS;
  225.   tmp1 = tundoPageId - (tundoPageId & (ZWRITE_UNDOPAGESIZE - 1));
  226.   /* START PAGE OF THE LAST UNDO PAGES GROUP */
  227.   tmp2 = (tundoPageId - tmp1) + 1; /* NO OF LEFT UNDO PAGES */
  228.   tmp1 = tmp1 & (cundopagesize - 1); /* 1 MBYTE PAGE WINDOW IN MEMORY */
  229.   fsConnectptr.i = cactiveOpenUndoFsPtr;
  230.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  231.   seizeFsOpRec(signal);
  232.   initFsOpRec(signal);
  233.   fsOpptr.p->fsOpstate = WAIT_WRITE_UNDO;
  234.   fsOpptr.p->fsOpMemPage = tundoPageId; /* RECORD MEMORY PAGE WRITTEN */
  235.   if (clblPageCounter >= (4 * tmp2)) {
  236.     jam();
  237.     clblPageCounter = clblPageCounter - (4 * tmp2);
  238.   } else {
  239.     jam();
  240.     clblPageOver = clblPageOver + ((4 * tmp2) - clblPageCounter);
  241.     clblPageCounter = 0;
  242.   }//if
  243.   /* ************************ */
  244.   /* FSWRITEREQ               */
  245.   /* ************************ */
  246.   signal->theData[0] = fsConnectptr.p->fsPtr;
  247.   signal->theData[1] = cownBlockref;
  248.   signal->theData[2] = fsOpptr.i;
  249.   /* FLAG = START MEM PAGES, START FILE PAGES */
  250.   /* SYNC FILE AFTER WRITING */
  251.   signal->theData[3] = 0x11;                                        
  252.   signal->theData[4] = ZUNDOPAGE_BASE_ADD;
  253.   /* NO OF UNDO PAGES */
  254.   signal->theData[5] = tmp2;                       
  255.   /* FIRST MEMORY PAGE */
  256.   signal->theData[6] = tmp1;
  257.   /* ACTIVE PAGE AT UNDO FILE */                                          
  258.   signal->theData[7] = cactiveUndoFilePage;
  259.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
  260.   return;
  261. }//Dbacc::checkSyncUndoPagesLab()
  262. void Dbacc::checkSendLcpConfLab(Signal* signal) 
  263. {
  264.   rootfragrecptr.i = fragrecptr.p->myroot;
  265.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  266.   lcpConnectptr.i = rootfragrecptr.p->lcpPtr;
  267.   ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  268.   ndbrequire(lcpConnectptr.p->lcpstate == LCP_ACTIVE);
  269.   switch (lcpConnectptr.p->syncUndopageState) {
  270.   case WAIT_ONE_CONF:
  271.     jam();
  272.     lcpConnectptr.p->syncUndopageState = WAIT_NOTHING;
  273.     break;
  274.   case WAIT_TWO_CONF:
  275.     jam();
  276.     lcpConnectptr.p->syncUndopageState = WAIT_ONE_CONF;
  277.     break;
  278.   default:
  279.     ndbrequire(false);
  280.     break;
  281.   }//switch
  282.   lcpConnectptr.p->noOfLcpConf++;
  283.   ndbrequire(lcpConnectptr.p->noOfLcpConf <= 4);
  284.   fragrecptr.p->fragState = ACTIVEFRAG;
  285.   rlpPageptr.i = fragrecptr.p->zeroPagePtr;
  286.   ptrCheckGuard(rlpPageptr, cpagesize, page8);
  287.   releaseLcpPage(signal);
  288.   fragrecptr.p->zeroPagePtr = RNIL;
  289.   for (Uint32 i = 0; i < ZWRITEPAGESIZE; i++) {
  290.     jam();
  291.     if (fragrecptr.p->datapages[i] != RNIL) {
  292.       jam();
  293.       rlpPageptr.i = fragrecptr.p->datapages[i];
  294.       ptrCheckGuard(rlpPageptr, cpagesize, page8);
  295.       releaseLcpPage(signal);
  296.       fragrecptr.p->datapages[i] = RNIL;
  297.     }//if
  298.   }//for
  299.   signal->theData[0] = fragrecptr.p->lcpLqhPtr;
  300.   sendSignal(lcpConnectptr.p->lcpUserblockref, GSN_ACC_LCPCONF, signal, 1, JBB);
  301.   if (lcpConnectptr.p->noOfLcpConf == 4) {
  302.     jam();
  303.     releaseLcpConnectRec(signal);
  304.     rootfragrecptr.i = fragrecptr.p->myroot;
  305.     ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  306.     rootfragrecptr.p->rootState = ACTIVEROOT;
  307.   }//if
  308. }//Dbacc::checkSendLcpConfLab()
  309. /* ******************--------------------------------------------------------------- */
  310. /* ACC_CONTOPREQ                                                                     */
  311. /*                                                     SENDER: LQH,    LEVEL B       */
  312. /*          ENTER ACC_CONTOPREQ WITH                                                 */
  313. /*                    LCP_CONNECTPTR                                                 */
  314. /*                    TMP1                             LOCAL FRAG ID                 */
  315. /* ******************--------------------------------------------------------------- */
  316. /* ******************--------------------------------------------------------------- */
  317. /* ACC_CONTOPREQ                                        COMMIT  TRANSACTION          */
  318. /* ******************------------------------------+                                 */
  319. /*   SENDER: LQH,    LEVEL B       */
  320. void Dbacc::execACC_CONTOPREQ(Signal* signal) 
  321. {
  322.   Uint32 tcorLocalFrag;
  323.   jamEntry();
  324.   lcpConnectptr.i = signal->theData[0];
  325.   /* CONNECTION PTR                  */
  326.   tcorLocalFrag = signal->theData[1];
  327.   /* LOCAL FRAG ID                   */
  328.   tresult = 0;
  329.   ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  330.   if(ERROR_INSERTED(3002) && lcpConnectptr.p->noOfLcpConf < 2)
  331.   {
  332.     sendSignalWithDelay(cownBlockref, GSN_ACC_CONTOPREQ, signal, 300, 
  333. signal->getLength());
  334.     return;
  335.   }
  336.   
  337.   ndbrequire(lcpConnectptr.p->lcpstate == LCP_ACTIVE);
  338.   rootfragrecptr.i = lcpConnectptr.p->rootrecptr;
  339.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  340.   if (rootfragrecptr.p->fragmentid[0] == tcorLocalFrag) {
  341.     jam();
  342.     fragrecptr.i = rootfragrecptr.p->fragmentptr[0];
  343.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  344.   } else {
  345.     ndbrequire(rootfragrecptr.p->fragmentid[1] == tcorLocalFrag);
  346.     jam();
  347.     fragrecptr.i = rootfragrecptr.p->fragmentptr[1];
  348.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  349.   }//if
  350.   operationRecPtr.i = fragrecptr.p->firstWaitInQueOp;
  351.   fragrecptr.p->sentWaitInQueOp = RNIL;
  352.   fragrecptr.p->stopQueOp = ZFALSE;
  353.   while (operationRecPtr.i != RNIL) {
  354.     jam();
  355.     ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
  356.     if (operationRecPtr.p->opState == WAIT_EXE_OP) {
  357.       jam();
  358.       //------------------------------------------------------------
  359.       // Indicate that we are now a normal waiter in the queue. We
  360.       // will remove the operation from the queue as part of starting
  361.       // operation again.
  362.       //------------------------------------------------------------
  363.       operationRecPtr.p->opState = WAIT_IN_QUEUE;
  364.       executeNextOperation(signal);
  365.     }//if
  366.     operationRecPtr.i = operationRecPtr.p->nextQueOp;
  367.   }//while
  368.   signal->theData[0] = fragrecptr.p->lcpLqhPtr;
  369.   sendSignal(lcpConnectptr.p->lcpUserblockref, GSN_ACC_CONTOPCONF, signal, 1, JBA);
  370.   lcpConnectptr.p->noOfLcpConf++;
  371.   if (lcpConnectptr.p->noOfLcpConf == 4) {
  372.     jam();
  373.     releaseLcpConnectRec(signal);
  374.     rootfragrecptr.i = fragrecptr.p->myroot;
  375.     ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  376.     rootfragrecptr.p->rootState = ACTIVEROOT;
  377.   }//if
  378.   return; /* ALL QUEUED OPERATION ARE RESTARTED IF NEEDED. */
  379. }//Dbacc::execACC_CONTOPREQ()
  380. /* ******************--------------------------------------------------------------- */
  381. /* END_LCPREQ                                        END  OF  LOCAL CHECK POINT      */
  382. /*          ENTER END_LCPREQ WITH                     SENDER: LQH,    LEVEL B        */
  383. /*                      CLQH_PTR,                     LQH  PTR                       */
  384. /*                      CLQH_BLOCK_REF                LQH  BLOCK REF                 */
  385. /* ******************--------------------------------------------------------------- */
  386. /* ******************--------------------------------------------------------------- */
  387. /* END_LCPREQ                                       PERFORM A LOCAL CHECK POINT      */
  388. /* ******************------------------------------+                                 */
  389. /*   SENDER: LQH,    LEVEL B       */
  390. void Dbacc::execEND_LCPREQ(Signal* signal) 
  391. {
  392.   jamEntry();
  393.   clqhPtr = signal->theData[0];
  394.   /*  LQH  PTR                       */
  395.   clqhBlockRef = signal->theData[1];
  396.   /*  LQH  BLOCK REF                 */
  397.   tresult = 0;
  398.   fsConnectptr.i = cactiveOpenUndoFsPtr;
  399.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  400.   fsConnectptr.p->fsState = WAIT_CLOSE_UNDO; /* CLOSE FILE AFTER WRITTING */
  401.   /* ************************ */
  402.   /* FSCLOSEREQ               */
  403.   /* ************************ */
  404.   signal->theData[0] = fsConnectptr.p->fsPtr;
  405.   signal->theData[1] = cownBlockref;
  406.   signal->theData[2] = fsConnectptr.i;
  407.   signal->theData[3] = ZFALSE;
  408.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  409.   /* FLAG = 0, DO NOT DELETE FILE */
  410.   cactiveUndoFileVersion = RNIL;
  411.   cactiveOpenUndoFsPtr = RNIL;
  412.   /* ************************ */
  413.   /* END_LCPCONF              */
  414.   /* ************************ */
  415.   signal->theData[0] = clqhPtr;
  416.   sendSignal(clqhBlockRef, GSN_END_LCPCONF, signal, 1, JBB);
  417.   return;
  418. }//Dbacc::execEND_LCPREQ()
  419. /*-----------------------------------------------------------------*/
  420. /*       WHEN WE COPY THE PAGE WE ALSO WRITE THE ELEMENT HEADER AS */
  421. /*       UNLOCKED IF THEY ARE CURRENTLY LOCKED.                    */
  422. /*-----------------------------------------------------------------*/
  423. void Dbacc::lcpCopyPage(Signal* signal) 
  424. {
  425.   Uint32 tlcnNextContainer;
  426.   Uint32 tlcnTmp;
  427.   Uint32 tlcnConIndex;
  428.   Uint32 tlcnIndex;
  429.   Uint32 Tmp1;
  430.   Uint32 Tmp2;
  431.   Uint32 Tmp3;
  432.   Uint32 Tmp4;
  433.   Uint32 Ti;
  434.   Uint32 Tchs;
  435.   Uint32 Tlimit;
  436.   Tchs = 0;
  437.   lupPageptr.p = lcnCopyPageptr.p;
  438.   lcnPageptr.p->word32[ZPOS_CHECKSUM] = Tchs;
  439.   for (Ti = 0; Ti < 32 ; Ti++) {
  440.     Tlimit = 16 + (Ti << 6);
  441.     for (tlcnTmp = (Ti << 6); tlcnTmp < Tlimit; tlcnTmp ++) {
  442.       Tmp1 = lcnPageptr.p->word32[tlcnTmp];
  443.       Tmp2 = lcnPageptr.p->word32[tlcnTmp + 16];
  444.       Tmp3 = lcnPageptr.p->word32[tlcnTmp + 32];
  445.       Tmp4 = lcnPageptr.p->word32[tlcnTmp + 48];
  446.       lcnCopyPageptr.p->word32[tlcnTmp]      = Tmp1;
  447.       lcnCopyPageptr.p->word32[tlcnTmp + 16] = Tmp2;
  448.       lcnCopyPageptr.p->word32[tlcnTmp + 32] = Tmp3;
  449.       lcnCopyPageptr.p->word32[tlcnTmp + 48] = Tmp4;
  450.       Tchs = Tchs ^ Tmp1;
  451.       Tchs = Tchs ^ Tmp2;
  452.       Tchs = Tchs ^ Tmp3;
  453.       Tchs = Tchs ^ Tmp4;
  454.     }//for
  455.   }//for
  456.   tlcnChecksum = Tchs;
  457.   if (((lcnCopyPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) != ZLONG_PAGE_TYPE) {
  458.     jam();
  459.     if (((lcnCopyPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) == ZNORMAL_PAGE_TYPE) {
  460.       jam();
  461.       /*-----------------------------------------------------------------*/
  462.       /*       TAKE CARE OF ALL 64 BUFFERS ADDRESSED BY ALGORITHM IN     */
  463.       /*       FIRST PAGE. IF THEY ARE EMPTY THEY STILL HAVE A CONTAINER */
  464.       /*       HEADER OF 2 WORDS.                                        */
  465.       /*-----------------------------------------------------------------*/
  466.       tlcnConIndex = ZHEAD_SIZE;
  467.       tlupForward = 1;
  468.       for (tlcnIndex = 0; tlcnIndex <= ZNO_CONTAINERS - 1; tlcnIndex++) {
  469.         tlupIndex = tlcnConIndex;
  470.         tlupElemIndex = tlcnConIndex + ZCON_HEAD_SIZE;
  471.         lcpUpdatePage(signal);
  472.         tlcnConIndex = tlcnConIndex + ZBUF_SIZE;
  473.       }//for
  474.     }//if
  475.     /*-----------------------------------------------------------------*/
  476.     /*       TAKE CARE OF ALL USED BUFFERS ON THE LEFT SIDE.           */
  477.     /*-----------------------------------------------------------------*/
  478.     tlcnNextContainer = (lcnCopyPageptr.p->word32[ZPOS_EMPTY_LIST] >> 23) & 0x7f;
  479.     while (tlcnNextContainer < ZEMPTYLIST) {
  480.       tlcnConIndex = (tlcnNextContainer << ZSHIFT_PLUS) - (tlcnNextContainer << ZSHIFT_MINUS);
  481.       tlcnConIndex = tlcnConIndex + ZHEAD_SIZE;
  482.       tlupIndex = tlcnConIndex;
  483.       tlupElemIndex = tlcnConIndex + ZCON_HEAD_SIZE;
  484.       tlupForward = 1;
  485.       lcpUpdatePage(signal);
  486.       tlcnNextContainer = (lcnCopyPageptr.p->word32[tlcnConIndex] >> 11) & 0x7f;
  487.     }//while
  488.     if (tlcnNextContainer == ZEMPTYLIST) {
  489.       jam();
  490.       /*empty*/;
  491.     } else {
  492.       jam();
  493.       sendSystemerror(signal);
  494.       return;
  495.     }//if
  496.     /*-----------------------------------------------------------------*/
  497.     /*       TAKE CARE OF ALL USED BUFFERS ON THE RIGHT SIDE.          */
  498.     /*-----------------------------------------------------------------*/
  499.     tlupForward = cminusOne;
  500.     tlcnNextContainer = (lcnCopyPageptr.p->word32[ZPOS_EMPTY_LIST] >> 16) & 0x7f;
  501.     while (tlcnNextContainer < ZEMPTYLIST) {
  502.       tlcnConIndex = (tlcnNextContainer << ZSHIFT_PLUS) - (tlcnNextContainer << ZSHIFT_MINUS);
  503.       tlcnConIndex = tlcnConIndex + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
  504.       tlupIndex = tlcnConIndex;
  505.       tlupElemIndex = tlcnConIndex - 1;
  506.       lcpUpdatePage(signal);
  507.       tlcnNextContainer = (lcnCopyPageptr.p->word32[tlcnConIndex] >> 11) & 0x7f;
  508.     }//while
  509.     if (tlcnNextContainer == ZEMPTYLIST) {
  510.       jam();
  511.       /*empty*/;
  512.     } else {
  513.       jam();
  514.       sendSystemerror(signal);
  515.       return;
  516.     }//if
  517.   }//if
  518.   lcnCopyPageptr.p->word32[ZPOS_CHECKSUM] = tlcnChecksum;
  519. }//Dbacc::lcpCopyPage()
  520. /* --------------------------------------------------------------------------------- */
  521. /*       THIS SUBROUTINE GOES THROUGH ONE CONTAINER TO CHECK FOR LOCKED ELEMENTS AND */
  522. /*       UPDATING THEM TO ENSURE ALL ELEMENTS ARE UNLOCKED ON DISK.                  */
  523. /* --------------------------------------------------------------------------------- */
  524. void Dbacc::lcpUpdatePage(Signal* signal) 
  525. {
  526.   OperationrecPtr lupOperationRecPtr;
  527.   Uint32 tlupElemHead;
  528.   Uint32 tlupElemLen;
  529.   Uint32 tlupElemStep;
  530.   Uint32 tlupConLen;
  531.   tlupConLen = lupPageptr.p->word32[tlupIndex] >> 26;
  532.   tlupElemLen = fragrecptr.p->elementLength;
  533.   tlupElemStep = tlupForward * tlupElemLen;
  534.   while (tlupConLen > ZCON_HEAD_SIZE) {
  535.     jam();
  536.     tlupElemHead = lupPageptr.p->word32[tlupElemIndex];
  537.     if (ElementHeader::getLocked(tlupElemHead)) {
  538.       jam();
  539.       /* --------------------------------------------------------------------------------- */
  540.       /*       WHEN CHANGING THE ELEMENT HEADER WE ALSO HAVE TO UPDATE THE CHECKSUM. IN    */
  541.       /*       DOING THIS WE USE THE FORMULA (A XOR B) XOR B = A WHICH MEANS THAT IF WE    */
  542.       /*       XOR SOMETHING TWICE WITH THE SAME OPERAND THEN WE RETURN TO THE ORIGINAL    */
  543.       /*       VALUE. THEN WE ALSO HAVE TO USE THE NEW ELEMENT HEADER IN THE CHECKSUM      */
  544.       /*       CALCULATION.                                                                */
  545.       /* --------------------------------------------------------------------------------- */
  546.       tlcnChecksum = tlcnChecksum ^ tlupElemHead;
  547.       lupOperationRecPtr.i = ElementHeader::getOpPtrI(tlupElemHead);
  548.       ptrCheckGuard(lupOperationRecPtr, coprecsize, operationrec);
  549.       const Uint32 hv = lupOperationRecPtr.p->hashvaluePart;
  550.       tlupElemHead = ElementHeader::setUnlocked(hv , 0);
  551.       arrGuard(tlupElemIndex, 2048);
  552.       lupPageptr.p->word32[tlupElemIndex] = tlupElemHead;
  553.       tlcnChecksum = tlcnChecksum ^ tlupElemHead;
  554.     }//if
  555.     tlupConLen = tlupConLen - tlupElemLen;
  556.     tlupElemIndex = tlupElemIndex + tlupElemStep;
  557.   }//while
  558.   if (tlupConLen < ZCON_HEAD_SIZE) {
  559.     jam();
  560.     sendSystemerror(signal);
  561.   }//if
  562. }//Dbacc::lcpUpdatePage()
  563. /*-----------------------------------------------------------------*/
  564. // At a system restart we check that the page do not contain any
  565. // locks that hinder the system restart procedure.
  566. /*-----------------------------------------------------------------*/
  567. void Dbacc::srCheckPage(Signal* signal) 
  568. {
  569.   Uint32 tlcnNextContainer;
  570.   Uint32 tlcnConIndex;
  571.   Uint32 tlcnIndex;
  572.   lupPageptr.p = lcnCopyPageptr.p;
  573.   if (((lcnCopyPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) != ZLONG_PAGE_TYPE) {
  574.     jam();
  575.     if (((lcnCopyPageptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) == ZNORMAL_PAGE_TYPE) {
  576.       jam();
  577.       /*-----------------------------------------------------------------*/
  578.       /*       TAKE CARE OF ALL 64 BUFFERS ADDRESSED BY ALGORITHM IN     */
  579.       /*       FIRST PAGE. IF THEY ARE EMPTY THEY STILL HAVE A CONTAINER */
  580.       /*       HEADER OF 2 WORDS.                                        */
  581.       /*-----------------------------------------------------------------*/
  582.       tlcnConIndex = ZHEAD_SIZE;
  583.       tlupForward = 1;
  584.       for (tlcnIndex = 0; tlcnIndex <= ZNO_CONTAINERS - 1; tlcnIndex++) {
  585.         tlupIndex = tlcnConIndex;
  586.         tlupElemIndex = tlcnConIndex + ZCON_HEAD_SIZE;
  587.         srCheckContainer(signal);
  588.         if (tresult != 0) {
  589.           jam();
  590.           return;
  591.         }//if
  592.         tlcnConIndex = tlcnConIndex + ZBUF_SIZE;
  593.       }//for
  594.     }//if
  595.     /*-----------------------------------------------------------------*/
  596.     /*       TAKE CARE OF ALL USED BUFFERS ON THE LEFT SIDE.           */
  597.     /*-----------------------------------------------------------------*/
  598.     tlcnNextContainer = (lcnCopyPageptr.p->word32[ZPOS_EMPTY_LIST] >> 23) & 0x7f;
  599.     while (tlcnNextContainer < ZEMPTYLIST) {
  600.       tlcnConIndex = (tlcnNextContainer << ZSHIFT_PLUS) - (tlcnNextContainer << ZSHIFT_MINUS);
  601.       tlcnConIndex = tlcnConIndex + ZHEAD_SIZE;
  602.       tlupIndex = tlcnConIndex;
  603.       tlupElemIndex = tlcnConIndex + ZCON_HEAD_SIZE;
  604.       tlupForward = 1;
  605.       srCheckContainer(signal);
  606.       if (tresult != 0) {
  607.         jam();
  608.         return;
  609.       }//if
  610.       tlcnNextContainer = (lcnCopyPageptr.p->word32[tlcnConIndex] >> 11) & 0x7f;
  611.     }//while
  612.     if (tlcnNextContainer == ZEMPTYLIST) {
  613.       jam();
  614.       /*empty*/;
  615.     } else {
  616.       jam();
  617.       tresult = 4;
  618.       return;
  619.     }//if
  620.     /*-----------------------------------------------------------------*/
  621.     /*       TAKE CARE OF ALL USED BUFFERS ON THE RIGHT SIDE.          */
  622.     /*-----------------------------------------------------------------*/
  623.     tlupForward = cminusOne;
  624.     tlcnNextContainer = (lcnCopyPageptr.p->word32[ZPOS_EMPTY_LIST] >> 16) & 0x7f;
  625.     while (tlcnNextContainer < ZEMPTYLIST) {
  626.       tlcnConIndex = (tlcnNextContainer << ZSHIFT_PLUS) - (tlcnNextContainer << ZSHIFT_MINUS);
  627.       tlcnConIndex = tlcnConIndex + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
  628.       tlupIndex = tlcnConIndex;
  629.       tlupElemIndex = tlcnConIndex - 1;
  630.       srCheckContainer(signal);
  631.       if (tresult != 0) {
  632.         jam();
  633.         return;
  634.       }//if
  635.       tlcnNextContainer = (lcnCopyPageptr.p->word32[tlcnConIndex] >> 11) & 0x7f;
  636.     }//while
  637.     if (tlcnNextContainer == ZEMPTYLIST) {
  638.       jam();
  639.       /*empty*/;
  640.     } else {
  641.       jam();
  642.       tresult = 4;
  643.       return;
  644.     }//if
  645.   }//if
  646. }//Dbacc::srCheckPage()
  647. /* --------------------------------------------------------------------------------- */
  648. /*       THIS SUBROUTINE GOES THROUGH ONE CONTAINER TO CHECK FOR LOCKED ELEMENTS AND */
  649. /*       UPDATING THEM TO ENSURE ALL ELEMENTS ARE UNLOCKED ON DISK.                  */
  650. /* --------------------------------------------------------------------------------- */
  651. void Dbacc::srCheckContainer(Signal* signal) 
  652. {
  653.   Uint32 tlupElemLen;
  654.   Uint32 tlupElemStep;
  655.   Uint32 tlupConLen;
  656.   tlupConLen = lupPageptr.p->word32[tlupIndex] >> 26;
  657.   tlupElemLen = fragrecptr.p->elementLength;
  658.   tlupElemStep = tlupForward * tlupElemLen;
  659.   while (tlupConLen > ZCON_HEAD_SIZE) {
  660.     jam();
  661.     const Uint32 tlupElemHead = lupPageptr.p->word32[tlupElemIndex];
  662.     if (ElementHeader::getLocked(tlupElemHead)){
  663.       jam();
  664.       //-------------------------------------------------------
  665.       // This is absolutely undesirable. We have a lock remaining
  666.       // after the system restart. We send a crash signal that will
  667.       // enter the trace file.
  668.       //-------------------------------------------------------
  669.       tresult = 2;
  670.       return;
  671.     }//if
  672.     tlupConLen = tlupConLen - tlupElemLen;
  673.     tlupElemIndex = tlupElemIndex + tlupElemStep;
  674.   }//while
  675.   if (tlupConLen < ZCON_HEAD_SIZE) {
  676.     jam();
  677.     tresult = 3;
  678.   }//if
  679.   return;
  680. }//Dbacc::srCheckContainer()
  681. /* ------------------------------------------------------------------------- */
  682. /*  CHECK_UNDO_PAGES                                                         */
  683. /*  DESCRIPTION: CHECKS WHEN A PAGE OR A GROUP OF UNDO PAGES IS FILLED.WHEN  */
  684. /*               A PAGE IS FILLED, CUNDOPOSITION WILL BE UPDATE, THE NEW     */
  685. /*               POSITION  IS THE BEGNING OF THE NEXT UNDO PAGE.             */
  686. /*               IN CASE THAT A GROUP IS FILLED THE PAGES ARE SENT TO DISK,  */
  687. /*               AND A NEW GROUP IS CHOSEN.                                  */
  688. /* ------------------------------------------------------------------------- */
  689. void Dbacc::checkUndoPages(Signal* signal) 
  690. {
  691.   fragrecptr.p->prevUndoposition = cundoposition;
  692.   cprevUndoaddress = cundoposition;
  693.   // Calculate active undo page id
  694.   Uint32 tundoPageId = cundoposition >> ZUNDOPAGEINDEXBITS;
  695.   /**
  696.    * WE WILL WRITE UNTIL WE HAVE ABOUT 8 KBYTE REMAINING ON THE 32 KBYTE 
  697.    * PAGE. THIS IS TO ENSURE THAT WE DO NOT HAVE ANY UNDO LOG RECORDS THAT PASS
  698.    * A PAGE BOUNDARIE. THIS SIMPLIFIES CODING TRADING SOME INEFFICIENCY.   
  699.    */
  700.   static const Uint32 ZMAXUNDOPAGEINDEX = 7100;
  701.   if (tundoindex < ZMAXUNDOPAGEINDEX) {
  702.     jam();
  703.     cundoposition = (tundoPageId << ZUNDOPAGEINDEXBITS) + tundoindex;
  704.     return;
  705.   }//if
  706.   /**
  707.    * WE CHECK IF MORE THAN 1 MBYTE OF WRITES ARE OUTSTANDING TO THE UNDO FILE.
  708.    * IF SO WE HAVE TO CRASH SINCE WE HAVE NO MORE SPACE TO WRITE UNDO LOG
  709.    * RECORDS IN
  710.    */
  711.   Uint16 nextUndoPageId = tundoPageId + 1;
  712.   updateUndoPositionPage(signal, nextUndoPageId << ZUNDOPAGEINDEXBITS);
  713.   if ((tundoPageId & (ZWRITE_UNDOPAGESIZE - 1)) == (ZWRITE_UNDOPAGESIZE - 1)) {
  714.     jam();
  715.     /* ----------  SEND A GROUP OF UNDO PAGES TO DISK --------- */
  716.     fsConnectptr.i = cactiveOpenUndoFsPtr;
  717.     ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  718.     Uint32 tcupTmp1 = (tundoPageId - ZWRITE_UNDOPAGESIZE) + 1;
  719.     tcupTmp1 = tcupTmp1 & (cundopagesize - 1); /* 1 MBYTE PAGE WINDOW */
  720.     seizeFsOpRec(signal);
  721.     initFsOpRec(signal);
  722.     fsOpptr.p->fsOpstate = WAIT_WRITE_UNDO_EXIT;
  723.     fsOpptr.p->fsOpMemPage = tundoPageId;
  724.     fragrecptr.p->nrWaitWriteUndoExit++;
  725.     if (clblPageCounter >= 8) {
  726.       jam();
  727.       clblPageCounter = clblPageCounter - 8;
  728.     } else {
  729.       jam();
  730.       clblPageOver = clblPageOver + (8 - clblPageCounter);
  731.       clblPageCounter = 0;
  732.     }//if
  733.     /* ************************ */
  734.     /* FSWRITEREQ               */
  735.     /* ************************ */
  736.     signal->theData[0] = fsConnectptr.p->fsPtr;
  737.     signal->theData[1] = cownBlockref;
  738.     signal->theData[2] = fsOpptr.i;
  739.     signal->theData[3] = 0x1;
  740.     /* FLAG = START MEM PAGES, START FILE PAGES */
  741.     signal->theData[4] = ZUNDOPAGE_BASE_ADD;
  742.     signal->theData[5] = ZWRITE_UNDOPAGESIZE;
  743.     signal->theData[6] = tcupTmp1;
  744.     signal->theData[7] = cactiveUndoFilePage;
  745.     sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
  746.     cactiveUndoFilePage = cactiveUndoFilePage + ZWRITE_UNDOPAGESIZE;
  747.   }//if
  748. }//Dbacc::checkUndoPages()
  749. /* --------------------------------------------------------------------------------- */
  750. /* UNDO_WRITING_PROCESS                                                              */
  751. /*             INPUT: FRAGRECPTR, CUNDO_ELEM_INDEX, DATAPAGEPTR, CUNDOINFOLENGTH     */
  752. /*                DESCRIPTION: WHEN THE PROCESS OF CREATION LOCAL CHECK POINT HAS    */
  753. /*                  STARTED. IF THE ACTIVE PAGE IS NOT ALREADY SENT TO DISK, THE     */
  754. /*                  OLD VALUE OF THE ITEM WHICH IS GOING TO BE CHECKED IS STORED ON  */
  755. /*                  THE ACTIVE UNDO PAGE. INFORMATION ABOUT UNDO PROCESS IN THE      */
  756. /*                  BLOCK AND IN THE FRAGMENT WILL BE UPDATED.                       */
  757. /* --------------------------------------------------------------------------------- */
  758. void Dbacc::undoWritingProcess(Signal* signal) 
  759. {
  760.   const Uint32 tactivePageDir = datapageptr.p->word32[ZPOS_PAGE_ID];
  761.   const Uint32 tpageType = (datapageptr.p->word32[ZPOS_EMPTY_LIST] >> ZPOS_PAGE_TYPE_BIT) & 3;
  762.   if (fragrecptr.p->fragState == LCP_SEND_PAGES) {
  763.     if (tpageType == ZNORMAL_PAGE_TYPE) {
  764.       /* --------------------------------------------------------------------------- */
  765.       /* HANDLING OF LOG OF NORMAL PAGES DURING WRITE OF NORMAL PAGES.               */
  766.       /* --------------------------------------------------------------------------- */
  767.       if (tactivePageDir < fragrecptr.p->lcpDirIndex) {
  768.         jam();
  769. /* ------------------------------------------------------------------- */
  770. /* THIS PAGE HAS ALREADY BEEN WRITTEN IN THE LOCAL CHECKPOINT.         */
  771. /* ------------------------------------------------------------------- */
  772.         /*empty*/;
  773.       } else {
  774.         if (tactivePageDir >= fragrecptr.p->lcpMaxDirIndex) {
  775.           jam();
  776.   /* --------------------------------------------------------------------------- */
  777.   /* OBVIOUSLY THE FRAGMENT HAS EXPANDED SINCE THE START OF THE LOCAL CHECKPOINT.*/
  778.   /* WE NEED NOT LOG ANY UPDATES OF PAGES THAT DID NOT EXIST AT START OF LCP.    */
  779.   /* --------------------------------------------------------------------------- */
  780.   /*empty*/;
  781.         } else {
  782.           jam();
  783.   /* --------------------------------------------------------------------------- */
  784.   /* IN ALL OTHER CASES WE HAVE TO WRITE TO THE UNDO LOG.                        */
  785.   /* --------------------------------------------------------------------------- */
  786.           undopageptr.i = (cundoposition >> ZUNDOPAGEINDEXBITS) & (cundopagesize - 1);
  787.           ptrAss(undopageptr, undopage);
  788.           theadundoindex = cundoposition & ZUNDOPAGEINDEX_MASK;
  789.           tundoindex = theadundoindex + ZUNDOHEADSIZE;
  790.           writeUndoHeader(signal, tactivePageDir, UndoHeader::ZPAGE_INFO);
  791.           tundoElemIndex = cundoElemIndex;
  792.           writeUndoDataInfo(signal);
  793.           checkUndoPages(signal);
  794.         }//if
  795.       }//if
  796.     } else if (tpageType == ZOVERFLOW_PAGE_TYPE) {
  797.       /* --------------------------------------------------------------------------------- */
  798.       /*       OVERFLOW PAGE HANDLING DURING WRITE OF NORMAL PAGES.                        */
  799.       /* --------------------------------------------------------------------------------- */
  800.       if (tactivePageDir >= fragrecptr.p->lcpMaxOverDirIndex) {
  801.         jam();
  802. /* --------------------------------------------------------------------------------- */
  803. /*       OBVIOUSLY THE FRAGMENT HAS EXPANDED THE NUMBER OF OVERFLOW PAGES SINCE THE  */
  804. /*       START OF THE LOCAL CHECKPOINT. WE NEED NOT LOG ANY UPDATES OF PAGES THAT DID*/
  805. /*       NOT EXIST AT START OF LCP.                                                  */
  806. /* --------------------------------------------------------------------------------- */
  807.         /*empty*/;
  808.       } else {
  809.         jam();
  810.         undopageptr.i = (cundoposition >> ZUNDOPAGEINDEXBITS) & (cundopagesize - 1);
  811.         ptrAss(undopageptr, undopage);
  812.         theadundoindex = cundoposition & ZUNDOPAGEINDEX_MASK;
  813. tundoindex = theadundoindex + ZUNDOHEADSIZE;
  814. writeUndoHeader(signal, tactivePageDir, UndoHeader::ZOVER_PAGE_INFO);
  815. tundoElemIndex = cundoElemIndex;
  816.         writeUndoDataInfo(signal);
  817.         checkUndoPages(signal);
  818.       }//if
  819.     } else if (tpageType != ZLONG_PAGE_TYPE) {
  820.       jam();
  821.       /* --------------------------------------------------------------------------- */
  822.       /* ONLY PAGE INFO AND OVERFLOW PAGE INFO CAN BE LOGGED BY THIS ROUTINE. A      */
  823.       /* SERIOUS ERROR.                                                              */
  824.       /* --------------------------------------------------------------------------- */
  825.       sendSystemerror(signal);
  826.     } else {
  827.       /* --------------------------------------------------------------------------------- */
  828.       /*       THIS LOG RECORD IS GENERATED ON A LONG KEY PAGE. THESE PAGES USE LOGICAL    */
  829.       /*       LOGGING.                                                                    */
  830.       /* --------------------------------------------------------------------------------- */
  831.       if (tactivePageDir >= fragrecptr.p->lcpMaxOverDirIndex) {
  832.         jam();  
  833. /* --------------------------------------------------------------------------------- */
  834. /*       OBVIOUSLY THE FRAGMENT HAS EXPANDED THE NUMBER OF OVERFLOW PAGES SINCE THE  */
  835. /*       START OF THE LOCAL CHECKPOINT. WE NEED NOT LOG ANY UPDATES OF PAGES THAT DID*/
  836. /*       NOT EXIST AT START OF LCP.                                                  */
  837. /* --------------------------------------------------------------------------------- */
  838.         /*empty*/;
  839.       } else {
  840.         jam();
  841. /* --------------------------------------------------------------------------------- */
  842. /*       LOGICAL LOGGING OF LONG KEY PAGES CAN EITHER BE UNDO OF AN INSERT OR UNDO   */
  843. /*       OF A DELETE KEY. UNDO OF DELETE NEEDS TO LOG THE KEY TO BE REINSERTED WHILE */
  844. /*       UNDO OF INSERT ONLY NEEDS TO LOG THE INDEX TO BE DELETED.                   */
  845. /* --------------------------------------------------------------------------------- */
  846.         undopageptr.i = (cundoposition >> ZUNDOPAGEINDEXBITS) & (cundopagesize - 1);
  847.         ptrAss(undopageptr, undopage);
  848.         theadundoindex = cundoposition & ZUNDOPAGEINDEX_MASK;
  849. tundoindex = theadundoindex + ZUNDOHEADSIZE;
  850. if (cundoinfolength == 0) {
  851.           jam();
  852.           writeUndoHeader(signal, tactivePageDir, UndoHeader::ZUNDO_INSERT_LONG_KEY);
  853.         } else {
  854.           jam();
  855.           writeUndoHeader(signal, tactivePageDir, UndoHeader::ZUNDO_DELETE_LONG_KEY);
  856.   arrGuard(ZWORDS_IN_PAGE - cundoElemIndex, 2048);
  857.           tundoElemIndex = datapageptr.p->word32[ZWORDS_IN_PAGE - cundoElemIndex] & 0xffff;
  858.           writeUndoDataInfo(signal);
  859.         }//if
  860.         checkUndoPages(signal);
  861.       }//if
  862.     }//if
  863.   } else {
  864.     if (fragrecptr.p->fragState == LCP_SEND_OVER_PAGES) {
  865.       jam();
  866.       /* --------------------------------------------------------------------------------- */
  867.       /*       DURING WRITE OF OVERFLOW PAGES WE NEED NOT WORRY ANYMORE ABOUT NORMAL PAGES.*/
  868.       /* --------------------------------------------------------------------------------- */
  869.       if (tpageType == ZOVERFLOW_PAGE_TYPE) {
  870.         if (tactivePageDir < fragrecptr.p->lcpDirIndex) {
  871.           jam();
  872.   /* --------------------------------------------------------------------------------- */
  873.   /*       THIS PAGE HAS ALREADY BEEN WRITTEN IN THE LOCAL CHECKPOINT.                 */
  874.   /* --------------------------------------------------------------------------------- */
  875.   /*empty*/;
  876.         } else {
  877.           if (tactivePageDir >= fragrecptr.p->lcpMaxOverDirIndex) {
  878.             jam();
  879.     /* --------------------------------------------------------------------------------- */
  880.     /*       OBVIOUSLY THE FRAGMENT HAS EXPANDED THE NUMBER OF OVERFLOW PAGES SINCE THE  */
  881.     /*       START OF THE LOCAL CHECKPOINT. WE NEED NOT LOG ANY UPDATES OF PAGES THAT DID*/
  882.     /*       NOT EXIST AT START OF LCP.                                                  */
  883.     /* --------------------------------------------------------------------------------- */
  884.             /*empty*/;
  885.           } else {
  886.             jam();
  887.             undopageptr.i = (cundoposition >> ZUNDOPAGEINDEXBITS) & (cundopagesize - 1);
  888.             ptrAss(undopageptr, undopage);
  889.             theadundoindex = cundoposition & ZUNDOPAGEINDEX_MASK;
  890.     tundoindex = theadundoindex + ZUNDOHEADSIZE;
  891.     writeUndoHeader(signal, tactivePageDir, UndoHeader::ZOVER_PAGE_INFO);
  892.     tundoElemIndex = cundoElemIndex;
  893.             writeUndoDataInfo(signal);
  894.             checkUndoPages(signal);
  895.           }//if
  896.         }//if
  897.       } else if (tpageType == ZLONG_PAGE_TYPE) {
  898.         if (tactivePageDir < fragrecptr.p->lcpDirIndex) {
  899.           jam();
  900.   // -------------------------------------------------------------
  901.   // THIS PAGE HAS ALREADY BEEN WRITTEN IN THE LOCAL CHECKPOINT.   
  902.   // -------------------------------------------------------------
  903.         } else {
  904.           if (tactivePageDir >= fragrecptr.p->lcpMaxOverDirIndex) {
  905.             jam();
  906.     // -------------------------------------------------------------
  907.     // OBVIOUSLY THE FRAGMENT HAS EXPANDED THE NUMBER OF OVERFLOW 
  908.     // PAGES SINCE THE START OF THE LOCAL CHECKPOINT. WE NEED NOT 
  909.     // LOG ANY UPDATES OF PAGES THAT DID NOT EXIST AT START OF LCP.     
  910.     // -------------------------------------------------------------
  911.   } else {
  912.             jam();
  913.     // -------------------------------------------------------------
  914.     // LOGICAL LOGGING OF LONG KEY PAGES CAN EITHER BE UNDO OF AN 
  915.     // INSERT OR UNDO OF A DELETE KEY. UNDO OF DELETE NEEDS TO LOG 
  916.     // THE KEY TO BE REINSERTED WHILE UNDO OF INSERT ONLY NEEDS TO 
  917.     // LOG THE INDEX TO BE DELETED.                   
  918.     // -------------------------------------------------------------
  919.             undopageptr.i = (cundoposition >> ZUNDOPAGEINDEXBITS) & (cundopagesize - 1);
  920.             ptrAss(undopageptr, undopage);
  921.             theadundoindex = cundoposition & ZUNDOPAGEINDEX_MASK;
  922.     tundoindex = theadundoindex + ZUNDOHEADSIZE;
  923.     if (cundoinfolength == 0) {
  924.               jam();
  925.               writeUndoHeader(signal, tactivePageDir, UndoHeader::ZUNDO_INSERT_LONG_KEY);
  926.             } else {
  927.               jam();
  928.               writeUndoHeader(signal, tactivePageDir, UndoHeader::ZUNDO_DELETE_LONG_KEY);
  929.       arrGuard(ZWORDS_IN_PAGE - cundoElemIndex, 2048);
  930.               tundoElemIndex = datapageptr.p->word32[ZWORDS_IN_PAGE - cundoElemIndex] & 0xffff;
  931.               writeUndoDataInfo(signal);
  932.             }//if
  933.             checkUndoPages(signal);
  934.           }//if
  935.         }//if
  936.       }//if
  937.     }//if
  938.   }//if
  939. }//Dbacc::undoWritingProcess()
  940. /* --------------------------------------------------------------------------------- */
  941. /*       OTHER STATES MEANS THAT WE HAVE ALREADY WRITTEN ALL PAGES BUT NOT YET RESET */
  942. /*       THE CREATE_LCP FLAG.                                                        */
  943. /* --------------------------------------------------------------------------------- */
  944. /* --------------------------------------------------------------------------------- */
  945. /* WRITE_UNDO_DATA_INFO                                                              */
  946. /* --------------------------------------------------------------------------------- */
  947. void Dbacc::writeUndoDataInfo(Signal* signal) 
  948. {
  949.   Uint32 twudiIndex;
  950.   Uint32 guard22;
  951.   guard22 = cundoinfolength;
  952.   arrGuard((tundoindex + guard22 - 1), 8192);
  953.   arrGuard((tundoElemIndex + guard22 - 1), 2048);
  954.   for (twudiIndex = 1; twudiIndex <= guard22; twudiIndex++) {
  955.     undopageptr.p->undoword[tundoindex] = datapageptr.p->word32[tundoElemIndex];
  956.     tundoindex++;
  957.     tundoElemIndex++;
  958.   }//for
  959. }//Dbacc::writeUndoDataInfo()
  960. /* --------------------------------------------------------------------------------- */
  961. /* WRITE_UNDO_HEADER                                                                 */
  962. /*      THE HEAD OF UNDO ELEMENT IS 24 BYTES AND CONTAINS THE FOLLOWING INFORMATION: */
  963. /*          TABLE IDENTITY                                              32  BITS     */
  964. /*          ROOT FRAGMENT IDENTITY                                      32  BITS     */
  965. /*          LOCAL FRAGMENT IDENTITY                                     32  BITS     */
  966. /*          LENGTH OF ELEMENT INF0 (BIT 31 - 18)                        14  BITS     */
  967. /*          INFO TYPE               (BIT 17 - 14)                        4  BITS     */
  968. /*          PAGE INDEX OF THE FIRST FIELD IN THE FRAGMENT  (BIT 13 - 0) 14  BITS     */
  969. /*          DIRECTORY INDEX OF THE PAGE IN THE FRAGMENT                 32  BITS     */
  970. /*          ADDRESS OF THE PREVIOUS ELEMENT OF THE FRAGMENT             64  BITS     */
  971. /*          ADDRESS OF THE PREVIOUS ELEMENT IN THE UNDO PAGES           64  BITS     */
  972. /* --------------------------------------------------------------------------------- */
  973. void Dbacc::writeUndoHeader(Signal* signal, 
  974.                             Uint32 logicalPageId,  
  975.                             UndoHeader::UndoHeaderType pageType) 
  976. {
  977.   rootfragrecptr.i = fragrecptr.p->myroot;
  978.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  979.   arrGuard(theadundoindex + 6, 8192);
  980.   // Set the structpointer to point at the undo page at the right address.
  981.   UndoHeader * const & undoHeaderPtr = 
  982.     (UndoHeader *) &undopageptr.p->undoword[theadundoindex];
  983.   undoHeaderPtr->tableId = rootfragrecptr.p->mytabptr;
  984.   undoHeaderPtr->rootFragId = rootfragrecptr.p->fragmentid[0];
  985.   undoHeaderPtr->localFragId = fragrecptr.p->myfid;
  986.   Uint32 Ttmp = cundoinfolength;
  987.   Ttmp = (Ttmp << 4) + pageType;
  988.   Ttmp = Ttmp << 14;
  989.   undoHeaderPtr->variousInfo = Ttmp + cundoElemIndex;
  990.   undoHeaderPtr->logicalPageId =  logicalPageId;
  991.   undoHeaderPtr->prevUndoAddressForThisFrag = fragrecptr.p->prevUndoposition;
  992.   undoHeaderPtr->prevUndoAddress = cprevUndoaddress;
  993. }//Dbacc::writeUndoHeader()
  994. /* --------------------------------------------------------------------------------- */
  995. /* WRITE_UNDO_OP_INFO                                                                */
  996. /*     FOR A LOCKED ELEMENT, OPERATION TYPE, UNDO OF ELEMENT HEADER AND THE LENGTH OF*/
  997. /*     THE TUPLE KEY HAVE TO BE SAVED IN UNDO PAGES. IN THIS CASE AN UNDO ELEMENT    */
  998. /*     INCLUDES THE FLLOWING ITEMS.                                                  */
  999. /*          OPERATION TYPE                                              32  BITS     */
  1000. /*          HASH VALUE                                                  32  BITS     */
  1001. /*          LENGTH OF THE TUPLE = N                                     32  BITS     */
  1002. /*          TUPLE KEYS                                             N *  32  BITS     */
  1003. /*                                                                                   */
  1004. /* --------------------------------------------------------------------------------- */
  1005. void Dbacc::writeUndoOpInfo(Signal* signal) 
  1006. {
  1007.   Page8Ptr locPageptr;
  1008.   arrGuard((tundoindex + 3), 8192);  
  1009.   undopageptr.p->undoword[tundoindex] = operationRecPtr.p->operation;
  1010.   undopageptr.p->undoword[tundoindex + 1] = operationRecPtr.p->hashValue;
  1011.   undopageptr.p->undoword[tundoindex + 2] = operationRecPtr.p->tupkeylen;
  1012.   tundoindex = tundoindex + 3;
  1013.   if (fragrecptr.p->keyLength != 0) {
  1014.     // Fixed size keys
  1015.     jam();
  1016.     locPageptr.i = operationRecPtr.p->elementPage;
  1017.     ptrCheckGuard(locPageptr, cpagesize, page8);
  1018.     Uint32 Tforward = operationRecPtr.p->elementIsforward;
  1019.     Uint32 TelemPtr = operationRecPtr.p->elementPointer;
  1020.     TelemPtr += Tforward;
  1021.     TelemPtr += Tforward;
  1022.     //--------------------------------------------------------------------------------- 
  1023.     // Now the pointer is at the start of the key part of the element. Now copy from there
  1024.     // to the UNDO log.
  1025.     //--------------------------------------------------------------------------------- 
  1026.     Uint32 keyLen = operationRecPtr.p->tupkeylen;
  1027.     ndbrequire(keyLen <= 8);
  1028.     arrGuard(tundoindex+keyLen, 8192);
  1029.     for (Uint32 twuoiIndex = 0; twuoiIndex < keyLen; twuoiIndex++) {
  1030.       jam();
  1031.       arrGuard(TelemPtr, 2048);
  1032.       undopageptr.p->undoword[tundoindex] = locPageptr.p->word32[TelemPtr];
  1033.       tundoindex++;
  1034.       TelemPtr += Tforward;
  1035.     }//for
  1036.     cundoinfolength = ZOP_HEAD_INFO_LN + operationRecPtr.p->tupkeylen;
  1037.   } else {
  1038.     // Long keys
  1039.     jam();
  1040.     arrGuard(operationRecPtr.p->longKeyPageIndex, ZMAX_NO_OF_LONGKEYS_IN_PAGE);
  1041.     locPageptr.i = operationRecPtr.p->longPagePtr;
  1042.     ptrCheckGuard(locPageptr, cpagesize, page8);
  1043.     Uint32 indexValue = 
  1044.       locPageptr.p->word32[ZWORDS_IN_PAGE - operationRecPtr.p->longKeyPageIndex];
  1045.     Uint32 keyLen = indexValue >> 16;
  1046.     Uint32 physPageIndex = indexValue & 0xffff;
  1047.     ndbrequire(keyLen == operationRecPtr.p->tupkeylen);
  1048.     arrGuard(tundoindex+keyLen, 8192);
  1049.     arrGuard(physPageIndex+keyLen, 2048);
  1050.     for (Uint32 i = 0; i < keyLen; i++){
  1051.       undopageptr.p->undoword[tundoindex + i] = locPageptr.p->word32[physPageIndex+i];
  1052.     }
  1053.     tundoindex = tundoindex + keyLen;    
  1054.     cundoinfolength = ZOP_HEAD_INFO_LN + keyLen;  
  1055.   }//if
  1056. }//Dbacc::writeUndoOpInfo()
  1057. /* --------------------------------------------------------------------------------- */
  1058. /* --------------------------------------------------------------------------------- */
  1059. /* --------------------------------------------------------------------------------- */
  1060. /*                                                                                   */
  1061. /*       END OF LOCAL CHECKPOINT MODULE                                              */
  1062. /*                                                                                   */
  1063. /* --------------------------------------------------------------------------------- */
  1064. /* --------------------------------------------------------------------------------- */
  1065. /* --------------------------------------------------------------------------------- */
  1066. /* --------------------------------------------------------------------------------- */
  1067. /* --------------------------------------------------------------------------------- */
  1068. /*                                                                                   */
  1069. /*       SYSTEM RESTART MODULE                                                       */
  1070. /*                                                                                   */
  1071. /* --------------------------------------------------------------------------------- */
  1072. /* --------------------------------------------------------------------------------- */
  1073. /* ******************--------------------------------------------------------------- */
  1074. /* SR_FRAGIDREQ                                    REQUEST FOR RESTART OF A FRAGMENT */
  1075. /*                                                 SENDER: LQH,    LEVEL B           */
  1076. /*          ENTER  SR_FRAGIDREQ WITH                                                 */
  1077. /*                    TUSERPTR,                    LQH CONNECTION PTR                */
  1078. /*                    TUSERBLOCKREF,               LQH BLOCK REFERENCE               */
  1079. /*                    TCHECKPOINTID,               THE CHECKPOINT NUMBER TO USE      */
  1080. /*                                                     (E.G. 1,2 OR 3)               */
  1081. /*                    TABPTR,                      TABLE ID = TABLE RECORD POINTER   */
  1082. /*                    TFID,                        ROOT FRAGMENT ID                  */
  1083. /* ******************--------------------------------------------------------------- */
  1084. /* ******************--------------------------------------------------------------- */
  1085. /* SR_FRAGIDREQ                           REQUEST FOR LIST OF STOPED OPERATION  */
  1086. /* ******************------------------------------+                                 */
  1087. /*   SENDER: LQH,    LEVEL B       */
  1088. void Dbacc::execSR_FRAGIDREQ(Signal* signal) 
  1089. {
  1090.   jamEntry();
  1091.   tuserptr = signal->theData[0];      /* LQH CONNECTION PTR              */
  1092.   tuserblockref = signal->theData[1]; /* LQH BLOCK REFERENCE             */
  1093.   tcheckpointid = signal->theData[2]; /* THE CHECKPOINT NUMBER TO USE    */
  1094.                                       /*   (E.G. 1,2 OR 3)               */
  1095.   tabptr.i = signal->theData[3];
  1096.   ptrCheckGuard(tabptr, ctablesize, tabrec);
  1097.   /* TABLE ID = TABLE RECORD POINTER */
  1098.   tfid = signal->theData[4];          /* ROOT FRAGMENT ID                */
  1099.   tresult = 0; /* 0= FALSE,1= TRUE,> ZLIMIT_OF_ERROR =ERRORCODE */
  1100.   seizeLcpConnectRec(signal);
  1101.   initLcpConnRec(signal);
  1102.   ndbrequire(getrootfragmentrec(signal, rootfragrecptr, tfid));
  1103.   rootfragrecptr.p->lcpPtr = lcpConnectptr.i;
  1104.   lcpConnectptr.p->rootrecptr = rootfragrecptr.i;
  1105.   lcpConnectptr.p->localCheckPid = tcheckpointid;
  1106.   for (Uint32 i = 0; i < 2; i++) {
  1107.     Page8Ptr zeroPagePtr;
  1108.     jam();
  1109.     fragrecptr.i = rootfragrecptr.p->fragmentptr[i];
  1110.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);    
  1111.     seizeLcpPage(zeroPagePtr);
  1112.     fragrecptr.p->zeroPagePtr = zeroPagePtr.i;
  1113.   }//for
  1114.   /* ---------------------------OPEN THE DATA FILE WHICH BELONGS TO TFID AND TCHECK POINT ---- */
  1115.   fragrecptr.i = rootfragrecptr.p->fragmentptr[0];
  1116.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  1117.   tfid = rootfragrecptr.p->fragmentid[0];
  1118.   tmp = 0;
  1119.   srOpenDataFileLoopLab(signal);
  1120.   
  1121.   return;
  1122. }//Dbacc::execSR_FRAGIDREQ()
  1123. void Dbacc::srOpenDataFileLoopLab(Signal* signal) 
  1124. {
  1125.   /* D6 AT FSOPENREQ. FILE TYPE = .DATA */
  1126.   tmp1 = 0x010003ff;                           /* VERSION OF FILENAME = 1 */
  1127.   tmp2 = 0x0;                                   /* D7 DON'T CREATE, READ ONLY */
  1128.   ndbrequire(cfsFirstfreeconnect != RNIL);
  1129.   seizeFsConnectRec(signal);
  1130.   fragrecptr.p->fsConnPtr = fsConnectptr.i;
  1131.   fsConnectptr.p->fragrecPtr = fragrecptr.i;
  1132.   fsConnectptr.p->fsState = WAIT_OPEN_DATA_FILE_FOR_READ;
  1133.   fsConnectptr.p->activeFragId = tmp; /* LOCAL FRAG INDEX */
  1134.   /* ************************ */
  1135.   /* FSOPENREQ                */
  1136.   /* ************************ */
  1137.   signal->theData[0] = cownBlockref;
  1138.   signal->theData[1] = fsConnectptr.i;
  1139.   signal->theData[2] = rootfragrecptr.p->mytabptr;     /* TABLE IDENTITY */
  1140.   signal->theData[3] = tfid;                           /* FRAGMENT IDENTITY */
  1141.   signal->theData[4] = lcpConnectptr.p->localCheckPid; /* CHECKPOINT ID */
  1142.   signal->theData[5] = tmp1;
  1143.   signal->theData[6] = tmp2;
  1144.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  1145.   return;
  1146. }//Dbacc::srOpenDataFileLoopLab()
  1147. void Dbacc::srFsOpenConfLab(Signal* signal) 
  1148. {
  1149.   fsConnectptr.p->fsState = WAIT_READ_PAGE_ZERO;
  1150.   /* ------------------------  READ ZERO PAGE ---------- */
  1151.   fragrecptr.i = fsConnectptr.p->fragrecPtr;
  1152.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  1153.   signal->theData[0] = fsConnectptr.p->fsPtr;
  1154.   signal->theData[1] = cownBlockref;
  1155.   signal->theData[2] = fsConnectptr.i;
  1156.   signal->theData[3] = 0x0;
  1157.   /* FLAG = LIST MEM PAGES, LIST FILE PAGES */
  1158.   signal->theData[4] = ZPAGE8_BASE_ADD;
  1159.   signal->theData[5] = 1;                 /* NO OF PAGES */
  1160.   signal->theData[6] = fragrecptr.p->zeroPagePtr; /* ZERO PAGE */
  1161.   signal->theData[7] = 0;                 /* PAGE ZERO OF THE DATA FILE */
  1162.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
  1163.   return;
  1164. }//Dbacc::srFsOpenConfLab()
  1165. void Dbacc::srReadPageZeroLab(Signal* signal) 
  1166. {
  1167.   Page8Ptr srzPageptr;
  1168.   rootfragrecptr.i = fragrecptr.p->myroot;
  1169.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  1170.   fragrecptr.p->activeDataFilePage = 1;
  1171.   srzPageptr.i = fragrecptr.p->zeroPagePtr;
  1172.   ptrCheckGuard(srzPageptr, cpagesize, page8);
  1173.   /* --------------------------------------------------------------------------------- */
  1174.   // Check that the checksum of the zero page is ok.
  1175.   /* --------------------------------------------------------------------------------- */
  1176.   ccoPageptr.p = srzPageptr.p;
  1177.   checksumControl(signal, (Uint32)0);
  1178.   if (tresult > 0) {
  1179.     jam();
  1180.     return; // We will crash through a DEBUG_SIG
  1181.   }//if
  1182.   ndbrequire(srzPageptr.p->word32[ZPAGEZERO_FRAGID0] == rootfragrecptr.p->fragmentid[0]);
  1183.   lcpConnectptr.i = rootfragrecptr.p->lcpPtr;
  1184.   ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  1185.   if (fsConnectptr.p->activeFragId == 0) {
  1186.     jam();
  1187.     rootfragrecptr.p->fragmentid[1] = srzPageptr.p->word32[ZPAGEZERO_FRAGID1];
  1188.     /* ---------------------------OPEN THE DATA FILE FOR NEXT LOCAL FRAGMENT ----------- ---- */
  1189.     tfid = rootfragrecptr.p->fragmentid[1];
  1190.     tmp = 1; /* LOCAL FRAG INDEX */
  1191.     fragrecptr.i = rootfragrecptr.p->fragmentptr[1];
  1192.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  1193.     srOpenDataFileLoopLab(signal);
  1194.     return;
  1195.   } else {
  1196.     jam();
  1197.     lcpConnectptr.p->lcpstate = LCP_ACTIVE;
  1198.     signal->theData[0] = lcpConnectptr.p->lcpUserptr;
  1199.     signal->theData[1] = lcpConnectptr.i;
  1200.     signal->theData[2] = 2;                         /* NO OF LOCAL FRAGMENTS */
  1201.     signal->theData[3] = srzPageptr.p->word32[ZPAGEZERO_FRAGID0];
  1202.     /* ROOTFRAGRECPTR:FRAGMENTID(0) */
  1203.     signal->theData[4] = srzPageptr.p->word32[ZPAGEZERO_FRAGID1];
  1204.     /* ROOTFRAGRECPTR:FRAGMENTID(1) */
  1205.     signal->theData[5] = RNIL;
  1206.     signal->theData[6] = RNIL;
  1207.     signal->theData[7] = rootfragrecptr.p->fragmentptr[0];
  1208.     signal->theData[8] = rootfragrecptr.p->fragmentptr[1];
  1209.     signal->theData[9] = srzPageptr.p->word32[ZPAGEZERO_HASH_CHECK];
  1210.     sendSignal(lcpConnectptr.p->lcpUserblockref, GSN_SR_FRAGIDCONF, signal, 10, JBB);
  1211.   }//if
  1212.   return;
  1213. }//Dbacc::srReadPageZeroLab()
  1214. void Dbacc::initFragAdd(Signal* signal,
  1215.                         Uint32 rootFragIndex,
  1216.                         Uint32 rootIndex,
  1217.                         FragmentrecPtr regFragPtr) 
  1218. {
  1219.   const AccFragReq * const req = (AccFragReq*)&signal->theData[0];  
  1220.   Uint32 lhFragBits = req->lhFragBits + 1;
  1221.   Uint32 minLoadFactor = (req->minLoadFactor * ZBUF_SIZE) / 100;
  1222.   Uint32 maxLoadFactor = (req->maxLoadFactor * ZBUF_SIZE) / 100;
  1223.   if (minLoadFactor >= maxLoadFactor) {
  1224.     jam();
  1225.     minLoadFactor = maxLoadFactor - 1;
  1226.   }//if
  1227.   regFragPtr.p->fragState = ACTIVEFRAG;
  1228.   // NOTE: next line must match calculation in Dblqh::execLQHFRAGREQ
  1229.   regFragPtr.p->myfid = (rootFragIndex << (lhFragBits - 1)) | req->fragId;
  1230.   regFragPtr.p->myroot = rootIndex;
  1231.   regFragPtr.p->myTableId = req->tableId;
  1232.   ndbrequire(req->kValue == 6);
  1233.   regFragPtr.p->k = req->kValue; /* TK_SIZE = 6 IN THIS VERSION */
  1234.   regFragPtr.p->expandCounter = 0;
  1235.   /**
  1236.    * Only allow shrink during SR
  1237.    *   - to make sure we don't run out of pages during REDO log execution
  1238.    *
  1239.    * Is later restored to 0 by LQH at end of REDO log execution
  1240.    */
  1241.   regFragPtr.p->expandFlag = (getNodeState().getSystemRestartInProgress()?1:0);
  1242.   regFragPtr.p->p = 0;
  1243.   regFragPtr.p->maxp = (1 << req->kValue) - 1;
  1244.   regFragPtr.p->minloadfactor = minLoadFactor;
  1245.   regFragPtr.p->maxloadfactor = maxLoadFactor;
  1246.   regFragPtr.p->slack = (regFragPtr.p->maxp + 1) * maxLoadFactor;
  1247.   regFragPtr.p->lhfragbits = lhFragBits;
  1248.   regFragPtr.p->lhdirbits = 0;
  1249.   regFragPtr.p->hashcheckbit = 0; //lhFragBits;
  1250.   regFragPtr.p->localkeylen = req->localKeyLen;
  1251.   regFragPtr.p->nodetype = (req->reqInfo >> 4) & 0x3;
  1252.   regFragPtr.p->lastOverIndex = 0;
  1253.   regFragPtr.p->dirsize = 1;
  1254.   regFragPtr.p->loadingFlag = ZFALSE;
  1255.   regFragPtr.p->keyLength = req->keyLength;
  1256.   if (req->keyLength == 0) {
  1257.     jam();
  1258.     regFragPtr.p->elementLength = (1 + ZELEM_HEAD_SIZE) + regFragPtr.p->localkeylen;
  1259.   } else {
  1260.     jam();
  1261.     regFragPtr.p->elementLength = (ZELEM_HEAD_SIZE + regFragPtr.p->localkeylen) + regFragPtr.p->keyLength;
  1262.   }//if
  1263.   Uint32 Tmp1 = (regFragPtr.p->maxp + 1) + regFragPtr.p->p;
  1264.   Uint32 Tmp2 = regFragPtr.p->maxloadfactor - regFragPtr.p->minloadfactor;
  1265.   Tmp2 = Tmp1 * Tmp2;
  1266.   regFragPtr.p->slackCheck = Tmp2;
  1267. }//Dbacc::initFragAdd()
  1268. void Dbacc::initFragGeneral(FragmentrecPtr regFragPtr)
  1269. {
  1270.   regFragPtr.p->directory = RNIL;
  1271.   regFragPtr.p->overflowdir = RNIL;
  1272.   regFragPtr.p->fsConnPtr = RNIL;
  1273.   regFragPtr.p->firstOverflowRec = RNIL;
  1274.   regFragPtr.p->lastOverflowRec = RNIL;
  1275.   regFragPtr.p->firstWaitInQueOp = RNIL;
  1276.   regFragPtr.p->lastWaitInQueOp = RNIL;
  1277.   regFragPtr.p->sentWaitInQueOp = RNIL;
  1278.   regFragPtr.p->lockOwnersList = RNIL;
  1279.   regFragPtr.p->firstFreeDirindexRec = RNIL;
  1280.   regFragPtr.p->zeroPagePtr = RNIL;
  1281.   regFragPtr.p->activeDataPage = 0;
  1282.   regFragPtr.p->createLcp = ZFALSE;
  1283.   regFragPtr.p->stopQueOp = ZFALSE;
  1284.   regFragPtr.p->nextAllocPage = 0;
  1285.   regFragPtr.p->nrWaitWriteUndoExit = 0;
  1286.   regFragPtr.p->lastUndoIsStored = ZFALSE;
  1287.   regFragPtr.p->loadingFlag = ZFALSE;
  1288.   regFragPtr.p->fragState = FREEFRAG;
  1289.   for (Uint32 i = 0; i < ZWRITEPAGESIZE; i++) {
  1290.     regFragPtr.p->datapages[i] = RNIL;
  1291.   }//for
  1292.   for (Uint32 j = 0; j < 4; j++) {
  1293.     regFragPtr.p->longKeyPageArray[j] = RNIL;
  1294.   }//for
  1295. }//Dbacc::initFragGeneral()
  1296. void Dbacc::initFragSr(FragmentrecPtr regFragPtr, Page8Ptr regPagePtr) 
  1297. {
  1298.   regFragPtr.p->prevUndoposition =    regPagePtr.p->word32[ZPAGEZERO_PREV_UNDOP];
  1299.   regFragPtr.p->noOfStoredOverPages = regPagePtr.p->word32[ZPAGEZERO_NO_OVER_PAGE];
  1300.   regFragPtr.p->noStoredPages =       regPagePtr.p->word32[ZPAGEZERO_NO_PAGES];
  1301.   regFragPtr.p->dirsize =             regPagePtr.p->word32[ZPAGEZERO_DIRSIZE];
  1302.   regFragPtr.p->expandCounter =       regPagePtr.p->word32[ZPAGEZERO_EXPCOUNTER];
  1303.   regFragPtr.p->slack =               regPagePtr.p->word32[ZPAGEZERO_SLACK];
  1304.   regFragPtr.p->hashcheckbit =        regPagePtr.p->word32[ZPAGEZERO_HASHCHECKBIT];
  1305.   regFragPtr.p->k =                   regPagePtr.p->word32[ZPAGEZERO_K];
  1306.   regFragPtr.p->lhfragbits =          regPagePtr.p->word32[ZPAGEZERO_LHFRAGBITS];
  1307.   regFragPtr.p->lhdirbits =           regPagePtr.p->word32[ZPAGEZERO_LHDIRBITS];
  1308.   regFragPtr.p->localkeylen =         regPagePtr.p->word32[ZPAGEZERO_LOCALKEYLEN];
  1309.   regFragPtr.p->maxp =                regPagePtr.p->word32[ZPAGEZERO_MAXP];
  1310.   regFragPtr.p->maxloadfactor =       regPagePtr.p->word32[ZPAGEZERO_MAXLOADFACTOR];
  1311.   regFragPtr.p->minloadfactor =       regPagePtr.p->word32[ZPAGEZERO_MINLOADFACTOR];
  1312.   regFragPtr.p->myfid =               regPagePtr.p->word32[ZPAGEZERO_MYFID];
  1313.   regFragPtr.p->lastOverIndex =       regPagePtr.p->word32[ZPAGEZERO_LAST_OVER_INDEX];
  1314.   regFragPtr.p->nodetype =            regPagePtr.p->word32[ZPAGEZERO_NODETYPE];
  1315.   regFragPtr.p->p =                   regPagePtr.p->word32[ZPAGEZERO_P];
  1316.   regFragPtr.p->elementLength =       regPagePtr.p->word32[ZPAGEZERO_ELEMENT_LENGTH];
  1317.   regFragPtr.p->keyLength =           regPagePtr.p->word32[ZPAGEZERO_KEY_LENGTH];
  1318.   regFragPtr.p->slackCheck =          regPagePtr.p->word32[ZPAGEZERO_SLACK_CHECK];
  1319.   regFragPtr.p->loadingFlag = ZTRUE;
  1320. }//Dbacc::initFragSr()
  1321. void Dbacc::initFragPageZero(FragmentrecPtr regFragPtr, Page8Ptr regPagePtr) 
  1322. {
  1323.   //------------------------------------------------------------------
  1324.   // PREV_UNDOP, NEXT_UNDO_FILE, NO_OVER_PAGE, NO_PAGES
  1325.   // is set at end of copy phase
  1326.   //------------------------------------------------------------------
  1327.   regPagePtr.p->word32[ZPAGEZERO_DIRSIZE] = regFragPtr.p->dirsize;
  1328.   regPagePtr.p->word32[ZPAGEZERO_EXPCOUNTER] = regFragPtr.p->expandCounter;
  1329.   regPagePtr.p->word32[ZPAGEZERO_SLACK] = regFragPtr.p->slack;
  1330.   regPagePtr.p->word32[ZPAGEZERO_HASHCHECKBIT] = regFragPtr.p->hashcheckbit;
  1331.   regPagePtr.p->word32[ZPAGEZERO_K] = regFragPtr.p->k;
  1332.   regPagePtr.p->word32[ZPAGEZERO_LHFRAGBITS] = regFragPtr.p->lhfragbits;
  1333.   regPagePtr.p->word32[ZPAGEZERO_LHDIRBITS] = regFragPtr.p->lhdirbits;
  1334.   regPagePtr.p->word32[ZPAGEZERO_LOCALKEYLEN] = regFragPtr.p->localkeylen;
  1335.   regPagePtr.p->word32[ZPAGEZERO_MAXP] = regFragPtr.p->maxp;
  1336.   regPagePtr.p->word32[ZPAGEZERO_MAXLOADFACTOR] = regFragPtr.p->maxloadfactor;
  1337.   regPagePtr.p->word32[ZPAGEZERO_MINLOADFACTOR] = regFragPtr.p->minloadfactor;
  1338.   regPagePtr.p->word32[ZPAGEZERO_MYFID] = regFragPtr.p->myfid;
  1339.   regPagePtr.p->word32[ZPAGEZERO_LAST_OVER_INDEX] = regFragPtr.p->lastOverIndex;
  1340.   regPagePtr.p->word32[ZPAGEZERO_NODETYPE] = regFragPtr.p->nodetype;
  1341.   regPagePtr.p->word32[ZPAGEZERO_P] = regFragPtr.p->p;
  1342.   regPagePtr.p->word32[ZPAGEZERO_ELEMENT_LENGTH] = regFragPtr.p->elementLength;
  1343.   regPagePtr.p->word32[ZPAGEZERO_KEY_LENGTH] = regFragPtr.p->keyLength;
  1344.   regPagePtr.p->word32[ZPAGEZERO_SLACK_CHECK] = regFragPtr.p->slackCheck;
  1345. }//Dbacc::initFragPageZero()
  1346. void Dbacc::initRootFragPageZero(RootfragmentrecPtr rootPtr, Page8Ptr regPagePtr) 
  1347. {
  1348.   regPagePtr.p->word32[ZPAGEZERO_TABID] = rootPtr.p->mytabptr;
  1349.   regPagePtr.p->word32[ZPAGEZERO_FRAGID0] = rootPtr.p->fragmentid[0];
  1350.   regPagePtr.p->word32[ZPAGEZERO_FRAGID1] = rootPtr.p->fragmentid[1];
  1351.   regPagePtr.p->word32[ZPAGEZERO_HASH_CHECK] = rootPtr.p->roothashcheck;
  1352.   regPagePtr.p->word32[ZPAGEZERO_NO_OF_ELEMENTS] = rootPtr.p->noOfElements;
  1353. }//Dbacc::initRootFragPageZero()
  1354. void Dbacc::initRootFragSr(RootfragmentrecPtr rootPtr, Page8Ptr regPagePtr)
  1355. {
  1356.   rootPtr.p->roothashcheck = regPagePtr.p->word32[ZPAGEZERO_HASH_CHECK];
  1357.   rootPtr.p->noOfElements = regPagePtr.p->word32[ZPAGEZERO_NO_OF_ELEMENTS];
  1358. }//Dbacc::initRootFragSr()
  1359. /* ******************--------------------------------------------------------------- */
  1360. /* ACC_SRREQ                               SYSTEM RESTART OF A LOCAL CHECK POINT     */
  1361. /*                                                   SENDER: LQH,    LEVEL B         */
  1362. /*          ENTER ACC_SRREQ WITH                                                     */
  1363. /*                    LCP_CONNECTPTR,                OPERATION RECORD PTR            */
  1364. /*                    TMP2,                          LQH'S  LOCAL FRAG CHECK VALUE   */
  1365. /*                    TFID,                          LOCAL FRAG ID                   */
  1366. /*                    TMP1,                          LOCAL CHECKPOINT ID             */
  1367. /* ******************--------------------------------------------------------------- */
  1368. /* ******************--------------------------------------------------------------- */
  1369. /* ACC_SRREQ                                       PERFORM A LOCAL CHECK POINT      */
  1370. /* ******************------------------------------+                                 */
  1371. /*   SENDER: LQH,    LEVEL B       */
  1372. void Dbacc::execACC_SRREQ(Signal* signal) 
  1373. {
  1374.   Page8Ptr asrPageidptr;
  1375.   jamEntry();
  1376.   lcpConnectptr.i = signal->theData[0];
  1377.   ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  1378.   Uint32 lqhPtr = signal->theData[1];
  1379.   Uint32 fragId = signal->theData[2];
  1380.   Uint32 lcpId = signal->theData[3];
  1381.   tresult = 0;
  1382.   ndbrequire(lcpConnectptr.p->lcpstate == LCP_ACTIVE);
  1383.   rootfragrecptr.i = lcpConnectptr.p->rootrecptr;
  1384.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  1385.   if (rootfragrecptr.p->fragmentid[0] == fragId) {
  1386.     jam();
  1387.     fragrecptr.i = rootfragrecptr.p->fragmentptr[0];
  1388.   } else {
  1389.     ndbrequire(rootfragrecptr.p->fragmentid[1] == fragId);
  1390.     jam();
  1391.     fragrecptr.i = rootfragrecptr.p->fragmentptr[1];
  1392.   }//if
  1393.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  1394.   fragrecptr.p->lcpLqhPtr = lqhPtr;
  1395.   fragrecptr.p->localCheckpId = lcpId;
  1396.   asrPageidptr.i = fragrecptr.p->zeroPagePtr;
  1397.   ptrCheckGuard(asrPageidptr, cpagesize, page8);
  1398.   ndbrequire(asrPageidptr.p->word32[ZPAGEZERO_TABID] == rootfragrecptr.p->mytabptr);
  1399.   ndbrequire(asrPageidptr.p->word32[ZPAGEZERO_FRAGID0] == rootfragrecptr.p->fragmentid[0]);
  1400.   ndbrequire(asrPageidptr.p->word32[ZPAGEZERO_FRAGID1] == rootfragrecptr.p->fragmentid[1]);
  1401.   initRootFragSr(rootfragrecptr, asrPageidptr);
  1402.   initFragSr(fragrecptr, asrPageidptr);
  1403.   for (Uint32 i = 0; i < ZMAX_UNDO_VERSION; i++) {
  1404.     jam();
  1405.     if (csrVersList[i] != RNIL) {
  1406.       jam();
  1407.       srVersionPtr.i = csrVersList[i];
  1408.       ptrCheckGuard(srVersionPtr, csrVersionRecSize, srVersionRec);
  1409.       if (fragrecptr.p->localCheckpId == srVersionPtr.p->checkPointId) {
  1410.         jam();
  1411.         ndbrequire(srVersionPtr.p->checkPointId == asrPageidptr.p->word32[ZPAGEZERO_NEXT_UNDO_FILE]);
  1412. /*--------------------------------------------------------------------------------*/
  1413. /*       SINCE -1 IS THE END OF LOG CODE WE MUST TREAT THIS CODE WITH CARE. WHEN  */
  1414. /*       COMPARING IT IS LARGER THAN EVERYTHING ELSE BUT SHOULD BE TREATED AS THE */
  1415. /*       SMALLEST POSSIBLE VALUE, MEANING EMPTY.                                  */
  1416. /*--------------------------------------------------------------------------------*/
  1417.         if (fragrecptr.p->prevUndoposition != cminusOne) {
  1418.           if (srVersionPtr.p->prevAddress < fragrecptr.p->prevUndoposition) {
  1419.             jam();
  1420.             srVersionPtr.p->prevAddress = fragrecptr.p->prevUndoposition;
  1421.           } else if (srVersionPtr.p->prevAddress == cminusOne) {
  1422.             jam();
  1423.             srVersionPtr.p->prevAddress = fragrecptr.p->prevUndoposition;
  1424.           }//if
  1425.         }//if
  1426.         srAllocPage0011Lab(signal);
  1427.         return;
  1428.       }//if
  1429.     } else {
  1430.       jam();
  1431.       seizeSrVerRec(signal);
  1432.       srVersionPtr.p->checkPointId = fragrecptr.p->localCheckpId;
  1433.       srVersionPtr.p->prevAddress = fragrecptr.p->prevUndoposition;
  1434.       csrVersList[i] = srVersionPtr.i;
  1435.       srAllocPage0011Lab(signal);
  1436.       return;
  1437.     }//if
  1438.   }//for
  1439.   ndbrequire(false);
  1440. }//Dbacc::execACC_SRREQ()
  1441. void
  1442. Dbacc::releaseLogicalPage(Fragmentrec * fragP, Uint32 logicalPageId){
  1443.   Ptr<struct DirRange> dirRangePtr;
  1444.   dirRangePtr.i = fragP->directory;
  1445.   ptrCheckGuard(dirRangePtr, cdirrangesize, dirRange);
  1446.   const Uint32 lp1 = logicalPageId >> 8;
  1447.   const Uint32 lp2 = logicalPageId & 0xFF;
  1448.   ndbrequire(lp1 < 256);
  1449.   Ptr<struct Directoryarray> dirArrPtr;
  1450.   dirArrPtr.i = dirRangePtr.p->dirArray[lp1];
  1451.   ptrCheckGuard(dirArrPtr, cdirarraysize, directoryarray);
  1452.   const Uint32 physicalPageId = dirArrPtr.p->pagep[lp2];
  1453.   
  1454.   rpPageptr.i = physicalPageId;
  1455.   ptrCheckGuard(rpPageptr, cpagesize, page8);
  1456.   releasePage(0);
  1457.   dirArrPtr.p->pagep[lp2] = RNIL;
  1458. }
  1459. void Dbacc::srAllocPage0011Lab(Signal* signal) 
  1460. {
  1461.   releaseLogicalPage(fragrecptr.p, 0);
  1462. #if JONAS
  1463.   ndbrequire(cfirstfreeDirrange != RNIL);
  1464.   seizeDirrange(signal);
  1465.   fragrecptr.p->directory = newDirRangePtr.i;
  1466.   ndbrequire(cfirstfreeDirrange != RNIL);
  1467.   seizeDirrange(signal);
  1468.   fragrecptr.p->overflowdir = newDirRangePtr.i;
  1469.   seizeDirectory(signal);
  1470.   ndbrequire(tresult < ZLIMIT_OF_ERROR);
  1471.   newDirRangePtr.p->dirArray[0] = sdDirptr.i;
  1472. #endif
  1473.   fragrecptr.p->nextAllocPage = 0;
  1474.   fragrecptr.p->fragState = SR_READ_PAGES;
  1475.   srReadPagesLab(signal);
  1476.   return;
  1477. }//Dbacc::srAllocPage0011Lab()
  1478. void Dbacc::srReadPagesLab(Signal* signal) 
  1479. {
  1480.   if (fragrecptr.p->nextAllocPage >= fragrecptr.p->noStoredPages) {
  1481.     /*--------------------------------------------------------------------------------*/
  1482.     /*       WE HAVE NOW READ ALL NORMAL PAGES FROM THE FILE.                         */
  1483.     /*--------------------------------------------------------------------------------*/
  1484.     if (fragrecptr.p->nextAllocPage == fragrecptr.p->dirsize) {
  1485.       jam();
  1486.       /*--------------------------------------------------------------------------------*/
  1487.       /*       WE HAVE NOW READ ALL NORMAL PAGES AND ALLOCATED ALL THE NEEDED PAGES.    */
  1488.       /*--------------------------------------------------------------------------------*/
  1489.       fragrecptr.p->nextAllocPage = 0; /* THE NEXT OVER FLOW PAGE WHICH WILL BE READ */
  1490.       fragrecptr.p->fragState = SR_READ_OVER_PAGES;
  1491.       srReadOverPagesLab(signal);
  1492.     } else {
  1493.       ndbrequire(fragrecptr.p->nextAllocPage < fragrecptr.p->dirsize);
  1494.       jam();
  1495.       /*--------------------------------------------------------------------------------*/
  1496.       /*       WE NEEDED TO ALLOCATE PAGES THAT WERE DEALLOCATED DURING THE LOCAL       */
  1497.       /*       CHECKPOINT.                                                              */
  1498.       /*       ALLOCATE THE PAGE AND INITIALISE IT. THEN WE INSERT A REAL-TIME BREAK.   */
  1499.       /*--------------------------------------------------------------------------------*/
  1500.       seizePage(signal);
  1501.       ndbrequire(tresult <= ZLIMIT_OF_ERROR);
  1502.       tipPageId = fragrecptr.p->nextAllocPage;
  1503.       inpPageptr.i = spPageptr.i;
  1504.       ptrCheckGuard(inpPageptr, cpagesize, page8);
  1505.       initPage(signal);
  1506.       fragrecptr.p->noOfExpectedPages = 1;
  1507.       fragrecptr.p->datapages[0] = spPageptr.i;
  1508.       signal->theData[0] = ZSR_READ_PAGES_ALLOC;
  1509.       signal->theData[1] = fragrecptr.i;
  1510.       sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
  1511.     }//if
  1512.     return;
  1513.   }//if
  1514.   Uint32 limitLoop;
  1515.   if ((fragrecptr.p->noStoredPages - fragrecptr.p->nextAllocPage) < ZWRITEPAGESIZE) {
  1516.     jam();
  1517.     limitLoop = fragrecptr.p->noStoredPages - fragrecptr.p->nextAllocPage;
  1518.   } else {
  1519.     jam();
  1520.     limitLoop = ZWRITEPAGESIZE;
  1521.   }//if
  1522.   ndbrequire(limitLoop <= 8);
  1523.   for (Uint32 i = 0; i < limitLoop; i++) {
  1524.     jam();
  1525.     seizePage(signal);
  1526.     ndbrequire(tresult <= ZLIMIT_OF_ERROR);
  1527.     fragrecptr.p->datapages[i] = spPageptr.i;
  1528.     signal->theData[i + 6] = spPageptr.i;
  1529.   }//for
  1530.   signal->theData[limitLoop + 6] = fragrecptr.p->activeDataFilePage;
  1531.   fragrecptr.p->noOfExpectedPages = limitLoop;
  1532.   /* -----------------SEND READ PAGES SIGNAL TO THE FILE MANAGER --------- */
  1533.   fsConnectptr.i = fragrecptr.p->fsConnPtr;
  1534.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  1535.   fsConnectptr.p->fsState = WAIT_READ_DATA;
  1536.   signal->theData[0] = fsConnectptr.p->fsPtr;
  1537.   signal->theData[1] = cownBlockref;
  1538.   signal->theData[2] = fsConnectptr.i;
  1539.   signal->theData[3] = 2;
  1540.   /* FLAG = LIST MEM PAGES, RANGE OF FILE PAGES */
  1541.   signal->theData[4] = ZPAGE8_BASE_ADD;
  1542.   signal->theData[5] = fragrecptr.p->noOfExpectedPages;
  1543.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 15, JBA);
  1544.   return;
  1545. }//Dbacc::srReadPagesLab()
  1546. void Dbacc::storeDataPageInDirectoryLab(Signal* signal) 
  1547. {
  1548.   fragrecptr.p->activeDataFilePage += fragrecptr.p->noOfExpectedPages;
  1549.   srReadPagesAllocLab(signal);
  1550.   return;
  1551. }//Dbacc::storeDataPageInDirectoryLab()
  1552. void Dbacc::srReadPagesAllocLab(Signal* signal) 
  1553. {
  1554.   DirRangePtr srpDirRangePtr;
  1555.   DirectoryarrayPtr srpDirptr;
  1556.   DirectoryarrayPtr srpOverflowDirptr;
  1557.   Page8Ptr srpPageidptr;
  1558.   if (fragrecptr.p->fragState == SR_READ_PAGES) {
  1559.     jam();
  1560.     for (Uint32 i = 0; i < fragrecptr.p->noOfExpectedPages; i++) {
  1561.       jam();
  1562.       tmpP = fragrecptr.p->nextAllocPage;
  1563.       srpDirRangePtr.i = fragrecptr.p->directory;
  1564.       tmpP2 = tmpP >> 8;
  1565.       tmp = tmpP & 0xff;
  1566.       ptrCheckGuard(srpDirRangePtr, cdirrangesize, dirRange);
  1567.       arrGuard(tmpP2, 256);
  1568.       if (srpDirRangePtr.p->dirArray[tmpP2] == RNIL) {
  1569.         seizeDirectory(signal);
  1570.         ndbrequire(tresult <= ZLIMIT_OF_ERROR);
  1571.         srpDirptr.i = sdDirptr.i;
  1572.         srpDirRangePtr.p->dirArray[tmpP2] = srpDirptr.i;
  1573.       } else {
  1574.         jam();
  1575.         srpDirptr.i = srpDirRangePtr.p->dirArray[tmpP2];
  1576.       }//if
  1577.       ptrCheckGuard(srpDirptr, cdirarraysize, directoryarray);
  1578.       arrGuard(i, 8);
  1579.       srpDirptr.p->pagep[tmp] = fragrecptr.p->datapages[i];
  1580.       srpPageidptr.i = fragrecptr.p->datapages[i];
  1581.       ptrCheckGuard(srpPageidptr, cpagesize, page8);
  1582.       ndbrequire(srpPageidptr.p->word32[ZPOS_PAGE_ID] == fragrecptr.p->nextAllocPage);
  1583.       ndbrequire(((srpPageidptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) == 0);
  1584.       ccoPageptr.p = srpPageidptr.p;
  1585.       checksumControl(signal, (Uint32)1);
  1586.       if (tresult > 0) {
  1587.         jam();
  1588.         return; // We will crash through a DEBUG_SIG
  1589.       }//if
  1590.       dbgWord32(srpPageidptr, ZPOS_OVERFLOWREC, RNIL);
  1591.       srpPageidptr.p->word32[ZPOS_OVERFLOWREC] = RNIL;
  1592.       fragrecptr.p->datapages[i] = RNIL;
  1593.       fragrecptr.p->nextAllocPage++;
  1594.     }//for
  1595.     srReadPagesLab(signal);
  1596.     return;
  1597.   } else {
  1598.     ndbrequire(fragrecptr.p->fragState == SR_READ_OVER_PAGES);
  1599.     for (Uint32 i = 0; i < fragrecptr.p->noOfExpectedPages; i++) {
  1600.       jam();
  1601.       arrGuard(i, 8);
  1602.       srpPageidptr.i = fragrecptr.p->datapages[i];
  1603.       ptrCheckGuard(srpPageidptr, cpagesize, page8);
  1604.       tmpP = srpPageidptr.p->word32[ZPOS_PAGE_ID]; /* DIR INDEX OF THE OVERFLOW PAGE */
  1605.       /*--------------------------------------------------------------------------------*/
  1606.       /*       IT IS POSSIBLE THAT WE HAVE LOGICAL PAGES WHICH ARE NOT PART OF THE LOCAL*/
  1607.       /*       CHECKPOINT. THUS WE USE THE LOGICAL PAGE ID FROM THE PAGE HERE.          */
  1608.       /*--------------------------------------------------------------------------------*/
  1609.       srpDirRangePtr.i = fragrecptr.p->overflowdir;
  1610.       tmpP2 = tmpP >> 8;
  1611.       tmpP = tmpP & 0xff;
  1612.       ptrCheckGuard(srpDirRangePtr, cdirrangesize, dirRange);
  1613.       arrGuard(tmpP2, 256);
  1614.       if (srpDirRangePtr.p->dirArray[tmpP2] == RNIL) {
  1615.         jam();
  1616.         seizeDirectory(signal);
  1617.         ndbrequire(tresult <= ZLIMIT_OF_ERROR);
  1618.         srpDirRangePtr.p->dirArray[tmpP2] = sdDirptr.i;
  1619.       }//if
  1620.       srpOverflowDirptr.i = srpDirRangePtr.p->dirArray[tmpP2];
  1621.       ndbrequire(((srpPageidptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) != 0);
  1622.       ndbrequire(((srpPageidptr.p->word32[ZPOS_PAGE_TYPE] >> ZPOS_PAGE_TYPE_BIT) & 3) != 3);
  1623.       ptrCheckGuard(srpOverflowDirptr, cdirarraysize, directoryarray);
  1624.       ndbrequire(srpOverflowDirptr.p->pagep[tmpP] == RNIL);
  1625.       srpOverflowDirptr.p->pagep[tmpP] = srpPageidptr.i;
  1626.       ccoPageptr.p = srpPageidptr.p;
  1627.       checksumControl(signal, (Uint32)1);
  1628.       ndbrequire(tresult == 0);
  1629.       dbgWord32(srpPageidptr, ZPOS_OVERFLOWREC, RNIL);
  1630.       srpPageidptr.p->word32[ZPOS_OVERFLOWREC] = RNIL;
  1631.       fragrecptr.p->nextAllocPage++;
  1632.     }//for
  1633.     srReadOverPagesLab(signal);
  1634.     return;
  1635.   }//if
  1636. }//Dbacc::srReadPagesAllocLab()
  1637. void Dbacc::srReadOverPagesLab(Signal* signal) 
  1638. {
  1639.   if (fragrecptr.p->nextAllocPage >= fragrecptr.p->noOfStoredOverPages) {
  1640.     fragrecptr.p->nextAllocPage = 0;
  1641.     if (fragrecptr.p->prevUndoposition == cminusOne) {
  1642.       jam();
  1643.       /* ************************ */
  1644.       /*   ACC_OVER_REC           */
  1645.       /* ************************ */
  1646.       /*--------------------------------------------------------------------------------*/
  1647.       /*       UPDATE FREE LIST OF OVERFLOW PAGES AS PART OF SYSTEM RESTART AFTER       */
  1648.       /*       READING PAGES AND EXECUTING THE UNDO LOG.                                */
  1649.       /*--------------------------------------------------------------------------------*/
  1650.       signal->theData[0] = fragrecptr.i;
  1651.       sendSignal(cownBlockref, GSN_ACC_OVER_REC, signal, 1, JBB);
  1652.     } else {
  1653.       jam();
  1654.       srCloseDataFileLab(signal);
  1655.     }//if
  1656.     return;
  1657.   }//if
  1658.   Uint32 limitLoop;
  1659.   if ((fragrecptr.p->noOfStoredOverPages - fragrecptr.p->nextAllocPage) < ZWRITEPAGESIZE) {
  1660.     jam();
  1661.     limitLoop = fragrecptr.p->noOfStoredOverPages - fragrecptr.p->nextAllocPage;
  1662.   } else {
  1663.     jam();
  1664.     limitLoop = ZWRITEPAGESIZE;
  1665.   }//if
  1666.   ndbrequire(limitLoop <= 8);
  1667.   for (Uint32 i = 0; i < limitLoop; i++) {
  1668.     jam();
  1669.     seizePage(signal);
  1670.     ndbrequire(tresult <= ZLIMIT_OF_ERROR);
  1671.     fragrecptr.p->datapages[i] = spPageptr.i;
  1672.     signal->theData[i + 6] = spPageptr.i;
  1673.   }//for
  1674.   fragrecptr.p->noOfExpectedPages = limitLoop;
  1675.   signal->theData[limitLoop + 6] = fragrecptr.p->activeDataFilePage;
  1676.   /* -----------------SEND READ PAGES SIGNAL TO THE FILE MANAGER --------- */
  1677.   fsConnectptr.i = fragrecptr.p->fsConnPtr;
  1678.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  1679.   fsConnectptr.p->fsState = WAIT_READ_DATA;
  1680.   signal->theData[0] = fsConnectptr.p->fsPtr;
  1681.   signal->theData[1] = cownBlockref;
  1682.   signal->theData[2] = fsConnectptr.i;
  1683.   signal->theData[3] = 2;
  1684.   signal->theData[4] = ZPAGE8_BASE_ADD;
  1685.   signal->theData[5] = fragrecptr.p->noOfExpectedPages;
  1686.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 15, JBA);
  1687.   return;
  1688. }//Dbacc::srReadOverPagesLab()
  1689. void Dbacc::srCloseDataFileLab(Signal* signal) 
  1690. {
  1691.   fsConnectptr.i = fragrecptr.p->fsConnPtr;
  1692.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  1693.   fsConnectptr.p->fsState = SR_CLOSE_DATA;
  1694.   /* ************************ */
  1695.   /* FSCLOSEREQ               */
  1696.   /* ************************ */
  1697.   signal->theData[0] = fsConnectptr.p->fsPtr;
  1698.   signal->theData[1] = cownBlockref;
  1699.   signal->theData[2] = fsConnectptr.i;
  1700.   signal->theData[3] = 0;
  1701.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  1702.   return;
  1703. }//Dbacc::srCloseDataFileLab()
  1704. /* ************************ */
  1705. /* ACC_SRCONF               */
  1706. /* ************************ */
  1707. void Dbacc::sendaccSrconfLab(Signal* signal) 
  1708. {
  1709.   fragrecptr.i = fsConnectptr.p->fragrecPtr;
  1710.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  1711.   releaseFsConnRec(signal);
  1712.   rootfragrecptr.i = fragrecptr.p->myroot;
  1713.   ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  1714.   lcpConnectptr.i = rootfragrecptr.p->lcpPtr;
  1715.   ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  1716.   fragrecptr.p->fragState = ACTIVEFRAG;
  1717.   fragrecptr.p->fsConnPtr = RNIL;
  1718.   for (Uint32 i = 0; i < ZWRITEPAGESIZE; i++) {
  1719.     fragrecptr.p->datapages[i] = RNIL;
  1720.   }//for
  1721.   rlpPageptr.i = fragrecptr.p->zeroPagePtr;
  1722.   ptrCheckGuard(rlpPageptr, cpagesize, page8);
  1723.   releaseLcpPage(signal);
  1724.   fragrecptr.p->zeroPagePtr = RNIL;
  1725.   signal->theData[0] = fragrecptr.p->lcpLqhPtr;
  1726.   sendSignal(lcpConnectptr.p->lcpUserblockref, GSN_ACC_SRCONF, signal, 1, JBB);
  1727.   lcpConnectptr.p->noOfLcpConf++;
  1728.   if (lcpConnectptr.p->noOfLcpConf == 2) {
  1729.     jam();
  1730.     releaseLcpConnectRec(signal);
  1731.     rootfragrecptr.p->lcpPtr = RNIL;
  1732.     rootfragrecptr.p->rootState = ACTIVEROOT;
  1733.   }//if
  1734.   return;
  1735. }//Dbacc::sendaccSrconfLab()
  1736. /* --------------------------------------------------------------------------------- */
  1737. /*       CHECKSUM_CONTROL                                                            */
  1738. /*               INPUT:          CCO_PAGEPTR                                         */
  1739. /*               OUTPUT:         TRESULT                                             */
  1740. /*                                                                                   */
  1741. /*       CHECK THAT CHECKSUM IN PAGE IS CORRECT TO ENSURE THAT NO ONE HAS CORRUPTED  */
  1742. /*       THE PAGE INFORMATION. WHEN CALCULATING THE CHECKSUM WE REMOVE THE CHECKSUM  */
  1743. /*       ITSELF FROM THE CHECKSUM BY XOR'ING THE CHECKSUM TWICE. WHEN CALCULATING    */
  1744. /*       THE CHECKSUM THE CHECKSUM WORD IS ZERO WHICH MEANS NO CHANGE FROM XOR'ING.  */
  1745. /* --------------------------------------------------------------------------------- */
  1746. void Dbacc::checksumControl(Signal* signal, Uint32 checkPage) 
  1747. {
  1748.   Uint32 Tchs;
  1749.   Uint32 tccoIndex;
  1750.   Uint32 Ti;
  1751.   Uint32 Tmp1;
  1752.   Uint32 Tmp2;
  1753.   Uint32 Tmp3;
  1754.   Uint32 Tmp4;
  1755.   Uint32 Tlimit;
  1756.   Tchs = 0;
  1757.   for (Ti = 0; Ti < 32 ; Ti++) {
  1758.     Tlimit = 16 + (Ti << 6);
  1759.     for (tccoIndex = (Ti << 6); tccoIndex < Tlimit; tccoIndex ++) {
  1760.       Tmp1 = ccoPageptr.p->word32[tccoIndex];
  1761.       Tmp2 = ccoPageptr.p->word32[tccoIndex + 16];
  1762.       Tmp3 = ccoPageptr.p->word32[tccoIndex + 32];
  1763.       Tmp4 = ccoPageptr.p->word32[tccoIndex + 48];
  1764.       Tchs = Tchs ^ Tmp1;
  1765.       Tchs = Tchs ^ Tmp2;
  1766.       Tchs = Tchs ^ Tmp3;
  1767.       Tchs = Tchs ^ Tmp4;
  1768.     }//for
  1769.   }//for
  1770.   if (Tchs == 0) {
  1771.     tresult = 0;
  1772.     if (checkPage != 0) {
  1773.       jam();
  1774.       lcnCopyPageptr.p = ccoPageptr.p;
  1775.       srCheckPage(signal);
  1776.     }//if
  1777.   } else {
  1778.     tresult = 1;
  1779.   }//if
  1780.   if (tresult != 0) {
  1781.     jam();
  1782.     rootfragrecptr.i = fragrecptr.p->myroot;
  1783.     ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  1784.     signal->theData[0] = RNIL;
  1785.     signal->theData[1] = rootfragrecptr.p->mytabptr;
  1786.     signal->theData[2] = fragrecptr.p->myfid;
  1787.     signal->theData[3] = ccoPageptr.p->word32[ZPOS_PAGE_ID];
  1788.     signal->theData[4] = tlupElemIndex;
  1789.     signal->theData[5] = ccoPageptr.p->word32[ZPOS_PAGE_TYPE];
  1790.     signal->theData[6] = tresult;
  1791.     sendSignal(cownBlockref, GSN_DEBUG_SIG, signal, 7, JBA);
  1792.   }//if
  1793. }//Dbacc::checksumControl()
  1794. /* ******************--------------------------------------------------------------- */
  1795. /* START_RECREQ                                  REQUEST TO START UNDO PROCESS       */
  1796. /*                                                     SENDER: LQH,    LEVEL B       */
  1797. /*          ENTER START_RECREQ WITH                                                  */
  1798. /*                    CLQH_PTR,                      LQH CONNECTION PTR              */
  1799. /*                    CLQH_BLOCK_REF,                LQH BLOCK REFERENCE             */
  1800. /* ******************--------------------------------------------------------------- */
  1801. /* ******************--------------------------------------------------------------- */
  1802. /* START_RECREQ                                       REQUEST TO START UNDO PROCESS  */
  1803. /* ******************------------------------------+                                 */
  1804. /*   SENDER: LQH,    LEVEL B       */
  1805. void Dbacc::execSTART_RECREQ(Signal* signal) 
  1806. {
  1807.   jamEntry();
  1808.   clqhPtr = signal->theData[0];        /* LQH CONNECTION PTR              */
  1809.   clqhBlockRef = signal->theData[1];   /* LQH BLOCK REFERENCE             */
  1810.   tresult = 0; /* 0= FALSE,1= TRUE,> ZLIMIT_OF_ERROR =ERRORCODE */
  1811.   for (int i = 0; i < UndoHeader::ZNO_UNDORECORD_TYPES; i++)
  1812.     cSrUndoRecords[i] = 0;
  1813.   startUndoLab(signal);
  1814.   return;
  1815. }//Dbacc::execSTART_RECREQ()
  1816. void Dbacc::startUndoLab(Signal* signal) 
  1817. {
  1818.   cundoLogActive = ZTRUE;
  1819.   /* ----- OPEN UNDO FILES --------- */
  1820.   for (tmp = 0; tmp <= ZMAX_UNDO_VERSION - 1; tmp++) {
  1821.     jam();
  1822.     if (csrVersList[tmp] != RNIL) {
  1823.       jam();
  1824.       /*---------------------------------------------------------------------------*/
  1825.       /*       SELECT THE NEXT SYSTEM RESTART RECORD WHICH CONTAINS AN UNDO LOG    */
  1826.       /*       THAT NEEDS TO BE EXECUTED AND SET UP THE DATA TO EXECUTE IT.        */
  1827.       /*---------------------------------------------------------------------------*/
  1828.       srVersionPtr.i = csrVersList[tmp];
  1829.       csrVersList[tmp] = RNIL;
  1830.       ptrCheckGuard(srVersionPtr, csrVersionRecSize, srVersionRec);
  1831.       cactiveUndoFilePage = srVersionPtr.p->prevAddress >> 13;
  1832.       cprevUndoaddress = srVersionPtr.p->prevAddress;
  1833.       cactiveCheckpId = srVersionPtr.p->checkPointId;
  1834.       releaseSrRec(signal);
  1835.       startActiveUndo(signal);
  1836.       return;
  1837.     }//if
  1838.   }//for
  1839.   // Send report of how many undo log records where executed
  1840.   signal->theData[0] = EventReport::UNDORecordsExecuted;
  1841.   signal->theData[1] = DBACC; // From block
  1842.   signal->theData[2] = 0; // Total records executed
  1843.   for (int i = 0; i < 10; i++){
  1844.     if (i < UndoHeader::ZNO_UNDORECORD_TYPES){
  1845.       signal->theData[i+3] = cSrUndoRecords[i];
  1846.       signal->theData[2] += cSrUndoRecords[i]; 
  1847.     }else{
  1848.       signal->theData[i+3] = 0;
  1849.     }
  1850.   }
  1851.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 12, JBB);
  1852.   /* ******************************< */
  1853.   /* START_RECCONF                   */
  1854.   /* ******************************< */
  1855.   /*---------------------------------------------------------------------------*/
  1856.   /*       REPORT COMPLETION OF UNDO LOG EXECUTION.                            */
  1857.   /*---------------------------------------------------------------------------*/
  1858.   cundoLogActive = ZFALSE;
  1859.   signal->theData[0] = clqhPtr;
  1860.   sendSignal(clqhBlockRef, GSN_START_RECCONF, signal, 1, JBB);
  1861.   /* LQH CONNECTION PTR   */
  1862.   return;
  1863. }//Dbacc::startUndoLab()
  1864. /*---------------------------------------------------------------------------*/
  1865. /*       START THE UNDO OF AN UNDO LOG FILE BY OPENING THE UNDO LOG FILE.    */
  1866. /*---------------------------------------------------------------------------*/
  1867. void Dbacc::startActiveUndo(Signal* signal) 
  1868. {
  1869.   if (cprevUndoaddress == cminusOne) {
  1870.     jam();
  1871.     /*---------------------------------------------------------------------------*/
  1872.     /*       THERE WAS NO UNDO LOG INFORMATION IN THIS LOG FILE. WE GET THE NEXT */
  1873.     /*       OR REPORT COMPLETION.                                               */
  1874.     /*---------------------------------------------------------------------------*/
  1875.     signal->theData[0] = ZSTART_UNDO;
  1876.     sendSignal(cownBlockref, GSN_CONTINUEB, signal, 1, JBB);
  1877.   } else {
  1878.     jam();
  1879.     /*---------------------------------------------------------------------------*/
  1880.     /*       OPEN THE LOG FILE PERTAINING TO THIS UNDO LOG.                      */
  1881.     /*---------------------------------------------------------------------------*/
  1882.     if (cfsFirstfreeconnect == RNIL) {
  1883.       jam();
  1884.       sendSystemerror(signal);
  1885.     }//if
  1886.     seizeFsConnectRec(signal);
  1887.     cactiveSrFsPtr = fsConnectptr.i;
  1888.     fsConnectptr.p->fsState = OPEN_UNDO_FILE_SR;
  1889.     fsConnectptr.p->fsPart = 0;
  1890.     tmp1 = 1;                                    /* FILE VERSION ? */
  1891.     tmp1 = (tmp1 << 8) + ZLOCALLOGFILE;            /* .LOCLOG = 2 */
  1892.     tmp1 = (tmp1 << 8) + 4;                    /* ROOT DIRECTORY = D4 */
  1893.     tmp1 = (tmp1 << 8) + fsConnectptr.p->fsPart;   /*        P2  */
  1894.     tmp2 = 0x0;                                    /* D7 DON'T CREATE , READ ONLY */
  1895.                                                    /* DON'T TRUNCATE TO ZERO */
  1896.     /* ---FILE NAME "D4"/"DBACC"/LCP_CONNECTPTR:LOCAL_CHECK_PID/FS_CONNECTPTR:FS_PART".LOCLOG-- */
  1897.     /* ************************ */
  1898.     /* FSOPENREQ                */
  1899.     /* ************************ */
  1900.     signal->theData[0] = cownBlockref;
  1901.     signal->theData[1] = fsConnectptr.i;
  1902.     signal->theData[2] = cminusOne;         /* #FFFFFFFF */
  1903.     signal->theData[3] = cminusOne;         /* #FFFFFFFF */
  1904.     signal->theData[4] = cactiveCheckpId;   /* CHECKPOINT VERSION */
  1905.     signal->theData[5] = tmp1;
  1906.     signal->theData[6] = tmp2;
  1907.     sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  1908.   }//if
  1909. }//Dbacc::startActiveUndo()
  1910. /* ------- READ A GROUP OF UNDO PAGES --------------- */
  1911. void Dbacc::srStartUndoLab(Signal* signal) 
  1912. {
  1913.   /*---------------------------------------------------------------------------*/
  1914.   /*       ALL LOG FILES HAVE BEEN OPENED. WE CAN NOW READ DATA FROM THE LAST  */
  1915.   /*       PAGE IN THE LAST LOG FILE AND BACKWARDS UNTIL WE REACH THE VERY     */
  1916.   /*       FIRST UNDO LOG RECORD.                                              */
  1917.   /*---------------------------------------------------------------------------*/
  1918.   if (cactiveUndoFilePage >= ZWRITE_UNDOPAGESIZE) {
  1919.     jam();
  1920.     tmp1 = ZWRITE_UNDOPAGESIZE; /* NO OF READ UNDO PAGES */
  1921.     cactiveSrUndoPage = ZWRITE_UNDOPAGESIZE - 1; /* LAST PAGE */
  1922.   } else {
  1923.     jam();
  1924.     tmp1 = cactiveUndoFilePage + 1; /* NO OF READ UNDO PAGES */
  1925.     cactiveSrUndoPage = cactiveUndoFilePage;
  1926.   }//if
  1927.   fsConnectptr.i = cactiveSrFsPtr;
  1928.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  1929.   signal->theData[0] = fsConnectptr.p->fsPtr;
  1930.   signal->theData[1] = cownBlockref;
  1931.   signal->theData[2] = fsConnectptr.i;
  1932.   signal->theData[3] = 0;
  1933.   /* FLAG = LIST MEM PAGES, LIST FILE PAGES */
  1934.   signal->theData[4] = ZUNDOPAGE_BASE_ADD;
  1935.   signal->theData[5] = tmp1;
  1936.   signal->theData[6] = 0;
  1937.   signal->theData[7] = (cactiveUndoFilePage - tmp1) + 1;
  1938.   signal->theData[8] = 1;
  1939.   signal->theData[9] = cactiveUndoFilePage;
  1940.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 10, JBA);
  1941.   if (tmp1 > cactiveUndoFilePage) {
  1942.     jam();
  1943.     /*---------------------------------------------------------------------------*/
  1944.     /*       THIS IS THE LAST READ IN THIS LOG FILE. WE SET THE ACTIVE FILE      */
  1945.     /*       POINTER. IF IT IS THE FIRST WE SHOULD NEVER ATTEMPT ANY MORE READS  */
  1946.     /*       SINCE WE SHOULD ENCOUNTER A FIRST LOG RECORD WITH PREVIOUS PAGE ID  */
  1947.     /*       EQUAL TO RNIL.                                                      */
  1948.     /*---------------------------------------------------------------------------*/
  1949.     cactiveSrFsPtr = RNIL;
  1950.     fsConnectptr.p->fsState = READ_UNDO_PAGE_AND_CLOSE;
  1951.   } else {
  1952.     jam();
  1953.     /*---------------------------------------------------------------------------*/
  1954.     /*       WE STILL HAVE MORE INFORMATION IN THIS LOG FILE. WE ONLY MOVE BACK  */
  1955.     /*       THE FILE PAGE.                                                      */
  1956.     /*---------------------------------------------------------------------------*/
  1957.     cactiveUndoFilePage = cactiveUndoFilePage - tmp1;
  1958.     fsConnectptr.p->fsState = READ_UNDO_PAGE;
  1959.   }//if
  1960.   return;
  1961. }//Dbacc::srStartUndoLab()
  1962. /* ------- DO UNDO ---------------------------*/
  1963. /* ******************--------------------------------------------------------------- */
  1964. /* NEXTOPERATION                                       ORD FOR EXECUTION OF NEXT OP  */
  1965. /* ******************------------------------------+                                 */
  1966. /*   SENDER: ACC,    LEVEL B       */
  1967. void Dbacc::execNEXTOPERATION(Signal* signal) 
  1968. {
  1969.   jamEntry();
  1970.   tresult = 0;
  1971.   srDoUndoLab(signal);
  1972.   return;
  1973. }//Dbacc::execNEXTOPERATION()
  1974. void Dbacc::srDoUndoLab(Signal* signal) 
  1975. {
  1976.   DirRangePtr souDirRangePtr;
  1977.   DirectoryarrayPtr souDirptr;
  1978.   Page8Ptr souPageidptr;
  1979.   Uint32 tundoPageindex;
  1980.   UndoHeader *undoHeaderPtr;
  1981.   Uint32 tmpindex;
  1982.   jam();
  1983.   undopageptr.i = cactiveSrUndoPage;
  1984.   ptrCheckGuard(undopageptr, cundopagesize, undopage);
  1985.   /*---------------------------------------------------------------------------*/
  1986.   /*       LAYOUT OF AN UNDO LOG RECORD:                                       */
  1987.   /*       *****************************                                       */
  1988.   /*                                                                           */
  1989.   /*       |----------------------------------------------------|              */
  1990.   /*       |  TABLE ID                                          |              */
  1991.   /*       |----------------------------------------------------|              */
  1992.   /*       |  ROOT FRAGMENT  ID                                 |              */
  1993.   /*       |----------------------------------------------------|              */
  1994.   /*       |  LOCAL FRAGMENT  ID                                |              */
  1995.   /*       |----------------------------------------------------|              */
  1996.   /*       |  UNDO INFO LEN 14 b | TYPE 4 b | PAGE INDEX 14 b   |              */
  1997.   /*       |----------------------------------------------------|              */
  1998.   /*       |  INDEX INTO PAGE DIRECTORY (LOGICAL PAGE ID)       |              */
  1999.   /*       |----------------------------------------------------|              */
  2000.   /*       |  PREVIOUS UNDO LOG RECORD FOR THE FRAGMENT         |              */
  2001.   /*       |----------------------------------------------------|              */
  2002.   /*       |  PREVIOUS UNDO LOG RECORD FOR ALL FRAGMENTS        |              */
  2003.   /*       |----------------------------------------------------|              */
  2004.   /*       |  TYPE SPECIFIC PART                                |              */
  2005.   /*       |----------------------------------------------------|              */
  2006.   /*---------------------------------------------------------------------------*/
  2007.   /*---------------------------------------------------------------------------*/
  2008.   /*       SET THE PAGE POINTER. WE ONLY WORK WITH TWO PAGES IN THIS RESTART   */
  2009.   /*       ACTIVITY. GET THE PAGE POINTER AND THE PAGE INDEX TO READ FROM.     */
  2010.   /*---------------------------------------------------------------------------*/
  2011.   tundoindex = cprevUndoaddress & ZUNDOPAGEINDEX_MASK; //0x1fff, 13 bits.
  2012.   undoHeaderPtr = (UndoHeader *) &undopageptr.p->undoword[tundoindex];
  2013.   tundoindex = tundoindex + ZUNDOHEADSIZE;
  2014.   
  2015.   /*------------------------------------------------------------------------*/
  2016.   /*    READ TABLE ID AND ROOT FRAGMENT ID AND USE THIS TO GET ROOT RECORD. */
  2017.   /*------------------------------------------------------------------------*/
  2018.   arrGuard((tundoindex + 6), 8192);
  2019.   // TABLE ID
  2020.   tabptr.i = undoHeaderPtr->tableId;
  2021.   ptrCheckGuard(tabptr, ctablesize, tabrec);
  2022.   // ROOT FRAGMENT ID
  2023.   tfid = undoHeaderPtr->rootFragId;
  2024.   if (!getrootfragmentrec(signal, rootfragrecptr, tfid)) {
  2025.     jam();
  2026.     /*---------------------------------------------------------------------*/
  2027.     /* THE ROOT RECORD WAS NOT FOUND. OBVIOUSLY WE ARE NOT RESTARTING THIS */
  2028.     /* FRAGMENT. WE THUS IGNORE THIS LOG RECORD AND PROCEED WITH THE NEXT. */
  2029.     /*---------------------------------------------------------------------*/
  2030.     creadyUndoaddress = cprevUndoaddress;
  2031.     // PREVIOUS UNDO LOG RECORD FOR ALL FRAGMENTS
  2032.     cprevUndoaddress = undoHeaderPtr->prevUndoAddress;
  2033.     undoNext2Lab(signal);    
  2034.     return;
  2035.   }//if
  2036.   /*-----------------------------------------------------------------------*/
  2037.   /*   READ THE LOCAL FRAGMENT ID AND VERIFY THAT IT IS CORRECT.           */
  2038.   /*-----------------------------------------------------------------------*/
  2039.   if (rootfragrecptr.p->fragmentid[0] == undoHeaderPtr->localFragId) {
  2040.     jam();
  2041.     fragrecptr.i = rootfragrecptr.p->fragmentptr[0];
  2042.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2043.   } else {
  2044.     if (rootfragrecptr.p->fragmentid[1] == undoHeaderPtr->localFragId) {
  2045.       jam();
  2046.       fragrecptr.i = rootfragrecptr.p->fragmentptr[1];
  2047.       ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2048.     } else {
  2049.       jam();
  2050.       progError(__LINE__, 0, "Invalid local fragment id in undo log");
  2051.       return;
  2052.     }//if
  2053.   }//if
  2054.   /*------------------------------------------------------------------------*/
  2055.   /*    READ UNDO INFO LENGTH, TYPE OF LOG RECORD AND PAGE INDEX WHERE TO   */
  2056.   /*    APPLY THIS LOG RECORD. ALSO STEP INDEX TO PREPARE READ OF LOGICAL   */
  2057.   /*    PAGE ID. SET TMPINDEX TO INDEX THE FIRST WORD IN THE TYPE SPECIFIC  */
  2058.   /*    PART.                                                               */
  2059.   /*------------------------------------------------------------------------*/
  2060.   // UNDO INFO LENGTH 14 b | TYPE 4 b | PAGE INDEX 14 b
  2061.   const Uint32 tmp1 = undoHeaderPtr->variousInfo;
  2062.   cundoinfolength = tmp1 >> 18;
  2063.   const Uint32 tpageType = (tmp1 >> 14) & 0xf;
  2064.   tundoPageindex = tmp1 & 0x3fff;
  2065.   
  2066.   // INDEX INTO PAGE DIRECTORY (LOGICAL PAGE ID)
  2067.   tmpP = undoHeaderPtr->logicalPageId ;
  2068.   tmpindex = tundoindex;
  2069.   arrGuard((tmpindex + cundoinfolength - 1), 8192);
  2070.   if (fragrecptr.p->localCheckpId != cactiveCheckpId) {
  2071.     jam();
  2072.     /*-----------------------------------------------------------------------*/
  2073.     /*  THE FRAGMENT DID EXIST BUT IS NOT AFFECTED BY THIS UNDO LOG          */
  2074.     /*  EXECUTION. EITHER IT BELONGS TO ANOTHER OR IT IS CREATED AND ONLY IN */
  2075.     /*  NEED OF EXECUTION OF REDO LOG RECORDS FROM LQH.                      */
  2076.     /*-----------------------------------------------------------------------*/
  2077.     creadyUndoaddress = cprevUndoaddress;
  2078.     // PREVIOUS UNDO LOG RECORD FOR ALL FRAGMENTS
  2079.     cprevUndoaddress = undoHeaderPtr->prevUndoAddress;
  2080.     undoNext2Lab(signal);
  2081.     return;
  2082.   }//if
  2083.   /*-----------------------------------------------------------------------*/
  2084.   /*   VERIFY CONSISTENCY OF UNDO LOG RECORDS.                             */
  2085.   /*-----------------------------------------------------------------------*/
  2086.   ndbrequire(fragrecptr.p->prevUndoposition == cprevUndoaddress);
  2087.   cSrUndoRecords[tpageType]++;
  2088.   switch(tpageType){
  2089.   case UndoHeader::ZPAGE_INFO:{
  2090.     jam();
  2091.     /*----------------------------------------------------------------------*/
  2092.     /*  WE HAVE TO UNDO UPDATES IN A NORMAL PAGE. GET THE PAGE POINTER BY   */
  2093.     /*  USING THE LOGICAL PAGE ID. THEN RESET THE OLD VALUE IN THE PAGE BY  */
  2094.     /*  USING THE OLD DATA WHICH IS STORED IN THIS UNDO LOG RECORD.         */
  2095.     /*----------------------------------------------------------------------*/
  2096.     souDirRangePtr.i = fragrecptr.p->directory;
  2097.     tmpP2 = tmpP >> 8;
  2098.     tmpP = tmpP & 0xff;
  2099.     ptrCheckGuard(souDirRangePtr, cdirrangesize, dirRange);
  2100.     arrGuard(tmpP2, 256);
  2101.     souDirptr.i = souDirRangePtr.p->dirArray[tmpP2];
  2102.     ptrCheckGuard(souDirptr, cdirarraysize, directoryarray);
  2103.     souPageidptr.i = souDirptr.p->pagep[tmpP];
  2104.     ptrCheckGuard(souPageidptr, cpagesize, page8);
  2105.     Uint32 loopLimit = tundoPageindex + cundoinfolength;
  2106.     ndbrequire(loopLimit <= 2048);
  2107.     for (Uint32 tmp = tundoPageindex; tmp < loopLimit; tmp++) {
  2108.       dbgWord32(souPageidptr, tmp, undopageptr.p->undoword[tmpindex]);
  2109.       souPageidptr.p->word32[tmp] = undopageptr.p->undoword[tmpindex];
  2110.       tmpindex = tmpindex + 1;
  2111.     }//for
  2112.     break;
  2113.   }
  2114.     
  2115.   case UndoHeader::ZOVER_PAGE_INFO:{
  2116.     jam();
  2117.     /*----------------------------------------------------------------------*/
  2118.     /*  WE HAVE TO UNDO UPDATES IN AN OVERFLOW PAGE. GET THE PAGE POINTER BY*/
  2119.     /*  USING THE LOGICAL PAGE ID. THEN RESET THE OLD VALUE IN THE PAGE BY  */
  2120.     /*  USING THE OLD DATA WHICH IS STORED IN THIS UNDO LOG RECORD.         */
  2121.     /*----------------------------------------------------------------------*/
  2122.     souDirRangePtr.i = fragrecptr.p->overflowdir;
  2123.     tmpP2 = tmpP >> 8;
  2124.     tmpP = tmpP & 0xff;
  2125.     ptrCheckGuard(souDirRangePtr, cdirrangesize, dirRange);
  2126.     arrGuard(tmpP2, 256);
  2127.     souDirptr.i = souDirRangePtr.p->dirArray[tmpP2];
  2128.     ptrCheckGuard(souDirptr, cdirarraysize, directoryarray);
  2129.     souPageidptr.i = souDirptr.p->pagep[tmpP];
  2130.     ptrCheckGuard(souPageidptr, cpagesize, page8);
  2131.     Uint32 loopLimit = tundoPageindex + cundoinfolength;
  2132.     ndbrequire(loopLimit <= 2048);
  2133.     for (Uint32 tmp = tundoPageindex; tmp < loopLimit; tmp++) {
  2134.       dbgWord32(souPageidptr, tmp, undopageptr.p->undoword[tmpindex]);
  2135.       souPageidptr.p->word32[tmp] = undopageptr.p->undoword[tmpindex];
  2136.       tmpindex = tmpindex + 1;
  2137.     }//for
  2138.     break;
  2139.   }
  2140.   case UndoHeader::ZUNDO_INSERT_LONG_KEY:{
  2141.     jam();
  2142.     /*---------------------------------------------------------------------*/
  2143.     /* WE WILL UNDO AN INSERT OF A LONG KEY. THIS IS PERFORMED BY DELETING */
  2144.     /* THE LONG KEY.                                                       */
  2145.     /*---------------------------------------------------------------------*/
  2146.     souDirRangePtr.i = fragrecptr.p->overflowdir;
  2147.     tmpP2 = tmpP >> 8;
  2148.     tmpP = tmpP & 0xff;
  2149.     arrGuard(tmpP2, 256);
  2150.     ptrCheckGuard(souDirRangePtr, cdirrangesize, dirRange);
  2151.     souDirptr.i = souDirRangePtr.p->dirArray[tmpP2];
  2152.     ptrCheckGuard(souDirptr, cdirarraysize, directoryarray);
  2153.     dlkPageptr.i = souDirptr.p->pagep[tmpP];
  2154.     ptrCheckGuard(dlkPageptr, cpagesize, page8);
  2155.     tdlkLogicalPageIndex = tundoPageindex;
  2156.     deleteLongKey(signal);
  2157.     break;
  2158.   }
  2159.   case UndoHeader::ZUNDO_DELETE_LONG_KEY: {
  2160.     jam();
  2161.     /*----------------------------------------------------------------------*/
  2162.     /*  WE WILL UNDO DELETE OF A LONG KEY. THIS IS PERFORMED BY INSERTING   */
  2163.     /*  IT AGAIN.                                                           */
  2164.     /*----------------------------------------------------------------------*/
  2165.     souDirRangePtr.i = fragrecptr.p->overflowdir;
  2166.     taslpDirIndex = tmpP;
  2167.     tmpP2 = tmpP >> 8;
  2168.     tmpP = tmpP & 0xff;
  2169.     ptrCheckGuard(souDirRangePtr, cdirrangesize, dirRange);
  2170.     arrGuard(tmpP2, 256);
  2171.     souDirptr.i = souDirRangePtr.p->dirArray[tmpP2];
  2172.     if(souDirptr.i == RNIL) {
  2173.       //----------------------------------------------------------------
  2174.       // Allocate a directory.
  2175.       //----------------------------------------------------------------
  2176.       jam();
  2177.       seizeDirectory(signal);
  2178.       if (tresult > ZLIMIT_OF_ERROR) {
  2179. jam();
  2180. sendSystemerror(signal);
  2181. return;
  2182.       }
  2183.       souDirRangePtr.p->dirArray[tmpP2] = sdDirptr.i;
  2184.       souDirptr.i = souDirRangePtr.p->dirArray[tmpP2];
  2185.     }
  2186.     ptrCheckGuard(souDirptr, cdirarraysize, directoryarray);
  2187.     slkapPageptr.i = souDirptr.p->pagep[tmpP];
  2188.     
  2189.     if(slkapPageptr.i == RNIL) {
  2190.       //----------------------------------------------------------------
  2191.       // The delete operation was probably the last on the page and the 
  2192.       // page was released and not written down to disk. We need to 
  2193.       // allocate a page and put it in the same dirindex as it was in
  2194.       // before it was released.
  2195.       // This is because an eventual UNDO_INSERT on the same key in the
  2196.       // same LCP must be able to find the key and it has only the 
  2197.       // dirindex to go on, the key itself is not saved on disk in a
  2198.       // UNDO_INSERT.
  2199.       //----------------------------------------------------------------
  2200.       jam();
  2201.       allocSpecificLongOverflowPage(signal);
  2202.       slkapPageptr.i = aslpPageptr.i;
  2203.     }
  2204.     
  2205.     ptrCheckGuard(slkapPageptr, cpagesize, page8);
  2206.     seizePage(signal);
  2207.     ndbrequire(tresult <= ZLIMIT_OF_ERROR);
  2208.     
  2209.     slkapCopyPageptr = spPageptr;
  2210.     ndbrequire(cundoinfolength <= 2048);
  2211.     
  2212.     for (Uint32 tmp = 0; tmp < cundoinfolength; tmp++) {
  2213.       dbgWord32(slkapCopyPageptr, tmp, undopageptr.p->undoword[tmpindex]);
  2214.       slkapCopyPageptr.p->word32[tmp] = undopageptr.p->undoword[tmpindex];
  2215.       tmpindex = tmpindex + 1;
  2216.     }//for
  2217.     jam();
  2218.     //----------------------------------------------------------------
  2219.     // We must store the key at the same place it was deleted from.
  2220.     // This is because an eventual UNDO_INSERT on the same key in the
  2221.     // same LCP must be able to find the key and it has only the index
  2222.     // information stored on disk to go on, the key itself is not 
  2223.     // saved on disk in an UNDO_INSERT.
  2224.     //----------------------------------------------------------------
  2225.     tslkapKeyLen = cundoinfolength;
  2226.     tslkapPageIndex = tundoPageindex;
  2227.     storeLongKeysAtPos(signal);
  2228.     
  2229.     rpPageptr = slkapCopyPageptr;
  2230.     releasePage(signal);
  2231.     break;
  2232.   }
  2233.   case UndoHeader::ZOP_INFO: {
  2234.     jam();
  2235.     /*---------------------------------------------------------------------*/
  2236.     /* AN OPERATION WAS ACTIVE WHEN LOCAL CHECKPOINT WAS EXECUTED. WE NEED */
  2237.     /* TO RESET THE LOCKS IT HAS SET. IF THE OPERATION WAS AN INSERT OR    */
  2238.     /* THE ELEMENT WAS MARKED AS DISSAPEARED IT WILL ALSO BE REMOVED       */
  2239.     /* FROM THE PAGE                                                       */
  2240.     /*                                                                     */
  2241.     /* BEGIN BY SEARCHING AFTER THE ELEMENT, WHEN FOUND UNDO THE           */
  2242.     /* CHANGES ON THE ELEMENT HEADER. IF IT WAS AN INSERT OPERATION OR     */
  2243.     /* MARKED AS DISSAPEARED  PROCEED BY REMOVING THE ELEMENT.             */
  2244.     /*---------------------------------------------------------------------*/
  2245.     seizeOpRec(signal);
  2246.     // Initialise the opRec
  2247.     operationRecPtr.p->transId1 = 0;
  2248.     operationRecPtr.p->transId2 = RNIL;
  2249.     operationRecPtr.p->transactionstate = ACTIVE;
  2250.     operationRecPtr.p->commitDeleteCheckFlag = ZFALSE;
  2251.     operationRecPtr.p->lockMode = 0;
  2252.     operationRecPtr.p->dirtyRead = 0;
  2253.     operationRecPtr.p->nodeType = 0;
  2254.     operationRecPtr.p->fid = fragrecptr.p->myfid;
  2255.     operationRecPtr.p->nextParallelQue = RNIL;
  2256.     operationRecPtr.p->prevParallelQue = RNIL;
  2257.     operationRecPtr.p->nextQueOp = RNIL;
  2258.     operationRecPtr.p->prevQueOp = RNIL;
  2259.     operationRecPtr.p->nextSerialQue = RNIL;
  2260.     operationRecPtr.p->prevSerialQue = RNIL;
  2261.     operationRecPtr.p->elementPage = RNIL;
  2262.     operationRecPtr.p->keyinfoPage = RNIL;
  2263.     operationRecPtr.p->insertIsDone = ZFALSE;
  2264.     operationRecPtr.p->lockOwner = ZFALSE;
  2265.     operationRecPtr.p->elementIsDisappeared = ZFALSE;
  2266.     operationRecPtr.p->insertDeleteLen = fragrecptr.p->elementLength;
  2267.     operationRecPtr.p->longPagePtr = RNIL;
  2268.     operationRecPtr.p->longKeyPageIndex = RNIL;
  2269.     operationRecPtr.p->scanRecPtr = RNIL;
  2270.     operationRecPtr.p->isAccLockReq = ZFALSE;
  2271.     // Read operation values from undo page
  2272.     operationRecPtr.p->operation = undopageptr.p->undoword[tmpindex];
  2273.     tmpindex++;
  2274.     operationRecPtr.p->hashValue = undopageptr.p->undoword[tmpindex];
  2275.     tmpindex++;
  2276.     const Uint32 tkeylen = undopageptr.p->undoword[tmpindex];
  2277.     tmpindex++;
  2278.     operationRecPtr.p->tupkeylen = tkeylen;
  2279.     operationRecPtr.p->fragptr = fragrecptr.i;
  2280.     ndbrequire((fragrecptr.p->keyLength == 0) ||
  2281.        ((fragrecptr.p->keyLength != 0) &&
  2282. (fragrecptr.p->keyLength == tkeylen)));
  2283.     
  2284.     // Read keydata from undo page
  2285.     for (Uint32 tmp = 0; tmp < tkeylen; tmp++) {
  2286.       signal->theData[7+tmp] = undopageptr.p->undoword[tmpindex];
  2287.       tmpindex = tmpindex + 1;
  2288.     }//for
  2289.     arrGuard((tmpindex - 1), 8192);
  2290.     getElement(signal);
  2291.     if (tgeResult != ZTRUE) {
  2292.       jam();
  2293.       signal->theData[0] = RNIL;
  2294.       signal->theData[1] = tabptr.i;
  2295.       signal->theData[2] = cactiveCheckpId;
  2296.       signal->theData[3] = cprevUndoaddress;
  2297.       signal->theData[4] = operationRecPtr.p->operation;
  2298.       signal->theData[5] = operationRecPtr.p->hashValue;
  2299.       signal->theData[6] = operationRecPtr.p->tupkeylen;
  2300.       sendSignal(cownBlockref, GSN_DEBUG_SIG, signal, 11, JBA);
  2301.       return;
  2302.     }//if
  2303.     
  2304.     operationRecPtr.p->elementPage = gePageptr.i;
  2305.     operationRecPtr.p->elementContainer = tgeContainerptr;
  2306.     operationRecPtr.p->elementPointer = tgeElementptr;
  2307.     operationRecPtr.p->elementIsforward = tgeForward;
  2308.     
  2309.     commitdelete(signal, true);
  2310.     releaseOpRec(signal);
  2311.     break;
  2312.   }
  2313.   default:
  2314.     jam();
  2315.     progError(__LINE__, 0, "Invalid pagetype in undo log");
  2316.     break;
  2317.   }//switch(tpageType)
  2318.   /*----------------------------------------------------------------------*/
  2319.   /*  READ THE PAGE ID AND THE PAGE INDEX OF THE PREVIOUS UNDO LOG RECORD */
  2320.   /*  FOR THIS FRAGMENT.                                                  */
  2321.   /*----------------------------------------------------------------------*/
  2322.   fragrecptr.p->prevUndoposition = undoHeaderPtr->prevUndoAddressForThisFrag;
  2323.   /*----------------------------------------------------------------------*/
  2324.   /*  READ THE PAGE ID AND THE PAGE INDEX OF THE PREVIOUS UNDO LOG RECORD */
  2325.   /*  FOR THIS UNDO LOG.                                                  */
  2326.   /*----------------------------------------------------------------------*/
  2327.   creadyUndoaddress = cprevUndoaddress;
  2328.   cprevUndoaddress = undoHeaderPtr->prevUndoAddress;
  2329.   if (fragrecptr.p->prevUndoposition == cminusOne) {
  2330.     jam();
  2331.     /*---------------------------------------------------------------------*/
  2332.     /* WE HAVE NOW EXECUTED ALL UNDO LOG RECORDS FOR THIS FRAGMENT. WE     */
  2333.     /* NOW NEED TO UPDATE THE FREE LIST OF OVERFLOW PAGES.                 */
  2334.     /*---------------------------------------------------------------------*/
  2335.     ndbrequire(fragrecptr.p->nextAllocPage == 0);
  2336.     signal->theData[0] = fragrecptr.i;
  2337.     sendSignal(cownBlockref, GSN_ACC_OVER_REC, signal, 1, JBB);
  2338.     return;
  2339.   }//if
  2340.   undoNext2Lab(signal);
  2341.   return;
  2342. }//Dbacc::srDoUndoLab()
  2343. void Dbacc::undoNext2Lab(Signal* signal) 
  2344. {
  2345.   /*---------------------------------------------------------------------------*/
  2346.   /*       EXECUTE NEXT UNDO LOG RECORD.                                       */
  2347.   /*---------------------------------------------------------------------------*/
  2348.   if (cprevUndoaddress == cminusOne) {
  2349.     jam();
  2350.     /*---------------------------------------------------------------------------*/
  2351.     /*       WE HAVE EXECUTED THIS UNDO LOG TO COMPLETION. IT IS NOW TIME TO TAKE*/
  2352.     /*       OF THE NEXT UNDO LOG OR REPORT COMPLETION OF UNDO LOG EXECUTION.    */
  2353.     /*---------------------------------------------------------------------------*/
  2354.     signal->theData[0] = ZSTART_UNDO;
  2355.     sendSignal(cownBlockref, GSN_CONTINUEB, signal, 1, JBB);
  2356.     return;
  2357.   }//if
  2358.   if ((creadyUndoaddress >> 13) != (cprevUndoaddress >> 13)) {
  2359.     /*---------------------------------------------------------------------------*/
  2360.     /*       WE ARE CHANGING PAGE.                                               */
  2361.     /*---------------------------------------------------------------------------*/
  2362.     if (cactiveSrUndoPage == 0) {
  2363.       jam();
  2364.       /*---------------------------------------------------------------------------*/
  2365.       /*       WE HAVE READ AND EXECUTED ALL UNDO LOG INFORMATION IN THE CURRENTLY */
  2366.       /*       READ PAGES. WE STILL HAVE MORE INFORMATION TO READ FROM FILE SINCE  */
  2367.       /*       WE HAVEN'T FOUND THE FIRST LOG RECORD IN THE LOG FILE YET.          */
  2368.       /*---------------------------------------------------------------------------*/
  2369.       srStartUndoLab(signal);
  2370.       return;
  2371.     } else {
  2372.       jam();
  2373.       /*---------------------------------------------------------------------------*/
  2374.       /*       WE HAVE ANOTHER PAGE READ THAT WE NEED TO EXECUTE.                  */
  2375.       /*---------------------------------------------------------------------------*/
  2376.       cactiveSrUndoPage = cactiveSrUndoPage - 1;
  2377.     }//if
  2378.   }//if
  2379.   /*---------------------------------------------------------------------------*/
  2380.   /*       REAL-TIME BREAK                                                     */
  2381.   /*---------------------------------------------------------------------------*/
  2382.   /* ******************************< */
  2383.   /* NEXTOPERATION                   */
  2384.   /* ******************************< */
  2385.   sendSignal(cownBlockref, GSN_NEXTOPERATION, signal, 1, JBB);
  2386.   return;
  2387. }//Dbacc::undoNext2Lab()
  2388. /*-----------------------------------------------------------------------------------*/
  2389. /*       AFTER COMPLETING THE READING OF DATA PAGES FROM DISK AND EXECUTING THE UNDO */
  2390. /*       LOG WE ARE READY TO UPDATE THE FREE LIST OF OVERFLOW PAGES. THIS LIST MUST  */
  2391. /*       BE BUILT AGAIN SINCE IT IS NOT CHECKPOINTED. WHEN THE PAGES ARE ALLOCATED   */
  2392. /*       THEY ARE NOT PART OF ANY LIST. PAGES CAN EITHER BE PUT IN FREE LIST, NOT    */
  2393. /*       IN FREE LIST OR BE PUT INTO LIST OF LONG KEY PAGES.                         */
  2394. /*-----------------------------------------------------------------------------------*/
  2395. void Dbacc::execACC_OVER_REC(Signal* signal) 
  2396. {
  2397.   DirRangePtr pnoDirRangePtr;
  2398.   DirectoryarrayPtr pnoOverflowDirptr;
  2399.   Page8Ptr pnoPageidptr;
  2400.   Uint32 tpnoPageType;
  2401.   Uint32 toverPageCheck;
  2402.   jamEntry();
  2403.   fragrecptr.i = signal->theData[0];
  2404.   toverPageCheck = 0;
  2405.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2406.   ndbrequire((fragrecptr.p->nextAllocPage != 0) ||
  2407.              (fragrecptr.p->firstOverflowRec == RNIL));
  2408.   /*-----------------------------------------------------------------------------------*/
  2409.   /*       WHO HAS PUT SOMETHING INTO THE LIST BEFORE WE EVEN STARTED PUTTING THINGS   */
  2410.   /*       THERE.                                                                      */
  2411.   /*-----------------------------------------------------------------------------------*/
  2412.   ndbrequire(fragrecptr.p->loadingFlag == ZTRUE);
  2413.   /*---------------------------------------------------------------------------*/
  2414.   /*       LOADING HAS STOPPED BEFORE WE HAVE LOADED, SYSTEM ERROR.            */
  2415.   /*---------------------------------------------------------------------------*/
  2416.   while (toverPageCheck < ZNO_OF_OP_PER_SIGNAL) {
  2417.     jam();
  2418.     if (fragrecptr.p->nextAllocPage >= fragrecptr.p->lastOverIndex) {
  2419.       jam();
  2420.       fragrecptr.p->loadingFlag = ZFALSE;
  2421.       rootfragrecptr.i = fragrecptr.p->myroot;
  2422.       ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  2423.       if (rootfragrecptr.p->lcpPtr != RNIL) {
  2424.         jam();
  2425.         srCloseDataFileLab(signal);
  2426.       } else {
  2427.         jam();
  2428.         undoNext2Lab(signal);
  2429.       }//if
  2430.       return;
  2431.     }//if
  2432.     tmpP = fragrecptr.p->nextAllocPage;
  2433.     pnoDirRangePtr.i = fragrecptr.p->overflowdir;
  2434.     tmpP2 = tmpP >> 8;
  2435.     tmpP = tmpP & 0xff;
  2436.     arrGuard(tmpP2, 256);
  2437.     ptrCheckGuard(pnoDirRangePtr, cdirrangesize, dirRange);
  2438.     if (pnoDirRangePtr.p->dirArray[tmpP2] == RNIL) {
  2439.       jam();
  2440.       pnoPageidptr.i = RNIL;
  2441.     } else {
  2442.       pnoOverflowDirptr.i = pnoDirRangePtr.p->dirArray[tmpP2];
  2443.       if (pnoOverflowDirptr.i == RNIL) {
  2444.         jam();
  2445.         pnoPageidptr.i = RNIL;
  2446.       } else {
  2447.         jam();
  2448.         ptrCheckGuard(pnoOverflowDirptr, cdirarraysize, directoryarray);
  2449.         pnoPageidptr.i = pnoOverflowDirptr.p->pagep[tmpP];
  2450.       }//if
  2451.     }//if
  2452.     if (pnoPageidptr.i == RNIL) {
  2453.       jam();
  2454.       seizeOverRec(signal);
  2455.       sorOverflowRecPtr.p->dirindex = fragrecptr.p->nextAllocPage;
  2456.       sorOverflowRecPtr.p->overpage = RNIL;
  2457.       priOverflowRecPtr = sorOverflowRecPtr;
  2458.       putRecInFreeOverdir(signal);
  2459.     } else {
  2460.       ptrCheckGuard(pnoPageidptr, cpagesize, page8);
  2461.       tpnoPageType = pnoPageidptr.p->word32[ZPOS_PAGE_TYPE];
  2462.       tpnoPageType = (tpnoPageType >> ZPOS_PAGE_TYPE_BIT) & 3;
  2463.       if (tpnoPageType == ZLONG_PAGE_TYPE) {
  2464.         jam();
  2465. // This is to clean the list parameters. 
  2466. pnoPageidptr.p->word32[ZPOS_PREV_PAGE] = RNIL;
  2467. pnoPageidptr.p->word32[ZPOS_NEXT_PAGE] = RNIL;
  2468.         if (pnoPageidptr.p->word32[ZPOS_ARRAY_POS] != 4) {
  2469.           jam();
  2470.   /*---------------------------------------------------------------------------*/
  2471.   /*  THE PAGE WAS A LONG PAGE AND IT BELONGED TO A FREE LIST. PUT IT INTO ONE */
  2472.   /*  OF THE FREE LIST THEN.                                                   */
  2473.   /*---------------------------------------------------------------------------*/
  2474.   // Insert page!
  2475.   ipaPagePtr = pnoPageidptr;
  2476.           tipaArrayPos = pnoPageidptr.p->word32[ZPOS_ARRAY_POS];
  2477.           insertPageArrayList(signal);
  2478.         }//if
  2479.       } else {
  2480.         if (pnoPageidptr.p->word32[ZPOS_ALLOC_CONTAINERS] > ZFREE_LIMIT) {
  2481.           jam();
  2482.           dbgWord32(pnoPageidptr, ZPOS_OVERFLOWREC, RNIL);
  2483.           pnoPageidptr.p->word32[ZPOS_OVERFLOWREC] = RNIL;
  2484.           ndbrequire(pnoPageidptr.p->word32[ZPOS_PAGE_ID] == fragrecptr.p->nextAllocPage);
  2485.         } else {
  2486.           jam();
  2487.           seizeOverRec(signal);
  2488.           sorOverflowRecPtr.p->dirindex = pnoPageidptr.p->word32[ZPOS_PAGE_ID];
  2489.           ndbrequire(sorOverflowRecPtr.p->dirindex == fragrecptr.p->nextAllocPage);
  2490.           dbgWord32(pnoPageidptr, ZPOS_OVERFLOWREC, sorOverflowRecPtr.i);
  2491.           pnoPageidptr.p->word32[ZPOS_OVERFLOWREC] = sorOverflowRecPtr.i;
  2492.           sorOverflowRecPtr.p->overpage = pnoPageidptr.i;
  2493.           porOverflowRecPtr = sorOverflowRecPtr;
  2494.           putOverflowRecInFrag(signal);
  2495.           if (pnoPageidptr.p->word32[ZPOS_ALLOC_CONTAINERS] == 0) {
  2496.             jam();
  2497.             ropPageptr = pnoPageidptr;
  2498.             releaseOverpage(signal);
  2499.           }//if
  2500.         }//if
  2501.       }//if
  2502.     }//if
  2503.     fragrecptr.p->nextAllocPage++;
  2504.     toverPageCheck++;
  2505.   }//while
  2506.   signal->theData[0] = fragrecptr.i;
  2507.   sendSignal(cownBlockref, GSN_ACC_OVER_REC, signal, 1, JBB);
  2508. }//Dbacc::execACC_OVER_REC()
  2509. /* --------------------------------------------------------------------------------- */
  2510. /* --------------------------------------------------------------------------------- */
  2511. /* --------------------------------------------------------------------------------- */
  2512. /*                                                                                   */
  2513. /*       END OF SYSTEM RESTART MODULE                                                */
  2514. /*                                                                                   */
  2515. /* --------------------------------------------------------------------------------- */
  2516. /* --------------------------------------------------------------------------------- */
  2517. /* --------------------------------------------------------------------------------- */
  2518. /* --------------------------------------------------------------------------------- */
  2519. /* --------------------------------------------------------------------------------- */
  2520. /*                                                                                   */
  2521. /*       SCAN MODULE                                                                 */
  2522. /*                                                                                   */
  2523. /* --------------------------------------------------------------------------------- */
  2524. /* --------------------------------------------------------------------------------- */
  2525. /* ******************--------------------------------------------------------------- */
  2526. /* ACC_SCANREQ                                         START OF A SCAN PROCESS       */
  2527. /*                                                     SENDER: LQH,    LEVEL B       */
  2528. /*         ENTER ACC_SCANREQ WITH                                                    */
  2529. /*                    TUSERPTR,                      LQH SCAN_CONNECT POINTER        */
  2530. /*                    TUSERBLOCKREF,                 LQH BLOCK REFERENCE             */
  2531. /*                    TABPTR,                        TABLE IDENTITY AND PTR          */
  2532. /*                    TFID                           ROOT FRAGMENT IDENTITY          */
  2533. /*                    TSCAN_FLAG ,                   = ZCOPY, ZSCAN, ZSCAN_LOCK_ALL  */
  2534. /*                                                     ZREADLOCK, ZWRITELOCK         */
  2535. /*                    TSCAN_TRID1 ,                  TRANSACTION ID PART 1           */
  2536. /*                    TSCAN_TRID2                    TRANSACTION ID PART 2           */
  2537. /* ******************--------------------------------------------------------------- */
  2538. /* ******************--------------------------------------------------------------- */
  2539. /* ACC_SCANREQ                                         START OF A SCAN PROCESS       */
  2540. /* ******************------------------------------+                                 */
  2541. /*   SENDER: LQH,    LEVEL B       */
  2542. void Dbacc::execACC_SCANREQ(Signal* signal) 
  2543. {
  2544.   jamEntry();
  2545.   AccScanReq * req = (AccScanReq*)&signal->theData[0];
  2546.   tuserptr = req->senderData;
  2547.   tuserblockref = req->senderRef;
  2548.   tabptr.i = req->tableId;
  2549.   tfid = req->fragmentNo;
  2550.   tscanFlag = req->requestInfo;
  2551.   tscanTrid1 = req->transId1;
  2552.   tscanTrid2 = req->transId2;
  2553.   
  2554.   tresult = 0;
  2555.   ptrCheckGuard(tabptr, ctablesize, tabrec);
  2556.   ndbrequire(getrootfragmentrec(signal,rootfragrecptr, tfid));
  2557.   
  2558.   Uint32 i;
  2559.   for (i = 0; i < MAX_PARALLEL_SCANS_PER_FRAG; i++) {
  2560.     jam();
  2561.     if (rootfragrecptr.p->scan[i] == RNIL) {
  2562.       jam();
  2563.       break;
  2564.     }
  2565.   }
  2566.   ndbrequire(i != MAX_PARALLEL_SCANS_PER_FRAG);
  2567.   ndbrequire(cfirstFreeScanRec != RNIL);
  2568.   seizeScanRec(signal);
  2569.   rootfragrecptr.p->scan[i] = scanPtr.i;
  2570.   scanPtr.p->scanBucketState =  ScanRec::FIRST_LAP;
  2571.   scanPtr.p->scanLockMode = AccScanReq::getLockMode(tscanFlag);
  2572.   scanPtr.p->scanKeyinfoFlag = AccScanReq::getKeyinfoFlag(tscanFlag);
  2573.   scanPtr.p->scanReadCommittedFlag = AccScanReq::getReadCommittedFlag(tscanFlag);
  2574.   
  2575.   /* TWELVE BITS OF THE ELEMENT HEAD ARE SCAN */
  2576.   /* CHECK BITS. THE MASK NOTES WHICH BIT IS */
  2577.   /* ALLOCATED FOR THE ACTIVE SCAN */
  2578.   scanPtr.p->scanMask = 1 << i;
  2579.   scanPtr.p->scanUserptr = tuserptr;
  2580.   scanPtr.p->scanUserblockref = tuserblockref;
  2581.   scanPtr.p->scanTrid1 = tscanTrid1;
  2582.   scanPtr.p->scanTrid2 = tscanTrid2;
  2583.   scanPtr.p->rootPtr = rootfragrecptr.i;
  2584.   scanPtr.p->scanLockHeld = 0;
  2585.   scanPtr.p->scanOpsAllocated = 0;
  2586.   scanPtr.p->scanFirstActiveOp = RNIL;
  2587.   scanPtr.p->scanFirstQueuedOp = RNIL;
  2588.   scanPtr.p->scanLastQueuedOp = RNIL;
  2589.   scanPtr.p->scanFirstLockedOp = RNIL;
  2590.   scanPtr.p->scanLastLockedOp = RNIL;
  2591.   scanPtr.p->scanState = ScanRec::WAIT_NEXT;
  2592.   fragrecptr.i = rootfragrecptr.p->fragmentptr[0];
  2593.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2594.   initScanFragmentPart(signal);
  2595.   /*------------------------------------------------------*/
  2596.   /* We start the timeout loop for the scan process here. */
  2597.   /*------------------------------------------------------*/
  2598.   ndbrequire(scanPtr.p->scanTimer == 0);
  2599.   if (scanPtr.p->scanContinuebCounter == 0) {
  2600.     jam();
  2601.     scanPtr.p->scanContinuebCounter = 1;
  2602.     signal->theData[0] = ZSEND_SCAN_HBREP;
  2603.     signal->theData[1] = scanPtr.i;
  2604.     sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 2);
  2605.   }//if
  2606.   scanPtr.p->scanTimer = scanPtr.p->scanContinuebCounter;
  2607.   /* ************************ */
  2608.   /*  ACC_SCANCONF            */
  2609.   /* ************************ */