MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DbtuxMaint.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #define DBTUX_MAINT_CPP
19 #include "Dbtux.hpp"
20 
21 /*
22  * Maintain index.
23  */
24 
25 void
26 Dbtux::execTUX_MAINT_REQ(Signal* signal)
27 {
28  jamEntry();
29  TuxMaintReq* const sig = (TuxMaintReq*)signal->getDataPtrSend();
30  // ignore requests from redo log
31  IndexPtr indexPtr;
32  c_indexPool.getPtr(indexPtr, sig->indexId);
33 
34  if (unlikely(! (indexPtr.p->m_state == Index::Online ||
35  indexPtr.p->m_state == Index::Building)))
36  {
37  jam();
38 #ifdef VM_TRACE
39  if (debugFlags & DebugMaint) {
40  TupLoc tupLoc(sig->pageId, sig->pageIndex);
41  debugOut << "opInfo=" << hex << sig->opInfo;
42  debugOut << " tableId=" << dec << sig->tableId;
43  debugOut << " indexId=" << dec << sig->indexId;
44  debugOut << " fragId=" << dec << sig->fragId;
45  debugOut << " tupLoc=" << tupLoc;
46  debugOut << " tupVersion=" << dec << sig->tupVersion;
47  debugOut << " -- ignored at ISP=" << dec << c_internalStartPhase;
48  debugOut << " TOS=" << dec << c_typeOfStart;
49  debugOut << endl;
50  }
51 #endif
52  sig->errorCode = 0;
53  return;
54  }
55 
56  TuxMaintReq reqCopy = *sig;
57  TuxMaintReq* const req = &reqCopy;
58  const Uint32 opCode = req->opInfo & 0xFF;
59  const Uint32 opFlag = req->opInfo >> 8;
60  // get the index
61  ndbrequire(indexPtr.p->m_tableId == req->tableId);
62  // get base fragment id and extra bits
63  const Uint32 fragId = req->fragId;
64  // get the fragment
65  FragPtr fragPtr;
66  findFrag(*indexPtr.p, fragId, fragPtr);
67  ndbrequire(fragPtr.i != RNIL);
68  Frag& frag = *fragPtr.p;
69  // set up search entry
70  TreeEnt ent;
71  ent.m_tupLoc = TupLoc(req->pageId, req->pageIndex);
72  ent.m_tupVersion = req->tupVersion;
73  // set up and read search key
74  KeyData searchKey(indexPtr.p->m_keySpec, false, 0);
75  searchKey.set_buf(c_ctx.c_searchKey, MaxAttrDataSize << 2);
76  readKeyAttrs(c_ctx, frag, ent, searchKey, indexPtr.p->m_numAttrs);
77  if (unlikely(! indexPtr.p->m_storeNullKey) &&
78  searchKey.get_null_cnt() == indexPtr.p->m_numAttrs) {
79  jam();
80  return;
81  }
82 #ifdef VM_TRACE
83  if (debugFlags & DebugMaint) {
84  debugOut << "opCode=" << dec << opCode;
85  debugOut << " opFlag=" << dec << opFlag;
86  debugOut << " tableId=" << dec << req->tableId;
87  debugOut << " indexId=" << dec << req->indexId;
88  debugOut << " fragId=" << dec << req->fragId;
89  debugOut << " entry=" << ent;
90  debugOut << endl;
91  }
92 #endif
93  // do the operation
94  req->errorCode = 0;
95  TreePos treePos;
96  bool ok;
97  switch (opCode) {
98  case TuxMaintReq::OpAdd:
99  jam();
100  ok = searchToAdd(c_ctx, frag, searchKey, ent, treePos);
101 #ifdef VM_TRACE
102  if (debugFlags & DebugMaint) {
103  debugOut << treePos << (! ok ? " - error" : "") << endl;
104  }
105 #endif
106  if (! ok) {
107  jam();
108  // there is no "Building" state so this will have to do
109  if (indexPtr.p->m_state == Index::Online) {
110  jam();
111  req->errorCode = TuxMaintReq::SearchError;
112  }
113  break;
114  }
115  /*
116  * At most one new node is inserted in the operation. Pre-allocate
117  * it so that the operation cannot fail.
118  */
119  if (frag.m_freeLoc == NullTupLoc) {
120  jam();
121  NodeHandle node(frag);
122  req->errorCode = allocNode(c_ctx, node);
123  if (req->errorCode != 0) {
124  jam();
125  break;
126  }
127  frag.m_freeLoc = node.m_loc;
128  ndbrequire(frag.m_freeLoc != NullTupLoc);
129  }
130  treeAdd(c_ctx, frag, treePos, ent);
131  frag.m_entryCount++;
132  frag.m_entryBytes += searchKey.get_data_len();
133  frag.m_entryOps++;
134  break;
135  case TuxMaintReq::OpRemove:
136  jam();
137  ok = searchToRemove(c_ctx, frag, searchKey, ent, treePos);
138 #ifdef VM_TRACE
139  if (debugFlags & DebugMaint) {
140  debugOut << treePos << (! ok ? " - error" : "") << endl;
141  }
142 #endif
143  if (! ok) {
144  jam();
145  // there is no "Building" state so this will have to do
146  if (indexPtr.p->m_state == Index::Online) {
147  jam();
148  req->errorCode = TuxMaintReq::SearchError;
149  }
150  break;
151  }
152  treeRemove(frag, treePos);
153  ndbrequire(frag.m_entryCount != 0);
154  frag.m_entryCount--;
155  frag.m_entryBytes -= searchKey.get_data_len();
156  frag.m_entryOps++;
157  break;
158  default:
159  ndbrequire(false);
160  break;
161  }
162 #ifdef VM_TRACE
163  if (debugFlags & DebugTree) {
164  printTree(signal, frag, debugOut);
165  }
166 #endif
167  // copy back
168  *sig = *req;
169 
170  //ndbrequire(c_keyAttrs[0] == c_keyAttrs[1]);
171  //ndbrequire(c_sqlCmp[0] == c_sqlCmp[1]);
172  //ndbrequire(c_searchKey[0] == c_searchKey[1]);
173  //ndbrequire(c_entryKey[0] == c_entryKey[1]);
174  //ndbrequire(c_dataBuffer[0] == c_dataBuffer[1]);
175 }