Commit cb048699 authored by unknown's avatar unknown
Browse files

tux optim 6 - remove node cache

parent becde519
Loading
Loading
Loading
Loading
+69 −85
Original line number Diff line number Diff line
@@ -102,11 +102,6 @@ private:
  // sizes are in words (Uint32)
  static const unsigned MaxIndexFragments = 2 * NO_OF_FRAG_PER_NODE;
  static const unsigned MaxIndexAttributes = MAX_ATTRIBUTES_IN_INDEX;
#ifdef VM_TRACE
  static const unsigned MaxNodeHandles = 10000; // More space for printTree
#else
  static const unsigned MaxNodeHandles = 128;   // enough for 1 operation
#endif
  static const unsigned MaxAttrDataSize = 2048;
public:
  static const unsigned DescPageSize = 256;
@@ -179,7 +174,7 @@ private:
  };

  /*
   * There is no const variable NullTupLoc since the compiler may not be
   * 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().
   */
@@ -462,8 +457,7 @@ private:
    Uint16 m_descOff;
    Uint16 m_numAttrs;
    TreeHead m_tree;
    Uint32 m_nodeList;          // node cache of current operation
    Uint32 m_nodeFree;          // one node pre-allocated for insert
    TupLoc m_freeLoc;           // one node pre-allocated for insert
    DLList<ScanOp> m_scanList;  // current scans on this fragment
    Uint32 m_tupIndexFragPtrI;
    Uint32 m_tupTableFragPtrI[2];
@@ -498,9 +492,8 @@ private:
  // node handles

  /*
   * A tree operation builds a cache of accessed nodes.  This allows
   * different implementations of index memory access.  The cache is
   * committed and released at the end of the operation.
   * A node handle is a reference to a tree node in TUP.  It is used to
   * operate on the node.  Node handles are allocated on the stack.
   */
  struct NodeHandle;
  friend struct NodeHandle;
@@ -509,11 +502,9 @@ private:
    TupLoc m_loc;               // physical node address
    TreeNode* m_node;           // pointer to node storage
    AccSize m_acc;              // accessed size
    union {
    Uint32 m_next;              // next active node under fragment
    Uint32 nextPool;
    };
    NodeHandle(Frag& frag);
    NodeHandle(const NodeHandle& node);
    NodeHandle& operator=(const NodeHandle& node);
    // getters
    TupLoc getLink(unsigned i);
    unsigned getChilds();       // cannot spell
@@ -521,20 +512,19 @@ private:
    unsigned getOccup();
    int getBalance();
    Uint32 getNodeScan();
    Data getPref(unsigned i);
    TreeEnt getEnt(unsigned pos);
    TreeEnt getMinMax(unsigned i);
    // setters
    void setLink(unsigned i, TupLoc loc);
    void setSide(unsigned i);
    void setOccup(unsigned n);
    void setBalance(int b);
    void setNodeScan(Uint32 scanPtrI);
    // access other parts of the node
    Data getPref(unsigned i);
    TreeEnt getEnt(unsigned pos);
    TreeEnt getMinMax(unsigned i);
    // for ndbrequire and ndbassert
    void progError(int line, int cause, const char* file);
  };
  typedef Ptr<NodeHandle> NodeHandlePtr;
  ArrayPool<NodeHandle> c_nodeHandlePool;

  // parameters for methods
  
@@ -565,17 +555,6 @@ private:
    ReadPar();
  };

  /*
   * Node storage operation.
   */
  struct StorePar {
    TupStoreTh::OpCode m_opCode;// operation code
    unsigned m_offset;          // data offset in words
    unsigned m_size;            // number of words
    Uint32 m_errorCode;         // terrorCode from TUP
    StorePar();
  };

  /*
   * Tree search for entry.
   */
@@ -649,15 +628,12 @@ private:
  /*
   * DbtuxNode.cpp
   */
  void seizeNode(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr);
  void preallocNode(Signal* signal, Frag& frag, Uint32& errorCode);
  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);
  int allocNode(Signal* signal, NodeHandle& node);
  void accessNode(Signal* signal, NodeHandle& node, AccSize acc);
  void selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc);
  void insertNode(Signal* signal, NodeHandle& node, AccSize acc);
  void deleteNode(Signal* signal, NodeHandle& node);
  void setNodePref(Signal* signal, NodeHandle& node, unsigned i);
  void commitNodes(Signal* signal, Frag& frag, bool updateOk);
  // node operations
  void nodePushUp(Signal* signal, NodeHandle& node, unsigned pos, const TreeEnt& ent);
  void nodePopDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent);
@@ -675,8 +651,8 @@ private:
  void treeSearch(Signal* signal, Frag& frag, SearchPar searchPar, TreePos& treePos);
  void treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent);
  void treeRemove(Signal* signal, Frag& frag, TreePos treePos);
  void treeRotateSingle(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, unsigned i);
  void treeRotateDouble(Signal* signal, Frag& frag, NodeHandlePtr& nodePtr, unsigned i);
  void treeRotateSingle(Signal* signal, Frag& frag, NodeHandle& node, unsigned i);
  void treeRotateDouble(Signal* signal, Frag& frag, NodeHandle& node, unsigned i);

  /*
   * DbtuxScan.cpp
@@ -1054,8 +1030,7 @@ Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) :
  m_descOff(0),
  m_numAttrs(ZNIL),
  m_tree(),
  m_nodeList(RNIL),
  m_nodeFree(RNIL),
  m_freeLoc(),
  m_scanList(scanOpPool),
  m_tupIndexFragPtrI(RNIL)
{
@@ -1086,11 +1061,29 @@ Dbtux::NodeHandle::NodeHandle(Frag& frag) :
  m_frag(frag),
  m_loc(),
  m_node(0),
  m_acc(AccNone),
  m_next(RNIL)
  m_acc(AccNone)
{
}

inline
Dbtux::NodeHandle::NodeHandle(const NodeHandle& node) :
  m_frag(node.m_frag),
  m_loc(node.m_loc),
  m_node(node.m_node),
  m_acc(node.m_acc)
{
}

inline Dbtux::NodeHandle&
Dbtux::NodeHandle::operator=(const NodeHandle& node)
{
  ndbassert(&m_frag == &node.m_frag);
  m_loc = node.m_loc;
  m_node = node.m_node;
  m_acc = node.m_acc;
  return *this;
}

inline Dbtux::TupLoc
Dbtux::NodeHandle::getLink(unsigned i)
{
@@ -1128,37 +1121,6 @@ Dbtux::NodeHandle::getNodeScan()
  return m_node->m_nodeScan;
}

inline Dbtux::Data
Dbtux::NodeHandle::getPref(unsigned i)
{
  TreeHead& tree = m_frag.m_tree;
  ndbrequire(m_acc >= AccPref && i <= 1);
  return tree.getPref(m_node, i);
}

inline Dbtux::TreeEnt
Dbtux::NodeHandle::getEnt(unsigned pos)
{
  TreeHead& tree = m_frag.m_tree;
  TreeEnt* entList = tree.getEntList(m_node);
  const unsigned occup = m_node->m_occup;
  ndbrequire(pos < occup);
  if (pos == 0 || pos == occup - 1) {
    ndbrequire(m_acc >= AccPref)
  } else {
    ndbrequire(m_acc == AccFull)
  }
  return entList[(1 + pos) % occup];
}

inline Dbtux::TreeEnt
Dbtux::NodeHandle::getMinMax(unsigned i)
{
  const unsigned occup = m_node->m_occup;
  ndbrequire(i <= 1 && occup != 0);
  return getEnt(i == 0 ? 0 : occup - 1);
}

inline void
Dbtux::NodeHandle::setLink(unsigned i, TupLoc loc)
{
@@ -1195,6 +1157,37 @@ Dbtux::NodeHandle::setNodeScan(Uint32 scanPtrI)
  m_node->m_nodeScan = scanPtrI;
}

inline Dbtux::Data
Dbtux::NodeHandle::getPref(unsigned i)
{
  TreeHead& tree = m_frag.m_tree;
  ndbrequire(m_acc >= AccPref && i <= 1);
  return tree.getPref(m_node, i);
}

inline Dbtux::TreeEnt
Dbtux::NodeHandle::getEnt(unsigned pos)
{
  TreeHead& tree = m_frag.m_tree;
  TreeEnt* entList = tree.getEntList(m_node);
  const unsigned occup = m_node->m_occup;
  ndbrequire(pos < occup);
  if (pos == 0 || pos == occup - 1) {
    ndbrequire(m_acc >= AccPref)
  } else {
    ndbrequire(m_acc == AccFull)
  }
  return entList[(1 + pos) % occup];
}

inline Dbtux::TreeEnt
Dbtux::NodeHandle::getMinMax(unsigned i)
{
  const unsigned occup = m_node->m_occup;
  ndbrequire(i <= 1 && occup != 0);
  return getEnt(i == 0 ? 0 : occup - 1);
}

// parameters for methods

inline
@@ -1217,15 +1210,6 @@ Dbtux::ReadPar::ReadPar() :
{
}

inline
Dbtux::StorePar::StorePar() :
  m_opCode(TupStoreTh::OpUndefined),
  m_offset(0),
  m_size(0),
  m_errorCode(0)
{
}

inline
Dbtux::SearchPar::SearchPar() :
  m_data(0),
+20 −22
Original line number Diff line number Diff line
@@ -106,13 +106,11 @@ Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out)
      signal->theData[1] = 1;
      execDUMP_STATE_ORD(signal);
      if (debugFile != 0) {
        commitNodes(signal, frag, false);
        printTree(signal, frag, debugOut);
      }
    }
    ndbrequire(false);
  }
  commitNodes(signal, frag, false);
}

void
@@ -123,9 +121,9 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar&
    return;
  }
  TreeHead& tree = frag.m_tree;
  NodeHandlePtr nodePtr;
  selectNode(signal, frag, nodePtr, loc, AccFull);
  out << par.m_path << " " << *nodePtr.p << endl;
  NodeHandle node(frag);
  selectNode(signal, node, loc, AccFull);
  out << par.m_path << " " << node << endl;
  // check children
  PrintPar cpar[2];
  ndbrequire(strlen(par.m_path) + 1 < sizeof(par.m_path));
@@ -134,56 +132,56 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar&
    cpar[i].m_side = i;
    cpar[i].m_depth = 0;
    cpar[i].m_parent = loc;
    printNode(signal, frag, out, nodePtr.p->getLink(i), cpar[i]);
    printNode(signal, frag, out, node.getLink(i), cpar[i]);
    if (! cpar[i].m_ok) {
      par.m_ok = false;
    }
  }
  // check child-parent links
  if (nodePtr.p->getLink(2) != par.m_parent) {
  if (node.getLink(2) != par.m_parent) {
    par.m_ok = false;
    out << par.m_path << " *** ";
    out << "parent loc " << hex << nodePtr.p->getLink(2);
    out << "parent loc " << hex << node.getLink(2);
    out << " should be " << hex << par.m_parent << endl;
  }
  if (nodePtr.p->getSide() != par.m_side) {
  if (node.getSide() != par.m_side) {
    par.m_ok = false;
    out << par.m_path << " *** ";
    out << "side " << dec << nodePtr.p->getSide();
    out << "side " << dec << node.getSide();
    out << " should be " << dec << par.m_side << endl;
  }
  // check balance
  const int balance = -cpar[0].m_depth + cpar[1].m_depth;
  if (nodePtr.p->getBalance() != balance) {
  if (node.getBalance() != balance) {
    par.m_ok = false;
    out << par.m_path << " *** ";
    out << "balance " << nodePtr.p->getBalance();
    out << "balance " << node.getBalance();
    out << " should be " << balance << endl;
  }
  if (abs(nodePtr.p->getBalance()) > 1) {
  if (abs(node.getBalance()) > 1) {
    par.m_ok = false;
    out << par.m_path << " *** ";
    out << "balance " << nodePtr.p->getBalance() << " is invalid" << endl;
    out << "balance " << node.getBalance() << " is invalid" << endl;
  }
  // check occupancy
  if (nodePtr.p->getOccup() > tree.m_maxOccup) {
  if (node.getOccup() > tree.m_maxOccup) {
    par.m_ok = false;
    out << par.m_path << " *** ";
    out << "occupancy " << nodePtr.p->getOccup();
    out << "occupancy " << node.getOccup();
    out << " greater than max " << tree.m_maxOccup << endl;
  }
  // check for occupancy of interior node
  if (nodePtr.p->getChilds() == 2 && nodePtr.p->getOccup() < tree.m_minOccup) {
  if (node.getChilds() == 2 && node.getOccup() < tree.m_minOccup) {
    par.m_ok = false;
    out << par.m_path << " *** ";
    out << "occupancy " << nodePtr.p->getOccup() << " of interior node";
    out << "occupancy " << node.getOccup() << " of interior node";
    out << " less than min " << tree.m_minOccup << endl;
  }
  // check missed half-leaf/leaf merge
  for (unsigned i = 0; i <= 1; i++) {
    if (nodePtr.p->getLink(i) != NullTupLoc &&
        nodePtr.p->getLink(1 - i) == NullTupLoc &&
        nodePtr.p->getOccup() + cpar[i].m_occup <= tree.m_maxOccup) {
    if (node.getLink(i) != NullTupLoc &&
        node.getLink(1 - i) == NullTupLoc &&
        node.getOccup() + cpar[i].m_occup <= tree.m_maxOccup) {
      par.m_ok = false;
      out << par.m_path << " *** ";
      out << "missed merge with child " << i << endl;
@@ -191,7 +189,7 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar&
  }
  // return values
  par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
  par.m_occup = nodePtr.p->getOccup();
  par.m_occup = node.getOccup();
}

NdbOut&
+0 −1
Original line number Diff line number Diff line
@@ -178,7 +178,6 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
  c_fragPool.setSize(nFragment);
  c_descPagePool.setSize(nDescPage);
  c_fragOpPool.setSize(MaxIndexFragments);
  c_nodeHandlePool.setSize(MaxNodeHandles);
  c_scanOpPool.setSize(nScanOp);
  c_scanBoundPool.setSize(nScanBoundWords);
  /*
+6 −7
Original line number Diff line number Diff line
@@ -72,7 +72,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
  }
  ndbrequire(fragPtr.i != RNIL);
  Frag& frag = *fragPtr.p;
  ndbrequire(frag.m_nodeList == RNIL);
  // set up index entry
  TreeEnt ent;
  ent.m_tupAddr = req->tupAddr;
@@ -143,17 +142,18 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
    }
    /*
     * At most one new node is inserted in the operation.  We keep one
     * free node pre-allocated so the operation cannot fail.  This also
     * gives a real TupAddr for links to the new node.
     * free node pre-allocated so the operation cannot fail.
     */
    if (frag.m_nodeFree == RNIL) {
    if (frag.m_freeLoc == NullTupLoc) {
      jam();
      preallocNode(signal, frag, req->errorCode);
      NodeHandle node(frag);
      req->errorCode = allocNode(signal, node);
      if (req->errorCode != 0) {
        jam();
        break;
      }
      ndbrequire(frag.m_nodeFree != RNIL);
      frag.m_freeLoc = node.m_loc;
      ndbrequire(frag.m_freeLoc != NullTupLoc);
    }
    treeAdd(signal, frag, treePos, ent);
    break;
@@ -175,7 +175,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
    break;
  }
  // commit and release nodes
  commitNodes(signal, frag, req->errorCode == 0);
#ifdef VM_TRACE
  if (debugFlags & DebugTree) {
    printTree(signal, frag, debugOut);
+0 −6
Original line number Diff line number Diff line
@@ -316,12 +316,6 @@ Dbtux::dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 sen
    unsigned i = --indexPtr.p->m_numFrags;
    FragPtr fragPtr;
    c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]);
    Frag& frag = *fragPtr.p;
    ndbrequire(frag.m_nodeList == RNIL);
    if (frag.m_nodeFree != RNIL) {
      c_nodeHandlePool.release(frag.m_nodeFree);
      frag.m_nodeFree = RNIL;
    }
    c_fragPool.release(fragPtr);
    // the real time break is not used for anything currently
    signal->theData[0] = TuxContinueB::DropIndex;
Loading