📄 dbtux.hpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#ifndef DBTUX_H#define DBTUX_H#include <ndb_limits.h>#include <SimulatedBlock.hpp>#include <AttributeDescriptor.hpp>#include <AttributeHeader.hpp>#include <ArrayPool.hpp>#include <DataBuffer.hpp>#include <md5_hash.hpp>// big brother#include <Dbtup.hpp>// signal classes#include <signaldata/DictTabInfo.hpp>#include <signaldata/TuxContinueB.hpp>#include <signaldata/TupFrag.hpp>#include <signaldata/AlterIndx.hpp>#include <signaldata/DropTab.hpp>#include <signaldata/TuxMaint.hpp>#include <signaldata/AccScan.hpp>#include <signaldata/TuxBound.hpp>#include <signaldata/NextScan.hpp>#include <signaldata/AccLock.hpp>#include <signaldata/DumpStateOrd.hpp>// debug#ifdef VM_TRACE#include <NdbOut.hpp>#include <OutputStream.hpp>#endif// jams#undef jam#undef jamEntry#ifdef DBTUX_GEN_CPP#define jam() jamLine(10000 + __LINE__)#define jamEntry() jamEntryLine(10000 + __LINE__)#endif#ifdef DBTUX_META_CPP#define jam() jamLine(20000 + __LINE__)#define jamEntry() jamEntryLine(20000 + __LINE__)#endif#ifdef DBTUX_MAINT_CPP#define jam() jamLine(30000 + __LINE__)#define jamEntry() jamEntryLine(30000 + __LINE__)#endif#ifdef DBTUX_NODE_CPP#define jam() jamLine(40000 + __LINE__)#define jamEntry() jamEntryLine(40000 + __LINE__)#endif#ifdef DBTUX_TREE_CPP#define jam() jamLine(50000 + __LINE__)#define jamEntry() jamEntryLine(50000 + __LINE__)#endif#ifdef DBTUX_SCAN_CPP#define jam() jamLine(60000 + __LINE__)#define jamEntry() jamEntryLine(60000 + __LINE__)#endif#ifdef DBTUX_SEARCH_CPP#define jam() jamLine(70000 + __LINE__)#define jamEntry() jamEntryLine(70000 + __LINE__)#endif#ifdef DBTUX_CMP_CPP#define jam() jamLine(80000 + __LINE__)#define jamEntry() jamEntryLine(80000 + __LINE__)#endif#ifdef DBTUX_DEBUG_CPP#define jam() jamLine(90000 + __LINE__)#define jamEntry() jamEntryLine(90000 + __LINE__)#endif#ifndef jam#define jam() jamLine(__LINE__)#define jamEntry() jamEntryLine(__LINE__)#endif#undef max#undef minclass Configuration;class Dbtux : public SimulatedBlock {public: Dbtux(const Configuration& conf); virtual ~Dbtux(); // pointer to TUP instance in this thread Dbtup* c_tup;private: // sizes are in words (Uint32) STATIC_CONST( MaxIndexFragments = 2 * MAX_FRAG_PER_NODE ); STATIC_CONST( MaxIndexAttributes = MAX_ATTRIBUTES_IN_INDEX ); STATIC_CONST( MaxAttrDataSize = 2048 );public: STATIC_CONST( DescPageSize = 256 );private: STATIC_CONST( MaxTreeNodeSize = MAX_TTREE_NODE_SIZE ); STATIC_CONST( MaxPrefSize = MAX_TTREE_PREF_SIZE ); STATIC_CONST( ScanBoundSegmentSize = 7 ); STATIC_CONST( MaxAccLockOps = MAX_PARALLEL_OP_PER_SCAN ); BLOCK_DEFINES(Dbtux); // forward declarations struct DescEnt; /* * Pointer to array of Uint32. */ struct Data { private: Uint32* m_data; public: Data(); Data(Uint32* data); Data& operator=(Uint32* data); operator Uint32*() const; Data& operator+=(size_t n); AttributeHeader& ah() const; }; friend class Data; /* * Pointer to array of constant Uint32. */ struct ConstData; friend struct ConstData; struct ConstData { private: const Uint32* m_data; public: ConstData(); ConstData(const Uint32* data); ConstData& operator=(const Uint32* data); operator const Uint32*() const; ConstData& operator+=(size_t n); const AttributeHeader& ah() const; // non-const pointer can be cast to const pointer ConstData(Data data); ConstData& operator=(Data data); }; // AttributeHeader size is assumed to be 1 word STATIC_CONST( AttributeHeaderSize = 1 ); /* * Logical tuple address, "local key". Identifies table tuples. */ typedef Uint32 TupAddr; STATIC_CONST( NullTupAddr = (Uint32)-1 ); /* * Physical tuple address in TUP. Provides fast access to table tuple * or index node. Valid within the db node and across timeslices. * Not valid between db nodes or across restarts. * * To avoid wasting an Uint16 the pageid is split in two. */ struct TupLoc { private: Uint16 m_pageId1; // page i-value (big-endian) Uint16 m_pageId2; Uint16 m_pageOffset; // page offset in words public: TupLoc(); TupLoc(Uint32 pageId, Uint16 pageOffset); Uint32 getPageId() const; void setPageId(Uint32 pageId); Uint32 getPageOffset() const; void setPageOffset(Uint32 pageOffset); bool operator==(const TupLoc& loc) const; bool operator!=(const TupLoc& loc) const; }; /* * There is no const member 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 /* * Tree entry. Points to a tuple in primary table via physical * address of "original" tuple and tuple version. * * ZTUP_VERSION_BITS must be 15 (or less). */ struct TreeEnt; friend struct TreeEnt; struct TreeEnt { TupLoc m_tupLoc; // address of original tuple unsigned m_tupVersion : 15; // version unsigned m_fragBit : 1; // which duplicated table fragment TreeEnt(); // methods bool eq(const TreeEnt ent) const; int cmp(const TreeEnt ent) const; }; STATIC_CONST( TreeEntSize = sizeof(TreeEnt) >> 2 ); static const TreeEnt NullTreeEnt; /* * Tree node has 1) fixed part 2) a prefix of index key data for min * entry 3) max and min entries 4) rest of entries 5) one extra entry * used as work space. * * struct TreeNode part 1, size 6 words * min prefix part 2, size TreeHead::m_prefSize * max entry part 3 * min entry part 3 * rest of entries part 4 * work entry part 5 * * There are 3 links to other nodes: left child, right child, parent. * Occupancy (number of entries) is at least 1 except temporarily when * a node is about to be removed. */ struct TreeNode; friend struct TreeNode; struct TreeNode { TupLoc m_link[3]; // link to 0-left child 1-right child 2-parent unsigned m_side : 2; // we are 0-left child 1-right child 2-root unsigned m_balance : 2; // balance -1, 0, +1 plus 1 for Solaris CC unsigned pad1 : 4; Uint8 m_occup; // current number of entries Uint32 m_nodeScan; // list of scans at this node TreeNode(); }; STATIC_CONST( NodeHeadSize = sizeof(TreeNode) >> 2 ); /* * Tree node "access size" was for an early version with signal * interface to TUP. It is now used only to compute sizes. */ enum AccSize { AccNone = 0, AccHead = 1, // part 1 AccPref = 2, // parts 1-3 AccFull = 3 // parts 1-5 }; /* * Tree header. There is one in each fragment. Contains tree * parameters and address of root node. */ struct TreeHead; friend struct TreeHead; struct TreeHead { Uint8 m_nodeSize; // words in tree node Uint8 m_prefSize; // words in min prefix Uint8 m_minOccup; // min entries in internal node Uint8 m_maxOccup; // max entries in node TupLoc m_root; // root node TreeHead(); // methods unsigned getSize(AccSize acc) const; Data getPref(TreeNode* node) const; TreeEnt* getEntList(TreeNode* node) const; }; /* * Tree position. Specifies node, position within node (from 0 to * m_occup), and whether the position is at an existing entry or * before one (if any). Position m_occup points past the node and is * also represented by position 0 of next node. Includes direction * used by scan. */ struct TreePos; friend struct TreePos; struct TreePos { TupLoc m_loc; // physical node address Uint16 m_pos; // position 0 to m_occup Uint8 m_match; // at an existing entry Uint8 m_dir; // see scanNext() TreePos(); }; // packed metadata /* * Descriptor page. The "hot" metadata for an index is stored as * a contiguous array of words on some page. */ struct DescPage; friend struct DescPage; struct DescPage { Uint32 m_nextPage; Uint32 m_numFree; // number of free words union { Uint32 m_data[DescPageSize]; Uint32 nextPool; }; DescPage(); }; typedef Ptr<DescPage> DescPagePtr; ArrayPool<DescPage> c_descPagePool; Uint32 c_descPageList; /* * Header for index metadata. Size must be multiple of word size. */ struct DescHead { unsigned m_indexId : 24; unsigned pad1 : 8; }; STATIC_CONST( DescHeadSize = sizeof(DescHead) >> 2 ); /* * Attribute metadata. Size must be multiple of word size. * * Prefix comparison of char data must use strxfrm and binary * comparison. The charset is currently unused. */ struct DescAttr { Uint32 m_attrDesc; // standard AttributeDescriptor Uint16 m_primaryAttrId; unsigned m_typeId : 6; unsigned m_charset : 10; }; STATIC_CONST( DescAttrSize = sizeof(DescAttr) >> 2 ); /* * Complete metadata for one index. The array of attributes has * variable size. */ friend struct DescEnt; struct DescEnt { DescHead m_descHead; DescAttr m_descAttr[1]; // variable size data }; // range scan /* * Scan bounds are stored in linked list of segments. */ typedef DataBuffer<ScanBoundSegmentSize> ScanBound; typedef DataBuffer<ScanBoundSegmentSize>::ConstDataBufferIterator ScanBoundIterator; typedef DataBuffer<ScanBoundSegmentSize>::DataBufferPool ScanBoundPool; ScanBoundPool c_scanBoundPool; /* * Scan operation. * * Tuples are locked one at a time. The current lock op is set to * RNIL as soon as the lock is obtained and passed to LQH. We must * however remember all locks which LQH has not returned for unlocking * since they must be aborted by us when the scan is closed. * * Scan state describes the entry we are interested in. There is * a separate lock wait flag. It may be for current entry or it may * be for an entry we were moved away from. In any case nothing * happens with current entry before lock wait flag is cleared. * * An unfinished scan is always linked to some tree node, and has * current position and direction (see comments at scanNext). There * is also a copy of latest entry found. */ struct ScanOp; friend struct ScanOp; struct ScanOp { enum { Undef = 0, First = 1, // before first entry Current = 2, // at current before locking Blocked = 3, // at current waiting for ACC lock Locked = 4, // at current and locked or no lock needed Next = 5, // looking for next extry Last = 6, // after last entry Aborting = 7, // lock wait at scan close Invalid = 9 // cannot return REF to LQH currently }; Uint16 m_state; Uint16 m_lockwait; Uint32 m_userPtr; // scanptr.i in LQH Uint32 m_userRef; Uint32 m_tableId; Uint32 m_indexId; Uint32 m_fragId; Uint32 m_fragPtrI; Uint32 m_transId1; Uint32 m_transId2; Uint32 m_savePointId; // lock waited for or obtained and not yet passed to LQH Uint32 m_accLockOp; Uint8 m_readCommitted; // no locking Uint8 m_lockMode; Uint8 m_descending; ScanBound m_boundMin; ScanBound m_boundMax; ScanBound* m_bound[2]; // pointers to above 2 Uint16 m_boundCnt[2]; // number of bounds in each TreePos m_scanPos; // position TreeEnt m_scanEnt; // latest entry found Uint32 m_nodeScan; // next scan at node (single-linked) union { Uint32 nextPool; Uint32 nextList; }; Uint32 prevList; /* * Locks obtained and passed to LQH but not yet returned by LQH. * The max was increased from 16 to 992 (default 64). Record max * ever used in this scan. TODO fix quadratic behaviour */ Uint32 m_maxAccLockOps; Uint32 m_accLockOps[MaxAccLockOps]; ScanOp(ScanBoundPool& scanBoundPool); }; typedef Ptr<ScanOp> ScanOpPtr; ArrayPool<ScanOp> c_scanOpPool;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -