mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
NDB dbtux minor change
This commit is contained in:
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
|
@@ -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;
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -968,8 +971,7 @@ Dbtux::TreePos::TreePos() :
|
||||
m_loc(),
|
||||
m_pos(ZNIL),
|
||||
m_match(false),
|
||||
m_dir(255),
|
||||
m_ent()
|
||||
m_dir(255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1010,7 +1012,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;
|
||||
|
@@ -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;
|
||||
}
|
||||
@@ -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];
|
||||
|
@@ -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
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
@@ -719,13 +717,14 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr 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)
|
||||
@@ -772,6 +771,8 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
|
||||
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) {
|
||||
@@ -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;
|
||||
@@ -819,10 +820,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) {
|
||||
@@ -833,7 +834,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;
|
||||
}
|
||||
@@ -853,7 +854,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();
|
||||
@@ -871,6 +872,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);
|
||||
@@ -888,7 +891,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.
|
||||
*/
|
||||
@@ -903,8 +906,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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user