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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #define DBACC_C
  14. #include "Dbacc.hpp"
  15. #include <AttributeHeader.hpp>
  16. #include <signaldata/AccFrag.hpp>
  17. #include <signaldata/AccScan.hpp>
  18. #include <signaldata/AccLock.hpp>
  19. #include <signaldata/EventReport.hpp>
  20. #include <signaldata/FsConf.hpp>
  21. #include <signaldata/FsRef.hpp>
  22. #include <signaldata/FsRemoveReq.hpp>
  23. #include <signaldata/DropTab.hpp>
  24. #include <signaldata/DumpStateOrd.hpp>
  25. // TO_DO_RONM is a label for comments on what needs to be improved in future versions
  26. // when more time is given.
  27. #ifdef VM_TRACE
  28. #define DEBUG(x) ndbout << "DBACC: "<< x << endl;
  29. #else
  30. #define DEBUG(x)
  31. #endif
  32. Uint32
  33. Dbacc::remainingUndoPages(){  
  34.   Uint32 HeadPage = cundoposition >> ZUNDOPAGEINDEXBITS;
  35.   Uint32 TailPage = clastUndoPageIdWritten;
  36.   // Head must be larger or same as tail
  37.   ndbrequire(HeadPage>=TailPage);
  38.   Uint32 UsedPages = HeadPage - TailPage;
  39.   Int32 Remaining = cundopagesize - UsedPages;
  40.   // There can not be more than cundopagesize remaining
  41.   if (Remaining <= 0){
  42.     // No more undolog, crash node
  43.     progError(__LINE__,
  44.       ERR_NO_MORE_UNDOLOG,
  45.       "There are more than 1Mbyte undolog writes outstanding");
  46.   }
  47.   return Remaining;
  48. }
  49. void
  50. Dbacc::updateLastUndoPageIdWritten(Signal* signal, Uint32 aNewValue){
  51.   if (remainingUndoPages() < ZMIN_UNDO_PAGES_AT_COMMIT) {
  52.     clastUndoPageIdWritten = aNewValue;
  53.     if (remainingUndoPages() >= ZMIN_UNDO_PAGES_AT_COMMIT) {
  54.       jam();
  55.       EXECUTE_DIRECT(DBLQH, GSN_ACC_COM_UNBLOCK, signal, 1);
  56.       jamEntry();
  57.     }//if
  58.   } else {
  59.     clastUndoPageIdWritten = aNewValue;
  60.   }//if
  61. }//Dbacc::updateLastUndoPageIdWritten()
  62. void 
  63. Dbacc::updateUndoPositionPage(Signal* signal, Uint32 aNewValue){
  64.   if (remainingUndoPages() >= ZMIN_UNDO_PAGES_AT_COMMIT) {
  65.     cundoposition = aNewValue;
  66.     if (remainingUndoPages() < ZMIN_UNDO_PAGES_AT_COMMIT) {
  67.       jam();
  68.       EXECUTE_DIRECT(DBLQH, GSN_ACC_COM_BLOCK, signal, 1);
  69.       jamEntry();
  70.     }//if
  71.   } else {
  72.     cundoposition = aNewValue;
  73.   }//if
  74. }//Dbacc::updateUndoPositionPage()
  75. // Signal entries and statement blocks
  76. /* --------------------------------------------------------------------------------- */
  77. /* --------------------------------------------------------------------------------- */
  78. /* --------------------------------------------------------------------------------- */
  79. /*                                                                                   */
  80. /*       COMMON SIGNAL RECEPTION MODULE                                              */
  81. /*                                                                                   */
  82. /* --------------------------------------------------------------------------------- */
  83. /* --------------------------------------------------------------------------------- */
  84. /* ******************--------------------------------------------------------------- */
  85. /* CONTINUEB                                       CONTINUE SIGNAL                   */
  86. /* ******************------------------------------+                                 */
  87. /*   SENDER: ACC,    LEVEL B       */
  88. void Dbacc::execCONTINUEB(Signal* signal) 
  89. {
  90.   Uint32 tcase;
  91.   jamEntry();
  92.   tcase = signal->theData[0];
  93.   tdata0 = signal->theData[1];
  94.   tresult = 0;
  95.   switch (tcase) {
  96.   case ZLOAD_BAL_LCP_TIMER:
  97.     if (clblPageOver == 0) {
  98.       jam();
  99.       clblPageCounter = clblPagesPerTick;
  100.     } else {
  101.       if (clblPageOver > clblPagesPerTick) {
  102.         jam();
  103.         clblPageOver = clblPageOver - clblPagesPerTick;
  104.       } else {
  105.         jam();
  106.         clblPageOver = 0;
  107.         clblPageCounter = clblPagesPerTick - clblPageOver;
  108.       }//if
  109.     }//if
  110.     signal->theData[0] = ZLOAD_BAL_LCP_TIMER;
  111.     sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1);
  112.     return;
  113.     break;
  114.   case ZINITIALISE_RECORDS:
  115.     jam();
  116.     initialiseRecordsLab(signal, signal->theData[3], signal->theData[4]);
  117.     return;
  118.     break;
  119.   case ZSR_READ_PAGES_ALLOC:
  120.     jam();
  121.     fragrecptr.i = tdata0;
  122.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  123.     srReadPagesAllocLab(signal);
  124.     return;
  125.     break;
  126.   case ZSTART_UNDO:
  127.     jam();
  128.     startUndoLab(signal);
  129.     return;
  130.     break;
  131.   case ZSEND_SCAN_HBREP:
  132.     jam();
  133.     sendScanHbRep(signal, tdata0);
  134.     break;
  135.   case ZREL_ROOT_FRAG:
  136.     {
  137.       jam();
  138.       Uint32 tableId = signal->theData[1];
  139.       releaseRootFragResources(signal, tableId);
  140.       break;
  141.     }
  142.   case ZREL_FRAG:
  143.     {
  144.       jam();
  145.       Uint32 fragIndex = signal->theData[1];
  146.       releaseFragResources(signal, fragIndex);
  147.       break;
  148.     }
  149.   case ZREL_DIR:
  150.     {
  151.       jam();
  152.       Uint32 fragIndex = signal->theData[1];
  153.       Uint32 dirIndex = signal->theData[2];
  154.       Uint32 startIndex = signal->theData[3];
  155.       releaseDirResources(signal, fragIndex, dirIndex, startIndex);
  156.       break;
  157.     }
  158.   case ZREPORT_MEMORY_USAGE:{
  159.     jam();
  160.     static int c_currentMemUsed = 0;
  161.     int now = (cnoOfAllocatedPages * 100)/cpagesize;
  162.     const int thresholds[] = { 99, 90, 80, 0};
  163.     
  164.     Uint32 i = 0;
  165.     const Uint32 sz = sizeof(thresholds)/sizeof(thresholds[0]);
  166.     for(i = 0; i<sz; i++){
  167.       if(now >= thresholds[i]){
  168. now = thresholds[i];
  169. break;
  170.       }
  171.     }
  172.     
  173.     if(now != c_currentMemUsed){
  174.       reportMemoryUsage(signal, now > c_currentMemUsed ? 1 : -1);
  175.     }
  176.     
  177.     c_currentMemUsed = now;
  178.     
  179.     signal->theData[0] = ZREPORT_MEMORY_USAGE;
  180.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1);    
  181.     return;
  182.   }
  183.   case ZLCP_OP_WRITE_RT_BREAK:
  184.   {
  185.     operationRecPtr.i= signal->theData[1];
  186.     fragrecptr.i= signal->theData[2];
  187.     lcpConnectptr.i= signal->theData[3];
  188.     ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
  189.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  190.     ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  191.     lcp_write_op_to_undolog(signal);
  192.     return;
  193.   }
  194.   default:
  195.     ndbrequire(false);
  196.     break;
  197.   }//switch
  198.   return;
  199. }//Dbacc::execCONTINUEB()
  200. /* ******************--------------------------------------------------------------- */
  201. /* FSCLOSECONF                                       CLOSE FILE CONF                 */
  202. /* ******************------------------------------+                                 */
  203. /* SENDER: FS,     LEVEL B         */
  204. void Dbacc::execFSCLOSECONF(Signal* signal) 
  205. {
  206.   jamEntry();
  207.   fsConnectptr.i = signal->theData[0];
  208.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  209.   tresult = 0;
  210.   switch (fsConnectptr.p->fsState) {
  211.   case WAIT_CLOSE_UNDO:
  212.     jam();
  213.     releaseFsConnRec(signal);
  214.     break;
  215.   case LCP_CLOSE_DATA:
  216.     jam();
  217.     checkSyncUndoPagesLab(signal);
  218.     return;
  219.     break;
  220.   case SR_CLOSE_DATA:
  221.     jam();
  222.     sendaccSrconfLab(signal);
  223.     return;
  224.     break;
  225.   default:
  226.     ndbrequire(false);
  227.     break;
  228.   }//switch
  229.   return;
  230. }//Dbacc::execFSCLOSECONF()
  231. /* ******************--------------------------------------------------------------- */
  232. /* FSOPENCONF                                         OPENFILE CONF                  */
  233. /* ******************------------------------------+                                 */
  234. /*   SENDER: FS,     LEVEL B       */
  235. void Dbacc::execFSOPENCONF(Signal* signal) 
  236. {
  237.   jamEntry();
  238.   fsConnectptr.i = signal->theData[0];
  239.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  240.   tuserptr = signal->theData[1];
  241.   tresult = 0; /* RESULT CHECK VALUE              */
  242.   switch (fsConnectptr.p->fsState) {
  243.   case WAIT_OPEN_UNDO_LCP:
  244.     jam();
  245.     lcpOpenUndofileConfLab(signal);
  246.     return;
  247.     break;
  248.   case WAIT_OPEN_UNDO_LCP_NEXT:
  249.     jam();
  250.     fsConnectptr.p->fsPtr = tuserptr;
  251.     return;
  252.     break;
  253.   case OPEN_UNDO_FILE_SR:
  254.     jam();
  255.     fsConnectptr.p->fsPtr = tuserptr;
  256.     srStartUndoLab(signal);
  257.     return;
  258.     break;
  259.   case WAIT_OPEN_DATA_FILE_FOR_WRITE:
  260.     jam();
  261.     lcpFsOpenConfLab(signal);
  262.     return;
  263.     break;
  264.   case WAIT_OPEN_DATA_FILE_FOR_READ:
  265.     jam();
  266.     fsConnectptr.p->fsPtr = tuserptr;
  267.     srFsOpenConfLab(signal);
  268.     return;
  269.     break;
  270.   default:
  271.     ndbrequire(false);
  272.     break;
  273.   }//switch
  274.   return;
  275. }//Dbacc::execFSOPENCONF()
  276. /* ******************--------------------------------------------------------------- */
  277. /* FSREADCONF                                          OPENFILE CONF                 */
  278. /* ******************------------------------------+                                 */
  279. /*   SENDER: FS,     LEVEL B       */
  280. void Dbacc::execFSREADCONF(Signal* signal) 
  281. {
  282.   jamEntry();
  283.   fsConnectptr.i = signal->theData[0];
  284.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  285.   tresult = 0; /* RESULT CHECK VALUE              */
  286.   switch (fsConnectptr.p->fsState) {
  287.   case WAIT_READ_PAGE_ZERO:
  288.     jam();
  289.     fragrecptr.i = fsConnectptr.p->fragrecPtr;
  290.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  291.     srReadPageZeroLab(signal);
  292.     return;
  293.     break;
  294.   case WAIT_READ_DATA:
  295.     jam();
  296.     fragrecptr.i = fsConnectptr.p->fragrecPtr;
  297.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  298.     storeDataPageInDirectoryLab(signal);
  299.     return;
  300.     break;
  301.   case READ_UNDO_PAGE:
  302.     jam();
  303.     srDoUndoLab(signal);
  304.     return;
  305.     break;
  306.   case READ_UNDO_PAGE_AND_CLOSE:
  307.     jam();
  308.     fsConnectptr.p->fsState = WAIT_CLOSE_UNDO;
  309.     /* ************************ */
  310.     /* FSCLOSEREQ               */
  311.     /* ************************ */
  312.     signal->theData[0] = fsConnectptr.p->fsPtr;
  313.     signal->theData[1] = cownBlockref;
  314.     signal->theData[2] = fsConnectptr.i;
  315.     signal->theData[3] = 0;
  316.     sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  317.     /* FLAG = DO NOT DELETE FILE */
  318.     srDoUndoLab(signal);
  319.     return;
  320.     break;
  321.   default:
  322.     ndbrequire(false);
  323.     break;
  324.   }//switch
  325.   return;
  326. }//Dbacc::execFSREADCONF()
  327. /* ******************--------------------------------------------------------------- */
  328. /* FSWRITECONF                                         OPENFILE CONF                 */
  329. /* ******************------------------------------+                                 */
  330. /*   SENDER: FS,     LEVEL B       */
  331. void Dbacc::execFSWRITECONF(Signal* signal) 
  332. {
  333.   jamEntry();
  334.   fsOpptr.i = signal->theData[0];
  335.   ptrCheckGuard(fsOpptr, cfsOpsize, fsOprec);
  336.   /* FS_OPERATION  PTR               */
  337.   tresult = 0; /* RESULT CHECK VALUE              */
  338.   fsConnectptr.i = fsOpptr.p->fsConptr;
  339.   ptrCheckGuard(fsConnectptr, cfsConnectsize, fsConnectrec);
  340.   fragrecptr.i = fsOpptr.p->fsOpfragrecPtr;
  341.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  342.   switch (fsOpptr.p->fsOpstate) {
  343.   case WAIT_WRITE_UNDO:
  344.     jam();
  345.     updateLastUndoPageIdWritten(signal, fsOpptr.p->fsOpMemPage);
  346.     releaseFsOpRec(signal);
  347.     if (fragrecptr.p->nrWaitWriteUndoExit == 0) {
  348.       jam();
  349.       checkSendLcpConfLab(signal);
  350.       return;
  351.     } else {
  352.       jam();
  353.       fragrecptr.p->lastUndoIsStored = ZTRUE;
  354.     }//if
  355.     return;
  356.     break;
  357.   case WAIT_WRITE_UNDO_EXIT:
  358.     jam();
  359.     updateLastUndoPageIdWritten(signal, fsOpptr.p->fsOpMemPage);
  360.     releaseFsOpRec(signal);
  361.     if (fragrecptr.p->nrWaitWriteUndoExit > 0) {
  362.       jam();
  363.       fragrecptr.p->nrWaitWriteUndoExit--;
  364.     }//if
  365.     if (fsConnectptr.p->fsState == WAIT_CLOSE_UNDO) {
  366.       jam();
  367.       /* ************************ */
  368.       /* FSCLOSEREQ               */
  369.       /* ************************ */
  370.       signal->theData[0] = fsConnectptr.p->fsPtr;
  371.       signal->theData[1] = cownBlockref;
  372.       signal->theData[2] = fsConnectptr.i;
  373.       signal->theData[3] = ZFALSE;
  374.       sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  375.     }//if
  376.     if (fragrecptr.p->nrWaitWriteUndoExit == 0) {
  377.       if (fragrecptr.p->lastUndoIsStored == ZTRUE) {
  378.         jam();
  379.         fragrecptr.p->lastUndoIsStored = ZFALSE;
  380.         checkSendLcpConfLab(signal);
  381.         return;
  382.       }//if
  383.     }//if
  384.     return;
  385.     break;
  386.   case WAIT_WRITE_DATA:
  387.     jam();
  388.     releaseFsOpRec(signal);
  389.     fragrecptr.p->activeDataFilePage += ZWRITEPAGESIZE;
  390.     fragrecptr.p->activeDataPage = 0;
  391.     rootfragrecptr.i = fragrecptr.p->myroot;
  392.     ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  393.     lcpConnectptr.i = rootfragrecptr.p->lcpPtr;
  394.     ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
  395.     switch (fragrecptr.p->fragState) {
  396.     case LCP_SEND_PAGES:
  397.       jam();
  398.       savepagesLab(signal);
  399.       return;
  400.       break;
  401.     case LCP_SEND_OVER_PAGES:
  402.       jam();
  403.       saveOverPagesLab(signal);
  404.       return;
  405.       break;
  406.     case LCP_SEND_ZERO_PAGE:
  407.       jam();
  408.       saveZeroPageLab(signal);
  409.       return;
  410.       break;
  411.     case WAIT_ZERO_PAGE_STORED:
  412.       jam();
  413.       lcpCloseDataFileLab(signal);
  414.       return;
  415.       break;
  416.     default:
  417.       ndbrequire(false);
  418.       return;
  419.       break;
  420.     }//switch
  421.     break;
  422.   default:
  423.     ndbrequire(false);
  424.     break;
  425.   }//switch
  426.   return;
  427. }//Dbacc::execFSWRITECONF()
  428. /* ------------------------------------------------------------------------- */
  429. /* ------------------------------------------------------------------------- */
  430. /* ------------------------------------------------------------------------- */
  431. /*                                                                           */
  432. /*       END OF COMMON SIGNAL RECEPTION MODULE                               */
  433. /*                                                                           */
  434. /* ------------------------------------------------------------------------- */
  435. /* ------------------------------------------------------------------------- */
  436. /* ------------------------------------------------------------------------- */
  437. /* ------------------------------------------------------------------------- */
  438. /* ------------------------------------------------------------------------- */
  439. /*                                                                           */
  440. /*       SYSTEM RESTART MODULE                                               */
  441. /*                                                                           */
  442. /* ------------------------------------------------------------------------- */
  443. /* ------------------------------------------------------------------------- */
  444. /* ------------------------------------------------------------------------- */
  445. void Dbacc::execNDB_STTOR(Signal* signal) 
  446. {
  447.   Uint32 tstartphase;
  448.   Uint32 tStartType;
  449.   jamEntry();
  450.   cndbcntrRef = signal->theData[0];
  451.   cmynodeid = signal->theData[1];
  452.   tstartphase = signal->theData[2];
  453.   tStartType = signal->theData[3];
  454.   switch (tstartphase) {
  455.   case ZSPH1:
  456.     jam();
  457.     ndbsttorryLab(signal);
  458.     return;
  459.     break;
  460.   case ZSPH2:
  461.     cnoLcpPages = 2 * (ZWRITEPAGESIZE + 1);
  462.     initialiseLcpPages(signal);
  463.     ndbsttorryLab(signal);
  464.     return;
  465.     break;
  466.   case ZSPH3:
  467.     if ((tStartType == NodeState::ST_NODE_RESTART) ||
  468.         (tStartType == NodeState::ST_INITIAL_NODE_RESTART)) {
  469.       jam();
  470.       //---------------------------------------------
  471.       // csystemRestart is used to check what is needed
  472.       // during log execution. When starting a node it
  473.       // is not a log execution and rather a normal
  474.       // execution. Thus we reset the variable here to
  475.       // avoid unnecessary system crashes.
  476.       //---------------------------------------------
  477.       csystemRestart = ZFALSE;
  478.     }//if
  479.     
  480.     signal->theData[0] = ZLOAD_BAL_LCP_TIMER;
  481.     sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1);
  482.     break;
  483.   case ZSPH6:
  484.     jam();
  485.     clblPagesPerTick = clblPagesPerTickAfterSr;
  486.     csystemRestart = ZFALSE;
  487.     signal->theData[0] = ZREPORT_MEMORY_USAGE;
  488.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1);    
  489.     break;
  490.   default:
  491.     jam();
  492.     /*empty*/;
  493.     break;
  494.   }//switch
  495.   ndbsttorryLab(signal);
  496.   return;
  497. }//Dbacc::execNDB_STTOR()
  498. /* ******************--------------------------------------------------------------- */
  499. /* STTOR                                              START /  RESTART               */
  500. /* ******************------------------------------+                                 */
  501. /*   SENDER: ANY,    LEVEL B       */
  502. void Dbacc::execSTTOR(Signal* signal) 
  503. {
  504.   jamEntry();
  505.   //  tstartphase = signal->theData[1];
  506.   tuserblockref = signal->theData[3];
  507.   csignalkey = signal->theData[6];
  508.   sttorrysignalLab(signal);
  509.   return;
  510. }//Dbacc::execSTTOR()
  511. /* --------------------------------------------------------------------------------- */
  512. /* ZSPH1                                                                             */
  513. /* --------------------------------------------------------------------------------- */
  514. void Dbacc::ndbrestart1Lab(Signal* signal) 
  515. {
  516.   cmynodeid = globalData.ownId;
  517.   cownBlockref = numberToRef(DBACC, cmynodeid);
  518.   czero = 0;
  519.   cminusOne = czero - 1;
  520.   ctest = 0;
  521.   cundoLogActive = ZFALSE;
  522.   csystemRestart = ZTRUE;
  523.   clblPageOver = 0;
  524.   clblPageCounter = 0;
  525.   cactiveUndoFilePage = 0;
  526.   cprevUndoaddress = cminusOne;
  527.   cundoposition = 0;
  528.   clastUndoPageIdWritten = 0;
  529.   cactiveUndoFileVersion = RNIL;
  530.   cactiveOpenUndoFsPtr = RNIL;
  531.   for (Uint32 tmp = 0; tmp < ZMAX_UNDO_VERSION; tmp++) {
  532.     csrVersList[tmp] = RNIL;
  533.   }//for
  534.   return;
  535. }//Dbacc::ndbrestart1Lab()
  536. void Dbacc::initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data) 
  537. {
  538.   switch (tdata0) {
  539.   case 0:
  540.     jam();
  541.     initialiseTableRec(signal);
  542.     break;
  543.   case 1:
  544.     jam();
  545.     initialiseFsConnectionRec(signal);
  546.     break;
  547.   case 2:
  548.     jam();
  549.     initialiseFsOpRec(signal);
  550.     break;
  551.   case 3:
  552.     jam();
  553.     initialiseLcpConnectionRec(signal);
  554.     break;
  555.   case 4:
  556.     jam();
  557.     initialiseDirRec(signal);
  558.     break;
  559.   case 5:
  560.     jam();
  561.     initialiseDirRangeRec(signal);
  562.     break;
  563.   case 6:
  564.     jam();
  565.     initialiseFragRec(signal);
  566.     break;
  567.   case 7:
  568.     jam();
  569.     initialiseOverflowRec(signal);
  570.     break;
  571.   case 8:
  572.     jam();
  573.     initialiseOperationRec(signal);
  574.     break;
  575.   case 9:
  576.     jam();
  577.     initialisePageRec(signal);
  578.     break;
  579.   case 10:
  580.     jam();
  581.     initialiseRootfragRec(signal);
  582.     break;
  583.   case 11:
  584.     jam();
  585.     initialiseScanRec(signal);
  586.     break;
  587.   case 12:
  588.     jam();
  589.     initialiseSrVerRec(signal);
  590.     {
  591.       ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
  592.       conf->senderRef = reference();
  593.       conf->senderData = data;
  594.       sendSignal(ref, GSN_READ_CONFIG_CONF, signal, 
  595.  ReadConfigConf::SignalLength, JBB);
  596.     }
  597.     return;
  598.     break;
  599.   default:
  600.     ndbrequire(false);
  601.     break;
  602.   }//switch
  603.   signal->theData[0] = ZINITIALISE_RECORDS;
  604.   signal->theData[1] = tdata0 + 1;
  605.   signal->theData[2] = 0;
  606.   signal->theData[3] = ref;
  607.   signal->theData[4] = data;
  608.   sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
  609.   return;
  610. }//Dbacc::initialiseRecordsLab()
  611. /* *********************************<< */
  612. /* NDB_STTORRY                         */
  613. /* *********************************<< */
  614. void Dbacc::ndbsttorryLab(Signal* signal) 
  615. {
  616.   signal->theData[0] = cownBlockref;
  617.   sendSignal(cndbcntrRef, GSN_NDB_STTORRY, signal, 1, JBB);
  618.   return;
  619. }//Dbacc::ndbsttorryLab()
  620. /* *********************************<< */
  621. /* SIZEALT_REP         SIZE ALTERATION */
  622. /* *********************************<< */
  623. void Dbacc::execREAD_CONFIG_REQ(Signal* signal) 
  624. {
  625.   const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
  626.   Uint32 ref = req->senderRef;
  627.   Uint32 senderData = req->senderData;
  628.   ndbrequire(req->noOfParameters == 0);
  629.   
  630.   jamEntry();
  631.   const ndb_mgm_configuration_iterator * p = 
  632.     theConfiguration.getOwnConfigIterator();
  633.   ndbrequire(p != 0);
  634.   
  635.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_DIR_RANGE, &cdirrangesize));
  636.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_DIR_ARRAY, &cdirarraysize));
  637.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_FRAGMENT, &cfragmentsize));
  638.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_OP_RECS, &coprecsize));
  639.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_OVERFLOW_RECS, 
  640. &coverflowrecsize));
  641.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_PAGE8, &cpagesize));
  642.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_ROOT_FRAG, 
  643. &crootfragmentsize));
  644.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_TABLE, &ctablesize));
  645.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_SCAN, &cscanRecSize));
  646.   initRecords();
  647.   ndbrestart1Lab(signal);
  648.   clblPagesPerTick = 50;
  649.   ndb_mgm_get_int_parameter(p, CFG_DB_LCP_DISC_PAGES_ACC_SR, 
  650.     &clblPagesPerTick);
  651.   clblPagesPerTickAfterSr = 50;
  652.   ndb_mgm_get_int_parameter(p, CFG_DB_LCP_DISC_PAGES_ACC, 
  653.     &clblPagesPerTickAfterSr);
  654.   tdata0 = 0;
  655.   initialiseRecordsLab(signal, ref, senderData);
  656.   return;
  657. }//Dbacc::execSIZEALT_REP()
  658. /* *********************************<< */
  659. /* STTORRY                             */
  660. /* *********************************<< */
  661. void Dbacc::sttorrysignalLab(Signal* signal) 
  662. {
  663.   signal->theData[0] = csignalkey;
  664.   signal->theData[1] = 3;
  665.   /* BLOCK CATEGORY */
  666.   signal->theData[2] = 2;
  667.   /* SIGNAL VERSION NUMBER */
  668.   signal->theData[3] = ZSPH1;
  669.   signal->theData[4] = 255;
  670.   sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
  671.   /* END OF START PHASES */
  672.   return;
  673. }//Dbacc::sttorrysignalLab()
  674. /* --------------------------------------------------------------------------------- */
  675. /* INITIALISE_DIR_REC                                                                */
  676. /*              INITIALATES THE DIRECTORY RECORDS.                                   */
  677. /* --------------------------------------------------------------------------------- */
  678. void Dbacc::initialiseDirRec(Signal* signal) 
  679. {
  680.   DirectoryarrayPtr idrDirptr;
  681.   ndbrequire(cdirarraysize > 0);
  682.   for (idrDirptr.i = 0; idrDirptr.i < cdirarraysize; idrDirptr.i++) {
  683.     refresh_watch_dog();
  684.     ptrAss(idrDirptr, directoryarray);
  685.     for (Uint32 i = 0; i <= 255; i++) {
  686.       idrDirptr.p->pagep[i] = RNIL;
  687.     }//for
  688.   }//for
  689.   cdirmemory = 0;
  690.   cfirstfreedir = RNIL;
  691. }//Dbacc::initialiseDirRec()
  692. /* --------------------------------------------------------------------------------- */
  693. /* INITIALISE_DIR_RANGE_REC                                                          */
  694. /*              INITIALATES THE DIR_RANGE RECORDS.                                   */
  695. /* --------------------------------------------------------------------------------- */
  696. void Dbacc::initialiseDirRangeRec(Signal* signal) 
  697. {
  698.   DirRangePtr idrDirRangePtr;
  699.   ndbrequire(cdirrangesize > 0);
  700.   for (idrDirRangePtr.i = 0; idrDirRangePtr.i < cdirrangesize; idrDirRangePtr.i++) {
  701.     refresh_watch_dog();
  702.     ptrAss(idrDirRangePtr, dirRange);
  703.     idrDirRangePtr.p->dirArray[0] = idrDirRangePtr.i + 1;
  704.     for (Uint32 i = 1; i < 256; i++) {
  705.       idrDirRangePtr.p->dirArray[i] = RNIL;
  706.     }//for
  707.   }//for
  708.   idrDirRangePtr.i = cdirrangesize - 1;
  709.   ptrAss(idrDirRangePtr, dirRange);
  710.   idrDirRangePtr.p->dirArray[0] = RNIL;
  711.   cfirstfreeDirrange = 0;
  712. }//Dbacc::initialiseDirRangeRec()
  713. /* --------------------------------------------------------------------------------- */
  714. /* INITIALISE_FRAG_REC                                                               */
  715. /*              INITIALATES THE FRAGMENT RECORDS.                                    */
  716. /* --------------------------------------------------------------------------------- */
  717. void Dbacc::initialiseFragRec(Signal* signal) 
  718. {
  719.   FragmentrecPtr regFragPtr;
  720.   ndbrequire(cfragmentsize > 0);
  721.   for (regFragPtr.i = 0; regFragPtr.i < cfragmentsize; regFragPtr.i++) {
  722.     jam();
  723.     refresh_watch_dog();
  724.     ptrAss(regFragPtr, fragmentrec);
  725.     initFragGeneral(regFragPtr);
  726.     regFragPtr.p->nextfreefrag = regFragPtr.i + 1;
  727.   }//for
  728.   regFragPtr.i = cfragmentsize - 1;
  729.   ptrAss(regFragPtr, fragmentrec);
  730.   regFragPtr.p->nextfreefrag = RNIL;
  731.   cfirstfreefrag = 0;
  732. }//Dbacc::initialiseFragRec()
  733. /* --------------------------------------------------------------------------------- */
  734. /* INITIALISE_FS_CONNECTION_REC                                                      */
  735. /*              INITIALATES THE FS_CONNECTION RECORDS                                */
  736. /* --------------------------------------------------------------------------------- */
  737. void Dbacc::initialiseFsConnectionRec(Signal* signal) 
  738. {
  739.   ndbrequire(cfsConnectsize > 0);
  740.   for (fsConnectptr.i = 0; fsConnectptr.i < cfsConnectsize; fsConnectptr.i++) {
  741.     ptrAss(fsConnectptr, fsConnectrec);
  742.     fsConnectptr.p->fsNext = fsConnectptr.i + 1;
  743.     fsConnectptr.p->fsPrev = RNIL;
  744.     fsConnectptr.p->fragrecPtr = RNIL;
  745.     fsConnectptr.p->fsState = WAIT_NOTHING;
  746.   }//for
  747.   fsConnectptr.i = cfsConnectsize - 1;
  748.   ptrAss(fsConnectptr, fsConnectrec);
  749.   fsConnectptr.p->fsNext = RNIL; /* INITIALITES THE LAST CONNECTRECORD */
  750.   cfsFirstfreeconnect = 0; /* INITIATES THE FIRST FREE CONNECT RECORD */
  751. }//Dbacc::initialiseFsConnectionRec()
  752. /* --------------------------------------------------------------------------------- */
  753. /* INITIALISE_FS_OP_REC                                                              */
  754. /*              INITIALATES THE FS_OP RECORDS                                        */
  755. /* --------------------------------------------------------------------------------- */
  756. void Dbacc::initialiseFsOpRec(Signal* signal) 
  757. {
  758.   ndbrequire(cfsOpsize > 0);
  759.   for (fsOpptr.i = 0; fsOpptr.i < cfsOpsize; fsOpptr.i++) {
  760.     ptrAss(fsOpptr, fsOprec);
  761.     fsOpptr.p->fsOpnext = fsOpptr.i + 1;
  762.     fsOpptr.p->fsOpfragrecPtr = RNIL;
  763.     fsOpptr.p->fsConptr = RNIL;
  764.     fsOpptr.p->fsOpstate = WAIT_NOTHING;
  765.   }//for
  766.   fsOpptr.i = cfsOpsize - 1;
  767.   ptrAss(fsOpptr, fsOprec);
  768.   fsOpptr.p->fsOpnext = RNIL;
  769.   cfsFirstfreeop = 0;
  770. }//Dbacc::initialiseFsOpRec()
  771. /* --------------------------------------------------------------------------------- */
  772. /* INITIALISE_LCP_CONNECTION_REC                                                     */
  773. /*              INITIALATES THE LCP_CONNECTION RECORDS                               */
  774. /* --------------------------------------------------------------------------------- */
  775. void Dbacc::initialiseLcpConnectionRec(Signal* signal) 
  776. {
  777.   ndbrequire(clcpConnectsize > 0);
  778.   for (lcpConnectptr.i = 0; lcpConnectptr.i < clcpConnectsize; lcpConnectptr.i++) {
  779.     ptrAss(lcpConnectptr, lcpConnectrec);
  780.     lcpConnectptr.p->nextLcpConn = lcpConnectptr.i + 1;
  781.     lcpConnectptr.p->lcpUserptr = RNIL;
  782.     lcpConnectptr.p->rootrecptr = RNIL;
  783.     lcpConnectptr.p->lcpstate = LCP_FREE;
  784.   }//for
  785.   lcpConnectptr.i = clcpConnectsize - 1;
  786.   ptrAss(lcpConnectptr, lcpConnectrec);
  787.   lcpConnectptr.p->nextLcpConn = RNIL;
  788.   cfirstfreelcpConnect = 0;
  789. }//Dbacc::initialiseLcpConnectionRec()
  790. /* --------------------------------------------------------------------------------- */
  791. /* INITIALISE_OPERATION_REC                                                          */
  792. /*              INITIALATES THE OPERATION RECORDS.                                   */
  793. /* --------------------------------------------------------------------------------- */
  794. void Dbacc::initialiseOperationRec(Signal* signal) 
  795. {
  796.   ndbrequire(coprecsize > 0);
  797.   for (operationRecPtr.i = 0; operationRecPtr.i < coprecsize; operationRecPtr.i++) {
  798.     refresh_watch_dog();
  799.     ptrAss(operationRecPtr, operationrec);
  800.     operationRecPtr.p->transactionstate = IDLE;
  801.     operationRecPtr.p->operation = ZUNDEFINED_OP;
  802.     operationRecPtr.p->opState = FREE_OP;
  803.     operationRecPtr.p->nextOp = operationRecPtr.i + 1;
  804.   }//for
  805.   operationRecPtr.i = coprecsize - 1;
  806.   ptrAss(operationRecPtr, operationrec);
  807.   operationRecPtr.p->nextOp = RNIL;
  808.   cfreeopRec = 0;
  809. }//Dbacc::initialiseOperationRec()
  810. /* --------------------------------------------------------------------------------- */
  811. /* INITIALISE_OVERFLOW_REC                                                           */
  812. /*              INITIALATES THE OVERFLOW RECORDS                                     */
  813. /* --------------------------------------------------------------------------------- */
  814. void Dbacc::initialiseOverflowRec(Signal* signal) 
  815. {
  816.   OverflowRecordPtr iorOverflowRecPtr;
  817.   ndbrequire(coverflowrecsize > 0);
  818.   for (iorOverflowRecPtr.i = 0; iorOverflowRecPtr.i < coverflowrecsize; iorOverflowRecPtr.i++) {
  819.     refresh_watch_dog();
  820.     ptrAss(iorOverflowRecPtr, overflowRecord);
  821.     iorOverflowRecPtr.p->nextfreeoverrec = iorOverflowRecPtr.i + 1;
  822.   }//for
  823.   iorOverflowRecPtr.i = coverflowrecsize - 1;
  824.   ptrAss(iorOverflowRecPtr, overflowRecord);
  825.   iorOverflowRecPtr.p->nextfreeoverrec = RNIL;
  826.   cfirstfreeoverrec = 0;
  827. }//Dbacc::initialiseOverflowRec()
  828. /* --------------------------------------------------------------------------------- */
  829. /* INITIALISE_PAGE_REC                                                               */
  830. /*              INITIALATES THE PAGE RECORDS.                                        */
  831. /* --------------------------------------------------------------------------------- */
  832. void Dbacc::initialisePageRec(Signal* signal) 
  833. {
  834.   ndbrequire(cpagesize > 0);
  835.   cfreepage = 0;
  836.   cfirstfreepage = RNIL;
  837.   cnoOfAllocatedPages = 0;
  838. }//Dbacc::initialisePageRec()
  839. /* --------------------------------------------------------------------------------- */
  840. /* INITIALISE_LCP_PAGES                                                              */
  841. /*              INITIALATES THE LCP PAGE RECORDS.                                    */
  842. /* --------------------------------------------------------------------------------- */
  843. void Dbacc::initialiseLcpPages(Signal* signal) 
  844. {
  845.   Uint32 tilpIndex;
  846.   ndbrequire(cnoLcpPages >= (2 * (ZWRITEPAGESIZE + 1)));
  847.   /* --------------------------------------------------------------------------------- */
  848.   /*       AN ABSOLUTE MINIMUM IS THAT WE HAVE 16 LCP PAGES TO HANDLE TWO CONCURRENT   */
  849.   /*       LCP'S ON LOCAL FRAGMENTS.                                                   */
  850.   /* --------------------------------------------------------------------------------- */
  851.   ndbrequire(cpagesize >= (cnoLcpPages + 8));
  852.   /* --------------------------------------------------------------------------------- */
  853.   /*       THE NUMBER OF PAGES MUST BE AT LEAST 8 PLUS THE NUMBER OF PAGES REQUIRED BY */
  854.   /*       THE LOCAL CHECKPOINT PROCESS. THIS NUMBER IS 8 TIMES THE PARALLELISM OF     */
  855.   /*       LOCAL CHECKPOINTS.                                                          */
  856.   /* --------------------------------------------------------------------------------- */
  857.   /* --------------------------------------------------------------------------------- */
  858.   /*       WE SET UP A LINKED LIST OF PAGES FOR EXCLUSIVE USE BY LOCAL CHECKPOINTS.    */
  859.   /* --------------------------------------------------------------------------------- */
  860.   cfirstfreeLcpPage = RNIL;
  861.   for (tilpIndex = 0; tilpIndex < cnoLcpPages; tilpIndex++) {
  862.     jam();
  863.     seizePage(signal);
  864.     rlpPageptr = spPageptr;
  865.     releaseLcpPage(signal);
  866.   }//for
  867. }//Dbacc::initialiseLcpPages()
  868. /* --------------------------------------------------------------------------------- */
  869. /* INITIALISE_ROOTFRAG_REC                                                           */
  870. /*              INITIALATES THE ROOTFRAG  RECORDS.                                   */
  871. /* --------------------------------------------------------------------------------- */
  872. void Dbacc::initialiseRootfragRec(Signal* signal) 
  873. {
  874.   ndbrequire(crootfragmentsize > 0);
  875.   for (rootfragrecptr.i = 0; rootfragrecptr.i < crootfragmentsize; rootfragrecptr.i++) {
  876.     refresh_watch_dog();
  877.     ptrAss(rootfragrecptr, rootfragmentrec);
  878.     rootfragrecptr.p->nextroot = rootfragrecptr.i + 1;
  879.     rootfragrecptr.p->fragmentptr[0] = RNIL;
  880.     rootfragrecptr.p->fragmentptr[1] = RNIL;
  881.   }//for
  882.   rootfragrecptr.i = crootfragmentsize - 1;
  883.   ptrAss(rootfragrecptr, rootfragmentrec);
  884.   rootfragrecptr.p->nextroot = RNIL;
  885.   cfirstfreerootfrag = 0;
  886. }//Dbacc::initialiseRootfragRec()
  887. /* --------------------------------------------------------------------------------- */
  888. /* INITIALISE_SCAN_REC                                                               */
  889. /*              INITIALATES THE QUE_SCAN RECORDS.                                    */
  890. /* --------------------------------------------------------------------------------- */
  891. void Dbacc::initialiseScanRec(Signal* signal) 
  892. {
  893.   ndbrequire(cscanRecSize > 0);
  894.   for (scanPtr.i = 0; scanPtr.i < cscanRecSize; scanPtr.i++) {
  895.     ptrAss(scanPtr, scanRec);
  896.     scanPtr.p->scanNextfreerec = scanPtr.i + 1;
  897.     scanPtr.p->scanState = ScanRec::SCAN_DISCONNECT;
  898.     scanPtr.p->scanTimer = 0;
  899.     scanPtr.p->scanContinuebCounter = 0;
  900.   }//for
  901.   scanPtr.i = cscanRecSize - 1;
  902.   ptrAss(scanPtr, scanRec);
  903.   scanPtr.p->scanNextfreerec = RNIL;
  904.   cfirstFreeScanRec = 0;
  905. }//Dbacc::initialiseScanRec()
  906. /* --------------------------------------------------------------------------------- */
  907. /* INITIALISE_SR_VER_REC                                                             */
  908. /* --------------------------------------------------------------------------------- */
  909. void Dbacc::initialiseSrVerRec(Signal* signal) 
  910. {
  911.   ndbrequire(csrVersionRecSize > 0);
  912.   for (srVersionPtr.i = 0; srVersionPtr.i < csrVersionRecSize; srVersionPtr.i++) {
  913.     ptrAss(srVersionPtr, srVersionRec);
  914.     srVersionPtr.p->nextFreeSr = srVersionPtr.i + 1;
  915.   }//for
  916.   srVersionPtr.i = csrVersionRecSize - 1;
  917.   ptrAss(srVersionPtr, srVersionRec);
  918.   srVersionPtr.p->nextFreeSr = RNIL;
  919.   cfirstFreeSrVersionRec = 0;
  920. }//Dbacc::initialiseSrVerRec()
  921. /* --------------------------------------------------------------------------------- */
  922. /* INITIALISE_TABLE_REC                                                              */
  923. /*              INITIALATES THE TABLE RECORDS.                                       */
  924. /* --------------------------------------------------------------------------------- */
  925. void Dbacc::initialiseTableRec(Signal* signal) 
  926. {
  927.   ndbrequire(ctablesize > 0);
  928.   for (tabptr.i = 0; tabptr.i < ctablesize; tabptr.i++) {
  929.     refresh_watch_dog();
  930.     ptrAss(tabptr, tabrec);
  931.     for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
  932.       tabptr.p->fragholder[i] = RNIL;
  933.       tabptr.p->fragptrholder[i] = RNIL;
  934.     }//for
  935.   }//for
  936. }//Dbacc::initialiseTableRec()
  937. /* --------------------------------------------------------------------------------- */
  938. /* --------------------------------------------------------------------------------- */
  939. /* --------------------------------------------------------------------------------- */
  940. /*                                                                                   */
  941. /*       END OF SYSTEM RESTART MODULE                                                */
  942. /*                                                                                   */
  943. /* --------------------------------------------------------------------------------- */
  944. /* --------------------------------------------------------------------------------- */
  945. /* --------------------------------------------------------------------------------- */
  946. /* --------------------------------------------------------------------------------- */
  947. /* --------------------------------------------------------------------------------- */
  948. /*                                                                                   */
  949. /*       ADD/DELETE FRAGMENT MODULE                                                  */
  950. /*                                                                                   */
  951. /* --------------------------------------------------------------------------------- */
  952. /* --------------------------------------------------------------------------------- */
  953. void Dbacc::initRootfragrec(Signal* signal)
  954. {
  955.   const AccFragReq * const req = (AccFragReq*)&signal->theData[0];  
  956.   rootfragrecptr.p->mytabptr = req->tableId;
  957.   rootfragrecptr.p->roothashcheck = req->kValue + req->lhFragBits;
  958.   rootfragrecptr.p->noOfElements = 0;
  959.   rootfragrecptr.p->m_commit_count = 0;
  960.   for (Uint32 i = 0; i < MAX_PARALLEL_SCANS_PER_FRAG; i++) {
  961.     rootfragrecptr.p->scan[i] = RNIL;
  962.   }//for
  963. }//Dbacc::initRootfragrec()
  964. void Dbacc::execACCFRAGREQ(Signal* signal) 
  965. {
  966.   const AccFragReq * const req = (AccFragReq*)&signal->theData[0];
  967.   jamEntry();
  968.   if (ERROR_INSERTED(3001)) {
  969.     jam();
  970.     addFragRefuse(signal, 1);
  971.     CLEAR_ERROR_INSERT_VALUE;
  972.     return;
  973.   }
  974.   tabptr.i = req->tableId;
  975. #ifndef VM_TRACE
  976.   // config mismatch - do not crash if release compiled
  977.   if (tabptr.i >= ctablesize) {
  978.     jam();
  979.     addFragRefuse(signal, 800);
  980.     return;
  981.   }
  982. #endif
  983.   ptrCheckGuard(tabptr, ctablesize, tabrec);
  984.   ndbrequire((req->reqInfo & 0xF) == ZADDFRAG);
  985.   ndbrequire(!getrootfragmentrec(signal, rootfragrecptr, req->fragId));
  986.   if (cfirstfreerootfrag == RNIL) {
  987.     jam();
  988.     addFragRefuse(signal, ZFULL_ROOTFRAGRECORD_ERROR);
  989.     return;
  990.   }//if
  991.   seizeRootfragrec(signal);
  992.   if (!addfragtotab(signal, rootfragrecptr.i, req->fragId)) {
  993.     jam();
  994.     releaseRootFragRecord(signal, rootfragrecptr);
  995.     addFragRefuse(signal, ZFULL_ROOTFRAGRECORD_ERROR);
  996.     return;
  997.   }//if
  998.   initRootfragrec(signal);
  999.   for (Uint32 i = 0; i < 2; i++) {
  1000.     jam();
  1001.     if (cfirstfreefrag == RNIL) {
  1002.       jam();
  1003.       addFragRefuse(signal, ZFULL_FRAGRECORD_ERROR);
  1004.       return;
  1005.     }//if
  1006.     seizeFragrec(signal);
  1007.     initFragGeneral(fragrecptr);
  1008.     initFragAdd(signal, i, rootfragrecptr.i, fragrecptr);
  1009.     rootfragrecptr.p->fragmentptr[i] = fragrecptr.i;
  1010.     rootfragrecptr.p->fragmentid[i] = fragrecptr.p->myfid;
  1011.     if (cfirstfreeDirrange == RNIL) {
  1012.       jam();
  1013.       addFragRefuse(signal, ZDIR_RANGE_ERROR);
  1014.       return;
  1015.     } else {
  1016.       jam();
  1017.       seizeDirrange(signal);
  1018.     }//if
  1019.     fragrecptr.p->directory = newDirRangePtr.i;
  1020.     seizeDirectory(signal);
  1021.     if (tresult < ZLIMIT_OF_ERROR) {
  1022.       jam();
  1023.       newDirRangePtr.p->dirArray[0] = sdDirptr.i;
  1024.     } else {
  1025.       jam();
  1026.       addFragRefuse(signal, tresult);
  1027.       return;
  1028.     }//if
  1029.     seizePage(signal);
  1030.     if (tresult > ZLIMIT_OF_ERROR) {
  1031.       jam();
  1032.       addFragRefuse(signal, tresult);
  1033.       return;
  1034.     }//if
  1035.     sdDirptr.p->pagep[0] = spPageptr.i;
  1036.     tipPageId = 0;
  1037.     inpPageptr = spPageptr;
  1038.     initPage(signal);
  1039.     if (cfirstfreeDirrange == RNIL) {
  1040.       jam();
  1041.       addFragRefuse(signal, ZDIR_RANGE_ERROR);
  1042.       return;
  1043.     } else {
  1044.       jam();
  1045.       seizeDirrange(signal);
  1046.     }//if
  1047.     fragrecptr.p->overflowdir = newDirRangePtr.i;
  1048.     seizeDirectory(signal);
  1049.     if (tresult < ZLIMIT_OF_ERROR) {
  1050.       jam();
  1051.       newDirRangePtr.p->dirArray[0] = sdDirptr.i;
  1052.     } else {
  1053.       jam();
  1054.       addFragRefuse(signal, tresult);
  1055.       return;
  1056.     }//if
  1057.   }//for
  1058.   Uint32 userPtr = req->userPtr;
  1059.   BlockReference retRef = req->userRef;
  1060.   rootfragrecptr.p->rootState = ACTIVEROOT;
  1061.   AccFragConf * const conf = (AccFragConf*)&signal->theData[0];
  1062.   conf->userPtr = userPtr;
  1063.   conf->rootFragPtr = rootfragrecptr.i;
  1064.   conf->fragId[0] = rootfragrecptr.p->fragmentid[0];
  1065.   conf->fragId[1] = rootfragrecptr.p->fragmentid[1];
  1066.   conf->fragPtr[0] = rootfragrecptr.p->fragmentptr[0];
  1067.   conf->fragPtr[1] = rootfragrecptr.p->fragmentptr[1];
  1068.   conf->rootHashCheck = rootfragrecptr.p->roothashcheck;
  1069.   sendSignal(retRef, GSN_ACCFRAGCONF, signal, AccFragConf::SignalLength, JBB);
  1070. }//Dbacc::execACCFRAGREQ()
  1071. void Dbacc::addFragRefuse(Signal* signal, Uint32 errorCode) 
  1072. {
  1073.   const AccFragReq * const req = (AccFragReq*)&signal->theData[0];  
  1074.   AccFragRef * const ref = (AccFragRef*)&signal->theData[0];  
  1075.   Uint32 userPtr = req->userPtr;
  1076.   BlockReference retRef = req->userRef;
  1077.   ref->userPtr = userPtr;
  1078.   ref->errorCode = errorCode;
  1079.   sendSignal(retRef, GSN_ACCFRAGREF, signal, AccFragRef::SignalLength, JBB);
  1080.   return;
  1081. }//Dbacc::addFragRefuseEarly()
  1082. void
  1083. Dbacc::execDROP_TAB_REQ(Signal* signal){
  1084.   jamEntry();
  1085.   DropTabReq* req = (DropTabReq*)signal->getDataPtr();
  1086.   TabrecPtr tabPtr;
  1087.   tabPtr.i = req->tableId;
  1088.   ptrCheckGuard(tabPtr, ctablesize, tabrec);
  1089.   
  1090.   tabPtr.p->tabUserRef = req->senderRef;
  1091.   tabPtr.p->tabUserPtr = req->senderData;
  1092.   
  1093.   signal->theData[0] = ZREL_ROOT_FRAG;
  1094.   signal->theData[1] = tabPtr.i;
  1095.   sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
  1096. }
  1097. void Dbacc::releaseRootFragResources(Signal* signal, Uint32 tableId)
  1098. {
  1099.   RootfragmentrecPtr rootPtr;
  1100.   TabrecPtr tabPtr;
  1101.   tabPtr.i = tableId;
  1102.   ptrCheckGuard(tabPtr, ctablesize, tabrec);
  1103.   for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
  1104.     jam();
  1105.     if (tabPtr.p->fragholder[i] != RNIL) {
  1106.       jam();
  1107.       Uint32 fragIndex;
  1108.       rootPtr.i = tabPtr.p->fragptrholder[i];
  1109.       ptrCheckGuard(rootPtr, crootfragmentsize, rootfragmentrec);
  1110.       if (rootPtr.p->fragmentptr[0] != RNIL) {
  1111.         jam();
  1112.         fragIndex = rootPtr.p->fragmentptr[0];
  1113.         rootPtr.p->fragmentptr[0] = RNIL;
  1114.       } else if (rootPtr.p->fragmentptr[1] != RNIL) {
  1115.         jam();
  1116.         fragIndex = rootPtr.p->fragmentptr[1];
  1117.         rootPtr.p->fragmentptr[1] = RNIL;
  1118.       } else {
  1119.         jam();
  1120.         releaseRootFragRecord(signal, rootPtr);
  1121.         tabPtr.p->fragholder[i] = RNIL;
  1122.         tabPtr.p->fragptrholder[i] = RNIL;
  1123.         continue;
  1124.       }//if
  1125.       releaseFragResources(signal, fragIndex);
  1126.       return;
  1127.     }//if
  1128.   }//for
  1129.   /**
  1130.    * Finished...
  1131.    */
  1132.   sendFSREMOVEREQ(signal, tableId);  
  1133. }//Dbacc::releaseRootFragResources()
  1134. void Dbacc::releaseRootFragRecord(Signal* signal, RootfragmentrecPtr rootPtr)
  1135. {
  1136.   rootPtr.p->nextroot = cfirstfreerootfrag;
  1137.   cfirstfreerootfrag = rootPtr.i;
  1138. }//Dbacc::releaseRootFragRecord()
  1139. void Dbacc::releaseFragResources(Signal* signal, Uint32 fragIndex)
  1140. {
  1141.   FragmentrecPtr regFragPtr;
  1142.   regFragPtr.i = fragIndex;
  1143.   ptrCheckGuard(regFragPtr, cfragmentsize, fragmentrec);
  1144.   verifyFragCorrect(regFragPtr);
  1145.   if (regFragPtr.p->directory != RNIL) {
  1146.     jam();
  1147.     releaseDirResources(signal, regFragPtr.i, regFragPtr.p->directory, 0);
  1148.     regFragPtr.p->directory = RNIL;
  1149.   } else if (regFragPtr.p->overflowdir != RNIL) {
  1150.     jam();
  1151.     releaseDirResources(signal, regFragPtr.i, regFragPtr.p->overflowdir, 0);
  1152.     regFragPtr.p->overflowdir = RNIL;
  1153.   } else if (regFragPtr.p->firstOverflowRec != RNIL) {
  1154.     jam();
  1155.     releaseOverflowResources(signal, regFragPtr);
  1156.   } else if (regFragPtr.p->firstFreeDirindexRec != RNIL) {
  1157.     jam();
  1158.     releaseDirIndexResources(signal, regFragPtr);
  1159.   } else {
  1160.     RootfragmentrecPtr rootPtr;
  1161.     jam();
  1162.     rootPtr.i = regFragPtr.p->myroot;
  1163.     ptrCheckGuard(rootPtr, crootfragmentsize, rootfragmentrec);    
  1164.     releaseFragRecord(signal, regFragPtr);
  1165.     signal->theData[0] = ZREL_ROOT_FRAG;
  1166.     signal->theData[1] = rootPtr.p->mytabptr;
  1167.     sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
  1168.   }//if
  1169. }//Dbacc::releaseFragResources()
  1170. void Dbacc::verifyFragCorrect(FragmentrecPtr regFragPtr)
  1171. {
  1172.   for (Uint32 i = 0; i < ZWRITEPAGESIZE; i++) {
  1173.     jam();
  1174.     ndbrequire(regFragPtr.p->datapages[i] == RNIL);
  1175.   }//for
  1176.   ndbrequire(regFragPtr.p->lockOwnersList == RNIL);
  1177.   ndbrequire(regFragPtr.p->firstWaitInQueOp == RNIL);
  1178.   ndbrequire(regFragPtr.p->lastWaitInQueOp == RNIL);
  1179.   ndbrequire(regFragPtr.p->sentWaitInQueOp == RNIL);
  1180.   //ndbrequire(regFragPtr.p->fsConnPtr == RNIL);
  1181.   ndbrequire(regFragPtr.p->zeroPagePtr == RNIL);
  1182.   ndbrequire(regFragPtr.p->nrWaitWriteUndoExit == 0);
  1183.   ndbrequire(regFragPtr.p->sentWaitInQueOp == RNIL);
  1184. }//Dbacc::verifyFragCorrect()
  1185. void Dbacc::releaseDirResources(Signal* signal, 
  1186. Uint32 fragIndex, 
  1187. Uint32 dirIndex, 
  1188. Uint32 startIndex)
  1189. {
  1190.   DirRangePtr regDirRangePtr;
  1191.   regDirRangePtr.i = dirIndex;
  1192.   ptrCheckGuard(regDirRangePtr, cdirrangesize, dirRange);
  1193.   for (Uint32 i = startIndex; i < 256; i++) {
  1194.     jam();
  1195.     if (regDirRangePtr.p->dirArray[i] != RNIL) {
  1196.       jam();
  1197.       Uint32 directoryIndex = regDirRangePtr.p->dirArray[i];
  1198.       regDirRangePtr.p->dirArray[i] = RNIL;
  1199.       releaseDirectoryResources(signal, fragIndex, dirIndex, (i + 1), directoryIndex);
  1200.       return;
  1201.     }//if
  1202.   }//for
  1203.   rdDirRangePtr = regDirRangePtr;
  1204.   releaseDirrange(signal);
  1205.   signal->theData[0] = ZREL_FRAG;
  1206.   signal->theData[1] = fragIndex;
  1207.   sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
  1208. }//Dbacc::releaseDirResources()
  1209. void Dbacc::releaseDirectoryResources(Signal* signal,
  1210.                                       Uint32 fragIndex,
  1211.                                       Uint32 dirIndex,
  1212.                                       Uint32 startIndex,
  1213.                                       Uint32 directoryIndex)
  1214. {
  1215.   DirectoryarrayPtr regDirPtr;
  1216.   regDirPtr.i = directoryIndex;
  1217.   ptrCheckGuard(regDirPtr, cdirarraysize, directoryarray);
  1218.   for (Uint32 i = 0; i < 256; i++) {
  1219.     jam();
  1220.     if (regDirPtr.p->pagep[i] != RNIL) {
  1221.       jam();
  1222.       rpPageptr.i = regDirPtr.p->pagep[i];
  1223.       ptrCheckGuard(rpPageptr, cpagesize, page8);
  1224.       releasePage(signal);
  1225.       regDirPtr.p->pagep[i] = RNIL;
  1226.     }//if
  1227.   }//for
  1228.   rdDirptr = regDirPtr;
  1229.   releaseDirectory(signal);
  1230.   signal->theData[0] = ZREL_DIR;
  1231.   signal->theData[1] = fragIndex;
  1232.   signal->theData[2] = dirIndex;
  1233.   signal->theData[3] = startIndex;
  1234.   sendSignal(cownBlockref, GSN_CONTINUEB, signal, 4, JBB);
  1235. }//Dbacc::releaseDirectoryResources()
  1236. void Dbacc::releaseOverflowResources(Signal* signal, FragmentrecPtr regFragPtr)
  1237. {
  1238.   Uint32 loopCount = 0;
  1239.   OverflowRecordPtr regOverflowRecPtr;
  1240.   while ((regFragPtr.p->firstOverflowRec != RNIL) &&
  1241.          (loopCount < 1)) {
  1242.     jam();
  1243.     regOverflowRecPtr.i = regFragPtr.p->firstOverflowRec;
  1244.     ptrCheckGuard(regOverflowRecPtr, coverflowrecsize, overflowRecord);
  1245.     regFragPtr.p->firstOverflowRec = regOverflowRecPtr.p->nextOverRec;
  1246.     rorOverflowRecPtr = regOverflowRecPtr;
  1247.     releaseOverflowRec(signal);
  1248.     loopCount++;
  1249.   }//while
  1250.   signal->theData[0] = ZREL_FRAG;
  1251.   signal->theData[1] = regFragPtr.i;
  1252.   sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
  1253. }//Dbacc::releaseOverflowResources()
  1254. void Dbacc::releaseDirIndexResources(Signal* signal, FragmentrecPtr regFragPtr)
  1255. {
  1256.   Uint32 loopCount = 0;
  1257.   OverflowRecordPtr regOverflowRecPtr;
  1258.   while ((regFragPtr.p->firstFreeDirindexRec != RNIL) &&
  1259.          (loopCount < 1)) {
  1260.     jam();
  1261.     regOverflowRecPtr.i = regFragPtr.p->firstFreeDirindexRec;
  1262.     ptrCheckGuard(regOverflowRecPtr, coverflowrecsize, overflowRecord);
  1263.     regFragPtr.p->firstFreeDirindexRec = regOverflowRecPtr.p->nextOverList;
  1264.     rorOverflowRecPtr = regOverflowRecPtr;
  1265.     releaseOverflowRec(signal);
  1266.     loopCount++;
  1267.   }//while
  1268.   signal->theData[0] = ZREL_FRAG;
  1269.   signal->theData[1] = regFragPtr.i;
  1270.   sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
  1271. }//Dbacc::releaseDirIndexResources()
  1272. void Dbacc::releaseFragRecord(Signal* signal, FragmentrecPtr regFragPtr) 
  1273. {
  1274.   regFragPtr.p->nextfreefrag = cfirstfreefrag;
  1275.   cfirstfreefrag = regFragPtr.i;
  1276.   initFragGeneral(regFragPtr);
  1277. }//Dbacc::releaseFragRecord()
  1278. void Dbacc::sendFSREMOVEREQ(Signal* signal, Uint32 tableId)
  1279. {
  1280.   FsRemoveReq * const fsReq = (FsRemoveReq *)signal->getDataPtrSend();
  1281.   fsReq->userReference = cownBlockref;
  1282.   fsReq->userPointer = tableId;
  1283.   fsReq->fileNumber[0] = tableId;
  1284.   fsReq->fileNumber[1] = (Uint32)-1; // Remove all fragments
  1285.   fsReq->fileNumber[2] = (Uint32)-1; // Remove all data files within fragment
  1286.   fsReq->fileNumber[3] = 255 |       // No P-value used here
  1287.     (3 << 8) |  // Data-files in D3
  1288.     (0 << 16) | // Data-files
  1289.     (1 << 24);  // Version 1 of fileNumber
  1290.   fsReq->directory = 1;
  1291.   fsReq->ownDirectory = 1;
  1292.   sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal, FsRemoveReq::SignalLength, JBA);  
  1293. }//Dbacc::sendFSREMOVEREQ()
  1294. void Dbacc::execFSREMOVECONF(Signal* signal)
  1295. {
  1296.   FsConf * const fsConf = (FsConf *)signal->getDataPtrSend();
  1297.   TabrecPtr tabPtr;
  1298.   tabPtr.i = fsConf->userPointer;
  1299.   ptrCheckGuard(tabPtr, ctablesize, tabrec);
  1300.   DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
  1301.   dropConf->senderRef = reference();
  1302.   dropConf->senderData = tabPtr.p->tabUserPtr;
  1303.   dropConf->tableId = tabPtr.i;
  1304.   sendSignal(tabPtr.p->tabUserRef, GSN_DROP_TAB_CONF,
  1305.              signal, DropTabConf::SignalLength, JBB);
  1306.   
  1307.   tabPtr.p->tabUserPtr = RNIL;
  1308.   tabPtr.p->tabUserRef = 0;
  1309. }//Dbacc::execFSREMOVECONF()
  1310. /* -------------------------------------------------------------------------- */
  1311. /* ADDFRAGTOTAB                                                               */
  1312. /*       DESCRIPTION: PUTS A FRAGMENT ID AND A POINTER TO ITS RECORD INTO     */
  1313. /*                                TABLE ARRRAY OF THE TABLE RECORD.           */
  1314. /* -------------------------------------------------------------------------- */
  1315. bool Dbacc::addfragtotab(Signal* signal, Uint32 rootIndex, Uint32 fid) 
  1316. {
  1317.   for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
  1318.     jam();
  1319.     if (tabptr.p->fragholder[i] == RNIL) {
  1320.       jam();
  1321.       tabptr.p->fragholder[i] = fid;
  1322.       tabptr.p->fragptrholder[i] = rootIndex;
  1323.       return true;
  1324.     }//if
  1325.   }//for
  1326.   return false;
  1327. }//Dbacc::addfragtotab()
  1328. /* --------------------------------------------------------------------------------- */
  1329. /* --------------------------------------------------------------------------------- */
  1330. /* --------------------------------------------------------------------------------- */
  1331. /*                                                                                   */
  1332. /*       END OF ADD/DELETE FRAGMENT MODULE                                           */
  1333. /*                                                                                   */
  1334. /* --------------------------------------------------------------------------------- */
  1335. /* --------------------------------------------------------------------------------- */
  1336. /* --------------------------------------------------------------------------------- */
  1337. /* --------------------------------------------------------------------------------- */
  1338. /* --------------------------------------------------------------------------------- */
  1339. /*                                                                                   */
  1340. /*       CONNECTION MODULE                                                           */
  1341. /*                                                                                   */
  1342. /* --------------------------------------------------------------------------------- */
  1343. /* --------------------------------------------------------------------------------- */
  1344. /* ******************--------------------------------------------------------------- */
  1345. /* ACCSEIZEREQ                                           SEIZE REQ                   */
  1346. /*                                                    SENDER: LQH,    LEVEL B        */
  1347. /*          ENTER ACCSEIZEREQ WITH                                                   */
  1348. /*                    TUSERPTR ,                     CONECTION PTR OF LQH            */
  1349. /*                    TUSERBLOCKREF                  BLOCK REFERENCE OF LQH          */
  1350. /* ******************--------------------------------------------------------------- */
  1351. /* ******************--------------------------------------------------------------- */
  1352. /* ACCSEIZEREQ                                           SEIZE REQ                   */
  1353. /* ******************------------------------------+                                 */
  1354. /*   SENDER: LQH,    LEVEL B       */
  1355. void Dbacc::execACCSEIZEREQ(Signal* signal) 
  1356. {
  1357.   jamEntry();
  1358.   tuserptr = signal->theData[0];
  1359.   /* CONECTION PTR OF LQH            */
  1360.   tuserblockref = signal->theData[1];
  1361.   /* BLOCK REFERENCE OF LQH          */
  1362.   tresult = 0;
  1363.   if (cfreeopRec == RNIL) {
  1364.     jam();
  1365.     refaccConnectLab(signal);
  1366.     return;
  1367.   }//if
  1368.   seizeOpRec(signal);
  1369.   ptrGuard(operationRecPtr);
  1370.   operationRecPtr.p->userptr = tuserptr;
  1371.   operationRecPtr.p->userblockref = tuserblockref;
  1372.   operationRecPtr.p->operation = ZUNDEFINED_OP;
  1373.   operationRecPtr.p->transactionstate = IDLE;
  1374.   /* ******************************< */
  1375.   /* ACCSEIZECONF                    */
  1376.   /* ******************************< */
  1377.   signal->theData[0] = tuserptr;
  1378.   signal->theData[1] = operationRecPtr.i;
  1379.   sendSignal(tuserblockref, GSN_ACCSEIZECONF, signal, 2, JBB);
  1380.   return;
  1381. }//Dbacc::execACCSEIZEREQ()
  1382. void Dbacc::refaccConnectLab(Signal* signal) 
  1383. {
  1384.   tresult = ZCONNECT_SIZE_ERROR;
  1385.   /* ******************************< */
  1386.   /* ACCSEIZEREF                     */
  1387.   /* ******************************< */
  1388.   signal->theData[0] = tuserptr;
  1389.   signal->theData[1] = tresult;
  1390.   sendSignal(tuserblockref, GSN_ACCSEIZEREF, signal, 2, JBB);
  1391.   return;
  1392. }//Dbacc::refaccConnectLab()
  1393. /* --------------------------------------------------------------------------------- */
  1394. /* --------------------------------------------------------------------------------- */
  1395. /* --------------------------------------------------------------------------------- */
  1396. /*                                                                                   */
  1397. /*       END OF CONNECTION MODULE                                                    */
  1398. /*                                                                                   */
  1399. /* --------------------------------------------------------------------------------- */
  1400. /* --------------------------------------------------------------------------------- */
  1401. /* --------------------------------------------------------------------------------- */
  1402. /* --------------------------------------------------------------------------------- */
  1403. /* --------------------------------------------------------------------------------- */
  1404. /*                                                                                   */
  1405. /*       EXECUTE OPERATION MODULE                                                    */
  1406. /*                                                                                   */
  1407. /* --------------------------------------------------------------------------------- */
  1408. /* --------------------------------------------------------------------------------- */
  1409. /* --------------------------------------------------------------------------------- */
  1410. /* INIT_OP_REC                                                                       */
  1411. /*           INFORMATION WHICH IS RECIEVED BY ACCKEYREQ WILL BE SAVED                */
  1412. /*           IN THE OPERATION RECORD.                                                */
  1413. /* --------------------------------------------------------------------------------- */
  1414. void Dbacc::initOpRec(Signal* signal) 
  1415. {
  1416.   register Uint32 Treqinfo;
  1417.   Treqinfo = signal->theData[2];
  1418.   operationRecPtr.p->hashValue = signal->theData[3];
  1419.   operationRecPtr.p->tupkeylen = signal->theData[4];
  1420.   operationRecPtr.p->transId1 = signal->theData[5];
  1421.   operationRecPtr.p->transId2 = signal->theData[6];
  1422.   operationRecPtr.p->transactionstate = ACTIVE;
  1423.   operationRecPtr.p->commitDeleteCheckFlag = ZFALSE;
  1424.   operationRecPtr.p->operation = Treqinfo & 0x7;
  1425.   /* --------------------------------------------------------------------------------- */
  1426.   // opSimple is not used in this version. Is needed for deadlock handling later on.
  1427.   /* --------------------------------------------------------------------------------- */
  1428.   //  operationRecPtr.p->opSimple = (Treqinfo >> 3) & 0x1; 
  1429.   operationRecPtr.p->lockMode = (Treqinfo >> 4) & 0x3;
  1430.   Uint32 readFlag = (((Treqinfo >> 4) & 0x3) == 0);      // Only 1 if Read
  1431.   Uint32 dirtyFlag = (((Treqinfo >> 6) & 0x1) == 1);     // Only 1 if Dirty
  1432.   Uint32 dirtyReadFlag = readFlag & dirtyFlag;
  1433.   operationRecPtr.p->dirtyRead = dirtyReadFlag;
  1434.   operationRecPtr.p->nodeType = (Treqinfo >> 7) & 0x3;
  1435.   operationRecPtr.p->fid = fragrecptr.p->myfid;
  1436.   operationRecPtr.p->fragptr = fragrecptr.i;
  1437.   operationRecPtr.p->nextParallelQue = RNIL;
  1438.   operationRecPtr.p->prevParallelQue = RNIL;
  1439.   operationRecPtr.p->prevQueOp = RNIL;
  1440.   operationRecPtr.p->nextQueOp = RNIL;
  1441.   operationRecPtr.p->nextSerialQue = RNIL;
  1442.   operationRecPtr.p->prevSerialQue = RNIL;
  1443.   operationRecPtr.p->elementPage = RNIL;
  1444.   operationRecPtr.p->keyinfoPage = RNIL;
  1445.   operationRecPtr.p->lockOwner = ZFALSE;
  1446.   operationRecPtr.p->insertIsDone = ZFALSE;
  1447.   operationRecPtr.p->elementIsDisappeared = ZFALSE;
  1448.   operationRecPtr.p->insertDeleteLen = fragrecptr.p->elementLength;
  1449.   operationRecPtr.p->longPagePtr = RNIL;
  1450.   operationRecPtr.p->longKeyPageIndex = RNIL;
  1451.   operationRecPtr.p->scanRecPtr = RNIL;
  1452.   // bit to mark lock operation
  1453.   operationRecPtr.p->isAccLockReq = (Treqinfo >> 31) & 0x1;
  1454. }//Dbacc::initOpRec()
  1455. /* --------------------------------------------------------------------------------- */
  1456. /* SEND_ACCKEYCONF                                                                   */
  1457. /* --------------------------------------------------------------------------------- */
  1458. void Dbacc::sendAcckeyconf(Signal* signal) 
  1459. {
  1460.   signal->theData[0] = operationRecPtr.p->userptr;
  1461.   signal->theData[1] = operationRecPtr.p->operation;
  1462.   signal->theData[2] = operationRecPtr.p->fid;
  1463.   signal->theData[3] = operationRecPtr.p->localdata[0];
  1464.   signal->theData[4] = operationRecPtr.p->localdata[1];
  1465.   signal->theData[5] = fragrecptr.p->localkeylen;
  1466. }//Dbacc::sendAcckeyconf()
  1467. void Dbacc::ACCKEY_error(Uint32 fromWhere)
  1468. {
  1469.   switch(fromWhere) {
  1470.   case 0:
  1471.     ndbrequire(false);
  1472.   case 1:
  1473.     ndbrequire(false);
  1474.   case 2:
  1475.     ndbrequire(false);
  1476.   case 3:
  1477.     ndbrequire(false);
  1478.   case 4:
  1479.     ndbrequire(false);
  1480.   case 5:
  1481.     ndbrequire(false);
  1482.   case 6:
  1483.     ndbrequire(false);
  1484.   case 7:
  1485.     ndbrequire(false);
  1486.   case 8:
  1487.     ndbrequire(false);
  1488.   case 9:
  1489.     ndbrequire(false);
  1490.   default:
  1491.     ndbrequire(false);
  1492.   }//switch
  1493. }//Dbacc::ACCKEY_error()
  1494. /* ******************--------------------------------------------------------------- */
  1495. /* ACCKEYREQ                                         REQUEST FOR INSERT, DELETE,     */
  1496. /*                                                   RERAD AND UPDATE, A TUPLE.      */
  1497. /*                                                   SENDER: LQH,    LEVEL B         */
  1498. /*  SIGNAL DATA:      OPERATION_REC_PTR,             CONNECTION PTR                  */
  1499. /*                    TABPTR,                        TABLE ID = TABLE RECORD POINTER */
  1500. /*                    TREQINFO,                                                      */
  1501. /*                    THASHVALUE,                    HASH VALUE OF THE TUP           */
  1502. /*                    TKEYLEN,                       LENGTH OF THE PRIMARY KEYS      */
  1503. /*                    TKEY1,                         PRIMARY KEY 1                   */
  1504. /*                    TKEY2,                         PRIMARY KEY 2                   */
  1505. /*                    TKEY3,                         PRIMARY KEY 3                   */
  1506. /*                    TKEY4,                         PRIMARY KEY 4                   */
  1507. /* ******************--------------------------------------------------------------- */
  1508. void Dbacc::execACCKEYREQ(Signal* signal) 
  1509. {
  1510.   jamEntry();
  1511.   operationRecPtr.i = signal->theData[0];   /* CONNECTION PTR */
  1512.   fragrecptr.i = signal->theData[1];        /* FRAGMENT RECORD POINTER         */
  1513.   if (!((operationRecPtr.i < coprecsize) ||
  1514. (fragrecptr.i < cfragmentsize))) {
  1515.     ACCKEY_error(0);
  1516.     return;
  1517.   }//if
  1518.   ptrAss(operationRecPtr, operationrec);
  1519.   ptrAss(fragrecptr, fragmentrec);  
  1520.   ndbrequire(operationRecPtr.p->transactionstate == IDLE);
  1521.   initOpRec(signal);
  1522.   /*---------------------------------------------------------------*/
  1523.   /*                                                               */
  1524.   /*       WE WILL USE THE HASH VALUE TO LOOK UP THE PROPER MEMORY */
  1525.   /*       PAGE AND MEMORY PAGE INDEX TO START THE SEARCH WITHIN.  */
  1526.   /*       WE REMEMBER THESE ADDRESS IF WE LATER NEED TO INSERT    */
  1527.   /*       THE ITEM AFTER NOT FINDING THE ITEM.                    */
  1528.   /*---------------------------------------------------------------*/
  1529.   getElement(signal);
  1530.   
  1531.   if (tgeResult == ZTRUE) {
  1532.     switch (operationRecPtr.p->operation) {
  1533.     case ZREAD:
  1534.     case ZUPDATE:
  1535.     case ZDELETE:
  1536.     case ZWRITE:
  1537.     case ZSCAN_OP:
  1538.       if (!tgeLocked){
  1539. if(operationRecPtr.p->operation == ZWRITE)
  1540. {
  1541.   jam();
  1542.   operationRecPtr.p->operation = ZUPDATE;
  1543. }
  1544.         sendAcckeyconf(signal);
  1545.         if (operationRecPtr.p->dirtyRead == ZFALSE) {
  1546.   /*---------------------------------------------------------------*/
  1547.   // It is not a dirty read. We proceed by locking and continue with
  1548.   // the operation.
  1549.   /*---------------------------------------------------------------*/
  1550.           Uint32 eh = gePageptr.p->word32[tgeElementptr];
  1551.           operationRecPtr.p->scanBits = ElementHeader::getScanBits(eh);
  1552.           operationRecPtr.p->hashvaluePart = ElementHeader::getHashValuePart(eh);
  1553.           operationRecPtr.p->elementPage = gePageptr.i;
  1554.           operationRecPtr.p->elementContainer = tgeContainerptr;
  1555.           operationRecPtr.p->elementPointer = tgeElementptr;
  1556.           operationRecPtr.p->elementIsforward = tgeForward;
  1557.   eh = ElementHeader::setLocked(operationRecPtr.i);
  1558.           dbgWord32(gePageptr, tgeElementptr, eh);
  1559.           gePageptr.p->word32[tgeElementptr] = eh;
  1560.   
  1561.   insertLockOwnersList(signal , operationRecPtr);
  1562.           return;
  1563.         } else {
  1564.           jam();
  1565.   /*---------------------------------------------------------------*/
  1566.   // It is a dirty read. We do not lock anything. Set state to
  1567.   // IDLE since no COMMIT call will come.
  1568.   /*---------------------------------------------------------------*/
  1569.           operationRecPtr.p->transactionstate = IDLE;
  1570.           operationRecPtr.p->operation = ZUNDEFINED_OP;
  1571.           return;
  1572.         }//if
  1573.       } else {
  1574.         jam();
  1575.         accIsLockedLab(signal);
  1576.         return;
  1577.       }//if
  1578.       break;
  1579.     case ZINSERT:
  1580.       jam();
  1581.       insertExistElemLab(signal);
  1582.       return;
  1583.       break;
  1584.     default:
  1585.       ndbrequire(false);
  1586.       break;
  1587.     }//switch
  1588.   } else if (tgeResult == ZFALSE) {
  1589.     switch (operationRecPtr.p->operation) {
  1590.     case ZINSERT:
  1591.     case ZWRITE:
  1592.       jam();
  1593.       // If a write operation makes an insert we switch operation to ZINSERT so
  1594.       // that the commit-method knows an insert has been made and updates noOfElements.
  1595.       operationRecPtr.p->operation = ZINSERT;
  1596.       operationRecPtr.p->insertIsDone = ZTRUE;
  1597.       insertelementLab(signal);
  1598.       return;
  1599.       break;
  1600.     case ZREAD:
  1601.     case ZUPDATE:
  1602.     case ZDELETE:
  1603.     case ZSCAN_OP:
  1604.       jam();
  1605.       acckeyref1Lab(signal, ZREAD_ERROR);
  1606.       return;
  1607.       break;
  1608.     default:
  1609.       ndbrequire(false);
  1610.       break;
  1611.     }//switch
  1612.   } else {
  1613.     jam();
  1614.     acckeyref1Lab(signal, tgeResult);
  1615.     return;
  1616.   }//if
  1617.   return;
  1618. }//Dbacc::execACCKEYREQ()
  1619. void Dbacc::accIsLockedLab(Signal* signal) 
  1620. {
  1621.   ndbrequire(csystemRestart == ZFALSE);
  1622.   queOperPtr.i = ElementHeader::getOpPtrI(gePageptr.p->word32[tgeElementptr]);
  1623.   ptrCheckGuard(queOperPtr, coprecsize, operationrec);
  1624.   if (operationRecPtr.p->dirtyRead == ZFALSE) {
  1625.     Uint32 return_result;
  1626.     if (operationRecPtr.p->lockMode == ZREADLOCK) {
  1627.       jam();
  1628.       priPageptr = gePageptr;
  1629.       tpriElementptr = tgeElementptr;
  1630.       return_result = placeReadInLockQueue(signal);
  1631.     } else {
  1632.       jam();
  1633.       pwiPageptr = gePageptr;
  1634.       tpwiElementptr = tgeElementptr;
  1635.       return_result = placeWriteInLockQueue(signal);
  1636.     }//if
  1637.     if (return_result == ZPARALLEL_QUEUE) {
  1638.       jam();
  1639.       sendAcckeyconf(signal);
  1640.       return;
  1641.     } else if (return_result == ZSERIAL_QUEUE) {
  1642.       jam();
  1643.       signal->theData[0] = RNIL;
  1644.       return;
  1645.     } else if (return_result == ZWRITE_ERROR) {
  1646.       jam();
  1647.       acckeyref1Lab(signal, return_result);
  1648.       return;
  1649.     }//if
  1650.     ndbrequire(false);
  1651.   } else {
  1652.     if (queOperPtr.p->elementIsDisappeared == ZFALSE) {
  1653.       jam();
  1654.       /*---------------------------------------------------------------*/
  1655.       // It is a dirty read. We do not lock anything. Set state to
  1656.       // IDLE since no COMMIT call will arrive.
  1657.       /*---------------------------------------------------------------*/
  1658.       sendAcckeyconf(signal);
  1659.       operationRecPtr.p->transactionstate = IDLE;
  1660.       operationRecPtr.p->operation = ZUNDEFINED_OP;
  1661.       return;
  1662.     } else {
  1663.       jam();
  1664.       /*---------------------------------------------------------------*/
  1665.       // The tuple does not exist in the committed world currently.
  1666.       // Report read error.
  1667.       /*---------------------------------------------------------------*/
  1668.       acckeyref1Lab(signal, ZREAD_ERROR);
  1669.       return;
  1670.     }//if
  1671.   }//if
  1672. }//Dbacc::accIsLockedLab()
  1673. /* --------------------------------------------------------------------------------- */
  1674. /*        I N S E R T      E X I S T      E L E M E N T                              */
  1675. /* --------------------------------------------------------------------------------- */
  1676. void Dbacc::insertExistElemLab(Signal* signal) 
  1677. {
  1678.   if (!tgeLocked){
  1679.     jam();
  1680.     acckeyref1Lab(signal, ZWRITE_ERROR);/* THE ELEMENT ALREADY EXIST */
  1681.     return;
  1682.   }//if
  1683.   accIsLockedLab(signal);
  1684. }//Dbacc::insertExistElemLab()
  1685. /* --------------------------------------------------------------------------------- */
  1686. /* INSERTELEMENT                                                                     */
  1687. /* --------------------------------------------------------------------------------- */
  1688. void Dbacc::insertelementLab(Signal* signal) 
  1689. {
  1690.   Uint32 tinsKeyLen;
  1691.   
  1692.   if (fragrecptr.p->createLcp == ZTRUE) {
  1693.     if (remainingUndoPages() < ZMIN_UNDO_PAGES_AT_OPERATION) {
  1694.       jam();
  1695.       acckeyref1Lab(signal, ZTEMPORARY_ACC_UNDO_FAILURE);
  1696.       return;
  1697.     }//if
  1698.   }//if
  1699.   if (fragrecptr.p->firstOverflowRec == RNIL) {
  1700.     jam();
  1701.     allocOverflowPage(signal);
  1702.     if (tresult > ZLIMIT_OF_ERROR) {
  1703.       jam();
  1704.       acckeyref1Lab(signal, tresult);
  1705.       return;
  1706.     }//if
  1707.   }//if
  1708.   if (fragrecptr.p->keyLength != operationRecPtr.p->tupkeylen) {
  1709.     ndbrequire(fragrecptr.p->keyLength == 0);
  1710.   }//if
  1711.   if (fragrecptr.p->keyLength != 0) {
  1712.     ndbrequire(operationRecPtr.p->tupkeylen <= 8);
  1713.     for (Uint32 i = 0; i < operationRecPtr.p->tupkeylen; i++) {
  1714.       jam();
  1715.       ckeys[i] = signal->theData[i + 7];
  1716.     }//for
  1717.     tinsKeyLen = operationRecPtr.p->tupkeylen;
  1718.   } else {
  1719.     jam();
  1720.     seizePage(signal);
  1721.     if (tresult > ZLIMIT_OF_ERROR) {
  1722.       jam();
  1723.       acckeyref1Lab(signal, tresult);
  1724.       return;
  1725.     }//if
  1726.     operationRecPtr.p->keyinfoPage = spPageptr.i;
  1727.     for (Uint32 i = 0; i < signal->theData[4]; i++) {
  1728.       spPageptr.p->word32[i] = signal->theData[i + 7];
  1729.     }//for
  1730.   
  1731.     getLongKeyPage(signal);
  1732.     if (tresult > ZLIMIT_OF_ERROR) {
  1733.       jam();
  1734.       acckeyref1Lab(signal, tresult);
  1735.       return;
  1736.     }//if
  1737.     slkPageptr = glkPageptr;
  1738.     slkCopyPageptr.i = operationRecPtr.p->keyinfoPage;
  1739.     ptrCheckGuard(slkCopyPageptr, cpagesize, page8);
  1740.     tslkKeyLen = operationRecPtr.p->tupkeylen;
  1741.     storeLongKeys(signal);
  1742.     ckeys[0] = (slkPageptr.p->word32[ZPOS_PAGE_ID] << 10) + tslkPageIndex;
  1743.     tinsKeyLen = ZACTIVE_LONG_KEY_LEN;
  1744.     rpPageptr.i = operationRecPtr.p->keyinfoPage;
  1745.     ptrCheckGuard(rpPageptr, cpagesize, page8);
  1746.     releasePage(signal);
  1747.     operationRecPtr.p->keyinfoPage = RNIL;
  1748.   }//if
  1749.   signal->theData[0] = operationRecPtr.p->userptr;
  1750.   Uint32 blockNo = refToBlock(operationRecPtr.p->userblockref);
  1751.   EXECUTE_DIRECT(blockNo, GSN_LQH_ALLOCREQ, signal, 1);
  1752.   jamEntry();
  1753.   if (signal->theData[0] != 0) {
  1754.     jam();
  1755.     Uint32 result_code = signal->theData[0];
  1756.     acckeyref1Lab(signal, result_code);
  1757.     return;
  1758.   }//if
  1759.   Uint32 localKey = (signal->theData[1] << MAX_TUPLES_BITS) + signal->theData[2];
  1760.   insertLockOwnersList(signal, operationRecPtr);
  1761.   const Uint32 tmp = fragrecptr.p->k + fragrecptr.p->lhfragbits;
  1762.   operationRecPtr.p->hashvaluePart = 
  1763.     (operationRecPtr.p->hashValue >> tmp) & 0xFFFF;
  1764.   operationRecPtr.p->scanBits = 0; /* NOT ANY ACTIVE SCAN */
  1765.   tidrElemhead = ElementHeader::setLocked(operationRecPtr.i);
  1766.   idrPageptr = gdiPageptr;
  1767.   tidrPageindex = tgdiPageindex;
  1768.   tidrForward = ZTRUE;
  1769.   tidrKeyLen = tinsKeyLen;
  1770.   idrOperationRecPtr = operationRecPtr;
  1771.   clocalkey[0] = localKey;
  1772.   operationRecPtr.p->localdata[0] = localKey;
  1773.   /* --------------------------------------------------------------------------------- */
  1774.   /*       WE SET THE LOCAL KEY TO MINUS ONE TO INDICATE IT IS NOT YET VALID.          */
  1775.   /* --------------------------------------------------------------------------------- */
  1776.   insertElement(signal);
  1777.   sendAcckeyconf(signal);
  1778.   return;
  1779. }//Dbacc::insertelementLab()
  1780. /* --------------------------------------------------------------------------------- */
  1781. /* PLACE_READ_IN_LOCK_QUEUE                                                          */
  1782. /* INPUT: OPERATION_REC_PTR OUR OPERATION POINTER     */
  1783. /* QUE_OPER_PTR LOCK QUEUE OWNER OPERATION POINTER  */
  1784. /* PRI_PAGEPTR             PAGE POINTER OF ELEMENT             */
  1785. /* TPRI_ELEMENTPTR         ELEMENT POINTER OF ELEMENT          */
  1786. /* OUTPUT TRESULT =                                                   */
  1787. /* ZPARALLEL_QUEUE OPERATION PLACED IN PARALLEL QUEUE  */
  1788. /* OPERATION CAN PROCEED NOW.          */
  1789. /* ZSERIAL_QUEUE OPERATION PLACED IN SERIAL QUEUE    */
  1790. /* ERROR CODE OPERATION NEEDS ABORTING            */
  1791. /* THE ELEMENT WAS LOCKED AND WE WANT TO READ THE TUPLE. WE WILL CHECK THE LOCK      */
  1792. /* QUEUES TO PERFORM THE PROPER ACTION.                                              */
  1793. /*                                                                                   */
  1794. /* IN SOME PLACES IN THE CODE BELOW THAT HANDLES WHAT TO DO WHEN THE TUPLE IS LOCKED */
  1795. /* WE DO ASSUME THAT NEXT_PARALLEL_QUEUE AND NEXT_SERIAL_QUEUE ON OPERATION_REC_PTR  */
  1796. /* HAVE BEEN INITIALISED TO RNIL. THUS WE DO NOT PERFORM THIS ONCE MORE EVEN IF IT   */
  1797. /* COULD BE NICE FOR READABILITY.                                                    */
  1798. /* --------------------------------------------------------------------------------- */
  1799. Uint32 Dbacc::placeReadInLockQueue(Signal* signal) 
  1800. {
  1801.   if (getNoParallelTransaction(queOperPtr.p) == 1) {
  1802.     if ((queOperPtr.p->transId1 == operationRecPtr.p->transId1) && 
  1803.         (queOperPtr.p->transId2 == operationRecPtr.p->transId2)) {
  1804.       /* --------------------------------------------------------------------------------- */
  1805.       /* WE ARE PERFORMING A READ OPERATION AND THIS TRANSACTION ALREADY OWNS THE LOCK     */
  1806.       /* ALONE. PUT THE OPERATION LAST IN THE PARALLEL QUEUE.                              */
  1807.       /* --------------------------------------------------------------------------------- */
  1808.       jam();
  1809.       mlpqOperPtr = queOperPtr;
  1810.       moveLastParallelQueue(signal);
  1811.       operationRecPtr.p->localdata[0] = queOperPtr.p->localdata[0];
  1812.       operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1];
  1813.       operationRecPtr.p->prevParallelQue = mlpqOperPtr.i;
  1814.       mlpqOperPtr.p->nextParallelQue = operationRecPtr.i;
  1815.       switch (queOperPtr.p->lockMode) {
  1816.       case ZREADLOCK:
  1817.         jam();
  1818.         /*empty*/;
  1819.         break;
  1820.       default:
  1821.         jam();
  1822.         /* --------------------------------------------------------------------------------- */
  1823.         /*       IF THE TRANSACTION PREVIOUSLY SET A WRITE LOCK WE MUST ENSURE THAT ALL      */
  1824.         /*       OPERATIONS IN THE PARALLEL QUEUE HAVE WRITE LOCK MODE TO AVOID STRANGE BUGS.*/
  1825.         /* --------------------------------------------------------------------------------- */
  1826.         operationRecPtr.p->lockMode = queOperPtr.p->lockMode;
  1827.         break;
  1828.       }//switch
  1829.       return ZPARALLEL_QUEUE;
  1830.     }//if
  1831.   }//if
  1832.   if (queOperPtr.p->nextSerialQue == RNIL) {
  1833.     /* --------------------------------------------------------------------------------- */
  1834.     /* WE ARE PERFORMING A READ OPERATION AND THERE IS NO SERIAL QUEUE. IF THERE IS NO   */
  1835.     /* WRITE OPERATION THAT OWNS THE LOCK OR ANY WRITE OPERATION IN THE PARALLEL QUEUE   */
  1836.     /* IT IS ENOUGH TO CHECK THE LOCK MODE OF THE LEADER IN THE PARALLEL QUEUE. IF IT IS */
  1837.     /* A READ LOCK THEN WE PLACE OURSELVES IN THE PARALLEL QUEUE OTHERWISE WE GO ON TO   */
  1838.     /* PLACE OURSELVES IN THE SERIAL QUEUE.                                              */
  1839.     /* --------------------------------------------------------------------------------- */
  1840.     switch (queOperPtr.p->lockMode) {
  1841.     case ZREADLOCK:
  1842.       jam();
  1843.       mlpqOperPtr = queOperPtr;
  1844.       moveLastParallelQueue(signal);
  1845.       operationRecPtr.p->prevParallelQue = mlpqOperPtr.i;
  1846.       mlpqOperPtr.p->nextParallelQue = operationRecPtr.i;
  1847.       operationRecPtr.p->localdata[0] = queOperPtr.p->localdata[0];
  1848.       operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1];
  1849.       return ZPARALLEL_QUEUE;
  1850.     default:
  1851.       jam();
  1852.       queOperPtr.p->nextSerialQue = operationRecPtr.i;
  1853.       operationRecPtr.p->prevSerialQue = queOperPtr.i;
  1854.       putOpInFragWaitQue(signal);
  1855.       break;
  1856.     }//switch
  1857.   } else {
  1858.     jam();
  1859.     placeSerialQueueRead(signal);
  1860.   }//if
  1861.   return ZSERIAL_QUEUE;
  1862. }//Dbacc::placeReadInLockQueue()
  1863. /* --------------------------------------------------------------------------------- */
  1864. /* WE WILL CHECK IF THIS TRANSACTION IS ALREADY PLACED AT SOME SPOT IN THE PARALLEL  */
  1865. /* SERIAL QUEUE WITHOUT ANY NEIGHBORS FROM OTHER TRANSACTION. IF SO WE WILL INSERT   */
  1866. /* IT IN THAT PARALLEL QUEUE.                                                        */
  1867. /* --------------------------------------------------------------------------------- */
  1868. void Dbacc::placeSerialQueueRead(Signal* signal) 
  1869. {
  1870.   readWriteOpPtr.i = queOperPtr.p->nextSerialQue;
  1871.   ptrCheckGuard(readWriteOpPtr, coprecsize, operationrec);
  1872.  PSQR_LOOP:
  1873.   jam();
  1874.   if (readWriteOpPtr.p->nextSerialQue == RNIL) {
  1875.     jam();
  1876.     /* --------------------------------------------------------------------------------- */
  1877.     /*       THERE WAS NO PREVIOUS OPERATION IN THIS TRANSACTION WHICH WE COULD PUT IT   */
  1878.     /*       IN THE PARALLEL QUEUE TOGETHER WITH.                                        */
  1879.     /* --------------------------------------------------------------------------------- */
  1880.     checkOnlyReadEntry(signal);
  1881.     return;
  1882.   }//if
  1883.   if (getNoParallelTransaction(readWriteOpPtr.p) == 1) {
  1884.     jam();
  1885.     /* --------------------------------------------------------------------------------- */
  1886.     /* THERE WAS ONLY ONE TRANSACTION INVOLVED IN THE PARALLEL QUEUE. IF THIS IS OUR     */
  1887.     /* TRANSACTION WE CAN STILL GET HOLD OF THE LOCK.                                    */
  1888.     /* --------------------------------------------------------------------------------- */
  1889.     if ((readWriteOpPtr.p->transId1 == operationRecPtr.p->transId1) && 
  1890.         (readWriteOpPtr.p->transId2 == operationRecPtr.p->transId2)) {
  1891.       jam();
  1892.       /* --------------------------------------------------------------------------------- */
  1893.       /* WE ARE PERFORMING A READ IN THE SAME TRANSACTION WHERE WE ALREADY                 */
  1894.       /* PREVIOUSLY HAVE EXECUTED AN OPERATION. INSERT-DELETE, READ-UPDATE, READ-READ,     */
  1895.       /* UPDATE-UPDATE, UPDATE-DELETE, READ-DELETE, INSERT-READ, INSERT-UPDATE ARE ALLOWED */
  1896.       /* COMBINATIONS. A NEW INSERT AFTER A DELETE IS NOT ALLOWED AND SUCH AN INSERT WILL  */
  1897.       /* GO TO THE SERIAL LOCK QUEUE WHICH IT WILL NOT LEAVE UNTIL A TIME-OUT AND THE      */
  1898.       /* TRANSACTION IS ABORTED. READS AND UPDATES AFTER DELETES IS ALSO NOT ALLOWED.      */
  1899.       /* --------------------------------------------------------------------------------- */
  1900.       mlpqOperPtr = readWriteOpPtr;
  1901.       moveLastParallelQueue(signal);
  1902.       readWriteOpPtr = mlpqOperPtr;
  1903.       operationRecPtr.p->prevParallelQue = readWriteOpPtr.i;
  1904.       readWriteOpPtr.p->nextParallelQue = operationRecPtr.i;
  1905.       operationRecPtr.p->localdata[0] = readWriteOpPtr.p->localdata[0];
  1906.       operationRecPtr.p->localdata[1] = readWriteOpPtr.p->localdata[1];
  1907.       switch (readWriteOpPtr.p->lockMode) {
  1908.       case ZREADLOCK:
  1909.         jam();
  1910.         /*empty*/;
  1911.         break;
  1912.       default:
  1913.         jam();
  1914.         /* --------------------------------------------------------------------------------- */
  1915.         /*       IF THE TRANSACTION PREVIOUSLY SET A WRITE LOCK WE MUST ENSURE THAT ALL      */
  1916.         /*       OPERATIONS IN THE PARALLEL QUEUE HAVE WRITE LOCK MODE TO AVOID STRANGE BUGS.*/
  1917.         /* --------------------------------------------------------------------------------- */
  1918.         operationRecPtr.p->lockMode = readWriteOpPtr.p->lockMode;
  1919.         break;
  1920.       }//switch
  1921.       putOpInFragWaitQue(signal);
  1922.       return;
  1923.     }//if
  1924.   }//if
  1925.   readWriteOpPtr.i = readWriteOpPtr.p->nextSerialQue;
  1926.   ptrCheckGuard(readWriteOpPtr, coprecsize, operationrec);
  1927.   goto PSQR_LOOP;
  1928. }//Dbacc::placeSerialQueueRead()
  1929. /* --------------------------------------------------------------------------------- */
  1930. /*       WE WILL CHECK IF THE LAST ENTRY IN THE SERIAL QUEUE CONTAINS ONLY READ      */
  1931. /*       OPERATIONS. IF SO WE WILL INSERT IT IN THAT PARALLEL QUEUE. OTHERWISE WE    */
  1932. /*       WILL PLACE IT AT THE END OF THE SERIAL QUEUE.                               */
  1933. /* --------------------------------------------------------------------------------- */
  1934. void Dbacc::checkOnlyReadEntry(Signal* signal) 
  1935. {
  1936.   switch (readWriteOpPtr.p->lockMode) {
  1937.   case ZREADLOCK:
  1938.     jam();
  1939.     /* --------------------------------------------------------------------------------- */
  1940.     /* SINCE THIS LAST QUEUE ONLY CONTAINS READ LOCKS WE CAN JOIN THE PARALLEL QUEUE AT  */
  1941.     /* THE END.                                                                          */
  1942.     /* --------------------------------------------------------------------------------- */
  1943.     mlpqOperPtr = readWriteOpPtr;
  1944.     moveLastParallelQueue(signal);
  1945.     readWriteOpPtr = mlpqOperPtr;
  1946.     operationRecPtr.p->prevParallelQue = readWriteOpPtr.i;
  1947.     readWriteOpPtr.p->nextParallelQue = operationRecPtr.i;
  1948.     operationRecPtr.p->localdata[0] = readWriteOpPtr.p->localdata[0];
  1949.     operationRecPtr.p->localdata[1] = readWriteOpPtr.p->localdata[1];
  1950.     break;
  1951.   default:
  1952.     jam();                             /* PUT THE OPERATION RECORD IN THE SERIAL QUEUE */
  1953.     readWriteOpPtr.p->nextSerialQue = operationRecPtr.i;
  1954.     operationRecPtr.p->prevSerialQue = readWriteOpPtr.i;
  1955.     break;
  1956.   }//switch
  1957.   putOpInFragWaitQue(signal);
  1958. }//Dbacc::checkOnlyReadEntry()
  1959. /* --------------------------------------------------------------------------------- */
  1960. /* GET_NO_PARALLEL_TRANSACTION                                                       */
  1961. /* --------------------------------------------------------------------------------- */
  1962. Uint32
  1963. Dbacc::getNoParallelTransaction(const Operationrec * op) 
  1964. {
  1965.   OperationrecPtr tmp;
  1966.   
  1967.   tmp.i= op->nextParallelQue;
  1968.   Uint32 transId[2] = { op->transId1, op->transId2 };
  1969.   while (tmp.i != RNIL) 
  1970.   {
  1971.     jam();
  1972.     ptrCheckGuard(tmp, coprecsize, operationrec);
  1973.     if (tmp.p->transId1 == transId[0] && tmp.p->transId2 == transId[1])
  1974.       tmp.i = tmp.p->nextParallelQue;
  1975.     else
  1976.       return 2;
  1977.   }
  1978.   return 1;
  1979. }//Dbacc::getNoParallelTransaction()
  1980. void Dbacc::moveLastParallelQueue(Signal* signal) 
  1981. {
  1982.   while (mlpqOperPtr.p->nextParallelQue != RNIL) {
  1983.     jam();
  1984.     mlpqOperPtr.i = mlpqOperPtr.p->nextParallelQue;
  1985.     ptrCheckGuard(mlpqOperPtr, coprecsize, operationrec);
  1986.   }//if
  1987. }//Dbacc::moveLastParallelQueue()
  1988. void Dbacc::moveLastParallelQueueWrite(Signal* signal) 
  1989. {
  1990.   /* --------------------------------------------------------------------------------- */
  1991.   /*       ENSURE THAT ALL OPERATIONS HAVE LOCK MODE SET TO WRITE SINCE WE INSERT A    */
  1992.   /*       WRITE LOCK INTO THE PARALLEL QUEUE.                                         */
  1993.   /* --------------------------------------------------------------------------------- */
  1994.   while (mlpqOperPtr.p->nextParallelQue != RNIL) {
  1995.     jam();
  1996.     mlpqOperPtr.p->lockMode = operationRecPtr.p->lockMode;
  1997.     mlpqOperPtr.i = mlpqOperPtr.p->nextParallelQue;
  1998.     ptrCheckGuard(mlpqOperPtr, coprecsize, operationrec);
  1999.   }//if
  2000.   mlpqOperPtr.p->lockMode = operationRecPtr.p->lockMode;
  2001. }//Dbacc::moveLastParallelQueueWrite()
  2002. /* --------------------------------------------------------------------------------- */
  2003. /* PLACE_WRITE_IN_LOCK_QUEUE                                                         */
  2004. /* INPUT: OPERATION_REC_PTR OUR OPERATION POINTER     */
  2005. /* QUE_OPER_PTR LOCK QUEUE OWNER OPERATION POINTER  */
  2006. /* PWI_PAGEPTR             PAGE POINTER OF ELEMENT             */
  2007. /* TPWI_ELEMENTPTR         ELEMENT POINTER OF ELEMENT          */
  2008. /* OUTPUT TRESULT =                                                   */
  2009. /* ZPARALLEL_QUEUE OPERATION PLACED IN PARALLEL QUEUE  */
  2010. /* OPERATION CAN PROCEED NOW.          */
  2011. /* ZSERIAL_QUEUE OPERATION PLACED IN SERIAL QUEUE    */
  2012. /* ERROR CODE OPERATION NEEDS ABORTING            */
  2013. /* --------------------------------------------------------------------------------- */
  2014. Uint32 Dbacc::placeWriteInLockQueue(Signal* signal) 
  2015. {
  2016.   if (!((getNoParallelTransaction(queOperPtr.p) == 1) &&
  2017. (queOperPtr.p->transId1 == operationRecPtr.p->transId1) &&
  2018. (queOperPtr.p->transId2 == operationRecPtr.p->transId2))) {
  2019.     jam();
  2020.     placeSerialQueueWrite(signal);
  2021.     return ZSERIAL_QUEUE;
  2022.   }//if
  2023.   
  2024.   /* 
  2025.     WE ARE PERFORMING AN READ EXCLUSIVE, INSERT, UPDATE OR DELETE IN THE SAME
  2026.     TRANSACTION WHERE WE PREVIOUSLY HAVE EXECUTED AN OPERATION.
  2027.     Read-All, Update-All, Insert-All and Delete-Insert are allowed
  2028.     combinations.
  2029.     Delete-Read, Delete-Update and Delete-Delete are not an allowed
  2030.     combination and will result in tuple not found error.
  2031.   */
  2032.   mlpqOperPtr = queOperPtr;
  2033.   moveLastParallelQueueWrite(signal);
  2034.   if (operationRecPtr.p->operation == ZINSERT && 
  2035.       mlpqOperPtr.p->operation != ZDELETE){
  2036.     jam();
  2037.     return ZWRITE_ERROR;
  2038.   }//if
  2039.   if(operationRecPtr.p->operation == ZWRITE)
  2040.   {
  2041.     operationRecPtr.p->operation = 
  2042.       (mlpqOperPtr.p->operation == ZDELETE) ? ZINSERT : ZUPDATE;
  2043.   }
  2044.   
  2045.   operationRecPtr.p->localdata[0] = queOperPtr.p->localdata[0];
  2046.   operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1];
  2047.   operationRecPtr.p->prevParallelQue = mlpqOperPtr.i;
  2048.   mlpqOperPtr.p->nextParallelQue = operationRecPtr.i;
  2049.   return ZPARALLEL_QUEUE;
  2050. }//Dbacc::placeWriteInLockQueue()
  2051. /* --------------------------------------------------------------------------------- */
  2052. /*       WE HAVE TO PLACE IT SOMEWHERE IN THE SERIAL QUEUE INSTEAD.                  */
  2053. /* --------------------------------------------------------------------------------- */
  2054. void Dbacc::placeSerialQueueWrite(Signal* signal) 
  2055. {
  2056.   readWriteOpPtr = queOperPtr;
  2057.  PSQW_LOOP:
  2058.   if (readWriteOpPtr.p->nextSerialQue == RNIL) {
  2059.     jam();
  2060.     /* --------------------------------------------------------------------------------- */
  2061.     /* WE COULD NOT PUT IN ANY PARALLEL QUEUE. WE MUST PUT IT LAST IN THE SERIAL QUEUE.  */
  2062.     /* --------------------------------------------------------------------------------- */
  2063.     readWriteOpPtr.p->nextSerialQue = operationRecPtr.i;
  2064.     operationRecPtr.p->prevSerialQue = readWriteOpPtr.i;
  2065.     putOpInFragWaitQue(signal);
  2066.     return;
  2067.   }//if
  2068.   readWriteOpPtr.i = readWriteOpPtr.p->nextSerialQue;
  2069.   ptrCheckGuard(readWriteOpPtr, coprecsize, operationrec);
  2070.   if (getNoParallelTransaction(readWriteOpPtr.p) == 1) {
  2071.     /* --------------------------------------------------------------------------------- */
  2072.     /* THERE WAS ONLY ONE TRANSACTION INVOLVED IN THE PARALLEL QUEUE. IF THIS IS OUR     */
  2073.     /* TRANSACTION WE CAN STILL GET HOLD OF THE LOCK.                                    */
  2074.     /* --------------------------------------------------------------------------------- */
  2075.     if ((readWriteOpPtr.p->transId1 == operationRecPtr.p->transId1) && 
  2076.         (readWriteOpPtr.p->transId2 == operationRecPtr.p->transId2)) {
  2077.       jam();
  2078.       /* --------------------------------------------------------------------------------- */
  2079.       /* WE ARE PERFORMING AN UPDATE OR DELETE IN THE SAME TRANSACTION WHERE WE ALREADY    */
  2080.       /* PREVIOUSLY HAVE EXECUTED AN OPERATION. INSERT-DELETE, READ-UPDATE, READ-READ,     */
  2081.       /* UPDATE-UPDATE, UPDATE-DELETE, READ-DELETE, INSERT-READ, INSERT-UPDATE ARE ALLOWED */
  2082.       /* COMBINATIONS. A NEW INSERT AFTER A DELETE IS NOT ALLOWED AND SUCH AN INSERT WILL  */
  2083.       /* GO TO THE SERIAL LOCK QUEUE WHICH IT WILL NOT LEAVE UNTIL A TIME-OUT AND THE      */
  2084.       /* TRANSACTION IS ABORTED. READS AND UPDATES AFTER DELETES IS ALSO NOT ALLOWED.      */
  2085.       /* --------------------------------------------------------------------------------- */
  2086.       mlpqOperPtr = readWriteOpPtr;
  2087.       moveLastParallelQueueWrite(signal);
  2088.       readWriteOpPtr = mlpqOperPtr;
  2089.       operationRecPtr.p->prevParallelQue = readWriteOpPtr.i;
  2090.       readWriteOpPtr.p->nextParallelQue = operationRecPtr.i;
  2091.       operationRecPtr.p->localdata[0] = readWriteOpPtr.p->localdata[0];
  2092.       operationRecPtr.p->localdata[1] = readWriteOpPtr.p->localdata[1];
  2093.       putOpInFragWaitQue(signal);
  2094.       return;
  2095.     }//if
  2096.   }//if
  2097.   goto PSQW_LOOP;
  2098. }//Dbacc::placeSerialQueueWrite()
  2099. /* ------------------------------------------------------------------------- */
  2100. /* ACC KEYREQ END                                                            */
  2101. /* ------------------------------------------------------------------------- */
  2102. void Dbacc::acckeyref1Lab(Signal* signal, Uint32 result_code) 
  2103. {
  2104.   if (operationRecPtr.p->keyinfoPage != RNIL) {
  2105.     jam();
  2106.     rpPageptr.i = operationRecPtr.p->keyinfoPage;
  2107.     ptrCheckGuard(rpPageptr, cpagesize, page8);
  2108.     releasePage(signal);
  2109.     operationRecPtr.p->keyinfoPage = RNIL;
  2110.   }//if
  2111.   operationRecPtr.p->transactionstate = WAIT_COMMIT_ABORT;
  2112.   /* ************************<< */
  2113.   /* ACCKEYREF                  */
  2114.   /* ************************<< */
  2115.   signal->theData[0] = cminusOne;
  2116.   signal->theData[1] = result_code;
  2117.   return;
  2118. }//Dbacc::acckeyref1Lab()
  2119. /* ******************--------------------------------------------------------------- */
  2120. /* ACCMINUPDATE                                      UPDATE LOCAL KEY REQ            */
  2121. /*  DESCRIPTION: UPDATES LOCAL KEY OF AN ELEMENTS IN THE HASH TABLE                  */
  2122. /*               THIS SIGNAL IS WAITED AFTER ANY INSERT REQ                          */
  2123. /*          ENTER ACCMINUPDATE WITH                    SENDER: LQH,    LEVEL B       */
  2124. /*                    OPERATION_REC_PTR,               OPERATION RECORD PTR          */
  2125. /*                    CLOCALKEY(0),                    LOCAL KEY 1                   */
  2126. /*                    CLOCALKEY(1)                     LOCAL KEY 2                   */
  2127. /* ******************--------------------------------------------------------------- */
  2128. void Dbacc::execACCMINUPDATE(Signal* signal) 
  2129. {
  2130.   Page8Ptr ulkPageidptr;
  2131.   Uint32 tulkLocalPtr;
  2132.   Uint32 tlocalkey1, tlocalkey2;
  2133.   Uint32 TlogStart;
  2134.   jamEntry();
  2135.   operationRecPtr.i = signal->theData[0];
  2136.   tlocalkey1 = signal->theData[1];
  2137.   tlocalkey2 = signal->theData[2];
  2138.   ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
  2139.   if (operationRecPtr.p->transactionstate == ACTIVE) {
  2140.     fragrecptr.i = operationRecPtr.p->fragptr;
  2141.     ulkPageidptr.i = operationRecPtr.p->elementPage;
  2142.     tulkLocalPtr = operationRecPtr.p->elementPointer + operationRecPtr.p->elementIsforward;
  2143.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2144.     ptrCheckGuard(ulkPageidptr, cpagesize, page8);
  2145.     if (fragrecptr.p->createLcp == ZTRUE) {
  2146.       //----------------------------------------------------------
  2147.       // To avoid undo log the element header we take care to only
  2148.       // undo log the local key part.
  2149.       //----------------------------------------------------------
  2150.       if (operationRecPtr.p->elementIsforward == 1) {
  2151.         jam();
  2152.         TlogStart = tulkLocalPtr;
  2153.       } else {
  2154.         jam();
  2155.         TlogStart = tulkLocalPtr - fragrecptr.p->localkeylen + 1;
  2156.       }//if
  2157.       datapageptr.p = ulkPageidptr.p;
  2158.       cundoinfolength = fragrecptr.p->localkeylen;
  2159.       cundoElemIndex = TlogStart;
  2160.       undoWritingProcess(signal);
  2161.     }//if
  2162.     dbgWord32(ulkPageidptr, tulkLocalPtr, tlocalkey1);
  2163.     arrGuard(tulkLocalPtr, 2048);
  2164.     ulkPageidptr.p->word32[tulkLocalPtr] = tlocalkey1;
  2165.     operationRecPtr.p->localdata[0] = tlocalkey1;
  2166.     if (fragrecptr.p->localkeylen == 1) {
  2167.       return;
  2168.     } else if (fragrecptr.p->localkeylen == 2) {
  2169.       jam();
  2170.       tulkLocalPtr = tulkLocalPtr + operationRecPtr.p->elementIsforward;
  2171.       operationRecPtr.p->localdata[1] = tlocalkey2;
  2172.       dbgWord32(ulkPageidptr, tulkLocalPtr, tlocalkey2);
  2173.       arrGuard(tulkLocalPtr, 2048);
  2174.       ulkPageidptr.p->word32[tulkLocalPtr] = tlocalkey2;
  2175.       return;
  2176.     } else {
  2177.       jam();
  2178.     }//if
  2179.   }//if
  2180.   ndbrequire(false);
  2181. }//Dbacc::execACCMINUPDATE()
  2182. /* ******************--------------------------------------------------------------- */
  2183. /* ACC_COMMITREQ                                        COMMIT  TRANSACTION          */
  2184. /*                                                     SENDER: LQH,    LEVEL B       */
  2185. /*       INPUT:  OPERATION_REC_PTR ,                                                 */
  2186. /* ******************--------------------------------------------------------------- */
  2187. void Dbacc::execACC_COMMITREQ(Signal* signal) 
  2188. {
  2189.   Uint8 Toperation;
  2190.   jamEntry();
  2191.   operationRecPtr.i = signal->theData[0];
  2192.   ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
  2193.   ndbrequire(operationRecPtr.p->transactionstate == ACTIVE);
  2194.   fragrecptr.i = operationRecPtr.p->fragptr;
  2195.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2196.   commitOperation(signal);
  2197.   Toperation = operationRecPtr.p->operation;
  2198.   operationRecPtr.p->transactionstate = IDLE;
  2199.   operationRecPtr.p->operation = ZUNDEFINED_OP;
  2200.   if(Toperation != ZREAD){
  2201.     rootfragrecptr.p->m_commit_count++;
  2202.     if (Toperation != ZINSERT) {
  2203.       if (Toperation != ZDELETE) {
  2204. return;
  2205.       } else {
  2206. jam();
  2207. rootfragrecptr.i = fragrecptr.p->myroot;
  2208. ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  2209. rootfragrecptr.p->noOfElements--;
  2210. fragrecptr.p->slack += operationRecPtr.p->insertDeleteLen;
  2211. if (fragrecptr.p->slack > fragrecptr.p->slackCheck) { 
  2212.           /* TIME FOR JOIN BUCKETS PROCESS */
  2213.   if (fragrecptr.p->expandCounter > 0) {
  2214.     if (fragrecptr.p->expandFlag < 2) {
  2215.       jam();
  2216.       signal->theData[0] = fragrecptr.i;
  2217.       signal->theData[1] = fragrecptr.p->p;
  2218.       signal->theData[2] = fragrecptr.p->maxp;
  2219.       signal->theData[3] = fragrecptr.p->expandFlag;
  2220.       fragrecptr.p->expandFlag = 2;
  2221.       sendSignal(cownBlockref, GSN_SHRINKCHECK2, signal, 4, JBB);
  2222.     }//if
  2223.   }//if
  2224. }//if
  2225.       }//if
  2226.     } else {
  2227.       jam();  /* EXPAND PROCESS HANDLING */
  2228.       rootfragrecptr.i = fragrecptr.p->myroot;
  2229.       ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  2230.       rootfragrecptr.p->noOfElements++;
  2231.       fragrecptr.p->slack -= operationRecPtr.p->insertDeleteLen;
  2232.       if (fragrecptr.p->slack >= (1u << 31)) { 
  2233. /* IT MEANS THAT IF SLACK < ZERO */
  2234. if (fragrecptr.p->expandFlag == 0) {
  2235.   jam();
  2236.   fragrecptr.p->expandFlag = 2;
  2237.   signal->theData[0] = fragrecptr.i;
  2238.   signal->theData[1] = fragrecptr.p->p;
  2239.   signal->theData[2] = fragrecptr.p->maxp;
  2240.   sendSignal(cownBlockref, GSN_EXPANDCHECK2, signal, 3, JBB);
  2241. }//if
  2242.       }//if
  2243.     }//if
  2244.   }
  2245.   return;
  2246. }//Dbacc::execACC_COMMITREQ()
  2247. /* ******************--------------------------------------------------------------- */
  2248. /* ACC ABORT REQ                           ABORT ALL OPERATION OF THE TRANSACTION    */
  2249. /* ******************------------------------------+                                 */
  2250. /*   SENDER: LQH,    LEVEL B       */
  2251. /* ******************--------------------------------------------------------------- */
  2252. /* ACC ABORT REQ                                                 ABORT TRANSACTION   */
  2253. /* ******************------------------------------+                                 */
  2254. /*   SENDER: LQH,    LEVEL B       */
  2255. void Dbacc::execACC_ABORTREQ(Signal* signal) 
  2256. {
  2257.   jamEntry();
  2258.   accAbortReqLab(signal, true);
  2259. }//Dbacc::execACC_ABORTREQ()
  2260. void Dbacc::accAbortReqLab(Signal* signal, bool sendConf)
  2261. {
  2262.   operationRecPtr.i = signal->theData[0];
  2263.   ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
  2264.   tresult = 0; /*                ZFALSE           */
  2265.   if ((operationRecPtr.p->transactionstate == ACTIVE) ||
  2266.       (operationRecPtr.p->transactionstate == WAIT_COMMIT_ABORT)) {
  2267.     jam();
  2268.     fragrecptr.i = operationRecPtr.p->fragptr;
  2269.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2270.     operationRecPtr.p->transactionstate = ABORT;
  2271.     abortOperation(signal);
  2272.   } else {
  2273.     ndbrequire(operationRecPtr.p->transactionstate == IDLE);
  2274.     jam();
  2275.   }//if
  2276.   operationRecPtr.p->transactionstate = IDLE;
  2277.   operationRecPtr.p->operation = ZUNDEFINED_OP;
  2278.   if (! sendConf)
  2279.     return;
  2280.   signal->theData[0] = operationRecPtr.p->userptr;
  2281.   sendSignal(operationRecPtr.p->userblockref, GSN_ACC_ABORTCONF, signal, 1, JBB);
  2282.   return;
  2283. }//Dbacc::accAbortReqLab()
  2284. /*
  2285.  * Lock or unlock tuple.
  2286.  */
  2287. void Dbacc::execACC_LOCKREQ(Signal* signal)
  2288. {
  2289.   jamEntry();
  2290.   AccLockReq* sig = (AccLockReq*)signal->getDataPtrSend();
  2291.   AccLockReq reqCopy = *sig;
  2292.   AccLockReq* const req = &reqCopy;
  2293.   Uint32 lockOp = (req->requestInfo & 0xFF);
  2294.   if (lockOp == AccLockReq::LockShared ||
  2295.       lockOp == AccLockReq::LockExclusive) {
  2296.     jam();
  2297.     // find table
  2298.     tabptr.i = req->tableId;
  2299.     ptrCheckGuard(tabptr, ctablesize, tabrec);
  2300.     // find fragment (TUX will know it)
  2301.     if (req->fragPtrI == RNIL) {
  2302.       for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
  2303.         jam();
  2304.         if (tabptr.p->fragptrholder[i] != RNIL) {
  2305.           rootfragrecptr.i = tabptr.p->fragptrholder[i];
  2306.           ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
  2307.           if (rootfragrecptr.p->fragmentid[0] == req->fragId) {
  2308.             jam();
  2309.             req->fragPtrI = rootfragrecptr.p->fragmentptr[0];
  2310.             break;
  2311.           }
  2312.           if (rootfragrecptr.p->fragmentid[1] == req->fragId) {
  2313.             jam();
  2314.             req->fragPtrI = rootfragrecptr.p->fragmentptr[1];
  2315.             break;
  2316.           }
  2317.         }
  2318.       }
  2319.     }
  2320.     fragrecptr.i = req->fragPtrI;
  2321.     ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2322.     ndbrequire(req->fragId == fragrecptr.p->myfid);
  2323.     // caller must be explicit here
  2324.     ndbrequire(req->accOpPtr == RNIL);
  2325.     // seize operation to hold the lock
  2326.     if (cfreeopRec != RNIL) {
  2327.       jam();
  2328.       seizeOpRec(signal);
  2329.       // init as in ACCSEIZEREQ
  2330.       operationRecPtr.p->userptr = req->userPtr;
  2331.       operationRecPtr.p->userblockref = req->userRef;
  2332.       operationRecPtr.p->operation = ZUNDEFINED_OP;
  2333.       operationRecPtr.p->transactionstate = IDLE;
  2334.       // do read with lock via ACCKEYREQ
  2335.       Uint32 lockMode = (lockOp == AccLockReq::LockShared) ? 0 : 1;
  2336.       Uint32 opCode = ZSCAN_OP;
  2337.       signal->theData[0] = operationRecPtr.i;
  2338.       signal->theData[1] = fragrecptr.i;
  2339.       signal->theData[2] = opCode | (lockMode << 4) | (1u << 31);
  2340.       signal->theData[3] = req->hashValue;
  2341.       signal->theData[4] = 1;   // fake primKeyLen
  2342.       signal->theData[5] = req->transId1;
  2343.       signal->theData[6] = req->transId2;
  2344.       signal->theData[7] = req->tupAddr;
  2345.       EXECUTE_DIRECT(DBACC, GSN_ACCKEYREQ, signal, 8);
  2346.       // translate the result
  2347.       if (signal->theData[0] < RNIL) {
  2348.         jam();
  2349.         req->returnCode = AccLockReq::Success;
  2350.         req->accOpPtr = operationRecPtr.i;
  2351.       } else if (signal->theData[0] == RNIL) {
  2352.         jam();
  2353.         req->returnCode = AccLockReq::IsBlocked;
  2354.         req->accOpPtr = operationRecPtr.i;
  2355.       } else {
  2356.         ndbrequire(signal->theData[0] == (UintR)-1);
  2357.         releaseOpRec(signal);
  2358.         req->returnCode = AccLockReq::Refused;
  2359.         req->accOpPtr = RNIL;
  2360.       }
  2361.     } else {
  2362.       jam();
  2363.       req->returnCode = AccLockReq::NoFreeOp;
  2364.     }
  2365.     *sig = *req;
  2366.     return;
  2367.   }
  2368.   operationRecPtr.i = req->accOpPtr;
  2369.   ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
  2370.   fragrecptr.i = operationRecPtr.p->fragptr;
  2371.   ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
  2372.   if (fragrecptr.p->keyLength == 0 &&
  2373.       // should test some state variable
  2374.       operationRecPtr.p->elementPage != RNIL) {
  2375.     jam();
  2376.     // re-compute long key vars
  2377.     Page8Ptr tPageptr;
  2378.     tPageptr.i = operationRecPtr.p->elementPage;
  2379.     ptrCheckGuard(tPageptr, cpagesize, page8);
  2380.     Uint32 tKeyptr =
  2381.       operationRecPtr.p->elementPointer +
  2382.       operationRecPtr.p->elementIsforward *
  2383.       (ZELEM_HEAD_SIZE + fragrecptr.p->localkeylen);
  2384.     tslcPageIndex = tPageptr.p->word32[tKeyptr] & 0x3ff;
  2385.     tslcPagedir = tPageptr.p->word32[tKeyptr] >> 10;
  2386.     searchLongKey(signal, false);
  2387.   }
  2388.   if (lockOp == AccLockReq::Unlock) {
  2389.     jam();
  2390.     // do unlock via ACC_COMMITREQ (immediate)
  2391.     signal->theData[0] = req->accOpPtr;
  2392.     EXECUTE_DIRECT(DBACC, GSN_ACC_COMMITREQ, signal, 1);
  2393.     releaseOpRec(signal);
  2394.     req->returnCode = AccLockReq::Success;
  2395.     *sig = *req;
  2396.     return;
  2397.   }
  2398.   if (lockOp == AccLockReq::Abort) {
  2399.     jam();
  2400.     // do abort via ACC_ABORTREQ (immediate)
  2401.     signal->theData[0] = req->accOpPtr;
  2402.     accAbortReqLab(signal, false);
  2403.     releaseOpRec(signal);
  2404.     req->returnCode = AccLockReq::Success;
  2405.     *sig = *req;
  2406.     return;
  2407.   }
  2408.   if (lockOp == AccLockReq::AbortWithConf) {
  2409.     jam();
  2410.     // do abort via ACC_ABORTREQ (with conf signal)
  2411.     signal->theData[0] = req->accOpPtr;
  2412.     accAbortReqLab(signal, true);
  2413.     releaseOpRec(signal);
  2414.     req->returnCode = AccLockReq::Success;
  2415.     *sig = *req;
  2416.     return;
  2417.   }
  2418.   ndbrequire(false);
  2419. }
  2420. /* --------------------------------------------------------------------------------- */
  2421. /* --------------------------------------------------------------------------------- */
  2422. /* --------------------------------------------------------------------------------- */
  2423. /*                                                                                   */
  2424. /*       END OF EXECUTE OPERATION MODULE                                             */
  2425. /*                                                                                   */
  2426. /* --------------------------------------------------------------------------------- */
  2427. /* --------------------------------------------------------------------------------- */
  2428. /* --------------------------------------------------------------------------------- */
  2429. /* --------------------------------------------------------------------------------- */
  2430. /*                                                                                   */
  2431. /*       MODULE:         INSERT                                                      */
  2432. /*               THE FOLLOWING SUBROUTINES ARE ONLY USED BY INSERT_ELEMENT. THIS     */
  2433. /*               ROUTINE IS THE SOLE INTERFACE TO INSERT ELEMENTS INTO THE INDEX.    */
  2434. /*               CURRENT USERS ARE INSERT REQUESTS, EXPAND CONTAINER AND SHRINK      */
  2435. /*               CONTAINER.                                                          */
  2436. /*                                                                                   */
  2437. /*               THE FOLLOWING SUBROUTINES ARE INCLUDED IN THIS MODULE:              */
  2438. /*               INSERT_ELEMENT                                                      */
  2439. /*               INSERT_CONTAINER                                                    */
  2440. /*               ADDNEWCONTAINER                                                     */
  2441. /*               GETFREELIST                                                         */
  2442. /*               INCREASELISTCONT                                                    */
  2443. /*               SEIZE_LEFTLIST                                                      */
  2444. /*               SEIZE_RIGHTLIST                                                     */
  2445. /*                                                                                   */
  2446. /*               THESE ROUTINES ARE ONLY USED BY THIS MODULE AND BY NO ONE ELSE.     */
  2447. /*               ALSO THE ROUTINES MAKE NO USE OF ROUTINES IN OTHER MODULES.         */
  2448. /*               TAKE_REC_OUT_OF_FREE_OVERPAGE AND RELEASE_OVERFLOW_REC ARE          */
  2449. /*               EXCEPTIONS TO THIS RULE.                                            */
  2450. /*                                                                                   */
  2451. /*               THE ONLY SHORT-LIVED VARIABLES USED IN OTHER PARTS OF THE BLOCK ARE */
  2452. /*               THOSE DEFINED AS INPUT AND OUTPUT IN INSERT_ELEMENT                 */
  2453. /*               SHORT-LIVED VARIABLES INCLUDE TEMPORARY VARIABLES, COMMON VARIABLES */
  2454. /*               AND POINTER VARIABLES.                                              */
  2455. /*               THE ONLY EXCEPTION TO THIS RULE IS FRAGRECPTR WHICH POINTS TO THE   */
  2456. /*               FRAGMENT RECORD. THIS IS MORE LESS STATIC ALWAYS DURING A SIGNAL    */
  2457. /*               EXECUTION.                                                          */
  2458. /*                                                                                   */
  2459. /* --------------------------------------------------------------------------------- */
  2460. /* --------------------------------------------------------------------------------- */
  2461. /* --------------------------------------------------------------------------------- */
  2462. /* INSERT_ELEMENT                                                                    */
  2463. /*       INPUT:                                                                      */
  2464. /*               IDR_PAGEPTR (POINTER TO THE ACTIVE PAGE REC)                        */
  2465. /*               TIDR_PAGEINDEX (INDEX OF THE CONTAINER)                             */
  2466. /*               TIDR_FORWARD (DIRECTION FORWARD OR BACKWARD)                        */
  2467. /*               TIDR_ELEMHEAD (HEADER OF ELEMENT TO BE INSERTED                     */
  2468. /*               CIDR_KEYS(ARRAY OF TUPLE KEYS)                                      */
  2469. /*               CLOCALKEY(ARRAY OF LOCAL KEYS).                                     */
  2470. /*               FRAGRECPTR                                                          */
  2471. /*               IDR_OPERATION_REC_PTR                                               */
  2472. /*               TIDR_KEY_LEN                                                        */
  2473. /*                                                                                   */
  2474. /*       OUTPUT:                                                                     */
  2475. /*               TIDR_PAGEINDEX (PAGE INDEX OF INSERTED ELEMENT)                     */
  2476. /*               IDR_PAGEPTR    (PAGE POINTER OF INSERTED ELEMENT)                   */
  2477. /*               TIDR_FORWARD   (CONTAINER DIRECTION OF INSERTED ELEMENT)            */
  2478. /*               NONE                                                                */
  2479. /* --------------------------------------------------------------------------------- */
  2480. void Dbacc::insertElement(Signal* signal) 
  2481. {
  2482.   DirRangePtr inrOverflowrangeptr;
  2483.   DirectoryarrayPtr inrOverflowDirptr;
  2484.   OverflowRecordPtr inrOverflowRecPtr;
  2485.   Page8Ptr inrNewPageptr;
  2486.   Uint32 tinrNextSamePage;
  2487.   Uint32 tinrTmp;
  2488.   do {
  2489.     insertContainer(signal);
  2490.     if (tidrResult != ZFALSE) {
  2491.       jam();
  2492.       return;
  2493.       /* INSERTION IS DONE, OR */
  2494.       /* AN ERROR IS DETECTED  */
  2495.     }//if
  2496.     if (((tidrContainerhead >> 7) & 0x3) != 0) {
  2497.       tinrNextSamePage = (tidrContainerhead >> 9) & 0x1; /* CHECK BIT FOR CHECKING WHERE */
  2498.       /* THE NEXT CONTAINER IS IN THE SAME PAGE */
  2499.       tidrPageindex = tidrContainerhead & 0x7f; /* NEXT CONTAINER PAGE INDEX 7 BITS */
  2500.       if (((tidrContainerhead >> 7) & 3) == ZLEFT) {
  2501.         jam();
  2502.         tidrForward = ZTRUE;
  2503.       } else if (((tidrContainerhead >> 7) & 3) == ZRIGHT) {
  2504.         jam();
  2505.         tidrForward = cminusOne;
  2506.       } else {
  2507.         ndbrequire(false);
  2508.         return;
  2509.       }//if
  2510.       if (tinrNextSamePage == ZFALSE) {
  2511.         jam();     /* NEXT CONTAINER IS IN AN OVERFLOW PAGE */
  2512.         tinrTmp = idrPageptr.p->word32[tidrContainerptr + 1];
  2513.         inrOverflowrangeptr.i = fragrecptr.p->overflowdir;
  2514.         ptrCheckGuard(inrOverflowrangeptr, cdirrangesize, dirRange);
  2515.         arrGuard((tinrTmp >> 8), 256);
  2516.         inrOverflowDirptr.i = inrOverflowrangeptr.p->dirArray[tinrTmp >> 8];
  2517.         ptrCheckGuard(inrOverflowDirptr, cdirarraysize, directoryarray);
  2518.         idrPageptr.i = inrOverflowDirptr.p->pagep[tinrTmp & 0xff];
  2519.         ptrCheckGuard(idrPageptr, cpagesize, page8);
  2520.       }//if
  2521.       ndbrequire(tidrPageindex < ZEMPTYLIST);
  2522.     } else {
  2523.       break;
  2524.     }//if
  2525.   } while (1);
  2526.   gflPageptr.p = idrPageptr.p;
  2527.   getfreelist(signal);
  2528.   if (tgflPageindex == ZEMPTYLIST) {
  2529.     jam();
  2530.     /* NO FREE BUFFER IS FOUND */
  2531.     if (fragrecptr.p->firstOverflowRec == RNIL) {
  2532.       jam();
  2533.       allocOverflowPage(signal);
  2534.       ndbrequire(tresult <= ZLIMIT_OF_ERROR);
  2535.     }//if
  2536.     inrOverflowRecPtr.i = fragrecptr.p->firstOverflowRec;
  2537.     ptrCheckGuard(inrOverflowRecPtr, coverflowrecsize, overflowRecord);
  2538.     inrNewPageptr.i = inrOverflowRecPtr.p->overpage;
  2539.     ptrCheckGuard(inrNewPageptr, cpagesize, page8);
  2540.     gflPageptr.p = inrNewPageptr.p;
  2541.     getfreelist(signal);
  2542.     ndbrequire(tgflPageindex != ZEMPTYLIST);
  2543.     tancNext = 0;
  2544.   } else {
  2545.     jam();
  2546.     inrNewPageptr = idrPageptr;
  2547.     tancNext = 1;
  2548.   }//if
  2549.   tslUpdateHeader = ZTRUE;
  2550.   tslPageindex = tgflPageindex;
  2551.   slPageptr.p = inrNewPageptr.p;
  2552.   if (tgflBufType == ZLEFT) {
  2553.     seizeLeftlist(signal);
  2554.     tidrForward = ZTRUE;
  2555.   } else {
  2556.     seizeRightlist(signal);
  2557.     tidrForward = cminusOne;
  2558.   }//if
  2559.   tancPageindex = tgflPageindex;
  2560.   tancPageid = inrNewPageptr.p->word32[ZPOS_PAGE_ID];
  2561.   tancBufType = tgflBufType;
  2562.   tancContainerptr = tidrContainerptr;
  2563.   ancPageptr.p = idrPageptr.p;
  2564.   addnewcontainer(signal);
  2565.   idrPageptr = inrNewPageptr;
  2566.   tidrPageindex = tgflPageindex;
  2567.   insertContainer(signal);
  2568.   ndbrequire(tidrResult == ZTRUE);
  2569. }//Dbacc::insertElement()
  2570. /* --------------------------------------------------------------------------------- */
  2571. /* INSERT_CONTAINER                                                                  */
  2572. /*           INPUT:                                                                  */
  2573. /*               IDR_PAGEPTR (POINTER TO THE ACTIVE PAGE REC)                        */
  2574. /*               TIDR_PAGEINDEX (INDEX OF THE CONTAINER)                             */
  2575. /*               TIDR_FORWARD (DIRECTION FORWARD OR BACKWARD)                        */
  2576. /*               TIDR_ELEMHEAD (HEADER OF ELEMENT TO BE INSERTED                     */
  2577. /*               CKEYS(ARRAY OF TUPLE KEYS)                                          */
  2578. /*               CLOCALKEY(ARRAY 0F LOCAL KEYS).                                     */
  2579. /*               TIDR_KEY_LEN                                                        */
  2580. /*               FRAGRECPTR                                                          */
  2581. /*               IDR_OPERATION_REC_PTR                                               */
  2582. /*           OUTPUT:                                                                 */
  2583. /*               TIDR_RESULT (ZTRUE FOR SUCCESS AND ZFALSE OTHERWISE)                */
  2584. /*               TIDR_CONTAINERHEAD (HEADER OF CONTAINER)                            */
  2585. /*               TIDR_CONTAINERPTR (POINTER TO CONTAINER HEADER)                     */
  2586. /*                                                                                   */
  2587. /*           DESCRIPTION:                                                            */
  2588. /*               THE FREE AREA OF THE CONTAINER WILL BE CALCULATED. IF IT IS         */
  2589. /*               LARGER THAN OR EQUAL THE ELEMENT LENGTH. THE ELEMENT WILL BE        */
  2590. /*               INSERT IN THE CONTAINER AND CONTAINER HEAD WILL BE UPDATED.         */
  2591. /*               THIS ROUTINE ALWAYS DEALS WITH ONLY ONE CONTAINER AND DO NEVER      */
  2592. /*               START ANYTHING OUTSIDE OF THIS CONTAINER.                           */
  2593. /*                                                                                   */
  2594. /*       SHORT FORM: IDR                                                             */
  2595. /* --------------------------------------------------------------------------------- */
  2596. void Dbacc::insertContainer(Signal* signal) 
  2597. {
  2598.   Uint32 tidrContainerlen;
  2599.   Uint32 tidrConfreelen;
  2600.   Uint32 tidrNextSide;
  2601.   Uint32 tidrNextConLen;
  2602.   Uint32 tidrIndex;
  2603.   Uint32 tidrInputIndex;