Commit becde519 authored by unknown's avatar unknown

tux optim 5 - move node ops to class level (prepare to remove node cache)

parent e1179bc7
...@@ -505,17 +505,15 @@ private: ...@@ -505,17 +505,15 @@ private:
struct NodeHandle; struct NodeHandle;
friend struct NodeHandle; friend struct NodeHandle;
struct NodeHandle { struct NodeHandle {
Dbtux& m_tux; // this block
Frag& m_frag; // fragment using the node Frag& m_frag; // fragment using the node
TupLoc m_loc; // physical node address TupLoc m_loc; // physical node address
TreeNode* m_node; // pointer to node storage
AccSize m_acc; // accessed size AccSize m_acc; // accessed size
union { union {
Uint32 m_next; // next active node under fragment Uint32 m_next; // next active node under fragment
Uint32 nextPool; Uint32 nextPool;
}; };
TreeNode* m_node; // pointer to node storage NodeHandle(Frag& frag);
Uint32 m_cache[MaxTreeNodeSize];
NodeHandle(Dbtux& tux, Frag& frag);
// getters // getters
TupLoc getLink(unsigned i); TupLoc getLink(unsigned i);
unsigned getChilds(); // cannot spell unsigned getChilds(); // cannot spell
...@@ -532,17 +530,8 @@ private: ...@@ -532,17 +530,8 @@ private:
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 // for ndbrequire and ndbassert
void pushUp(Signal* signal, unsigned pos, const TreeEnt& ent); void progError(int line, int cause, const char* file);
void popDown(Signal* signal, unsigned pos, TreeEnt& ent);
void pushDown(Signal* signal, unsigned pos, TreeEnt& ent);
void popUp(Signal* signal, unsigned pos, TreeEnt& ent);
void slide(Signal* signal, Ptr<NodeHandle> nodePtr, unsigned i);
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; typedef Ptr<NodeHandle> NodeHandlePtr;
ArrayPool<NodeHandle> c_nodeHandlePool; ArrayPool<NodeHandle> c_nodeHandlePool;
...@@ -656,7 +645,6 @@ private: ...@@ -656,7 +645,6 @@ 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
...@@ -668,8 +656,18 @@ private: ...@@ -668,8 +656,18 @@ private:
void insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc); void insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc);
void deleteNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr); void deleteNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr);
void accessNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc); void accessNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc);
void setNodePref(Signal* signal, Frag& frag, NodeHandle& node, unsigned i); void setNodePref(Signal* signal, NodeHandle& node, unsigned i);
void commitNodes(Signal* signal, Frag& frag, bool updateOk); void commitNodes(Signal* signal, Frag& frag, bool updateOk);
// node operations
void nodePushUp(Signal* signal, NodeHandle& node, unsigned pos, const TreeEnt& ent);
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
...@@ -1084,13 +1082,12 @@ Dbtux::FragOp::FragOp() : ...@@ -1084,13 +1082,12 @@ Dbtux::FragOp::FragOp() :
// Dbtux::NodeHandle // 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_loc(), m_loc(),
m_node(0),
m_acc(AccNone), m_acc(AccNone),
m_next(RNIL), m_next(RNIL)
m_node(0)
{ {
} }
......
...@@ -270,97 +270,3 @@ Dbtux::tupReadKeys(Signal* signal, const Frag& frag, ReadPar& readPar) ...@@ -270,97 +270,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 = frag.m_tupIndexFragPtrI;
req->tupAddr = RNIL; // no longer used
req->tupVersion = 0; // no longer used
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);
}
break;
case TupStoreTh::OpInsert:
jam();
nodePtr.p->m_loc.m_pageId = req->pageId;
nodePtr.p->m_loc.m_pageOffset = req->pageOffset;
break;
case TupStoreTh::OpUpdate:
jam();
break;
case TupStoreTh::OpDelete:
jam();
nodePtr.p->m_loc = NullTupLoc;
break;
default:
ndbrequire(false);
break;
}
}
This diff is collapsed.
...@@ -280,7 +280,7 @@ Dbtux::execNEXT_SCANREQ(Signal* signal) ...@@ -280,7 +280,7 @@ Dbtux::execNEXT_SCANREQ(Signal* signal)
const TupLoc loc = scan.m_scanPos.m_loc; const TupLoc loc = scan.m_scanPos.m_loc;
NodeHandlePtr nodePtr; NodeHandlePtr nodePtr;
selectNode(signal, frag, nodePtr, loc, AccHead); selectNode(signal, frag, nodePtr, loc, AccHead);
nodePtr.p->unlinkScan(scanPtr); unlinkScan(*nodePtr.p, scanPtr);
scan.m_scanPos.m_loc = NullTupLoc; scan.m_scanPos.m_loc = NullTupLoc;
} }
if (scan.m_lockwait) { if (scan.m_lockwait) {
...@@ -763,7 +763,7 @@ loop: { ...@@ -763,7 +763,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(*nodePtr.p, scanPtr);
return; return;
} }
if (i == 1 && ret > 0) { if (i == 1 && ret > 0) {
...@@ -779,7 +779,7 @@ loop: { ...@@ -779,7 +779,7 @@ loop: {
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(*nodePtr.p, scanPtr);
return; return;
} }
} }
...@@ -808,7 +808,7 @@ loop: { ...@@ -808,7 +808,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(*nodePtr.p, scanPtr);
return; return;
} }
} }
...@@ -870,7 +870,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) ...@@ -870,7 +870,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
// get and remember original node // get and remember original node
NodeHandlePtr origNodePtr; NodeHandlePtr origNodePtr;
selectNode(signal, frag, origNodePtr, pos.m_loc, AccHead); selectNode(signal, frag, origNodePtr, pos.m_loc, AccHead);
ndbrequire(origNodePtr.p->islinkScan(scanPtr)); ndbrequire(islinkScan(*origNodePtr.p, scanPtr));
// current node in loop // current node in loop
NodeHandlePtr nodePtr = origNodePtr; NodeHandlePtr nodePtr = origNodePtr;
while (true) { while (true) {
...@@ -977,13 +977,13 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) ...@@ -977,13 +977,13 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr)
ndbrequire(pos.m_loc == nodePtr.p->m_loc); ndbrequire(pos.m_loc == nodePtr.p->m_loc);
if (origNodePtr.i != nodePtr.i) { if (origNodePtr.i != nodePtr.i) {
jam(); jam();
origNodePtr.p->unlinkScan(scanPtr); unlinkScan(*origNodePtr.p, scanPtr);
nodePtr.p->linkScan(scanPtr); linkScan(*nodePtr.p, scanPtr);
} }
} else if (scan.m_state == ScanOp::Last) { } else if (scan.m_state == ScanOp::Last) {
jam(); jam();
ndbrequire(pos.m_loc == NullTupLoc); ndbrequire(pos.m_loc == NullTupLoc);
origNodePtr.p->unlinkScan(scanPtr); unlinkScan(*origNodePtr.p, scanPtr);
} else { } else {
ndbrequire(false); ndbrequire(false);
} }
......
...@@ -161,7 +161,7 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent) ...@@ -161,7 +161,7 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent)
if (treePos.m_loc == NullTupLoc) { if (treePos.m_loc == NullTupLoc) {
jam(); jam();
insertNode(signal, frag, nodePtr, AccPref); insertNode(signal, frag, nodePtr, AccPref);
nodePtr.p->pushUp(signal, 0, ent); nodePushUp(signal, *nodePtr.p, 0, ent);
nodePtr.p->setSide(2); nodePtr.p->setSide(2);
tree.m_root = nodePtr.p->m_loc; tree.m_root = nodePtr.p->m_loc;
return; return;
...@@ -174,11 +174,11 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent) ...@@ -174,11 +174,11 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent)
// check if room for one more // check if room for one more
if (nodePtr.p->getOccup() < tree.m_maxOccup) { if (nodePtr.p->getOccup() < tree.m_maxOccup) {
jam(); jam();
nodePtr.p->pushUp(signal, pos, ent); nodePushUp(signal, *nodePtr.p, pos, ent);
return; return;
} }
// returns min entry // returns min entry
nodePtr.p->pushDown(signal, pos - 1, ent); nodePushDown(signal, *nodePtr.p, pos - 1, ent);
// find position to add the removed min entry // find position to add the removed min entry
TupLoc childLoc = nodePtr.p->getLink(0); TupLoc childLoc = nodePtr.p->getLink(0);
if (childLoc == NullTupLoc) { if (childLoc == NullTupLoc) {
...@@ -205,13 +205,13 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent) ...@@ -205,13 +205,13 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent)
// check if the half-leaf/leaf has room for one more // check if the half-leaf/leaf has room for one more
if (nodePtr.p->getOccup() < tree.m_maxOccup) { if (nodePtr.p->getOccup() < tree.m_maxOccup) {
jam(); jam();
nodePtr.p->pushUp(signal, pos, ent); nodePushUp(signal, *nodePtr.p, pos, ent);
return; return;
} }
// add a new node // add a new node
NodeHandlePtr childPtr; NodeHandlePtr childPtr;
insertNode(signal, frag, childPtr, AccPref); insertNode(signal, frag, childPtr, AccPref);
childPtr.p->pushUp(signal, 0, ent); nodePushUp(signal, *childPtr.p, 0, ent);
// connect parent and child // connect parent and child
nodePtr.p->setLink(i, childPtr.p->m_loc); nodePtr.p->setLink(i, childPtr.p->m_loc);
childPtr.p->setLink(2, nodePtr.p->m_loc); childPtr.p->setLink(2, nodePtr.p->m_loc);
...@@ -283,7 +283,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) ...@@ -283,7 +283,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
// check if no underflow // check if no underflow
if (nodePtr.p->getOccup() > tree.m_minOccup) { if (nodePtr.p->getOccup() > tree.m_minOccup) {
jam(); jam();
nodePtr.p->popDown(signal, pos, ent); nodePopDown(signal, *nodePtr.p, pos, ent);
return; return;
} }
// save current handle // save current handle
...@@ -299,13 +299,13 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) ...@@ -299,13 +299,13 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
accessNode(signal, frag, nodePtr, AccFull); accessNode(signal, frag, nodePtr, AccFull);
// use glb max as new parent min // use glb max as new parent min
ent = nodePtr.p->getEnt(nodePtr.p->getOccup() - 1); ent = nodePtr.p->getEnt(nodePtr.p->getOccup() - 1);
parentPtr.p->popUp(signal, pos, ent); nodePopUp(signal, *parentPtr.p, pos, ent);
// set up to remove glb max // set up to remove glb max
pos = nodePtr.p->getOccup() - 1; pos = nodePtr.p->getOccup() - 1;
// fall thru to next case // fall thru to next case
} }
// remove the element // remove the element
nodePtr.p->popDown(signal, pos, ent); nodePopDown(signal, *nodePtr.p, pos, ent);
ndbrequire(nodePtr.p->getChilds() <= 1); ndbrequire(nodePtr.p->getChilds() <= 1);
// handle half-leaf // handle half-leaf
for (unsigned i = 0; i <= 1; i++) { for (unsigned i = 0; i <= 1; i++) {
...@@ -327,7 +327,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) ...@@ -327,7 +327,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
if (parentLoc != NullTupLoc) { if (parentLoc != NullTupLoc) {
jam(); jam();
selectNode(signal, frag, parentPtr, nodePtr.p->getLink(2), AccFull); selectNode(signal, frag, parentPtr, nodePtr.p->getLink(2), AccFull);
parentPtr.p->slide(signal, nodePtr, i); nodeSlide(signal, *parentPtr.p, *nodePtr.p, i);
// fall thru to next case // fall thru to next case
} }
// non-empty leaf // non-empty leaf
...@@ -353,7 +353,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) ...@@ -353,7 +353,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos)
TupLoc childLoc = nodePtr.p->getLink(1 - i); TupLoc childLoc = nodePtr.p->getLink(1 - i);
NodeHandlePtr childPtr; NodeHandlePtr childPtr;
selectNode(signal, frag, childPtr, childLoc, AccFull); selectNode(signal, frag, childPtr, childLoc, AccFull);
nodePtr.p->slide(signal, childPtr, 1 - i); nodeSlide(signal, *nodePtr.p, *childPtr.i, 1 - i);
if (childPtr.p->getOccup() == 0) { if (childPtr.p->getOccup() == 0) {
jam(); jam();
deleteNode(signal, frag, childPtr); deleteNode(signal, frag, childPtr);
...@@ -688,7 +688,7 @@ Dbtux::treeRotateDouble(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, unsi ...@@ -688,7 +688,7 @@ Dbtux::treeRotateDouble(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, unsi
TreeHead& tree = frag.m_tree; TreeHead& tree = frag.m_tree;
accessNode(signal, frag, n2Ptr, AccFull); accessNode(signal, frag, n2Ptr, AccFull);
accessNode(signal, frag, n4Ptr, AccFull); accessNode(signal, frag, n4Ptr, AccFull);
n4Ptr.p->slide(signal, n2Ptr, i); nodeSlide(signal, *n4Ptr.p, *n2Ptr.p, i);
// implied by rule of merging half-leaves with leaves // implied by rule of merging half-leaves with leaves
ndbrequire(n4Ptr.p->getOccup() >= tree.m_minOccup); ndbrequire(n4Ptr.p->getOccup() >= tree.m_minOccup);
ndbrequire(n2Ptr.p->getOccup() != 0); ndbrequire(n2Ptr.p->getOccup() != 0);
......
...@@ -11,6 +11,7 @@ testOIBasic -case u -table 2 -index 4 -fragtype small -threads 10 -rows 100000 - ...@@ -11,6 +11,7 @@ testOIBasic -case u -table 2 -index 4 -fragtype small -threads 10 -rows 100000 -
1 million rows, pk update without index, pk update with index 1 million rows, pk update without index, pk update with index
shows ms / 1000 rows for each and pct overhead 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 040616 mc02/a 40 ms 87 ms 114 pct
mc02/b 51 ms 128 ms 148 pct mc02/b 51 ms 128 ms 148 pct
...@@ -27,5 +28,9 @@ optim 3 mc02/a 43 ms 80 ms 85 pct ...@@ -27,5 +28,9 @@ optim 3 mc02/a 43 ms 80 ms 85 pct
optim 4 mc02/a 42 ms 80 ms 87 pct optim 4 mc02/a 42 ms 80 ms 87 pct
mc02/b 51 ms 119 ms 129 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
vim: set et: vim: set et:
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