Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
d3b0753d
Commit
d3b0753d
authored
Jun 17, 2004
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-4.1
into mc05.(none):/space2/tomas/mysql-4.1-ndb-test
parents
a9eb4993
6b099d2c
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1056 additions
and
1323 deletions
+1056
-1323
ndb/include/kernel/signaldata/TupAccess.hpp
ndb/include/kernel/signaldata/TupAccess.hpp
+2
-0
ndb/include/kernel/signaldata/TupFrag.hpp
ndb/include/kernel/signaldata/TupFrag.hpp
+4
-1
ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+1
-0
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+12
-0
ndb/src/kernel/blocks/dbtup/Dbtup.hpp
ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+8
-0
ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
+58
-0
ndb/src/kernel/blocks/dbtux/Dbtux.hpp
ndb/src/kernel/blocks/dbtux/Dbtux.hpp
+289
-261
ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+44
-32
ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
+4
-2
ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
+8
-106
ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
+8
-8
ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
+179
-292
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
+51
-64
ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp
ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp
+216
-217
ndb/src/kernel/blocks/dbtux/Makefile.am
ndb/src/kernel/blocks/dbtux/Makefile.am
+2
-0
ndb/src/kernel/blocks/dbtux/Times.txt
ndb/src/kernel/blocks/dbtux/Times.txt
+37
-0
ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+3
-3
ndb/test/ndbapi/testOIBasic.cpp
ndb/test/ndbapi/testOIBasic.cpp
+51
-10
ndb/test/run-test/make-html-reports.sh
ndb/test/run-test/make-html-reports.sh
+79
-327
No files found.
ndb/include/kernel/signaldata/TupAccess.hpp
View file @
d3b0753d
...
@@ -129,6 +129,8 @@ private:
...
@@ -129,6 +129,8 @@ private:
/*
/*
* Operate on entire tuple. Used by TUX where the table has a single
* Operate on entire tuple. Used by TUX where the table has a single
* Uint32 array attribute representing an index tree node.
* Uint32 array attribute representing an index tree node.
*
* XXX this signal is no longer used by TUX and can be removed
*/
*/
class
TupStoreTh
{
class
TupStoreTh
{
friend
class
Dbtup
;
friend
class
Dbtup
;
...
...
ndb/include/kernel/signaldata/TupFrag.hpp
View file @
d3b0753d
...
@@ -69,7 +69,7 @@ class TuxFragReq {
...
@@ -69,7 +69,7 @@ class TuxFragReq {
friend
class
Dblqh
;
friend
class
Dblqh
;
friend
class
Dbtux
;
friend
class
Dbtux
;
public:
public:
STATIC_CONST
(
SignalLength
=
9
);
STATIC_CONST
(
SignalLength
=
14
);
private:
private:
Uint32
userPtr
;
Uint32
userPtr
;
Uint32
userRef
;
Uint32
userRef
;
...
@@ -80,6 +80,9 @@ private:
...
@@ -80,6 +80,9 @@ private:
Uint32
fragOff
;
Uint32
fragOff
;
Uint32
tableType
;
Uint32
tableType
;
Uint32
primaryTableId
;
Uint32
primaryTableId
;
Uint32
tupIndexFragPtrI
;
Uint32
tupTableFragPtrI
[
2
];
Uint32
accTableFragPtrI
[
2
];
};
};
class
TuxFragConf
{
class
TuxFragConf
{
...
...
ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
View file @
d3b0753d
...
@@ -2432,6 +2432,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
...
@@ -2432,6 +2432,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
}
}
fragrecptr
.
i
=
req
->
fragPtrI
;
fragrecptr
.
i
=
req
->
fragPtrI
;
ptrCheckGuard
(
fragrecptr
,
cfragmentsize
,
fragmentrec
);
ptrCheckGuard
(
fragrecptr
,
cfragmentsize
,
fragmentrec
);
ndbrequire
(
req
->
fragId
==
fragrecptr
.
p
->
myfid
);
// caller must be explicit here
// caller must be explicit here
ndbrequire
(
req
->
accOpPtr
==
RNIL
);
ndbrequire
(
req
->
accOpPtr
==
RNIL
);
// seize operation to hold the lock
// seize operation to hold the lock
...
...
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
View file @
d3b0753d
...
@@ -1225,6 +1225,18 @@ Dblqh::sendAddFragReq(Signal* signal)
...
@@ -1225,6 +1225,18 @@ Dblqh::sendAddFragReq(Signal* signal)
tuxreq
->
fragOff
=
addfragptr
.
p
->
lh3DistrBits
;
tuxreq
->
fragOff
=
addfragptr
.
p
->
lh3DistrBits
;
tuxreq
->
tableType
=
addfragptr
.
p
->
tableType
;
tuxreq
->
tableType
=
addfragptr
.
p
->
tableType
;
tuxreq
->
primaryTableId
=
addfragptr
.
p
->
primaryTableId
;
tuxreq
->
primaryTableId
=
addfragptr
.
p
->
primaryTableId
;
// pointer to index fragment in TUP
tuxreq
->
tupIndexFragPtrI
=
addfragptr
.
p
->
addfragStatus
==
AddFragRecord
::
WAIT_TWO_TUX
?
fragptr
.
p
->
tupFragptr
[
0
]
:
fragptr
.
p
->
tupFragptr
[
1
];
// pointers to table fragments in TUP and ACC
FragrecordPtr
tFragPtr
;
tFragPtr
.
i
=
fragptr
.
p
->
tableFragptr
;
ptrCheckGuard
(
tFragPtr
,
cfragrecFileSize
,
fragrecord
);
tuxreq
->
tupTableFragPtrI
[
0
]
=
tFragPtr
.
p
->
tupFragptr
[
0
];
tuxreq
->
tupTableFragPtrI
[
1
]
=
tFragPtr
.
p
->
tupFragptr
[
1
];
tuxreq
->
accTableFragPtrI
[
0
]
=
tFragPtr
.
p
->
accFragptr
[
0
];
tuxreq
->
accTableFragPtrI
[
1
]
=
tFragPtr
.
p
->
accFragptr
[
1
];
sendSignal
(
fragptr
.
p
->
tuxBlockref
,
GSN_TUXFRAGREQ
,
sendSignal
(
fragptr
.
p
->
tuxBlockref
,
GSN_TUXFRAGREQ
,
signal
,
TuxFragReq
::
SignalLength
,
JBB
);
signal
,
TuxFragReq
::
SignalLength
,
JBB
);
return
;
return
;
...
...
ndb/src/kernel/blocks/dbtup/Dbtup.hpp
View file @
d3b0753d
...
@@ -996,6 +996,14 @@ public:
...
@@ -996,6 +996,14 @@ public:
Dbtup
(
const
class
Configuration
&
);
Dbtup
(
const
class
Configuration
&
);
virtual
~
Dbtup
();
virtual
~
Dbtup
();
/*
* TUX index in TUP has single Uint32 array attribute which stores an
* index node. TUX uses following methods.
*/
int
tuxAllocNode
(
Signal
*
signal
,
Uint32
fragPtrI
,
Uint32
&
pageId
,
Uint32
&
pageOffset
,
Uint32
*&
node
);
void
tuxFreeNode
(
Signal
*
signal
,
Uint32
fragPtrI
,
Uint32
pageId
,
Uint32
pageOffset
,
Uint32
*
node
);
void
tuxGetNode
(
Uint32
fragPtrI
,
Uint32
pageId
,
Uint32
pageOffset
,
Uint32
*&
node
);
private
:
private
:
BLOCK_DEFINES
(
Dbtup
);
BLOCK_DEFINES
(
Dbtup
);
...
...
ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
View file @
d3b0753d
...
@@ -179,6 +179,64 @@ Dbtup::execTUP_QUERY_TH(Signal* signal)
...
@@ -179,6 +179,64 @@ Dbtup::execTUP_QUERY_TH(Signal* signal)
return
;
return
;
}
}
int
Dbtup
::
tuxAllocNode
(
Signal
*
signal
,
Uint32
fragPtrI
,
Uint32
&
pageId
,
Uint32
&
pageOffset
,
Uint32
*&
node
)
{
FragrecordPtr
fragPtr
;
fragPtr
.
i
=
fragPtrI
;
ptrCheckGuard
(
fragPtr
,
cnoOfFragrec
,
fragrecord
);
TablerecPtr
tablePtr
;
tablePtr
.
i
=
fragPtr
.
p
->
fragTableId
;
ptrCheckGuard
(
tablePtr
,
cnoOfTablerec
,
tablerec
);
PagePtr
pagePtr
;
terrorCode
=
0
;
if
(
!
allocTh
(
fragPtr
.
p
,
tablePtr
.
p
,
NORMAL_PAGE
,
signal
,
pageOffset
,
pagePtr
))
{
jam
();
ndbrequire
(
terrorCode
!=
0
);
return
terrorCode
;
}
pageId
=
pagePtr
.
i
;
Uint32
attrDescIndex
=
tablePtr
.
p
->
tabDescriptor
+
(
0
<<
ZAD_LOG_SIZE
);
Uint32
attrDataOffset
=
AttributeOffset
::
getOffset
(
tableDescriptor
[
attrDescIndex
+
1
].
tabDescr
);
node
=
&
pagePtr
.
p
->
pageWord
[
pageOffset
]
+
attrDataOffset
;
return
0
;
}
void
Dbtup
::
tuxFreeNode
(
Signal
*
signal
,
Uint32
fragPtrI
,
Uint32
pageId
,
Uint32
pageOffset
,
Uint32
*
node
)
{
FragrecordPtr
fragPtr
;
fragPtr
.
i
=
fragPtrI
;
ptrCheckGuard
(
fragPtr
,
cnoOfFragrec
,
fragrecord
);
TablerecPtr
tablePtr
;
tablePtr
.
i
=
fragPtr
.
p
->
fragTableId
;
ptrCheckGuard
(
tablePtr
,
cnoOfTablerec
,
tablerec
);
PagePtr
pagePtr
;
pagePtr
.
i
=
pageId
;
ptrCheckGuard
(
pagePtr
,
cnoOfPage
,
page
);
Uint32
attrDescIndex
=
tablePtr
.
p
->
tabDescriptor
+
(
0
<<
ZAD_LOG_SIZE
);
Uint32
attrDataOffset
=
AttributeOffset
::
getOffset
(
tableDescriptor
[
attrDescIndex
+
1
].
tabDescr
);
ndbrequire
(
node
==
&
pagePtr
.
p
->
pageWord
[
pageOffset
]
+
attrDataOffset
);
freeTh
(
fragPtr
.
p
,
tablePtr
.
p
,
signal
,
pagePtr
.
p
,
pageOffset
);
}
void
Dbtup
::
tuxGetNode
(
Uint32
fragPtrI
,
Uint32
pageId
,
Uint32
pageOffset
,
Uint32
*&
node
)
{
FragrecordPtr
fragPtr
;
fragPtr
.
i
=
fragPtrI
;
ptrCheckGuard
(
fragPtr
,
cnoOfFragrec
,
fragrecord
);
TablerecPtr
tablePtr
;
tablePtr
.
i
=
fragPtr
.
p
->
fragTableId
;
ptrCheckGuard
(
tablePtr
,
cnoOfTablerec
,
tablerec
);
PagePtr
pagePtr
;
pagePtr
.
i
=
pageId
;
ptrCheckGuard
(
pagePtr
,
cnoOfPage
,
page
);
Uint32
attrDescIndex
=
tablePtr
.
p
->
tabDescriptor
+
(
0
<<
ZAD_LOG_SIZE
);
Uint32
attrDataOffset
=
AttributeOffset
::
getOffset
(
tableDescriptor
[
attrDescIndex
+
1
].
tabDescr
);
node
=
&
pagePtr
.
p
->
pageWord
[
pageOffset
]
+
attrDataOffset
;
}
void
void
Dbtup
::
execTUP_STORE_TH
(
Signal
*
signal
)
Dbtup
::
execTUP_STORE_TH
(
Signal
*
signal
)
{
{
...
...
ndb/src/kernel/blocks/dbtux/Dbtux.hpp
View file @
d3b0753d
...
@@ -25,6 +25,9 @@
...
@@ -25,6 +25,9 @@
#include <DataBuffer.hpp>
#include <DataBuffer.hpp>
#include <md5_hash.hpp>
#include <md5_hash.hpp>
// big brother
#include <Dbtup.hpp>
// signal classes
// signal classes
#include <signaldata/DictTabInfo.hpp>
#include <signaldata/DictTabInfo.hpp>
#include <signaldata/TuxContinueB.hpp>
#include <signaldata/TuxContinueB.hpp>
...
@@ -92,15 +95,13 @@ public:
...
@@ -92,15 +95,13 @@ public:
Dbtux
(
const
Configuration
&
conf
);
Dbtux
(
const
Configuration
&
conf
);
virtual
~
Dbtux
();
virtual
~
Dbtux
();
// pointer to TUP instance in this thread
Dbtup
*
c_tup
;
private:
private:
// sizes are in words (Uint32)
// sizes are in words (Uint32)
static
const
unsigned
MaxIndexFragments
=
2
*
NO_OF_FRAG_PER_NODE
;
static
const
unsigned
MaxIndexFragments
=
2
*
NO_OF_FRAG_PER_NODE
;
static
const
unsigned
MaxIndexAttributes
=
MAX_ATTRIBUTES_IN_INDEX
;
static
const
unsigned
MaxIndexAttributes
=
MAX_ATTRIBUTES_IN_INDEX
;
#ifdef VM_TRACE
static
const
unsigned
MaxNodeHandles
=
10000
;
// More space for printTree
#else
static
const
unsigned
MaxNodeHandles
=
128
;
// enough for 1 operation
#endif
static
const
unsigned
MaxAttrDataSize
=
2048
;
static
const
unsigned
MaxAttrDataSize
=
2048
;
public:
public:
static
const
unsigned
DescPageSize
=
256
;
static
const
unsigned
DescPageSize
=
256
;
...
@@ -153,8 +154,7 @@ private:
...
@@ -153,8 +154,7 @@ private:
static
const
unsigned
AttributeHeaderSize
=
1
;
static
const
unsigned
AttributeHeaderSize
=
1
;
/*
/*
* Logical tuple address, "local key". Identifies both table tuples
* Logical tuple address, "local key". Identifies table tuples.
* and index tuples. The code assumes it is one word.
*/
*/
typedef
Uint32
TupAddr
;
typedef
Uint32
TupAddr
;
static
const
unsigned
NullTupAddr
=
(
Uint32
)
-
1
;
static
const
unsigned
NullTupAddr
=
(
Uint32
)
-
1
;
...
@@ -168,8 +168,18 @@ private:
...
@@ -168,8 +168,18 @@ private:
Uint32
m_pageId
;
// page i-value
Uint32
m_pageId
;
// page i-value
Uint16
m_pageOffset
;
// page offset in words
Uint16
m_pageOffset
;
// page offset in words
TupLoc
();
TupLoc
();
TupLoc
(
Uint32
pageId
,
Uint16
pageOffset
);
bool
operator
==
(
const
TupLoc
&
loc
)
const
;
bool
operator
!=
(
const
TupLoc
&
loc
)
const
;
};
};
/*
* There is no const member NullTupLoc since the compiler may not be
* able to optimize it to TupLoc() constants. Instead null values are
* constructed on the stack with TupLoc().
*/
#define NullTupLoc TupLoc()
// tree definitions
// tree definitions
/*
/*
...
@@ -183,7 +193,7 @@ private:
...
@@ -183,7 +193,7 @@ private:
TupAddr
m_tupAddr
;
// address of original tuple
TupAddr
m_tupAddr
;
// address of original tuple
Uint16
m_tupVersion
;
// version
Uint16
m_tupVersion
;
// version
Uint8
m_fragBit
;
// which duplicated table fragment
Uint8
m_fragBit
;
// which duplicated table fragment
Uint8
unuse
d1
;
Uint8
pa
d1
;
TreeEnt
();
TreeEnt
();
// methods
// methods
int
cmp
(
const
TreeEnt
ent
)
const
;
int
cmp
(
const
TreeEnt
ent
)
const
;
...
@@ -196,7 +206,7 @@ private:
...
@@ -196,7 +206,7 @@ private:
* prefix 3) max and min entries 4) rest of entries 5) one extra entry
* prefix 3) max and min entries 4) rest of entries 5) one extra entry
* used as work space.
* used as work space.
*
*
* struct TreeNode part 1
* struct TreeNode part 1
, size 6 words
* min prefix part 2, size TreeHead::m_prefSize
* min prefix part 2, size TreeHead::m_prefSize
* max prefix part 2, size TreeHead::m_prefSize
* max prefix part 2, size TreeHead::m_prefSize
* max entry part 3
* max entry part 3
...
@@ -204,6 +214,10 @@ private:
...
@@ -204,6 +214,10 @@ private:
* rest of entries part 4
* rest of entries part 4
* work entry part 5
* work entry part 5
*
*
* There are 3 links to other nodes: left child, right child, parent.
* These are in TupLoc format but the pageIds and pageOffsets are
* stored in separate arrays (saves 1 word).
*
* Occupancy (number of entries) is at least 1 except temporarily when
* Occupancy (number of entries) is at least 1 except temporarily when
* a node is about to be removed. If occupancy is 1, only max entry
* a node is about to be removed. If occupancy is 1, only max entry
* is present but both min and max prefixes are set.
* is present but both min and max prefixes are set.
...
@@ -211,11 +225,12 @@ private:
...
@@ -211,11 +225,12 @@ private:
struct
TreeNode
;
struct
TreeNode
;
friend
struct
TreeNode
;
friend
struct
TreeNode
;
struct
TreeNode
{
struct
TreeNode
{
TupAddr
m_link
[
3
];
// link to 0-left child 1-right child 2-parent
Uint32
m_linkPI
[
3
];
// link to 0-left child 1-right child 2-parent
Uint8
m_side
;
// we are 0-left child 1-right child 2-root
Uint16
m_linkPO
[
3
];
// page offsets for above real page ids
unsigned
m_side
:
2
;
// we are 0-left child 1-right child 2-root
int
m_balance
:
2
;
// balance -1, 0, +1
unsigned
pad1
:
4
;
Uint8
m_occup
;
// current number of entries
Uint8
m_occup
;
// current number of entries
Int8
m_balance
;
// balance -1, 0, +1
Uint8
unused1
;
Uint32
m_nodeScan
;
// list of scans at this node
Uint32
m_nodeScan
;
// list of scans at this node
TreeNode
();
TreeNode
();
};
};
...
@@ -243,7 +258,7 @@ private:
...
@@ -243,7 +258,7 @@ private:
Uint8
m_prefSize
;
// words in min/max prefix each
Uint8
m_prefSize
;
// words in min/max prefix each
Uint8
m_minOccup
;
// min entries in internal node
Uint8
m_minOccup
;
// min entries in internal node
Uint8
m_maxOccup
;
// max entries in node
Uint8
m_maxOccup
;
// max entries in node
Tup
Addr
m_root
;
// root node
Tup
Loc
m_root
;
// root node
TreeHead
();
TreeHead
();
// methods
// methods
unsigned
getSize
(
AccSize
acc
)
const
;
unsigned
getSize
(
AccSize
acc
)
const
;
...
@@ -261,8 +276,7 @@ private:
...
@@ -261,8 +276,7 @@ private:
struct
TreePos
;
struct
TreePos
;
friend
struct
TreePos
;
friend
struct
TreePos
;
struct
TreePos
{
struct
TreePos
{
TupAddr
m_addr
;
// logical node address
TupLoc
m_loc
;
// physical node address
TupLoc
m_loc
;
// physical address
Uint16
m_pos
;
// position 0 to m_occup
Uint16
m_pos
;
// position 0 to m_occup
Uint8
m_match
;
// at an existing entry
Uint8
m_match
;
// at an existing entry
Uint8
m_dir
;
// from link (0-2) or within node (3)
Uint8
m_dir
;
// from link (0-2) or within node (3)
...
@@ -443,9 +457,11 @@ private:
...
@@ -443,9 +457,11 @@ private:
Uint16
m_descOff
;
Uint16
m_descOff
;
Uint16
m_numAttrs
;
Uint16
m_numAttrs
;
TreeHead
m_tree
;
TreeHead
m_tree
;
Uint32
m_nodeList
;
// node cache of current operation
TupLoc
m_freeLoc
;
// one node pre-allocated for insert
Uint32
m_nodeFree
;
// one node pre-allocated for insert
DLList
<
ScanOp
>
m_scanList
;
// current scans on this fragment
DLList
<
ScanOp
>
m_scanList
;
// current scans on this fragment
Uint32
m_tupIndexFragPtrI
;
Uint32
m_tupTableFragPtrI
[
2
];
Uint32
m_accTableFragPtrI
[
2
];
union
{
union
{
Uint32
nextPool
;
Uint32
nextPool
;
};
};
...
@@ -476,62 +492,39 @@ private:
...
@@ -476,62 +492,39 @@ private:
// node handles
// node handles
/*
/*
* A tree operation builds a cache of accessed nodes. This allows
* A node handle is a reference to a tree node in TUP. It is used to
* different implementations of index memory access. The cache is
* operate on the node. Node handles are allocated on the stack.
* committed and released at the end of the operation.
*/
*/
struct
NodeHandle
;
struct
NodeHandle
;
friend
struct
NodeHandle
;
friend
struct
NodeHandle
;
struct
NodeHandle
{
struct
NodeHandle
{
enum
Flags
{
// bits 0,1 mark need for left,right prefix
DoInsert
=
(
1
<<
2
),
DoDelete
=
(
1
<<
3
),
DoUpdate
=
(
1
<<
4
)
};
Dbtux
&
m_tux
;
// this block
Frag
&
m_frag
;
// fragment using the node
Frag
&
m_frag
;
// fragment using the node
TupAddr
m_addr
;
// logical node address
TupLoc
m_loc
;
// physical node address
TupLoc
m_loc
;
// physical node address
AccSize
m_acc
;
// accessed size
unsigned
m_flags
;
// flags
union
{
Uint32
m_next
;
// next active node under fragment
Uint32
nextPool
;
};
TreeNode
*
m_node
;
// pointer to node storage
TreeNode
*
m_node
;
// pointer to node storage
Uint32
m_cache
[
MaxTreeNodeSize
];
AccSize
m_acc
;
// accessed size
NodeHandle
(
Dbtux
&
tux
,
Frag
&
frag
);
NodeHandle
(
Frag
&
frag
);
NodeHandle
(
const
NodeHandle
&
node
);
NodeHandle
&
operator
=
(
const
NodeHandle
&
node
);
// getters
// getters
Tup
Addr
getLink
(
unsigned
i
);
Tup
Loc
getLink
(
unsigned
i
);
unsigned
getChilds
();
// cannot spell
unsigned
getChilds
();
// cannot spell
unsigned
getSide
();
unsigned
getSide
();
unsigned
getOccup
();
unsigned
getOccup
();
int
getBalance
();
int
getBalance
();
Uint32
getNodeScan
();
Uint32
getNodeScan
();
Data
getPref
(
unsigned
i
);
TreeEnt
getEnt
(
unsigned
pos
);
TreeEnt
getMinMax
(
unsigned
i
);
// setters
// setters
void
setLink
(
unsigned
i
,
Tup
Addr
addr
);
void
setLink
(
unsigned
i
,
Tup
Loc
loc
);
void
setSide
(
unsigned
i
);
void
setSide
(
unsigned
i
);
void
setOccup
(
unsigned
n
);
void
setOccup
(
unsigned
n
);
void
setBalance
(
int
b
);
void
setBalance
(
int
b
);
void
setNodeScan
(
Uint32
scanPtrI
);
void
setNodeScan
(
Uint32
scanPtrI
);
// operations XXX maybe these should move to Dbtux level
// access other parts of the node
void
pushUp
(
Signal
*
signal
,
unsigned
pos
,
const
TreeEnt
&
ent
);
Data
getPref
(
unsigned
i
);
void
popDown
(
Signal
*
signal
,
unsigned
pos
,
TreeEnt
&
ent
);
TreeEnt
getEnt
(
unsigned
pos
);
void
pushDown
(
Signal
*
signal
,
unsigned
pos
,
TreeEnt
&
ent
);
TreeEnt
getMinMax
(
unsigned
i
);
void
popUp
(
Signal
*
signal
,
unsigned
pos
,
TreeEnt
&
ent
);
// for ndbrequire and ndbassert
void
slide
(
Signal
*
signal
,
Ptr
<
NodeHandle
>
nodePtr
,
unsigned
i
);
void
progError
(
int
line
,
int
cause
,
const
char
*
file
);
void
linkScan
(
Dbtux
::
ScanOpPtr
scanPtr
);
void
unlinkScan
(
Dbtux
::
ScanOpPtr
scanPtr
);
bool
islinkScan
(
Dbtux
::
ScanOpPtr
scanPtr
);
// for ndbrequire
void
progError
(
int
line
,
int
cause
,
const
char
*
extra
);
};
};
typedef
Ptr
<
NodeHandle
>
NodeHandlePtr
;
ArrayPool
<
NodeHandle
>
c_nodeHandlePool
;
// parameters for methods
// parameters for methods
...
@@ -562,17 +555,6 @@ private:
...
@@ -562,17 +555,6 @@ private:
ReadPar
();
ReadPar
();
};
};
/*
* Node storage operation.
*/
struct
StorePar
{
TupStoreTh
::
OpCode
m_opCode
;
// operation code
unsigned
m_offset
;
// data offset in words
unsigned
m_size
;
// number of words
Uint32
m_errorCode
;
// terrorCode from TUP
StorePar
();
};
/*
/*
* Tree search for entry.
* Tree search for entry.
*/
*/
...
@@ -642,20 +624,26 @@ private:
...
@@ -642,20 +624,26 @@ private:
void
execTUX_MAINT_REQ
(
Signal
*
signal
);
void
execTUX_MAINT_REQ
(
Signal
*
signal
);
void
tupReadAttrs
(
Signal
*
signal
,
const
Frag
&
frag
,
ReadPar
&
readPar
);
void
tupReadAttrs
(
Signal
*
signal
,
const
Frag
&
frag
,
ReadPar
&
readPar
);
void
tupReadKeys
(
Signal
*
signal
,
const
Frag
&
frag
,
ReadPar
&
readPar
);
void
tupReadKeys
(
Signal
*
signal
,
const
Frag
&
frag
,
ReadPar
&
readPar
);
void
tupStoreTh
(
Signal
*
signal
,
const
Frag
&
frag
,
NodeHandlePtr
nodePtr
,
StorePar
storePar
);
/*
/*
* DbtuxNode.cpp
* DbtuxNode.cpp
*/
*/
void
seizeNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
);
int
allocNode
(
Signal
*
signal
,
NodeHandle
&
node
);
void
preallocNode
(
Signal
*
signal
,
Frag
&
frag
,
Uint32
&
errorCode
);
void
accessNode
(
Signal
*
signal
,
NodeHandle
&
node
,
AccSize
acc
);
void
findNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
TupAddr
addr
);
void
selectNode
(
Signal
*
signal
,
NodeHandle
&
node
,
TupLoc
loc
,
AccSize
acc
);
void
selectNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
TupAddr
addr
,
AccSize
acc
);
void
insertNode
(
Signal
*
signal
,
NodeHandle
&
node
,
AccSize
acc
);
void
insertNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
AccSize
acc
);
void
deleteNode
(
Signal
*
signal
,
NodeHandle
&
node
);
void
deleteNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
);
void
setNodePref
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
i
);
void
accessNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
AccSize
acc
);
// node operations
void
setNodePref
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
unsigned
i
);
void
nodePushUp
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
const
TreeEnt
&
ent
);
void
commitNodes
(
Signal
*
signal
,
Frag
&
frag
,
bool
updateOk
);
void
nodePopDown
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
TreeEnt
&
ent
);
void
nodePushDown
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
TreeEnt
&
ent
);
void
nodePopUp
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
TreeEnt
&
ent
);
void
nodeSlide
(
Signal
*
signal
,
NodeHandle
&
dstNode
,
NodeHandle
&
srcNode
,
unsigned
i
);
// scans linked to node
void
linkScan
(
NodeHandle
&
node
,
ScanOpPtr
scanPtr
);
void
unlinkScan
(
NodeHandle
&
node
,
ScanOpPtr
scanPtr
);
bool
islinkScan
(
NodeHandle
&
node
,
ScanOpPtr
scanPtr
);
/*
/*
* DbtuxTree.cpp
* DbtuxTree.cpp
...
@@ -663,8 +651,8 @@ private:
...
@@ -663,8 +651,8 @@ private:
void
treeSearch
(
Signal
*
signal
,
Frag
&
frag
,
SearchPar
searchPar
,
TreePos
&
treePos
);
void
treeSearch
(
Signal
*
signal
,
Frag
&
frag
,
SearchPar
searchPar
,
TreePos
&
treePos
);
void
treeAdd
(
Signal
*
signal
,
Frag
&
frag
,
TreePos
treePos
,
TreeEnt
ent
);
void
treeAdd
(
Signal
*
signal
,
Frag
&
frag
,
TreePos
treePos
,
TreeEnt
ent
);
void
treeRemove
(
Signal
*
signal
,
Frag
&
frag
,
TreePos
treePos
);
void
treeRemove
(
Signal
*
signal
,
Frag
&
frag
,
TreePos
treePos
);
void
treeRotateSingle
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandle
Ptr
&
nodePtr
,
unsigned
i
);
void
treeRotateSingle
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandle
&
node
,
unsigned
i
);
void
treeRotateDouble
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandle
Ptr
&
nodePtr
,
unsigned
i
);
void
treeRotateDouble
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandle
&
node
,
unsigned
i
);
/*
/*
* DbtuxScan.cpp
* DbtuxScan.cpp
...
@@ -698,23 +686,24 @@ private:
...
@@ -698,23 +686,24 @@ private:
struct
PrintPar
{
struct
PrintPar
{
char
m_path
[
100
];
// LR prefix
char
m_path
[
100
];
// LR prefix
unsigned
m_side
;
// expected side
unsigned
m_side
;
// expected side
Tup
Addr
m_parent
;
// expected parent address
Tup
Loc
m_parent
;
// expected parent address
int
m_depth
;
// returned depth
int
m_depth
;
// returned depth
unsigned
m_occup
;
// returned occupancy
unsigned
m_occup
;
// returned occupancy
bool
m_ok
;
// returned status
bool
m_ok
;
// returned status
PrintPar
();
PrintPar
();
};
};
void
printTree
(
Signal
*
signal
,
Frag
&
frag
,
NdbOut
&
out
);
void
printTree
(
Signal
*
signal
,
Frag
&
frag
,
NdbOut
&
out
);
void
printNode
(
Signal
*
signal
,
Frag
&
frag
,
NdbOut
&
out
,
TupAddr
addr
,
PrintPar
&
par
);
void
printNode
(
Signal
*
signal
,
Frag
&
frag
,
NdbOut
&
out
,
TupLoc
loc
,
PrintPar
&
par
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TupLoc
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreeEnt
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreeEnt
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreeNode
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreeNode
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreeHead
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreeHead
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreePos
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
TreePos
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
DescAttr
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
DescAttr
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
ScanOp
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
Index
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
Index
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
Frag
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
Frag
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
NodeHandle
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
NodeHandle
&
);
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
ScanOp
&
);
FILE
*
debugFile
;
FILE
*
debugFile
;
NdbOut
debugOut
;
NdbOut
debugOut
;
unsigned
debugFlags
;
unsigned
debugFlags
;
...
@@ -831,8 +820,45 @@ Dbtux::ConstData::operator=(Data data)
...
@@ -831,8 +820,45 @@ Dbtux::ConstData::operator=(Data data)
return
*
this
;
return
*
this
;
}
}
// Dbtux::TupLoc
inline
Dbtux
::
TupLoc
::
TupLoc
()
:
m_pageId
(
RNIL
),
m_pageOffset
(
0
)
{
}
inline
Dbtux
::
TupLoc
::
TupLoc
(
Uint32
pageId
,
Uint16
pageOffset
)
:
m_pageId
(
pageId
),
m_pageOffset
(
pageOffset
)
{
}
inline
bool
Dbtux
::
TupLoc
::
operator
==
(
const
TupLoc
&
loc
)
const
{
return
m_pageId
==
loc
.
m_pageId
&&
m_pageOffset
==
loc
.
m_pageOffset
;
}
inline
bool
Dbtux
::
TupLoc
::
operator
!=
(
const
TupLoc
&
loc
)
const
{
return
!
(
*
this
==
loc
);
}
// Dbtux::TreeEnt
// Dbtux::TreeEnt
inline
Dbtux
::
TreeEnt
::
TreeEnt
()
:
m_tupAddr
(
NullTupAddr
),
m_tupVersion
(
0
),
m_fragBit
(
255
),
pad1
(
0
)
{
}
inline
int
inline
int
Dbtux
::
TreeEnt
::
cmp
(
const
TreeEnt
ent
)
const
Dbtux
::
TreeEnt
::
cmp
(
const
TreeEnt
ent
)
const
{
{
...
@@ -852,8 +878,36 @@ Dbtux::TreeEnt::cmp(const TreeEnt ent) const
...
@@ -852,8 +878,36 @@ Dbtux::TreeEnt::cmp(const TreeEnt ent) const
return
0
;
return
0
;
}
}
// Dbtux::TreeNode
inline
Dbtux
::
TreeNode
::
TreeNode
()
:
m_side
(
2
),
m_balance
(
0
),
pad1
(
0
),
m_occup
(
0
),
m_nodeScan
(
RNIL
)
{
m_linkPI
[
0
]
=
NullTupLoc
.
m_pageId
;
m_linkPO
[
0
]
=
NullTupLoc
.
m_pageOffset
;
m_linkPI
[
1
]
=
NullTupLoc
.
m_pageId
;
m_linkPO
[
1
]
=
NullTupLoc
.
m_pageOffset
;
m_linkPI
[
2
]
=
NullTupLoc
.
m_pageId
;
m_linkPO
[
2
]
=
NullTupLoc
.
m_pageOffset
;
}
// Dbtux::TreeHead
// Dbtux::TreeHead
inline
Dbtux
::
TreeHead
::
TreeHead
()
:
m_nodeSize
(
0
),
m_prefSize
(
0
),
m_minOccup
(
0
),
m_maxOccup
(
0
),
m_root
()
{
}
inline
unsigned
inline
unsigned
Dbtux
::
TreeHead
::
getSize
(
AccSize
acc
)
const
Dbtux
::
TreeHead
::
getSize
(
AccSize
acc
)
const
{
{
...
@@ -885,52 +939,10 @@ Dbtux::TreeHead::getEntList(TreeNode* node) const
...
@@ -885,52 +939,10 @@ Dbtux::TreeHead::getEntList(TreeNode* node) const
return
(
TreeEnt
*
)
ptr
;
return
(
TreeEnt
*
)
ptr
;
}
}
// Dbtux
// Dbtux::TreePos
// constructors
inline
Dbtux
::
TupLoc
::
TupLoc
()
:
m_pageId
(
RNIL
),
m_pageOffset
(
0
)
{
}
inline
Dbtux
::
TreeEnt
::
TreeEnt
()
:
m_tupAddr
(
NullTupAddr
),
m_tupVersion
(
0
),
m_fragBit
(
255
),
unused1
(
0
)
{
}
inline
Dbtux
::
TreeNode
::
TreeNode
()
:
m_side
(
255
),
m_occup
(
0
),
m_balance
(
0
),
unused1
(
0xa1
),
m_nodeScan
(
RNIL
)
{
m_link
[
0
]
=
NullTupAddr
;
m_link
[
1
]
=
NullTupAddr
;
m_link
[
2
]
=
NullTupAddr
;
}
inline
Dbtux
::
TreeHead
::
TreeHead
()
:
m_nodeSize
(
0
),
m_prefSize
(
0
),
m_minOccup
(
0
),
m_maxOccup
(
0
),
m_root
(
0
)
{
}
inline
inline
Dbtux
::
TreePos
::
TreePos
()
:
Dbtux
::
TreePos
::
TreePos
()
:
m_addr
(
NullTupAddr
),
m_loc
(),
m_loc
(),
m_pos
(
ZNIL
),
m_pos
(
ZNIL
),
m_match
(
false
),
m_match
(
false
),
...
@@ -939,6 +951,8 @@ Dbtux::TreePos::TreePos() :
...
@@ -939,6 +951,8 @@ Dbtux::TreePos::TreePos() :
{
{
}
}
// Dbtux::DescPage
inline
inline
Dbtux
::
DescPage
::
DescPage
()
:
Dbtux
::
DescPage
::
DescPage
()
:
m_nextPage
(
RNIL
),
m_nextPage
(
RNIL
),
...
@@ -953,6 +967,41 @@ Dbtux::DescPage::DescPage() :
...
@@ -953,6 +967,41 @@ Dbtux::DescPage::DescPage() :
}
}
}
}
// Dbtux::ScanOp
inline
Dbtux
::
ScanOp
::
ScanOp
(
ScanBoundPool
&
scanBoundPool
)
:
m_state
(
Undef
),
m_lockwait
(
false
),
m_userPtr
(
RNIL
),
m_userRef
(
RNIL
),
m_tableId
(
RNIL
),
m_indexId
(
RNIL
),
m_fragPtrI
(
RNIL
),
m_transId1
(
0
),
m_transId2
(
0
),
m_savePointId
(
0
),
m_accLockOp
(
RNIL
),
m_readCommitted
(
0
),
m_lockMode
(
0
),
m_keyInfo
(
0
),
m_boundMin
(
scanBoundPool
),
m_boundMax
(
scanBoundPool
),
m_scanPos
(),
m_lastEnt
(),
m_nodeScan
(
RNIL
)
{
m_bound
[
0
]
=
&
m_boundMin
;
m_bound
[
1
]
=
&
m_boundMax
;
m_boundCnt
[
0
]
=
0
;
m_boundCnt
[
1
]
=
0
;
for
(
unsigned
i
=
0
;
i
<
MaxAccLockOps
;
i
++
)
{
m_accLockOps
[
i
]
=
RNIL
;
}
}
// Dbtux::Index
inline
inline
Dbtux
::
Index
::
Index
()
:
Dbtux
::
Index
::
Index
()
:
m_state
(
NotDefined
),
m_state
(
NotDefined
),
...
@@ -969,6 +1018,8 @@ Dbtux::Index::Index() :
...
@@ -969,6 +1018,8 @@ Dbtux::Index::Index() :
};
};
};
};
// Dbtux::Frag
inline
inline
Dbtux
::
Frag
::
Frag
(
ArrayPool
<
ScanOp
>&
scanOpPool
)
:
Dbtux
::
Frag
::
Frag
(
ArrayPool
<
ScanOp
>&
scanOpPool
)
:
m_tableId
(
RNIL
),
m_tableId
(
RNIL
),
...
@@ -979,12 +1030,18 @@ Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) :
...
@@ -979,12 +1030,18 @@ Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) :
m_descOff
(
0
),
m_descOff
(
0
),
m_numAttrs
(
ZNIL
),
m_numAttrs
(
ZNIL
),
m_tree
(),
m_tree
(),
m_
nodeList
(
RNIL
),
m_
freeLoc
(
),
m_
nodeFree
(
RNIL
),
m_
scanList
(
scanOpPool
),
m_
scanList
(
scanOpPool
)
m_
tupIndexFragPtrI
(
RNIL
)
{
{
m_tupTableFragPtrI
[
0
]
=
RNIL
;
m_tupTableFragPtrI
[
1
]
=
RNIL
;
m_accTableFragPtrI
[
0
]
=
RNIL
;
m_accTableFragPtrI
[
1
]
=
RNIL
;
}
}
// Dbtux::FragOp
inline
inline
Dbtux
::
FragOp
::
FragOp
()
:
Dbtux
::
FragOp
::
FragOp
()
:
m_userPtr
(
RNIL
),
m_userPtr
(
RNIL
),
...
@@ -997,160 +1054,107 @@ Dbtux::FragOp::FragOp() :
...
@@ -997,160 +1054,107 @@ Dbtux::FragOp::FragOp() :
{
{
};
};
// Dbtux::NodeHandle
inline
inline
Dbtux
::
NodeHandle
::
NodeHandle
(
Dbtux
&
tux
,
Frag
&
frag
)
:
Dbtux
::
NodeHandle
::
NodeHandle
(
Frag
&
frag
)
:
m_tux
(
tux
),
m_frag
(
frag
),
m_frag
(
frag
),
m_addr
(
NullTupAddr
),
m_loc
(),
m_loc
(),
m_acc
(
AccNone
),
m_node
(
0
),
m_flags
(
0
),
m_acc
(
AccNone
)
m_next
(
RNIL
),
m_node
(
0
)
{
{
}
}
inline
inline
Dbtux
::
ScanOp
::
ScanOp
(
ScanBoundPool
&
scanBoundPool
)
:
Dbtux
::
NodeHandle
::
NodeHandle
(
const
NodeHandle
&
node
)
:
m_state
(
Undef
),
m_frag
(
node
.
m_frag
),
m_lockwait
(
false
),
m_loc
(
node
.
m_loc
),
m_userPtr
(
RNIL
),
m_node
(
node
.
m_node
),
m_userRef
(
RNIL
),
m_acc
(
node
.
m_acc
)
m_tableId
(
RNIL
),
m_indexId
(
RNIL
),
m_fragPtrI
(
RNIL
),
m_transId1
(
0
),
m_transId2
(
0
),
m_savePointId
(
0
),
m_accLockOp
(
RNIL
),
m_readCommitted
(
0
),
m_lockMode
(
0
),
m_keyInfo
(
0
),
m_boundMin
(
scanBoundPool
),
m_boundMax
(
scanBoundPool
),
m_scanPos
(),
m_lastEnt
(),
m_nodeScan
(
RNIL
)
{
{
m_bound
[
0
]
=
&
m_boundMin
;
m_bound
[
1
]
=
&
m_boundMax
;
m_boundCnt
[
0
]
=
0
;
m_boundCnt
[
1
]
=
0
;
for
(
unsigned
i
=
0
;
i
<
MaxAccLockOps
;
i
++
)
{
m_accLockOps
[
i
]
=
RNIL
;
}
}
}
inline
inline
Dbtux
::
NodeHandle
&
Dbtux
::
CopyPar
::
CopyPar
()
:
Dbtux
::
NodeHandle
::
operator
=
(
const
NodeHandle
&
node
)
m_items
(
0
),
m_headers
(
true
),
m_maxwords
(
~
0
),
// max unsigned
// output
m_numitems
(
0
),
m_numwords
(
0
)
{
{
ndbassert
(
&
m_frag
==
&
node
.
m_frag
);
m_loc
=
node
.
m_loc
;
m_node
=
node
.
m_node
;
m_acc
=
node
.
m_acc
;
return
*
this
;
}
}
inline
inline
Dbtux
::
TupLoc
Dbtux
::
ReadPar
::
ReadPar
()
:
Dbtux
::
NodeHandle
::
getLink
(
unsigned
i
)
m_first
(
0
),
m_count
(
0
),
m_data
(
0
),
m_size
(
0
)
{
{
ndbrequire
(
i
<=
2
);
return
TupLoc
(
m_node
->
m_linkPI
[
i
],
m_node
->
m_linkPO
[
i
]);
}
}
inline
inline
unsigned
Dbtux
::
StorePar
::
StorePar
()
:
Dbtux
::
NodeHandle
::
getChilds
()
m_opCode
(
TupStoreTh
::
OpUndefined
),
m_offset
(
0
),
m_size
(
0
),
m_errorCode
(
0
)
{
{
return
(
getLink
(
0
)
!=
NullTupLoc
)
+
(
getLink
(
1
)
!=
NullTupLoc
);
}
}
inline
inline
unsigned
Dbtux
::
SearchPar
::
SearchPar
()
:
Dbtux
::
NodeHandle
::
getSide
()
m_data
(
0
),
m_ent
()
{
{
return
m_node
->
m_side
;
}
}
inline
inline
unsigned
Dbtux
::
CmpPar
::
CmpPar
()
:
Dbtux
::
NodeHandle
::
getOccup
()
m_data1
(
0
),
m_data2
(
0
),
m_len2
(
0
),
m_first
(
0
),
m_numEq
(
0
)
{
{
return
m_node
->
m_occup
;
}
}
inline
inline
int
Dbtux
::
BoundPar
::
BoundPar
()
:
Dbtux
::
NodeHandle
::
getBalance
()
m_data1
(
0
),
m_data2
(
0
),
m_count1
(
0
),
m_len2
(
0
),
m_dir
(
255
)
{
{
return
m_node
->
m_balance
;
}
}
#ifdef VM_TRACE
inline
Uint32
inline
Dbtux
::
NodeHandle
::
getNodeScan
()
Dbtux
::
PrintPar
::
PrintPar
()
:
// caller fills in
m_path
(),
m_side
(
255
),
m_parent
(
NullTupAddr
),
// default return values
m_depth
(
0
),
m_occup
(
0
),
m_ok
(
true
)
{
{
return
m_node
->
m_nodeScan
;
}
}
#endif
// node handles
inline
void
Dbtux
::
NodeHandle
::
setLink
(
unsigned
i
,
TupLoc
loc
)
inline
Dbtux
::
TupAddr
Dbtux
::
NodeHandle
::
getLink
(
unsigned
i
)
{
{
ndbrequire
(
i
<=
2
);
ndbrequire
(
i
<=
2
);
return
m_node
->
m_link
[
i
];
m_node
->
m_linkPI
[
i
]
=
loc
.
m_pageId
;
}
m_node
->
m_linkPO
[
i
]
=
loc
.
m_pageOffset
;
inline
unsigned
Dbtux
::
NodeHandle
::
getChilds
()
{
return
(
m_node
->
m_link
[
0
]
!=
NullTupAddr
)
+
(
m_node
->
m_link
[
1
]
!=
NullTupAddr
);
}
}
inline
Dbtux
::
TupAddr
inline
void
Dbtux
::
NodeHandle
::
getSide
(
)
Dbtux
::
NodeHandle
::
setSide
(
unsigned
i
)
{
{
return
m_node
->
m_side
;
ndbrequire
(
i
<=
2
);
m_node
->
m_side
=
i
;
}
}
inline
unsigne
d
inline
voi
d
Dbtux
::
NodeHandle
::
getOccup
(
)
Dbtux
::
NodeHandle
::
setOccup
(
unsigned
n
)
{
{
return
m_node
->
m_occup
;
TreeHead
&
tree
=
m_frag
.
m_tree
;
ndbrequire
(
n
<=
tree
.
m_maxOccup
);
m_node
->
m_occup
=
n
;
}
}
inline
int
inline
void
Dbtux
::
NodeHandle
::
getBalance
(
)
Dbtux
::
NodeHandle
::
setBalance
(
int
b
)
{
{
return
m_node
->
m_balance
;
ndbrequire
(
abs
(
b
)
<=
1
);
m_node
->
m_balance
=
b
;
}
}
inline
Uint32
inline
void
Dbtux
::
NodeHandle
::
getNodeScan
(
)
Dbtux
::
NodeHandle
::
setNodeScan
(
Uint32
scanPtrI
)
{
{
return
m_node
->
m_nodeScan
;
m_node
->
m_nodeScan
=
scanPtrI
;
}
}
inline
Dbtux
::
Data
inline
Dbtux
::
Data
...
@@ -1184,45 +1188,69 @@ Dbtux::NodeHandle::getMinMax(unsigned i)
...
@@ -1184,45 +1188,69 @@ Dbtux::NodeHandle::getMinMax(unsigned i)
return
getEnt
(
i
==
0
?
0
:
occup
-
1
);
return
getEnt
(
i
==
0
?
0
:
occup
-
1
);
}
}
inline
void
// parameters for methods
Dbtux
::
NodeHandle
::
setLink
(
unsigned
i
,
TupAddr
addr
)
inline
Dbtux
::
CopyPar
::
CopyPar
()
:
m_items
(
0
),
m_headers
(
true
),
m_maxwords
(
~
0
),
// max unsigned
// output
m_numitems
(
0
),
m_numwords
(
0
)
{
{
ndbrequire
(
i
<=
2
);
m_node
->
m_link
[
i
]
=
addr
;
m_flags
|=
DoUpdate
;
}
}
inline
void
inline
Dbtux
::
NodeHandle
::
setSide
(
unsigned
i
)
Dbtux
::
ReadPar
::
ReadPar
()
:
m_first
(
0
),
m_count
(
0
),
m_data
(
0
),
m_size
(
0
)
{
{
// ndbrequire(i <= 1);
m_node
->
m_side
=
i
;
m_flags
|=
DoUpdate
;
}
}
inline
void
inline
Dbtux
::
NodeHandle
::
setOccup
(
unsigned
n
)
Dbtux
::
SearchPar
::
SearchPar
()
:
m_data
(
0
),
m_ent
()
{
{
TreeHead
&
tree
=
m_frag
.
m_tree
;
ndbrequire
(
n
<=
tree
.
m_maxOccup
);
m_node
->
m_occup
=
n
;
m_flags
|=
DoUpdate
;
}
}
inline
void
inline
Dbtux
::
NodeHandle
::
setBalance
(
int
b
)
Dbtux
::
CmpPar
::
CmpPar
()
:
m_data1
(
0
),
m_data2
(
0
),
m_len2
(
0
),
m_first
(
0
),
m_numEq
(
0
)
{
{
ndbrequire
(
abs
(
b
)
<=
1
);
m_node
->
m_balance
=
b
;
m_flags
|=
DoUpdate
;
}
}
inline
void
inline
Dbtux
::
NodeHandle
::
setNodeScan
(
Uint32
scanPtrI
)
Dbtux
::
BoundPar
::
BoundPar
()
:
m_data1
(
0
),
m_data2
(
0
),
m_count1
(
0
),
m_len2
(
0
),
m_dir
(
255
)
{
}
#ifdef VM_TRACE
inline
Dbtux
::
PrintPar
::
PrintPar
()
:
// caller fills in
m_path
(),
m_side
(
255
),
m_parent
(),
// default return values
m_depth
(
0
),
m_occup
(
0
),
m_ok
(
true
)
{
{
m_node
->
m_nodeScan
=
scanPtrI
;
m_flags
|=
DoUpdate
;
}
}
#endif
// other methods
// other methods
...
...
ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
View file @
d3b0753d
...
@@ -97,7 +97,7 @@ Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out)
...
@@ -97,7 +97,7 @@ Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out)
PrintPar
par
;
PrintPar
par
;
strcpy
(
par
.
m_path
,
"."
);
strcpy
(
par
.
m_path
,
"."
);
par
.
m_side
=
2
;
par
.
m_side
=
2
;
par
.
m_parent
=
NullTup
Addr
;
par
.
m_parent
=
NullTup
Loc
;
printNode
(
signal
,
frag
,
out
,
tree
.
m_root
,
par
);
printNode
(
signal
,
frag
,
out
,
tree
.
m_root
,
par
);
out
.
m_out
->
flush
();
out
.
m_out
->
flush
();
if
(
!
par
.
m_ok
)
{
if
(
!
par
.
m_ok
)
{
...
@@ -106,26 +106,24 @@ Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out)
...
@@ -106,26 +106,24 @@ Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out)
signal
->
theData
[
1
]
=
1
;
signal
->
theData
[
1
]
=
1
;
execDUMP_STATE_ORD
(
signal
);
execDUMP_STATE_ORD
(
signal
);
if
(
debugFile
!=
0
)
{
if
(
debugFile
!=
0
)
{
commitNodes
(
signal
,
frag
,
false
);
printTree
(
signal
,
frag
,
debugOut
);
printTree
(
signal
,
frag
,
debugOut
);
}
}
}
}
ndbrequire
(
false
);
ndbrequire
(
false
);
}
}
commitNodes
(
signal
,
frag
,
false
);
}
}
void
void
Dbtux
::
printNode
(
Signal
*
signal
,
Frag
&
frag
,
NdbOut
&
out
,
Tup
Addr
addr
,
PrintPar
&
par
)
Dbtux
::
printNode
(
Signal
*
signal
,
Frag
&
frag
,
NdbOut
&
out
,
Tup
Loc
loc
,
PrintPar
&
par
)
{
{
if
(
addr
==
NullTupAddr
)
{
if
(
loc
==
NullTupLoc
)
{
par
.
m_depth
=
0
;
par
.
m_depth
=
0
;
return
;
return
;
}
}
TreeHead
&
tree
=
frag
.
m_tree
;
TreeHead
&
tree
=
frag
.
m_tree
;
NodeHandle
Ptr
nodePtr
;
NodeHandle
node
(
frag
)
;
selectNode
(
signal
,
frag
,
nodePtr
,
addr
,
AccFull
);
selectNode
(
signal
,
node
,
loc
,
AccFull
);
out
<<
par
.
m_path
<<
" "
<<
*
nodePtr
.
p
<<
endl
;
out
<<
par
.
m_path
<<
" "
<<
node
<<
endl
;
// check children
// check children
PrintPar
cpar
[
2
];
PrintPar
cpar
[
2
];
ndbrequire
(
strlen
(
par
.
m_path
)
+
1
<
sizeof
(
par
.
m_path
));
ndbrequire
(
strlen
(
par
.
m_path
)
+
1
<
sizeof
(
par
.
m_path
));
...
@@ -133,57 +131,57 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupAddr addr, PrintPar
...
@@ -133,57 +131,57 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupAddr addr, PrintPar
sprintf
(
cpar
[
i
].
m_path
,
"%s%c"
,
par
.
m_path
,
"LR"
[
i
]);
sprintf
(
cpar
[
i
].
m_path
,
"%s%c"
,
par
.
m_path
,
"LR"
[
i
]);
cpar
[
i
].
m_side
=
i
;
cpar
[
i
].
m_side
=
i
;
cpar
[
i
].
m_depth
=
0
;
cpar
[
i
].
m_depth
=
0
;
cpar
[
i
].
m_parent
=
addr
;
cpar
[
i
].
m_parent
=
loc
;
printNode
(
signal
,
frag
,
out
,
node
Ptr
.
p
->
getLink
(
i
),
cpar
[
i
]);
printNode
(
signal
,
frag
,
out
,
node
.
getLink
(
i
),
cpar
[
i
]);
if
(
!
cpar
[
i
].
m_ok
)
{
if
(
!
cpar
[
i
].
m_ok
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
}
}
}
}
// check child-parent links
// check child-parent links
if
(
node
Ptr
.
p
->
getLink
(
2
)
!=
par
.
m_parent
)
{
if
(
node
.
getLink
(
2
)
!=
par
.
m_parent
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
"parent
addr "
<<
hex
<<
nodePtr
.
p
->
getLink
(
2
);
out
<<
"parent
loc "
<<
hex
<<
node
.
getLink
(
2
);
out
<<
" should be "
<<
hex
<<
par
.
m_parent
<<
endl
;
out
<<
" should be "
<<
hex
<<
par
.
m_parent
<<
endl
;
}
}
if
(
node
Ptr
.
p
->
getSide
()
!=
par
.
m_side
)
{
if
(
node
.
getSide
()
!=
par
.
m_side
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
"side "
<<
dec
<<
node
Ptr
.
p
->
getSide
();
out
<<
"side "
<<
dec
<<
node
.
getSide
();
out
<<
" should be "
<<
dec
<<
par
.
m_side
<<
endl
;
out
<<
" should be "
<<
dec
<<
par
.
m_side
<<
endl
;
}
}
// check balance
// check balance
const
int
balance
=
-
cpar
[
0
].
m_depth
+
cpar
[
1
].
m_depth
;
const
int
balance
=
-
cpar
[
0
].
m_depth
+
cpar
[
1
].
m_depth
;
if
(
node
Ptr
.
p
->
getBalance
()
!=
balance
)
{
if
(
node
.
getBalance
()
!=
balance
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
"balance "
<<
node
Ptr
.
p
->
getBalance
();
out
<<
"balance "
<<
node
.
getBalance
();
out
<<
" should be "
<<
balance
<<
endl
;
out
<<
" should be "
<<
balance
<<
endl
;
}
}
if
(
abs
(
node
Ptr
.
p
->
getBalance
())
>
1
)
{
if
(
abs
(
node
.
getBalance
())
>
1
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
"balance "
<<
node
Ptr
.
p
->
getBalance
()
<<
" is invalid"
<<
endl
;
out
<<
"balance "
<<
node
.
getBalance
()
<<
" is invalid"
<<
endl
;
}
}
// check occupancy
// check occupancy
if
(
node
Ptr
.
p
->
getOccup
()
>
tree
.
m_maxOccup
)
{
if
(
node
.
getOccup
()
>
tree
.
m_maxOccup
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
"occupancy "
<<
node
Ptr
.
p
->
getOccup
();
out
<<
"occupancy "
<<
node
.
getOccup
();
out
<<
" greater than max "
<<
tree
.
m_maxOccup
<<
endl
;
out
<<
" greater than max "
<<
tree
.
m_maxOccup
<<
endl
;
}
}
// check for occupancy of interior node
// check for occupancy of interior node
if
(
node
Ptr
.
p
->
getChilds
()
==
2
&&
nodePtr
.
p
->
getOccup
()
<
tree
.
m_minOccup
)
{
if
(
node
.
getChilds
()
==
2
&&
node
.
getOccup
()
<
tree
.
m_minOccup
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
"occupancy "
<<
node
Ptr
.
p
->
getOccup
()
<<
" of interior node"
;
out
<<
"occupancy "
<<
node
.
getOccup
()
<<
" of interior node"
;
out
<<
" less than min "
<<
tree
.
m_minOccup
<<
endl
;
out
<<
" less than min "
<<
tree
.
m_minOccup
<<
endl
;
}
}
// check missed half-leaf/leaf merge
// check missed half-leaf/leaf merge
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
if
(
node
Ptr
.
p
->
getLink
(
i
)
!=
NullTupAddr
&&
if
(
node
.
getLink
(
i
)
!=
NullTupLoc
&&
node
Ptr
.
p
->
getLink
(
1
-
i
)
==
NullTupAddr
&&
node
.
getLink
(
1
-
i
)
==
NullTupLoc
&&
node
Ptr
.
p
->
getOccup
()
+
cpar
[
i
].
m_occup
<=
tree
.
m_maxOccup
)
{
node
.
getOccup
()
+
cpar
[
i
].
m_occup
<=
tree
.
m_maxOccup
)
{
par
.
m_ok
=
false
;
par
.
m_ok
=
false
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
par
.
m_path
<<
" *** "
;
out
<<
"missed merge with child "
<<
i
<<
endl
;
out
<<
"missed merge with child "
<<
i
<<
endl
;
...
@@ -191,7 +189,19 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupAddr addr, PrintPar
...
@@ -191,7 +189,19 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupAddr addr, PrintPar
}
}
// return values
// return values
par
.
m_depth
=
1
+
max
(
cpar
[
0
].
m_depth
,
cpar
[
1
].
m_depth
);
par
.
m_depth
=
1
+
max
(
cpar
[
0
].
m_depth
,
cpar
[
1
].
m_depth
);
par
.
m_occup
=
nodePtr
.
p
->
getOccup
();
par
.
m_occup
=
node
.
getOccup
();
}
NdbOut
&
operator
<<
(
NdbOut
&
out
,
const
Dbtux
::
TupLoc
&
loc
)
{
if
(
loc
==
Dbtux
::
NullTupLoc
)
{
out
<<
"null"
;
}
else
{
out
<<
hex
<<
loc
.
m_pageId
;
out
<<
"."
<<
dec
<<
loc
.
m_pageOffset
;
}
return
out
;
}
}
NdbOut
&
NdbOut
&
...
@@ -206,10 +216,13 @@ operator<<(NdbOut& out, const Dbtux::TreeEnt& ent)
...
@@ -206,10 +216,13 @@ operator<<(NdbOut& out, const Dbtux::TreeEnt& ent)
NdbOut
&
NdbOut
&
operator
<<
(
NdbOut
&
out
,
const
Dbtux
::
TreeNode
&
node
)
operator
<<
(
NdbOut
&
out
,
const
Dbtux
::
TreeNode
&
node
)
{
{
Dbtux
::
TupLoc
link0
(
node
.
m_linkPI
[
0
],
node
.
m_linkPO
[
0
]);
Dbtux
::
TupLoc
link1
(
node
.
m_linkPI
[
1
],
node
.
m_linkPO
[
1
]);
Dbtux
::
TupLoc
link2
(
node
.
m_linkPI
[
2
],
node
.
m_linkPO
[
2
]);
out
<<
"[TreeNode "
<<
hex
<<
&
node
;
out
<<
"[TreeNode "
<<
hex
<<
&
node
;
out
<<
" [left "
<<
hex
<<
node
.
m_link
[
0
]
<<
"]"
;
out
<<
" [left "
<<
link0
<<
"]"
;
out
<<
" [right "
<<
hex
<<
node
.
m_link
[
1
]
<<
"]"
;
out
<<
" [right "
<<
link1
<<
"]"
;
out
<<
" [up "
<<
hex
<<
node
.
m_link
[
2
]
<<
"]"
;
out
<<
" [up "
<<
link2
<<
"]"
;
out
<<
" [side "
<<
dec
<<
node
.
m_side
<<
"]"
;
out
<<
" [side "
<<
dec
<<
node
.
m_side
<<
"]"
;
out
<<
" [occup "
<<
dec
<<
node
.
m_occup
<<
"]"
;
out
<<
" [occup "
<<
dec
<<
node
.
m_occup
<<
"]"
;
out
<<
" [balance "
<<
dec
<<
(
int
)
node
.
m_balance
<<
"]"
;
out
<<
" [balance "
<<
dec
<<
(
int
)
node
.
m_balance
<<
"]"
;
...
@@ -238,7 +251,7 @@ NdbOut&
...
@@ -238,7 +251,7 @@ NdbOut&
operator
<<
(
NdbOut
&
out
,
const
Dbtux
::
TreePos
&
pos
)
operator
<<
(
NdbOut
&
out
,
const
Dbtux
::
TreePos
&
pos
)
{
{
out
<<
"[TreePos "
<<
hex
<<
&
pos
;
out
<<
"[TreePos "
<<
hex
<<
&
pos
;
out
<<
" [
addr "
<<
hex
<<
pos
.
m_addr
<<
"]"
;
out
<<
" [
loc "
<<
pos
.
m_loc
<<
"]"
;
out
<<
" [pos "
<<
dec
<<
pos
.
m_pos
<<
"]"
;
out
<<
" [pos "
<<
dec
<<
pos
.
m_pos
<<
"]"
;
out
<<
" [match "
<<
dec
<<
pos
.
m_match
<<
"]"
;
out
<<
" [match "
<<
dec
<<
pos
.
m_match
<<
"]"
;
out
<<
" [dir "
<<
dec
<<
pos
.
m_dir
<<
"]"
;
out
<<
" [dir "
<<
dec
<<
pos
.
m_dir
<<
"]"
;
...
@@ -338,9 +351,8 @@ operator<<(NdbOut& out, const Dbtux::NodeHandle& node)
...
@@ -338,9 +351,8 @@ operator<<(NdbOut& out, const Dbtux::NodeHandle& node)
const
Dbtux
::
Frag
&
frag
=
node
.
m_frag
;
const
Dbtux
::
Frag
&
frag
=
node
.
m_frag
;
const
Dbtux
::
TreeHead
&
tree
=
frag
.
m_tree
;
const
Dbtux
::
TreeHead
&
tree
=
frag
.
m_tree
;
out
<<
"[NodeHandle "
<<
hex
<<
&
node
;
out
<<
"[NodeHandle "
<<
hex
<<
&
node
;
out
<<
" [
addr "
<<
hex
<<
node
.
m_addr
<<
"]"
;
out
<<
" [
loc "
<<
node
.
m_loc
<<
"]"
;
out
<<
" [acc "
<<
dec
<<
node
.
m_acc
<<
"]"
;
out
<<
" [acc "
<<
dec
<<
node
.
m_acc
<<
"]"
;
out
<<
" [flags "
<<
hex
<<
node
.
m_flags
<<
"]"
;
out
<<
" [node "
<<
*
node
.
m_node
<<
"]"
;
out
<<
" [node "
<<
*
node
.
m_node
<<
"]"
;
if
(
node
.
m_acc
>=
Dbtux
::
AccPref
)
{
if
(
node
.
m_acc
>=
Dbtux
::
AccPref
)
{
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
...
...
ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
View file @
d3b0753d
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
Dbtux
::
Dbtux
(
const
Configuration
&
conf
)
:
Dbtux
::
Dbtux
(
const
Configuration
&
conf
)
:
SimulatedBlock
(
DBTUX
,
conf
),
SimulatedBlock
(
DBTUX
,
conf
),
c_tup
(
0
),
c_descPageList
(
RNIL
),
c_descPageList
(
RNIL
),
#ifdef VM_TRACE
#ifdef VM_TRACE
debugFile
(
0
),
debugFile
(
0
),
...
@@ -123,6 +124,8 @@ Dbtux::execSTTOR(Signal* signal)
...
@@ -123,6 +124,8 @@ Dbtux::execSTTOR(Signal* signal)
case
1
:
case
1
:
jam
();
jam
();
CLEAR_ERROR_INSERT_VALUE
;
CLEAR_ERROR_INSERT_VALUE
;
c_tup
=
(
Dbtup
*
)
globalData
.
getBlock
(
DBTUP
);
ndbrequire
(
c_tup
!=
0
);
break
;
break
;
case
3
:
case
3
:
jam
();
jam
();
...
@@ -175,12 +178,11 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
...
@@ -175,12 +178,11 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
c_fragPool
.
setSize
(
nFragment
);
c_fragPool
.
setSize
(
nFragment
);
c_descPagePool
.
setSize
(
nDescPage
);
c_descPagePool
.
setSize
(
nDescPage
);
c_fragOpPool
.
setSize
(
MaxIndexFragments
);
c_fragOpPool
.
setSize
(
MaxIndexFragments
);
c_nodeHandlePool
.
setSize
(
MaxNodeHandles
);
c_scanOpPool
.
setSize
(
nScanOp
);
c_scanOpPool
.
setSize
(
nScanOp
);
c_scanBoundPool
.
setSize
(
nScanBoundWords
);
c_scanBoundPool
.
setSize
(
nScanBoundWords
);
/*
/*
* Index id is physical array index. We seize and initialize all
* Index id is physical array index. We seize and initialize all
* index records now.
This assumes ArrayPool is an array.
* index records now.
*/
*/
IndexPtr
indexPtr
;
IndexPtr
indexPtr
;
while
(
1
)
{
while
(
1
)
{
...
...
ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
View file @
d3b0753d
...
@@ -72,7 +72,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
...
@@ -72,7 +72,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
}
}
ndbrequire
(
fragPtr
.
i
!=
RNIL
);
ndbrequire
(
fragPtr
.
i
!=
RNIL
);
Frag
&
frag
=
*
fragPtr
.
p
;
Frag
&
frag
=
*
fragPtr
.
p
;
ndbrequire
(
frag
.
m_nodeList
==
RNIL
);
// set up index entry
// set up index entry
TreeEnt
ent
;
TreeEnt
ent
;
ent
.
m_tupAddr
=
req
->
tupAddr
;
ent
.
m_tupAddr
=
req
->
tupAddr
;
...
@@ -143,17 +142,18 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
...
@@ -143,17 +142,18 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
}
}
/*
/*
* At most one new node is inserted in the operation. We keep one
* At most one new node is inserted in the operation. We keep one
* free node pre-allocated so the operation cannot fail. This also
* free node pre-allocated so the operation cannot fail.
* gives a real TupAddr for links to the new node.
*/
*/
if
(
frag
.
m_
nodeFree
==
RNIL
)
{
if
(
frag
.
m_
freeLoc
==
NullTupLoc
)
{
jam
();
jam
();
preallocNode
(
signal
,
frag
,
req
->
errorCode
);
NodeHandle
node
(
frag
);
req
->
errorCode
=
allocNode
(
signal
,
node
);
if
(
req
->
errorCode
!=
0
)
{
if
(
req
->
errorCode
!=
0
)
{
jam
();
jam
();
break
;
break
;
}
}
ndbrequire
(
frag
.
m_nodeFree
!=
RNIL
);
frag
.
m_freeLoc
=
node
.
m_loc
;
ndbrequire
(
frag
.
m_freeLoc
!=
NullTupLoc
);
}
}
treeAdd
(
signal
,
frag
,
treePos
,
ent
);
treeAdd
(
signal
,
frag
,
treePos
,
ent
);
break
;
break
;
...
@@ -175,7 +175,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
...
@@ -175,7 +175,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
break
;
break
;
}
}
// commit and release nodes
// commit and release nodes
commitNodes
(
signal
,
frag
,
req
->
errorCode
==
0
);
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
debugFlags
&
DebugTree
)
{
if
(
debugFlags
&
DebugTree
)
{
printTree
(
signal
,
frag
,
debugOut
);
printTree
(
signal
,
frag
,
debugOut
);
...
@@ -199,7 +198,7 @@ Dbtux::tupReadAttrs(Signal* signal, const Frag& frag, ReadPar& readPar)
...
@@ -199,7 +198,7 @@ Dbtux::tupReadAttrs(Signal* signal, const Frag& frag, ReadPar& readPar)
req
->
requestInfo
=
0
;
req
->
requestInfo
=
0
;
req
->
tableId
=
frag
.
m_tableId
;
req
->
tableId
=
frag
.
m_tableId
;
req
->
fragId
=
frag
.
m_fragId
|
(
ent
.
m_fragBit
<<
frag
.
m_fragOff
);
req
->
fragId
=
frag
.
m_fragId
|
(
ent
.
m_fragBit
<<
frag
.
m_fragOff
);
req
->
fragPtrI
=
RNIL
;
req
->
fragPtrI
=
frag
.
m_tupTableFragPtrI
[
ent
.
m_fragBit
]
;
req
->
tupAddr
=
ent
.
m_tupAddr
;
req
->
tupAddr
=
ent
.
m_tupAddr
;
req
->
tupVersion
=
ent
.
m_tupVersion
;
req
->
tupVersion
=
ent
.
m_tupVersion
;
req
->
pageId
=
RNIL
;
req
->
pageId
=
RNIL
;
...
@@ -246,7 +245,7 @@ Dbtux::tupReadKeys(Signal* signal, const Frag& frag, ReadPar& readPar)
...
@@ -246,7 +245,7 @@ Dbtux::tupReadKeys(Signal* signal, const Frag& frag, ReadPar& readPar)
req
->
requestInfo
=
TupReadAttrs
::
ReadKeys
;
req
->
requestInfo
=
TupReadAttrs
::
ReadKeys
;
req
->
tableId
=
frag
.
m_tableId
;
req
->
tableId
=
frag
.
m_tableId
;
req
->
fragId
=
frag
.
m_fragId
|
(
ent
.
m_fragBit
<<
frag
.
m_fragOff
);
req
->
fragId
=
frag
.
m_fragId
|
(
ent
.
m_fragBit
<<
frag
.
m_fragOff
);
req
->
fragPtrI
=
RNIL
;
req
->
fragPtrI
=
frag
.
m_tupTableFragPtrI
[
ent
.
m_fragBit
]
;
req
->
tupAddr
=
ent
.
m_tupAddr
;
req
->
tupAddr
=
ent
.
m_tupAddr
;
req
->
tupVersion
=
RNIL
;
// not used
req
->
tupVersion
=
RNIL
;
// not used
req
->
pageId
=
RNIL
;
req
->
pageId
=
RNIL
;
...
@@ -270,100 +269,3 @@ Dbtux::tupReadKeys(Signal* signal, const Frag& frag, ReadPar& readPar)
...
@@ -270,100 +269,3 @@ Dbtux::tupReadKeys(Signal* signal, const Frag& frag, ReadPar& readPar)
readPar
.
m_count
=
numKeys
;
readPar
.
m_count
=
numKeys
;
readPar
.
m_size
=
copyPar
.
m_numwords
;
readPar
.
m_size
=
copyPar
.
m_numwords
;
}
}
/*
* Operate on index node tuple in TUP. The data is copied between node
* cache and index storage via signal data.
*/
void
Dbtux
::
tupStoreTh
(
Signal
*
signal
,
const
Frag
&
frag
,
NodeHandlePtr
nodePtr
,
StorePar
storePar
)
{
const
TreeHead
&
tree
=
frag
.
m_tree
;
// define the direct signal
TupStoreTh
*
req
=
(
TupStoreTh
*
)
signal
->
getDataPtrSend
();
req
->
errorCode
=
RNIL
;
req
->
tableId
=
frag
.
m_indexId
;
req
->
fragId
=
frag
.
m_fragId
;
req
->
fragPtrI
=
RNIL
;
req
->
tupAddr
=
nodePtr
.
p
->
m_addr
;
req
->
tupVersion
=
0
;
req
->
pageId
=
nodePtr
.
p
->
m_loc
.
m_pageId
;
req
->
pageOffset
=
nodePtr
.
p
->
m_loc
.
m_pageOffset
;
req
->
bufferId
=
0
;
req
->
opCode
=
storePar
.
m_opCode
;
ndbrequire
(
storePar
.
m_offset
+
storePar
.
m_size
<=
tree
.
m_nodeSize
);
req
->
dataOffset
=
storePar
.
m_offset
;
req
->
dataSize
=
storePar
.
m_size
;
// the node cache
ndbrequire
(
nodePtr
.
p
->
m_node
!=
0
);
// the buffer in signal data
Uint32
*
const
buffer
=
(
Uint32
*
)
req
+
TupStoreTh
::
SignalLength
;
// copy in data
switch
(
storePar
.
m_opCode
)
{
case
TupStoreTh
:
:
OpRead
:
jam
();
#ifdef VM_TRACE
{
Uint32
*
dst
=
buffer
+
storePar
.
m_offset
;
memset
(
dst
,
0xa9
,
storePar
.
m_size
<<
2
);
}
#endif
break
;
case
TupStoreTh
:
:
OpInsert
:
jam
();
// fallthru
case
TupStoreTh
:
:
OpUpdate
:
jam
();
// copy from cache to signal data
{
Uint32
*
dst
=
buffer
+
storePar
.
m_offset
;
const
Uint32
*
src
=
(
const
Uint32
*
)
nodePtr
.
p
->
m_node
+
storePar
.
m_offset
;
memcpy
(
dst
,
src
,
storePar
.
m_size
<<
2
);
}
break
;
case
TupStoreTh
:
:
OpDelete
:
jam
();
break
;
default:
ndbrequire
(
false
);
break
;
}
// execute
EXECUTE_DIRECT
(
DBTUP
,
GSN_TUP_STORE_TH
,
signal
,
TupStoreTh
::
SignalLength
);
jamEntry
();
if
(
req
->
errorCode
!=
0
)
{
jam
();
storePar
.
m_errorCode
=
req
->
errorCode
;
return
;
}
ndbrequire
(
req
->
errorCode
==
0
);
// copy out data
switch
(
storePar
.
m_opCode
)
{
case
TupStoreTh
:
:
OpRead
:
jam
();
{
Uint32
*
dst
=
(
Uint32
*
)
nodePtr
.
p
->
m_node
+
storePar
.
m_offset
;
const
Uint32
*
src
=
(
const
Uint32
*
)
buffer
+
storePar
.
m_offset
;
memcpy
(
dst
,
src
,
storePar
.
m_size
<<
2
);
}
// fallthru
case
TupStoreTh
:
:
OpInsert
:
jam
();
// fallthru
case
TupStoreTh
:
:
OpUpdate
:
jam
();
nodePtr
.
p
->
m_addr
=
req
->
tupAddr
;
nodePtr
.
p
->
m_loc
.
m_pageId
=
req
->
pageId
;
nodePtr
.
p
->
m_loc
.
m_pageOffset
=
req
->
pageOffset
;
break
;
case
TupStoreTh
:
:
OpDelete
:
jam
();
nodePtr
.
p
->
m_addr
=
NullTupAddr
;
nodePtr
.
p
->
m_loc
.
m_pageId
=
RNIL
;
nodePtr
.
p
->
m_loc
.
m_pageOffset
=
0
;
break
;
default:
ndbrequire
(
false
);
break
;
}
}
ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
View file @
d3b0753d
...
@@ -85,6 +85,11 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
...
@@ -85,6 +85,11 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
fragPtr
.
p
->
m_fragOff
=
req
->
fragOff
;
fragPtr
.
p
->
m_fragOff
=
req
->
fragOff
;
fragPtr
.
p
->
m_fragId
=
req
->
fragId
;
fragPtr
.
p
->
m_fragId
=
req
->
fragId
;
fragPtr
.
p
->
m_numAttrs
=
req
->
noOfAttr
;
fragPtr
.
p
->
m_numAttrs
=
req
->
noOfAttr
;
fragPtr
.
p
->
m_tupIndexFragPtrI
=
req
->
tupIndexFragPtrI
;
fragPtr
.
p
->
m_tupTableFragPtrI
[
0
]
=
req
->
tupTableFragPtrI
[
0
];
fragPtr
.
p
->
m_tupTableFragPtrI
[
1
]
=
req
->
tupTableFragPtrI
[
1
];
fragPtr
.
p
->
m_accTableFragPtrI
[
0
]
=
req
->
accTableFragPtrI
[
0
];
fragPtr
.
p
->
m_accTableFragPtrI
[
1
]
=
req
->
accTableFragPtrI
[
1
];
// add the fragment to the index
// add the fragment to the index
indexPtr
.
p
->
m_fragId
[
indexPtr
.
p
->
m_numFrags
]
=
req
->
fragId
;
indexPtr
.
p
->
m_fragId
[
indexPtr
.
p
->
m_numFrags
]
=
req
->
fragId
;
indexPtr
.
p
->
m_fragPtrI
[
indexPtr
.
p
->
m_numFrags
]
=
fragPtr
.
i
;
indexPtr
.
p
->
m_fragPtrI
[
indexPtr
.
p
->
m_numFrags
]
=
fragPtr
.
i
;
...
@@ -197,6 +202,7 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
...
@@ -197,6 +202,7 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
jam
();
jam
();
// initialize tree header
// initialize tree header
TreeHead
&
tree
=
fragPtr
.
p
->
m_tree
;
TreeHead
&
tree
=
fragPtr
.
p
->
m_tree
;
new
(
&
tree
)
TreeHead
();
// make these configurable later
// make these configurable later
tree
.
m_nodeSize
=
MAX_TTREE_NODE_SIZE
;
tree
.
m_nodeSize
=
MAX_TTREE_NODE_SIZE
;
tree
.
m_prefSize
=
MAX_TTREE_PREF_SIZE
;
tree
.
m_prefSize
=
MAX_TTREE_PREF_SIZE
;
...
@@ -222,8 +228,8 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
...
@@ -222,8 +228,8 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
break
;
break
;
}
}
tree
.
m_minOccup
=
tree
.
m_maxOccup
-
maxSlack
;
tree
.
m_minOccup
=
tree
.
m_maxOccup
-
maxSlack
;
// root node does not exist
// root node does not exist
(also set by ctor)
tree
.
m_root
=
NullTup
Addr
;
tree
.
m_root
=
NullTup
Loc
;
// fragment is defined
// fragment is defined
c_fragOpPool
.
release
(
fragOpPtr
);
c_fragOpPool
.
release
(
fragOpPtr
);
}
}
...
@@ -310,12 +316,6 @@ Dbtux::dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 sen
...
@@ -310,12 +316,6 @@ Dbtux::dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 sen
unsigned
i
=
--
indexPtr
.
p
->
m_numFrags
;
unsigned
i
=
--
indexPtr
.
p
->
m_numFrags
;
FragPtr
fragPtr
;
FragPtr
fragPtr
;
c_fragPool
.
getPtr
(
fragPtr
,
indexPtr
.
p
->
m_fragPtrI
[
i
]);
c_fragPool
.
getPtr
(
fragPtr
,
indexPtr
.
p
->
m_fragPtrI
[
i
]);
Frag
&
frag
=
*
fragPtr
.
p
;
ndbrequire
(
frag
.
m_nodeList
==
RNIL
);
if
(
frag
.
m_nodeFree
!=
RNIL
)
{
c_nodeHandlePool
.
release
(
frag
.
m_nodeFree
);
frag
.
m_nodeFree
=
RNIL
;
}
c_fragPool
.
release
(
fragPtr
);
c_fragPool
.
release
(
fragPtr
);
// the real time break is not used for anything currently
// the real time break is not used for anything currently
signal
->
theData
[
0
]
=
TuxContinueB
::
DropIndex
;
signal
->
theData
[
0
]
=
TuxContinueB
::
DropIndex
;
...
...
ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
View file @
d3b0753d
...
@@ -18,175 +18,107 @@
...
@@ -18,175 +18,107 @@
#include "Dbtux.hpp"
#include "Dbtux.hpp"
/*
/*
* Node handles.
* Allocate index node in TUP.
*
* We use the "cache" implementation. Node operations are done on
* cached copies. Index memory is updated at the end of the operation.
* At most one node is inserted and it is always pre-allocated.
*
* An alternative "pointer" implementation which writes directly into
* index memory is planned for later.
*/
*/
int
// Dbtux
Dbtux
::
allocNode
(
Signal
*
signal
,
NodeHandle
&
node
)
void
Dbtux
::
seizeNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
)
{
if
(
!
c_nodeHandlePool
.
seize
(
nodePtr
))
{
jam
();
return
;
}
new
(
nodePtr
.
p
)
NodeHandle
(
*
this
,
frag
);
nodePtr
.
p
->
m_next
=
frag
.
m_nodeList
;
frag
.
m_nodeList
=
nodePtr
.
i
;
// node cache used always
nodePtr
.
p
->
m_node
=
(
TreeNode
*
)
nodePtr
.
p
->
m_cache
;
new
(
nodePtr
.
p
->
m_node
)
TreeNode
();
#ifdef VM_TRACE
TreeHead
&
tree
=
frag
.
m_tree
;
TreeNode
*
node
=
nodePtr
.
p
->
m_node
;
memset
(
tree
.
getPref
(
node
,
0
),
0xa2
,
tree
.
m_prefSize
<<
2
);
memset
(
tree
.
getPref
(
node
,
1
),
0xa2
,
tree
.
m_prefSize
<<
2
);
TreeEnt
*
entList
=
tree
.
getEntList
(
node
);
memset
(
entList
,
0xa4
,
(
tree
.
m_maxOccup
+
1
)
*
(
TreeEntSize
<<
2
));
#endif
}
void
Dbtux
::
preallocNode
(
Signal
*
signal
,
Frag
&
frag
,
Uint32
&
errorCode
)
{
{
ndbrequire
(
frag
.
m_nodeFree
==
RNIL
);
Frag
&
frag
=
node
.
m_frag
;
NodeHandlePtr
nodePtr
;
Uint32
pageId
=
NullTupLoc
.
m_pageId
;
seizeNode
(
signal
,
frag
,
nodePtr
);
Uint32
pageOffset
=
NullTupLoc
.
m_pageOffset
;
ndbrequire
(
nodePtr
.
i
!=
RNIL
);
Uint32
*
node32
=
0
;
// remove from cache XXX ugly
int
errorCode
=
c_tup
->
tuxAllocNode
(
signal
,
frag
.
m_tupIndexFragPtrI
,
pageId
,
pageOffset
,
node32
);
frag
.
m_nodeFree
=
frag
.
m_nodeList
;
if
(
errorCode
==
0
)
{
frag
.
m_nodeList
=
nodePtr
.
p
->
m_next
;
StorePar
storePar
;
storePar
.
m_opCode
=
TupStoreTh
::
OpInsert
;
storePar
.
m_offset
=
0
;
storePar
.
m_size
=
0
;
tupStoreTh
(
signal
,
frag
,
nodePtr
,
storePar
);
if
(
storePar
.
m_errorCode
!=
0
)
{
jam
();
jam
();
errorCode
=
storePar
.
m_errorCode
;
node
.
m_loc
=
TupLoc
(
pageId
,
pageOffset
);
c_nodeHandlePool
.
release
(
nodePtr
);
node
.
m_node
=
reinterpret_cast
<
TreeNode
*>
(
node32
);
frag
.
m_nodeFree
=
RNIL
;
node
.
m_acc
=
AccNone
;
ndbrequire
(
node
.
m_loc
!=
NullTupLoc
&&
node
.
m_node
!=
0
);
}
}
return
errorCode
;
}
}
/*
/*
* Find node in the cache. XXX too slow, use direct links instead
* Access more of the node.
*/
void
Dbtux
::
findNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
TupAddr
addr
)
{
NodeHandlePtr
tmpPtr
;
tmpPtr
.
i
=
frag
.
m_nodeList
;
while
(
tmpPtr
.
i
!=
RNIL
)
{
jam
();
c_nodeHandlePool
.
getPtr
(
tmpPtr
);
if
(
tmpPtr
.
p
->
m_addr
==
addr
)
{
jam
();
nodePtr
=
tmpPtr
;
return
;
}
tmpPtr
.
i
=
tmpPtr
.
p
->
m_next
;
}
nodePtr
.
i
=
RNIL
;
nodePtr
.
p
=
0
;
}
/*
* Get handle for existing node.
*/
*/
void
void
Dbtux
::
selectNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
TupAddr
addr
,
AccSize
acc
)
Dbtux
::
accessNode
(
Signal
*
signal
,
NodeHandle
&
node
,
AccSize
acc
)
{
{
ndbrequire
(
addr
!=
NullTupAddr
&&
acc
>
AccNone
);
ndbrequire
(
node
.
m_loc
!=
NullTupLoc
&&
node
.
m_node
!=
0
);
NodeHandlePtr
tmpPtr
;
if
(
node
.
m_acc
>=
acc
)
// search in cache
return
;
findNode
(
signal
,
frag
,
tmpPtr
,
addr
);
// XXX could do prefetch
if
(
tmpPtr
.
i
==
RNIL
)
{
node
.
m_acc
=
acc
;
jam
();
// add new node
seizeNode
(
signal
,
frag
,
tmpPtr
);
ndbrequire
(
tmpPtr
.
i
!=
RNIL
);
tmpPtr
.
p
->
m_addr
=
addr
;
}
if
(
tmpPtr
.
p
->
m_acc
<
acc
)
{
jam
();
accessNode
(
signal
,
frag
,
tmpPtr
,
acc
);
}
nodePtr
=
tmpPtr
;
}
}
/*
/*
*
Create new node in the cache and mark it for insert
.
*
Set handle to point to existing node
.
*/
*/
void
void
Dbtux
::
insertNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
AccSize
acc
)
Dbtux
::
selectNode
(
Signal
*
signal
,
NodeHandle
&
node
,
TupLoc
loc
,
AccSize
acc
)
{
{
ndbrequire
(
acc
>
AccNone
);
Frag
&
frag
=
node
.
m_frag
;
NodeHandlePtr
tmpPtr
;
ndbrequire
(
loc
!=
NullTupLoc
);
// use the pre-allocated node
Uint32
pageId
=
loc
.
m_pageId
;
tmpPtr
.
i
=
frag
.
m_nodeFree
;
Uint32
pageOffset
=
loc
.
m_pageOffset
;
frag
.
m_nodeFree
=
RNIL
;
Uint32
*
node32
=
0
;
c_nodeHandlePool
.
getPtr
(
tmpPtr
);
c_tup
->
tuxGetNode
(
frag
.
m_tupIndexFragPtrI
,
pageId
,
pageOffset
,
node32
);
// move it to the cache
node
.
m_loc
=
loc
;
tmpPtr
.
p
->
m_next
=
frag
.
m_nodeList
;
node
.
m_node
=
reinterpret_cast
<
TreeNode
*>
(
node32
);
frag
.
m_nodeList
=
tmpPtr
.
i
;
node
.
m_acc
=
AccNone
;
tmpPtr
.
p
->
m_acc
=
acc
;
ndbrequire
(
node
.
m_loc
!=
NullTupLoc
&&
node
.
m_node
!=
0
);
tmpPtr
.
p
->
m_flags
|=
NodeHandle
::
DoInsert
;
accessNode
(
signal
,
node
,
acc
);
nodePtr
=
tmpPtr
;
}
}
/*
/*
*
Mark existing node for deletion
.
*
Set handle to point to new node. Uses the pre-allocated node
.
*/
*/
void
void
Dbtux
::
deleteNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
)
Dbtux
::
insertNode
(
Signal
*
signal
,
NodeHandle
&
node
,
AccSize
acc
)
{
{
NodeHandlePtr
tmpPtr
=
nodePtr
;
Frag
&
frag
=
node
.
m_frag
;
ndbrequire
(
tmpPtr
.
p
->
getOccup
()
==
0
);
TupLoc
loc
=
frag
.
m_freeLoc
;
tmpPtr
.
p
->
m_flags
|=
NodeHandle
::
DoDelete
;
frag
.
m_freeLoc
=
NullTupLoc
;
// scans have already been moved by popDown or popUp
selectNode
(
signal
,
node
,
loc
,
acc
);
new
(
node
.
m_node
)
TreeNode
();
#ifdef VM_TRACE
TreeHead
&
tree
=
frag
.
m_tree
;
memset
(
tree
.
getPref
(
node
.
m_node
,
0
),
0xa2
,
tree
.
m_prefSize
<<
2
);
memset
(
tree
.
getPref
(
node
.
m_node
,
1
),
0xa2
,
tree
.
m_prefSize
<<
2
);
TreeEnt
*
entList
=
tree
.
getEntList
(
node
.
m_node
);
memset
(
entList
,
0xa4
,
(
tree
.
m_maxOccup
+
1
)
*
(
TreeEntSize
<<
2
));
#endif
}
}
/*
/*
*
Access more of the
node.
*
Delete existing
node.
*/
*/
void
void
Dbtux
::
accessNode
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
AccSize
acc
)
Dbtux
::
deleteNode
(
Signal
*
signal
,
NodeHandle
&
node
)
{
{
TreeHead
&
tree
=
frag
.
m_tree
;
Frag
&
frag
=
node
.
m_frag
;
NodeHandlePtr
tmpPtr
=
nodePtr
;
ndbrequire
(
node
.
getOccup
()
==
0
);
if
(
tmpPtr
.
p
->
m_acc
>=
acc
)
TupLoc
loc
=
node
.
m_loc
;
return
;
Uint32
pageId
=
loc
.
m_pageId
;
if
(
!
(
tmpPtr
.
p
->
m_flags
&
NodeHandle
::
DoInsert
))
{
Uint32
pageOffset
=
loc
.
m_pageOffset
;
jam
();
Uint32
*
node32
=
reinterpret_cast
<
Uint32
*>
(
node
.
m_node
);
StorePar
storePar
;
c_tup
->
tuxFreeNode
(
signal
,
frag
.
m_tupIndexFragPtrI
,
pageId
,
pageOffset
,
node32
);
storePar
.
m_opCode
=
TupStoreTh
::
OpRead
;
// invalidate handle and storage
storePar
.
m_offset
=
tree
.
getSize
(
tmpPtr
.
p
->
m_acc
);
node
.
m_loc
=
NullTupLoc
;
storePar
.
m_size
=
tree
.
getSize
(
acc
)
-
tree
.
getSize
(
tmpPtr
.
p
->
m_acc
);
node
.
m_node
=
0
;
tmpPtr
.
p
->
m_tux
.
tupStoreTh
(
signal
,
frag
,
tmpPtr
,
storePar
);
ndbrequire
(
storePar
.
m_errorCode
==
0
);
}
tmpPtr
.
p
->
m_acc
=
acc
;
}
}
/*
/*
* Set prefix.
* Set prefix.
*/
*/
void
void
Dbtux
::
setNodePref
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandlePtr
&
nodePtr
,
unsigned
i
)
Dbtux
::
setNodePref
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
i
)
{
{
Frag
&
frag
=
node
.
m_frag
;
TreeHead
&
tree
=
frag
.
m_tree
;
TreeHead
&
tree
=
frag
.
m_tree
;
NodeHandlePtr
tmpPtr
=
nodePtr
;
ReadPar
readPar
;
ReadPar
readPar
;
ndbrequire
(
i
<=
1
);
ndbrequire
(
i
<=
1
);
readPar
.
m_ent
=
tmpPtr
.
p
->
getMinMax
(
i
);
readPar
.
m_ent
=
node
.
getMinMax
(
i
);
readPar
.
m_first
=
0
;
readPar
.
m_first
=
0
;
readPar
.
m_count
=
frag
.
m_numAttrs
;
readPar
.
m_count
=
frag
.
m_numAttrs
;
// leave in signal data
// leave in signal data
...
@@ -198,61 +130,11 @@ Dbtux::setNodePref(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, unsigned
...
@@ -198,61 +130,11 @@ Dbtux::setNodePref(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, unsigned
copyPar
.
m_items
=
readPar
.
m_count
;
copyPar
.
m_items
=
readPar
.
m_count
;
copyPar
.
m_headers
=
true
;
copyPar
.
m_headers
=
true
;
copyPar
.
m_maxwords
=
tree
.
m_prefSize
;
copyPar
.
m_maxwords
=
tree
.
m_prefSize
;
Data
pref
=
tmpPtr
.
p
->
getPref
(
i
);
Data
pref
=
node
.
getPref
(
i
);
copyAttrs
(
pref
,
readPar
.
m_data
,
copyPar
);
copyAttrs
(
pref
,
readPar
.
m_data
,
copyPar
);
nodePtr
.
p
->
m_flags
|=
NodeHandle
::
DoUpdate
;
}
}
/*
// node operations
* Commit and release nodes at the end of an operation. Used also on
* error since no changes have been made (updateOk false).
*/
void
Dbtux
::
commitNodes
(
Signal
*
signal
,
Frag
&
frag
,
bool
updateOk
)
{
TreeHead
&
tree
=
frag
.
m_tree
;
NodeHandlePtr
nodePtr
;
nodePtr
.
i
=
frag
.
m_nodeList
;
frag
.
m_nodeList
=
RNIL
;
while
(
nodePtr
.
i
!=
RNIL
)
{
c_nodeHandlePool
.
getPtr
(
nodePtr
);
const
unsigned
flags
=
nodePtr
.
p
->
m_flags
;
if
(
flags
&
NodeHandle
::
DoDelete
)
{
jam
();
ndbrequire
(
updateOk
);
// delete
StorePar
storePar
;
storePar
.
m_opCode
=
TupStoreTh
::
OpDelete
;
nodePtr
.
p
->
m_tux
.
tupStoreTh
(
signal
,
frag
,
nodePtr
,
storePar
);
ndbrequire
(
storePar
.
m_errorCode
==
0
);
}
else
if
(
flags
&
NodeHandle
::
DoUpdate
)
{
jam
();
ndbrequire
(
updateOk
);
// set prefixes
if
(
flags
&
(
1
<<
0
))
{
jam
();
setNodePref
(
signal
,
frag
,
nodePtr
,
0
);
}
if
(
flags
&
(
1
<<
1
))
{
jam
();
setNodePref
(
signal
,
frag
,
nodePtr
,
1
);
}
// update
StorePar
storePar
;
storePar
.
m_opCode
=
TupStoreTh
::
OpUpdate
;
storePar
.
m_offset
=
0
;
storePar
.
m_size
=
tree
.
getSize
(
nodePtr
.
p
->
m_acc
);
nodePtr
.
p
->
m_tux
.
tupStoreTh
(
signal
,
frag
,
nodePtr
,
storePar
);
ndbrequire
(
storePar
.
m_errorCode
==
0
);
}
// release
NodeHandlePtr
tmpPtr
=
nodePtr
;
nodePtr
.
i
=
nodePtr
.
p
->
m_next
;
c_nodeHandlePool
.
release
(
tmpPtr
);
}
}
// Dbtux::NodeHandle
/*
/*
* Add entry at position. Move entries greater than or equal to the old
* Add entry at position. Move entries greater than or equal to the old
...
@@ -264,25 +146,26 @@ Dbtux::commitNodes(Signal* signal, Frag& frag, bool updateOk)
...
@@ -264,25 +146,26 @@ Dbtux::commitNodes(Signal* signal, Frag& frag, bool updateOk)
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
*/
*/
void
void
Dbtux
::
NodeHandle
::
pushUp
(
Signal
*
signal
,
unsigned
pos
,
const
TreeEnt
&
ent
)
Dbtux
::
nodePushUp
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
const
TreeEnt
&
ent
)
{
{
TreeHead
&
tree
=
m_frag
.
m_tree
;
Frag
&
frag
=
node
.
m_frag
;
const
unsigned
occup
=
getOccup
();
TreeHead
&
tree
=
frag
.
m_tree
;
const
unsigned
occup
=
node
.
getOccup
();
ndbrequire
(
occup
<
tree
.
m_maxOccup
&&
pos
<=
occup
);
ndbrequire
(
occup
<
tree
.
m_maxOccup
&&
pos
<=
occup
);
// fix scans
// fix scans
ScanOpPtr
scanPtr
;
ScanOpPtr
scanPtr
;
scanPtr
.
i
=
getNodeScan
();
scanPtr
.
i
=
node
.
getNodeScan
();
while
(
scanPtr
.
i
!=
RNIL
)
{
while
(
scanPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
scanPtr
);
c_scanOpPool
.
getPtr
(
scanPtr
);
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
ndbrequire
(
scanPos
.
m_
addr
==
m_addr
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_
loc
==
node
.
m_loc
&&
scanPos
.
m_pos
<
occup
);
if
(
scanPos
.
m_pos
>=
pos
)
{
if
(
scanPos
.
m_pos
>=
pos
)
{
jam
();
jam
();
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"At pushUp pos="
<<
pos
<<
" "
<<
*
this
<<
endl
;
debugOut
<<
"At pushUp pos="
<<
pos
<<
" "
<<
node
<<
endl
;
}
}
#endif
#endif
scanPos
.
m_pos
++
;
scanPos
.
m_pos
++
;
...
@@ -290,7 +173,7 @@ Dbtux::NodeHandle::pushUp(Signal* signal, unsigned pos, const TreeEnt& ent)
...
@@ -290,7 +173,7 @@ Dbtux::NodeHandle::pushUp(Signal* signal, unsigned pos, const TreeEnt& ent)
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
}
}
// fix node
// fix node
TreeEnt
*
const
entList
=
tree
.
getEntList
(
m_node
);
TreeEnt
*
const
entList
=
tree
.
getEntList
(
node
.
m_node
);
entList
[
occup
]
=
entList
[
0
];
entList
[
occup
]
=
entList
[
0
];
TreeEnt
*
const
tmpList
=
entList
+
1
;
TreeEnt
*
const
tmpList
=
entList
+
1
;
for
(
unsigned
i
=
occup
;
i
>
pos
;
i
--
)
{
for
(
unsigned
i
=
occup
;
i
>
pos
;
i
--
)
{
...
@@ -298,18 +181,18 @@ Dbtux::NodeHandle::pushUp(Signal* signal, unsigned pos, const TreeEnt& ent)
...
@@ -298,18 +181,18 @@ Dbtux::NodeHandle::pushUp(Signal* signal, unsigned pos, const TreeEnt& ent)
tmpList
[
i
]
=
tmpList
[
i
-
1
];
tmpList
[
i
]
=
tmpList
[
i
-
1
];
}
}
tmpList
[
pos
]
=
ent
;
tmpList
[
pos
]
=
ent
;
entList
[
0
]
=
entList
[
occup
+
1
];
node
.
setOccup
(
occup
+
1
);
// fix prefixes
if
(
occup
==
0
||
pos
==
0
)
if
(
occup
==
0
||
pos
==
0
)
m_flags
|=
(
1
<<
0
);
setNodePref
(
signal
,
node
,
0
);
if
(
occup
==
0
||
pos
==
occup
)
if
(
occup
==
0
||
pos
==
occup
)
m_flags
|=
(
1
<<
1
);
setNodePref
(
signal
,
node
,
1
);
entList
[
0
]
=
entList
[
occup
+
1
];
setOccup
(
occup
+
1
);
m_flags
|=
DoUpdate
;
}
}
/*
/*
* Remove and return entry at position. Move entries greater than the
* Remove and return entry at position. Move entries greater than the
* removed one to the left. This is the opposite of
p
ushUp.
* removed one to the left. This is the opposite of
nodeP
ushUp.
*
*
* D
* D
* ^ ^
* ^ ^
...
@@ -317,46 +200,47 @@ Dbtux::NodeHandle::pushUp(Signal* signal, unsigned pos, const TreeEnt& ent)
...
@@ -317,46 +200,47 @@ Dbtux::NodeHandle::pushUp(Signal* signal, unsigned pos, const TreeEnt& ent)
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
*/
*/
void
void
Dbtux
::
NodeHandle
::
popDown
(
Signal
*
signal
,
unsigned
pos
,
TreeEnt
&
ent
)
Dbtux
::
nodePopDown
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
TreeEnt
&
ent
)
{
{
TreeHead
&
tree
=
m_frag
.
m_tree
;
Frag
&
frag
=
node
.
m_frag
;
const
unsigned
occup
=
getOccup
();
TreeHead
&
tree
=
frag
.
m_tree
;
const
unsigned
occup
=
node
.
getOccup
();
ndbrequire
(
occup
<=
tree
.
m_maxOccup
&&
pos
<
occup
);
ndbrequire
(
occup
<=
tree
.
m_maxOccup
&&
pos
<
occup
);
ScanOpPtr
scanPtr
;
ScanOpPtr
scanPtr
;
// move scans whose entry disappears
// move scans whose entry disappears
scanPtr
.
i
=
getNodeScan
();
scanPtr
.
i
=
node
.
getNodeScan
();
while
(
scanPtr
.
i
!=
RNIL
)
{
while
(
scanPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
scanPtr
);
c_scanOpPool
.
getPtr
(
scanPtr
);
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
ndbrequire
(
scanPos
.
m_
addr
==
m_addr
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_
loc
==
node
.
m_loc
&&
scanPos
.
m_pos
<
occup
);
const
Uint32
nextPtrI
=
scanPtr
.
p
->
m_nodeScan
;
const
Uint32
nextPtrI
=
scanPtr
.
p
->
m_nodeScan
;
if
(
scanPos
.
m_pos
==
pos
)
{
if
(
scanPos
.
m_pos
==
pos
)
{
jam
();
jam
();
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Move scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Move scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"At popDown pos="
<<
pos
<<
" "
<<
*
this
<<
endl
;
debugOut
<<
"At popDown pos="
<<
pos
<<
" "
<<
node
<<
endl
;
}
}
#endif
#endif
m_tux
.
scanNext
(
signal
,
scanPtr
);
scanNext
(
signal
,
scanPtr
);
}
}
scanPtr
.
i
=
nextPtrI
;
scanPtr
.
i
=
nextPtrI
;
}
}
// fix other scans
// fix other scans
scanPtr
.
i
=
getNodeScan
();
scanPtr
.
i
=
node
.
getNodeScan
();
while
(
scanPtr
.
i
!=
RNIL
)
{
while
(
scanPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
scanPtr
);
c_scanOpPool
.
getPtr
(
scanPtr
);
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
ndbrequire
(
scanPos
.
m_
addr
==
m_addr
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_
loc
==
node
.
m_loc
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_pos
!=
pos
);
ndbrequire
(
scanPos
.
m_pos
!=
pos
);
if
(
scanPos
.
m_pos
>
pos
)
{
if
(
scanPos
.
m_pos
>
pos
)
{
jam
();
jam
();
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"At popDown pos="
<<
pos
<<
" "
<<
*
this
<<
endl
;
debugOut
<<
"At popDown pos="
<<
pos
<<
" "
<<
node
<<
endl
;
}
}
#endif
#endif
scanPos
.
m_pos
--
;
scanPos
.
m_pos
--
;
...
@@ -364,7 +248,7 @@ Dbtux::NodeHandle::popDown(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -364,7 +248,7 @@ Dbtux::NodeHandle::popDown(Signal* signal, unsigned pos, TreeEnt& ent)
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
}
}
// fix node
// fix node
TreeEnt
*
const
entList
=
tree
.
getEntList
(
m_node
);
TreeEnt
*
const
entList
=
tree
.
getEntList
(
node
.
m_node
);
entList
[
occup
]
=
entList
[
0
];
entList
[
occup
]
=
entList
[
0
];
TreeEnt
*
const
tmpList
=
entList
+
1
;
TreeEnt
*
const
tmpList
=
entList
+
1
;
ent
=
tmpList
[
pos
];
ent
=
tmpList
[
pos
];
...
@@ -372,13 +256,13 @@ Dbtux::NodeHandle::popDown(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -372,13 +256,13 @@ Dbtux::NodeHandle::popDown(Signal* signal, unsigned pos, TreeEnt& ent)
jam
();
jam
();
tmpList
[
i
]
=
tmpList
[
i
+
1
];
tmpList
[
i
]
=
tmpList
[
i
+
1
];
}
}
entList
[
0
]
=
entList
[
occup
-
1
];
node
.
setOccup
(
occup
-
1
);
// fix prefixes
if
(
occup
!=
1
&&
pos
==
0
)
if
(
occup
!=
1
&&
pos
==
0
)
m_flags
|=
(
1
<<
0
);
setNodePref
(
signal
,
node
,
0
);
if
(
occup
!=
1
&&
pos
==
occup
-
1
)
if
(
occup
!=
1
&&
pos
==
occup
-
1
)
m_flags
|=
(
1
<<
1
);
setNodePref
(
signal
,
node
,
1
);
entList
[
0
]
=
entList
[
occup
-
1
];
setOccup
(
occup
-
1
);
m_flags
|=
DoUpdate
;
}
}
/*
/*
...
@@ -391,47 +275,48 @@ Dbtux::NodeHandle::popDown(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -391,47 +275,48 @@ Dbtux::NodeHandle::popDown(Signal* signal, unsigned pos, TreeEnt& ent)
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
*/
*/
void
void
Dbtux
::
NodeHandle
::
pushDown
(
Signal
*
signal
,
unsigned
pos
,
TreeEnt
&
ent
)
Dbtux
::
nodePushDown
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
TreeEnt
&
ent
)
{
{
TreeHead
&
tree
=
m_frag
.
m_tree
;
Frag
&
frag
=
node
.
m_frag
;
const
unsigned
occup
=
getOccup
();
TreeHead
&
tree
=
frag
.
m_tree
;
const
unsigned
occup
=
node
.
getOccup
();
ndbrequire
(
occup
<=
tree
.
m_maxOccup
&&
pos
<
occup
);
ndbrequire
(
occup
<=
tree
.
m_maxOccup
&&
pos
<
occup
);
ScanOpPtr
scanPtr
;
ScanOpPtr
scanPtr
;
// move scans whose entry disappears
// move scans whose entry disappears
scanPtr
.
i
=
getNodeScan
();
scanPtr
.
i
=
node
.
getNodeScan
();
while
(
scanPtr
.
i
!=
RNIL
)
{
while
(
scanPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
scanPtr
);
c_scanOpPool
.
getPtr
(
scanPtr
);
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
ndbrequire
(
scanPos
.
m_
addr
==
m_addr
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_
loc
==
node
.
m_loc
&&
scanPos
.
m_pos
<
occup
);
const
Uint32
nextPtrI
=
scanPtr
.
p
->
m_nodeScan
;
const
Uint32
nextPtrI
=
scanPtr
.
p
->
m_nodeScan
;
if
(
scanPos
.
m_pos
==
0
)
{
if
(
scanPos
.
m_pos
==
0
)
{
jam
();
jam
();
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Move scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Move scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"At pushDown pos="
<<
pos
<<
" "
<<
*
this
<<
endl
;
debugOut
<<
"At pushDown pos="
<<
pos
<<
" "
<<
node
<<
endl
;
}
}
#endif
#endif
// here we may miss a valid entry "X" XXX known bug
// here we may miss a valid entry "X" XXX known bug
m_tux
.
scanNext
(
signal
,
scanPtr
);
scanNext
(
signal
,
scanPtr
);
}
}
scanPtr
.
i
=
nextPtrI
;
scanPtr
.
i
=
nextPtrI
;
}
}
// fix other scans
// fix other scans
scanPtr
.
i
=
getNodeScan
();
scanPtr
.
i
=
node
.
getNodeScan
();
while
(
scanPtr
.
i
!=
RNIL
)
{
while
(
scanPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
scanPtr
);
c_scanOpPool
.
getPtr
(
scanPtr
);
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
ndbrequire
(
scanPos
.
m_
addr
==
m_addr
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_
loc
==
node
.
m_loc
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_pos
!=
0
);
ndbrequire
(
scanPos
.
m_pos
!=
0
);
if
(
scanPos
.
m_pos
<=
pos
)
{
if
(
scanPos
.
m_pos
<=
pos
)
{
jam
();
jam
();
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"At pushDown pos="
<<
pos
<<
" "
<<
*
this
<<
endl
;
debugOut
<<
"At pushDown pos="
<<
pos
<<
" "
<<
node
<<
endl
;
}
}
#endif
#endif
scanPos
.
m_pos
--
;
scanPos
.
m_pos
--
;
...
@@ -439,7 +324,7 @@ Dbtux::NodeHandle::pushDown(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -439,7 +324,7 @@ Dbtux::NodeHandle::pushDown(Signal* signal, unsigned pos, TreeEnt& ent)
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
}
}
// fix node
// fix node
TreeEnt
*
const
entList
=
tree
.
getEntList
(
m_node
);
TreeEnt
*
const
entList
=
tree
.
getEntList
(
node
.
m_node
);
entList
[
occup
]
=
entList
[
0
];
entList
[
occup
]
=
entList
[
0
];
TreeEnt
*
const
tmpList
=
entList
+
1
;
TreeEnt
*
const
tmpList
=
entList
+
1
;
TreeEnt
oldMin
=
tmpList
[
0
];
TreeEnt
oldMin
=
tmpList
[
0
];
...
@@ -449,18 +334,18 @@ Dbtux::NodeHandle::pushDown(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -449,18 +334,18 @@ Dbtux::NodeHandle::pushDown(Signal* signal, unsigned pos, TreeEnt& ent)
}
}
tmpList
[
pos
]
=
ent
;
tmpList
[
pos
]
=
ent
;
ent
=
oldMin
;
ent
=
oldMin
;
entList
[
0
]
=
entList
[
occup
];
// fix prefixes
if
(
true
)
if
(
true
)
m_flags
|=
(
1
<<
0
);
setNodePref
(
signal
,
node
,
0
);
if
(
occup
==
1
||
pos
==
occup
-
1
)
if
(
occup
==
1
||
pos
==
occup
-
1
)
m_flags
|=
(
1
<<
1
);
setNodePref
(
signal
,
node
,
1
);
entList
[
0
]
=
entList
[
occup
];
m_flags
|=
DoUpdate
;
}
}
/*
/*
* Remove and return entry at position. Move entries less than the
* Remove and return entry at position. Move entries less than the
* removed one to the right. Replace min entry by the input entry.
* removed one to the right. Replace min entry by the input entry.
* This is the opposite of
p
ushDown.
* This is the opposite of
nodeP
ushDown.
*
*
* X D
* X D
* v ^ ^
* v ^ ^
...
@@ -468,47 +353,48 @@ Dbtux::NodeHandle::pushDown(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -468,47 +353,48 @@ Dbtux::NodeHandle::pushDown(Signal* signal, unsigned pos, TreeEnt& ent)
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
* 0 1 2 3 4 5 6 0 1 2 3 4 5 6
*/
*/
void
void
Dbtux
::
NodeHandle
::
popUp
(
Signal
*
signal
,
unsigned
pos
,
TreeEnt
&
ent
)
Dbtux
::
nodePopUp
(
Signal
*
signal
,
NodeHandle
&
node
,
unsigned
pos
,
TreeEnt
&
ent
)
{
{
TreeHead
&
tree
=
m_frag
.
m_tree
;
Frag
&
frag
=
node
.
m_frag
;
const
unsigned
occup
=
getOccup
();
TreeHead
&
tree
=
frag
.
m_tree
;
const
unsigned
occup
=
node
.
getOccup
();
ndbrequire
(
occup
<=
tree
.
m_maxOccup
&&
pos
<
occup
);
ndbrequire
(
occup
<=
tree
.
m_maxOccup
&&
pos
<
occup
);
ScanOpPtr
scanPtr
;
ScanOpPtr
scanPtr
;
// move scans whose entry disappears
// move scans whose entry disappears
scanPtr
.
i
=
getNodeScan
();
scanPtr
.
i
=
node
.
getNodeScan
();
while
(
scanPtr
.
i
!=
RNIL
)
{
while
(
scanPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
scanPtr
);
c_scanOpPool
.
getPtr
(
scanPtr
);
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
ndbrequire
(
scanPos
.
m_
addr
==
m_addr
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_
loc
==
node
.
m_loc
&&
scanPos
.
m_pos
<
occup
);
const
Uint32
nextPtrI
=
scanPtr
.
p
->
m_nodeScan
;
const
Uint32
nextPtrI
=
scanPtr
.
p
->
m_nodeScan
;
if
(
scanPos
.
m_pos
==
pos
)
{
if
(
scanPos
.
m_pos
==
pos
)
{
jam
();
jam
();
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Move scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Move scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"At popUp pos="
<<
pos
<<
" "
<<
*
this
<<
endl
;
debugOut
<<
"At popUp pos="
<<
pos
<<
" "
<<
node
<<
endl
;
}
}
#endif
#endif
// here we may miss a valid entry "X" XXX known bug
// here we may miss a valid entry "X" XXX known bug
m_tux
.
scanNext
(
signal
,
scanPtr
);
scanNext
(
signal
,
scanPtr
);
}
}
scanPtr
.
i
=
nextPtrI
;
scanPtr
.
i
=
nextPtrI
;
}
}
// fix other scans
// fix other scans
scanPtr
.
i
=
getNodeScan
();
scanPtr
.
i
=
node
.
getNodeScan
();
while
(
scanPtr
.
i
!=
RNIL
)
{
while
(
scanPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
scanPtr
);
c_scanOpPool
.
getPtr
(
scanPtr
);
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
TreePos
&
scanPos
=
scanPtr
.
p
->
m_scanPos
;
ndbrequire
(
scanPos
.
m_
addr
==
m_addr
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_
loc
==
node
.
m_loc
&&
scanPos
.
m_pos
<
occup
);
ndbrequire
(
scanPos
.
m_pos
!=
pos
);
ndbrequire
(
scanPos
.
m_pos
!=
pos
);
if
(
scanPos
.
m_pos
<
pos
)
{
if
(
scanPos
.
m_pos
<
pos
)
{
jam
();
jam
();
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Fix scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"At popUp pos="
<<
pos
<<
" "
<<
*
this
<<
endl
;
debugOut
<<
"At popUp pos="
<<
pos
<<
" "
<<
node
<<
endl
;
}
}
#endif
#endif
scanPos
.
m_pos
++
;
scanPos
.
m_pos
++
;
...
@@ -516,7 +402,7 @@ Dbtux::NodeHandle::popUp(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -516,7 +402,7 @@ Dbtux::NodeHandle::popUp(Signal* signal, unsigned pos, TreeEnt& ent)
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
scanPtr
.
i
=
scanPtr
.
p
->
m_nodeScan
;
}
}
// fix node
// fix node
TreeEnt
*
const
entList
=
tree
.
getEntList
(
m_node
);
TreeEnt
*
const
entList
=
tree
.
getEntList
(
node
.
m_node
);
entList
[
occup
]
=
entList
[
0
];
entList
[
occup
]
=
entList
[
0
];
TreeEnt
*
const
tmpList
=
entList
+
1
;
TreeEnt
*
const
tmpList
=
entList
+
1
;
TreeEnt
newMin
=
ent
;
TreeEnt
newMin
=
ent
;
...
@@ -526,12 +412,12 @@ Dbtux::NodeHandle::popUp(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -526,12 +412,12 @@ Dbtux::NodeHandle::popUp(Signal* signal, unsigned pos, TreeEnt& ent)
tmpList
[
i
]
=
tmpList
[
i
-
1
];
tmpList
[
i
]
=
tmpList
[
i
-
1
];
}
}
tmpList
[
0
]
=
newMin
;
tmpList
[
0
]
=
newMin
;
entList
[
0
]
=
entList
[
occup
];
// fix prefixes
if
(
true
)
if
(
true
)
m_flags
|=
(
1
<<
0
);
setNodePref
(
signal
,
node
,
0
);
if
(
occup
==
1
||
pos
==
occup
-
1
)
if
(
occup
==
1
||
pos
==
occup
-
1
)
m_flags
|=
(
1
<<
1
);
setNodePref
(
signal
,
node
,
1
);
entList
[
0
]
=
entList
[
occup
];
m_flags
|=
DoUpdate
;
}
}
/*
/*
...
@@ -539,14 +425,15 @@ Dbtux::NodeHandle::popUp(Signal* signal, unsigned pos, TreeEnt& ent)
...
@@ -539,14 +425,15 @@ Dbtux::NodeHandle::popUp(Signal* signal, unsigned pos, TreeEnt& ent)
* after the max (i=1). XXX can be optimized
* after the max (i=1). XXX can be optimized
*/
*/
void
void
Dbtux
::
NodeHandle
::
slide
(
Signal
*
signal
,
NodeHandlePtr
nodePtr
,
unsigned
i
)
Dbtux
::
nodeSlide
(
Signal
*
signal
,
NodeHandle
&
dstNode
,
NodeHandle
&
srcNode
,
unsigned
i
)
{
{
Frag
&
frag
=
dstNode
.
m_frag
;
TreeHead
&
tree
=
frag
.
m_tree
;
ndbrequire
(
i
<=
1
);
ndbrequire
(
i
<=
1
);
TreeHead
&
tree
=
m_frag
.
m_tree
;
while
(
dstNode
.
getOccup
()
<
tree
.
m_maxOccup
&&
srcNode
.
getOccup
()
!=
0
)
{
while
(
getOccup
()
<
tree
.
m_maxOccup
&&
nodePtr
.
p
->
getOccup
()
!=
0
)
{
TreeEnt
ent
;
TreeEnt
ent
;
nodeP
tr
.
p
->
popDown
(
signal
,
i
==
0
?
nodePtr
.
p
->
getOccup
()
-
1
:
0
,
ent
);
nodeP
opDown
(
signal
,
srcNode
,
i
==
0
?
srcNode
.
getOccup
()
-
1
:
0
,
ent
);
pushUp
(
signal
,
i
==
0
?
0
:
getOccup
(),
ent
);
nodePushUp
(
signal
,
dstNode
,
i
==
0
?
0
:
dstNode
.
getOccup
(),
ent
);
}
}
}
}
...
@@ -555,50 +442,50 @@ Dbtux::NodeHandle::slide(Signal* signal, NodeHandlePtr nodePtr, unsigned i)
...
@@ -555,50 +442,50 @@ Dbtux::NodeHandle::slide(Signal* signal, NodeHandlePtr nodePtr, unsigned i)
* ordering does not matter.
* ordering does not matter.
*/
*/
void
void
Dbtux
::
NodeHandle
::
linkScan
(
Dbtux
::
ScanOpPtr
scanPtr
)
Dbtux
::
linkScan
(
NodeHandle
&
node
,
ScanOpPtr
scanPtr
)
{
{
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Link scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Link scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"To node "
<<
*
this
<<
endl
;
debugOut
<<
"To node "
<<
node
<<
endl
;
}
}
#endif
#endif
ndbrequire
(
!
islinkScan
(
scanPtr
)
&&
scanPtr
.
p
->
m_nodeScan
==
RNIL
);
ndbrequire
(
!
islinkScan
(
node
,
scanPtr
)
&&
scanPtr
.
p
->
m_nodeScan
==
RNIL
);
scanPtr
.
p
->
m_nodeScan
=
getNodeScan
();
scanPtr
.
p
->
m_nodeScan
=
node
.
getNodeScan
();
setNodeScan
(
scanPtr
.
i
);
node
.
setNodeScan
(
scanPtr
.
i
);
}
}
/*
/*
* Unlink a scan from the list under the node.
* Unlink a scan from the list under the node.
*/
*/
void
void
Dbtux
::
NodeHandle
::
unlinkScan
(
Dbtux
::
ScanOpPtr
scanPtr
)
Dbtux
::
unlinkScan
(
NodeHandle
&
node
,
ScanOpPtr
scanPtr
)
{
{
#ifdef VM_TRACE
#ifdef VM_TRACE
if
(
m_tux
.
debugFlags
&
m_tux
.
DebugScan
)
{
if
(
debugFlags
&
DebugScan
)
{
m_tux
.
debugOut
<<
"Unlink scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
debugOut
<<
"Unlink scan "
<<
scanPtr
.
i
<<
" "
<<
*
scanPtr
.
p
<<
endl
;
m_tux
.
debugOut
<<
"From node "
<<
*
this
<<
endl
;
debugOut
<<
"From node "
<<
node
<<
endl
;
}
}
#endif
#endif
Dbtux
::
ScanOpPtr
currPtr
;
ScanOpPtr
currPtr
;
currPtr
.
i
=
getNodeScan
();
currPtr
.
i
=
node
.
getNodeScan
();
Dbtux
::
ScanOpPtr
prevPtr
;
ScanOpPtr
prevPtr
;
prevPtr
.
i
=
RNIL
;
prevPtr
.
i
=
RNIL
;
while
(
true
)
{
while
(
true
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
currPtr
);
c_scanOpPool
.
getPtr
(
currPtr
);
Uint32
nextPtrI
=
currPtr
.
p
->
m_nodeScan
;
Uint32
nextPtrI
=
currPtr
.
p
->
m_nodeScan
;
if
(
currPtr
.
i
==
scanPtr
.
i
)
{
if
(
currPtr
.
i
==
scanPtr
.
i
)
{
jam
();
jam
();
if
(
prevPtr
.
i
==
RNIL
)
{
if
(
prevPtr
.
i
==
RNIL
)
{
setNodeScan
(
nextPtrI
);
node
.
setNodeScan
(
nextPtrI
);
}
else
{
}
else
{
jam
();
jam
();
prevPtr
.
p
->
m_nodeScan
=
nextPtrI
;
prevPtr
.
p
->
m_nodeScan
=
nextPtrI
;
}
}
scanPtr
.
p
->
m_nodeScan
=
RNIL
;
scanPtr
.
p
->
m_nodeScan
=
RNIL
;
// check for duplicates
// check for duplicates
ndbrequire
(
!
islinkScan
(
scanPtr
));
ndbrequire
(
!
islinkScan
(
node
,
scanPtr
));
return
;
return
;
}
}
prevPtr
=
currPtr
;
prevPtr
=
currPtr
;
...
@@ -610,13 +497,13 @@ Dbtux::NodeHandle::unlinkScan(Dbtux::ScanOpPtr scanPtr)
...
@@ -610,13 +497,13 @@ Dbtux::NodeHandle::unlinkScan(Dbtux::ScanOpPtr scanPtr)
* Check if a scan is linked to this node. Only for ndbrequire.
* Check if a scan is linked to this node. Only for ndbrequire.
*/
*/
bool
bool
Dbtux
::
NodeHandle
::
islinkScan
(
Dbtux
::
ScanOpPtr
scanPtr
)
Dbtux
::
islinkScan
(
NodeHandle
&
node
,
ScanOpPtr
scanPtr
)
{
{
Dbtux
::
ScanOpPtr
currPtr
;
ScanOpPtr
currPtr
;
currPtr
.
i
=
getNodeScan
();
currPtr
.
i
=
node
.
getNodeScan
();
while
(
currPtr
.
i
!=
RNIL
)
{
while
(
currPtr
.
i
!=
RNIL
)
{
jam
();
jam
();
m_tux
.
c_scanOpPool
.
getPtr
(
currPtr
);
c_scanOpPool
.
getPtr
(
currPtr
);
if
(
currPtr
.
i
==
scanPtr
.
i
)
{
if
(
currPtr
.
i
==
scanPtr
.
i
)
{
jam
();
jam
();
return
true
;
return
true
;
...
@@ -627,7 +514,7 @@ Dbtux::NodeHandle::islinkScan(Dbtux::ScanOpPtr scanPtr)
...
@@ -627,7 +514,7 @@ Dbtux::NodeHandle::islinkScan(Dbtux::ScanOpPtr scanPtr)
}
}
void
void
Dbtux
::
NodeHandle
::
progError
(
int
line
,
int
cause
,
const
char
*
extra
)
Dbtux
::
NodeHandle
::
progError
(
int
line
,
int
cause
,
const
char
*
file
)
{
{
m_tux
.
progError
(
line
,
cause
,
extra
);
ErrorReporter
::
handleAssert
(
"Dbtux::NodeHandle: assert failed"
,
file
,
line
);
}
}
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
View file @
d3b0753d
...
@@ -42,12 +42,11 @@ Dbtux::execACC_SCANREQ(Signal* signal)
...
@@ -42,12 +42,11 @@ Dbtux::execACC_SCANREQ(Signal* signal)
}
}
ndbrequire
(
fragPtr
.
i
!=
RNIL
);
ndbrequire
(
fragPtr
.
i
!=
RNIL
);
Frag
&
frag
=
*
fragPtr
.
p
;
Frag
&
frag
=
*
fragPtr
.
p
;
ndbrequire
(
frag
.
m_nodeList
==
RNIL
);
// must be normal DIH/TC fragment
// must be normal DIH/TC fragment
ndbrequire
(
frag
.
m_fragId
<
(
1
<<
frag
.
m_fragOff
));
ndbrequire
(
frag
.
m_fragId
<
(
1
<<
frag
.
m_fragOff
));
TreeHead
&
tree
=
frag
.
m_tree
;
TreeHead
&
tree
=
frag
.
m_tree
;
// check for empty fragment
// check for empty fragment
if
(
tree
.
m_root
==
NullTup
Addr
)
{
if
(
tree
.
m_root
==
NullTup
Loc
)
{
jam
();
jam
();
AccScanConf
*
const
conf
=
(
AccScanConf
*
)
signal
->
getDataPtrSend
();
AccScanConf
*
const
conf
=
(
AccScanConf
*
)
signal
->
getDataPtrSend
();
conf
->
scanPtr
=
req
->
senderData
;
conf
->
scanPtr
=
req
->
senderData
;
...
@@ -241,7 +240,6 @@ Dbtux::execNEXT_SCANREQ(Signal* signal)
...
@@ -241,7 +240,6 @@ Dbtux::execNEXT_SCANREQ(Signal* signal)
debugOut
<<
"NEXT_SCANREQ scan "
<<
scanPtr
.
i
<<
" "
<<
scan
<<
endl
;
debugOut
<<
"NEXT_SCANREQ scan "
<<
scanPtr
.
i
<<
" "
<<
scan
<<
endl
;
}
}
#endif
#endif
ndbrequire
(
frag
.
m_nodeList
==
RNIL
);
// handle unlock previous and close scan
// handle unlock previous and close scan
switch
(
req
->
scanFlag
)
{
switch
(
req
->
scanFlag
)
{
case
NextScanReq
:
:
ZSCAN_NEXT
:
case
NextScanReq
:
:
ZSCAN_NEXT
:
...
@@ -275,13 +273,13 @@ Dbtux::execNEXT_SCANREQ(Signal* signal)
...
@@ -275,13 +273,13 @@ Dbtux::execNEXT_SCANREQ(Signal* signal)
case
NextScanReq
:
:
ZSCAN_CLOSE
:
case
NextScanReq
:
:
ZSCAN_CLOSE
:
jam
();
jam
();
// unlink from tree node first to avoid state changes
// unlink from tree node first to avoid state changes
if
(
scan
.
m_scanPos
.
m_
addr
!=
NullTupAddr
)
{
if
(
scan
.
m_scanPos
.
m_
loc
!=
NullTupLoc
)
{
jam
();
jam
();
const
Tup
Addr
addr
=
scan
.
m_scanPos
.
m_addr
;
const
Tup
Loc
loc
=
scan
.
m_scanPos
.
m_loc
;
NodeHandle
Ptr
nodePtr
;
NodeHandle
node
(
frag
)
;
selectNode
(
signal
,
frag
,
nodePtr
,
addr
,
AccHead
);
selectNode
(
signal
,
node
,
loc
,
AccHead
);
nodePtr
.
p
->
unlinkScan
(
scanPtr
);
unlinkScan
(
node
,
scanPtr
);
scan
.
m_scanPos
.
m_
addr
=
NullTupAddr
;
scan
.
m_scanPos
.
m_
loc
=
NullTupLoc
;
}
}
if
(
scan
.
m_lockwait
)
{
if
(
scan
.
m_lockwait
)
{
jam
();
jam
();
...
@@ -295,7 +293,6 @@ Dbtux::execNEXT_SCANREQ(Signal* signal)
...
@@ -295,7 +293,6 @@ Dbtux::execNEXT_SCANREQ(Signal* signal)
jamEntry
();
jamEntry
();
ndbrequire
(
lockReq
->
returnCode
==
AccLockReq
::
Success
);
ndbrequire
(
lockReq
->
returnCode
==
AccLockReq
::
Success
);
scan
.
m_state
=
ScanOp
::
Aborting
;
scan
.
m_state
=
ScanOp
::
Aborting
;
commitNodes
(
signal
,
frag
,
true
);
return
;
return
;
}
}
if
(
scan
.
m_state
==
ScanOp
::
Locked
)
{
if
(
scan
.
m_state
==
ScanOp
::
Locked
)
{
...
@@ -350,7 +347,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -350,7 +347,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
signal
->
theData
[
1
]
=
true
;
signal
->
theData
[
1
]
=
true
;
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
jamEntry
();
jamEntry
();
commitNodes
(
signal
,
frag
,
true
);
return
;
// stop
return
;
// stop
}
}
if
(
scan
.
m_lockwait
)
{
if
(
scan
.
m_lockwait
)
{
...
@@ -365,7 +361,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -365,7 +361,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
// if TC has ordered scan close, it will be detected here
// if TC has ordered scan close, it will be detected here
sendSignal
(
scan
.
m_userRef
,
GSN_NEXT_SCANCONF
,
sendSignal
(
scan
.
m_userRef
,
GSN_NEXT_SCANCONF
,
signal
,
signalLength
,
JBB
);
signal
,
signalLength
,
JBB
);
commitNodes
(
signal
,
frag
,
true
);
return
;
// stop
return
;
// stop
}
}
if
(
scan
.
m_state
==
ScanOp
::
First
)
{
if
(
scan
.
m_state
==
ScanOp
::
First
)
{
...
@@ -407,8 +402,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -407,8 +402,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
lockReq
->
userRef
=
reference
();
lockReq
->
userRef
=
reference
();
lockReq
->
tableId
=
scan
.
m_tableId
;
lockReq
->
tableId
=
scan
.
m_tableId
;
lockReq
->
fragId
=
frag
.
m_fragId
|
(
ent
.
m_fragBit
<<
frag
.
m_fragOff
);
lockReq
->
fragId
=
frag
.
m_fragId
|
(
ent
.
m_fragBit
<<
frag
.
m_fragOff
);
// should cache this at fragment create
lockReq
->
fragPtrI
=
frag
.
m_accTableFragPtrI
[
ent
.
m_fragBit
];
lockReq
->
fragPtrI
=
RNIL
;
const
Uint32
*
const
buf32
=
static_cast
<
Uint32
*>
(
keyPar
.
m_data
);
const
Uint32
*
const
buf32
=
static_cast
<
Uint32
*>
(
keyPar
.
m_data
);
const
Uint64
*
const
buf64
=
reinterpret_cast
<
const
Uint64
*>
(
buf32
);
const
Uint64
*
const
buf64
=
reinterpret_cast
<
const
Uint64
*>
(
buf32
);
lockReq
->
hashValue
=
md5_hash
(
buf64
,
keyPar
.
m_size
);
lockReq
->
hashValue
=
md5_hash
(
buf64
,
keyPar
.
m_size
);
...
@@ -445,7 +439,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -445,7 +439,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
signal
->
theData
[
1
]
=
true
;
signal
->
theData
[
1
]
=
true
;
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
jamEntry
();
jamEntry
();
commitNodes
(
signal
,
frag
,
true
);
return
;
// stop
return
;
// stop
break
;
break
;
case
AccLockReq
:
:
Refused
:
case
AccLockReq
:
:
Refused
:
...
@@ -458,7 +451,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -458,7 +451,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
signal
->
theData
[
1
]
=
true
;
signal
->
theData
[
1
]
=
true
;
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
jamEntry
();
jamEntry
();
commitNodes
(
signal
,
frag
,
true
);
return
;
// stop
return
;
// stop
break
;
break
;
case
AccLockReq
:
:
NoFreeOp
:
case
AccLockReq
:
:
NoFreeOp
:
...
@@ -471,7 +463,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -471,7 +463,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
signal
->
theData
[
1
]
=
true
;
signal
->
theData
[
1
]
=
true
;
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
EXECUTE_DIRECT
(
DBLQH
,
GSN_CHECK_LCP_STOP
,
signal
,
2
);
jamEntry
();
jamEntry
();
commitNodes
(
signal
,
frag
,
true
);
return
;
// stop
return
;
// stop
break
;
break
;
default:
default:
...
@@ -555,7 +546,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -555,7 +546,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
scan
.
m_lastEnt
=
ent
;
scan
.
m_lastEnt
=
ent
;
// next time look for next entry
// next time look for next entry
scan
.
m_state
=
ScanOp
::
Next
;
scan
.
m_state
=
ScanOp
::
Next
;
commitNodes
(
signal
,
frag
,
true
);
return
;
return
;
}
}
// XXX in ACC this is checked before req->checkLcpStop
// XXX in ACC this is checked before req->checkLcpStop
...
@@ -569,7 +559,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
...
@@ -569,7 +559,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
unsigned
signalLength
=
3
;
unsigned
signalLength
=
3
;
sendSignal
(
scanPtr
.
p
->
m_userRef
,
GSN_NEXT_SCANCONF
,
sendSignal
(
scanPtr
.
p
->
m_userRef
,
GSN_NEXT_SCANCONF
,
signal
,
signalLength
,
JBB
);
signal
,
signalLength
,
JBB
);
commitNodes
(
signal
,
frag
,
true
);
return
;
return
;
}
}
ndbrequire
(
false
);
ndbrequire
(
false
);
...
@@ -700,15 +689,15 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr)
...
@@ -700,15 +689,15 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr)
ScanOp
&
scan
=
*
scanPtr
.
p
;
ScanOp
&
scan
=
*
scanPtr
.
p
;
Frag
&
frag
=
*
c_fragPool
.
getPtr
(
scan
.
m_fragPtrI
);
Frag
&
frag
=
*
c_fragPool
.
getPtr
(
scan
.
m_fragPtrI
);
TreeHead
&
tree
=
frag
.
m_tree
;
TreeHead
&
tree
=
frag
.
m_tree
;
if
(
tree
.
m_root
==
NullTup
Addr
)
{
if
(
tree
.
m_root
==
NullTup
Loc
)
{
// tree may have become empty
// tree may have become empty
jam
();
jam
();
scan
.
m_state
=
ScanOp
::
Last
;
scan
.
m_state
=
ScanOp
::
Last
;
return
;
return
;
}
}
TreePos
pos
;
TreePos
pos
;
pos
.
m_
addr
=
tree
.
m_root
;
pos
.
m_
loc
=
tree
.
m_root
;
NodeHandle
Ptr
nodePtr
;
NodeHandle
node
(
frag
)
;
// unpack lower bound
// unpack lower bound
const
ScanBound
&
bound
=
*
scan
.
m_bound
[
0
];
const
ScanBound
&
bound
=
*
scan
.
m_bound
[
0
];
ScanBoundIterator
iter
;
ScanBoundIterator
iter
;
...
@@ -725,20 +714,20 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr)
...
@@ -725,20 +714,20 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr)
boundPar
.
m_dir
=
0
;
boundPar
.
m_dir
=
0
;
loop:
{
loop:
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
nodePtr
,
pos
.
m_addr
,
AccPref
);
selectNode
(
signal
,
node
,
pos
.
m_loc
,
AccPref
);
const
unsigned
occup
=
node
Ptr
.
p
->
getOccup
();
const
unsigned
occup
=
node
.
getOccup
();
ndbrequire
(
occup
!=
0
);
ndbrequire
(
occup
!=
0
);
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
jam
();
jam
();
// compare prefix
// compare prefix
boundPar
.
m_data2
=
node
Ptr
.
p
->
getPref
(
i
);
boundPar
.
m_data2
=
node
.
getPref
(
i
);
boundPar
.
m_len2
=
tree
.
m_prefSize
;
boundPar
.
m_len2
=
tree
.
m_prefSize
;
int
ret
=
cmpScanBound
(
frag
,
boundPar
);
int
ret
=
cmpScanBound
(
frag
,
boundPar
);
if
(
ret
==
NdbSqlUtil
::
CmpUnknown
)
{
if
(
ret
==
NdbSqlUtil
::
CmpUnknown
)
{
jam
();
jam
();
// read full value
// read full value
ReadPar
readPar
;
ReadPar
readPar
;
readPar
.
m_ent
=
node
Ptr
.
p
->
getMinMax
(
i
);
readPar
.
m_ent
=
node
.
getMinMax
(
i
);
readPar
.
m_first
=
0
;
readPar
.
m_first
=
0
;
readPar
.
m_count
=
frag
.
m_numAttrs
;
readPar
.
m_count
=
frag
.
m_numAttrs
;
readPar
.
m_data
=
0
;
// leave in signal data
readPar
.
m_data
=
0
;
// leave in signal data
...
@@ -751,11 +740,11 @@ loop: {
...
@@ -751,11 +740,11 @@ loop: {
}
}
if
(
i
==
0
&&
ret
<
0
)
{
if
(
i
==
0
&&
ret
<
0
)
{
jam
();
jam
();
const
Tup
Addr
tupAddr
=
nodePtr
.
p
->
getLink
(
i
);
const
Tup
Loc
loc
=
node
.
getLink
(
i
);
if
(
tupAddr
!=
NullTupAddr
)
{
if
(
loc
!=
NullTupLoc
)
{
jam
();
jam
();
// continue to left subtree
// continue to left subtree
pos
.
m_
addr
=
tupAddr
;
pos
.
m_
loc
=
loc
;
goto
loop
;
goto
loop
;
}
}
// start scanning this node
// start scanning this node
...
@@ -764,34 +753,34 @@ loop: {
...
@@ -764,34 +753,34 @@ loop: {
pos
.
m_dir
=
3
;
pos
.
m_dir
=
3
;
scan
.
m_scanPos
=
pos
;
scan
.
m_scanPos
=
pos
;
scan
.
m_state
=
ScanOp
::
Next
;
scan
.
m_state
=
ScanOp
::
Next
;
nodePtr
.
p
->
linkScan
(
scanPtr
);
linkScan
(
node
,
scanPtr
);
return
;
return
;
}
}
if
(
i
==
1
&&
ret
>
0
)
{
if
(
i
==
1
&&
ret
>
0
)
{
jam
();
jam
();
const
Tup
Addr
tupAddr
=
nodePtr
.
p
->
getLink
(
i
);
const
Tup
Loc
loc
=
node
.
getLink
(
i
);
if
(
tupAddr
!=
NullTupAddr
)
{
if
(
loc
!=
NullTupLoc
)
{
jam
();
jam
();
// continue to right subtree
// continue to right subtree
pos
.
m_
addr
=
tupAddr
;
pos
.
m_
loc
=
loc
;
goto
loop
;
goto
loop
;
}
}
// start scanning upwards
// start scanning upwards
pos
.
m_dir
=
1
;
pos
.
m_dir
=
1
;
scan
.
m_scanPos
=
pos
;
scan
.
m_scanPos
=
pos
;
scan
.
m_state
=
ScanOp
::
Next
;
scan
.
m_state
=
ScanOp
::
Next
;
nodePtr
.
p
->
linkScan
(
scanPtr
);
linkScan
(
node
,
scanPtr
);
return
;
return
;
}
}
}
}
// read rest of current node
// read rest of current node
accessNode
(
signal
,
frag
,
nodePtr
,
AccFull
);
accessNode
(
signal
,
node
,
AccFull
);
// look for first entry
// look for first entry
ndbrequire
(
occup
>=
2
);
ndbrequire
(
occup
>=
2
);
for
(
unsigned
j
=
1
;
j
<
occup
;
j
++
)
{
for
(
unsigned
j
=
1
;
j
<
occup
;
j
++
)
{
jam
();
jam
();
ReadPar
readPar
;
ReadPar
readPar
;
readPar
.
m_ent
=
node
Ptr
.
p
->
getEnt
(
j
);
readPar
.
m_ent
=
node
.
getEnt
(
j
);
readPar
.
m_first
=
0
;
readPar
.
m_first
=
0
;
readPar
.
m_count
=
frag
.
m_numAttrs
;
readPar
.
m_count
=
frag
.
m_numAttrs
;
readPar
.
m_data
=
0
;
// leave in signal data
readPar
.
m_data
=
0
;
// leave in signal data
...
@@ -809,7 +798,7 @@ loop: {
...
@@ -809,7 +798,7 @@ loop: {
pos
.
m_dir
=
3
;
pos
.
m_dir
=
3
;
scan
.
m_scanPos
=
pos
;
scan
.
m_scanPos
=
pos
;
scan
.
m_state
=
ScanOp
::
Next
;
scan
.
m_state
=
ScanOp
::
Next
;
nodePtr
.
p
->
linkScan
(
scanPtr
);
linkScan
(
node
,
scanPtr
);
return
;
return
;
}
}
}
}
...
@@ -869,31 +858,31 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
...
@@ -869,31 +858,31 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
// use copy of position
// use copy of position
TreePos
pos
=
scan
.
m_scanPos
;
TreePos
pos
=
scan
.
m_scanPos
;
// get and remember original node
// get and remember original node
NodeHandle
Ptr
origNodePtr
;
NodeHandle
origNode
(
frag
)
;
selectNode
(
signal
,
frag
,
origNodePtr
,
pos
.
m_addr
,
AccHead
);
selectNode
(
signal
,
origNode
,
pos
.
m_loc
,
AccHead
);
ndbrequire
(
origNodePtr
.
p
->
islinkScan
(
scanPtr
));
ndbrequire
(
islinkScan
(
origNode
,
scanPtr
));
// current node in loop
// current node in loop
NodeHandle
Ptr
nodePtr
=
origNodePtr
;
NodeHandle
node
=
origNode
;
while
(
true
)
{
while
(
true
)
{
jam
();
jam
();
if
(
pos
.
m_dir
==
2
)
{
if
(
pos
.
m_dir
==
2
)
{
// coming up from root ends the scan
// coming up from root ends the scan
jam
();
jam
();
pos
.
m_
addr
=
NullTupAddr
;
pos
.
m_
loc
=
NullTupLoc
;
scan
.
m_state
=
ScanOp
::
Last
;
scan
.
m_state
=
ScanOp
::
Last
;
break
;
break
;
}
}
if
(
node
Ptr
.
p
->
m_addr
!=
pos
.
m_addr
)
{
if
(
node
.
m_loc
!=
pos
.
m_loc
)
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
nodePtr
,
pos
.
m_addr
,
AccHead
);
selectNode
(
signal
,
node
,
pos
.
m_loc
,
AccHead
);
}
}
if
(
pos
.
m_dir
==
4
)
{
if
(
pos
.
m_dir
==
4
)
{
// coming down from parent proceed to left child
// coming down from parent proceed to left child
jam
();
jam
();
Tup
Addr
addr
=
nodePtr
.
p
->
getLink
(
0
);
Tup
Loc
loc
=
node
.
getLink
(
0
);
if
(
addr
!=
NullTupAddr
)
{
if
(
loc
!=
NullTupLoc
)
{
jam
();
jam
();
pos
.
m_
addr
=
addr
;
pos
.
m_
loc
=
loc
;
pos
.
m_dir
=
4
;
// unchanged
pos
.
m_dir
=
4
;
// unchanged
continue
;
continue
;
}
}
...
@@ -910,10 +899,10 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
...
@@ -910,10 +899,10 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
if
(
pos
.
m_dir
==
3
)
{
if
(
pos
.
m_dir
==
3
)
{
// within node
// within node
jam
();
jam
();
unsigned
occup
=
node
Ptr
.
p
->
getOccup
();
unsigned
occup
=
node
.
getOccup
();
ndbrequire
(
occup
>=
1
);
ndbrequire
(
occup
>=
1
);
// access full node
// access full node
accessNode
(
signal
,
frag
,
nodePtr
,
AccFull
);
accessNode
(
signal
,
node
,
AccFull
);
// advance position
// advance position
if
(
!
pos
.
m_match
)
if
(
!
pos
.
m_match
)
pos
.
m_match
=
true
;
pos
.
m_match
=
true
;
...
@@ -921,7 +910,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
...
@@ -921,7 +910,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
pos
.
m_pos
++
;
pos
.
m_pos
++
;
if
(
pos
.
m_pos
<
occup
)
{
if
(
pos
.
m_pos
<
occup
)
{
jam
();
jam
();
pos
.
m_ent
=
node
Ptr
.
p
->
getEnt
(
pos
.
m_pos
);
pos
.
m_ent
=
node
.
getEnt
(
pos
.
m_pos
);
pos
.
m_dir
=
3
;
// unchanged
pos
.
m_dir
=
3
;
// unchanged
// XXX implement prefix optimization
// XXX implement prefix optimization
ReadPar
readPar
;
ReadPar
readPar
;
...
@@ -938,7 +927,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
...
@@ -938,7 +927,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
jam
();
jam
();
// hit upper bound of single range scan
// hit upper bound of single range scan
pos
.
m_
addr
=
NullTupAddr
;
pos
.
m_
loc
=
NullTupLoc
;
scan
.
m_state
=
ScanOp
::
Last
;
scan
.
m_state
=
ScanOp
::
Last
;
break
;
break
;
}
}
...
@@ -952,10 +941,10 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
...
@@ -952,10 +941,10 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
break
;
break
;
}
}
// after node proceed to right child
// after node proceed to right child
Tup
Addr
addr
=
nodePtr
.
p
->
getLink
(
1
);
Tup
Loc
loc
=
node
.
getLink
(
1
);
if
(
addr
!=
NullTupAddr
)
{
if
(
loc
!=
NullTupLoc
)
{
jam
();
jam
();
pos
.
m_
addr
=
addr
;
pos
.
m_
loc
=
loc
;
pos
.
m_dir
=
4
;
pos
.
m_dir
=
4
;
continue
;
continue
;
}
}
...
@@ -965,8 +954,8 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
...
@@ -965,8 +954,8 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
if
(
pos
.
m_dir
==
1
)
{
if
(
pos
.
m_dir
==
1
)
{
// coming from right child proceed to parent
// coming from right child proceed to parent
jam
();
jam
();
pos
.
m_
addr
=
nodePtr
.
p
->
getLink
(
2
);
pos
.
m_
loc
=
node
.
getLink
(
2
);
pos
.
m_dir
=
node
Ptr
.
p
->
getSide
();
pos
.
m_dir
=
node
.
getSide
();
continue
;
continue
;
}
}
ndbrequire
(
false
);
ndbrequire
(
false
);
...
@@ -975,16 +964,16 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
...
@@ -975,16 +964,16 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
scan
.
m_scanPos
=
pos
;
scan
.
m_scanPos
=
pos
;
// relink
// relink
if
(
scan
.
m_state
==
ScanOp
::
Current
)
{
if
(
scan
.
m_state
==
ScanOp
::
Current
)
{
ndbrequire
(
pos
.
m_
addr
==
nodePtr
.
p
->
m_addr
);
ndbrequire
(
pos
.
m_
loc
==
node
.
m_loc
);
if
(
origNode
Ptr
.
i
!=
nodePtr
.
i
)
{
if
(
origNode
.
m_loc
!=
node
.
m_loc
)
{
jam
();
jam
();
origNodePtr
.
p
->
unlinkScan
(
scanPtr
);
unlinkScan
(
origNode
,
scanPtr
);
nodePtr
.
p
->
linkScan
(
scanPtr
);
linkScan
(
node
,
scanPtr
);
}
}
}
else
if
(
scan
.
m_state
==
ScanOp
::
Last
)
{
}
else
if
(
scan
.
m_state
==
ScanOp
::
Last
)
{
jam
();
jam
();
ndbrequire
(
pos
.
m_
addr
==
NullTupAddr
);
ndbrequire
(
pos
.
m_
loc
==
NullTupLoc
);
origNodePtr
.
p
->
unlinkScan
(
scanPtr
);
unlinkScan
(
origNode
,
scanPtr
);
}
else
{
}
else
{
ndbrequire
(
false
);
ndbrequire
(
false
);
}
}
...
@@ -1044,7 +1033,6 @@ void
...
@@ -1044,7 +1033,6 @@ void
Dbtux
::
scanClose
(
Signal
*
signal
,
ScanOpPtr
scanPtr
)
Dbtux
::
scanClose
(
Signal
*
signal
,
ScanOpPtr
scanPtr
)
{
{
ScanOp
&
scan
=
*
scanPtr
.
p
;
ScanOp
&
scan
=
*
scanPtr
.
p
;
Frag
&
frag
=
*
c_fragPool
.
getPtr
(
scanPtr
.
p
->
m_fragPtrI
);
ndbrequire
(
!
scan
.
m_lockwait
&&
scan
.
m_accLockOp
==
RNIL
);
ndbrequire
(
!
scan
.
m_lockwait
&&
scan
.
m_accLockOp
==
RNIL
);
// unlock all not unlocked by LQH
// unlock all not unlocked by LQH
for
(
unsigned
i
=
0
;
i
<
MaxAccLockOps
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
MaxAccLockOps
;
i
++
)
{
...
@@ -1069,7 +1057,6 @@ Dbtux::scanClose(Signal* signal, ScanOpPtr scanPtr)
...
@@ -1069,7 +1057,6 @@ Dbtux::scanClose(Signal* signal, ScanOpPtr scanPtr)
sendSignal
(
scanPtr
.
p
->
m_userRef
,
GSN_NEXT_SCANCONF
,
sendSignal
(
scanPtr
.
p
->
m_userRef
,
GSN_NEXT_SCANCONF
,
signal
,
signalLength
,
JBB
);
signal
,
signalLength
,
JBB
);
releaseScanOp
(
scanPtr
);
releaseScanOp
(
scanPtr
);
commitNodes
(
signal
,
frag
,
true
);
}
}
void
void
...
...
ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp
View file @
d3b0753d
...
@@ -30,19 +30,19 @@ Dbtux::treeSearch(Signal* signal, Frag& frag, SearchPar searchPar, TreePos& tree
...
@@ -30,19 +30,19 @@ Dbtux::treeSearch(Signal* signal, Frag& frag, SearchPar searchPar, TreePos& tree
{
{
const
TreeHead
&
tree
=
frag
.
m_tree
;
const
TreeHead
&
tree
=
frag
.
m_tree
;
const
unsigned
numAttrs
=
frag
.
m_numAttrs
;
const
unsigned
numAttrs
=
frag
.
m_numAttrs
;
treePos
.
m_addr
=
tree
.
m_root
;
treePos
.
m_loc
=
tree
.
m_root
;
NodeHandlePtr
nodePtr
;
if
(
treePos
.
m_loc
==
NullTupLoc
)
{
if
(
treePos
.
m_addr
==
NullTupAddr
)
{
// empty tree
// empty tree
jam
();
jam
();
treePos
.
m_pos
=
0
;
treePos
.
m_pos
=
0
;
treePos
.
m_match
=
false
;
treePos
.
m_match
=
false
;
return
;
return
;
}
}
NodeHandle
node
(
frag
);
loop:
{
loop:
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
nodePtr
,
treePos
.
m_addr
,
AccPref
);
selectNode
(
signal
,
node
,
treePos
.
m_loc
,
AccPref
);
const
unsigned
occup
=
node
Ptr
.
p
->
getOccup
();
const
unsigned
occup
=
node
.
getOccup
();
ndbrequire
(
occup
!=
0
);
ndbrequire
(
occup
!=
0
);
// number of equal initial attributes in bounding node
// number of equal initial attributes in bounding node
unsigned
numEq
=
ZNIL
;
unsigned
numEq
=
ZNIL
;
...
@@ -51,7 +51,7 @@ loop: {
...
@@ -51,7 +51,7 @@ loop: {
// compare prefix
// compare prefix
CmpPar
cmpPar
;
CmpPar
cmpPar
;
cmpPar
.
m_data1
=
searchPar
.
m_data
;
cmpPar
.
m_data1
=
searchPar
.
m_data
;
cmpPar
.
m_data2
=
node
Ptr
.
p
->
getPref
(
i
);
cmpPar
.
m_data2
=
node
.
getPref
(
i
);
cmpPar
.
m_len2
=
tree
.
m_prefSize
;
cmpPar
.
m_len2
=
tree
.
m_prefSize
;
cmpPar
.
m_first
=
0
;
cmpPar
.
m_first
=
0
;
cmpPar
.
m_numEq
=
0
;
cmpPar
.
m_numEq
=
0
;
...
@@ -60,7 +60,7 @@ loop: {
...
@@ -60,7 +60,7 @@ loop: {
jam
();
jam
();
// read full value
// read full value
ReadPar
readPar
;
ReadPar
readPar
;
readPar
.
m_ent
=
node
Ptr
.
p
->
getMinMax
(
i
);
readPar
.
m_ent
=
node
.
getMinMax
(
i
);
ndbrequire
(
cmpPar
.
m_numEq
<
numAttrs
);
ndbrequire
(
cmpPar
.
m_numEq
<
numAttrs
);
readPar
.
m_first
=
cmpPar
.
m_numEq
;
readPar
.
m_first
=
cmpPar
.
m_numEq
;
readPar
.
m_count
=
numAttrs
-
cmpPar
.
m_numEq
;
readPar
.
m_count
=
numAttrs
-
cmpPar
.
m_numEq
;
...
@@ -78,19 +78,18 @@ loop: {
...
@@ -78,19 +78,18 @@ loop: {
if
(
ret
==
0
)
{
if
(
ret
==
0
)
{
jam
();
jam
();
// keys are equal, compare entry values
// keys are equal, compare entry values
ret
=
searchPar
.
m_ent
.
cmp
(
node
Ptr
.
p
->
getMinMax
(
i
));
ret
=
searchPar
.
m_ent
.
cmp
(
node
.
getMinMax
(
i
));
}
}
if
(
i
==
0
?
(
ret
<
0
)
:
(
ret
>
0
))
{
if
(
i
==
0
?
(
ret
<
0
)
:
(
ret
>
0
))
{
jam
();
jam
();
const
Tup
Addr
tupAddr
=
nodePtr
.
p
->
getLink
(
i
);
const
Tup
Loc
loc
=
node
.
getLink
(
i
);
if
(
tupAddr
!=
NullTupAddr
)
{
if
(
loc
!=
NullTupLoc
)
{
jam
();
jam
();
// continue to left/right subtree
// continue to left/right subtree
treePos
.
m_
addr
=
tupAddr
;
treePos
.
m_
loc
=
loc
;
goto
loop
;
goto
loop
;
}
}
// position is immediately before/after this node
// position is immediately before/after this node
// XXX disallow second case
treePos
.
m_pos
=
(
i
==
0
?
0
:
occup
);
treePos
.
m_pos
=
(
i
==
0
?
0
:
occup
);
treePos
.
m_match
=
false
;
treePos
.
m_match
=
false
;
return
;
return
;
...
@@ -103,8 +102,8 @@ loop: {
...
@@ -103,8 +102,8 @@ loop: {
return
;
return
;
}
}
}
}
//
read
rest of the bounding node
//
access
rest of the bounding node
accessNode
(
signal
,
frag
,
nodePtr
,
AccFull
);
accessNode
(
signal
,
node
,
AccFull
);
// position is strictly within the node
// position is strictly within the node
ndbrequire
(
occup
>=
2
);
ndbrequire
(
occup
>=
2
);
const
unsigned
numWithin
=
occup
-
2
;
const
unsigned
numWithin
=
occup
-
2
;
...
@@ -115,7 +114,7 @@ loop: {
...
@@ -115,7 +114,7 @@ loop: {
if
(
numEq
<
numAttrs
)
{
if
(
numEq
<
numAttrs
)
{
jam
();
jam
();
ReadPar
readPar
;
ReadPar
readPar
;
readPar
.
m_ent
=
node
Ptr
.
p
->
getEnt
(
j
);
readPar
.
m_ent
=
node
.
getEnt
(
j
);
readPar
.
m_first
=
numEq
;
readPar
.
m_first
=
numEq
;
readPar
.
m_count
=
numAttrs
-
numEq
;
readPar
.
m_count
=
numAttrs
-
numEq
;
readPar
.
m_data
=
0
;
// leave in signal data
readPar
.
m_data
=
0
;
// leave in signal data
...
@@ -132,7 +131,7 @@ loop: {
...
@@ -132,7 +131,7 @@ loop: {
if
(
ret
==
0
)
{
if
(
ret
==
0
)
{
jam
();
jam
();
// keys are equal, compare entry values
// keys are equal, compare entry values
ret
=
searchPar
.
m_ent
.
cmp
(
node
Ptr
.
p
->
getEnt
(
j
));
ret
=
searchPar
.
m_ent
.
cmp
(
node
.
getEnt
(
j
));
}
}
if
(
ret
<=
0
)
{
if
(
ret
<=
0
)
{
jam
();
jam
();
...
@@ -157,94 +156,94 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent)
...
@@ -157,94 +156,94 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent)
{
{
TreeHead
&
tree
=
frag
.
m_tree
;
TreeHead
&
tree
=
frag
.
m_tree
;
unsigned
pos
=
treePos
.
m_pos
;
unsigned
pos
=
treePos
.
m_pos
;
NodeHandle
Ptr
nodePtr
;
NodeHandle
node
(
frag
)
;
// check for empty tree
// check for empty tree
if
(
treePos
.
m_
addr
==
NullTupAddr
)
{
if
(
treePos
.
m_
loc
==
NullTupLoc
)
{
jam
();
jam
();
insertNode
(
signal
,
frag
,
nodePtr
,
AccPref
);
insertNode
(
signal
,
node
,
AccPref
);
nodeP
tr
.
p
->
pushUp
(
signal
,
0
,
ent
);
nodeP
ushUp
(
signal
,
node
,
0
,
ent
);
node
Ptr
.
p
->
setSide
(
2
);
node
.
setSide
(
2
);
tree
.
m_root
=
node
Ptr
.
p
->
m_addr
;
tree
.
m_root
=
node
.
m_loc
;
return
;
return
;
}
}
// access full node
// access full node
selectNode
(
signal
,
frag
,
nodePtr
,
treePos
.
m_addr
,
AccFull
);
selectNode
(
signal
,
node
,
treePos
.
m_loc
,
AccFull
);
// check if it is bounding node
// check if it is bounding node
if
(
pos
!=
0
&&
pos
!=
node
Ptr
.
p
->
getOccup
())
{
if
(
pos
!=
0
&&
pos
!=
node
.
getOccup
())
{
jam
();
jam
();
// check if room for one more
// check if room for one more
if
(
node
Ptr
.
p
->
getOccup
()
<
tree
.
m_maxOccup
)
{
if
(
node
.
getOccup
()
<
tree
.
m_maxOccup
)
{
jam
();
jam
();
nodeP
tr
.
p
->
pushUp
(
signal
,
pos
,
ent
);
nodeP
ushUp
(
signal
,
node
,
pos
,
ent
);
return
;
return
;
}
}
// returns min entry
// returns min entry
nodeP
tr
.
p
->
pushDown
(
signal
,
pos
-
1
,
ent
);
nodeP
ushDown
(
signal
,
node
,
pos
-
1
,
ent
);
// find position to add the removed min entry
// find position to add the removed min entry
Tup
Addr
childAddr
=
nodePtr
.
p
->
getLink
(
0
);
Tup
Loc
childLoc
=
node
.
getLink
(
0
);
if
(
child
Addr
==
NullTupAddr
)
{
if
(
child
Loc
==
NullTupLoc
)
{
jam
();
jam
();
// left child will be added
// left child will be added
pos
=
0
;
pos
=
0
;
}
else
{
}
else
{
jam
();
jam
();
// find glb node
// find glb node
while
(
child
Addr
!=
NullTupAddr
)
{
while
(
child
Loc
!=
NullTupLoc
)
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
nodePtr
,
childAddr
,
AccHead
);
selectNode
(
signal
,
node
,
childLoc
,
AccHead
);
child
Addr
=
nodePtr
.
p
->
getLink
(
1
);
child
Loc
=
node
.
getLink
(
1
);
}
}
// access full node again
// access full node again
accessNode
(
signal
,
frag
,
nodePtr
,
AccFull
);
accessNode
(
signal
,
node
,
AccFull
);
pos
=
node
Ptr
.
p
->
getOccup
();
pos
=
node
.
getOccup
();
}
}
// fall thru to next case
// fall thru to next case
}
}
// adding new min or max
// adding new min or max
unsigned
i
=
(
pos
==
0
?
0
:
1
);
unsigned
i
=
(
pos
==
0
?
0
:
1
);
ndbrequire
(
node
Ptr
.
p
->
getLink
(
i
)
==
NullTupAddr
);
ndbrequire
(
node
.
getLink
(
i
)
==
NullTupLoc
);
// check if the half-leaf/leaf has room for one more
// check if the half-leaf/leaf has room for one more
if
(
node
Ptr
.
p
->
getOccup
()
<
tree
.
m_maxOccup
)
{
if
(
node
.
getOccup
()
<
tree
.
m_maxOccup
)
{
jam
();
jam
();
nodeP
tr
.
p
->
pushUp
(
signal
,
pos
,
ent
);
nodeP
ushUp
(
signal
,
node
,
pos
,
ent
);
return
;
return
;
}
}
// add a new node
// add a new node
NodeHandle
Ptr
childPtr
;
NodeHandle
childNode
(
frag
)
;
insertNode
(
signal
,
frag
,
childPtr
,
AccPref
);
insertNode
(
signal
,
childNode
,
AccPref
);
childPtr
.
p
->
pushUp
(
signal
,
0
,
ent
);
nodePushUp
(
signal
,
childNode
,
0
,
ent
);
// connect parent and child
// connect parent and child
node
Ptr
.
p
->
setLink
(
i
,
childPtr
.
p
->
m_addr
);
node
.
setLink
(
i
,
childNode
.
m_loc
);
child
Ptr
.
p
->
setLink
(
2
,
nodePtr
.
p
->
m_addr
);
child
Node
.
setLink
(
2
,
node
.
m_loc
);
child
Ptr
.
p
->
setSide
(
i
);
child
Node
.
setSide
(
i
);
// re-balance tree at each node
// re-balance tree at each node
while
(
true
)
{
while
(
true
)
{
// height of subtree i has increased by 1
// height of subtree i has increased by 1
int
j
=
(
i
==
0
?
-
1
:
+
1
);
int
j
=
(
i
==
0
?
-
1
:
+
1
);
int
b
=
node
Ptr
.
p
->
getBalance
();
int
b
=
node
.
getBalance
();
if
(
b
==
0
)
{
if
(
b
==
0
)
{
// perfectly balanced
// perfectly balanced
jam
();
jam
();
node
Ptr
.
p
->
setBalance
(
j
);
node
.
setBalance
(
j
);
// height change propagates up
// height change propagates up
}
else
if
(
b
==
-
j
)
{
}
else
if
(
b
==
-
j
)
{
// height of shorter subtree increased
// height of shorter subtree increased
jam
();
jam
();
node
Ptr
.
p
->
setBalance
(
0
);
node
.
setBalance
(
0
);
// height of tree did not change - done
// height of tree did not change - done
break
;
break
;
}
else
if
(
b
==
j
)
{
}
else
if
(
b
==
j
)
{
// height of longer subtree increased
// height of longer subtree increased
jam
();
jam
();
NodeHandle
Ptr
childPtr
;
NodeHandle
childNode
(
frag
)
;
selectNode
(
signal
,
frag
,
childPtr
,
nodePtr
.
p
->
getLink
(
i
),
AccHead
);
selectNode
(
signal
,
childNode
,
node
.
getLink
(
i
),
AccHead
);
int
b2
=
child
Ptr
.
p
->
getBalance
();
int
b2
=
child
Node
.
getBalance
();
if
(
b2
==
b
)
{
if
(
b2
==
b
)
{
jam
();
jam
();
treeRotateSingle
(
signal
,
frag
,
node
Ptr
,
i
);
treeRotateSingle
(
signal
,
frag
,
node
,
i
);
}
else
if
(
b2
==
-
b
)
{
}
else
if
(
b2
==
-
b
)
{
jam
();
jam
();
treeRotateDouble
(
signal
,
frag
,
node
Ptr
,
i
);
treeRotateDouble
(
signal
,
frag
,
node
,
i
);
}
else
{
}
else
{
// height of subtree increased so it cannot be perfectly balanced
// height of subtree increased so it cannot be perfectly balanced
ndbrequire
(
false
);
ndbrequire
(
false
);
...
@@ -254,14 +253,14 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent)
...
@@ -254,14 +253,14 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent)
}
else
{
}
else
{
ndbrequire
(
false
);
ndbrequire
(
false
);
}
}
Tup
Addr
parentAddr
=
nodePtr
.
p
->
getLink
(
2
);
Tup
Loc
parentLoc
=
node
.
getLink
(
2
);
if
(
parent
Addr
==
NullTupAddr
)
{
if
(
parent
Loc
==
NullTupLoc
)
{
jam
();
jam
();
// root node - done
// root node - done
break
;
break
;
}
}
i
=
node
Ptr
.
p
->
getSide
();
i
=
node
.
getSide
();
selectNode
(
signal
,
frag
,
nodePtr
,
parentAddr
,
AccHead
);
selectNode
(
signal
,
node
,
parentLoc
,
AccHead
);
}
}
}
}
...
@@ -273,101 +272,101 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
...
@@ -273,101 +272,101 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
{
{
TreeHead
&
tree
=
frag
.
m_tree
;
TreeHead
&
tree
=
frag
.
m_tree
;
unsigned
pos
=
treePos
.
m_pos
;
unsigned
pos
=
treePos
.
m_pos
;
NodeHandle
Ptr
nodePtr
;
NodeHandle
node
(
frag
)
;
// access full node
// access full node
selectNode
(
signal
,
frag
,
nodePtr
,
treePos
.
m_addr
,
AccFull
);
selectNode
(
signal
,
node
,
treePos
.
m_loc
,
AccFull
);
TreeEnt
ent
;
TreeEnt
ent
;
// check interior node first
// check interior node first
if
(
node
Ptr
.
p
->
getChilds
()
==
2
)
{
if
(
node
.
getChilds
()
==
2
)
{
jam
();
jam
();
ndbrequire
(
node
Ptr
.
p
->
getOccup
()
>=
tree
.
m_minOccup
);
ndbrequire
(
node
.
getOccup
()
>=
tree
.
m_minOccup
);
// check if no underflow
// check if no underflow
if
(
node
Ptr
.
p
->
getOccup
()
>
tree
.
m_minOccup
)
{
if
(
node
.
getOccup
()
>
tree
.
m_minOccup
)
{
jam
();
jam
();
nodeP
tr
.
p
->
popDown
(
signal
,
pos
,
ent
);
nodeP
opDown
(
signal
,
node
,
pos
,
ent
);
return
;
return
;
}
}
// save current handle
// save current handle
NodeHandle
Ptr
parentPtr
=
nodePtr
;
NodeHandle
parentNode
=
node
;
// find glb node
// find glb node
Tup
Addr
childAddr
=
nodePtr
.
p
->
getLink
(
0
);
Tup
Loc
childLoc
=
node
.
getLink
(
0
);
while
(
child
Addr
!=
NullTupAddr
)
{
while
(
child
Loc
!=
NullTupLoc
)
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
nodePtr
,
childAddr
,
AccHead
);
selectNode
(
signal
,
node
,
childLoc
,
AccHead
);
child
Addr
=
nodePtr
.
p
->
getLink
(
1
);
child
Loc
=
node
.
getLink
(
1
);
}
}
// access full node again
// access full node again
accessNode
(
signal
,
frag
,
nodePtr
,
AccFull
);
accessNode
(
signal
,
node
,
AccFull
);
// use glb max as new parent min
// use glb max as new parent min
ent
=
node
Ptr
.
p
->
getEnt
(
nodePtr
.
p
->
getOccup
()
-
1
);
ent
=
node
.
getEnt
(
node
.
getOccup
()
-
1
);
parentPtr
.
p
->
popUp
(
signal
,
pos
,
ent
);
nodePopUp
(
signal
,
parentNode
,
pos
,
ent
);
// set up to remove glb max
// set up to remove glb max
pos
=
node
Ptr
.
p
->
getOccup
()
-
1
;
pos
=
node
.
getOccup
()
-
1
;
// fall thru to next case
// fall thru to next case
}
}
// remove the element
// remove the element
nodeP
tr
.
p
->
popDown
(
signal
,
pos
,
ent
);
nodeP
opDown
(
signal
,
node
,
pos
,
ent
);
ndbrequire
(
node
Ptr
.
p
->
getChilds
()
<=
1
);
ndbrequire
(
node
.
getChilds
()
<=
1
);
// handle half-leaf
// handle half-leaf
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<=
1
;
i
++
)
{
jam
();
jam
();
Tup
Addr
childAddr
=
nodePtr
.
p
->
getLink
(
i
);
Tup
Loc
childLoc
=
node
.
getLink
(
i
);
if
(
child
Addr
!=
NullTupAddr
)
{
if
(
child
Loc
!=
NullTupLoc
)
{
// move to child
// move to child
selectNode
(
signal
,
frag
,
nodePtr
,
childAddr
,
AccFull
);
selectNode
(
signal
,
node
,
childLoc
,
AccFull
);
// balance of half-leaf parent requires child to be leaf
// balance of half-leaf parent requires child to be leaf
break
;
break
;
}
}
}
}
ndbrequire
(
node
Ptr
.
p
->
getChilds
()
==
0
);
ndbrequire
(
node
.
getChilds
()
==
0
);
// get parent if any
// get parent if any
Tup
Addr
parentAddr
=
nodePtr
.
p
->
getLink
(
2
);
Tup
Loc
parentLoc
=
node
.
getLink
(
2
);
NodeHandle
Ptr
parentPtr
;
NodeHandle
parentNode
(
frag
)
;
unsigned
i
=
node
Ptr
.
p
->
getSide
();
unsigned
i
=
node
.
getSide
();
// move all that fits into parent
// move all that fits into parent
if
(
parent
Addr
!=
NullTupAddr
)
{
if
(
parent
Loc
!=
NullTupLoc
)
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
parentPtr
,
nodePtr
.
p
->
getLink
(
2
),
AccFull
);
selectNode
(
signal
,
parentNode
,
node
.
getLink
(
2
),
AccFull
);
parentPtr
.
p
->
slide
(
signal
,
nodePtr
,
i
);
nodeSlide
(
signal
,
parentNode
,
node
,
i
);
// fall thru to next case
// fall thru to next case
}
}
// non-empty leaf
// non-empty leaf
if
(
node
Ptr
.
p
->
getOccup
()
>=
1
)
{
if
(
node
.
getOccup
()
>=
1
)
{
jam
();
jam
();
return
;
return
;
}
}
// remove empty leaf
// remove empty leaf
deleteNode
(
signal
,
frag
,
nodePtr
);
deleteNode
(
signal
,
node
);
if
(
parent
Addr
==
NullTupAddr
)
{
if
(
parent
Loc
==
NullTupLoc
)
{
jam
();
jam
();
// tree is now empty
// tree is now empty
tree
.
m_root
=
NullTup
Addr
;
tree
.
m_root
=
NullTup
Loc
;
return
;
return
;
}
}
node
Ptr
=
parentPtr
;
node
=
parentNode
;
node
Ptr
.
p
->
setLink
(
i
,
NullTupAddr
);
node
.
setLink
(
i
,
NullTupLoc
);
#ifdef dbtux_min_occup_less_max_occup
#ifdef dbtux_min_occup_less_max_occup
// check if we created a half-leaf
// check if we created a half-leaf
if
(
node
Ptr
.
p
->
getBalance
()
==
0
)
{
if
(
node
.
getBalance
()
==
0
)
{
jam
();
jam
();
// move entries from the other child
// move entries from the other child
Tup
Addr
childAddr
=
nodePtr
.
p
->
getLink
(
1
-
i
);
Tup
Loc
childLoc
=
node
.
getLink
(
1
-
i
);
NodeHandle
Ptr
childPtr
;
NodeHandle
childNode
(
frag
)
;
selectNode
(
signal
,
frag
,
childPtr
,
childAddr
,
AccFull
);
selectNode
(
signal
,
childNode
,
childLoc
,
AccFull
);
node
Ptr
.
p
->
slide
(
signal
,
childPtr
,
1
-
i
);
node
Slide
(
signal
,
node
,
childNode
,
1
-
i
);
if
(
child
Ptr
.
p
->
getOccup
()
==
0
)
{
if
(
child
Node
.
getOccup
()
==
0
)
{
jam
();
jam
();
deleteNode
(
signal
,
frag
,
childPtr
);
deleteNode
(
signal
,
childNode
);
node
Ptr
.
p
->
setLink
(
1
-
i
,
NullTupAddr
);
node
.
setLink
(
1
-
i
,
NullTupLoc
);
// we are balanced again but our parent balance changes by -1
// we are balanced again but our parent balance changes by -1
parent
Addr
=
nodePtr
.
p
->
getLink
(
2
);
parent
Loc
=
node
.
getLink
(
2
);
if
(
parent
Addr
==
NullTupAddr
)
{
if
(
parent
Loc
==
NullTupLoc
)
{
jam
();
jam
();
return
;
return
;
}
}
// fix side and become parent
// fix side and become parent
i
=
node
Ptr
.
p
->
getSide
();
i
=
node
.
getSide
();
selectNode
(
signal
,
frag
,
nodePtr
,
parentAddr
,
AccHead
);
selectNode
(
signal
,
node
,
parentLoc
,
AccHead
);
}
}
}
}
#endif
#endif
...
@@ -375,50 +374,50 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
...
@@ -375,50 +374,50 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
while
(
true
)
{
while
(
true
)
{
// height of subtree i has decreased by 1
// height of subtree i has decreased by 1
int
j
=
(
i
==
0
?
-
1
:
+
1
);
int
j
=
(
i
==
0
?
-
1
:
+
1
);
int
b
=
node
Ptr
.
p
->
getBalance
();
int
b
=
node
.
getBalance
();
if
(
b
==
0
)
{
if
(
b
==
0
)
{
// perfectly balanced
// perfectly balanced
jam
();
jam
();
node
Ptr
.
p
->
setBalance
(
-
j
);
node
.
setBalance
(
-
j
);
// height of tree did not change - done
// height of tree did not change - done
return
;
return
;
}
else
if
(
b
==
j
)
{
}
else
if
(
b
==
j
)
{
// height of longer subtree has decreased
// height of longer subtree has decreased
jam
();
jam
();
node
Ptr
.
p
->
setBalance
(
0
);
node
.
setBalance
(
0
);
// height change propagates up
// height change propagates up
}
else
if
(
b
==
-
j
)
{
}
else
if
(
b
==
-
j
)
{
// height of shorter subtree has decreased
// height of shorter subtree has decreased
jam
();
jam
();
NodeHandlePtr
childPtr
;
// child on the other side
// child on the other side
selectNode
(
signal
,
frag
,
childPtr
,
nodePtr
.
p
->
getLink
(
1
-
i
),
AccHead
);
NodeHandle
childNode
(
frag
);
int
b2
=
childPtr
.
p
->
getBalance
();
selectNode
(
signal
,
childNode
,
node
.
getLink
(
1
-
i
),
AccHead
);
int
b2
=
childNode
.
getBalance
();
if
(
b2
==
b
)
{
if
(
b2
==
b
)
{
jam
();
jam
();
treeRotateSingle
(
signal
,
frag
,
node
Ptr
,
1
-
i
);
treeRotateSingle
(
signal
,
frag
,
node
,
1
-
i
);
// height of tree decreased and propagates up
// height of tree decreased and propagates up
}
else
if
(
b2
==
-
b
)
{
}
else
if
(
b2
==
-
b
)
{
jam
();
jam
();
treeRotateDouble
(
signal
,
frag
,
node
Ptr
,
1
-
i
);
treeRotateDouble
(
signal
,
frag
,
node
,
1
-
i
);
// height of tree decreased and propagates up
// height of tree decreased and propagates up
}
else
{
}
else
{
jam
();
jam
();
treeRotateSingle
(
signal
,
frag
,
node
Ptr
,
1
-
i
);
treeRotateSingle
(
signal
,
frag
,
node
,
1
-
i
);
// height of tree did not change - done
// height of tree did not change - done
return
;
return
;
}
}
}
else
{
}
else
{
ndbrequire
(
false
);
ndbrequire
(
false
);
}
}
Tup
Addr
parentAddr
=
nodePtr
.
p
->
getLink
(
2
);
Tup
Loc
parentLoc
=
node
.
getLink
(
2
);
if
(
parent
Addr
==
NullTupAddr
)
{
if
(
parent
Loc
==
NullTupLoc
)
{
jam
();
jam
();
// root node - done
// root node - done
return
;
return
;
}
}
i
=
node
Ptr
.
p
->
getSide
();
i
=
node
.
getSide
();
selectNode
(
signal
,
frag
,
nodePtr
,
parentAddr
,
AccHead
);
selectNode
(
signal
,
node
,
parentLoc
,
AccHead
);
}
}
}
}
...
@@ -441,55 +440,55 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
...
@@ -441,55 +440,55 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
void
void
Dbtux
::
treeRotateSingle
(
Signal
*
signal
,
Dbtux
::
treeRotateSingle
(
Signal
*
signal
,
Frag
&
frag
,
Frag
&
frag
,
NodeHandle
Ptr
&
nodePtr
,
NodeHandle
&
node
,
unsigned
i
)
unsigned
i
)
{
{
ndbrequire
(
i
<=
1
);
ndbrequire
(
i
<=
1
);
/*
/*
5 is the old top node that have been unbalanced due to an insert or
5 is the old top node that have been unbalanced due to an insert or
delete. The balance is still the old balance before the update.
delete. The balance is still the old balance before the update.
Verify that
n5Bal
is 1 if RR rotate and -1 if LL rotate.
Verify that
bal5
is 1 if RR rotate and -1 if LL rotate.
*/
*/
NodeHandle
Ptr
n5Ptr
=
nodePtr
;
NodeHandle
node5
=
node
;
const
Tup
Addr
n5Addr
=
n5Ptr
.
p
->
m_addr
;
const
Tup
Loc
loc5
=
node5
.
m_loc
;
const
int
n5Bal
=
n5Ptr
.
p
->
getBalance
();
const
int
bal5
=
node5
.
getBalance
();
const
int
n5side
=
n5Ptr
.
p
->
getSide
();
const
int
side5
=
node5
.
getSide
();
ndbrequire
(
n5Bal
+
(
1
-
i
)
==
i
);
ndbrequire
(
bal5
+
(
1
-
i
)
==
i
);
/*
/*
3 is the new root of this part of the tree which is to swap place with
3 is the new root of this part of the tree which is to swap place with
node 5. For an insert to cause this it must have the same balance as 5.
node 5. For an insert to cause this it must have the same balance as 5.
For deletes it can have the balance 0.
For deletes it can have the balance 0.
*/
*/
Tup
Addr
n3Addr
=
n5Ptr
.
p
->
getLink
(
i
);
Tup
Loc
loc3
=
node5
.
getLink
(
i
);
NodeHandle
Ptr
n3Ptr
;
NodeHandle
node3
(
frag
)
;
selectNode
(
signal
,
frag
,
n3Ptr
,
n3Addr
,
AccHead
);
selectNode
(
signal
,
node3
,
loc3
,
AccHead
);
const
int
n3Bal
=
n3Ptr
.
p
->
getBalance
();
const
int
bal3
=
node3
.
getBalance
();
/*
/*
2 must always be there but is not changed. Thus we mereley check that it
2 must always be there but is not changed. Thus we mereley check that it
exists.
exists.
*/
*/
ndbrequire
(
n
3Ptr
.
p
->
getLink
(
i
)
!=
NullTupAddr
);
ndbrequire
(
n
ode3
.
getLink
(
i
)
!=
NullTupLoc
);
/*
/*
4 is not necessarily there but if it is there it will move from one
4 is not necessarily there but if it is there it will move from one
side of 3 to the other side of 5. For LL it moves from the right side
side of 3 to the other side of 5. For LL it moves from the right side
to the left side and for RR it moves from the left side to the right
to the left side and for RR it moves from the left side to the right
side. This means that it also changes parent from 3 to 5.
side. This means that it also changes parent from 3 to 5.
*/
*/
Tup
Addr
n4Addr
=
n3Ptr
.
p
->
getLink
(
1
-
i
);
Tup
Loc
loc4
=
node3
.
getLink
(
1
-
i
);
NodeHandle
Ptr
n4Ptr
;
NodeHandle
node4
(
frag
)
;
if
(
n4Addr
!=
NullTupAddr
)
{
if
(
loc4
!=
NullTupLoc
)
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
n4Ptr
,
n4Addr
,
AccHead
);
selectNode
(
signal
,
node4
,
loc4
,
AccHead
);
ndbrequire
(
n
4Ptr
.
p
->
getSide
()
==
(
1
-
i
)
&&
ndbrequire
(
n
ode4
.
getSide
()
==
(
1
-
i
)
&&
n
4Ptr
.
p
->
getLink
(
2
)
==
n3Addr
);
n
ode4
.
getLink
(
2
)
==
loc3
);
n
4Ptr
.
p
->
setSide
(
i
);
n
ode4
.
setSide
(
i
);
n
4Ptr
.
p
->
setLink
(
2
,
n5Addr
);
n
ode4
.
setLink
(
2
,
loc5
);
}
//if
}
//if
/*
/*
Retrieve the address of 5's parent before it is destroyed
Retrieve the address of 5's parent before it is destroyed
*/
*/
Tup
Addr
n0Addr
=
n5Ptr
.
p
->
getLink
(
2
);
Tup
Loc
loc0
=
node5
.
getLink
(
2
);
/*
/*
The next step is to perform the rotation. 3 will inherit 5's parent
The next step is to perform the rotation. 3 will inherit 5's parent
...
@@ -503,22 +502,22 @@ Dbtux::treeRotateSingle(Signal* signal,
...
@@ -503,22 +502,22 @@ Dbtux::treeRotateSingle(Signal* signal,
1. 3 must have had 5 as parent before the change.
1. 3 must have had 5 as parent before the change.
2. 3's side is left for LL and right for RR before change.
2. 3's side is left for LL and right for RR before change.
*/
*/
ndbrequire
(
n
3Ptr
.
p
->
getLink
(
2
)
==
n5Addr
);
ndbrequire
(
n
ode3
.
getLink
(
2
)
==
loc5
);
ndbrequire
(
n
3Ptr
.
p
->
getSide
()
==
i
);
ndbrequire
(
n
ode3
.
getSide
()
==
i
);
n
3Ptr
.
p
->
setLink
(
1
-
i
,
n5Addr
);
n
ode3
.
setLink
(
1
-
i
,
loc5
);
n
3Ptr
.
p
->
setLink
(
2
,
n0Addr
);
n
ode3
.
setLink
(
2
,
loc0
);
n
3Ptr
.
p
->
setSide
(
n5side
);
n
ode3
.
setSide
(
side5
);
n
5Ptr
.
p
->
setLink
(
i
,
n4Addr
);
n
ode5
.
setLink
(
i
,
loc4
);
n
5Ptr
.
p
->
setLink
(
2
,
n3Addr
);
n
ode5
.
setLink
(
2
,
loc3
);
n
5Ptr
.
p
->
setSide
(
1
-
i
);
n
ode5
.
setSide
(
1
-
i
);
if
(
n0Addr
!=
NullTupAddr
)
{
if
(
loc0
!=
NullTupLoc
)
{
jam
();
jam
();
NodeHandle
Ptr
n0Ptr
;
NodeHandle
node0
(
frag
)
;
selectNode
(
signal
,
frag
,
n0Ptr
,
n0Addr
,
AccHead
);
selectNode
(
signal
,
node0
,
loc0
,
AccHead
);
n
0Ptr
.
p
->
setLink
(
n5side
,
n3Addr
);
n
ode0
.
setLink
(
side5
,
loc3
);
}
else
{
}
else
{
jam
();
jam
();
frag
.
m_tree
.
m_root
=
n3Addr
;
frag
.
m_tree
.
m_root
=
loc3
;
}
//if
}
//if
/* The final step of the change is to update the balance of 3 and
/* The final step of the change is to update the balance of 3 and
5 that changed places. There are two cases here. The first case is
5 that changed places. There are two cases here. The first case is
...
@@ -531,22 +530,22 @@ Dbtux::treeRotateSingle(Signal* signal,
...
@@ -531,22 +530,22 @@ Dbtux::treeRotateSingle(Signal* signal,
In this case 5 will change balance but still be unbalanced and 3 will
In this case 5 will change balance but still be unbalanced and 3 will
be unbalanced in the opposite direction of 5.
be unbalanced in the opposite direction of 5.
*/
*/
if
(
n3Bal
==
n5Bal
)
{
if
(
bal3
==
bal5
)
{
jam
();
jam
();
n
3Ptr
.
p
->
setBalance
(
0
);
n
ode3
.
setBalance
(
0
);
n
5Ptr
.
p
->
setBalance
(
0
);
n
ode5
.
setBalance
(
0
);
}
else
if
(
n3Bal
==
0
)
{
}
else
if
(
bal3
==
0
)
{
jam
();
jam
();
n
3Ptr
.
p
->
setBalance
(
-
n5Bal
);
n
ode3
.
setBalance
(
-
bal5
);
n
5Ptr
.
p
->
setBalance
(
n5Bal
);
n
ode5
.
setBalance
(
bal5
);
}
else
{
}
else
{
ndbrequire
(
false
);
ndbrequire
(
false
);
}
//if
}
//if
/*
/*
Set node
Ptr
to 3 as return parameter for enabling caller to continue
Set node to 3 as return parameter for enabling caller to continue
traversing the tree.
traversing the tree.
*/
*/
node
Ptr
=
n3Ptr
;
node
=
node3
;
}
}
/*
/*
...
@@ -651,105 +650,105 @@ Dbtux::treeRotateSingle(Signal* signal,
...
@@ -651,105 +650,105 @@ Dbtux::treeRotateSingle(Signal* signal,
*
*
*/
*/
void
void
Dbtux
::
treeRotateDouble
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandle
Ptr
&
nodePtr
,
unsigned
i
)
Dbtux
::
treeRotateDouble
(
Signal
*
signal
,
Frag
&
frag
,
NodeHandle
&
node
,
unsigned
i
)
{
{
// old top node
// old top node
NodeHandle
Ptr
n6Ptr
=
nodePtr
;
NodeHandle
node6
=
node
;
const
Tup
Addr
n6Addr
=
n6Ptr
.
p
->
m_addr
;
const
Tup
Loc
loc6
=
node6
.
m_loc
;
// the un-updated balance
// the un-updated balance
const
int
n6Bal
=
n6Ptr
.
p
->
getBalance
();
const
int
bal6
=
node6
.
getBalance
();
const
unsigned
n6Side
=
n6Ptr
.
p
->
getSide
();
const
unsigned
side6
=
node6
.
getSide
();
// level 1
// level 1
Tup
Addr
n2Addr
=
n6Ptr
.
p
->
getLink
(
i
);
Tup
Loc
loc2
=
node6
.
getLink
(
i
);
NodeHandle
Ptr
n2Ptr
;
NodeHandle
node2
(
frag
)
;
selectNode
(
signal
,
frag
,
n2Ptr
,
n2Addr
,
AccHead
);
selectNode
(
signal
,
node2
,
loc2
,
AccHead
);
const
int
n2Bal
=
n2Ptr
.
p
->
getBalance
();
const
int
bal2
=
node2
.
getBalance
();
// level 2
// level 2
Tup
Addr
n4Addr
=
n2Ptr
.
p
->
getLink
(
1
-
i
);
Tup
Loc
loc4
=
node2
.
getLink
(
1
-
i
);
NodeHandle
Ptr
n4Ptr
;
NodeHandle
node4
(
frag
)
;
selectNode
(
signal
,
frag
,
n4Ptr
,
n4Addr
,
AccHead
);
selectNode
(
signal
,
node4
,
loc4
,
AccHead
);
const
int
n4Bal
=
n4Ptr
.
p
->
getBalance
();
const
int
bal4
=
node4
.
getBalance
();
ndbrequire
(
i
<=
1
);
ndbrequire
(
i
<=
1
);
ndbrequire
(
n6Bal
+
(
1
-
i
)
==
i
);
ndbrequire
(
bal6
+
(
1
-
i
)
==
i
);
ndbrequire
(
n2Bal
==
-
n6Bal
);
ndbrequire
(
bal2
==
-
bal6
);
ndbrequire
(
n
2Ptr
.
p
->
getLink
(
2
)
==
n6Addr
);
ndbrequire
(
n
ode2
.
getLink
(
2
)
==
loc6
);
ndbrequire
(
n
2Ptr
.
p
->
getSide
()
==
i
);
ndbrequire
(
n
ode2
.
getSide
()
==
i
);
ndbrequire
(
n
4Ptr
.
p
->
getLink
(
2
)
==
n2Addr
);
ndbrequire
(
n
ode4
.
getLink
(
2
)
==
loc2
);
// level 3
// level 3
Tup
Addr
n3Addr
=
n4Ptr
.
p
->
getLink
(
i
);
Tup
Loc
loc3
=
node4
.
getLink
(
i
);
Tup
Addr
n5Addr
=
n4Ptr
.
p
->
getLink
(
1
-
i
);
Tup
Loc
loc5
=
node4
.
getLink
(
1
-
i
);
// fill up leaf before it becomes internal
// fill up leaf before it becomes internal
if
(
n3Addr
==
NullTupAddr
&&
n5Addr
==
NullTupAddr
)
{
if
(
loc3
==
NullTupLoc
&&
loc5
==
NullTupLoc
)
{
jam
();
jam
();
TreeHead
&
tree
=
frag
.
m_tree
;
TreeHead
&
tree
=
frag
.
m_tree
;
accessNode
(
signal
,
frag
,
n2Ptr
,
AccFull
);
accessNode
(
signal
,
node2
,
AccFull
);
accessNode
(
signal
,
frag
,
n4Ptr
,
AccFull
);
accessNode
(
signal
,
node4
,
AccFull
);
n
4Ptr
.
p
->
slide
(
signal
,
n2Ptr
,
i
);
n
odeSlide
(
signal
,
node4
,
node2
,
i
);
// implied by rule of merging half-leaves with leaves
// implied by rule of merging half-leaves with leaves
ndbrequire
(
n
4Ptr
.
p
->
getOccup
()
>=
tree
.
m_minOccup
);
ndbrequire
(
n
ode4
.
getOccup
()
>=
tree
.
m_minOccup
);
ndbrequire
(
n
2Ptr
.
p
->
getOccup
()
!=
0
);
ndbrequire
(
n
ode2
.
getOccup
()
!=
0
);
}
else
{
}
else
{
if
(
n3Addr
!=
NullTupAddr
)
{
if
(
loc3
!=
NullTupLoc
)
{
jam
();
jam
();
NodeHandle
Ptr
n3Ptr
;
NodeHandle
node3
(
frag
)
;
selectNode
(
signal
,
frag
,
n3Ptr
,
n3Addr
,
AccHead
);
selectNode
(
signal
,
node3
,
loc3
,
AccHead
);
n
3Ptr
.
p
->
setLink
(
2
,
n2Addr
);
n
ode3
.
setLink
(
2
,
loc2
);
n
3Ptr
.
p
->
setSide
(
1
-
i
);
n
ode3
.
setSide
(
1
-
i
);
}
}
if
(
n5Addr
!=
NullTupAddr
)
{
if
(
loc5
!=
NullTupLoc
)
{
jam
();
jam
();
NodeHandle
Ptr
n5Ptr
;
NodeHandle
node5
(
frag
)
;
selectNode
(
signal
,
frag
,
n5Ptr
,
n5Addr
,
AccHead
);
selectNode
(
signal
,
node5
,
loc5
,
AccHead
);
n
5Ptr
.
p
->
setLink
(
2
,
n6Ptr
.
p
->
m_addr
);
n
ode5
.
setLink
(
2
,
node6
.
m_loc
);
n
5Ptr
.
p
->
setSide
(
i
);
n
ode5
.
setSide
(
i
);
}
}
}
}
// parent
// parent
Tup
Addr
n0Addr
=
n6Ptr
.
p
->
getLink
(
2
);
Tup
Loc
loc0
=
node6
.
getLink
(
2
);
NodeHandle
Ptr
n0Ptr
;
NodeHandle
node0
(
frag
)
;
// perform the rotation
// perform the rotation
n
6Ptr
.
p
->
setLink
(
i
,
n5Addr
);
n
ode6
.
setLink
(
i
,
loc5
);
n
6Ptr
.
p
->
setLink
(
2
,
n4Addr
);
n
ode6
.
setLink
(
2
,
loc4
);
n
6Ptr
.
p
->
setSide
(
1
-
i
);
n
ode6
.
setSide
(
1
-
i
);
n
2Ptr
.
p
->
setLink
(
1
-
i
,
n3Addr
);
n
ode2
.
setLink
(
1
-
i
,
loc3
);
n
2Ptr
.
p
->
setLink
(
2
,
n4Addr
);
n
ode2
.
setLink
(
2
,
loc4
);
n
4Ptr
.
p
->
setLink
(
i
,
n2Addr
);
n
ode4
.
setLink
(
i
,
loc2
);
n
4Ptr
.
p
->
setLink
(
1
-
i
,
n6Addr
);
n
ode4
.
setLink
(
1
-
i
,
loc6
);
n
4Ptr
.
p
->
setLink
(
2
,
n0Addr
);
n
ode4
.
setLink
(
2
,
loc0
);
n
4Ptr
.
p
->
setSide
(
n6Side
);
n
ode4
.
setSide
(
side6
);
if
(
n0Addr
!=
NullTupAddr
)
{
if
(
loc0
!=
NullTupLoc
)
{
jam
();
jam
();
selectNode
(
signal
,
frag
,
n0Ptr
,
n0Addr
,
AccHead
);
selectNode
(
signal
,
node0
,
loc0
,
AccHead
);
n
0Ptr
.
p
->
setLink
(
n6Side
,
n4Addr
);
n
ode0
.
setLink
(
side6
,
loc4
);
}
else
{
}
else
{
jam
();
jam
();
frag
.
m_tree
.
m_root
=
n4Addr
;
frag
.
m_tree
.
m_root
=
loc4
;
}
}
// set balance of changed nodes
// set balance of changed nodes
n
4Ptr
.
p
->
setBalance
(
0
);
n
ode4
.
setBalance
(
0
);
if
(
n4Bal
==
0
)
{
if
(
bal4
==
0
)
{
jam
();
jam
();
n
2Ptr
.
p
->
setBalance
(
0
);
n
ode2
.
setBalance
(
0
);
n
6Ptr
.
p
->
setBalance
(
0
);
n
ode6
.
setBalance
(
0
);
}
else
if
(
n4Bal
==
-
n2Bal
)
{
}
else
if
(
bal4
==
-
bal2
)
{
jam
();
jam
();
n
2Ptr
.
p
->
setBalance
(
0
);
n
ode2
.
setBalance
(
0
);
n
6Ptr
.
p
->
setBalance
(
n2Bal
);
n
ode6
.
setBalance
(
bal2
);
}
else
if
(
n4Bal
==
n2Bal
)
{
}
else
if
(
bal4
==
bal2
)
{
jam
();
jam
();
n
2Ptr
.
p
->
setBalance
(
-
n2Bal
);
n
ode2
.
setBalance
(
-
bal2
);
n
6Ptr
.
p
->
setBalance
(
0
);
n
ode6
.
setBalance
(
0
);
}
else
{
}
else
{
ndbrequire
(
false
);
ndbrequire
(
false
);
}
}
// new top node
// new top node
node
Ptr
=
n4Ptr
;
node
=
node4
;
}
}
ndb/src/kernel/blocks/dbtux/Makefile.am
View file @
d3b0753d
...
@@ -10,6 +10,8 @@ libdbtux_a_SOURCES = \
...
@@ -10,6 +10,8 @@ libdbtux_a_SOURCES = \
DbtuxCmp.cpp
\
DbtuxCmp.cpp
\
DbtuxDebug.cpp
DbtuxDebug.cpp
INCLUDES_LOC
=
-I
$(top_srcdir)
/ndb/src/kernel/blocks/dbtup
include
$(top_srcdir)/ndb/config/common.mk.am
include
$(top_srcdir)/ndb/config/common.mk.am
include
$(top_srcdir)/ndb/config/type_kernel.mk.am
include
$(top_srcdir)/ndb/config/type_kernel.mk.am
...
...
ndb/src/kernel/blocks/dbtux/Times.txt
0 → 100644
View file @
d3b0753d
index maintenance overhead
==========================
"mc02" 2x1700 MHz linux-2.4.9 gcc-2.96 -O3 one db-node
case a: index on Unsigned
testOIBasic -case u -table 1 -index 1 -fragtype small -threads 10 -rows 100000 -subloop 1 -nologging
case b: index on Varchar(5) + Varchar(5) + Varchar(20) + Unsigned
testOIBasic -case u -table 2 -index 4 -fragtype small -threads 10 -rows 100000 -subloop 1 -nologging
1 million rows, pk update without index, pk update with index
shows ms / 1000 rows for each and pct overhead
the figures are based on single run on idle machine
040616 mc02/a 40 ms 87 ms 114 pct
mc02/b 51 ms 128 ms 148 pct
optim 1 mc02/a 38 ms 85 ms 124 pct
mc02/b 51 ms 123 ms 140 pct
optim 2 mc02/a 41 ms 80 ms 96 pct
mc02/b 51 ms 117 ms 128 pct
optim 3 mc02/a 43 ms 80 ms 85 pct
mc02/b 54 ms 118 ms 117 pct
optim 4 mc02/a 42 ms 80 ms 87 pct
mc02/b 51 ms 119 ms 129 pct
optim 5 mc02/a 43 ms 77 ms 77 pct
mc02/b 54 ms 118 ms 117 pct
optim 6 mc02/a 42 ms 70 ms 66 pct
mc02/b 53 ms 109 ms 105 pct
vim: set et:
ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
View file @
d3b0753d
...
@@ -525,7 +525,7 @@ void Qmgr::execCM_REGREQ(Signal* signal)
...
@@ -525,7 +525,7 @@ void Qmgr::execCM_REGREQ(Signal* signal)
cmRegConf
->
dynamicId
=
TdynId
;
cmRegConf
->
dynamicId
=
TdynId
;
c_clusterNodes
.
copyto
(
NdbNodeBitmask
::
Size
,
cmRegConf
->
allNdbNodes
);
c_clusterNodes
.
copyto
(
NdbNodeBitmask
::
Size
,
cmRegConf
->
allNdbNodes
);
sendSignal
(
Tblockref
,
GSN_CM_REGCONF
,
signal
,
sendSignal
(
Tblockref
,
GSN_CM_REGCONF
,
signal
,
CmRegConf
::
SignalLength
,
JB
B
);
CmRegConf
::
SignalLength
,
JB
A
);
DEBUG_START
(
GSN_CM_REGCONF
,
refToNode
(
Tblockref
),
""
);
DEBUG_START
(
GSN_CM_REGCONF
,
refToNode
(
Tblockref
),
""
);
/**
/**
...
@@ -847,7 +847,7 @@ void Qmgr::execCM_NODEINFOCONF(Signal* signal)
...
@@ -847,7 +847,7 @@ void Qmgr::execCM_NODEINFOCONF(Signal* signal)
nodePtr
.
i
=
getOwnNodeId
();
nodePtr
.
i
=
getOwnNodeId
();
ptrAss
(
nodePtr
,
nodeRec
);
ptrAss
(
nodePtr
,
nodeRec
);
ndbrequire
(
nodePtr
.
p
->
phase
==
ZSTARTING
);
ndbrequire
(
nodePtr
.
p
->
phase
==
ZSTARTING
);
ndbrequire
(
c_start
.
m_gsn
=
GSN_CM_NODEINFOREQ
);
ndbrequire
(
c_start
.
m_gsn
=
=
GSN_CM_NODEINFOREQ
);
c_start
.
m_nodes
.
clearWaitingFor
(
nodeId
);
c_start
.
m_nodes
.
clearWaitingFor
(
nodeId
);
/**
/**
...
@@ -1019,7 +1019,7 @@ void Qmgr::execCM_ADD(Signal* signal)
...
@@ -1019,7 +1019,7 @@ void Qmgr::execCM_ADD(Signal* signal)
ndbrequire
(
addNodePtr
.
i
==
nodePtr
.
i
);
ndbrequire
(
addNodePtr
.
i
==
nodePtr
.
i
);
switch
(
type
){
switch
(
type
){
case
CmAdd
:
:
Prepare
:
case
CmAdd
:
:
Prepare
:
ndbrequire
(
c_start
.
m_gsn
=
GSN_CM_NODEINFOREQ
);
ndbrequire
(
c_start
.
m_gsn
=
=
GSN_CM_NODEINFOREQ
);
/**
/**
* Wait for CM_NODEINFO_CONF
* Wait for CM_NODEINFO_CONF
*/
*/
...
...
ndb/test/ndbapi/testOIBasic.cpp
View file @
d3b0753d
...
@@ -39,6 +39,7 @@ struct Opt {
...
@@ -39,6 +39,7 @@ struct Opt {
NdbDictionary
::
Object
::
FragmentType
m_fragtype
;
NdbDictionary
::
Object
::
FragmentType
m_fragtype
;
const
char
*
m_index
;
const
char
*
m_index
;
unsigned
m_loop
;
unsigned
m_loop
;
bool
m_nologging
;
unsigned
m_rows
;
unsigned
m_rows
;
unsigned
m_scanrd
;
unsigned
m_scanrd
;
unsigned
m_scanex
;
unsigned
m_scanex
;
...
@@ -54,6 +55,7 @@ struct Opt {
...
@@ -54,6 +55,7 @@ struct Opt {
m_fragtype
(
NdbDictionary
::
Object
::
FragUndefined
),
m_fragtype
(
NdbDictionary
::
Object
::
FragUndefined
),
m_index
(
0
),
m_index
(
0
),
m_loop
(
1
),
m_loop
(
1
),
m_nologging
(
false
),
m_rows
(
1000
),
m_rows
(
1000
),
m_scanrd
(
240
),
m_scanrd
(
240
),
m_scanex
(
240
),
m_scanex
(
240
),
...
@@ -82,6 +84,7 @@ printhelp()
...
@@ -82,6 +84,7 @@ printhelp()
<<
" -fragtype T fragment type single/small/medium/large"
<<
endl
<<
" -fragtype T fragment type single/small/medium/large"
<<
endl
<<
" -index xyz only given index numbers (digits 1-9)"
<<
endl
<<
" -index xyz only given index numbers (digits 1-9)"
<<
endl
<<
" -loop N loop count full suite forever=0 ["
<<
d
.
m_loop
<<
"]"
<<
endl
<<
" -loop N loop count full suite forever=0 ["
<<
d
.
m_loop
<<
"]"
<<
endl
<<
" -nologging create tables in no-logging mode"
<<
endl
<<
" -rows N rows per thread ["
<<
d
.
m_rows
<<
"]"
<<
endl
<<
" -rows N rows per thread ["
<<
d
.
m_rows
<<
"]"
<<
endl
<<
" -scanrd N scan read parallelism ["
<<
d
.
m_scanrd
<<
"]"
<<
endl
<<
" -scanrd N scan read parallelism ["
<<
d
.
m_scanrd
<<
"]"
<<
endl
<<
" -scanex N scan exclusive parallelism ["
<<
d
.
m_scanex
<<
"]"
<<
endl
<<
" -scanex N scan exclusive parallelism ["
<<
d
.
m_scanex
<<
"]"
<<
endl
...
@@ -476,7 +479,7 @@ tt1 = {
...
@@ -476,7 +479,7 @@ tt1 = {
"TT1"
,
5
,
tt1col
,
4
,
tt1itab
"TT1"
,
5
,
tt1col
,
4
,
tt1itab
};
};
// tt2 + tt2x1 tt2x2 tt2x3
// tt2 + tt2x1 tt2x2 tt2x3
tt2x4
static
const
Col
static
const
Col
tt2col
[]
=
{
tt2col
[]
=
{
...
@@ -505,6 +508,14 @@ tt2x3col[] = {
...
@@ -505,6 +508,14 @@ tt2x3col[] = {
{
1
,
tt2col
[
4
]
}
{
1
,
tt2col
[
4
]
}
};
};
static
const
ICol
tt2x4col
[]
=
{
{
0
,
tt2col
[
4
]
},
{
1
,
tt2col
[
3
]
},
{
2
,
tt2col
[
2
]
},
{
3
,
tt2col
[
1
]
}
};
static
const
ITab
static
const
ITab
tt2x1
=
{
tt2x1
=
{
"TT2X1"
,
2
,
tt2x1col
"TT2X1"
,
2
,
tt2x1col
...
@@ -520,16 +531,22 @@ tt2x3 = {
...
@@ -520,16 +531,22 @@ tt2x3 = {
"TT2X3"
,
2
,
tt2x3col
"TT2X3"
,
2
,
tt2x3col
};
};
static
const
ITab
tt2x4
=
{
"TT2X4"
,
4
,
tt2x4col
};
static
const
ITab
static
const
ITab
tt2itab
[]
=
{
tt2itab
[]
=
{
tt2x1
,
tt2x1
,
tt2x2
,
tt2x2
,
tt2x3
tt2x3
,
tt2x4
};
};
static
const
Tab
static
const
Tab
tt2
=
{
tt2
=
{
"TT2"
,
5
,
tt2col
,
3
,
tt2itab
"TT2"
,
5
,
tt2col
,
4
,
tt2itab
};
};
// all tables
// all tables
...
@@ -823,6 +840,9 @@ createtable(Par par)
...
@@ -823,6 +840,9 @@ createtable(Par par)
if
(
par
.
m_fragtype
!=
NdbDictionary
::
Object
::
FragUndefined
)
{
if
(
par
.
m_fragtype
!=
NdbDictionary
::
Object
::
FragUndefined
)
{
t
.
setFragmentType
(
par
.
m_fragtype
);
t
.
setFragmentType
(
par
.
m_fragtype
);
}
}
if
(
par
.
m_nologging
)
{
t
.
setLogging
(
false
);
}
for
(
unsigned
k
=
0
;
k
<
tab
.
m_cols
;
k
++
)
{
for
(
unsigned
k
=
0
;
k
<
tab
.
m_cols
;
k
++
)
{
const
Col
&
col
=
tab
.
m_col
[
k
];
const
Col
&
col
=
tab
.
m_col
[
k
];
NdbDictionary
::
Column
c
(
col
.
m_name
);
NdbDictionary
::
Column
c
(
col
.
m_name
);
...
@@ -2202,7 +2222,6 @@ pkupdateindexbuild(Par par)
...
@@ -2202,7 +2222,6 @@ pkupdateindexbuild(Par par)
{
{
if
(
par
.
m_no
==
0
)
{
if
(
par
.
m_no
==
0
)
{
CHK
(
createindex
(
par
)
==
0
);
CHK
(
createindex
(
par
)
==
0
);
CHK
(
invalidateindex
(
par
)
==
0
);
}
else
{
}
else
{
CHK
(
pkupdate
(
par
)
==
0
);
CHK
(
pkupdate
(
par
)
==
0
);
}
}
...
@@ -2493,6 +2512,7 @@ tbusybuild(Par par)
...
@@ -2493,6 +2512,7 @@ tbusybuild(Par par)
RUNSTEP
(
par
,
pkinsert
,
MT
);
RUNSTEP
(
par
,
pkinsert
,
MT
);
for
(
unsigned
i
=
0
;
i
<
par
.
m_subloop
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
par
.
m_subloop
;
i
++
)
{
RUNSTEP
(
par
,
pkupdateindexbuild
,
MT
);
RUNSTEP
(
par
,
pkupdateindexbuild
,
MT
);
RUNSTEP
(
par
,
invalidateindex
,
MT
);
RUNSTEP
(
par
,
readverify
,
MT
);
RUNSTEP
(
par
,
readverify
,
MT
);
RUNSTEP
(
par
,
dropindex
,
ST
);
RUNSTEP
(
par
,
dropindex
,
ST
);
}
}
...
@@ -2500,9 +2520,28 @@ tbusybuild(Par par)
...
@@ -2500,9 +2520,28 @@ tbusybuild(Par par)
}
}
static
int
static
int
ttiming
(
Par
par
)
ttimebuild
(
Par
par
)
{
Tmr
t1
;
RUNSTEP
(
par
,
droptable
,
ST
);
RUNSTEP
(
par
,
createtable
,
ST
);
RUNSTEP
(
par
,
invalidatetable
,
MT
);
for
(
unsigned
i
=
0
;
i
<
par
.
m_subloop
;
i
++
)
{
RUNSTEP
(
par
,
pkinsert
,
MT
);
t1
.
on
();
RUNSTEP
(
par
,
createindex
,
ST
);
t1
.
off
(
par
.
m_totrows
);
RUNSTEP
(
par
,
invalidateindex
,
MT
);
RUNSTEP
(
par
,
dropindex
,
ST
);
}
LL1
(
"build index - "
<<
t1
.
time
());
return
0
;
}
static
int
ttimemaint
(
Par
par
)
{
{
Tmr
t
0
,
t
1
,
t2
;
Tmr
t1
,
t2
;
RUNSTEP
(
par
,
droptable
,
ST
);
RUNSTEP
(
par
,
droptable
,
ST
);
RUNSTEP
(
par
,
createtable
,
ST
);
RUNSTEP
(
par
,
createtable
,
ST
);
RUNSTEP
(
par
,
invalidatetable
,
MT
);
RUNSTEP
(
par
,
invalidatetable
,
MT
);
...
@@ -2511,16 +2550,13 @@ ttiming(Par par)
...
@@ -2511,16 +2550,13 @@ ttiming(Par par)
t1
.
on
();
t1
.
on
();
RUNSTEP
(
par
,
pkupdate
,
MT
);
RUNSTEP
(
par
,
pkupdate
,
MT
);
t1
.
off
(
par
.
m_totrows
);
t1
.
off
(
par
.
m_totrows
);
t0
.
on
();
RUNSTEP
(
par
,
createindex
,
ST
);
RUNSTEP
(
par
,
createindex
,
ST
);
RUNSTEP
(
par
,
invalidateindex
,
MT
);
RUNSTEP
(
par
,
invalidateindex
,
MT
);
t0
.
off
(
par
.
m_totrows
);
t2
.
on
();
t2
.
on
();
RUNSTEP
(
par
,
pkupdate
,
MT
);
RUNSTEP
(
par
,
pkupdate
,
MT
);
t2
.
off
(
par
.
m_totrows
);
t2
.
off
(
par
.
m_totrows
);
RUNSTEP
(
par
,
dropindex
,
ST
);
RUNSTEP
(
par
,
dropindex
,
ST
);
}
}
LL1
(
"build index - "
<<
t0
.
time
());
LL1
(
"update - "
<<
t1
.
time
());
LL1
(
"update - "
<<
t1
.
time
());
LL1
(
"update indexed - "
<<
t2
.
time
());
LL1
(
"update indexed - "
<<
t2
.
time
());
LL1
(
"overhead - "
<<
t2
.
over
(
t1
));
LL1
(
"overhead - "
<<
t2
.
over
(
t1
));
...
@@ -2551,7 +2587,8 @@ tcaselist[] = {
...
@@ -2551,7 +2587,8 @@ tcaselist[] = {
TCase
(
"b"
,
tpkops
,
"pk operations and scan reads"
),
TCase
(
"b"
,
tpkops
,
"pk operations and scan reads"
),
TCase
(
"c"
,
tmixedops
,
"pk operations and scan operations"
),
TCase
(
"c"
,
tmixedops
,
"pk operations and scan operations"
),
TCase
(
"d"
,
tbusybuild
,
"pk operations and index build"
),
TCase
(
"d"
,
tbusybuild
,
"pk operations and index build"
),
TCase
(
"t"
,
ttiming
,
"time index build and maintenance"
),
TCase
(
"t"
,
ttimebuild
,
"time index build"
),
TCase
(
"u"
,
ttimemaint
,
"time index maintenance"
),
TCase
(
"z"
,
tdrop
,
"drop test tables"
)
TCase
(
"z"
,
tdrop
,
"drop test tables"
)
};
};
...
@@ -2689,6 +2726,10 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
...
@@ -2689,6 +2726,10 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
continue
;
continue
;
}
}
}
}
if
(
strcmp
(
arg
,
"-nologging"
)
==
0
)
{
g_opt
.
m_nologging
=
true
;
continue
;
}
if
(
strcmp
(
arg
,
"-rows"
)
==
0
)
{
if
(
strcmp
(
arg
,
"-rows"
)
==
0
)
{
if
(
++
argv
,
--
argc
>
0
)
{
if
(
++
argv
,
--
argc
>
0
)
{
g_opt
.
m_rows
=
atoi
(
argv
[
0
]);
g_opt
.
m_rows
=
atoi
(
argv
[
0
]);
...
...
ndb/test/run-test/make-html-reports.sh
View file @
d3b0753d
#!/bin/sh
#!/bin/sh
# NAME
# make-html-reports.sh
#
# SYNOPSIS
# make-html-reports.sh [-q] [ -R <YYYY-MM-DD> ] [ -s <src dir> ] [ -d <dst dir> ] [ -c <conf dir> ]
#
# DESCRIPTION
#
# OPTIONS
#
# EXAMPLES
#
#
# ENVIRONMENT
# NDB_PROJ_HOME Home dir for ndb
#
# FILES
# $NDB_PROJ_HOME/lib/funcs.sh general shell script functions
#
#
# SEE ALSO
#
# DIAGNOSTICTS
#
# VERSION
# 1.0
#
# AUTHOR
# Jonas Oreland
#
progname
=
`
basename
$0
`
synopsis
=
"make-html-reports.sh [ -R <YYYY-MM-DD> ] [ -s <src dir> ] [ -d <dst dir> ] [ -c <conf dir> ]"
:
${
NDB_PROJ_HOME
:?
}
# If undefined, exit with error message
:
${
NDB_LOCAL_BUILD_OPTIONS
:
=--
}
# If undef, set to --. Keeps getopts happy.
# You may have to experiment a bit
# to get quoting right (if you need it).
.
$NDB_PROJ_HOME
/lib/funcs.sh
# Load some good stuff
# defaults for options related variables
#
src_dir
=
`
pwd
`
dst_dir
=
`
pwd
`
conf_dir
=
`
pwd
`
report_date
=
`
date
'+%Y-%m-%d'
`
uniq_id
=
$$
.
$$
verbose
=
yes
# used if error when parsing the options environment variable
#
env_opterr
=
"options environment variable: <<
$options
>>"
# Option parsing, for the options variable as well as the command line.
#
# We want to be able to set options in an environment variable,
# as well as on the command line. In order not to have to repeat
# the same getopts information twice, we loop two times over the
# getopts while loop. The first time, we process options from
# the options environment variable, the second time we process
# options from the command line.
#
# The things to change are the actual options and what they do.
#
#
for
optstring
in
"
$options
"
""
# 1. options variable 2. cmd line
do
while
getopts
q:s:R:d:c: i
$optstring
# optstring empty => no arg => cmd line
do
case
$i
in
q
)
verbose
=
""
;;
# echo important things
d
)
dst_dir
=
$OPTARG
;;
# Destination directory
s
)
src_dir
=
$OPTARG
;;
# Destination directory
c
)
conf_dir
=
$OPTARG
;;
#
R
)
report_date
=
$OPTARG
;;
#
\?
)
syndie
$env_opterr
;;
# print synopsis and exit
esac
done
[
-n
"
$optstring
"
]
&&
OPTIND
=
1
# Reset for round 2, cmdline options
env_opterr
=
# Round 2 should not use the value
src_dir
=
$1
run
=
$2
date
=
$3
src_file
=
$src_dir
/report.txt
done
if
[
!
-f
$src_dir
/report.txt
]
shift
`
expr
$OPTIND
- 1
`
then
echo
"
$src_dir
/report.txt is missing"
src_dir
=
`
abspath
$src_dir
`
exit
1
dst_dir
=
`
abspath
$dst_dir
`
fi
conf_dir
=
`
abspath
$conf_dir
`
###
###
#
#
# General html functions
# General html functions
trim
(){
echo
$*
}
header
(){
header
(){
cat
<<
EOF
cat
<<
EOF
<html><head><title>
$*
</title></head>
<html><head><title>
$*
</title></head>
...
@@ -166,64 +83,7 @@ hr(){
...
@@ -166,64 +83,7 @@ hr(){
EOF
EOF
}
}
# --- option parsing done ---
# -- Verify
# -- Verify
trace
"Verifying arguments"
summary_file
=
$src_dir
/reports/summary.
$report_date
if
[
!
-r
$summary_file
]
then
syndie
"Invalid src directory or report date:
$summary_file
not found"
fi
if
[
!
-d
$conf_dir
/configurations
]
then
syndie
"Invalid src directory:
$conf_dir
/configurations not found"
fi
if
[
!
-d
$conf_dir
/testcases
]
then
syndie
"Invalid src directory:
$conf_dir
/testcases not found"
fi
if
[
!
-d
$dst_dir
]
then
syndie
"Invalid dst dir..."
fi
# --- option verifying done ---
trace
"src_dir:
$src_dir
"
trace
"dst_dir:
$dst_dir
"
trace
"conf_dir:
$conf_dir
"
trace
"report date:
$report_date
"
###
config_spec
(){
cat
<<
EOF
<a href=#
$1
>
$1
</a>
EOF
}
config_spec_include
(){
# Print the $1 file to the file we are generating
cat
<<
EOF
<a name=
$1
><pre>
EOF
if
[
-r
$conf_dir
/configurations/
$1
]
then
cat
-E
$conf_dir
/configurations/
$1
|
sed
's/\$/<BR>/g'
else
cat
<<
EOF
Config spec
$1
not found
EOF
fi
cat
<<
EOF
</pre></a>
EOF
}
time_spec
(){
time_spec
(){
# $1 - secs
# $1 - secs
_ts_tmp
=
$1
_ts_tmp
=
$1
...
@@ -232,8 +92,14 @@ time_spec(){
...
@@ -232,8 +92,14 @@ time_spec(){
_ts_tmp
=
`
expr
$_ts_tmp
/ 60
`
_ts_tmp
=
`
expr
$_ts_tmp
/ 60
`
_ts_m
=
`
expr
$_ts_tmp
% 60
`
_ts_m
=
`
expr
$_ts_tmp
% 60
`
_ts_tmp
=
`
expr
$_ts_tmp
/ 60
`
if
[
$_ts_tmp
-ge
60
]
then
_ts_tmp
=
`
expr
$_ts_tmp
/ 60
`
else
_ts_tmp
=
0
fi
a
=
3
_ts_h
=
$_ts_tmp
_ts_h
=
$_ts_tmp
if
[
$_ts_h
-gt
0
]
if
[
$_ts_h
-gt
0
]
...
@@ -247,191 +113,77 @@ time_spec(){
...
@@ -247,191 +113,77 @@ time_spec(){
echo
$ret
echo
$ret
}
}
log_spec
(){
### Main
_ff_
=
$src_dir
/log/
$report_date
/
$1
.
$2
/test.
$3
.out
if
[
-r
$_ff_
]
&&
[
-s
$_ff_
]
then
_f2_
=
$dst_dir
/log.
$report_date
.
$1
.
$2
.
$3
.out.gz
if
[
-r
$_f2_
]
then
rm
$_f2_
fi
cp
$_ff_
$dst_dir
/log.
$report_date
.
$1
.
$2
.
$3
.out
gzip
$dst_dir
/log.
$report_date
.
$1
.
$2
.
$3
.out
rm
-f
$dst_dir
/log.
$report_date
.
$1
.
$2
.
$3
.out
echo
"<a href=log.
$report_date
.
$1
.
$2
.
$3
.out.gz>Log file</a>"
else
echo
"-"
fi
}
err_spec
(){
report_file
=
$src_dir
/report.html
_ff_
=
$src_dir
/log/
$report_date
/
$1
.
$2
/test.
$3
.err.tar
summary_file
=
$src_dir
/summary.html
if
[
-r
$_ff_
]
&&
[
-s
$_ff_
]
then
cp
$_ff_
$dst_dir
/err.
$report_date
.
$1
.
$2
.
$3
.err.tar
gzip
$dst_dir
/err.
$report_date
.
$1
.
$2
.
$3
.err.tar
rm
-f
$dst_dir
/err.
$report_date
.
$1
.
$2
.
$3
.err.tar
echo
"<a href=err.
$report_date
.
$1
.
$2
.
$3
.err.tar.gz>Error tarball</a>"
else
echo
"-"
fi
}
command_spec
(){
passed
=
0
echo
$*
|
sed
's/;/<BR>/g'
failed
=
0
}
total
=
0
### Main
pass
(){
passed
=
`
expr
$passed
+ 1
`
}
html_summary_file
=
$dst_dir
/summary.
$report_date
.html
fail
(){
failed
=
`
expr
$failed
+ 1
`
}
trace
"Creating summary"
(
(
eval
`
grep
"TOTAL"
$summary_file
|
awk
-F
";"
'{ printf("test_file=\"%s\"; elapsed=\"%s\"; started=\"%s\"; stopped=\"%s\"", $2, $3, $4, $5); }'
`
header Report
$run
$date
table
"border=1"
header
"Autotest summary
$report_date
"
heading 1
"Autotest summary
$report_date
"
table
row
;
column
`
bold
test
file:
`
;
column
$test_file
;
end_row
row
;
column
`
bold Started:
`
;
column
"
$started
"
;
end_row
row
;
column
`
bold Stopped:
`
;
column
"
$stopped
"
;
end_row
row
;
column
`
bold Elapsed:
`
;
column
"
`
time_spec
$elapsed
secs
`
"
;
end_row
end_table
hr
table
"border=1"
row
c_column
`
bold Report
`
c_column
`
bold Tag
`
c_column
`
bold Version
`
c_column
`
bold Distr-Config
`
c_column
`
bold Db-Config
`
c_column
`
bold Type
`
c_column
`
bold Test file
`
c_column
`
bold Make
`
c_column
`
bold Config
`
c_column
`
bold Test
time
`
c_column
`
bold Passed
`
c_column
`
bold Failed
`
end_row
grep
-v
"^#"
$summary_file
|
grep
-v
TOTAL |
sed
's/;/ /g'
|
\
while
read
tag version config template
type
test_file make_res make_time conf_res conf_time test_time passed failed
do
row
row
if
[
-r
$src_dir
/reports/report.
$tag
.
$version
.
$config
.
$template
.
$type
.
$test_file
.
$report_date
]
column
`
bold Test
case
`
then
column
`
bold Result
`
column
"<a href=
\"
report.
$tag
.
$version
.
$config
.
$template
.
$type
.
$test_file
.
$report_date
.html
\"
>report</a>"
column
`
bold Elapsed
`
else
column
`
bold Log
`
column
"-"
fi
column
$tag
column
$version
column
$config
column
$template
column
$type
column
$test_file
column
"
$make_res
(
`
time_spec
$make_time
`
)"
column
"
$conf_res
(
`
time_spec
$conf_time
`
)"
c_column
"
`
time_spec
$test_time
`
"
c_column
`
bold
$passed
`
c_column
`
bold
$failed
`
end_row
end_row
done
)
>
$report_file
end_table
footer
cat
$src_file
|
while
read
line
)
>
$html_summary_file
for
i
in
$src_dir
/reports/report.
*
.
$report_date
do
do
f
=
`
basename
$i
`
eval
`
echo
$line
|
awk
-F
";"
'{ printf("prg=\"%s\"; no=\"%s\"; res=\"%s\"; time=\"%s\"", $1, $2, $3, $4); }'
`
trace
"Creating report:
$f
"
eval
`
echo
$f
|
awk
-F
"."
'{printf("tag=%s;version=%s;config=%s;template=%s;type=%s;test_file=%s", $2, $3, $4, $5, $6, $7);}'
`
prg
=
`
trim
$prg
`
no
=
`
trim
$no
`
(
res
=
`
trim
$res
`
header
"Autotest report
$report_date
"
time
=
`
trim
$time
`
heading 1
"Autotest report
$report_date
"
res_dir
=
"<a href=
\"
result-
$run
/
$date
/result.
$no
/
\"
>log</a>"
table
#"border=1"
row
;
column
`
bold Tag:
`
;
column
$tag
;
end_row
ts
=
`
time_spec
$time
`
row
;
column
`
bold Version:
`
;
column
$version
;
end_row
res_txt
=
""
row
;
column
`
bold Configuration:
`
;
column
`
config_spec
$config
`
;
end_row
case
$res
in
row
;
column
`
bold Template:
`
;
column
`
config_spec
$template
`
;
end_row
0
)
pass
;
res_txt
=
"PASSED"
;
res_dir
=
" "
;;
row
;
column
`
bold Type:
`
;
column
$type
;
end_row
*
)
fail
;
res_txt
=
"FAILED"
;;
row
;
column
`
bold Test file:
`
;
column
$test_file
;
end_row
esac
end_table
total
=
`
expr
$total
+
$time
`
hr
(
table
"border=1"
row
row
column
$prg
c_column
`
bold Test
case
`
column
$res_txt
c_column
`
bold Result
`
column
$ts
c_column
`
bold Test
time
`
column
$res_dir
c_column
`
bold Logfile
`
end_row
c_column
`
bold Error tarfile
`
)
>>
$report_file
end_row
(
grep
-v
"^#"
$i
|
sed
's/;/ /g'
|
\
row
while
read
test_no test_res test_time cmd
column
$run
do
column
$date
row
column
$passed
column
"
`
command_spec
$cmd
`
"
column
$failed
case
"
$test_res
"
in
column
`
time_spec
$total
`
0
)
column
"<a href=
\"
result-
$run
/
$date
/report.html
\"
>report</a>"
column
"PASSED"
;;
column
"<a href=
\"
result-
$run
/
$date
/log.txt
\"
>log.txt</a>"
1001
)
end_row
column
"API error"
;;
)
>
$summary_file
1002
)
column
"Max time expired"
;;
1003
)
column
"Mgm port busy"
;;
*
)
column
"Unknown:
$test_res
"
;;
esac
column
"
`
time_spec
$test_time
`
"
column
"
`
log_spec
$tag
$version
$test_no
`
"
column
"
`
err_spec
$tag
$version
$test_no
`
"
end_row
done
end_table
# Last on page we include spec
# of used machines and template for config
# for future reference
hr
table
"border=1"
row
;
column
`
bold Configuration:
`
$config
;
end_row
row
;
column
`
config_spec_include
$config
`
;
end_row
end_table
hr
table
"border=1"
row
;
column
`
bold Template:
`
$template
;
end_row
row
;
column
`
config_spec_include
$template
`
;
end_row
end_table
footer
)
>
$dst_dir
/
$f
.html
done
done
# Re creating index
trace
"Recreating index"
(
(
header
"Autotest super-duper index"
end_table
heading 1
"<center>Autotest super-duper index</center>"
footer
hr
)
>>
$report_file
for
i
in
`
ls
$dst_dir
/summary.
*
.html
|
sort
-r
-n
`
do
f
=
`
basename
$i
`
cat
<<
EOF
<p><a href=
$f
>
$f
</a></p>
EOF
done
footer
)
>
$dst_dir
/index.html
exit
0
exit
0
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment