mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
tux optim 11 - use TUP method to read min/max prefixes
This commit is contained in:
parent
e063f90995
commit
164878bb6d
7 changed files with 105 additions and 65 deletions
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue