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:
void execSTTOR(Signal* signal);
void execREAD_CONFIG_REQ(Signal* signal);
// 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(const Frag& frag, TableData data1, Data data2, unsigned maxlen2 = MaxAttrDataSize);
/*
* DbtuxMeta.cpp
......@@ -657,7 +660,7 @@ private:
/*
* 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 cmpScanBound(const Frag& frag, const BoundPar boundPar);
......@@ -702,23 +705,25 @@ private:
Uint32 c_internalStartPhase;
Uint32 c_typeOfStart;
// buffer for scan bounds and keyinfo (primary key)
Data c_dataBuffer;
// array of index key attribute ids in AttributeHeader format
/*
* Array of index key attribute ids in AttributeHeader format.
* Includes fixed attribute sizes. This is global data set at
* operation start and is not passed as a parameter.
*/
Data c_keyAttrs;
// search key data as pointers to TUP storage
// buffer for search key data as pointers to TUP storage
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;
// buffer for scan bounds and keyinfo (primary key)
Data c_dataBuffer;
// inlined utils
DescEnt& getDescEnt(Uint32 descPage, Uint32 descOff);
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 max(unsigned x, unsigned y);
};
......@@ -1257,34 +1262,6 @@ Dbtux::getTupAddr(const Frag& frag, TreeEnt ent)
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
Dbtux::min(unsigned x, unsigned y)
{
......
......@@ -25,12 +25,12 @@
* prefix may be partial in which case CmpUnknown may be returned.
*/
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 DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
// number of words of attribute data left
unsigned len2 = size2;
unsigned len2 = maxlen2;
// skip to right position in search key
data1 += start;
int ret = 0;
......
......@@ -195,10 +195,10 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
new (indexPtr.p) Index();
}
// allocate buffers
c_dataBuffer = (Uint32*)allocRecord("c_dataBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1);
c_keyAttrs = (Uint32*)allocRecord("c_keyAttrs", sizeof(Uint32), MaxIndexAttributes);
c_searchKey = (TableData)allocRecord("c_searchKey", sizeof(Uint32*), MaxIndexAttributes);
c_entryKey = (TableData)allocRecord("c_entryKey", sizeof(Uint32*), MaxIndexAttributes);
c_dataBuffer = (Uint32*)allocRecord("c_dataBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1);
// ack
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
conf->senderRef = reference();
......@@ -209,6 +209,37 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
// 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
Dbtux::copyAttrs(Data dst, ConstData src, CopyPar& copyPar)
{
......@@ -243,4 +274,46 @@ Dbtux::copyAttrs(Data dst, ConstData src, CopyPar& copyPar)
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);
......@@ -74,14 +74,14 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
ndbrequire(fragPtr.i != RNIL);
Frag& frag = *fragPtr.p;
// set up index keys for this operation
setKeyAttrs(frag, c_keyAttrs);
setKeyAttrs(frag);
// set up search entry
TreeEnt ent;
ent.m_tupLoc = TupLoc(req->pageId, req->pageOffset);
ent.m_tupVersion = req->tupVersion;
ent.m_fragBit = fragBit;
// read search key
readKeyAttrs(frag, ent, 0, c_keyAttrs, c_searchKey);
readKeyAttrs(frag, ent, 0, c_searchKey);
// check if all keys are null
{
const unsigned numAttrs = frag.m_numAttrs;
......
......@@ -85,8 +85,8 @@ Dbtux::insertNode(Signal* signal, NodeHandle& node, AccSize 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);
memset(node.getPref(0), 0xa2, tree.m_prefSize << 2);
memset(node.getPref(1), 0xa2, tree.m_prefSize << 2);
TreeEnt* entList = tree.getEntList(node.m_node);
memset(entList, 0xa4, (tree.m_maxOccup + 1) * (TreeEntSize << 2));
#endif
......@@ -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
Dbtux::setNodePref(Signal* signal, NodeHandle& node, unsigned i)
{
Frag& frag = node.m_frag;
TreeHead& tree = frag.m_tree;
ReadPar readPar;
ndbrequire(i <= 1);
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);
const Frag& frag = node.m_frag;
const TreeHead& tree = frag.m_tree;
readKeyAttrs(frag, node.getMinMax(i), 0, c_entryKey);
copyAttrs(frag, c_entryKey, node.getPref(i), tree.m_prefSize);
}
// node operations
......
......@@ -54,7 +54,7 @@ loop: {
if (ret == NdbSqlUtil::CmpUnknown) {
jam();
// 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);
ndbrequire(ret != NdbSqlUtil::CmpUnknown);
}
......@@ -99,7 +99,7 @@ loop: {
jam();
// read and compare remaining attributes
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);
ndbrequire(ret != NdbSqlUtil::CmpUnknown);
}
......
......@@ -46,4 +46,7 @@ optim 9 mc02/a 43 ms 67 ms 54 pct
optim 10 mc02/a 44 ms 65 ms 46 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:
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