Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions  Download package

gbd600.h

/*!**************************************************************************

  module        : gbd600.h
  special area  : Node Handling
  see also      : example.html ...
  responsible   : UweH
  last changed  : 1999-09-03  15:46
  copyright     : (c) 1999-2004 SAP AG
  implementation: vbd600.cpp, vbd610.cpp, vbd620.cpp
  description   : defines class cbd600_Node



    ========== licence begin  GPL
    Copyright (c) 1999-2005 SAP AG

    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.
    ========== licence end


*****************************************************************************/


#ifndef GBD600_H
#define GBD600_H

/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/

#include "gsp00.h"
#include "ggg00.h"
#include "gbd00.h"
#include "gsp03.h"
#include "gsp03_3.h"
#include "hgg10.h"

#include "gbd300.h"
#include "hbd13.h"
#include "hgg01_1.h"

#if COMPILEMODE_MEO00 >= SLOW_MEO00 
#include "hta99.h"
#endif

/*===========================================================================*
 *  FORWARD DECLARATIONS                                                     *
 *===========================================================================*/

class cbd500_Tree;
class cbd500_SubTree;
class cbd800_PrimaryTree;

/*===========================================================================*
 *  DEFINES                                                                  *
 *===========================================================================*/

#define UNDER_FLOW_LIMIT_BD600 HALF_COVERING_BD00
#define IS_CHANGED_BD600       true

#define IS_LEFT_NODE_GBD600    true
#define IS_RIGHT_NODE_GBD600   false

#define TRUE                   1

/*===========================================================================*
 *  MACROS                                                                   *
 *===========================================================================*/

/*===========================================================================*
 *  EXTERNAL VARIABLES                                                       *
 *===========================================================================*/

/*===========================================================================*
*  CLASSES, STRUCTURES, TYPES, UNIONS ...                                   *
*===========================================================================*/

/*---------------------------------------------------------------------------*/
/*!
    class:       cbd600_Node
    description: methodes to handle Node-Pages
*/

00096 class cbd600_Node
{
      friend class cbd500_Tree;
      friend class cbd500_SubTree;
      friend class cbd800_PrimaryTree;
      friend class cbd400_InvTree;
public:
    /*!
    function:    cbd600_Node
    description: copy constructor.
    arguments:   Node [in]    Node to copy.
    */
      cbd600_Node (const cbd600_Node &Node);

    /*!
    function:    cbd600_Node
    description: this is for accessing the root node.
    arguments:   Current       [in/out] for TrError, TaskID.
                 PageLockMode  [in]     How the Page of the node is locked. (default = CacheLock)
    */
      cbd600_Node (cbd300_InvCurrentBasis   &Current,
                     const tbd00_PageLockMode &PageLockMode = tbd00_PageLockMode::fromConst(plmLock_ebd00));
    /*!
    function:    cbd600_Node
    description: This constructs an empty node, which can be used to access any node.
    arguments:   Current       [in/out] for TrError, TaskID.
                 RequestKind   [in]     How pages are requested from the Datacache (for_read/for_update)
                 PageLockMode  [in]     How the Page of the node is locked. (default = CacheLock)
    */
      cbd600_Node (cbd300_InvCurrentBasis   &Current,
                     const tbd_node_request   &RequestKind,
                     const tbd00_PageLockMode &PageLockMode = tbd00_PageLockMode::fromConst(plmLock_ebd00));
    /*!
    function:    cbd600_Node
    description: create a nodehandle and get specified page.
    arguments:   Current       [in/out] for TrError, TaskID.
                 RequestKind   [in]     How pages are requested from the Datacache (for_read/for_update)
                 Pno           [in]     Page Number
                 PageLockMode  [in]     How the Page of the node is locked. (default = CacheLock)
    */
      cbd600_Node (cbd300_InvCurrentBasis   &Current,
                     const tbd_node_request   &RequestKind,
                         tsp00_PageNo              Pno,
                     const tbd00_PageLockMode &PageLockMode = tbd00_PageLockMode::fromConst(plmLock_ebd00));
    /*!
    function:    cbd600_Node
    description: create a nodehandle and use the given CacheHandle NPTR.
    arguments:   Current       [in/out] for TrError, TaskID.
                 RequestKind   [in]     How pages are requested from the Datacache (for_read/for_update)
                 Nptr          [in/out] DataCacheHandle
                 PageLockMode  [in]     How the Page of the node is locked. (default = CacheLock)
    */
      cbd600_Node (cbd300_InvCurrentBasis   &Current,
                     const tbd_node_request   &RequestKind,
                         tbd_node_ptrs            &Nptr,
                     const tbd00_PageLockMode &PageLockMode = tbd00_PageLockMode::fromConst(plmLock_ebd00));
    /*!
    function:    cbd600_Node
    description: create a nodehandle and use the given buffer, no DataCache is used.
    arguments:   Current       [in/out] for TrError, TaskID.
                 Buffer        [in/out] Node Buffer
                 PageLockMode  [in]     How the Page of the node is locked. (default = CacheLock)
    */
      cbd600_Node (cbd300_InvCurrentBasis   &Current,
                     tbd_node                 &Buffer,
                     const tbd00_PageLockMode &PageLockMode = tbd00_PageLockMode::fromConst(plmLock_ebd00));
    /*!
    function:    ~cbd600_Node
    description: releases the DataCache Page if there is one, checks, if updated
    */
      ~cbd600_Node ();
    /*!
    function:    bd600AddRecordSpace
    description: Given length is reserved in the page, at the given position, if there
                 is not enough space e_no_more_space is set.
    arguments:   RequiredLen [in]  Total record length
                 RecIndex    [in]  position, where the new record must be inserted
                 pRec        [out] Points to the ByteString, where the requested space is available
    */
      void              bd600AddRecordSpace    (tsp00_Int4    RequiredLen,
                                                                tsp00_Int4    RecIndex,
                                                                  tgg00_RecPtr &pRec);
    /*!
    function:    bd600BuildSeparatorKey
    */
      void              bd600BuildSeparatorKey (cbd600_Node  &RightNeighbor,
                                                              tsp00_KeyPtr &pSepKey,
                                                              tsp00_Int2   &SepKeyLen) const;
    /*!
    function:    bd600BuildSeparatorKey
    */
      void              bd600BuildSeparatorKey (bool          bNodeIsLeft,
                                                              tsp00_KeyPtr  pNeighborKey,
                                              tsp00_Int4    NeighborKeyLen,
                                              tsp00_KeyPtr &pNewSepKey,
                                              tsp00_Int2   &NewSepKeyLen) const;
    /*!
    function:    bd600Check
    */
    void              bd600Check             (const bool bWithExtendedCheck) const;
    void              bd600CheckWithErrorHandling() const;
      void              bd600CheckIndex        () const;
      void              bd600CopyBody          (cbd600_Node &SrcNode);
      void              bd600CountRecords      (tsp00_KeyPtr  pStartKey, 
                                                  tsp00_Int4    StartKeyLen, 
                                                                  tsp00_KeyPtr  pStopKey,
                                                                  tsp00_Int4    StopKeyLen,
                                                  tsp00_Int4   &RecordCnt) const;
      tsp00_Int4        bd600Covering          () const;
      void              bd600DelRecordSpace    (tsp00_Int4 RecIndex);
      void              bd600Dump              (tsp00_Int4 ErrorId, const char *MsgText /*tsp00_C24*/) const;
    void              bd600EvalSepKeyLen     (tsp00_KeyPtr pKey,
                                                            tsp00_Int4   KeyLen,
                                                            tsp00_KeyPtr pNewSepKey,
                                                            tsp00_Int2   &NewSepKeyLen) const;
      void              bd600Exchange          (cbd600_Node &Neighbor);
      void              bd600Free              ();
    tsp00_PageNo      bd600GetId             () const;
    tsp00_Int4        bd600PageConverterVersion () const;
    tbd_nodeptr       bd600GetNodePtr        ();
    void              bd600GetNode           (tsp00_PageNo            PageNo,
                                                              const tbd_node_request &RequestKind);
    void              bd600GetNode           (tsp00_PageNo PageNo);
    void              bd600GetStatistic      (tgg00_SampleInfo  &Info,
                                                            tbd_stat_aux_vars &StatAuxVars,
                                                            bool               bWithSelectivity) const;
      bool              bd600IsAccessable      () const;
    bool              bd600IsLeaf            () const;
    bool              bd600IsRoot            () const;
    bool              bd600IsUpdateable      () const;
      tsp00_Int4       &bd600LeafCount         ();
      tsp00_Int4        bd600LeafCount         (const tsp00_Int4 StartRecIndex,
                                                  const tsp00_Int4 StopRecIndex) const;
    tsp00_Int4      bd600Level             () const;
      tsp00_PageNo      bd600RightNeighbor     () const;
      tsp00_Int4          bd600MaxRecIndex       () const;
    void              bd600Move              (tsp00_PageNo NewId);
      void                bd600New               (tsp00_Int4 Level);
    tgg00_RecPtr      bd600NewRecPtr         ();
      bool              bd600NodeIsRequested   () const; 
      tsp00_Int4        bd600NumRecords        () const;
    tsp00_Int4        bd600PrimKeyCount      (const tsp00_Int4 StartRecIndex, 
                                                          const tsp00_Int4 StopRecIndex) const;
      tgg00_RecPtr      bd600RecPtr            (tsp00_Int4 RecIndex) const;
    void              bd600Release           (bool IsChanged);
      void              bd600SearchRecord      (tsp00_KeyPtr      pKey,
                                                  tsp00_Int4        KeyLen,
                                                                  tsp00_Int4       &RecIndex,
                                                                  tbd_searchresult &SearchResult) const;
      bool              bd600SpaceIsAvailable  (tsp00_Int4 RequiredLen) const;
      tsp00_Int4        bd600SumKeyLen         () const;
      tgg00_BasisError &bd600TrError           ();
      tgg00_BasisError  bd600TrError           () const;
      void              bd600UpdRecordSpace    (tsp00_Int4   RecSizeDelta,
                                                                  tsp00_Int4   RecIndex,
                                                                tgg00_RecPtr pRec);

    tsp00_Int4          bd600RecOffset       (tsp00_Int4 RecIndex) const;
    tgg00_RecPtr        bd600FirstRecPtr     () const;

      static tgg00_RecPtr bd600FirstRecPtr     (tbd_nodeptr pNode);
      
#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
    void              bd600Print             () const;
    void              bd600PrintPointerList  () const;
#   endif
      
      /* ---- protected members of class cbd600Node ----*/

   tbd_node_ptrs      bd600GetNodePtrs()
   {
         return m_NodePtrs; //schmutz
   }
      
protected:
      /* Variables */
      tgg00_BasisError       &m_TrError;       /* For a convenient access                   */
      tbd_nodeptr            &m_pNode;         /* For a convenient access                   */
      cbd300_InvCurrentBasis &m_Current;       /* Transactions context, necessary for       */
                                               /* DataCache operations and errorhandling    */
    tbd_node_ptrs           m_NodePtrs;      /* DataCache: Anchor to the page and the     */
                                               /*            Caches Control Block           */
      tbd_node_request        m_RequestKind;   /* DataCache: for_update = locked exclusive  */
                                               /*            for_read   = locked shared     */
      tbd00_PageLockMode      m_PageLockMode;  /* DataCache: tbd00_PageLockMode::fromConst(plmLock_ebd00) means the DC     */
                                               /*            controls the concurrent        */
                                                                   /*            page access                    */
      tsp00_Int4             *m_pRecIndexList; /* The OffsetList for the Records            */

      /* Methods */
      void             bd600_GetPageFromDataCache    (tsp00_PageNo            PageNo,
                                                        const tbd_node_request &RequestKind);
    void             bd600_CheckLeafCount          () const;
    void             bd600_GetIndexNodeStatistic   (tgg00_SampleInfo  &SampleInfo,
                                                        tbd_stat_aux_vars &StatAuxVars) const;
      void             bd600_GetInvLeafStatistic     (tgg00_SampleInfo  &SampleInfo) const;
      void             bd600_GetInvLeafSelectivity   (tgg00_SampleInfo  &SampleInfo) const;
      void             bd600_GetSubTreeLeafStatistic (tgg00_SampleInfo  &SampleInfo) const;
    void             bd600_GetSubTreeStatistics    (tgg00_RecPtr       pRec,
                                                                      tgg00_SampleInfo  &SampleInfo) const;
      void               bd610_Merge                   (cbd600_Node &SourceNode,
                                                                    tsp00_Int4  Offset);
      void               bd610_AddPosition             (tsp00_Int4 RecPos, 
                                                                      tsp00_Int4 RecIndex);
      void               bd610_DelPosition             (tsp00_Int4 RecIndex);
      void               bd610_SortForDistribution     (tsp00_Int4 LastDistribIndex);
      void               bd610_UpdatePositions         (tsp00_Int4 TargetPos,
                                                                        tsp00_Int4 ShiftLen);
      void               bd610_UpdatePositionsRange    (tsp00_Int4 FirstIndex,
                                                                            tsp00_Int4 LastIndex,
                                                                            tsp00_Int4 MinRecOffset,
                                                                          tsp00_Int4 MaxRecOffset,
                                                                            tsp00_Int4 ShiftLen);
      void               bd610_QuickSort               (tsp00_Int4      NumRecPosElem,
                                                                      tgg00_PagePos  *pMinRecPosElem);
      void             bd610_CopyPointerList         (const cbd600_Node &SrcNode);
      void             bd610_DelHighIndexPositions   (tsp00_Int4 NumDeletedRecords);

    tsp00_Int4       bd620_CalcBlockLenAndSetIndexToNextBlock (cbd600_Node &AuxNode,
                                                                                   tsp00_Int4  &CurrIndex, 
                                                                                   tsp00_Int4   MaxIndex);
      void               bd620_DeleteRecordsFromPage     (bool       bRightDistribution,
                                                                              tsp00_Int4 RecIndex);
      void               bd620_FindOptimDistribForDelete (cbd600_Node &Neighbor,
                                                                                bool         bRightDistribution,
                                                                                tsp00_Int4   Covering,
                                                                                tsp00_Int4   NeighborCovering,
                                                                                bool        &bDistributionFound,
                                                                                tsp00_Int4  &OptimRecIndex);
      void               bd620_FindOptimDistribForInsert (bool              bRightDistribution,
                                                                                tsp00_Int4        RequiredLen,
                                                                                tsp00_Int4        NeighborCovering,
                                                                                tsp00_Int4        RecIndex,
                                                                                bool             &bDistributionFound,
                                                                                tsp00_Int4       &OptimRecIndex,
                                                                                bool             &bMoveNewRecordIntoNeighbor);
      void               bd620_FindOptimDistribForUpdate (bool              bRightDistribution,
                                                                                tsp00_Int4        RequiredLen,
                                                                                tsp00_Int4        NeighborCovering,
                                                                                tsp00_Int4        RecIndex,
                                                                                bool             &bDistributionFound,
                                                                                tsp00_Int4       &OptimRecIndex,
                                                                          bool             &bMoveRecordIntoNeighbor);
      void             bd620_MergeNodes                (cbd600_Node &LeftNode);
};
/*! endclass: cbd600_Node */

/*===========================================================================*
 *  DEFINITION OF METHODS                                                    *
 *===========================================================================*/

/*---------------------------------------------------------------------------*/

inline void
00350 cbd600_Node::bd600CopyBody (cbd600_Node &SrcNode)
{
      ROUTINE_DBG_MEO00 ("bd600CopyBody");

      g10mv( __FILE__, 1,    
            sizeof (*SrcNode.m_pNode), sizeof(*m_pNode),
            SrcNode.m_pNode, BODY_BEG_BD00, 
            m_pNode,         BODY_BEG_BD00,
            SrcNode.m_pNode->nd_bottom() - BODY_BEG_BD00, m_TrError);
      if ( e_ok != m_TrError ) return;

    tsp00_Int4 PointerListSize = SrcNode.m_pNode->nd_record_cnt() * POINTERSIZE_BD00;

    g10mv( __FILE__,   1,
            sizeof (*SrcNode.m_pNode), sizeof(*m_pNode),
            SrcNode.m_pNode, MAX_BOTTOM_BD00 - PointerListSize, 
            m_pNode,         MAX_BOTTOM_BD00 - PointerListSize,
            PointerListSize, m_TrError);
      if ( e_ok != m_TrError ) return;

      m_pNode->nd_bottom()        = SrcNode.m_pNode->nd_bottom();
      m_pNode->nd_record_cnt()    = SrcNode.m_pNode->nd_record_cnt();
    m_pNode->ndLeafCount_bd00() = SrcNode.m_pNode->ndLeafCount_bd00(); //PTS 1103857 AK 02-09-1999

#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
      t01p2int4 (bd_inv, "CopyNodeBody", SrcNode.m_pNode->nd_id(),
                           "to Node  #> ", m_pNode->nd_id());
#   endif
}

/*---------------------------------------------------------------------------*/

inline void
cbd600_Node::bd600CountRecords (tsp00_KeyPtr  pStartKey, 
                                                tsp00_Int4    StartKeyLen, 
                                                tsp00_KeyPtr  pStopKey,
                                                tsp00_Int4    StopKeyLen,
                                                tsp00_Int4   &RecordCnt) const
{
      ROUTINE_DBG_MEO00 ("bd600CountRecords");
      
      tsp00_Int4       StartRecIndex;
      tbd_searchresult KeySearchResult;
      
      bd600SearchRecord (pStartKey, StartKeyLen, StartRecIndex, KeySearchResult);
      if (lastfound == KeySearchResult || nonefound == KeySearchResult)
            RecordCnt = 0;
      else
      {
            tsp00_Int4       StopRecIndex;
            
            bd600SearchRecord (pStopKey, StopKeyLen, StopRecIndex, KeySearchResult);
            if (nextfound != KeySearchResult)
                  RecordCnt = StopRecIndex - StartRecIndex + 1;
            else
                  RecordCnt = StopRecIndex - StartRecIndex;
      }                 
}

/*---------------------------------------------------------------------------*/

inline tsp00_Int4
cbd600_Node::bd600RecOffset (tsp00_Int4 RecIndex) const
{
      return *(m_pRecIndexList-RecIndex) - POS_OFF_DIFF_BD00;
}

/*---------------------------------------------------------------------------*/

inline tgg00_RecPtr
cbd600_Node::bd600RecPtr (tsp00_Int4 RecIndex) const
{
      return REINTERPRET_CAST(tgg00_RecPtr,REINTERPRET_CAST(tsp00_BytePtr,m_pNode)+bd600RecOffset(RecIndex));
}

/*---------------------------------------------------------------------------*/

inline tgg00_RecPtr
cbd600_Node::bd600FirstRecPtr (tbd_nodeptr pNode)
{
      return REINTERPRET_CAST(tgg00_RecPtr,REINTERPRET_CAST(tsp00_BytePtr,pNode)+pNode->nd_pointer_list() [MAX_POINTERINDEX_BD00 - POS_OFF_DIFF_BD00] - POS_OFF_DIFF_BD00);
}

/*---------------------------------------------------------------------------*/

inline tgg00_RecPtr
cbd600_Node::bd600FirstRecPtr() const
{
     return bd600FirstRecPtr( m_pNode );
}

/*---------------------------------------------------------------------------*/

inline bool
cbd600_Node::bd600IsAccessable () const
{
      return NULL != m_NodePtrs.np_ptr();
}

/*---------------------------------------------------------------------------*/

inline void
cbd600_Node::bd600_GetPageFromDataCache (tsp00_PageNo            PageNo,
                                                     const tbd_node_request &RequestKind)
{
    ROUTINE_DBG_MEO00 ("bd600_GetPageFromDataCache");

      m_RequestKind = RequestKind;

      if ( bd600IsAccessable() )
        g01abort (csp3_bd_msg, csp3_n_btree, "bd600_GetPage:np_ptr!=NIL",
                          m_pNode->nd_id());

      bd13GetNode (m_Current, PageNo, m_PageLockMode, m_RequestKind, m_NodePtrs);
      if (e_ok != m_TrError) return;

      m_pRecIndexList = &m_pNode->nd_pointer_list() [MAX_POINTERINDEX_BD00 - POS_OFF_DIFF_BD00];
}

/*---------------------------------------------------------------------------*/

inline void
cbd600_Node::bd600GetNode (tsp00_PageNo            PageNo,
                                     const tbd_node_request &RequestKind)
{
    ROUTINE_DBG_MEO00 ("bd600GetNode");

      bd600_GetPageFromDataCache (PageNo, RequestKind);
}

/*---------------------------------------------------------------------------*/

inline void
cbd600_Node::bd600New (tsp00_Int4 Level)
{
    ROUTINE_DBG_MEO00 ("bd600New");

      if (NULL != m_pNode)
        g01abort (csp3_bd_msg, csp3_n_btree,
                      "GBD600: New not allowed  ",
                          m_pNode->nd_id());

      b13new_node (Level, m_NodePtrs, m_Current);
      if (e_ok != m_TrError) return;
      m_pRecIndexList = &m_pNode->nd_pointer_list() [MAX_POINTERINDEX_BD00 - POS_OFF_DIFF_BD00];
      if ( LEAF_LEVEL_BD00 == Level ) m_pNode->ndLeafCount_bd00() = 1;
}

/*---------------------------------------------------------------------------*/

inline tgg00_RecPtr
cbd600_Node::bd600NewRecPtr()
{
    ROUTINE_DBG_MEO00 ("bd600NewRecPtr");
      /* this contructs a pointer to a new record on the node m_pNode */      
      return tgg00_RecPtr (tsp00_BytePtr(m_pNode) + m_pNode->nd_bottom() - POS_OFF_DIFF_BD00);
}

/*---------------------------------------------------------------------------*/

inline tsp00_Int4
cbd600_Node::bd600Covering () const
{
    ROUTINE_DBG_MEO00 ("bd600Covering");

      return m_NodePtrs.np_ptr()->nd_bottom() - BODY_BEG_BD00 +
               (m_NodePtrs.np_ptr()->nd_record_cnt() << DIVISOR_POINTERSIZE_BD00);
}


/*---------------------------------------------------------------------------*/

inline void
cbd600_Node::bd600Exchange (cbd600_Node &Neighbor)
{
      ROUTINE_DBG_MEO00 ("bd600Exchange");

#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
      t01p2int4 (bd_inv, "Exchange:   ", (NULL!=m_pNode)?(m_pNode->nd_id()):(-1),
                           "with Node:  ", (NULL!=Neighbor.m_pNode)?(Neighbor.m_pNode->nd_id()):(-1));
#   endif

    tbd_node_ptrs  AuxNodePtrs      = m_NodePtrs;
      tsp00_Int4    *pAuxRecIndexList = m_pRecIndexList;

    m_NodePtrs               = Neighbor.m_NodePtrs;
      m_pRecIndexList          = Neighbor.m_pRecIndexList;

    Neighbor.m_NodePtrs      = AuxNodePtrs;
      Neighbor.m_pRecIndexList = pAuxRecIndexList;
}

/*---------------------------------------------------------------------------*/

inline void
cbd600_Node::bd600GetNode (tsp00_PageNo PageNo)
{
      bd600_GetPageFromDataCache (PageNo, m_RequestKind);
}

/*---------------------------------------------------------------------------*/

inline bool
cbd600_Node::bd600IsLeaf() const
{
      return LEAF_LEVEL_BD00 == m_NodePtrs.np_ptr()->nd_level();
}

/*---------------------------------------------------------------------------*/

inline bool
cbd600_Node::bd600IsUpdateable () const
{
      return nr_for_update == m_RequestKind;
}

/*---------------------------------------------------------------------------*/

inline bool
cbd600_Node::bd600IsRoot() const
{
      return m_NodePtrs.np_ptr()->nd_id()== m_NodePtrs.np_ptr()->nd_root();
}

/*---------------------------------------------------------------------------*/

inline tsp00_Int4
cbd600_Node::bd600Level() const
{
      return m_NodePtrs.np_ptr()->nd_level();
}

/*---------------------------------------------------------------------------*/

inline tsp00_PageNo
cbd600_Node::bd600RightNeighbor() const
{
      return m_NodePtrs.np_ptr()->nd_right();
}


#if COMPILEMODE_MEO00 >= SLOW_MEO00 

/*---------------------------------------------------------------------------*/

inline void 
cbd600_Node::bd600PrintPointerList () const
{
      for (tsp00_Int4 CurrRecIndex = FIRST_REC_INDEX_BD00;
           CurrRecIndex < m_pNode->nd_record_cnt();
             CurrRecIndex++)
      {
            t01p4int4 (bd_oflw, "RecIndex(0) ",
                  CurrRecIndex,
                  *(m_pRecIndexList-CurrRecIndex),
            bd600RecPtr(CurrRecIndex)->recLen_gg00(),
            bd600RecPtr(CurrRecIndex)->recKeyLen_gg00());
      }
}

/*---------------------------------------------------------------------------*/

inline void 
cbd600_Node::bd600Print () const
{
      t01int4   (bd_inv, "NodeId      ", m_pNode->nd_id());
      t01p2int4 (bd_inv, "RecordCnt   ", m_pNode->nd_record_cnt(),
                           "Bottom      ", m_pNode->nd_bottom());
      t01addr   (bd_inv, "NodeAddr    ", m_pNode);
      bd600PrintPointerList ();
      t01sname  (bd_oflw, "Body        ");
      t01page   (bd_oflw, *m_NodePtrs.np_ptr_buf(), POS_OFF_DIFF_BD00, m_pNode->nd_bottom());
}


#endif

/*---------------------------------------------------------------------------*/

inline tsp00_PageNo
cbd600_Node::bd600GetId () const
{
      return m_NodePtrs.np_ptr()->nd_id();
}

/*---------------------------------------------------------------------------*/

inline tsp00_Int4
cbd600_Node::bd600PageConverterVersion () const
{
      return m_NodePtrs.np_ptr()->nd_conv_version();
}

/*---------------------------------------------------------------------------*/
inline void
cbd600_Node::bd600Free ()
{
    ROUTINE_DBG_MEO00 ("bd600Free");

    if ( NULL == m_NodePtrs.np_ptr() ) return;

      const tsp00_PageNo FreePno = bd600GetId();

      if ( FreePno == m_NodePtrs.np_ptr()->nd_root() )
      {
            m_Current.bd300FreeRoot ();

            m_NodePtrs.np_ptr()   = NULL;
            m_NodePtrs.np_cbptr() = NULL;
      }
      else
      {
        const SAPDB_Int4 freePageVersion = bd600PageConverterVersion();

            bd600Release (nr_for_update == m_RequestKind);
            bd13FreePageNo (FreePno, freePageVersion, m_Current);
      }
}


/*---------------------------------------------------------------------------*/

inline tbd_nodeptr
cbd600_Node::bd600GetNodePtr ()
{
      return m_NodePtrs.np_ptr();
}

/*---------------------------------------------------------------------------*/

inline tsp00_Int4 &
cbd600_Node::bd600LeafCount()
{
      return m_NodePtrs.np_ptr()->ndLeafCount_bd00();
}

/*---------------------------------------------------------------------------*/

inline tsp00_Int4
cbd600_Node::bd600NumRecords () const
{
      return m_pNode->nd_record_cnt();
}

/*---------------------------------------------------------------------------*/

inline bool
cbd600_Node::bd600SpaceIsAvailable (tsp00_Int4 RequiredLen) const
{
    ROUTINE_DBG_MEO00 ("bd600SpaceIsAvailable");
    
    // In case of an insert RequiredLen contains the recordlength as well
    // as the bytes for the pointerlist entry
    
    return RequiredLen + m_pNode->nd_bottom() <= MAX_BOTTOM_BD00 - 
        (m_pNode->nd_record_cnt() << DIVISOR_POINTERSIZE_BD00);
}

/*---------------------------------------------------------------------------*/
inline tsp00_Int4
cbd600_Node::bd600SumKeyLen () const
{
      tsp00_Int4 ResultLen = 0;
      for (tsp00_Int4 RecIndex = FIRST_REC_INDEX_BD00;
           RecIndex < m_pNode->nd_record_cnt();
             RecIndex ++)
      {
            ResultLen += bd600RecPtr (RecIndex)->recKeyLen_gg00();
      }
      return ResultLen;
}

/*---------------------------------------------------------------------------*/
inline tgg00_BasisError
cbd600_Node::bd600TrError() const
{
      return m_TrError;
}

/*---------------------------------------------------------------------------*/
inline tgg00_BasisError &
cbd600_Node::bd600TrError()
{
      return m_TrError;
}

/*---------------------------------------------------------------------------*/

inline tsp00_Int4       
cbd600_Node::bd600MaxRecIndex() const
{
  return m_pNode->nd_record_cnt() - 1;
}

/*---------------------------------------------------------------------------*/

inline void 
cbd600_Node::bd600Move (tsp00_PageNo NewId)
{
      ROUTINE_DBG_MEO00 ("bd600Move");

      if ( bd600IsAccessable() )
    {
        if ( NewId == bd600GetId() )
            return;
        
        bd600Release(nr_for_update == m_RequestKind);
    }

      bd13GetNode (m_Current, NewId, m_PageLockMode, m_RequestKind, m_NodePtrs);
      if (e_ok != m_TrError) return;

      m_pRecIndexList = &m_pNode->nd_pointer_list() [MAX_POINTERINDEX_BD00 - POS_OFF_DIFF_BD00];
}

/*---------------------------------------------------------------------------*/
 
inline void
cbd600_Node::bd600EvalSepKeyLen (tsp00_KeyPtr pKey,
                                               tsp00_Int4   KeyLen,
                                               tsp00_KeyPtr pNewSepKey,
                                               tsp00_Int2   &NewSepKeyLen) const
{
      ROUTINE_DBG_MEO00 ("bd600EvalSepKeyLen");

      tsp00_Int4 ByteOffset;
      tsp00_Int4 MinSepKeyLen;

      /* predsep < sep */
      if ( KeyLen <= NewSepKeyLen )
            MinSepKeyLen = KeyLen;
      else
            MinSepKeyLen = NewSepKeyLen;

      for ( ByteOffset=0;
            (*(pKey+ByteOffset) == *(pNewSepKey+ByteOffset)) &&
              (ByteOffset < MinSepKeyLen);
              ++ByteOffset)
            /*empty*/;

      if ( ByteOffset < MinSepKeyLen )
      {
            if ( *(pKey+ByteOffset) > *(pNewSepKey+ByteOffset) )
            {
                  g01opmsg (sp3p_console, sp3m_error,
                          BD600_X1_INVALID_SEPARATOR_SP03, csp3_n_btree,
                          "BD600: predsep.k > sep.k", 0);
                  m_TrError = e_invalid_leaves_structure;
                  return;
            }
      }
      else
      {
            if ( MinSepKeyLen == NewSepKeyLen )
            {
                  g01opmsg (sp3p_console, sp3m_error,
                          BD600_X2_INVALID_SEPARATOR_SP03, csp3_n_btree,
                          "BD600: min_len = sep.len", 0);
                  m_TrError = e_invalid_leaves_structure;
                  return;
            }
      }

      /* include the next nonzero byte: */
      if ( ByteOffset < sizeof (tsp00_Key) )
      {
            for ( /*empty*/;
                  (0 == *(pNewSepKey+ByteOffset)) && (ByteOffset < NewSepKeyLen);
                    ++ByteOffset)
                  /*empty*/ ;
            NewSepKeyLen = ByteOffset+1;
      }
}
 

/*---------------------------------------------------------------------------*/
 
inline void
00828 cbd600_Node::bd600BuildSeparatorKey (bool          bNodeIsLeft,
                                                     tsp00_KeyPtr  pNeighborKey,
                                     tsp00_Int4    NeighborKeyLen,
                                     tsp00_KeyPtr &pNewSepKey,
                                     tsp00_Int2   &NewSepKeyLen) const
{
      ROUTINE_DBG_MEO00 ("bd600BuildSeparatorKey1");

      tgg00_RecPtr pRec;

      if ( bNodeIsLeft )
      {
            pRec = bd600RecPtr (bd600MaxRecIndex());
            pNewSepKey   = pNeighborKey;
            NewSepKeyLen = NeighborKeyLen;
            if ( LEAF_LEVEL_BD00 == m_pNode->nd_level() )
                  bd600EvalSepKeyLen (tsp00_BytePtr(pRec)+cgg_rec_key_offset, pRec->recKeyLen_gg00(),
                        pNewSepKey, NewSepKeyLen);
      }
      else
      {
            pRec = bd600RecPtr (FIRST_REC_INDEX_BD00);
            pNewSepKey   = tsp00_BytePtr(pRec)+cgg_rec_key_offset;
            NewSepKeyLen = pRec->recKeyLen_gg00();
            if ( LEAF_LEVEL_BD00 == m_pNode->nd_level() )
                  bd600EvalSepKeyLen (pNeighborKey, NeighborKeyLen, pNewSepKey, NewSepKeyLen);
      }

#   if COMPILEMODE_MEO00 >= SLOW_MEO00
      t01moveobj (bd_index, pRec, cgg_rec_key_offset+POS_OFF_DIFF_BD00, pRec->recKeyLen_gg00());
      t01moveobj (bd_index, pNewSepKey, POS_OFF_DIFF_BD00, NewSepKeyLen);
#   endif

      if ( e_invalid_leaves_structure == m_TrError )
            bd600Dump (csp3_bd_msg, "bd600BuildNewSeparator: ");
}

/*---------------------------------------------------------------------------*/
 
inline void
00868 cbd600_Node::bd600BuildSeparatorKey (cbd600_Node  &RightNeighbor,
                                                     tsp00_KeyPtr &pSepKey,
                                                     tsp00_Int2   &SepKeyLen) const
{
      ROUTINE_DBG_MEO00 ("bd600BuildSeparatorKey2");

      tgg00_RecPtr pRec = RightNeighbor.bd600RecPtr (FIRST_REC_INDEX_BD00);

      pSepKey   = REINTERPRET_CAST(tsp00_BytePtr,pRec) + cgg_rec_key_offset;
      SepKeyLen = pRec->recKeyLen_gg00();

      pRec      = bd600RecPtr (bd600MaxRecIndex());
      
#   if COMPILEMODE_MEO00 >= SLOW_MEO00
      t01moveobj (bd_index, pRec, cgg_rec_key_offset+POS_OFF_DIFF_BD00, pRec->recKeyLen_gg00());
      t01moveobj (bd_index, pSepKey, POS_OFF_DIFF_BD00, SepKeyLen);
#   endif

      if ( LEAF_LEVEL_BD00 == m_pNode->nd_level() )
            bd600EvalSepKeyLen (tsp00_BytePtr(pRec)+cgg_rec_key_offset, pRec->recKeyLen_gg00(),
                  pSepKey, SepKeyLen);

      if ( e_invalid_leaves_structure == m_TrError )
      {
            bd600Dump (csp3_bd_msg, "bd600BuildSeparator: lef");
            RightNeighbor.bd600Dump (csp3_bd_msg, "bd600BuildSeparator: rig");
      }
#   if COMPILEMODE_MEO00 >= SLOW_MEO00
      t01moveobj (bd_index, pSepKey, POS_OFF_DIFF_BD00, SepKeyLen);
#   endif
}
 
/*---------------------------------------------------------------------------*/

inline
00903 cbd600_Node::cbd600_Node (const cbd600_Node &Node)
: m_TrError       (Node.m_TrError),
  m_Current       (Node.m_Current),
  m_RequestKind   (Node.m_RequestKind),
  m_PageLockMode  (Node.m_PageLockMode),
  m_pRecIndexList (Node.m_pRecIndexList),
  m_pNode (m_NodePtrs.np_ptr())
{
  if (e_ok != m_TrError) return; // PTS 1104721 TS 1999-11-23

  bd13GetNode (m_Current, Node.bd600GetId(), m_PageLockMode, m_RequestKind, m_NodePtrs);
}

/*---------------------------------------------------------------------------*/

inline
00919 cbd600_Node::cbd600_Node (cbd300_InvCurrentBasis   &Current,
                              const tbd00_PageLockMode &PageLockMode)
: m_TrError       (Current.curr_trans->trError_gg00),
  m_pNode         (m_NodePtrs.np_ptr()),
  m_Current       (Current),
  m_RequestKind   (Current.bd300RootRequestKind()),
  m_PageLockMode  (PageLockMode),
  m_pRecIndexList (NULL)
{
    ROUTINE_DBG_MEO00 ("cbd600_Node_Root");

    if (e_ok != m_TrError) return; // PTS 1104721 TS 1999-11-23

    m_NodePtrs.np_ptr()   = NULL;
    m_NodePtrs.np_cbptr() = NULL;
      bd600GetNode (m_Current.curr_tree_id.fileRoot_gg00());
}

/*---------------------------------------------------------------------------*/

inline
00940 cbd600_Node::cbd600_Node (cbd300_InvCurrentBasis   &Current,
                                      const tbd_node_request   &RequestKind,
                                      const tbd00_PageLockMode &PageLockMode)
: m_TrError       (Current.curr_trans->trError_gg00),
  m_pNode         (m_NodePtrs.np_ptr()),
  m_Current       (Current),
  m_RequestKind   (RequestKind),
  m_PageLockMode  (PageLockMode),
  m_pRecIndexList (NULL)
{
    ROUTINE_DBG_MEO00 ("cbd600_Node");

    m_NodePtrs.np_ptr()   = NULL;
    m_NodePtrs.np_cbptr() = NULL;
}

/*---------------------------------------------------------------------------*/

inline
00959 cbd600_Node::cbd600_Node (cbd300_InvCurrentBasis   &Current,
                                      const tbd_node_request   &RequestKind,
                                      tsp00_PageNo              Pno,
                                      const tbd00_PageLockMode &PageLockMode)
: m_TrError       (Current.curr_trans->trError_gg00),
  m_pNode         (m_NodePtrs.np_ptr()),
  m_Current       (Current),
  m_RequestKind   (RequestKind),
  m_PageLockMode  (PageLockMode),
  m_pRecIndexList (NULL)
{
    ROUTINE_DBG_MEO00 ("cbd600_Node_Pno");

   if (e_ok != m_TrError) return; // PTS 1104721 TS 1999-11-23

    m_NodePtrs.np_ptr()   = NULL;
    m_NodePtrs.np_cbptr() = NULL;
      bd600GetNode (Pno);
}

/*---------------------------------------------------------------------------*/

inline
00982 cbd600_Node::cbd600_Node (cbd300_InvCurrentBasis   &Current,
                                      const tbd_node_request   &RequestKind,
                                      tbd_node_ptrs            &Nptr,
                                      const tbd00_PageLockMode &PageLockMode)
: m_TrError       (Current.curr_trans->trError_gg00),
  m_pNode         (m_NodePtrs.np_ptr()),
  m_Current       (Current),
  m_NodePtrs      (Nptr),
  m_RequestKind   (RequestKind),
  m_PageLockMode  (PageLockMode),
  m_pRecIndexList (&m_pNode->nd_pointer_list() [MAX_POINTERINDEX_BD00 - POS_OFF_DIFF_BD00])
{
    ROUTINE_DBG_MEO00 ("cbd600_Node_PascalInterface");
}


/*---------------------------------------------------------------------------*/

inline
01001 cbd600_Node::cbd600_Node (cbd300_InvCurrentBasis   &Current,
                                      tbd_node                 &Buffer,
                                      const tbd00_PageLockMode &PageLockMode)
: m_TrError       (Current.curr_trans->trError_gg00),
  m_pNode         (m_NodePtrs.np_ptr()),
  m_Current       (Current),
  m_RequestKind   (tbd_node_request::fromConst(nr_for_update)),
  m_PageLockMode  (PageLockMode),
  m_pRecIndexList (&Buffer.nd_pointer_list() [MAX_POINTERINDEX_BD00 - POS_OFF_DIFF_BD00])
{
    ROUTINE_DBG_MEO00 ("cbd600_Node_Buffer");

    if (e_ok != m_TrError) return; // PTS 1104721 TS 1999-11-23

    m_NodePtrs.np_ptr()   = &Buffer;
    m_NodePtrs.np_cbptr() = NULL;
}


/*---------------------------------------------------------------------------*/

01022 inline cbd600_Node::~cbd600_Node ()
{
    ROUTINE_DBG_MEO00 ("cbd600_~Node");

#     if COMPILEMODE_MEO00 >= SLOW_MEO00 
    t01int4 (bd_inv, "Node:       ", (m_pNode != NULL)?(m_pNode->nd_id()):(NIL_PAGE_NO_GG00));
#     endif

      bd600Release (nr_for_update == m_RequestKind);

      if ( e_page_in_wrong_tree == m_TrError)
    {
        bd600Dump (csp3_bd_msg, "~cbd600_Node: PageInWron");
    }

#     if COMPILEMODE_MEO00 >= SLOW_MEO00 
      if ( e_ok != m_TrError)
            t01basis_error (bd_inv, "TrError     ", m_TrError);
#     endif
}

#endif  /* GBD600_H */

Generated by  Doxygen 1.6.0   Back to index