📄 dbtuxnode.cpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#define DBTUX_NODE_CPP#include "Dbtux.hpp"/* * Allocate index node in TUP. */intDbtux::allocNode(Signal* signal, NodeHandle& node){ if (ERROR_INSERTED(12007)) { jam(); CLEAR_ERROR_INSERT_VALUE; return TuxMaintReq::NoMemError; } Frag& frag = node.m_frag; Uint32 pageId = NullTupLoc.getPageId(); Uint32 pageOffset = NullTupLoc.getPageOffset(); Uint32* node32 = 0; int errorCode = c_tup->tuxAllocNode(signal, frag.m_tupIndexFragPtrI, pageId, pageOffset, node32); jamEntry(); if (errorCode == 0) { jam(); node.m_loc = TupLoc(pageId, pageOffset); node.m_node = reinterpret_cast<TreeNode*>(node32); ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); } else { switch (errorCode) { case 827: errorCode = TuxMaintReq::NoMemError; break; } } return errorCode;}/* * Set handle to point to existing node. */voidDbtux::selectNode(NodeHandle& node, TupLoc loc){ Frag& frag = node.m_frag; ndbrequire(loc != NullTupLoc); Uint32 pageId = loc.getPageId(); Uint32 pageOffset = loc.getPageOffset(); Uint32* node32 = 0; c_tup->tuxGetNode(frag.m_tupIndexFragPtrI, pageId, pageOffset, node32); jamEntry(); node.m_loc = loc; node.m_node = reinterpret_cast<TreeNode*>(node32); ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0);}/* * Set handle to point to new node. Uses a pre-allocated node. */voidDbtux::insertNode(NodeHandle& node){ Frag& frag = node.m_frag; // unlink from freelist selectNode(node, frag.m_freeLoc); frag.m_freeLoc = node.getLink(0); new (node.m_node) TreeNode();#ifdef VM_TRACE TreeHead& tree = frag.m_tree; memset(node.getPref(), DataFillByte, tree.m_prefSize << 2); TreeEnt* entList = tree.getEntList(node.m_node); memset(entList, NodeFillByte, (tree.m_maxOccup + 1) * (TreeEntSize << 2));#endif}/* * Delete existing node. Simply put it on the freelist. */voidDbtux::deleteNode(NodeHandle& node){ Frag& frag = node.m_frag; ndbrequire(node.getOccup() == 0); // link to freelist node.setLink(0, frag.m_freeLoc); frag.m_freeLoc = node.m_loc; // invalidate the handle node.m_loc = NullTupLoc; node.m_node = 0;}/* * Set prefix. Copies the number of words that fits. Includes * attribute headers for now. XXX use null mask instead */voidDbtux::setNodePref(NodeHandle& node){ const Frag& frag = node.m_frag; const TreeHead& tree = frag.m_tree; readKeyAttrs(frag, node.getMinMax(0), 0, c_entryKey); copyAttrs(frag, c_entryKey, node.getPref(), tree.m_prefSize);}// node operations/* * Add entry at position. Move entries greater than or equal to the old * one (if any) to the right. * * X * v * A B C D E _ _ => A B C X D E _ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6 * * Add list of scans at the new entry. */voidDbtux::nodePushUp(NodeHandle& node, unsigned pos, const TreeEnt& ent, Uint32 scanList){ Frag& frag = node.m_frag; TreeHead& tree = frag.m_tree; const unsigned occup = node.getOccup(); ndbrequire(occup < tree.m_maxOccup && pos <= occup); // fix old scans if (node.getNodeScan() != RNIL) nodePushUpScans(node, pos); // fix node TreeEnt* const entList = tree.getEntList(node.m_node); entList[occup] = entList[0]; TreeEnt* const tmpList = entList + 1; for (unsigned i = occup; i > pos; i--) { jam(); tmpList[i] = tmpList[i - 1]; } tmpList[pos] = ent; entList[0] = entList[occup + 1]; node.setOccup(occup + 1); // add new scans if (scanList != RNIL) addScanList(node, pos, scanList); // fix prefix if (occup == 0 || pos == 0) setNodePref(node);}voidDbtux::nodePushUpScans(NodeHandle& node, unsigned pos){ const unsigned occup = node.getOccup(); ScanOpPtr scanPtr; scanPtr.i = node.getNodeScan(); do { jam(); c_scanOpPool.getPtr(scanPtr); TreePos& scanPos = scanPtr.p->m_scanPos; ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup); if (scanPos.m_pos >= pos) { jam();#ifdef VM_TRACE if (debugFlags & DebugScan) { debugOut << "Fix scan " << scanPtr.i << " " << *scanPtr.p << endl; debugOut << "At pushUp pos=" << pos << " " << node << endl; }#endif scanPos.m_pos++; } scanPtr.i = scanPtr.p->m_nodeScan; } while (scanPtr.i != RNIL);}/* * Remove and return entry at position. Move entries greater than the * removed one to the left. This is the opposite of nodePushUp. * * D * ^ ^ * A B C D E F _ => A B C E F _ _ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6 * * Scans at removed entry are returned if non-zero location is passed or * else moved forward. */voidDbtux::nodePopDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32* scanList){ Frag& frag = node.m_frag; TreeHead& tree = frag.m_tree; const unsigned occup = node.getOccup(); ndbrequire(occup <= tree.m_maxOccup && pos < occup); if (node.getNodeScan() != RNIL) { // remove or move scans at this position if (scanList == 0) moveScanList(node, pos); else removeScanList(node, pos, *scanList); // fix other scans if (node.getNodeScan() != RNIL) nodePopDownScans(node, pos); } // fix node TreeEnt* const entList = tree.getEntList(node.m_node); entList[occup] = entList[0]; TreeEnt* const tmpList = entList + 1; ent = tmpList[pos]; for (unsigned i = pos; i < occup - 1; i++) { jam(); tmpList[i] = tmpList[i + 1]; } entList[0] = entList[occup - 1]; node.setOccup(occup - 1); // fix prefix if (occup != 1 && pos == 0) setNodePref(node);}voidDbtux::nodePopDownScans(NodeHandle& node, unsigned pos){ const unsigned occup = node.getOccup(); ScanOpPtr scanPtr; scanPtr.i = node.getNodeScan(); do { jam(); c_scanOpPool.getPtr(scanPtr); TreePos& scanPos = scanPtr.p->m_scanPos; ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup); // handled before ndbrequire(scanPos.m_pos != pos); if (scanPos.m_pos > pos) { jam();#ifdef VM_TRACE if (debugFlags & DebugScan) { debugOut << "Fix scan " << scanPtr.i << " " << *scanPtr.p << endl; debugOut << "At popDown pos=" << pos << " " << node << endl; }#endif scanPos.m_pos--; } scanPtr.i = scanPtr.p->m_nodeScan; } while (scanPtr.i != RNIL);}/* * Add entry at existing position. Move entries less than or equal to * the old one to the left. Remove and return old min entry. * * X A * ^ v ^ * A B C D E _ _ => B C D X E _ _ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6 * * Return list of scans at the removed position 0. */voidDbtux::nodePushDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32& scanList){ Frag& frag = node.m_frag; TreeHead& tree = frag.m_tree; const unsigned occup = node.getOccup(); ndbrequire(occup <= tree.m_maxOccup && pos < occup); if (node.getNodeScan() != RNIL) { // remove scans at 0 removeScanList(node, 0, scanList); // fix other scans if (node.getNodeScan() != RNIL) nodePushDownScans(node, pos); } // fix node TreeEnt* const entList = tree.getEntList(node.m_node); entList[occup] = entList[0]; TreeEnt* const tmpList = entList + 1; TreeEnt oldMin = tmpList[0]; for (unsigned i = 0; i < pos; i++) { jam(); tmpList[i] = tmpList[i + 1]; } tmpList[pos] = ent; ent = oldMin; entList[0] = entList[occup]; // fix prefix if (true) setNodePref(node);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -