Dbtux.hpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:32k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #ifndef DBTUX_H
  14. #define DBTUX_H
  15. #include <ndb_limits.h>
  16. #include <SimulatedBlock.hpp>
  17. #include <AttributeDescriptor.hpp>
  18. #include <AttributeHeader.hpp>
  19. #include <ArrayPool.hpp>
  20. #include <DataBuffer.hpp>
  21. #include <md5_hash.hpp>
  22. // big brother
  23. #include <Dbtup.hpp>
  24. // signal classes
  25. #include <signaldata/DictTabInfo.hpp>
  26. #include <signaldata/TuxContinueB.hpp>
  27. #include <signaldata/TupFrag.hpp>
  28. #include <signaldata/AlterIndx.hpp>
  29. #include <signaldata/DropTab.hpp>
  30. #include <signaldata/TuxMaint.hpp>
  31. #include <signaldata/AccScan.hpp>
  32. #include <signaldata/TuxBound.hpp>
  33. #include <signaldata/NextScan.hpp>
  34. #include <signaldata/AccLock.hpp>
  35. #include <signaldata/DumpStateOrd.hpp>
  36. // debug
  37. #ifdef VM_TRACE
  38. #include <NdbOut.hpp>
  39. #include <OutputStream.hpp>
  40. #endif
  41. // jams
  42. #undef jam
  43. #undef jamEntry
  44. #ifdef DBTUX_GEN_CPP
  45. #define jam()           jamLine(10000 + __LINE__)
  46. #define jamEntry()      jamEntryLine(10000 + __LINE__)
  47. #endif
  48. #ifdef DBTUX_META_CPP
  49. #define jam()           jamLine(20000 + __LINE__)
  50. #define jamEntry()      jamEntryLine(20000 + __LINE__)
  51. #endif
  52. #ifdef DBTUX_MAINT_CPP
  53. #define jam()           jamLine(30000 + __LINE__)
  54. #define jamEntry()      jamEntryLine(30000 + __LINE__)
  55. #endif
  56. #ifdef DBTUX_NODE_CPP
  57. #define jam()           jamLine(40000 + __LINE__)
  58. #define jamEntry()      jamEntryLine(40000 + __LINE__)
  59. #endif
  60. #ifdef DBTUX_TREE_CPP
  61. #define jam()           jamLine(50000 + __LINE__)
  62. #define jamEntry()      jamEntryLine(50000 + __LINE__)
  63. #endif
  64. #ifdef DBTUX_SCAN_CPP
  65. #define jam()           jamLine(60000 + __LINE__)
  66. #define jamEntry()      jamEntryLine(60000 + __LINE__)
  67. #endif
  68. #ifdef DBTUX_SEARCH_CPP
  69. #define jam()           jamLine(70000 + __LINE__)
  70. #define jamEntry()      jamEntryLine(70000 + __LINE__)
  71. #endif
  72. #ifdef DBTUX_CMP_CPP
  73. #define jam()           jamLine(80000 + __LINE__)
  74. #define jamEntry()      jamEntryLine(80000 + __LINE__)
  75. #endif
  76. #ifdef DBTUX_DEBUG_CPP
  77. #define jam()           jamLine(90000 + __LINE__)
  78. #define jamEntry()      jamEntryLine(90000 + __LINE__)
  79. #endif
  80. #ifndef jam
  81. #define jam()           jamLine(__LINE__)
  82. #define jamEntry()      jamEntryLine(__LINE__)
  83. #endif
  84. #undef max
  85. #undef min
  86. class Configuration;
  87. class Dbtux : public SimulatedBlock {
  88. public:
  89.   Dbtux(const Configuration& conf);
  90.   virtual ~Dbtux();
  91.   // pointer to TUP instance in this thread
  92.   Dbtup* c_tup;
  93. private:
  94.   // sizes are in words (Uint32)
  95.   STATIC_CONST( MaxIndexFragments = 2 * MAX_FRAG_PER_NODE );
  96.   STATIC_CONST( MaxIndexAttributes = MAX_ATTRIBUTES_IN_INDEX );
  97.   STATIC_CONST( MaxAttrDataSize = 2048 );
  98. public:
  99.   STATIC_CONST( DescPageSize = 256 );
  100. private:
  101.   STATIC_CONST( MaxTreeNodeSize = MAX_TTREE_NODE_SIZE );
  102.   STATIC_CONST( MaxPrefSize = MAX_TTREE_PREF_SIZE );
  103.   STATIC_CONST( ScanBoundSegmentSize = 7 );
  104.   STATIC_CONST( MaxAccLockOps = MAX_PARALLEL_OP_PER_SCAN );
  105.   BLOCK_DEFINES(Dbtux);
  106.   // forward declarations
  107.   struct DescEnt;
  108.   /*
  109.    * Pointer to array of Uint32.
  110.    */
  111.   struct Data {
  112.   private:
  113.     Uint32* m_data;
  114.   public:
  115.     Data();
  116.     Data(Uint32* data);
  117.     Data& operator=(Uint32* data);
  118.     operator Uint32*() const;
  119.     Data& operator+=(size_t n);
  120.     AttributeHeader& ah() const;
  121.   };
  122.   friend class Data;
  123.   /*
  124.    * Pointer to array of constant Uint32.
  125.    */
  126.   struct ConstData;
  127.   friend struct ConstData;
  128.   struct ConstData {
  129.   private:
  130.     const Uint32* m_data;
  131.   public:
  132.     ConstData();
  133.     ConstData(const Uint32* data);
  134.     ConstData& operator=(const Uint32* data);
  135.     operator const Uint32*() const;
  136.     ConstData& operator+=(size_t n);
  137.     const AttributeHeader& ah() const;
  138.     // non-const pointer can be cast to const pointer
  139.     ConstData(Data data);
  140.     ConstData& operator=(Data data);
  141.   };
  142.   // AttributeHeader size is assumed to be 1 word
  143.   STATIC_CONST( AttributeHeaderSize = 1 );
  144.   /*
  145.    * Logical tuple address, "local key".  Identifies table tuples.
  146.    */
  147.   typedef Uint32 TupAddr;
  148.   STATIC_CONST( NullTupAddr = (Uint32)-1 );
  149.   /*
  150.    * Physical tuple address in TUP.  Provides fast access to table tuple
  151.    * or index node.  Valid within the db node and across timeslices.
  152.    * Not valid between db nodes or across restarts.
  153.    *
  154.    * To avoid wasting an Uint16 the pageid is split in two.
  155.    */
  156.   struct TupLoc {
  157.   private:
  158.     Uint16 m_pageId1;           // page i-value (big-endian)
  159.     Uint16 m_pageId2;
  160.     Uint16 m_pageOffset;        // page offset in words
  161.   public:
  162.     TupLoc();
  163.     TupLoc(Uint32 pageId, Uint16 pageOffset);
  164.     Uint32 getPageId() const;
  165.     void setPageId(Uint32 pageId);
  166.     Uint32 getPageOffset() const;
  167.     void setPageOffset(Uint32 pageOffset);
  168.     bool operator==(const TupLoc& loc) const;
  169.     bool operator!=(const TupLoc& loc) const;
  170.   };
  171.   /*
  172.    * There is no const member NullTupLoc since the compiler may not be
  173.    * able to optimize it to TupLoc() constants.  Instead null values are
  174.    * constructed on the stack with TupLoc().
  175.    */
  176. #define NullTupLoc TupLoc()
  177.   // tree definitions
  178.   /*
  179.    * Tree entry.  Points to a tuple in primary table via physical
  180.    * address of "original" tuple and tuple version.
  181.    *
  182.    * ZTUP_VERSION_BITS must be 15 (or less).
  183.    */
  184.   struct TreeEnt;
  185.   friend struct TreeEnt;
  186.   struct TreeEnt {
  187.     TupLoc m_tupLoc;            // address of original tuple
  188.     unsigned m_tupVersion : 15; // version
  189.     unsigned m_fragBit : 1;     // which duplicated table fragment
  190.     TreeEnt();
  191.     // methods
  192.     bool eq(const TreeEnt ent) const;
  193.     int cmp(const TreeEnt ent) const;
  194.   };
  195.   STATIC_CONST( TreeEntSize = sizeof(TreeEnt) >> 2 );
  196.   static const TreeEnt NullTreeEnt;
  197.   /*
  198.    * Tree node has 1) fixed part 2) a prefix of index key data for min
  199.    * entry 3) max and min entries 4) rest of entries 5) one extra entry
  200.    * used as work space.
  201.    *
  202.    * struct TreeNode            part 1, size 6 words
  203.    * min prefix                 part 2, size TreeHead::m_prefSize
  204.    * max entry                  part 3
  205.    * min entry                  part 3
  206.    * rest of entries            part 4
  207.    * work entry                 part 5
  208.    *
  209.    * There are 3 links to other nodes: left child, right child, parent.
  210.    * Occupancy (number of entries) is at least 1 except temporarily when
  211.    * a node is about to be removed.
  212.    */
  213.   struct TreeNode;
  214.   friend struct TreeNode;
  215.   struct TreeNode {
  216.     TupLoc m_link[3];           // link to 0-left child 1-right child 2-parent
  217.     unsigned m_side : 2;        // we are 0-left child 1-right child 2-root
  218.     unsigned m_balance : 2;     // balance -1, 0, +1 plus 1 for Solaris CC
  219.     unsigned pad1 : 4;
  220.     Uint8 m_occup;              // current number of entries
  221.     Uint32 m_nodeScan;          // list of scans at this node
  222.     TreeNode();
  223.   };
  224.   STATIC_CONST( NodeHeadSize = sizeof(TreeNode) >> 2 );
  225.   /*
  226.    * Tree node "access size" was for an early version with signal
  227.    * interface to TUP.  It is now used only to compute sizes.
  228.    */
  229.   enum AccSize {
  230.     AccNone = 0,
  231.     AccHead = 1,                // part 1
  232.     AccPref = 2,                // parts 1-3
  233.     AccFull = 3                 // parts 1-5
  234.   };
  235.   /*
  236.    * Tree header.  There is one in each fragment.  Contains tree
  237.    * parameters and address of root node.
  238.    */
  239.   struct TreeHead;
  240.   friend struct TreeHead;
  241.   struct TreeHead {
  242.     Uint8 m_nodeSize;           // words in tree node
  243.     Uint8 m_prefSize;           // words in min prefix
  244.     Uint8 m_minOccup;           // min entries in internal node
  245.     Uint8 m_maxOccup;           // max entries in node
  246.     TupLoc m_root;              // root node
  247.     TreeHead();
  248.     // methods
  249.     unsigned getSize(AccSize acc) const;
  250.     Data getPref(TreeNode* node) const;
  251.     TreeEnt* getEntList(TreeNode* node) const;
  252.   };
  253.   /*
  254.    * Tree position.  Specifies node, position within node (from 0 to
  255.    * m_occup), and whether the position is at an existing entry or
  256.    * before one (if any).  Position m_occup points past the node and is
  257.    * also represented by position 0 of next node.  Includes direction
  258.    * used by scan.
  259.    */
  260.   struct TreePos;
  261.   friend struct TreePos;
  262.   struct TreePos {
  263.     TupLoc m_loc;               // physical node address
  264.     Uint16 m_pos;               // position 0 to m_occup
  265.     Uint8 m_match;              // at an existing entry
  266.     Uint8 m_dir;                // see scanNext()
  267.     TreePos();
  268.   };
  269.   // packed metadata
  270.   /*
  271.    * Descriptor page.  The "hot" metadata for an index is stored as
  272.    * a contiguous array of words on some page.
  273.    */
  274.   struct DescPage;
  275.   friend struct DescPage;
  276.   struct DescPage {
  277.     Uint32 m_nextPage;
  278.     Uint32 m_numFree;           // number of free words
  279.     union {
  280.     Uint32 m_data[DescPageSize];
  281.     Uint32 nextPool;
  282.     };
  283.     DescPage();
  284.   };
  285.   typedef Ptr<DescPage> DescPagePtr;
  286.   ArrayPool<DescPage> c_descPagePool;
  287.   Uint32 c_descPageList;
  288.   /*
  289.    * Header for index metadata.  Size must be multiple of word size.
  290.    */
  291.   struct DescHead {
  292.     unsigned m_indexId : 24;
  293.     unsigned pad1 : 8;
  294.   };
  295.   STATIC_CONST( DescHeadSize = sizeof(DescHead) >> 2 );
  296.   /*
  297.    * Attribute metadata.  Size must be multiple of word size.
  298.    *
  299.    * Prefix comparison of char data must use strxfrm and binary
  300.    * comparison.  The charset is currently unused.
  301.    */
  302.   struct DescAttr {
  303.     Uint32 m_attrDesc;          // standard AttributeDescriptor
  304.     Uint16 m_primaryAttrId;
  305.     unsigned m_typeId : 6;
  306.     unsigned m_charset : 10;
  307.   };
  308.   STATIC_CONST( DescAttrSize = sizeof(DescAttr) >> 2 );
  309.   /*
  310.    * Complete metadata for one index. The array of attributes has
  311.    * variable size.
  312.    */
  313.   friend struct DescEnt;
  314.   struct DescEnt {
  315.     DescHead m_descHead;
  316.     DescAttr m_descAttr[1];     // variable size data
  317.   };
  318.   // range scan
  319.  
  320.   /*
  321.    * Scan bounds are stored in linked list of segments.
  322.    */
  323.   typedef DataBuffer<ScanBoundSegmentSize> ScanBound;
  324.   typedef DataBuffer<ScanBoundSegmentSize>::ConstDataBufferIterator ScanBoundIterator;
  325.   typedef DataBuffer<ScanBoundSegmentSize>::DataBufferPool ScanBoundPool;
  326.   ScanBoundPool c_scanBoundPool;
  327.  
  328.   /*
  329.    * Scan operation.
  330.    *
  331.    * Tuples are locked one at a time.  The current lock op is set to
  332.    * RNIL as soon as the lock is obtained and passed to LQH.  We must
  333.    * however remember all locks which LQH has not returned for unlocking
  334.    * since they must be aborted by us when the scan is closed.
  335.    *
  336.    * Scan state describes the entry we are interested in.  There is
  337.    * a separate lock wait flag.  It may be for current entry or it may
  338.    * be for an entry we were moved away from.  In any case nothing
  339.    * happens with current entry before lock wait flag is cleared.
  340.    *
  341.    * An unfinished scan is always linked to some tree node, and has
  342.    * current position and direction (see comments at scanNext).  There
  343.    * is also a copy of latest entry found.
  344.    */
  345.   struct ScanOp;
  346.   friend struct ScanOp;
  347.   struct ScanOp {
  348.     enum {
  349.       Undef = 0,
  350.       First = 1,                // before first entry
  351.       Current = 2,              // at current before locking
  352.       Blocked = 3,              // at current waiting for ACC lock
  353.       Locked = 4,               // at current and locked or no lock needed
  354.       Next = 5,                 // looking for next extry
  355.       Last = 6,                 // after last entry
  356.       Aborting = 7,             // lock wait at scan close
  357.       Invalid = 9               // cannot return REF to LQH currently
  358.     };
  359.     Uint16 m_state;
  360.     Uint16 m_lockwait;
  361.     Uint32 m_userPtr;           // scanptr.i in LQH
  362.     Uint32 m_userRef;
  363.     Uint32 m_tableId;
  364.     Uint32 m_indexId;
  365.     Uint32 m_fragId;
  366.     Uint32 m_fragPtrI;
  367.     Uint32 m_transId1;
  368.     Uint32 m_transId2;
  369.     Uint32 m_savePointId;
  370.     // lock waited for or obtained and not yet passed to LQH
  371.     Uint32 m_accLockOp;
  372.     Uint8 m_readCommitted;      // no locking
  373.     Uint8 m_lockMode;
  374.     Uint8 m_keyInfo;
  375.     ScanBound m_boundMin;
  376.     ScanBound m_boundMax;
  377.     ScanBound* m_bound[2];      // pointers to above 2
  378.     Uint16 m_boundCnt[2];       // number of bounds in each
  379.     TreePos m_scanPos;          // position
  380.     TreeEnt m_scanEnt;          // latest entry found
  381.     Uint32 m_nodeScan;          // next scan at node (single-linked)
  382.     union {
  383.     Uint32 nextPool;
  384.     Uint32 nextList;
  385.     };
  386.     Uint32 prevList;
  387.     /*
  388.      * Locks obtained and passed to LQH but not yet returned by LQH.
  389.      * The max was increased from 16 to 992 (default 64).  Record max
  390.      * ever used in this scan.  TODO fix quadratic behaviour
  391.      */
  392.     Uint32 m_maxAccLockOps;
  393.     Uint32 m_accLockOps[MaxAccLockOps];
  394.     ScanOp(ScanBoundPool& scanBoundPool);
  395.   };
  396.   typedef Ptr<ScanOp> ScanOpPtr;
  397.   ArrayPool<ScanOp> c_scanOpPool;
  398.   // indexes and fragments
  399.   /*
  400.    * Ordered index.  Top level data structure.  The primary table (table
  401.    * being indexed) lives in TUP.
  402.    */
  403.   struct Index;
  404.   friend struct Index;
  405.   struct Index {
  406.     enum State {
  407.       NotDefined = 0,
  408.       Defining = 1,
  409.       Online = 2,               // triggers activated and build done
  410.       Dropping = 9
  411.     };
  412.     State m_state;
  413.     DictTabInfo::TableType m_tableType;
  414.     Uint32 m_tableId;
  415.     Uint16 m_fragOff;           // offset for duplicate fragId bits
  416.     Uint16 m_numFrags;
  417.     Uint32 m_fragId[MaxIndexFragments];
  418.     Uint32 m_fragPtrI[MaxIndexFragments];
  419.     Uint32 m_descPage;          // descriptor page
  420.     Uint16 m_descOff;           // offset within the page
  421.     Uint16 m_numAttrs;
  422.     bool m_storeNullKey;
  423.     union {
  424.     Uint32 nextPool;
  425.     };
  426.     Index();
  427.   };
  428.   typedef Ptr<Index> IndexPtr;
  429.   ArrayPool<Index> c_indexPool;
  430.   /*
  431.    * Fragment of an index, as known to DIH/TC.  Represents the two
  432.    * duplicate fragments known to LQH/ACC/TUP.  Includes tree header.
  433.    * There are no maintenance operation records yet.
  434.    */
  435.   struct Frag;
  436.   friend struct Frag;
  437.   struct Frag {
  438.     Uint32 m_tableId;           // copy from index level
  439.     Uint32 m_indexId;
  440.     Uint16 m_fragOff;
  441.     Uint16 m_fragId;
  442.     Uint32 m_descPage;          // copy from index level
  443.     Uint16 m_descOff;
  444.     Uint16 m_numAttrs;
  445.     bool m_storeNullKey;
  446.     TreeHead m_tree;
  447.     TupLoc m_freeLoc;           // list of free index nodes
  448.     DLList<ScanOp> m_scanList;  // current scans on this fragment
  449.     Uint32 m_tupIndexFragPtrI;
  450.     Uint32 m_tupTableFragPtrI[2];
  451.     Uint32 m_accTableFragPtrI[2];
  452.     union {
  453.     Uint32 nextPool;
  454.     };
  455.     Frag(ArrayPool<ScanOp>& scanOpPool);
  456.   };
  457.   typedef Ptr<Frag> FragPtr;
  458.   ArrayPool<Frag> c_fragPool;
  459.   /*
  460.    * Fragment metadata operation.
  461.    */
  462.   struct FragOp {
  463.     Uint32 m_userPtr;
  464.     Uint32 m_userRef;
  465.     Uint32 m_indexId;
  466.     Uint32 m_fragId;
  467.     Uint32 m_fragPtrI;
  468.     Uint32 m_fragNo;            // fragment number starting at zero
  469.     Uint32 m_numAttrsRecvd;
  470.     union {
  471.     Uint32 nextPool;
  472.     };
  473.     FragOp();
  474.   };
  475.   typedef Ptr<FragOp> FragOpPtr;
  476.   ArrayPool<FragOp> c_fragOpPool;
  477.   // node handles
  478.   /*
  479.    * A node handle is a reference to a tree node in TUP.  It is used to
  480.    * operate on the node.  Node handles are allocated on the stack.
  481.    */
  482.   struct NodeHandle;
  483.   friend struct NodeHandle;
  484.   struct NodeHandle {
  485.     Frag& m_frag;               // fragment using the node
  486.     TupLoc m_loc;               // physical node address
  487.     TreeNode* m_node;           // pointer to node storage
  488.     NodeHandle(Frag& frag);
  489.     NodeHandle(const NodeHandle& node);
  490.     NodeHandle& operator=(const NodeHandle& node);
  491.     // check if unassigned
  492.     bool isNull();
  493.     // getters
  494.     TupLoc getLink(unsigned i);
  495.     unsigned getChilds();       // cannot spell
  496.     unsigned getSide();
  497.     unsigned getOccup();
  498.     int getBalance();
  499.     Uint32 getNodeScan();
  500.     // setters
  501.     void setLink(unsigned i, TupLoc loc);
  502.     void setSide(unsigned i);
  503.     void setOccup(unsigned n);
  504.     void setBalance(int b);
  505.     void setNodeScan(Uint32 scanPtrI);
  506.     // access other parts of the node
  507.     Data getPref();
  508.     TreeEnt getEnt(unsigned pos);
  509.     TreeEnt getMinMax(unsigned i);
  510.     // for ndbrequire and ndbassert
  511.     void progError(int line, int cause, const char* file);
  512.   };
  513.   // methods
  514.   /*
  515.    * DbtuxGen.cpp
  516.    */
  517.   void execCONTINUEB(Signal* signal);
  518.   void execSTTOR(Signal* signal);
  519.   void execREAD_CONFIG_REQ(Signal* signal);
  520.   // utils
  521.   void setKeyAttrs(const Frag& frag);
  522.   void readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData);
  523.   void readTablePk(const Frag& frag, TreeEnt ent, Data pkData, unsigned& pkSize);
  524.   void copyAttrs(const Frag& frag, ConstData data1, Data data2, unsigned maxlen2 = MaxAttrDataSize);
  525.   /*
  526.    * DbtuxMeta.cpp
  527.    */
  528.   void execTUXFRAGREQ(Signal* signal);
  529.   void execTUX_ADD_ATTRREQ(Signal* signal);
  530.   void execALTER_INDX_REQ(Signal* signal);
  531.   void execDROP_TAB_REQ(Signal* signal);
  532.   bool allocDescEnt(IndexPtr indexPtr);
  533.   void freeDescEnt(IndexPtr indexPtr);
  534.   void abortAddFragOp(Signal* signal);
  535.   void dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 senderData);
  536.   /*
  537.    * DbtuxMaint.cpp
  538.    */
  539.   void execTUX_MAINT_REQ(Signal* signal);
  540.   
  541.   /*
  542.    * DbtuxNode.cpp
  543.    */
  544.   int allocNode(Signal* signal, NodeHandle& node);
  545.   void selectNode(NodeHandle& node, TupLoc loc);
  546.   void insertNode(NodeHandle& node);
  547.   void deleteNode(NodeHandle& node);
  548.   void setNodePref(NodeHandle& node);
  549.   // node operations
  550.   void nodePushUp(NodeHandle& node, unsigned pos, const TreeEnt& ent, Uint32 scanList);
  551.   void nodePushUpScans(NodeHandle& node, unsigned pos);
  552.   void nodePopDown(NodeHandle& node, unsigned pos, TreeEnt& en, Uint32* scanList);
  553.   void nodePopDownScans(NodeHandle& node, unsigned pos);
  554.   void nodePushDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32& scanList);
  555.   void nodePushDownScans(NodeHandle& node, unsigned pos);
  556.   void nodePopUp(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32 scanList);
  557.   void nodePopUpScans(NodeHandle& node, unsigned pos);
  558.   void nodeSlide(NodeHandle& dstNode, NodeHandle& srcNode, unsigned cnt, unsigned i);
  559.   // scans linked to node
  560.   void addScanList(NodeHandle& node, unsigned pos, Uint32 scanList);
  561.   void removeScanList(NodeHandle& node, unsigned pos, Uint32& scanList);
  562.   void moveScanList(NodeHandle& node, unsigned pos);
  563.   void linkScan(NodeHandle& node, ScanOpPtr scanPtr);
  564.   void unlinkScan(NodeHandle& node, ScanOpPtr scanPtr);
  565.   bool islinkScan(NodeHandle& node, ScanOpPtr scanPtr);
  566.   /*
  567.    * DbtuxTree.cpp
  568.    */
  569.   // add entry
  570.   void treeAdd(Frag& frag, TreePos treePos, TreeEnt ent);
  571.   void treeAddFull(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent);
  572.   void treeAddNode(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent, NodeHandle parentNode, unsigned i);
  573.   void treeAddRebalance(Frag& frag, NodeHandle node, unsigned i);
  574.   // remove entry
  575.   void treeRemove(Frag& frag, TreePos treePos);
  576.   void treeRemoveInner(Frag& frag, NodeHandle lubNode, unsigned pos);
  577.   void treeRemoveSemi(Frag& frag, NodeHandle node, unsigned i);
  578.   void treeRemoveLeaf(Frag& frag, NodeHandle node);
  579.   void treeRemoveNode(Frag& frag, NodeHandle node);
  580.   void treeRemoveRebalance(Frag& frag, NodeHandle node, unsigned i);
  581.   // rotate
  582.   void treeRotateSingle(Frag& frag, NodeHandle& node, unsigned i);
  583.   void treeRotateDouble(Frag& frag, NodeHandle& node, unsigned i);
  584.   /*
  585.    * DbtuxScan.cpp
  586.    */
  587.   void execACC_SCANREQ(Signal* signal);
  588.   void execTUX_BOUND_INFO(Signal* signal);
  589.   void execNEXT_SCANREQ(Signal* signal);
  590.   void execACC_CHECK_SCAN(Signal* signal);
  591.   void execACCKEYCONF(Signal* signal);
  592.   void execACCKEYREF(Signal* signal);
  593.   void execACC_ABORTCONF(Signal* signal);
  594.   void scanFirst(ScanOpPtr scanPtr);
  595.   void scanNext(ScanOpPtr scanPtr);
  596.   bool scanVisible(ScanOpPtr scanPtr, TreeEnt ent);
  597.   void scanClose(Signal* signal, ScanOpPtr scanPtr);
  598.   void addAccLockOp(ScanOp& scan, Uint32 accLockOp);
  599.   void removeAccLockOp(ScanOp& scan, Uint32 accLockOp);
  600.   void releaseScanOp(ScanOpPtr& scanPtr);
  601.   /*
  602.    * DbtuxSearch.cpp
  603.    */
  604.   void searchToAdd(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos);
  605.   void searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos);
  606.   void searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos);
  607.   /*
  608.    * DbtuxCmp.cpp
  609.    */
  610.   int cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen = MaxAttrDataSize);
  611.   int cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen = MaxAttrDataSize);
  612.   /*
  613.    * DbtuxDebug.cpp
  614.    */
  615.   void execDUMP_STATE_ORD(Signal* signal);
  616. #ifdef VM_TRACE
  617.   struct PrintPar {
  618.     char m_path[100];           // LR prefix
  619.     unsigned m_side;            // expected side
  620.     TupLoc m_parent;            // expected parent address
  621.     int m_depth;                // returned depth
  622.     unsigned m_occup;           // returned occupancy
  623.     TreeEnt m_minmax[2];        // returned subtree min and max
  624.     bool m_ok;                  // returned status
  625.     PrintPar();
  626.   };
  627.   void printTree(Signal* signal, Frag& frag, NdbOut& out);
  628.   void printNode(Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par);
  629.   friend class NdbOut& operator<<(NdbOut&, const TupLoc&);
  630.   friend class NdbOut& operator<<(NdbOut&, const TreeEnt&);
  631.   friend class NdbOut& operator<<(NdbOut&, const TreeNode&);
  632.   friend class NdbOut& operator<<(NdbOut&, const TreeHead&);
  633.   friend class NdbOut& operator<<(NdbOut&, const TreePos&);
  634.   friend class NdbOut& operator<<(NdbOut&, const DescAttr&);
  635.   friend class NdbOut& operator<<(NdbOut&, const ScanOp&);
  636.   friend class NdbOut& operator<<(NdbOut&, const Index&);
  637.   friend class NdbOut& operator<<(NdbOut&, const Frag&);
  638.   friend class NdbOut& operator<<(NdbOut&, const FragOp&);
  639.   friend class NdbOut& operator<<(NdbOut&, const NodeHandle&);
  640.   FILE* debugFile;
  641.   NdbOut debugOut;
  642.   unsigned debugFlags;
  643.   enum {
  644.     DebugMeta = 1,              // log create and drop index
  645.     DebugMaint = 2,             // log maintenance ops
  646.     DebugTree = 4,              // log and check tree after each op
  647.     DebugScan = 8               // log scans
  648.   };
  649.   STATIC_CONST( DataFillByte = 0xa2 );
  650.   STATIC_CONST( NodeFillByte = 0xa4 );
  651. #endif
  652.   // start up info
  653.   Uint32 c_internalStartPhase;
  654.   Uint32 c_typeOfStart;
  655.   /*
  656.    * Global data set at operation start.  Unpacked from index metadata.
  657.    * Not passed as parameter to methods.  Invalid across timeslices.
  658.    *
  659.    * TODO inline all into index metadata
  660.    */
  661.   // index key attr ids with sizes in AttributeHeader format
  662.   Data c_keyAttrs;
  663.   // pointers to index key comparison functions
  664.   NdbSqlUtil::Cmp** c_sqlCmp;
  665.   /*
  666.    * Other buffers used during the operation.
  667.    */
  668.   // buffer for search key data with headers
  669.   Data c_searchKey;
  670.   // buffer for current entry key data with headers
  671.   Data c_entryKey;
  672.   // buffer for scan bounds and keyinfo (primary key)
  673.   Data c_dataBuffer;
  674.   // inlined utils
  675.   DescEnt& getDescEnt(Uint32 descPage, Uint32 descOff);
  676.   Uint32 getTupAddr(const Frag& frag, TreeEnt ent);
  677.   static unsigned min(unsigned x, unsigned y);
  678.   static unsigned max(unsigned x, unsigned y);
  679. };
  680. // Dbtux::Data
  681. inline
  682. Dbtux::Data::Data() :
  683.   m_data(0)
  684. {
  685. }
  686. inline
  687. Dbtux::Data::Data(Uint32* data) :
  688.   m_data(data)
  689. {
  690. }
  691. inline Dbtux::Data&
  692. Dbtux::Data::operator=(Uint32* data)
  693. {
  694.   m_data = data;
  695.   return *this;
  696. }
  697. inline
  698. Dbtux::Data::operator Uint32*() const
  699. {
  700.   return m_data;
  701. }
  702. inline Dbtux::Data&
  703. Dbtux::Data::operator+=(size_t n)
  704. {
  705.   m_data += n;
  706.   return *this;
  707. }
  708. inline AttributeHeader&
  709. Dbtux::Data::ah() const
  710. {
  711.   return *reinterpret_cast<AttributeHeader*>(m_data);
  712. }
  713. // Dbtux::ConstData
  714. inline
  715. Dbtux::ConstData::ConstData() :
  716.   m_data(0)
  717. {
  718. }
  719. inline
  720. Dbtux::ConstData::ConstData(const Uint32* data) :
  721.   m_data(data)
  722. {
  723. }
  724. inline Dbtux::ConstData&
  725. Dbtux::ConstData::operator=(const Uint32* data)
  726. {
  727.   m_data = data;
  728.   return *this;
  729. }
  730. inline
  731. Dbtux::ConstData::operator const Uint32*() const
  732. {
  733.   return m_data;
  734. }
  735. inline Dbtux::ConstData&
  736. Dbtux::ConstData::operator+=(size_t n)
  737. {
  738.   m_data += n;
  739.   return *this;
  740. }
  741. inline const AttributeHeader&
  742. Dbtux::ConstData::ah() const
  743. {
  744.   return *reinterpret_cast<const AttributeHeader*>(m_data);
  745. }
  746. inline
  747. Dbtux::ConstData::ConstData(Data data) :
  748.   m_data(static_cast<Uint32*>(data))
  749. {
  750. }
  751. inline Dbtux::ConstData&
  752. Dbtux::ConstData::operator=(Data data)
  753. {
  754.   m_data = static_cast<Uint32*>(data);
  755.   return *this;
  756. }
  757. // Dbtux::TupLoc
  758. inline
  759. Dbtux::TupLoc::TupLoc() :
  760.   m_pageId1(RNIL >> 16),
  761.   m_pageId2(RNIL & 0xFFFF),
  762.   m_pageOffset(0)
  763. {
  764. }
  765. inline
  766. Dbtux::TupLoc::TupLoc(Uint32 pageId, Uint16 pageOffset) :
  767.   m_pageId1(pageId >> 16),
  768.   m_pageId2(pageId & 0xFFFF),
  769.   m_pageOffset(pageOffset)
  770. {
  771. }
  772. inline Uint32
  773. Dbtux::TupLoc::getPageId() const
  774. {
  775.   return (m_pageId1 << 16) | m_pageId2;
  776. }
  777. inline void
  778. Dbtux::TupLoc::setPageId(Uint32 pageId)
  779. {
  780.   m_pageId1 = (pageId >> 16);
  781.   m_pageId2 = (pageId & 0xFFFF);
  782. }
  783. inline Uint32
  784. Dbtux::TupLoc::getPageOffset() const
  785. {
  786.   return (Uint32)m_pageOffset;
  787. }
  788. inline void
  789. Dbtux::TupLoc::setPageOffset(Uint32 pageOffset)
  790. {
  791.   m_pageOffset = (Uint16)pageOffset;
  792. }
  793. inline bool
  794. Dbtux::TupLoc::operator==(const TupLoc& loc) const
  795. {
  796.   return
  797.     m_pageId1 == loc.m_pageId1 &&
  798.     m_pageId2 == loc.m_pageId2 &&
  799.     m_pageOffset == loc.m_pageOffset;
  800. }
  801. inline bool
  802. Dbtux::TupLoc::operator!=(const TupLoc& loc) const
  803. {
  804.   return ! (*this == loc);
  805. }
  806. // Dbtux::TreeEnt
  807. inline
  808. Dbtux::TreeEnt::TreeEnt() :
  809.   m_tupLoc(),
  810.   m_tupVersion(0),
  811.   m_fragBit(0)
  812. {
  813. }
  814. inline bool
  815. Dbtux::TreeEnt::eq(const TreeEnt ent) const
  816. {
  817.   return
  818.     m_tupLoc == ent.m_tupLoc &&
  819.     m_tupVersion == ent.m_tupVersion &&
  820.     m_fragBit == ent.m_fragBit;
  821. }
  822. inline int
  823. Dbtux::TreeEnt::cmp(const TreeEnt ent) const
  824. {
  825.   if (m_tupLoc.getPageId() < ent.m_tupLoc.getPageId())
  826.     return -1;
  827.   if (m_tupLoc.getPageId() > ent.m_tupLoc.getPageId())
  828.     return +1;
  829.   if (m_tupLoc.getPageOffset() < ent.m_tupLoc.getPageOffset())
  830.     return -1;
  831.   if (m_tupLoc.getPageOffset() > ent.m_tupLoc.getPageOffset())
  832.     return +1;
  833.   if (m_tupVersion < ent.m_tupVersion)
  834.     return -1;
  835.   if (m_tupVersion > ent.m_tupVersion)
  836.     return +1;
  837.   if (m_fragBit < ent.m_fragBit)
  838.     return -1;
  839.   if (m_fragBit > ent.m_fragBit)
  840.     return +1;
  841.   return 0;
  842. }
  843. // Dbtux::TreeNode
  844. inline
  845. Dbtux::TreeNode::TreeNode() :
  846.   m_side(2),
  847.   m_balance(0 + 1),
  848.   pad1(0),
  849.   m_occup(0),
  850.   m_nodeScan(RNIL)
  851. {
  852.   m_link[0] = NullTupLoc;
  853.   m_link[1] = NullTupLoc;
  854.   m_link[2] = NullTupLoc;
  855. }
  856. // Dbtux::TreeHead
  857. inline
  858. Dbtux::TreeHead::TreeHead() :
  859.   m_nodeSize(0),
  860.   m_prefSize(0),
  861.   m_minOccup(0),
  862.   m_maxOccup(0),
  863.   m_root()
  864. {
  865. }
  866. inline unsigned
  867. Dbtux::TreeHead::getSize(AccSize acc) const
  868. {
  869.   switch (acc) {
  870.   case AccNone:
  871.     return 0;
  872.   case AccHead:
  873.     return NodeHeadSize;
  874.   case AccPref:
  875.     return NodeHeadSize + m_prefSize + 2 * TreeEntSize;
  876.   case AccFull:
  877.     return m_nodeSize;
  878.   }
  879.   return 0;
  880. }
  881. inline Dbtux::Data
  882. Dbtux::TreeHead::getPref(TreeNode* node) const
  883. {
  884.   Uint32* ptr = (Uint32*)node + NodeHeadSize;
  885.   return ptr;
  886. }
  887. inline Dbtux::TreeEnt*
  888. Dbtux::TreeHead::getEntList(TreeNode* node) const
  889. {
  890.   Uint32* ptr = (Uint32*)node + NodeHeadSize + m_prefSize;
  891.   return (TreeEnt*)ptr;
  892. }
  893. // Dbtux::TreePos
  894. inline
  895. Dbtux::TreePos::TreePos() :
  896.   m_loc(),
  897.   m_pos(ZNIL),
  898.   m_match(false),
  899.   m_dir(255)
  900. {
  901. }
  902. // Dbtux::DescPage
  903. inline
  904. Dbtux::DescPage::DescPage() :
  905.   m_nextPage(RNIL),
  906.   m_numFree(ZNIL)
  907. {
  908.   for (unsigned i = 0; i < DescPageSize; i++) {
  909. #ifdef VM_TRACE
  910.     m_data[i] = 0x13571357;
  911. #else
  912.     m_data[i] = 0;
  913. #endif
  914.   }
  915. }
  916. // Dbtux::ScanOp
  917. inline
  918. Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) :
  919.   m_state(Undef),
  920.   m_lockwait(false),
  921.   m_userPtr(RNIL),
  922.   m_userRef(RNIL),
  923.   m_tableId(RNIL),
  924.   m_indexId(RNIL),
  925.   m_fragPtrI(RNIL),
  926.   m_transId1(0),
  927.   m_transId2(0),
  928.   m_savePointId(0),
  929.   m_accLockOp(RNIL),
  930.   m_readCommitted(0),
  931.   m_lockMode(0),
  932.   m_keyInfo(0),
  933.   m_boundMin(scanBoundPool),
  934.   m_boundMax(scanBoundPool),
  935.   m_scanPos(),
  936.   m_scanEnt(),
  937.   m_nodeScan(RNIL),
  938.   m_maxAccLockOps(0)
  939. {
  940.   m_bound[0] = &m_boundMin;
  941.   m_bound[1] = &m_boundMax;
  942.   m_boundCnt[0] = 0;
  943.   m_boundCnt[1] = 0;
  944. #ifdef VM_TRACE
  945.   for (unsigned i = 0; i < MaxAccLockOps; i++) {
  946.     m_accLockOps[i] = 0x1f1f1f1f;
  947.   }
  948. #endif
  949. }
  950. // Dbtux::Index
  951. inline
  952. Dbtux::Index::Index() :
  953.   m_state(NotDefined),
  954.   m_tableType(DictTabInfo::UndefTableType),
  955.   m_tableId(RNIL),
  956.   m_numFrags(0),
  957.   m_descPage(RNIL),
  958.   m_descOff(0),
  959.   m_numAttrs(0),
  960.   m_storeNullKey(false)
  961. {
  962.   for (unsigned i = 0; i < MaxIndexFragments; i++) {
  963.     m_fragId[i] = ZNIL;
  964.     m_fragPtrI[i] = RNIL;
  965.   };
  966. }
  967. // Dbtux::Frag
  968. inline
  969. Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) :
  970.   m_tableId(RNIL),
  971.   m_indexId(RNIL),
  972.   m_fragOff(ZNIL),
  973.   m_fragId(ZNIL),
  974.   m_descPage(RNIL),
  975.   m_descOff(0),
  976.   m_numAttrs(ZNIL),
  977.   m_storeNullKey(false),
  978.   m_tree(),
  979.   m_freeLoc(),
  980.   m_scanList(scanOpPool),
  981.   m_tupIndexFragPtrI(RNIL)
  982. {
  983.   m_tupTableFragPtrI[0] = RNIL;
  984.   m_tupTableFragPtrI[1] = RNIL;
  985.   m_accTableFragPtrI[0] = RNIL;
  986.   m_accTableFragPtrI[1] = RNIL;
  987. }
  988. // Dbtux::FragOp
  989. inline
  990. Dbtux::FragOp::FragOp() :
  991.   m_userPtr(RNIL),
  992.   m_userRef(RNIL),
  993.   m_indexId(RNIL),
  994.   m_fragId(ZNIL),
  995.   m_fragPtrI(RNIL),
  996.   m_fragNo(ZNIL),
  997.   m_numAttrsRecvd(ZNIL)
  998. {
  999. }
  1000. // Dbtux::NodeHandle
  1001. inline
  1002. Dbtux::NodeHandle::NodeHandle(Frag& frag) :
  1003.   m_frag(frag),
  1004.   m_loc(),
  1005.   m_node(0)
  1006. {
  1007. }
  1008. inline
  1009. Dbtux::NodeHandle::NodeHandle(const NodeHandle& node) :
  1010.   m_frag(node.m_frag),
  1011.   m_loc(node.m_loc),
  1012.   m_node(node.m_node)
  1013. {
  1014. }
  1015. inline Dbtux::NodeHandle&
  1016. Dbtux::NodeHandle::operator=(const NodeHandle& node)
  1017. {
  1018.   ndbassert(&m_frag == &node.m_frag);
  1019.   m_loc = node.m_loc;
  1020.   m_node = node.m_node;
  1021.   return *this;
  1022. }
  1023. inline bool
  1024. Dbtux::NodeHandle::isNull()
  1025. {
  1026.   return m_node == 0;
  1027. }
  1028. inline Dbtux::TupLoc
  1029. Dbtux::NodeHandle::getLink(unsigned i)
  1030. {
  1031.   ndbrequire(i <= 2);
  1032.   return m_node->m_link[i];
  1033. }
  1034. inline unsigned
  1035. Dbtux::NodeHandle::getChilds()
  1036. {
  1037.   return (m_node->m_link[0] != NullTupLoc) + (m_node->m_link[1] != NullTupLoc);
  1038. }
  1039. inline unsigned
  1040. Dbtux::NodeHandle::getSide()
  1041. {
  1042.   return m_node->m_side;
  1043. }
  1044. inline unsigned
  1045. Dbtux::NodeHandle::getOccup()
  1046. {
  1047.   return m_node->m_occup;
  1048. }
  1049. inline int
  1050. Dbtux::NodeHandle::getBalance()
  1051. {
  1052.   return (int)m_node->m_balance - 1;
  1053. }
  1054. inline Uint32
  1055. Dbtux::NodeHandle::getNodeScan()
  1056. {
  1057.   return m_node->m_nodeScan;
  1058. }
  1059. inline void
  1060. Dbtux::NodeHandle::setLink(unsigned i, TupLoc loc)
  1061. {
  1062.   ndbrequire(i <= 2);
  1063.   m_node->m_link[i] = loc;
  1064. }
  1065. inline void
  1066. Dbtux::NodeHandle::setSide(unsigned i)
  1067. {
  1068.   ndbrequire(i <= 2);
  1069.   m_node->m_side = i;
  1070. }
  1071. inline void
  1072. Dbtux::NodeHandle::setOccup(unsigned n)
  1073. {
  1074.   TreeHead& tree = m_frag.m_tree;
  1075.   ndbrequire(n <= tree.m_maxOccup);
  1076.   m_node->m_occup = n;
  1077. }
  1078. inline void
  1079. Dbtux::NodeHandle::setBalance(int b)
  1080. {
  1081.   ndbrequire(abs(b) <= 1);
  1082.   m_node->m_balance = (unsigned)(b + 1);
  1083. }
  1084. inline void
  1085. Dbtux::NodeHandle::setNodeScan(Uint32 scanPtrI)
  1086. {
  1087.   m_node->m_nodeScan = scanPtrI;
  1088. }
  1089. inline Dbtux::Data
  1090. Dbtux::NodeHandle::getPref()
  1091. {
  1092.   TreeHead& tree = m_frag.m_tree;
  1093.   return tree.getPref(m_node);
  1094. }
  1095. inline Dbtux::TreeEnt
  1096. Dbtux::NodeHandle::getEnt(unsigned pos)
  1097. {
  1098.   TreeHead& tree = m_frag.m_tree;
  1099.   TreeEnt* entList = tree.getEntList(m_node);
  1100.   const unsigned occup = m_node->m_occup;
  1101.   ndbrequire(pos < occup);
  1102.   return entList[(1 + pos) % occup];
  1103. }
  1104. inline Dbtux::TreeEnt
  1105. Dbtux::NodeHandle::getMinMax(unsigned i)
  1106. {
  1107.   const unsigned occup = m_node->m_occup;
  1108.   ndbrequire(i <= 1 && occup != 0);
  1109.   return getEnt(i == 0 ? 0 : occup - 1);
  1110. }
  1111. // parameters for methods
  1112. #ifdef VM_TRACE
  1113. inline
  1114. Dbtux::PrintPar::PrintPar() :
  1115.   // caller fills in
  1116.   m_path(),
  1117.   m_side(255),
  1118.   m_parent(),
  1119.   // default return values
  1120.   m_depth(0),
  1121.   m_occup(0),
  1122.   m_ok(true)
  1123. {
  1124. }
  1125. #endif
  1126. // utils
  1127. inline Dbtux::DescEnt&
  1128. Dbtux::getDescEnt(Uint32 descPage, Uint32 descOff)
  1129. {
  1130.   DescPagePtr pagePtr;
  1131.   pagePtr.i = descPage;
  1132.   c_descPagePool.getPtr(pagePtr);
  1133.   ndbrequire(descOff < DescPageSize);
  1134.   DescEnt* descEnt = (DescEnt*)&pagePtr.p->m_data[descOff];
  1135.   return *descEnt;
  1136. }
  1137. inline Uint32
  1138. Dbtux::getTupAddr(const Frag& frag, TreeEnt ent)
  1139. {
  1140.   const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit];
  1141.   const TupLoc tupLoc = ent.m_tupLoc;
  1142.   Uint32 tupAddr = NullTupAddr;
  1143.   c_tup->tuxGetTupAddr(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), tupAddr);
  1144.   jamEntry();
  1145.   return tupAddr;
  1146. }
  1147. inline unsigned
  1148. Dbtux::min(unsigned x, unsigned y)
  1149. {
  1150.   return x < y ? x : y;
  1151. }
  1152. inline unsigned
  1153. Dbtux::max(unsigned x, unsigned y)
  1154. {
  1155.   return x > y ? x : y;
  1156. }
  1157. #endif