Loading mysql-test/ndb/ndb_range_bounds.pl +15 −10 Original line number Diff line number Diff line Loading @@ -7,10 +7,12 @@ use strict; use integer; use Getopt::Long; my $all = shift; !defined($all) || ($all eq '--all' && !defined(shift)) or die "only available option is --all"; my $opt_all = 0; my $opt_cnt = 5; GetOptions("all" => \$opt_all, "cnt=i" => \$opt_cnt) or die "options are: --all --cnt=N"; my $table = 't'; Loading Loading @@ -67,15 +69,18 @@ sub mkall ($$$\@) { my($col, $key1, $key2, $val) = @_; my @a = (); my $p = mkdummy(@$val); push(@a, $p) if $all; my @ops1 = $all ? qw(< <= = >= >) : qw(= >= >); my @ops2 = $all ? qw(< <= = >= >) : qw(< <=); push(@a, $p) if $opt_all; my @ops = qw(< <= = >= >); for my $op (@ops) { my $p = mkone($col, $op, $key1, @$val); push(@a, $p) if $opt_all || $p->{cnt} != 0; } my @ops1 = $opt_all ? @ops : qw(= >= >); my @ops2 = $opt_all ? @ops : qw(<= <); for my $op1 (@ops1) { my $p = mkone($col, $op1, $key1, @$val); push(@a, $p) if $all || $p->{cnt} != 0; for my $op2 (@ops2) { my $p = mktwo($col, $op1, $key1, $op2, $key2, @$val); push(@a, $p) if $all || $p->{cnt} != 0; push(@a, $p) if $opt_all || $p->{cnt} != 0; } } return \@a; Loading @@ -95,7 +100,7 @@ create table $table ( index (b, c, d) ) engine=ndb; EOF my @val = (0..4); my @val = (0..($opt_cnt-1)); my $v0 = 0; for my $v1 (@val) { for my $v2 (@val) { Loading ndb/src/kernel/blocks/dbtux/Dbtux.hpp +15 −24 Original line number Diff line number Diff line Loading @@ -250,8 +250,8 @@ private: static const unsigned NodeHeadSize = sizeof(TreeNode) >> 2; /* * Tree nodes are not always accessed fully, for cache reasons. There * are 3 access sizes. * Tree node "access size" was for an early version with signal * interface to TUP. It is now used only to compute sizes. */ enum AccSize { AccNone = 0, Loading Loading @@ -284,7 +284,7 @@ private: * m_occup), and whether the position is at an existing entry or * before one (if any). Position m_occup points past the node and is * also represented by position 0 of next node. Includes direction * and copy of entry used by scan. * used by scan. */ struct TreePos; friend struct TreePos; Loading @@ -292,8 +292,7 @@ private: TupLoc m_loc; // physical node address Uint16 m_pos; // position 0 to m_occup Uint8 m_match; // at an existing entry Uint8 m_dir; // from link (0-2) or within node (3) TreeEnt m_ent; // copy of current entry Uint8 m_dir; // see scanNext() TreePos(); }; Loading Loading @@ -374,6 +373,10 @@ private: * a separate lock wait flag. It may be for current entry or it may * be for an entry we were moved away from. In any case nothing * happens with current entry before lock wait flag is cleared. * * An unfinished scan is always linked to some tree node, and has * current position and direction (see comments at scanNext). There * is also a copy of latest entry found. */ struct ScanOp; friend struct ScanOp; Loading Loading @@ -412,7 +415,7 @@ private: ScanBound* m_bound[2]; // pointers to above 2 Uint16 m_boundCnt[2]; // number of bounds in each TreePos m_scanPos; // position TreeEnt m_lastEnt; // last entry returned TreeEnt m_scanEnt; // latest entry found Uint32 m_nodeScan; // next scan at node (single-linked) union { Uint32 nextPool; Loading Loading @@ -519,7 +522,6 @@ private: Frag& m_frag; // fragment using the node TupLoc m_loc; // physical node address TreeNode* m_node; // pointer to node storage AccSize m_acc; // accessed size NodeHandle(Frag& frag); NodeHandle(const NodeHandle& node); NodeHandle& operator=(const NodeHandle& node); Loading Loading @@ -580,9 +582,8 @@ private: * DbtuxNode.cpp */ int allocNode(Signal* signal, NodeHandle& node); void accessNode(Signal* signal, NodeHandle& node, AccSize acc); void selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc); void insertNode(Signal* signal, NodeHandle& node, AccSize acc); void selectNode(Signal* signal, NodeHandle& node, TupLoc loc); void insertNode(Signal* signal, NodeHandle& node); void deleteNode(Signal* signal, NodeHandle& node); void setNodePref(Signal* signal, NodeHandle& node); // node operations Loading Loading @@ -968,8 +969,7 @@ Dbtux::TreePos::TreePos() : m_loc(), m_pos(ZNIL), m_match(false), m_dir(255), m_ent() m_dir(255) { } Loading Loading @@ -1010,7 +1010,7 @@ Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), m_lastEnt(), m_scanEnt(), m_nodeScan(RNIL) { m_bound[0] = &m_boundMin; Loading Loading @@ -1084,8 +1084,7 @@ inline Dbtux::NodeHandle::NodeHandle(Frag& frag) : m_frag(frag), m_loc(), m_node(0), m_acc(AccNone) m_node(0) { } Loading @@ -1093,8 +1092,7 @@ inline Dbtux::NodeHandle::NodeHandle(const NodeHandle& node) : m_frag(node.m_frag), m_loc(node.m_loc), m_node(node.m_node), m_acc(node.m_acc) m_node(node.m_node) { } Loading @@ -1104,7 +1102,6 @@ Dbtux::NodeHandle::operator=(const NodeHandle& node) ndbassert(&m_frag == &node.m_frag); m_loc = node.m_loc; m_node = node.m_node; m_acc = node.m_acc; return *this; } Loading Loading @@ -1190,7 +1187,6 @@ inline Dbtux::Data Dbtux::NodeHandle::getPref() { TreeHead& tree = m_frag.m_tree; ndbrequire(m_acc >= AccPref); return tree.getPref(m_node); } Loading @@ -1201,11 +1197,6 @@ Dbtux::NodeHandle::getEnt(unsigned pos) TreeEnt* entList = tree.getEntList(m_node); const unsigned occup = m_node->m_occup; ndbrequire(pos < occup); if (pos == 0 || pos == occup - 1) { ndbrequire(m_acc >= AccPref) } else { ndbrequire(m_acc == AccFull) } return entList[(1 + pos) % occup]; } Loading ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp +16 −23 Original line number Diff line number Diff line Loading @@ -122,7 +122,7 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& } TreeHead& tree = frag.m_tree; NodeHandle node(frag); selectNode(signal, node, loc, AccFull); selectNode(signal, node, loc); out << par.m_path << " " << node << endl; // check children PrintPar cpar[2]; Loading Loading @@ -310,7 +310,6 @@ operator<<(NdbOut& out, const Dbtux::TreePos& pos) out << " [pos " << dec << pos.m_pos << "]"; out << " [match " << dec << pos.m_match << "]"; out << " [dir " << dec << pos.m_dir << "]"; out << " [ent " << pos.m_ent << "]"; out << "]"; return out; } Loading Loading @@ -347,6 +346,7 @@ operator<<(NdbOut& out, const Dbtux::ScanOp& scan) out << " [lockMode " << dec << scan.m_lockMode << "]"; out << " [keyInfo " << dec << scan.m_keyInfo << "]"; out << " [pos " << scan.m_scanPos << "]"; out << " [ent " << scan.m_scanEnt << "]"; for (unsigned i = 0; i <= 1; i++) { out << " [bound " << dec << i; Dbtux::ScanBound& bound = *scan.m_bound[i]; Loading Loading @@ -407,9 +407,7 @@ operator<<(NdbOut& out, const Dbtux::NodeHandle& node) const Dbtux::TreeHead& tree = frag.m_tree; out << "[NodeHandle " << hex << &node; out << " [loc " << node.m_loc << "]"; out << " [acc " << dec << node.m_acc << "]"; out << " [node " << *node.m_node << "]"; if (node.m_acc >= Dbtux::AccPref) { const Uint32* data; out << " [pref"; data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize; Loading @@ -418,17 +416,12 @@ operator<<(NdbOut& out, const Dbtux::NodeHandle& node) out << "]"; out << " [entList"; unsigned numpos = node.m_node->m_occup; if (node.m_acc < Dbtux::AccFull && numpos > 2) { numpos = 2; out << "(" << dec << numpos << ")"; } data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize + tree.m_prefSize; const Dbtux::TreeEnt* entList = (const Dbtux::TreeEnt*)data; // print entries in logical order for (unsigned pos = 1; pos <= numpos; pos++) out << " " << entList[pos % numpos]; out << "]"; } out << "]"; return out; } Loading ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp +3 −19 Original line number Diff line number Diff line Loading @@ -33,30 +33,16 @@ Dbtux::allocNode(Signal* signal, NodeHandle& node) jam(); node.m_loc = TupLoc(pageId, pageOffset); node.m_node = reinterpret_cast<TreeNode*>(node32); node.m_acc = AccNone; ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); } return errorCode; } /* * Access more of the node. */ void Dbtux::accessNode(Signal* signal, NodeHandle& node, AccSize acc) { ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); if (node.m_acc >= acc) return; // XXX could do prefetch node.m_acc = acc; } /* * Set handle to point to existing node. */ void Dbtux::selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc) Dbtux::selectNode(Signal* signal, NodeHandle& node, TupLoc loc) { Frag& frag = node.m_frag; ndbrequire(loc != NullTupLoc); Loading @@ -67,21 +53,19 @@ Dbtux::selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc) jamEntry(); node.m_loc = loc; node.m_node = reinterpret_cast<TreeNode*>(node32); node.m_acc = AccNone; ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); accessNode(signal, node, acc); } /* * Set handle to point to new node. Uses the pre-allocated node. */ void Dbtux::insertNode(Signal* signal, NodeHandle& node, AccSize acc) Dbtux::insertNode(Signal* signal, NodeHandle& node) { Frag& frag = node.m_frag; TupLoc loc = frag.m_freeLoc; frag.m_freeLoc = NullTupLoc; selectNode(signal, node, loc, acc); selectNode(signal, node, loc); new (node.m_node) TreeNode(); #ifdef VM_TRACE TreeHead& tree = frag.m_tree; Loading ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp +26 −25 Original line number Diff line number Diff line Loading @@ -275,7 +275,7 @@ Dbtux::execNEXT_SCANREQ(Signal* signal) jam(); const TupLoc loc = scan.m_scanPos.m_loc; NodeHandle node(frag); selectNode(signal, node, loc, AccHead); selectNode(signal, node, loc); unlinkScan(node, scanPtr); scan.m_scanPos.m_loc = NullTupLoc; } Loading Loading @@ -350,7 +350,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) if (scan.m_lockwait) { jam(); // LQH asks if we are waiting for lock and we tell it to ask again const TreeEnt ent = scan.m_scanPos.m_ent; const TreeEnt ent = scan.m_scanEnt; NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend(); conf->scanPtr = scan.m_userPtr; conf->accOperationPtr = RNIL; // no tuple returned Loading Loading @@ -385,7 +385,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) ndbrequire(scan.m_accLockOp == RNIL); if (! scan.m_readCommitted) { jam(); const TreeEnt ent = scan.m_scanPos.m_ent; const TreeEnt ent = scan.m_scanEnt; // read tuple key readTablePk(frag, ent, pkData, pkSize); // get read lock or exclusive lock Loading Loading @@ -473,7 +473,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) // we have lock or do not need one jam(); // read keys if not already done (uses signal) const TreeEnt ent = scan.m_scanPos.m_ent; const TreeEnt ent = scan.m_scanEnt; if (scan.m_keyInfo) { jam(); if (pkSize == 0) { Loading Loading @@ -536,8 +536,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) total += length; } } // remember last entry returned scan.m_lastEnt = ent; // next time look for next entry scan.m_state = ScanOp::Next; return; Loading Loading @@ -712,20 +710,21 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr) scan.m_state = ScanOp::Next; // link the scan to node found NodeHandle node(frag); selectNode(signal, node, treePos.m_loc, AccFull); selectNode(signal, node, treePos.m_loc); linkScan(node, scanPtr); } /* * Move to next entry. The scan is already linked to some node. When * we leave, if any entry was found, it will be linked to a possibly * different node. The scan has a direction, one of: * different node. The scan has a position, and a direction which tells * from where we came to this position. This is one of: * * 0 - coming up from left child * 1 - coming up from right child (proceed to parent immediately) * 2 - coming up from root (the scan ends) * 3 - left to right within node * 4 - coming down from parent to left or right child * 0 - up from left child (scan this node next) * 1 - up from right child (proceed to parent) * 2 - up from root (the scan ends) * 3 - left to right within node (at end proceed to right child) * 4 - down from parent (proceed to left child) */ void Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) Loading Loading @@ -768,10 +767,12 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) TreePos pos = scan.m_scanPos; // get and remember original node NodeHandle origNode(frag); selectNode(signal, origNode, pos.m_loc, AccHead); selectNode(signal, origNode, pos.m_loc); ndbrequire(islinkScan(origNode, scanPtr)); // current node in loop NodeHandle node = origNode; // copy of entry found TreeEnt ent; while (true) { jam(); if (pos.m_dir == 2) { Loading @@ -783,7 +784,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) } if (node.m_loc != pos.m_loc) { jam(); selectNode(signal, node, pos.m_loc, AccHead); selectNode(signal, node, pos.m_loc); } if (pos.m_dir == 4) { // coming down from parent proceed to left child Loading @@ -799,7 +800,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_dir = 0; } if (pos.m_dir == 0) { // coming from left child scan current node // coming up from left child scan current node jam(); pos.m_pos = 0; pos.m_match = false; Loading @@ -810,8 +811,6 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) jam(); unsigned occup = node.getOccup(); ndbrequire(occup >= 1); // access full node accessNode(signal, node, AccFull); // advance position if (! pos.m_match) pos.m_match = true; Loading @@ -819,10 +818,10 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_pos++; if (pos.m_pos < occup) { jam(); pos.m_ent = node.getEnt(pos.m_pos); ent = node.getEnt(pos.m_pos); pos.m_dir = 3; // unchanged // read and compare all attributes readKeyAttrs(frag, pos.m_ent, 0, c_entryKey); readKeyAttrs(frag, ent, 0, c_entryKey); int ret = cmpScanBound(frag, 1, c_dataBuffer, scan.m_boundCnt[1], c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); if (ret < 0) { Loading @@ -833,7 +832,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) break; } // can we see it if (! scanVisible(signal, scanPtr, pos.m_ent)) { if (! scanVisible(signal, scanPtr, ent)) { jam(); continue; } Loading @@ -853,7 +852,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_dir = 1; } if (pos.m_dir == 1) { // coming from right child proceed to parent // coming up from right child proceed to parent jam(); pos.m_loc = node.getLink(2); pos.m_dir = node.getSide(); Loading @@ -871,6 +870,8 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) unlinkScan(origNode, scanPtr); linkScan(node, scanPtr); } // copy found entry scan.m_scanEnt = ent; } else if (scan.m_state == ScanOp::Last) { jam(); ndbrequire(pos.m_loc == NullTupLoc); Loading @@ -888,7 +889,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) /* * Check if an entry is visible to the scan. * * There is a special check to never return same tuple twice in a row. * There is a special check to never accept same tuple twice in a row. * This is faster than asking TUP. It also fixes some special cases * which are not analyzed or handled yet. */ Loading @@ -903,8 +904,8 @@ Dbtux::scanVisible(Signal* signal, ScanOpPtr scanPtr, TreeEnt ent) Uint32 tupAddr = getTupAddr(frag, ent); Uint32 tupVersion = ent.m_tupVersion; // check for same tuple twice in row if (scan.m_lastEnt.m_tupLoc == ent.m_tupLoc && scan.m_lastEnt.m_fragBit == fragBit) { if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc && scan.m_scanEnt.m_fragBit == fragBit) { jam(); return false; } Loading Loading
mysql-test/ndb/ndb_range_bounds.pl +15 −10 Original line number Diff line number Diff line Loading @@ -7,10 +7,12 @@ use strict; use integer; use Getopt::Long; my $all = shift; !defined($all) || ($all eq '--all' && !defined(shift)) or die "only available option is --all"; my $opt_all = 0; my $opt_cnt = 5; GetOptions("all" => \$opt_all, "cnt=i" => \$opt_cnt) or die "options are: --all --cnt=N"; my $table = 't'; Loading Loading @@ -67,15 +69,18 @@ sub mkall ($$$\@) { my($col, $key1, $key2, $val) = @_; my @a = (); my $p = mkdummy(@$val); push(@a, $p) if $all; my @ops1 = $all ? qw(< <= = >= >) : qw(= >= >); my @ops2 = $all ? qw(< <= = >= >) : qw(< <=); push(@a, $p) if $opt_all; my @ops = qw(< <= = >= >); for my $op (@ops) { my $p = mkone($col, $op, $key1, @$val); push(@a, $p) if $opt_all || $p->{cnt} != 0; } my @ops1 = $opt_all ? @ops : qw(= >= >); my @ops2 = $opt_all ? @ops : qw(<= <); for my $op1 (@ops1) { my $p = mkone($col, $op1, $key1, @$val); push(@a, $p) if $all || $p->{cnt} != 0; for my $op2 (@ops2) { my $p = mktwo($col, $op1, $key1, $op2, $key2, @$val); push(@a, $p) if $all || $p->{cnt} != 0; push(@a, $p) if $opt_all || $p->{cnt} != 0; } } return \@a; Loading @@ -95,7 +100,7 @@ create table $table ( index (b, c, d) ) engine=ndb; EOF my @val = (0..4); my @val = (0..($opt_cnt-1)); my $v0 = 0; for my $v1 (@val) { for my $v2 (@val) { Loading
ndb/src/kernel/blocks/dbtux/Dbtux.hpp +15 −24 Original line number Diff line number Diff line Loading @@ -250,8 +250,8 @@ private: static const unsigned NodeHeadSize = sizeof(TreeNode) >> 2; /* * Tree nodes are not always accessed fully, for cache reasons. There * are 3 access sizes. * Tree node "access size" was for an early version with signal * interface to TUP. It is now used only to compute sizes. */ enum AccSize { AccNone = 0, Loading Loading @@ -284,7 +284,7 @@ private: * m_occup), and whether the position is at an existing entry or * before one (if any). Position m_occup points past the node and is * also represented by position 0 of next node. Includes direction * and copy of entry used by scan. * used by scan. */ struct TreePos; friend struct TreePos; Loading @@ -292,8 +292,7 @@ private: TupLoc m_loc; // physical node address Uint16 m_pos; // position 0 to m_occup Uint8 m_match; // at an existing entry Uint8 m_dir; // from link (0-2) or within node (3) TreeEnt m_ent; // copy of current entry Uint8 m_dir; // see scanNext() TreePos(); }; Loading Loading @@ -374,6 +373,10 @@ private: * a separate lock wait flag. It may be for current entry or it may * be for an entry we were moved away from. In any case nothing * happens with current entry before lock wait flag is cleared. * * An unfinished scan is always linked to some tree node, and has * current position and direction (see comments at scanNext). There * is also a copy of latest entry found. */ struct ScanOp; friend struct ScanOp; Loading Loading @@ -412,7 +415,7 @@ private: ScanBound* m_bound[2]; // pointers to above 2 Uint16 m_boundCnt[2]; // number of bounds in each TreePos m_scanPos; // position TreeEnt m_lastEnt; // last entry returned TreeEnt m_scanEnt; // latest entry found Uint32 m_nodeScan; // next scan at node (single-linked) union { Uint32 nextPool; Loading Loading @@ -519,7 +522,6 @@ private: Frag& m_frag; // fragment using the node TupLoc m_loc; // physical node address TreeNode* m_node; // pointer to node storage AccSize m_acc; // accessed size NodeHandle(Frag& frag); NodeHandle(const NodeHandle& node); NodeHandle& operator=(const NodeHandle& node); Loading Loading @@ -580,9 +582,8 @@ private: * DbtuxNode.cpp */ int allocNode(Signal* signal, NodeHandle& node); void accessNode(Signal* signal, NodeHandle& node, AccSize acc); void selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc); void insertNode(Signal* signal, NodeHandle& node, AccSize acc); void selectNode(Signal* signal, NodeHandle& node, TupLoc loc); void insertNode(Signal* signal, NodeHandle& node); void deleteNode(Signal* signal, NodeHandle& node); void setNodePref(Signal* signal, NodeHandle& node); // node operations Loading Loading @@ -968,8 +969,7 @@ Dbtux::TreePos::TreePos() : m_loc(), m_pos(ZNIL), m_match(false), m_dir(255), m_ent() m_dir(255) { } Loading Loading @@ -1010,7 +1010,7 @@ Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), m_lastEnt(), m_scanEnt(), m_nodeScan(RNIL) { m_bound[0] = &m_boundMin; Loading Loading @@ -1084,8 +1084,7 @@ inline Dbtux::NodeHandle::NodeHandle(Frag& frag) : m_frag(frag), m_loc(), m_node(0), m_acc(AccNone) m_node(0) { } Loading @@ -1093,8 +1092,7 @@ inline Dbtux::NodeHandle::NodeHandle(const NodeHandle& node) : m_frag(node.m_frag), m_loc(node.m_loc), m_node(node.m_node), m_acc(node.m_acc) m_node(node.m_node) { } Loading @@ -1104,7 +1102,6 @@ Dbtux::NodeHandle::operator=(const NodeHandle& node) ndbassert(&m_frag == &node.m_frag); m_loc = node.m_loc; m_node = node.m_node; m_acc = node.m_acc; return *this; } Loading Loading @@ -1190,7 +1187,6 @@ inline Dbtux::Data Dbtux::NodeHandle::getPref() { TreeHead& tree = m_frag.m_tree; ndbrequire(m_acc >= AccPref); return tree.getPref(m_node); } Loading @@ -1201,11 +1197,6 @@ Dbtux::NodeHandle::getEnt(unsigned pos) TreeEnt* entList = tree.getEntList(m_node); const unsigned occup = m_node->m_occup; ndbrequire(pos < occup); if (pos == 0 || pos == occup - 1) { ndbrequire(m_acc >= AccPref) } else { ndbrequire(m_acc == AccFull) } return entList[(1 + pos) % occup]; } Loading
ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp +16 −23 Original line number Diff line number Diff line Loading @@ -122,7 +122,7 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& } TreeHead& tree = frag.m_tree; NodeHandle node(frag); selectNode(signal, node, loc, AccFull); selectNode(signal, node, loc); out << par.m_path << " " << node << endl; // check children PrintPar cpar[2]; Loading Loading @@ -310,7 +310,6 @@ operator<<(NdbOut& out, const Dbtux::TreePos& pos) out << " [pos " << dec << pos.m_pos << "]"; out << " [match " << dec << pos.m_match << "]"; out << " [dir " << dec << pos.m_dir << "]"; out << " [ent " << pos.m_ent << "]"; out << "]"; return out; } Loading Loading @@ -347,6 +346,7 @@ operator<<(NdbOut& out, const Dbtux::ScanOp& scan) out << " [lockMode " << dec << scan.m_lockMode << "]"; out << " [keyInfo " << dec << scan.m_keyInfo << "]"; out << " [pos " << scan.m_scanPos << "]"; out << " [ent " << scan.m_scanEnt << "]"; for (unsigned i = 0; i <= 1; i++) { out << " [bound " << dec << i; Dbtux::ScanBound& bound = *scan.m_bound[i]; Loading Loading @@ -407,9 +407,7 @@ operator<<(NdbOut& out, const Dbtux::NodeHandle& node) const Dbtux::TreeHead& tree = frag.m_tree; out << "[NodeHandle " << hex << &node; out << " [loc " << node.m_loc << "]"; out << " [acc " << dec << node.m_acc << "]"; out << " [node " << *node.m_node << "]"; if (node.m_acc >= Dbtux::AccPref) { const Uint32* data; out << " [pref"; data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize; Loading @@ -418,17 +416,12 @@ operator<<(NdbOut& out, const Dbtux::NodeHandle& node) out << "]"; out << " [entList"; unsigned numpos = node.m_node->m_occup; if (node.m_acc < Dbtux::AccFull && numpos > 2) { numpos = 2; out << "(" << dec << numpos << ")"; } data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize + tree.m_prefSize; const Dbtux::TreeEnt* entList = (const Dbtux::TreeEnt*)data; // print entries in logical order for (unsigned pos = 1; pos <= numpos; pos++) out << " " << entList[pos % numpos]; out << "]"; } out << "]"; return out; } Loading
ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp +3 −19 Original line number Diff line number Diff line Loading @@ -33,30 +33,16 @@ Dbtux::allocNode(Signal* signal, NodeHandle& node) jam(); node.m_loc = TupLoc(pageId, pageOffset); node.m_node = reinterpret_cast<TreeNode*>(node32); node.m_acc = AccNone; ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); } return errorCode; } /* * Access more of the node. */ void Dbtux::accessNode(Signal* signal, NodeHandle& node, AccSize acc) { ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); if (node.m_acc >= acc) return; // XXX could do prefetch node.m_acc = acc; } /* * Set handle to point to existing node. */ void Dbtux::selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc) Dbtux::selectNode(Signal* signal, NodeHandle& node, TupLoc loc) { Frag& frag = node.m_frag; ndbrequire(loc != NullTupLoc); Loading @@ -67,21 +53,19 @@ Dbtux::selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc) jamEntry(); node.m_loc = loc; node.m_node = reinterpret_cast<TreeNode*>(node32); node.m_acc = AccNone; ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); accessNode(signal, node, acc); } /* * Set handle to point to new node. Uses the pre-allocated node. */ void Dbtux::insertNode(Signal* signal, NodeHandle& node, AccSize acc) Dbtux::insertNode(Signal* signal, NodeHandle& node) { Frag& frag = node.m_frag; TupLoc loc = frag.m_freeLoc; frag.m_freeLoc = NullTupLoc; selectNode(signal, node, loc, acc); selectNode(signal, node, loc); new (node.m_node) TreeNode(); #ifdef VM_TRACE TreeHead& tree = frag.m_tree; Loading
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp +26 −25 Original line number Diff line number Diff line Loading @@ -275,7 +275,7 @@ Dbtux::execNEXT_SCANREQ(Signal* signal) jam(); const TupLoc loc = scan.m_scanPos.m_loc; NodeHandle node(frag); selectNode(signal, node, loc, AccHead); selectNode(signal, node, loc); unlinkScan(node, scanPtr); scan.m_scanPos.m_loc = NullTupLoc; } Loading Loading @@ -350,7 +350,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) if (scan.m_lockwait) { jam(); // LQH asks if we are waiting for lock and we tell it to ask again const TreeEnt ent = scan.m_scanPos.m_ent; const TreeEnt ent = scan.m_scanEnt; NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend(); conf->scanPtr = scan.m_userPtr; conf->accOperationPtr = RNIL; // no tuple returned Loading Loading @@ -385,7 +385,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) ndbrequire(scan.m_accLockOp == RNIL); if (! scan.m_readCommitted) { jam(); const TreeEnt ent = scan.m_scanPos.m_ent; const TreeEnt ent = scan.m_scanEnt; // read tuple key readTablePk(frag, ent, pkData, pkSize); // get read lock or exclusive lock Loading Loading @@ -473,7 +473,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) // we have lock or do not need one jam(); // read keys if not already done (uses signal) const TreeEnt ent = scan.m_scanPos.m_ent; const TreeEnt ent = scan.m_scanEnt; if (scan.m_keyInfo) { jam(); if (pkSize == 0) { Loading Loading @@ -536,8 +536,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) total += length; } } // remember last entry returned scan.m_lastEnt = ent; // next time look for next entry scan.m_state = ScanOp::Next; return; Loading Loading @@ -712,20 +710,21 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr) scan.m_state = ScanOp::Next; // link the scan to node found NodeHandle node(frag); selectNode(signal, node, treePos.m_loc, AccFull); selectNode(signal, node, treePos.m_loc); linkScan(node, scanPtr); } /* * Move to next entry. The scan is already linked to some node. When * we leave, if any entry was found, it will be linked to a possibly * different node. The scan has a direction, one of: * different node. The scan has a position, and a direction which tells * from where we came to this position. This is one of: * * 0 - coming up from left child * 1 - coming up from right child (proceed to parent immediately) * 2 - coming up from root (the scan ends) * 3 - left to right within node * 4 - coming down from parent to left or right child * 0 - up from left child (scan this node next) * 1 - up from right child (proceed to parent) * 2 - up from root (the scan ends) * 3 - left to right within node (at end proceed to right child) * 4 - down from parent (proceed to left child) */ void Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) Loading Loading @@ -768,10 +767,12 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) TreePos pos = scan.m_scanPos; // get and remember original node NodeHandle origNode(frag); selectNode(signal, origNode, pos.m_loc, AccHead); selectNode(signal, origNode, pos.m_loc); ndbrequire(islinkScan(origNode, scanPtr)); // current node in loop NodeHandle node = origNode; // copy of entry found TreeEnt ent; while (true) { jam(); if (pos.m_dir == 2) { Loading @@ -783,7 +784,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) } if (node.m_loc != pos.m_loc) { jam(); selectNode(signal, node, pos.m_loc, AccHead); selectNode(signal, node, pos.m_loc); } if (pos.m_dir == 4) { // coming down from parent proceed to left child Loading @@ -799,7 +800,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_dir = 0; } if (pos.m_dir == 0) { // coming from left child scan current node // coming up from left child scan current node jam(); pos.m_pos = 0; pos.m_match = false; Loading @@ -810,8 +811,6 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) jam(); unsigned occup = node.getOccup(); ndbrequire(occup >= 1); // access full node accessNode(signal, node, AccFull); // advance position if (! pos.m_match) pos.m_match = true; Loading @@ -819,10 +818,10 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_pos++; if (pos.m_pos < occup) { jam(); pos.m_ent = node.getEnt(pos.m_pos); ent = node.getEnt(pos.m_pos); pos.m_dir = 3; // unchanged // read and compare all attributes readKeyAttrs(frag, pos.m_ent, 0, c_entryKey); readKeyAttrs(frag, ent, 0, c_entryKey); int ret = cmpScanBound(frag, 1, c_dataBuffer, scan.m_boundCnt[1], c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); if (ret < 0) { Loading @@ -833,7 +832,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) break; } // can we see it if (! scanVisible(signal, scanPtr, pos.m_ent)) { if (! scanVisible(signal, scanPtr, ent)) { jam(); continue; } Loading @@ -853,7 +852,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_dir = 1; } if (pos.m_dir == 1) { // coming from right child proceed to parent // coming up from right child proceed to parent jam(); pos.m_loc = node.getLink(2); pos.m_dir = node.getSide(); Loading @@ -871,6 +870,8 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) unlinkScan(origNode, scanPtr); linkScan(node, scanPtr); } // copy found entry scan.m_scanEnt = ent; } else if (scan.m_state == ScanOp::Last) { jam(); ndbrequire(pos.m_loc == NullTupLoc); Loading @@ -888,7 +889,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) /* * Check if an entry is visible to the scan. * * There is a special check to never return same tuple twice in a row. * There is a special check to never accept same tuple twice in a row. * This is faster than asking TUP. It also fixes some special cases * which are not analyzed or handled yet. */ Loading @@ -903,8 +904,8 @@ Dbtux::scanVisible(Signal* signal, ScanOpPtr scanPtr, TreeEnt ent) Uint32 tupAddr = getTupAddr(frag, ent); Uint32 tupVersion = ent.m_tupVersion; // check for same tuple twice in row if (scan.m_lastEnt.m_tupLoc == ent.m_tupLoc && scan.m_lastEnt.m_fragBit == fragBit) { if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc && scan.m_scanEnt.m_fragBit == fragBit) { jam(); return false; } Loading