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

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 DBTUX_MAINT_CPP
  14. #include "Dbtux.hpp"
  15. /*
  16.  * Maintain index.
  17.  */
  18. void
  19. Dbtux::execTUX_MAINT_REQ(Signal* signal)
  20. {
  21.   jamEntry();
  22.   TuxMaintReq* const sig = (TuxMaintReq*)signal->getDataPtrSend();
  23.   // ignore requests from redo log
  24.   if (c_internalStartPhase < 6 &&
  25.       c_typeOfStart != NodeState::ST_NODE_RESTART &&
  26.       c_typeOfStart != NodeState::ST_INITIAL_NODE_RESTART) {
  27.     jam();
  28. #ifdef VM_TRACE
  29.     if (debugFlags & DebugMaint) {
  30.       TupLoc tupLoc(sig->pageId, sig->pageOffset);
  31.       debugOut << "opInfo=" << hex << sig->opInfo;
  32.       debugOut << " tableId=" << dec << sig->tableId;
  33.       debugOut << " indexId=" << dec << sig->indexId;
  34.       debugOut << " fragId=" << dec << sig->fragId;
  35.       debugOut << " tupLoc=" << tupLoc;
  36.       debugOut << " tupVersion=" << dec << sig->tupVersion;
  37.       debugOut << " -- ignored at ISP=" << dec << c_internalStartPhase;
  38.       debugOut << " TOS=" << dec << c_typeOfStart;
  39.       debugOut << endl;
  40.     }
  41. #endif
  42.     sig->errorCode = 0;
  43.     return;
  44.   }
  45.   TuxMaintReq reqCopy = *sig;
  46.   TuxMaintReq* const req = &reqCopy;
  47.   const Uint32 opCode = req->opInfo & 0xFF;
  48.   const Uint32 opFlag = req->opInfo >> 8;
  49.   // get the index
  50.   IndexPtr indexPtr;
  51.   c_indexPool.getPtr(indexPtr, req->indexId);
  52.   ndbrequire(indexPtr.p->m_tableId == req->tableId);
  53.   // get base fragment id and extra bits
  54.   const Uint32 fragOff = indexPtr.p->m_fragOff;
  55.   const Uint32 fragId = req->fragId & ((1 << fragOff) - 1);
  56.   const Uint32 fragBit = req->fragId >> fragOff;
  57.   // get the fragment
  58.   FragPtr fragPtr;
  59.   fragPtr.i = RNIL;
  60.   for (unsigned i = 0; i < indexPtr.p->m_numFrags; i++) {
  61.     jam();
  62.     if (indexPtr.p->m_fragId[i] == fragId) {
  63.       jam();
  64.       c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]);
  65.       break;
  66.     }
  67.   }
  68.   ndbrequire(fragPtr.i != RNIL);
  69.   Frag& frag = *fragPtr.p;
  70.   // set up index keys for this operation
  71.   setKeyAttrs(frag);
  72.   // set up search entry
  73.   TreeEnt ent;
  74.   ent.m_tupLoc = TupLoc(req->pageId, req->pageOffset);
  75.   ent.m_tupVersion = req->tupVersion;
  76.   ent.m_fragBit = fragBit;
  77.   // read search key
  78.   readKeyAttrs(frag, ent, 0, c_searchKey);
  79.   if (! frag.m_storeNullKey) {
  80.     // check if all keys are null
  81.     const unsigned numAttrs = frag.m_numAttrs;
  82.     bool allNull = true;
  83.     for (unsigned i = 0; i < numAttrs; i++) {
  84.       if (c_searchKey[i] != 0) {
  85.         jam();
  86.         allNull = false;
  87.         break;
  88.       }
  89.     }
  90.     if (allNull) {
  91.       jam();
  92.       req->errorCode = 0;
  93.       *sig = *req;
  94.       return;
  95.     }
  96.   }
  97. #ifdef VM_TRACE
  98.   if (debugFlags & DebugMaint) {
  99.     debugOut << "opCode=" << dec << opCode;
  100.     debugOut << " opFlag=" << dec << opFlag;
  101.     debugOut << " tableId=" << dec << req->tableId;
  102.     debugOut << " indexId=" << dec << req->indexId;
  103.     debugOut << " fragId=" << dec << req->fragId;
  104.     debugOut << " entry=" << ent;
  105.     debugOut << endl;
  106.   }
  107. #endif
  108.   // do the operation
  109.   req->errorCode = 0;
  110.   TreePos treePos;
  111.   switch (opCode) {
  112.   case TuxMaintReq::OpAdd:
  113.     jam();
  114.     searchToAdd(frag, c_searchKey, ent, treePos);
  115. #ifdef VM_TRACE
  116.     if (debugFlags & DebugMaint) {
  117.       debugOut << treePos << (treePos.m_match ? " - error" : "") << endl;
  118.     }
  119. #endif
  120.     if (treePos.m_match) {
  121.       jam();
  122.       // there is no "Building" state so this will have to do
  123.       if (indexPtr.p->m_state == Index::Online) {
  124.         jam();
  125.         req->errorCode = TuxMaintReq::SearchError;
  126.       }
  127.       break;
  128.     }
  129.     /*
  130.      * At most one new node is inserted in the operation.  Pre-allocate
  131.      * it so that the operation cannot fail.
  132.      */
  133.     if (frag.m_freeLoc == NullTupLoc) {
  134.       jam();
  135.       NodeHandle node(frag);
  136.       req->errorCode = allocNode(signal, node);
  137.       if (req->errorCode != 0) {
  138.         jam();
  139.         break;
  140.       }
  141.       // link to freelist
  142.       node.setLink(0, frag.m_freeLoc);
  143.       frag.m_freeLoc = node.m_loc;
  144.       ndbrequire(frag.m_freeLoc != NullTupLoc);
  145.     }
  146.     treeAdd(frag, treePos, ent);
  147.     break;
  148.   case TuxMaintReq::OpRemove:
  149.     jam();
  150.     searchToRemove(frag, c_searchKey, ent, treePos);
  151. #ifdef VM_TRACE
  152.     if (debugFlags & DebugMaint) {
  153.       debugOut << treePos << (! treePos.m_match ? " - error" : "") << endl;
  154.     }
  155. #endif
  156.     if (! treePos.m_match) {
  157.       jam();
  158.       // there is no "Building" state so this will have to do
  159.       if (indexPtr.p->m_state == Index::Online) {
  160.         jam();
  161.         req->errorCode = TuxMaintReq::SearchError;
  162.       }
  163.       break;
  164.     }
  165.     treeRemove(frag, treePos);
  166.     break;
  167.   default:
  168.     ndbrequire(false);
  169.     break;
  170.   }
  171. #ifdef VM_TRACE
  172.   if (debugFlags & DebugTree) {
  173.     printTree(signal, frag, debugOut);
  174.   }
  175. #endif
  176.   // copy back
  177.   *sig = *req;
  178. }