18 #define DBTUX_NODE_CPP
25 Dbtux::allocNode(TuxCtx& ctx, NodeHandle& node)
27 if (ERROR_INSERTED(12007)) {
29 CLEAR_ERROR_INSERT_VALUE;
30 return TuxMaintReq::NoMemError;
32 Frag& frag = node.m_frag;
33 Uint32 pageId = NullTupLoc.getPageId();
34 Uint32 pageOffset = NullTupLoc.getPageOffset();
36 int errorCode = c_tup->tuxAllocNode(ctx.jamBuffer,
37 frag.m_tupIndexFragPtrI,
38 pageId, pageOffset, node32);
39 thrjamEntry(ctx.jamBuffer);
41 thrjam(ctx.jamBuffer);
42 node.m_loc = TupLoc(pageId, pageOffset);
43 node.m_node =
reinterpret_cast<TreeNode*
>(node32);
44 ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0);
48 errorCode = TuxMaintReq::NoMemError;
59 Dbtux::freeNode(NodeHandle& node)
61 Frag& frag = node.m_frag;
62 Uint32 pageId = node.m_loc.getPageId();
63 Uint32 pageOffset = node.m_loc.getPageOffset();
64 Uint32* node32 =
reinterpret_cast<Uint32*
>(node.m_node);
65 c_tup->tuxFreeNode(frag.m_tupIndexFragPtrI,
66 pageId, pageOffset, node32);
69 node.m_loc = NullTupLoc;
77 Dbtux::selectNode(NodeHandle& node, TupLoc loc)
79 Frag& frag = node.m_frag;
80 ndbrequire(loc != NullTupLoc);
81 Uint32 pageId = loc.getPageId();
82 Uint32 pageOffset = loc.getPageOffset();
84 c_tup->tuxGetNode(frag.m_tupIndexFragPtrI, pageId, pageOffset, node32);
86 node.m_node =
reinterpret_cast<TreeNode*
>(node32);
87 ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0);
94 Dbtux::insertNode(NodeHandle& node)
96 Frag& frag = node.m_frag;
98 selectNode(node, frag.m_freeLoc);
99 frag.m_freeLoc = NullTupLoc;
100 new (node.m_node) TreeNode();
102 TreeHead& tree = frag.m_tree;
103 memset(node.getPref(), DataFillByte, tree.m_prefSize << 2);
104 TreeEnt* entList = tree.getEntList(node.m_node);
105 memset(entList, NodeFillByte, tree.m_maxOccup * (TreeEntSize << 2));
114 Dbtux::deleteNode(NodeHandle& node)
116 Frag& frag = node.m_frag;
117 ndbrequire(node.getOccup() == 0);
118 if (frag.m_freeLoc == NullTupLoc)
121 frag.m_freeLoc = node.m_loc;
123 node.m_loc = NullTupLoc;
138 Dbtux::freePreallocatedNode(Frag& frag)
140 if (frag.m_freeLoc != NullTupLoc)
143 NodeHandle node(frag);
144 selectNode(node, frag.m_freeLoc);
146 frag.m_freeLoc = NullTupLoc;
154 Dbtux::setNodePref(TuxCtx & ctx, NodeHandle& node)
156 const Frag& frag = node.m_frag;
157 const Index&
index = *c_indexPool.
getPtr(frag.m_indexId);
165 if (index.m_prefAttrs > 0) {
166 KeyData prefKey(index.m_keySpec,
false, 0);
167 prefKey.set_buf(node.getPref(), index.m_prefBytes);
169 readKeyAttrs(ctx, frag, node.getEnt(0), prefKey, index.m_prefAttrs);
171 if (debugFlags & DebugMaint) {
172 debugOut <<
"setNodePref: " << node;
173 debugOut <<
" " << prefKey.print(ctx.c_debugBuffer, DebugBufferBytes);
194 Dbtux::nodePushUp(TuxCtx & ctx, NodeHandle& node,
unsigned pos,
const TreeEnt& ent, Uint32 scanList)
196 Frag& frag = node.m_frag;
197 TreeHead& tree = frag.m_tree;
198 const unsigned occup = node.getOccup();
199 ndbrequire(occup < tree.m_maxOccup && pos <= occup);
201 if (node.getNodeScan() != RNIL)
202 nodePushUpScans(node, pos);
204 TreeEnt*
const entList = tree.getEntList(node.m_node);
205 for (
unsigned i = occup;
i > pos;
i--) {
206 thrjam(ctx.jamBuffer);
207 entList[
i] = entList[
i - 1];
210 node.setOccup(occup + 1);
212 if (scanList != RNIL)
213 addScanList(node, pos, scanList);
215 if (occup == 0 || pos == 0)
216 setNodePref(ctx, node);
220 Dbtux::nodePushUpScans(NodeHandle& node,
unsigned pos)
222 const unsigned occup = node.getOccup();
224 scanPtr.i = node.getNodeScan();
227 c_scanOpPool.
getPtr(scanPtr);
228 TreePos& scanPos = scanPtr.p->m_scanPos;
229 ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
230 if (scanPos.m_pos >= pos) {
233 if (debugFlags & DebugScan) {
234 debugOut <<
"Fix scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
235 debugOut <<
"At pushUp pos=" << pos <<
" " << node << endl;
240 scanPtr.i = scanPtr.p->m_nodeScan;
241 }
while (scanPtr.i != RNIL);
257 Dbtux::nodePopDown(TuxCtx& ctx, NodeHandle& node,
unsigned pos, TreeEnt& ent, Uint32* scanList)
259 Frag& frag = node.m_frag;
260 TreeHead& tree = frag.m_tree;
261 const unsigned occup = node.getOccup();
262 ndbrequire(occup <= tree.m_maxOccup && pos < occup);
263 if (node.getNodeScan() != RNIL) {
266 moveScanList(node, pos);
268 removeScanList(node, pos, *scanList);
270 if (node.getNodeScan() != RNIL)
271 nodePopDownScans(node, pos);
274 TreeEnt*
const entList = tree.getEntList(node.m_node);
276 for (
unsigned i = pos;
i < occup - 1;
i++) {
277 thrjam(ctx.jamBuffer);
278 entList[
i] = entList[
i + 1];
280 node.setOccup(occup - 1);
282 if (occup != 1 && pos == 0)
283 setNodePref(ctx, node);
287 Dbtux::nodePopDownScans(NodeHandle& node,
unsigned pos)
289 const unsigned occup = node.getOccup();
291 scanPtr.i = node.getNodeScan();
294 c_scanOpPool.
getPtr(scanPtr);
295 TreePos& scanPos = scanPtr.p->m_scanPos;
296 ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
298 ndbrequire(scanPos.m_pos != pos);
299 if (scanPos.m_pos > pos) {
302 if (debugFlags & DebugScan) {
303 debugOut <<
"Fix scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
304 debugOut <<
"At popDown pos=" << pos <<
" " << node << endl;
309 scanPtr.i = scanPtr.p->m_nodeScan;
310 }
while (scanPtr.i != RNIL);
325 Dbtux::nodePushDown(TuxCtx& ctx, NodeHandle& node,
unsigned pos, TreeEnt& ent, Uint32& scanList)
327 Frag& frag = node.m_frag;
328 TreeHead& tree = frag.m_tree;
329 const unsigned occup = node.getOccup();
330 ndbrequire(occup <= tree.m_maxOccup && pos < occup);
331 if (node.getNodeScan() != RNIL) {
333 removeScanList(node, 0, scanList);
335 if (node.getNodeScan() != RNIL)
336 nodePushDownScans(node, pos);
339 TreeEnt*
const entList = tree.getEntList(node.m_node);
340 TreeEnt oldMin = entList[0];
341 for (
unsigned i = 0;
i < pos;
i++) {
342 thrjam(ctx.jamBuffer);
343 entList[
i] = entList[
i + 1];
349 setNodePref(ctx, node);
353 Dbtux::nodePushDownScans(NodeHandle& node,
unsigned pos)
355 const unsigned occup = node.getOccup();
357 scanPtr.i = node.getNodeScan();
360 c_scanOpPool.
getPtr(scanPtr);
361 TreePos& scanPos = scanPtr.p->m_scanPos;
362 ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
364 ndbrequire(scanPos.m_pos != 0);
365 if (scanPos.m_pos <= pos) {
368 if (debugFlags & DebugScan) {
369 debugOut <<
"Fix scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
370 debugOut <<
"At pushDown pos=" << pos <<
" " << node << endl;
375 scanPtr.i = scanPtr.p->m_nodeScan;
376 }
while (scanPtr.i != RNIL);
392 Dbtux::nodePopUp(TuxCtx& ctx, NodeHandle& node,
unsigned pos, TreeEnt& ent, Uint32 scanList)
394 Frag& frag = node.m_frag;
395 TreeHead& tree = frag.m_tree;
396 const unsigned occup = node.getOccup();
397 ndbrequire(occup <= tree.m_maxOccup && pos < occup);
398 if (node.getNodeScan() != RNIL) {
400 moveScanList(node, pos);
402 if (node.getNodeScan() != RNIL)
403 nodePopUpScans(node, pos);
406 TreeEnt*
const entList = tree.getEntList(node.m_node);
407 TreeEnt newMin = ent;
409 for (
unsigned i = pos;
i > 0;
i--) {
410 thrjam(ctx.jamBuffer);
411 entList[
i] = entList[
i - 1];
415 if (scanList != RNIL)
416 addScanList(node, 0, scanList);
419 setNodePref(ctx, node);
423 Dbtux::nodePopUpScans(NodeHandle& node,
unsigned pos)
425 const unsigned occup = node.getOccup();
427 scanPtr.i = node.getNodeScan();
430 c_scanOpPool.
getPtr(scanPtr);
431 TreePos& scanPos = scanPtr.p->m_scanPos;
432 ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
433 ndbrequire(scanPos.m_pos != pos);
434 if (scanPos.m_pos < pos) {
437 if (debugFlags & DebugScan) {
438 debugOut <<
"Fix scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
439 debugOut <<
"At popUp pos=" << pos <<
" " << node << endl;
444 scanPtr.i = scanPtr.p->m_nodeScan;
445 }
while (scanPtr.i != RNIL);
453 Dbtux::nodeSlide(TuxCtx& ctx, NodeHandle& dstNode, NodeHandle& srcNode,
unsigned cnt,
unsigned i)
458 Uint32 scanList = RNIL;
459 nodePopDown(ctx, srcNode, i == 0 ? srcNode.getOccup() - 1 : 0, ent, &scanList);
460 nodePushUp(ctx, dstNode, i == 0 ? 0 : dstNode.getOccup(), ent, scanList);
472 Dbtux::addScanList(NodeHandle& node,
unsigned pos, Uint32 scanList)
475 scanPtr.i = scanList;
478 c_scanOpPool.
getPtr(scanPtr);
480 if (debugFlags & DebugScan) {
481 debugOut <<
"Add scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
482 debugOut <<
"To pos=" << pos <<
" " << node << endl;
485 const Uint32 nextPtrI = scanPtr.p->m_nodeScan;
486 scanPtr.p->m_nodeScan = RNIL;
487 linkScan(node, scanPtr);
488 TreePos& scanPos = scanPtr.p->m_scanPos;
490 scanPos.m_loc = node.m_loc;
492 scanPtr.i = nextPtrI;
493 }
while (scanPtr.i != RNIL);
501 Dbtux::removeScanList(NodeHandle& node,
unsigned pos, Uint32& scanList)
504 scanPtr.i = node.getNodeScan();
507 c_scanOpPool.
getPtr(scanPtr);
508 const Uint32 nextPtrI = scanPtr.p->m_nodeScan;
509 TreePos& scanPos = scanPtr.p->m_scanPos;
510 ndbrequire(scanPos.m_loc == node.m_loc);
511 if (scanPos.m_pos == pos) {
514 if (debugFlags & DebugScan) {
515 debugOut <<
"Remove scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
516 debugOut <<
"Fron pos=" << pos <<
" " << node << endl;
519 unlinkScan(node, scanPtr);
520 scanPtr.p->m_nodeScan = scanList;
521 scanList = scanPtr.i;
523 scanPos.m_loc = NullTupLoc;
524 scanPos.m_pos = ZNIL;
526 scanPtr.i = nextPtrI;
527 }
while (scanPtr.i != RNIL);
535 Dbtux::moveScanList(NodeHandle& node,
unsigned pos)
538 scanPtr.i = node.getNodeScan();
541 c_scanOpPool.
getPtr(scanPtr);
542 TreePos& scanPos = scanPtr.p->m_scanPos;
543 const Uint32 nextPtrI = scanPtr.p->m_nodeScan;
544 ndbrequire(scanPos.m_loc == node.m_loc);
545 if (scanPos.m_pos == pos) {
548 if (debugFlags & DebugScan) {
549 debugOut <<
"Move scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
550 debugOut <<
"At pos=" << pos <<
" " << node << endl;
553 scanNext(scanPtr,
true);
554 ndbrequire(! (scanPos.m_loc == node.m_loc && scanPos.m_pos == pos));
556 scanPtr.i = nextPtrI;
557 }
while (scanPtr.i != RNIL);
565 Dbtux::linkScan(NodeHandle& node, ScanOpPtr scanPtr)
568 if (debugFlags & DebugScan) {
569 debugOut <<
"Link scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
570 debugOut <<
"To node " << node << endl;
573 ndbrequire(! islinkScan(node, scanPtr) && scanPtr.p->m_nodeScan == RNIL);
574 scanPtr.p->m_nodeScan = node.getNodeScan();
575 node.setNodeScan(scanPtr.i);
582 Dbtux::unlinkScan(NodeHandle& node, ScanOpPtr scanPtr)
585 if (debugFlags & DebugScan) {
586 debugOut <<
"Unlink scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
587 debugOut <<
"From node " << node << endl;
591 currPtr.i = node.getNodeScan();
596 c_scanOpPool.
getPtr(currPtr);
597 Uint32 nextPtrI = currPtr.p->m_nodeScan;
598 if (currPtr.i == scanPtr.i) {
600 if (prevPtr.i == RNIL) {
601 node.setNodeScan(nextPtrI);
604 prevPtr.p->m_nodeScan = nextPtrI;
606 scanPtr.p->m_nodeScan = RNIL;
608 ndbrequire(! islinkScan(node, scanPtr));
612 currPtr.i = nextPtrI;
620 Dbtux::islinkScan(NodeHandle& node, ScanOpPtr scanPtr)
623 currPtr.i = node.getNodeScan();
624 while (currPtr.i != RNIL) {
626 c_scanOpPool.
getPtr(currPtr);
627 if (currPtr.i == scanPtr.i) {
631 currPtr.i = currPtr.p->m_nodeScan;
639 ErrorReporter::handleAssert(
"Dbtux::NodeHandle: assert failed", file, line);