Loading ndb/include/kernel/signaldata/TupAccess.hpp +4 −2 Original line number Diff line number Diff line Loading @@ -129,6 +129,8 @@ private: /* * Operate on entire tuple. Used by TUX where the table has a single * Uint32 array attribute representing an index tree node. * * XXX this signal will be replaced by method in TUP */ class TupStoreTh { friend class Dbtup; Loading @@ -153,8 +155,8 @@ private: Uint32 tableId; Uint32 fragId; Uint32 fragPtrI; Uint32 tupAddr; Uint32 tupVersion; Uint32 tupAddr; // no longer used Uint32 tupVersion; // no longer used Uint32 pageId; Uint32 pageOffset; Uint32 bufferId; Loading ndb/include/kernel/signaldata/TupFrag.hpp +4 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ class TuxFragReq { friend class Dblqh; friend class Dbtux; public: STATIC_CONST( SignalLength = 9 ); STATIC_CONST( SignalLength = 14 ); private: Uint32 userPtr; Uint32 userRef; Loading @@ -80,6 +80,9 @@ private: Uint32 fragOff; Uint32 tableType; Uint32 primaryTableId; Uint32 tupIndexFragPtrI; Uint32 tupTableFragPtrI[2]; Uint32 accTableFragPtrI[2]; }; class TuxFragConf { Loading ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -2432,6 +2432,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal) } fragrecptr.i = req->fragPtrI; ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec); ndbrequire(req->fragId == fragrecptr.p->myfid); // caller must be explicit here ndbrequire(req->accOpPtr == RNIL); // seize operation to hold the lock Loading ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -1225,6 +1225,18 @@ Dblqh::sendAddFragReq(Signal* signal) tuxreq->fragOff = addfragptr.p->lh3DistrBits; tuxreq->tableType = addfragptr.p->tableType; tuxreq->primaryTableId = addfragptr.p->primaryTableId; // pointer to index fragment in TUP tuxreq->tupIndexFragPtrI = addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX ? fragptr.p->tupFragptr[0] : fragptr.p->tupFragptr[1]; // pointers to table fragments in TUP and ACC FragrecordPtr tFragPtr; tFragPtr.i = fragptr.p->tableFragptr; ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); tuxreq->tupTableFragPtrI[0] = tFragPtr.p->tupFragptr[0]; tuxreq->tupTableFragPtrI[1] = tFragPtr.p->tupFragptr[1]; tuxreq->accTableFragPtrI[0] = tFragPtr.p->accFragptr[0]; tuxreq->accTableFragPtrI[1] = tFragPtr.p->accFragptr[1]; sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, TuxFragReq::SignalLength, JBB); return; Loading ndb/src/kernel/blocks/dbtux/Dbtux.hpp +231 −177 Original line number Diff line number Diff line Loading @@ -153,8 +153,7 @@ private: static const unsigned AttributeHeaderSize = 1; /* * Logical tuple address, "local key". Identifies both table tuples * and index tuples. The code assumes it is one word. * Logical tuple address, "local key". Identifies table tuples. */ typedef Uint32 TupAddr; static const unsigned NullTupAddr = (Uint32)-1; Loading @@ -168,8 +167,18 @@ private: Uint32 m_pageId; // page i-value Uint16 m_pageOffset; // page offset in words TupLoc(); TupLoc(Uint32 pageId, Uint16 pageOffset); bool operator==(const TupLoc& loc) const; bool operator!=(const TupLoc& loc) const; }; /* * There is no const variable NullTupLoc since the compiler may not be * able to optimize it to TupLoc() constants. Instead null values are * constructed on the stack with TupLoc(). */ #define NullTupLoc TupLoc() // tree definitions /* Loading @@ -183,7 +192,7 @@ private: TupAddr m_tupAddr; // address of original tuple Uint16 m_tupVersion; // version Uint8 m_fragBit; // which duplicated table fragment Uint8 unused1; Uint8 pad1; TreeEnt(); // methods int cmp(const TreeEnt ent) const; Loading @@ -196,7 +205,7 @@ private: * prefix 3) max and min entries 4) rest of entries 5) one extra entry * used as work space. * * struct TreeNode part 1 * struct TreeNode part 1, size 6 words * min prefix part 2, size TreeHead::m_prefSize * max prefix part 2, size TreeHead::m_prefSize * max entry part 3 Loading @@ -204,6 +213,10 @@ private: * rest of entries part 4 * work entry part 5 * * There are 3 links to other nodes: left child, right child, parent. * These are in TupLoc format but the pageIds and pageOffsets are * stored in separate arrays (saves 1 word). * * Occupancy (number of entries) is at least 1 except temporarily when * a node is about to be removed. If occupancy is 1, only max entry * is present but both min and max prefixes are set. Loading @@ -211,11 +224,12 @@ private: struct TreeNode; friend struct TreeNode; struct TreeNode { TupAddr m_link[3]; // link to 0-left child 1-right child 2-parent Uint8 m_side; // we are 0-left child 1-right child 2-root Uint32 m_linkPI[3]; // link to 0-left child 1-right child 2-parent Uint16 m_linkPO[3]; // page offsets for above real page ids unsigned m_side : 2; // we are 0-left child 1-right child 2-root int m_balance : 2; // balance -1, 0, +1 unsigned pad1 : 4; Uint8 m_occup; // current number of entries Int8 m_balance; // balance -1, 0, +1 Uint8 unused1; Uint32 m_nodeScan; // list of scans at this node TreeNode(); }; Loading Loading @@ -243,7 +257,7 @@ private: Uint8 m_prefSize; // words in min/max prefix each Uint8 m_minOccup; // min entries in internal node Uint8 m_maxOccup; // max entries in node TupAddr m_root; // root node TupLoc m_root; // root node TreeHead(); // methods unsigned getSize(AccSize acc) const; Loading @@ -261,8 +275,7 @@ private: struct TreePos; friend struct TreePos; struct TreePos { TupAddr m_addr; // logical node address TupLoc m_loc; // physical address TupLoc m_loc; // physical node address Uint16 m_pos; // position 0 to m_occup Uint8 m_match; // at an existing entry Uint8 m_dir; // from link (0-2) or within node (3) Loading Loading @@ -446,6 +459,9 @@ private: Uint32 m_nodeList; // node cache of current operation Uint32 m_nodeFree; // one node pre-allocated for insert DLList<ScanOp> m_scanList; // current scans on this fragment Uint32 m_tupIndexFragPtrI; Uint32 m_tupTableFragPtrI[2]; Uint32 m_accTableFragPtrI[2]; union { Uint32 nextPool; }; Loading Loading @@ -491,7 +507,6 @@ private: }; Dbtux& m_tux; // this block Frag& m_frag; // fragment using the node TupAddr m_addr; // logical node address TupLoc m_loc; // physical node address AccSize m_acc; // accessed size unsigned m_flags; // flags Loading @@ -503,7 +518,7 @@ private: Uint32 m_cache[MaxTreeNodeSize]; NodeHandle(Dbtux& tux, Frag& frag); // getters TupAddr getLink(unsigned i); TupLoc getLink(unsigned i); unsigned getChilds(); // cannot spell unsigned getSide(); unsigned getOccup(); Loading @@ -513,7 +528,7 @@ private: TreeEnt getEnt(unsigned pos); TreeEnt getMinMax(unsigned i); // setters void setLink(unsigned i, TupAddr addr); void setLink(unsigned i, TupLoc loc); void setSide(unsigned i); void setOccup(unsigned n); void setBalance(int b); Loading Loading @@ -649,8 +664,8 @@ private: */ void seizeNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr); void preallocNode(Signal* signal, Frag& frag, Uint32& errorCode); void findNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupAddr addr); void selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupAddr addr, AccSize acc); void findNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc); void selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc, AccSize acc); void insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc); void deleteNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr); void accessNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc); Loading Loading @@ -698,23 +713,24 @@ private: struct PrintPar { char m_path[100]; // LR prefix unsigned m_side; // expected side TupAddr m_parent; // expected parent address TupLoc m_parent; // expected parent address int m_depth; // returned depth unsigned m_occup; // returned occupancy bool m_ok; // returned status PrintPar(); }; void printTree(Signal* signal, Frag& frag, NdbOut& out); void printNode(Signal* signal, Frag& frag, NdbOut& out, TupAddr addr, PrintPar& par); void printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par); friend class NdbOut& operator<<(NdbOut&, const TupLoc&); friend class NdbOut& operator<<(NdbOut&, const TreeEnt&); friend class NdbOut& operator<<(NdbOut&, const TreeNode&); friend class NdbOut& operator<<(NdbOut&, const TreeHead&); friend class NdbOut& operator<<(NdbOut&, const TreePos&); friend class NdbOut& operator<<(NdbOut&, const DescAttr&); friend class NdbOut& operator<<(NdbOut&, const ScanOp&); friend class NdbOut& operator<<(NdbOut&, const Index&); friend class NdbOut& operator<<(NdbOut&, const Frag&); friend class NdbOut& operator<<(NdbOut&, const NodeHandle&); friend class NdbOut& operator<<(NdbOut&, const ScanOp&); FILE* debugFile; NdbOut debugOut; unsigned debugFlags; Loading Loading @@ -831,8 +847,45 @@ Dbtux::ConstData::operator=(Data data) return *this; } // Dbtux::TupLoc inline Dbtux::TupLoc::TupLoc() : m_pageId(RNIL), m_pageOffset(0) { } inline Dbtux::TupLoc::TupLoc(Uint32 pageId, Uint16 pageOffset) : m_pageId(pageId), m_pageOffset(pageOffset) { } inline bool Dbtux::TupLoc::operator==(const TupLoc& loc) const { return m_pageId == loc.m_pageId && m_pageOffset == loc.m_pageOffset; } inline bool Dbtux::TupLoc::operator!=(const TupLoc& loc) const { return ! (*this == loc); } // Dbtux::TreeEnt inline Dbtux::TreeEnt::TreeEnt() : m_tupAddr(NullTupAddr), m_tupVersion(0), m_fragBit(255), pad1(0) { } inline int Dbtux::TreeEnt::cmp(const TreeEnt ent) const { Loading @@ -852,8 +905,36 @@ Dbtux::TreeEnt::cmp(const TreeEnt ent) const return 0; } // Dbtux::TreeNode inline Dbtux::TreeNode::TreeNode() : m_side(2), m_balance(0), pad1(0), m_occup(0), m_nodeScan(RNIL) { m_linkPI[0] = NullTupLoc.m_pageId; m_linkPO[0] = NullTupLoc.m_pageOffset; m_linkPI[1] = NullTupLoc.m_pageId; m_linkPO[1] = NullTupLoc.m_pageOffset; m_linkPI[2] = NullTupLoc.m_pageId; m_linkPO[2] = NullTupLoc.m_pageOffset; } // Dbtux::TreeHead inline Dbtux::TreeHead::TreeHead() : m_nodeSize(0), m_prefSize(0), m_minOccup(0), m_maxOccup(0), m_root() { } inline unsigned Dbtux::TreeHead::getSize(AccSize acc) const { Loading Loading @@ -885,52 +966,10 @@ Dbtux::TreeHead::getEntList(TreeNode* node) const return (TreeEnt*)ptr; } // Dbtux // constructors inline Dbtux::TupLoc::TupLoc() : m_pageId(RNIL), m_pageOffset(0) { } inline Dbtux::TreeEnt::TreeEnt() : m_tupAddr(NullTupAddr), m_tupVersion(0), m_fragBit(255), unused1(0) { } inline Dbtux::TreeNode::TreeNode() : m_side(255), m_occup(0), m_balance(0), unused1(0xa1), m_nodeScan(RNIL) { m_link[0] = NullTupAddr; m_link[1] = NullTupAddr; m_link[2] = NullTupAddr; } inline Dbtux::TreeHead::TreeHead() : m_nodeSize(0), m_prefSize(0), m_minOccup(0), m_maxOccup(0), m_root(0) { } // Dbtux::TreePos inline Dbtux::TreePos::TreePos() : m_addr(NullTupAddr), m_loc(), m_pos(ZNIL), m_match(false), Loading @@ -939,6 +978,8 @@ Dbtux::TreePos::TreePos() : { } // Dbtux::DescPage inline Dbtux::DescPage::DescPage() : m_nextPage(RNIL), Loading @@ -953,6 +994,41 @@ Dbtux::DescPage::DescPage() : } } // Dbtux::ScanOp inline Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_state(Undef), m_lockwait(false), m_userPtr(RNIL), m_userRef(RNIL), m_tableId(RNIL), m_indexId(RNIL), m_fragPtrI(RNIL), m_transId1(0), m_transId2(0), m_savePointId(0), m_accLockOp(RNIL), m_readCommitted(0), m_lockMode(0), m_keyInfo(0), m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), m_lastEnt(), m_nodeScan(RNIL) { m_bound[0] = &m_boundMin; m_bound[1] = &m_boundMax; m_boundCnt[0] = 0; m_boundCnt[1] = 0; for (unsigned i = 0; i < MaxAccLockOps; i++) { m_accLockOps[i] = RNIL; } } // Dbtux::Index inline Dbtux::Index::Index() : m_state(NotDefined), Loading @@ -969,6 +1045,8 @@ Dbtux::Index::Index() : }; }; // Dbtux::Frag inline Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) : m_tableId(RNIL), Loading @@ -981,10 +1059,17 @@ Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) : m_tree(), m_nodeList(RNIL), m_nodeFree(RNIL), m_scanList(scanOpPool) m_scanList(scanOpPool), m_tupIndexFragPtrI(RNIL) { m_tupTableFragPtrI[0] = RNIL; m_tupTableFragPtrI[1] = RNIL; m_accTableFragPtrI[0] = RNIL; m_accTableFragPtrI[1] = RNIL; } // Dbtux::FragOp inline Dbtux::FragOp::FragOp() : m_userPtr(RNIL), Loading @@ -997,11 +1082,12 @@ Dbtux::FragOp::FragOp() : { }; // Dbtux::NodeHandle inline Dbtux::NodeHandle::NodeHandle(Dbtux& tux, Frag& frag) : m_tux(tux), m_frag(frag), m_addr(NullTupAddr), m_loc(), m_acc(AccNone), m_flags(0), Loading @@ -1010,126 +1096,20 @@ Dbtux::NodeHandle::NodeHandle(Dbtux& tux, Frag& frag) : { } inline Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_state(Undef), m_lockwait(false), m_userPtr(RNIL), m_userRef(RNIL), m_tableId(RNIL), m_indexId(RNIL), m_fragPtrI(RNIL), m_transId1(0), m_transId2(0), m_savePointId(0), m_accLockOp(RNIL), m_readCommitted(0), m_lockMode(0), m_keyInfo(0), m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), m_lastEnt(), m_nodeScan(RNIL) { m_bound[0] = &m_boundMin; m_bound[1] = &m_boundMax; m_boundCnt[0] = 0; m_boundCnt[1] = 0; for (unsigned i = 0; i < MaxAccLockOps; i++) { m_accLockOps[i] = RNIL; } } inline Dbtux::CopyPar::CopyPar() : m_items(0), m_headers(true), m_maxwords(~0), // max unsigned // output m_numitems(0), m_numwords(0) { } inline Dbtux::ReadPar::ReadPar() : m_first(0), m_count(0), m_data(0), m_size(0) { } inline Dbtux::StorePar::StorePar() : m_opCode(TupStoreTh::OpUndefined), m_offset(0), m_size(0), m_errorCode(0) { } inline Dbtux::SearchPar::SearchPar() : m_data(0), m_ent() { } inline Dbtux::CmpPar::CmpPar() : m_data1(0), m_data2(0), m_len2(0), m_first(0), m_numEq(0) { } inline Dbtux::BoundPar::BoundPar() : m_data1(0), m_data2(0), m_count1(0), m_len2(0), m_dir(255) { } #ifdef VM_TRACE inline Dbtux::PrintPar::PrintPar() : // caller fills in m_path(), m_side(255), m_parent(NullTupAddr), // default return values m_depth(0), m_occup(0), m_ok(true) { } #endif // node handles inline Dbtux::TupAddr inline Dbtux::TupLoc Dbtux::NodeHandle::getLink(unsigned i) { ndbrequire(i <= 2); return m_node->m_link[i]; return TupLoc(m_node->m_linkPI[i], m_node->m_linkPO[i]); } inline unsigned Dbtux::NodeHandle::getChilds() { return (m_node->m_link[0] != NullTupAddr) + (m_node->m_link[1] != NullTupAddr); return (getLink(0) != NullTupLoc) + (getLink(1) != NullTupLoc); } inline Dbtux::TupAddr inline unsigned Dbtux::NodeHandle::getSide() { return m_node->m_side; Loading Loading @@ -1185,17 +1165,18 @@ Dbtux::NodeHandle::getMinMax(unsigned i) } inline void Dbtux::NodeHandle::setLink(unsigned i, TupAddr addr) Dbtux::NodeHandle::setLink(unsigned i, TupLoc loc) { ndbrequire(i <= 2); m_node->m_link[i] = addr; m_node->m_linkPI[i] = loc.m_pageId; m_node->m_linkPO[i] = loc.m_pageOffset; m_flags |= DoUpdate; } inline void Dbtux::NodeHandle::setSide(unsigned i) { // ndbrequire(i <= 1); ndbrequire(i <= 2); m_node->m_side = i; m_flags |= DoUpdate; } Loading Loading @@ -1224,6 +1205,79 @@ Dbtux::NodeHandle::setNodeScan(Uint32 scanPtrI) m_flags |= DoUpdate; } // parameters for methods inline Dbtux::CopyPar::CopyPar() : m_items(0), m_headers(true), m_maxwords(~0), // max unsigned // output m_numitems(0), m_numwords(0) { } inline Dbtux::ReadPar::ReadPar() : m_first(0), m_count(0), m_data(0), m_size(0) { } inline Dbtux::StorePar::StorePar() : m_opCode(TupStoreTh::OpUndefined), m_offset(0), m_size(0), m_errorCode(0) { } inline Dbtux::SearchPar::SearchPar() : m_data(0), m_ent() { } inline Dbtux::CmpPar::CmpPar() : m_data1(0), m_data2(0), m_len2(0), m_first(0), m_numEq(0) { } inline Dbtux::BoundPar::BoundPar() : m_data1(0), m_data2(0), m_count1(0), m_len2(0), m_dir(255) { } #ifdef VM_TRACE inline Dbtux::PrintPar::PrintPar() : // caller fills in m_path(), m_side(255), m_parent(), // default return values m_depth(0), m_occup(0), m_ok(true) { } #endif // other methods inline Dbtux::DescEnt& Loading Loading
ndb/include/kernel/signaldata/TupAccess.hpp +4 −2 Original line number Diff line number Diff line Loading @@ -129,6 +129,8 @@ private: /* * Operate on entire tuple. Used by TUX where the table has a single * Uint32 array attribute representing an index tree node. * * XXX this signal will be replaced by method in TUP */ class TupStoreTh { friend class Dbtup; Loading @@ -153,8 +155,8 @@ private: Uint32 tableId; Uint32 fragId; Uint32 fragPtrI; Uint32 tupAddr; Uint32 tupVersion; Uint32 tupAddr; // no longer used Uint32 tupVersion; // no longer used Uint32 pageId; Uint32 pageOffset; Uint32 bufferId; Loading
ndb/include/kernel/signaldata/TupFrag.hpp +4 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ class TuxFragReq { friend class Dblqh; friend class Dbtux; public: STATIC_CONST( SignalLength = 9 ); STATIC_CONST( SignalLength = 14 ); private: Uint32 userPtr; Uint32 userRef; Loading @@ -80,6 +80,9 @@ private: Uint32 fragOff; Uint32 tableType; Uint32 primaryTableId; Uint32 tupIndexFragPtrI; Uint32 tupTableFragPtrI[2]; Uint32 accTableFragPtrI[2]; }; class TuxFragConf { Loading
ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -2432,6 +2432,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal) } fragrecptr.i = req->fragPtrI; ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec); ndbrequire(req->fragId == fragrecptr.p->myfid); // caller must be explicit here ndbrequire(req->accOpPtr == RNIL); // seize operation to hold the lock Loading
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -1225,6 +1225,18 @@ Dblqh::sendAddFragReq(Signal* signal) tuxreq->fragOff = addfragptr.p->lh3DistrBits; tuxreq->tableType = addfragptr.p->tableType; tuxreq->primaryTableId = addfragptr.p->primaryTableId; // pointer to index fragment in TUP tuxreq->tupIndexFragPtrI = addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX ? fragptr.p->tupFragptr[0] : fragptr.p->tupFragptr[1]; // pointers to table fragments in TUP and ACC FragrecordPtr tFragPtr; tFragPtr.i = fragptr.p->tableFragptr; ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); tuxreq->tupTableFragPtrI[0] = tFragPtr.p->tupFragptr[0]; tuxreq->tupTableFragPtrI[1] = tFragPtr.p->tupFragptr[1]; tuxreq->accTableFragPtrI[0] = tFragPtr.p->accFragptr[0]; tuxreq->accTableFragPtrI[1] = tFragPtr.p->accFragptr[1]; sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, TuxFragReq::SignalLength, JBB); return; Loading
ndb/src/kernel/blocks/dbtux/Dbtux.hpp +231 −177 Original line number Diff line number Diff line Loading @@ -153,8 +153,7 @@ private: static const unsigned AttributeHeaderSize = 1; /* * Logical tuple address, "local key". Identifies both table tuples * and index tuples. The code assumes it is one word. * Logical tuple address, "local key". Identifies table tuples. */ typedef Uint32 TupAddr; static const unsigned NullTupAddr = (Uint32)-1; Loading @@ -168,8 +167,18 @@ private: Uint32 m_pageId; // page i-value Uint16 m_pageOffset; // page offset in words TupLoc(); TupLoc(Uint32 pageId, Uint16 pageOffset); bool operator==(const TupLoc& loc) const; bool operator!=(const TupLoc& loc) const; }; /* * There is no const variable NullTupLoc since the compiler may not be * able to optimize it to TupLoc() constants. Instead null values are * constructed on the stack with TupLoc(). */ #define NullTupLoc TupLoc() // tree definitions /* Loading @@ -183,7 +192,7 @@ private: TupAddr m_tupAddr; // address of original tuple Uint16 m_tupVersion; // version Uint8 m_fragBit; // which duplicated table fragment Uint8 unused1; Uint8 pad1; TreeEnt(); // methods int cmp(const TreeEnt ent) const; Loading @@ -196,7 +205,7 @@ private: * prefix 3) max and min entries 4) rest of entries 5) one extra entry * used as work space. * * struct TreeNode part 1 * struct TreeNode part 1, size 6 words * min prefix part 2, size TreeHead::m_prefSize * max prefix part 2, size TreeHead::m_prefSize * max entry part 3 Loading @@ -204,6 +213,10 @@ private: * rest of entries part 4 * work entry part 5 * * There are 3 links to other nodes: left child, right child, parent. * These are in TupLoc format but the pageIds and pageOffsets are * stored in separate arrays (saves 1 word). * * Occupancy (number of entries) is at least 1 except temporarily when * a node is about to be removed. If occupancy is 1, only max entry * is present but both min and max prefixes are set. Loading @@ -211,11 +224,12 @@ private: struct TreeNode; friend struct TreeNode; struct TreeNode { TupAddr m_link[3]; // link to 0-left child 1-right child 2-parent Uint8 m_side; // we are 0-left child 1-right child 2-root Uint32 m_linkPI[3]; // link to 0-left child 1-right child 2-parent Uint16 m_linkPO[3]; // page offsets for above real page ids unsigned m_side : 2; // we are 0-left child 1-right child 2-root int m_balance : 2; // balance -1, 0, +1 unsigned pad1 : 4; Uint8 m_occup; // current number of entries Int8 m_balance; // balance -1, 0, +1 Uint8 unused1; Uint32 m_nodeScan; // list of scans at this node TreeNode(); }; Loading Loading @@ -243,7 +257,7 @@ private: Uint8 m_prefSize; // words in min/max prefix each Uint8 m_minOccup; // min entries in internal node Uint8 m_maxOccup; // max entries in node TupAddr m_root; // root node TupLoc m_root; // root node TreeHead(); // methods unsigned getSize(AccSize acc) const; Loading @@ -261,8 +275,7 @@ private: struct TreePos; friend struct TreePos; struct TreePos { TupAddr m_addr; // logical node address TupLoc m_loc; // physical address TupLoc m_loc; // physical node address Uint16 m_pos; // position 0 to m_occup Uint8 m_match; // at an existing entry Uint8 m_dir; // from link (0-2) or within node (3) Loading Loading @@ -446,6 +459,9 @@ private: Uint32 m_nodeList; // node cache of current operation Uint32 m_nodeFree; // one node pre-allocated for insert DLList<ScanOp> m_scanList; // current scans on this fragment Uint32 m_tupIndexFragPtrI; Uint32 m_tupTableFragPtrI[2]; Uint32 m_accTableFragPtrI[2]; union { Uint32 nextPool; }; Loading Loading @@ -491,7 +507,6 @@ private: }; Dbtux& m_tux; // this block Frag& m_frag; // fragment using the node TupAddr m_addr; // logical node address TupLoc m_loc; // physical node address AccSize m_acc; // accessed size unsigned m_flags; // flags Loading @@ -503,7 +518,7 @@ private: Uint32 m_cache[MaxTreeNodeSize]; NodeHandle(Dbtux& tux, Frag& frag); // getters TupAddr getLink(unsigned i); TupLoc getLink(unsigned i); unsigned getChilds(); // cannot spell unsigned getSide(); unsigned getOccup(); Loading @@ -513,7 +528,7 @@ private: TreeEnt getEnt(unsigned pos); TreeEnt getMinMax(unsigned i); // setters void setLink(unsigned i, TupAddr addr); void setLink(unsigned i, TupLoc loc); void setSide(unsigned i); void setOccup(unsigned n); void setBalance(int b); Loading Loading @@ -649,8 +664,8 @@ private: */ void seizeNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr); void preallocNode(Signal* signal, Frag& frag, Uint32& errorCode); void findNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupAddr addr); void selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupAddr addr, AccSize acc); void findNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc); void selectNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, TupLoc loc, AccSize acc); void insertNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc); void deleteNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr); void accessNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, AccSize acc); Loading Loading @@ -698,23 +713,24 @@ private: struct PrintPar { char m_path[100]; // LR prefix unsigned m_side; // expected side TupAddr m_parent; // expected parent address TupLoc m_parent; // expected parent address int m_depth; // returned depth unsigned m_occup; // returned occupancy bool m_ok; // returned status PrintPar(); }; void printTree(Signal* signal, Frag& frag, NdbOut& out); void printNode(Signal* signal, Frag& frag, NdbOut& out, TupAddr addr, PrintPar& par); void printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par); friend class NdbOut& operator<<(NdbOut&, const TupLoc&); friend class NdbOut& operator<<(NdbOut&, const TreeEnt&); friend class NdbOut& operator<<(NdbOut&, const TreeNode&); friend class NdbOut& operator<<(NdbOut&, const TreeHead&); friend class NdbOut& operator<<(NdbOut&, const TreePos&); friend class NdbOut& operator<<(NdbOut&, const DescAttr&); friend class NdbOut& operator<<(NdbOut&, const ScanOp&); friend class NdbOut& operator<<(NdbOut&, const Index&); friend class NdbOut& operator<<(NdbOut&, const Frag&); friend class NdbOut& operator<<(NdbOut&, const NodeHandle&); friend class NdbOut& operator<<(NdbOut&, const ScanOp&); FILE* debugFile; NdbOut debugOut; unsigned debugFlags; Loading Loading @@ -831,8 +847,45 @@ Dbtux::ConstData::operator=(Data data) return *this; } // Dbtux::TupLoc inline Dbtux::TupLoc::TupLoc() : m_pageId(RNIL), m_pageOffset(0) { } inline Dbtux::TupLoc::TupLoc(Uint32 pageId, Uint16 pageOffset) : m_pageId(pageId), m_pageOffset(pageOffset) { } inline bool Dbtux::TupLoc::operator==(const TupLoc& loc) const { return m_pageId == loc.m_pageId && m_pageOffset == loc.m_pageOffset; } inline bool Dbtux::TupLoc::operator!=(const TupLoc& loc) const { return ! (*this == loc); } // Dbtux::TreeEnt inline Dbtux::TreeEnt::TreeEnt() : m_tupAddr(NullTupAddr), m_tupVersion(0), m_fragBit(255), pad1(0) { } inline int Dbtux::TreeEnt::cmp(const TreeEnt ent) const { Loading @@ -852,8 +905,36 @@ Dbtux::TreeEnt::cmp(const TreeEnt ent) const return 0; } // Dbtux::TreeNode inline Dbtux::TreeNode::TreeNode() : m_side(2), m_balance(0), pad1(0), m_occup(0), m_nodeScan(RNIL) { m_linkPI[0] = NullTupLoc.m_pageId; m_linkPO[0] = NullTupLoc.m_pageOffset; m_linkPI[1] = NullTupLoc.m_pageId; m_linkPO[1] = NullTupLoc.m_pageOffset; m_linkPI[2] = NullTupLoc.m_pageId; m_linkPO[2] = NullTupLoc.m_pageOffset; } // Dbtux::TreeHead inline Dbtux::TreeHead::TreeHead() : m_nodeSize(0), m_prefSize(0), m_minOccup(0), m_maxOccup(0), m_root() { } inline unsigned Dbtux::TreeHead::getSize(AccSize acc) const { Loading Loading @@ -885,52 +966,10 @@ Dbtux::TreeHead::getEntList(TreeNode* node) const return (TreeEnt*)ptr; } // Dbtux // constructors inline Dbtux::TupLoc::TupLoc() : m_pageId(RNIL), m_pageOffset(0) { } inline Dbtux::TreeEnt::TreeEnt() : m_tupAddr(NullTupAddr), m_tupVersion(0), m_fragBit(255), unused1(0) { } inline Dbtux::TreeNode::TreeNode() : m_side(255), m_occup(0), m_balance(0), unused1(0xa1), m_nodeScan(RNIL) { m_link[0] = NullTupAddr; m_link[1] = NullTupAddr; m_link[2] = NullTupAddr; } inline Dbtux::TreeHead::TreeHead() : m_nodeSize(0), m_prefSize(0), m_minOccup(0), m_maxOccup(0), m_root(0) { } // Dbtux::TreePos inline Dbtux::TreePos::TreePos() : m_addr(NullTupAddr), m_loc(), m_pos(ZNIL), m_match(false), Loading @@ -939,6 +978,8 @@ Dbtux::TreePos::TreePos() : { } // Dbtux::DescPage inline Dbtux::DescPage::DescPage() : m_nextPage(RNIL), Loading @@ -953,6 +994,41 @@ Dbtux::DescPage::DescPage() : } } // Dbtux::ScanOp inline Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_state(Undef), m_lockwait(false), m_userPtr(RNIL), m_userRef(RNIL), m_tableId(RNIL), m_indexId(RNIL), m_fragPtrI(RNIL), m_transId1(0), m_transId2(0), m_savePointId(0), m_accLockOp(RNIL), m_readCommitted(0), m_lockMode(0), m_keyInfo(0), m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), m_lastEnt(), m_nodeScan(RNIL) { m_bound[0] = &m_boundMin; m_bound[1] = &m_boundMax; m_boundCnt[0] = 0; m_boundCnt[1] = 0; for (unsigned i = 0; i < MaxAccLockOps; i++) { m_accLockOps[i] = RNIL; } } // Dbtux::Index inline Dbtux::Index::Index() : m_state(NotDefined), Loading @@ -969,6 +1045,8 @@ Dbtux::Index::Index() : }; }; // Dbtux::Frag inline Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) : m_tableId(RNIL), Loading @@ -981,10 +1059,17 @@ Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) : m_tree(), m_nodeList(RNIL), m_nodeFree(RNIL), m_scanList(scanOpPool) m_scanList(scanOpPool), m_tupIndexFragPtrI(RNIL) { m_tupTableFragPtrI[0] = RNIL; m_tupTableFragPtrI[1] = RNIL; m_accTableFragPtrI[0] = RNIL; m_accTableFragPtrI[1] = RNIL; } // Dbtux::FragOp inline Dbtux::FragOp::FragOp() : m_userPtr(RNIL), Loading @@ -997,11 +1082,12 @@ Dbtux::FragOp::FragOp() : { }; // Dbtux::NodeHandle inline Dbtux::NodeHandle::NodeHandle(Dbtux& tux, Frag& frag) : m_tux(tux), m_frag(frag), m_addr(NullTupAddr), m_loc(), m_acc(AccNone), m_flags(0), Loading @@ -1010,126 +1096,20 @@ Dbtux::NodeHandle::NodeHandle(Dbtux& tux, Frag& frag) : { } inline Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_state(Undef), m_lockwait(false), m_userPtr(RNIL), m_userRef(RNIL), m_tableId(RNIL), m_indexId(RNIL), m_fragPtrI(RNIL), m_transId1(0), m_transId2(0), m_savePointId(0), m_accLockOp(RNIL), m_readCommitted(0), m_lockMode(0), m_keyInfo(0), m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), m_lastEnt(), m_nodeScan(RNIL) { m_bound[0] = &m_boundMin; m_bound[1] = &m_boundMax; m_boundCnt[0] = 0; m_boundCnt[1] = 0; for (unsigned i = 0; i < MaxAccLockOps; i++) { m_accLockOps[i] = RNIL; } } inline Dbtux::CopyPar::CopyPar() : m_items(0), m_headers(true), m_maxwords(~0), // max unsigned // output m_numitems(0), m_numwords(0) { } inline Dbtux::ReadPar::ReadPar() : m_first(0), m_count(0), m_data(0), m_size(0) { } inline Dbtux::StorePar::StorePar() : m_opCode(TupStoreTh::OpUndefined), m_offset(0), m_size(0), m_errorCode(0) { } inline Dbtux::SearchPar::SearchPar() : m_data(0), m_ent() { } inline Dbtux::CmpPar::CmpPar() : m_data1(0), m_data2(0), m_len2(0), m_first(0), m_numEq(0) { } inline Dbtux::BoundPar::BoundPar() : m_data1(0), m_data2(0), m_count1(0), m_len2(0), m_dir(255) { } #ifdef VM_TRACE inline Dbtux::PrintPar::PrintPar() : // caller fills in m_path(), m_side(255), m_parent(NullTupAddr), // default return values m_depth(0), m_occup(0), m_ok(true) { } #endif // node handles inline Dbtux::TupAddr inline Dbtux::TupLoc Dbtux::NodeHandle::getLink(unsigned i) { ndbrequire(i <= 2); return m_node->m_link[i]; return TupLoc(m_node->m_linkPI[i], m_node->m_linkPO[i]); } inline unsigned Dbtux::NodeHandle::getChilds() { return (m_node->m_link[0] != NullTupAddr) + (m_node->m_link[1] != NullTupAddr); return (getLink(0) != NullTupLoc) + (getLink(1) != NullTupLoc); } inline Dbtux::TupAddr inline unsigned Dbtux::NodeHandle::getSide() { return m_node->m_side; Loading Loading @@ -1185,17 +1165,18 @@ Dbtux::NodeHandle::getMinMax(unsigned i) } inline void Dbtux::NodeHandle::setLink(unsigned i, TupAddr addr) Dbtux::NodeHandle::setLink(unsigned i, TupLoc loc) { ndbrequire(i <= 2); m_node->m_link[i] = addr; m_node->m_linkPI[i] = loc.m_pageId; m_node->m_linkPO[i] = loc.m_pageOffset; m_flags |= DoUpdate; } inline void Dbtux::NodeHandle::setSide(unsigned i) { // ndbrequire(i <= 1); ndbrequire(i <= 2); m_node->m_side = i; m_flags |= DoUpdate; } Loading Loading @@ -1224,6 +1205,79 @@ Dbtux::NodeHandle::setNodeScan(Uint32 scanPtrI) m_flags |= DoUpdate; } // parameters for methods inline Dbtux::CopyPar::CopyPar() : m_items(0), m_headers(true), m_maxwords(~0), // max unsigned // output m_numitems(0), m_numwords(0) { } inline Dbtux::ReadPar::ReadPar() : m_first(0), m_count(0), m_data(0), m_size(0) { } inline Dbtux::StorePar::StorePar() : m_opCode(TupStoreTh::OpUndefined), m_offset(0), m_size(0), m_errorCode(0) { } inline Dbtux::SearchPar::SearchPar() : m_data(0), m_ent() { } inline Dbtux::CmpPar::CmpPar() : m_data1(0), m_data2(0), m_len2(0), m_first(0), m_numEq(0) { } inline Dbtux::BoundPar::BoundPar() : m_data1(0), m_data2(0), m_count1(0), m_len2(0), m_dir(255) { } #ifdef VM_TRACE inline Dbtux::PrintPar::PrintPar() : // caller fills in m_path(), m_side(255), m_parent(), // default return values m_depth(0), m_occup(0), m_ok(true) { } #endif // other methods inline Dbtux::DescEnt& Loading