Commit 164878bb authored by pekka@mysql.com's avatar pekka@mysql.com

tux optim 11 - use TUP method to read min/max prefixes

parent e063f909
...@@ -587,7 +587,10 @@ private: ...@@ -587,7 +587,10 @@ private:
void execSTTOR(Signal* signal); void execSTTOR(Signal* signal);
void execREAD_CONFIG_REQ(Signal* signal); void execREAD_CONFIG_REQ(Signal* signal);
// utils // utils
void setKeyAttrs(const Frag& frag);
void readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, TableData keyData);
void copyAttrs(Data dst, ConstData src, CopyPar& copyPar); void copyAttrs(Data dst, ConstData src, CopyPar& copyPar);
void copyAttrs(const Frag& frag, TableData data1, Data data2, unsigned maxlen2 = MaxAttrDataSize);
/* /*
* DbtuxMeta.cpp * DbtuxMeta.cpp
...@@ -657,7 +660,7 @@ private: ...@@ -657,7 +660,7 @@ private:
/* /*
* DbtuxCmp.cpp * DbtuxCmp.cpp
*/ */
int cmpSearchKey(const Frag& frag, unsigned& start, TableData data1, ConstData data2, unsigned size2 = MaxAttrDataSize); int cmpSearchKey(const Frag& frag, unsigned& start, TableData data1, ConstData data2, unsigned maxlen2 = MaxAttrDataSize);
int cmpSearchKey(const Frag& frag, unsigned& start, TableData data1, TableData data2); int cmpSearchKey(const Frag& frag, unsigned& start, TableData data1, TableData data2);
int cmpScanBound(const Frag& frag, const BoundPar boundPar); int cmpScanBound(const Frag& frag, const BoundPar boundPar);
...@@ -702,23 +705,25 @@ private: ...@@ -702,23 +705,25 @@ private:
Uint32 c_internalStartPhase; Uint32 c_internalStartPhase;
Uint32 c_typeOfStart; Uint32 c_typeOfStart;
// buffer for scan bounds and keyinfo (primary key) /*
Data c_dataBuffer; * Array of index key attribute ids in AttributeHeader format.
* Includes fixed attribute sizes. This is global data set at
// array of index key attribute ids in AttributeHeader format * operation start and is not passed as a parameter.
*/
Data c_keyAttrs; Data c_keyAttrs;
// search key data as pointers to TUP storage // buffer for search key data as pointers to TUP storage
TableData c_searchKey; TableData c_searchKey;
// current entry key data as pointers to TUP storage // buffer for current entry key data as pointers to TUP storage
TableData c_entryKey; TableData c_entryKey;
// buffer for scan bounds and keyinfo (primary key)
Data c_dataBuffer;
// inlined utils // inlined utils
DescEnt& getDescEnt(Uint32 descPage, Uint32 descOff); DescEnt& getDescEnt(Uint32 descPage, Uint32 descOff);
Uint32 getTupAddr(const Frag& frag, TreeEnt ent); Uint32 getTupAddr(const Frag& frag, TreeEnt ent);
void setKeyAttrs(const Frag& frag, Data keyAttrs);
void readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, ConstData keyAttrs, TableData keyData);
static unsigned min(unsigned x, unsigned y); static unsigned min(unsigned x, unsigned y);
static unsigned max(unsigned x, unsigned y); static unsigned max(unsigned x, unsigned y);
}; };
...@@ -1257,34 +1262,6 @@ Dbtux::getTupAddr(const Frag& frag, TreeEnt ent) ...@@ -1257,34 +1262,6 @@ Dbtux::getTupAddr(const Frag& frag, TreeEnt ent)
return tupAddr; return tupAddr;
} }
inline void
Dbtux::setKeyAttrs(const Frag& frag, Data keyAttrs)
{
const unsigned numAttrs = frag.m_numAttrs;
const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
for (unsigned i = 0; i < numAttrs; i++) {
const DescAttr& descAttr = descEnt.m_descAttr[i];
Uint32 size = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc);
keyAttrs.ah() = AttributeHeader(descAttr.m_primaryAttrId, size);
keyAttrs += 1;
}
}
inline void
Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, ConstData keyAttrs, TableData keyData)
{
const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit];
const TupLoc tupLoc = ent.m_tupLoc;
const Uint32 tupVersion = ent.m_tupVersion;
ndbrequire(start < frag.m_numAttrs);
const unsigned numAttrs = frag.m_numAttrs - start;
// start applies to both keys and output data
keyAttrs += start;
keyData += start;
c_tup->tuxReadAttrs(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, tupVersion, numAttrs, keyAttrs, keyData);
jamEntry();
}
inline unsigned inline unsigned
Dbtux::min(unsigned x, unsigned y) Dbtux::min(unsigned x, unsigned y)
{ {
......
...@@ -25,12 +25,12 @@ ...@@ -25,12 +25,12 @@
* prefix may be partial in which case CmpUnknown may be returned. * prefix may be partial in which case CmpUnknown may be returned.
*/ */
int int
Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData data1, ConstData data2, unsigned size2) Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData data1, ConstData data2, unsigned maxlen2)
{ {
const unsigned numAttrs = frag.m_numAttrs; const unsigned numAttrs = frag.m_numAttrs;
const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
// number of words of attribute data left // number of words of attribute data left
unsigned len2 = size2; unsigned len2 = maxlen2;
// skip to right position in search key // skip to right position in search key
data1 += start; data1 += start;
int ret = 0; int ret = 0;
......
...@@ -195,10 +195,10 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal) ...@@ -195,10 +195,10 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
new (indexPtr.p) Index(); new (indexPtr.p) Index();
} }
// allocate buffers // allocate buffers
c_dataBuffer = (Uint32*)allocRecord("c_dataBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1);
c_keyAttrs = (Uint32*)allocRecord("c_keyAttrs", sizeof(Uint32), MaxIndexAttributes); c_keyAttrs = (Uint32*)allocRecord("c_keyAttrs", sizeof(Uint32), MaxIndexAttributes);
c_searchKey = (TableData)allocRecord("c_searchKey", sizeof(Uint32*), MaxIndexAttributes); c_searchKey = (TableData)allocRecord("c_searchKey", sizeof(Uint32*), MaxIndexAttributes);
c_entryKey = (TableData)allocRecord("c_entryKey", sizeof(Uint32*), MaxIndexAttributes); c_entryKey = (TableData)allocRecord("c_entryKey", sizeof(Uint32*), MaxIndexAttributes);
c_dataBuffer = (Uint32*)allocRecord("c_dataBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1);
// ack // ack
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
conf->senderRef = reference(); conf->senderRef = reference();
...@@ -209,6 +209,37 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal) ...@@ -209,6 +209,37 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
// utils // utils
void
Dbtux::setKeyAttrs(const Frag& frag)
{
Data keyAttrs = c_keyAttrs; // global
const unsigned numAttrs = frag.m_numAttrs;
const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
for (unsigned i = 0; i < numAttrs; i++) {
const DescAttr& descAttr = descEnt.m_descAttr[i];
Uint32 size = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc);
// set attr id and fixed size
keyAttrs.ah() = AttributeHeader(descAttr.m_primaryAttrId, size);
keyAttrs += 1;
}
}
void
Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, TableData keyData)
{
ConstData keyAttrs = c_keyAttrs; // global
const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit];
const TupLoc tupLoc = ent.m_tupLoc;
const Uint32 tupVersion = ent.m_tupVersion;
ndbrequire(start < frag.m_numAttrs);
const unsigned numAttrs = frag.m_numAttrs - start;
// start applies to both keys and output data
keyAttrs += start;
keyData += start;
c_tup->tuxReadAttrs(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, tupVersion, numAttrs, keyAttrs, keyData);
jamEntry();
}
void void
Dbtux::copyAttrs(Data dst, ConstData src, CopyPar& copyPar) Dbtux::copyAttrs(Data dst, ConstData src, CopyPar& copyPar)
{ {
...@@ -243,4 +274,46 @@ Dbtux::copyAttrs(Data dst, ConstData src, CopyPar& copyPar) ...@@ -243,4 +274,46 @@ Dbtux::copyAttrs(Data dst, ConstData src, CopyPar& copyPar)
copyPar = c; copyPar = c;
} }
/*
* Input is pointers to table attributes. Output is array of attribute
* data with headers. Copies whatever fits.
*/
void
Dbtux::copyAttrs(const Frag& frag, TableData data1, Data data2, unsigned maxlen2)
{
ConstData keyAttrs = c_keyAttrs; // global
const unsigned numAttrs = frag.m_numAttrs;
unsigned len2 = maxlen2;
for (unsigned n = 0; n < numAttrs; n++) {
jam();
const unsigned attrId = keyAttrs.ah().getAttributeId();
const unsigned dataSize = keyAttrs.ah().getDataSize();
const Uint32* const p1 = *data1;
if (p1 != 0) {
if (len2 == 0)
return;
data2.ah() = AttributeHeader(attrId, dataSize);
data2 += 1;
len2 -= 1;
unsigned n = dataSize;
for (unsigned i = 0; i < dataSize; i++) {
if (len2 == 0)
return;
*data2 = p1[i];
data2 += 1;
len2 -= 1;
}
} else {
if (len2 == 0)
return;
data2.ah() = AttributeHeader(attrId, 0);
data2.ah().setNULL();
data2 += 1;
len2 -= 1;
}
keyAttrs += 1;
data1 += 1;
}
}
BLOCK_FUNCTIONS(Dbtux); BLOCK_FUNCTIONS(Dbtux);
...@@ -74,14 +74,14 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal) ...@@ -74,14 +74,14 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
ndbrequire(fragPtr.i != RNIL); ndbrequire(fragPtr.i != RNIL);
Frag& frag = *fragPtr.p; Frag& frag = *fragPtr.p;
// set up index keys for this operation // set up index keys for this operation
setKeyAttrs(frag, c_keyAttrs); setKeyAttrs(frag);
// set up search entry // set up search entry
TreeEnt ent; TreeEnt ent;
ent.m_tupLoc = TupLoc(req->pageId, req->pageOffset); ent.m_tupLoc = TupLoc(req->pageId, req->pageOffset);
ent.m_tupVersion = req->tupVersion; ent.m_tupVersion = req->tupVersion;
ent.m_fragBit = fragBit; ent.m_fragBit = fragBit;
// read search key // read search key
readKeyAttrs(frag, ent, 0, c_keyAttrs, c_searchKey); readKeyAttrs(frag, ent, 0, c_searchKey);
// check if all keys are null // check if all keys are null
{ {
const unsigned numAttrs = frag.m_numAttrs; const unsigned numAttrs = frag.m_numAttrs;
......
...@@ -85,8 +85,8 @@ Dbtux::insertNode(Signal* signal, NodeHandle& node, AccSize acc) ...@@ -85,8 +85,8 @@ Dbtux::insertNode(Signal* signal, NodeHandle& node, AccSize acc)
new (node.m_node) TreeNode(); new (node.m_node) TreeNode();
#ifdef VM_TRACE #ifdef VM_TRACE
TreeHead& tree = frag.m_tree; TreeHead& tree = frag.m_tree;
memset(tree.getPref(node.m_node, 0), 0xa2, tree.m_prefSize << 2); memset(node.getPref(0), 0xa2, tree.m_prefSize << 2);
memset(tree.getPref(node.m_node, 1), 0xa2, tree.m_prefSize << 2); memset(node.getPref(1), 0xa2, tree.m_prefSize << 2);
TreeEnt* entList = tree.getEntList(node.m_node); TreeEnt* entList = tree.getEntList(node.m_node);
memset(entList, 0xa4, (tree.m_maxOccup + 1) * (TreeEntSize << 2)); memset(entList, 0xa4, (tree.m_maxOccup + 1) * (TreeEntSize << 2));
#endif #endif
...@@ -112,29 +112,16 @@ Dbtux::deleteNode(Signal* signal, NodeHandle& node) ...@@ -112,29 +112,16 @@ Dbtux::deleteNode(Signal* signal, NodeHandle& node)
} }
/* /*
* Set prefix. * Set prefix. Copies the number of words that fits. Includes
* attribute headers for now. XXX use null mask instead
*/ */
void void
Dbtux::setNodePref(Signal* signal, NodeHandle& node, unsigned i) Dbtux::setNodePref(Signal* signal, NodeHandle& node, unsigned i)
{ {
Frag& frag = node.m_frag; const Frag& frag = node.m_frag;
TreeHead& tree = frag.m_tree; const TreeHead& tree = frag.m_tree;
ReadPar readPar; readKeyAttrs(frag, node.getMinMax(i), 0, c_entryKey);
ndbrequire(i <= 1); copyAttrs(frag, c_entryKey, node.getPref(i), tree.m_prefSize);
readPar.m_ent = node.getMinMax(i);
readPar.m_first = 0;
readPar.m_count = frag.m_numAttrs;
// leave in signal data
readPar.m_data = 0;
// XXX implement max words to read
tupReadAttrs(signal, frag, readPar);
// copy whatever fits
CopyPar copyPar;
copyPar.m_items = readPar.m_count;
copyPar.m_headers = true;
copyPar.m_maxwords = tree.m_prefSize;
Data pref = node.getPref(i);
copyAttrs(pref, readPar.m_data, copyPar);
} }
// node operations // node operations
......
...@@ -54,7 +54,7 @@ loop: { ...@@ -54,7 +54,7 @@ loop: {
if (ret == NdbSqlUtil::CmpUnknown) { if (ret == NdbSqlUtil::CmpUnknown) {
jam(); jam();
// read and compare remaining attributes // read and compare remaining attributes
readKeyAttrs(frag, node.getMinMax(i), start1, c_keyAttrs, c_entryKey); readKeyAttrs(frag, node.getMinMax(i), start1, c_entryKey);
ret = cmpSearchKey(frag, start1, searchKey, c_entryKey); ret = cmpSearchKey(frag, start1, searchKey, c_entryKey);
ndbrequire(ret != NdbSqlUtil::CmpUnknown); ndbrequire(ret != NdbSqlUtil::CmpUnknown);
} }
...@@ -99,7 +99,7 @@ loop: { ...@@ -99,7 +99,7 @@ loop: {
jam(); jam();
// read and compare remaining attributes // read and compare remaining attributes
unsigned start1 = start; unsigned start1 = start;
readKeyAttrs(frag, node.getEnt(j), start1, c_keyAttrs, c_entryKey); readKeyAttrs(frag, node.getEnt(j), start1, c_entryKey);
ret = cmpSearchKey(frag, start1, searchKey, c_entryKey); ret = cmpSearchKey(frag, start1, searchKey, c_entryKey);
ndbrequire(ret != NdbSqlUtil::CmpUnknown); ndbrequire(ret != NdbSqlUtil::CmpUnknown);
} }
......
...@@ -46,4 +46,7 @@ optim 9 mc02/a 43 ms 67 ms 54 pct ...@@ -46,4 +46,7 @@ optim 9 mc02/a 43 ms 67 ms 54 pct
optim 10 mc02/a 44 ms 65 ms 46 pct optim 10 mc02/a 44 ms 65 ms 46 pct
mc02/b 53 ms 88 ms 66 pct mc02/b 53 ms 88 ms 66 pct
optim 11 mc02/a 43 ms 63 ms 46 pct
mc02/b 52 ms 86 ms 63 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