Commit 5fd214dc authored by pekka@mysql.com's avatar pekka@mysql.com

tux optim 3 - use TUP methods instead of TUP_STORE_TH signal

parent fd8acbc2
...@@ -130,7 +130,7 @@ private: ...@@ -130,7 +130,7 @@ 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 will be replaced by method in TUP * XXX this signal is no longer used by TUX and can be removed
*/ */
class TupStoreTh { class TupStoreTh {
friend class Dbtup; friend class Dbtup;
...@@ -155,8 +155,8 @@ private: ...@@ -155,8 +155,8 @@ private:
Uint32 tableId; Uint32 tableId;
Uint32 fragId; Uint32 fragId;
Uint32 fragPtrI; Uint32 fragPtrI;
Uint32 tupAddr; // no longer used Uint32 tupAddr;
Uint32 tupVersion; // no longer used Uint32 tupVersion;
Uint32 pageId; Uint32 pageId;
Uint32 pageOffset; Uint32 pageOffset;
Uint32 bufferId; Uint32 bufferId;
......
...@@ -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);
......
...@@ -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)
{ {
......
...@@ -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,6 +95,9 @@ public: ...@@ -92,6 +95,9 @@ 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;
......
...@@ -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();
...@@ -180,7 +183,7 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal) ...@@ -180,7 +183,7 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
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) {
......
...@@ -20,12 +20,7 @@ ...@@ -20,12 +20,7 @@
/* /*
* Node handles. * Node handles.
* *
* We use the "cache" implementation. Node operations are done on * Temporary version between "cache" and "pointer" implementations.
* 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.
*/ */
// Dbtux // Dbtux
...@@ -40,17 +35,6 @@ Dbtux::seizeNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr) ...@@ -40,17 +35,6 @@ Dbtux::seizeNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr)
new (nodePtr.p) NodeHandle(*this, frag); new (nodePtr.p) NodeHandle(*this, frag);
nodePtr.p->m_next = frag.m_nodeList; nodePtr.p->m_next = frag.m_nodeList;
frag.m_nodeList = nodePtr.i; 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 void
...@@ -63,17 +47,29 @@ Dbtux::preallocNode(Signal* signal, Frag& frag, Uint32& errorCode) ...@@ -63,17 +47,29 @@ Dbtux::preallocNode(Signal* signal, Frag& frag, Uint32& errorCode)
// remove from cache XXX ugly // remove from cache XXX ugly
frag.m_nodeFree = frag.m_nodeList; frag.m_nodeFree = frag.m_nodeList;
frag.m_nodeList = nodePtr.p->m_next; frag.m_nodeList = nodePtr.p->m_next;
StorePar storePar; // alloc index node in TUP
storePar.m_opCode = TupStoreTh::OpInsert; Uint32 pageId = NullTupLoc.m_pageId;
storePar.m_offset = 0; Uint32 pageOffset = NullTupLoc.m_pageOffset;
storePar.m_size = 0; Uint32* node32 = 0;
tupStoreTh(signal, frag, nodePtr, storePar); errorCode = c_tup->tuxAllocNode(signal, frag.m_tupIndexFragPtrI, pageId, pageOffset, node32);
if (storePar.m_errorCode != 0) { if (errorCode != 0) {
jam(); jam();
errorCode = storePar.m_errorCode;
c_nodeHandlePool.release(nodePtr); c_nodeHandlePool.release(nodePtr);
frag.m_nodeFree = RNIL; frag.m_nodeFree = RNIL;
return;
} }
nodePtr.p->m_loc = TupLoc(pageId, pageOffset);
nodePtr.p->m_node = reinterpret_cast<TreeNode*>(node32);
ndbrequire(nodePtr.p->m_loc != NullTupLoc && nodePtr.p->m_node != 0);
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
} }
/* /*
...@@ -114,6 +110,12 @@ Dbtux::selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc ...@@ -114,6 +110,12 @@ Dbtux::selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc
seizeNode(signal, frag, tmpPtr); seizeNode(signal, frag, tmpPtr);
ndbrequire(tmpPtr.i != RNIL); ndbrequire(tmpPtr.i != RNIL);
tmpPtr.p->m_loc = loc; tmpPtr.p->m_loc = loc;
Uint32 pageId = loc.m_pageId;
Uint32 pageOffset = loc.m_pageOffset;
Uint32* node32 = 0;
c_tup->tuxGetNode(frag.m_tupIndexFragPtrI, pageId, pageOffset, node32);
tmpPtr.p->m_node = reinterpret_cast<TreeNode*>(node32);
ndbrequire(tmpPtr.p->m_loc != NullTupLoc && tmpPtr.p->m_node != 0);
} }
if (tmpPtr.p->m_acc < acc) { if (tmpPtr.p->m_acc < acc) {
jam(); jam();
...@@ -123,7 +125,7 @@ Dbtux::selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc ...@@ -123,7 +125,7 @@ Dbtux::selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc
} }
/* /*
* Create new node in the cache and mark it for insert. * Create new node in the cache using the pre-allocated node.
*/ */
void void
Dbtux::insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc) Dbtux::insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc)
...@@ -143,13 +145,20 @@ Dbtux::insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize ac ...@@ -143,13 +145,20 @@ Dbtux::insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize ac
} }
/* /*
* Mark existing node for deletion. * Delete existing node.
*/ */
void void
Dbtux::deleteNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr) Dbtux::deleteNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr)
{ {
NodeHandlePtr tmpPtr = nodePtr; NodeHandlePtr tmpPtr = nodePtr;
ndbrequire(tmpPtr.p->getOccup() == 0); ndbrequire(tmpPtr.p->getOccup() == 0);
Uint32 pageId = tmpPtr.p->m_loc.m_pageId;
Uint32 pageOffset = tmpPtr.p->m_loc.m_pageOffset;
Uint32* node32 = reinterpret_cast<Uint32*>(tmpPtr.p->m_node);
c_tup->tuxFreeNode(signal, frag.m_tupIndexFragPtrI, pageId, pageOffset, node32);
// invalidate handle and storage
tmpPtr.p->m_loc = NullTupLoc;
tmpPtr.p->m_node = 0;
tmpPtr.p->m_flags |= NodeHandle::DoDelete; tmpPtr.p->m_flags |= NodeHandle::DoDelete;
// scans have already been moved by popDown or popUp // scans have already been moved by popDown or popUp
} }
...@@ -162,17 +171,10 @@ Dbtux::accessNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize ac ...@@ -162,17 +171,10 @@ Dbtux::accessNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize ac
{ {
TreeHead& tree = frag.m_tree; TreeHead& tree = frag.m_tree;
NodeHandlePtr tmpPtr = nodePtr; NodeHandlePtr tmpPtr = nodePtr;
ndbrequire(tmpPtr.p->m_loc != NullTupLoc && tmpPtr.p->m_node != 0);
if (tmpPtr.p->m_acc >= acc) if (tmpPtr.p->m_acc >= acc)
return; return;
if (! (tmpPtr.p->m_flags & NodeHandle::DoInsert)) { // XXX could do prefetch
jam();
StorePar storePar;
storePar.m_opCode = TupStoreTh::OpRead;
storePar.m_offset = tree.getSize(tmpPtr.p->m_acc);
storePar.m_size = tree.getSize(acc) - tree.getSize(tmpPtr.p->m_acc);
tmpPtr.p->m_tux.tupStoreTh(signal, frag, tmpPtr, storePar);
ndbrequire(storePar.m_errorCode == 0);
}
tmpPtr.p->m_acc = acc; tmpPtr.p->m_acc = acc;
} }
...@@ -220,11 +222,7 @@ Dbtux::commitNodes(Signal* signal, Frag& frag, bool updateOk) ...@@ -220,11 +222,7 @@ Dbtux::commitNodes(Signal* signal, Frag& frag, bool updateOk)
if (flags & NodeHandle::DoDelete) { if (flags & NodeHandle::DoDelete) {
jam(); jam();
ndbrequire(updateOk); ndbrequire(updateOk);
// delete // delete already done
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) { } else if (flags & NodeHandle::DoUpdate) {
jam(); jam();
ndbrequire(updateOk); ndbrequire(updateOk);
...@@ -237,13 +235,7 @@ Dbtux::commitNodes(Signal* signal, Frag& frag, bool updateOk) ...@@ -237,13 +235,7 @@ Dbtux::commitNodes(Signal* signal, Frag& frag, bool updateOk)
jam(); jam();
setNodePref(signal, frag, nodePtr, 1); setNodePref(signal, frag, nodePtr, 1);
} }
// update // update already done via pointer
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 // release
NodeHandlePtr tmpPtr = nodePtr; NodeHandlePtr tmpPtr = nodePtr;
......
...@@ -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
......
...@@ -21,5 +21,7 @@ optim 1 mc02/a 38 ms 85 ms 124 pct ...@@ -21,5 +21,7 @@ optim 1 mc02/a 38 ms 85 ms 124 pct
optim 2 mc02/a 41 ms 80 ms 96 pct optim 2 mc02/a 41 ms 80 ms 96 pct
mc02/b 51 ms 117 ms 128 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
vim: set et: vim: set et:
...@@ -2222,7 +2222,6 @@ pkupdateindexbuild(Par par) ...@@ -2222,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);
} }
...@@ -2513,6 +2512,7 @@ tbusybuild(Par par) ...@@ -2513,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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment