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

vbd620.cpp

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

  module      : vbd620.cpp

  -------------------------------------------------------------------------

  responsible : UweH

  special area: OverflowHandling and UnderflowHandling within a Node
  description : 


  last changed: 1999-09-15  13:44
  see also    : example.html ...

  -------------------------------------------------------------------------

  copyright:    (c) 1998-2004 SAP AG



    ========== licence begin  GPL
    Copyright (c) 1998-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


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

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

#include "gsp00.h"
#include "ggg00.h"
#include "gbd00.h"
#include "gbd500.h"
#include "gbd600.h"
#include "hbd102.h"  // PTS 1103980 JA 1999-09-15
#include "hgg01_1.h" // g01opmsg
#include "SAPDB/SAPDBCommon/SAPDB_RangeCode.hpp" // Kernel_move_and_fill
#include "hgg10.h"

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

#define RIGHT_DISTRIBUTION_BD620    true
#define LEFT_DISTRIBUTION_BD620   ! RIGHT_DISTRIBUTION_BD620

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



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



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



/*===========================================================================*
 *  GLOBAL VARIABLES                                                         *
 *===========================================================================*/



/*===========================================================================*
 *  LOCAL VARIABLES                                                          *
 *===========================================================================*/



/*===========================================================================*
 *  LOCAL FUNCTIONS (PROTOTYPES)                                             *
 *===========================================================================*/


/*===========================================================================*
 *  GLOBAL FUNCTIONS (CODE)                                                  *
 *===========================================================================*/

/*===========================================================================*
 *  LOCAL FUNCTIONS (CODE)                                                   *
 *===========================================================================*/
 
tsp00_Int4   
cbd600_Node::bd620_CalcBlockLenAndSetIndexToNextBlock (cbd600_Node &AuxNode,
                                                                           tsp00_Int4  &CurrIndex, 
                                                                           tsp00_Int4   MaxIndex)     
 {
    ROUTINE_DBG_MEO00 ("bd620_CalcBlockLenAndSetIndexToNextBlock");

      /* This function caluclates the the length of the block starting at the CurrIndex record */
      /* of records which follow each other in the pointerlist as well as in the record part  */
      /* of thge page. Moreover CurrIndex is set to the first record of the next block         */

    if (CurrIndex < MaxIndex) return 0;

    tsp00_Int4   BlockLen       = 0;
    tsp00_Int4   FirstRecOffset = AuxNode.bd600RecOffset (CurrIndex);
    tsp00_Int4   NextRecOffset;
    tgg00_RecPtr pRec           = tgg00_RecPtr (tsp00_BytePtr(m_pNode) + FirstRecOffset);
            
    while (CurrIndex > MaxIndex)
    {
        BlockLen      += bd102RecAlign(pRec->recLen_gg00());
            NextRecOffset  = AuxNode.bd600RecOffset (CurrIndex - 1);
        if (FirstRecOffset + BlockLen != NextRecOffset) break;
        --CurrIndex;
        pRec = tgg00_RecPtr (tsp00_BytePtr(m_pNode) + NextRecOffset);
    }
      if (CurrIndex == MaxIndex) BlockLen += bd102RecAlign(pRec->recLen_gg00());
    --CurrIndex;
    return BlockLen;
}
 
/*---------------------------------------------------------------------------*/

void
cbd600_Node::bd620_DeleteRecordsFromPage (bool         bRightDistribution,
                                                              tsp00_Int4 RecIndex)
{
      /* if bRightDistribution = true this routine removes all   */
      /* records from the current page with Indexes <= RecIndex. */
      /* if if bRightDistribution = true  all records with       */
      /* Indexes >= RecIndex are removed                         */

    ROUTINE_DBG_MEO00 ("bd620_DeleteRecordsFromPage");
    
      tbd_node          Buffer;               // must be aligned for pointers
      cbd600_Node       AuxNode (m_Current, Buffer);

    tsp00_Int4        DestOffset;
    tsp00_Int4        SrcOffset;
    tsp00_Int4        ShiftLen;
    tsp00_Int4        SumShiftLen       = 0;
    tsp00_Int4        MoveLen;
    tsp00_Int4        NumDistribIndexes;
    tsp00_Int4        CurrMoveIndex;
    tsp00_Int4        MaxMoveIndex;
    tsp00_Int4        MinMoveIndex;
    tsp00_Int4        CurrDistIndex;
    tsp00_Int4        MaxDistIndex;

      AuxNode.bd610_CopyPointerList (*this);

    if (e_ok != m_TrError) return;

      if (bRightDistribution)
      {
            if ( RecIndex > bd600MaxRecIndex() ) return; /* nothing to remove */
            
            if (RecIndex > FIRST_REC_INDEX_BD00)
                  MinMoveIndex =  RecIndex - 1;
            else 
            {
                  /* remove all records from page */
                  m_pNode->nd_bottom()     = BODY_BEG_BD00;
                  m_pNode->nd_record_cnt() = 0;
                  return;
            }
            
            NumDistribIndexes = bd600MaxRecIndex() - RecIndex + 1;
            CurrDistIndex     = bd600MaxRecIndex();
            MaxDistIndex      = RecIndex;
            MaxMoveIndex      = FIRST_REC_INDEX_BD00;
            CurrMoveIndex     = MinMoveIndex;
            
            AuxNode.bd610_SortForDistribution (MaxDistIndex);
      }
      else
      {
            if (RecIndex < FIRST_REC_INDEX_BD00) return; /* nothing to remove */
            
            if (RecIndex < bd600MaxRecIndex())
                  MaxMoveIndex  = RecIndex + 1;
            else 
            {
                  /* remove all records from page */
                  m_pNode->nd_bottom()     = BODY_BEG_BD00;
                  m_pNode->nd_record_cnt() = 0;
                  return;
            }
            NumDistribIndexes = RecIndex + 1;
            CurrDistIndex     = RecIndex;
            MaxDistIndex      = FIRST_REC_INDEX_BD00;
            MinMoveIndex      = bd600MaxRecIndex();
            CurrMoveIndex     = MinMoveIndex;
            
            AuxNode.bd610_SortForDistribution (RecIndex + 1);
      }
      
      /* set DestOffset to the first beginning of the first block of connected records to be deleted */
      if (AuxNode.bd600RecOffset (CurrDistIndex) >  AuxNode.bd600RecOffset (CurrMoveIndex))
      {
            DestOffset = BODY_BEG_BD00 +
                  bd620_CalcBlockLenAndSetIndexToNextBlock (AuxNode, CurrMoveIndex, MaxMoveIndex)
                  - POS_OFF_DIFF_BD00;
            if (e_ok != m_TrError) return;
      }
      else
                  DestOffset = BODY_BEG_BD00 - POS_OFF_DIFF_BD00;

    while (CurrDistIndex >= MaxDistIndex)
    {
            /* position of the next block, consisting of records, to move */
            if (CurrMoveIndex >= MaxMoveIndex)
            {
                  SrcOffset  = AuxNode.bd600RecOffset (CurrMoveIndex);
                  if (e_ok != m_TrError) return;
            }

            /* length of the next block to be deleted */
            ShiftLen = bd620_CalcBlockLenAndSetIndexToNextBlock (AuxNode, CurrDistIndex, MaxDistIndex);
            if (e_ok != m_TrError) return;

            /* sum up shift lengths */
            SumShiftLen += ShiftLen;

            /* length of the next block to move */
        MoveLen = bd620_CalcBlockLenAndSetIndexToNextBlock (AuxNode, CurrMoveIndex, MaxMoveIndex);
            if (e_ok != m_TrError) return;
        
            /* stop if there is nothing more to move */
        if (0 == MoveLen)
            {
#           if COMPILEMODE_MEO00 >= SLOW_MEO00 
                  if (CurrMoveIndex >= MaxMoveIndex)
                  {
                        g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                              csp3_n_btree, "VBD620:rec not moved    ", CurrMoveIndex);
                        g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                              csp3_n_btree, "VBD620:rec not moved    ", MaxMoveIndex);
                  }
#           endif
                  break;
            }
            
            /* check if the source position is equal to the destination */
            /* plus the sum of the lengths of the record deleted so far */ 
#       if COMPILEMODE_MEO00 >= SLOW_MEO00 
            if (SrcOffset != DestOffset + SumShiftLen)
            {
                  g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                        csp3_n_btree, "VBD620: wrong record pos", DestOffset);
                  g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                        csp3_n_btree, "VBD620:  old  record pos", SrcOffset);
                  g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                        csp3_n_btree, "VBD620:  wanted shiftlen", SumShiftLen);
              g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                        csp3_n_btree, "VBD620: DelRecIndex     ", RecIndex);
                  AuxNode.bd600PrintPointerList ();
                  bd600PrintPointerList ();
            }
#       endif
            
            /* move the next block to the position of the deleted block of records */
            g10mv( __FILE__, 1,    
                  sizeof (*m_pNode), sizeof(*m_pNode),
                  m_pNode, POS_OFF_DIFF_BD00 + SrcOffset, 
                  m_pNode, POS_OFF_DIFF_BD00 + DestOffset,
                  MoveLen, m_TrError);
            if (e_ok != m_TrError) return;

            /* update the pointer list entries of the records in the block which was just moved */
#       if COMPILEMODE_MEO00 >= SLOW_MEO00 
            bd600PrintPointerList ();
#       endif

            bd610_UpdatePositionsRange (MaxMoveIndex, MinMoveIndex,
                  SrcOffset, SrcOffset + MoveLen, - SumShiftLen);

            if (e_ok != m_TrError) return;
            
            DestOffset += MoveLen;
    }

      m_pNode->nd_bottom()   -= SumShiftLen;

      if ( bRightDistribution)
            m_pNode->nd_record_cnt() -= NumDistribIndexes;
      else
            bd610_DelHighIndexPositions (NumDistribIndexes);

#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
      bd600PrintPointerList ();
#   endif
}


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

void
cbd600_Node::bd620_FindOptimDistribForDelete(cbd600_Node &Neighbor,
                                                                   bool         bRightDistribution,
                                                                   tsp00_Int4   Covering,
                                                                   tsp00_Int4   NeighborCovering,
                                                                   bool        &bDistributionFound,
                                                                   tsp00_Int4  &OptimRecIndex)
{
      /* OptimRecIndex is to move inclusively */

    ROUTINE_DBG_MEO00 ("bd620_FindOptimDistribForDelete");

    const tsp00_Int4          OptimOverflow  = NeighborCovering - ((Covering + NeighborCovering) >> 1);

    tsp00_Int4                StartRecIndex;
    tsp00_Int4                StopRecIndex;
    tsp00_Int4                CurrRecIndex;
    tsp00_Int4                Step;
    tsp00_Int4                Diff;
    tsp00_Int4                OptimDiff      = MAX_INT4_SP00;
    tsp00_Int4                SumOverFlow    = 0;
    tgg00_RecPtr              pRec           = NULL;

    bDistributionFound = false;
        
    /* set ranges */
    if (bRightDistribution)
    {
        Step          = 1;
        StartRecIndex = FIRST_REC_INDEX_BD00;
            StopRecIndex  = Neighbor.bd600MaxRecIndex() + 1;
    }
    else
    {
        Step          = -1;
        StartRecIndex = Neighbor.bd600MaxRecIndex();
            StopRecIndex  = FIRST_REC_INDEX_BD00 - 1;
    }
    
    for (CurrRecIndex = StartRecIndex; CurrRecIndex != StopRecIndex; CurrRecIndex += Step)
    {
        pRec = Neighbor.bd600RecPtr (CurrRecIndex);
      
        SumOverFlow += (bd102RecAlign(pRec->recLen_gg00()) + POINTERSIZE_BD00);
        
        if (Covering + SumOverFlow > FULLCOVERING_BD00) break;
        
        Diff = abs (OptimOverflow - SumOverFlow); 

        if (Diff >= OptimDiff) break;

        OptimRecIndex      = CurrRecIndex;
        OptimDiff          = Diff;
        bDistributionFound = true;
    }
    
      
#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
      t01bool   (bd_oflw, "distr found ", bDistributionFound);
      if (bDistributionFound)
      {
            t01int4   (bd_oflw, "break index ", OptimRecIndex);
            t01p2int4 (bd_oflw, "Overflow    ", SumOverFlow, "New Cov Diff", 2 * OptimDiff);           
      }
#   endif
}    

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

void
cbd600_Node::bd620_FindOptimDistribForInsert (bool              bRightDistribution,     //false : load balancing with left neighbor otherwise with the right one 
                                                                    tsp00_Int4        RequiredLen,
                                                                    tsp00_Int4        NeighborCovering,
                                                                  tsp00_Int4        RecIndex,
                                                                  bool             &bDistributionFound,
                                                                    tsp00_Int4       &OptimRecIndex,
                                                                    bool             &bMoveNewRecordIntoNeighbor)
{
    ROUTINE_DBG_MEO00 ("bd620_FindOptimDistribForInsert");

    const tsp00_Int4 Covering      = bd600Covering();
    const tsp00_Int4 OptimOverflow = Covering + RequiredLen - ((Covering + NeighborCovering + RequiredLen) >> 1);
    const tsp00_Int4 SumRecLen     = Covering + RequiredLen;
    bool bOptimDistributionFound   = false;
    bool bNoMoreDistribution       = false;
    tsp00_Int4   StartRecIndex;
    tsp00_Int4   StopRecIndex;
    tsp00_Int4   AuxRecIndex;
    tsp00_Int4   Step;
    tsp00_Int4   Diff;
    tsp00_Int4   OptimDiff         = MAX_INT4_SP00;
    tsp00_Int4   SumOverFlow       = 0;
    tgg00_RecPtr pRec              = NULL;

    bDistributionFound         = false;
    bMoveNewRecordIntoNeighbor = false;
        
    /* set ranges */
    if (bRightDistribution)
    {
        Step          = -1;
        StartRecIndex = bd600MaxRecIndex();
        StopRecIndex  = RecIndex - 1;
    }
    else
    {
        Step          = 1;
        StartRecIndex = FIRST_REC_INDEX_BD00;
        StopRecIndex  = RecIndex;
    }
    
      /* check all records which have to be moved into neighbor before the new record is moved */
    for (AuxRecIndex = StartRecIndex; AuxRecIndex != StopRecIndex; AuxRecIndex += Step)
    {
        pRec = bd600RecPtr (AuxRecIndex);
      
        SumOverFlow +=  (bd102RecAlign(pRec->recLen_gg00()) + POINTERSIZE_BD00);
        
        if (SumRecLen - SumOverFlow < FULLCOVERING_BD00 )
        {
            if (NeighborCovering + SumOverFlow > FULLCOVERING_BD00)
            {
                bNoMoreDistribution = true;
                break;
            }
            
            Diff = abs (OptimOverflow - SumOverFlow); 
            if(Diff < OptimDiff) 
            {
                OptimRecIndex      = AuxRecIndex;
                OptimDiff          = Diff;
                bDistributionFound = true;
            }
            else
            {
                bOptimDistributionFound = true;
                break;
            }
        }
    }
    
      /* check if the new record has to be moved into neighbor */
    if (!bOptimDistributionFound && !bNoMoreDistribution)
    {
        SumOverFlow += RequiredLen; 
            
            if (NeighborCovering + SumOverFlow > FULLCOVERING_BD00)
                  bNoMoreDistribution = true;
            else
            {
                  Diff = abs (OptimOverflow - SumOverFlow); 
                  if(Diff < OptimDiff) 
                  {
                        if (bRightDistribution)
                              OptimRecIndex          = RecIndex;
                        else
                              OptimRecIndex          = RecIndex - 1;
                        OptimDiff                  = Diff;
                        bDistributionFound         = true;
                        bMoveNewRecordIntoNeighbor = true;
                        
                  }
                  else
                        bOptimDistributionFound = true;
            }
            
            /* check remaining records */
            if (!bOptimDistributionFound && !bNoMoreDistribution)
            {                 
                  if (bRightDistribution)
                  {
                        StartRecIndex = StopRecIndex;
                        StopRecIndex  = FIRST_REC_INDEX_BD00 - 1;
                  }
                  else
                  {
                        StartRecIndex = StopRecIndex;
                        StopRecIndex  = bd600MaxRecIndex() + 1;
                  }
                  
                  for (AuxRecIndex = StartRecIndex; AuxRecIndex != StopRecIndex; AuxRecIndex += Step)
                  {
                        pRec = bd600RecPtr (AuxRecIndex);
                        
                        SumOverFlow +=  (bd102RecAlign(pRec->recLen_gg00()) + POINTERSIZE_BD00);
                        
                        if (NeighborCovering + SumOverFlow > FULLCOVERING_BD00) 
                              break;
                        
                        Diff = abs (OptimOverflow - SumOverFlow); 
                        if(Diff < OptimDiff) 
                        {
                              OptimRecIndex              = AuxRecIndex;
                              OptimDiff                  = Diff;
                              bDistributionFound         = true;
                        }
                        else
                        {
                              bOptimDistributionFound = true;
                              break;
                        }
                  }
            }
    }
#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
      t01bool   (bd_oflw, "distr found ", bDistributionFound);
      if (bDistributionFound)
      {
            t01int4   (bd_oflw, "break index ", OptimRecIndex);
            t01bool   (bd_oflw, "rec to neigh", bMoveNewRecordIntoNeighbor);
            t01p2int4 (bd_oflw, "Overflow    ", SumOverFlow, "New Cov Diff", 2 * OptimDiff);           
      }
#   endif
}    

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

void
cbd600_Node::bd620_FindOptimDistribForUpdate (bool              bRightDistribution,     //false : load balancing with left neighbor otherwise with the right one 
                                                                    tsp00_Int4        RequiredLen,
                                                                  tsp00_Int4        NeighborCovering,
                                                                    tsp00_Int4        RecIndex,
                                                                  bool             &bDistributionFound,
                                                                    tsp00_Int4       &OptimRecIndex,
                                                              bool             &bMoveRecordIntoNeighbor)
{
    ROUTINE_DBG_MEO00 ("bd620_FindOptimDistribForUpdate");

    const tsp00_Int4          Covering                = bd600Covering();
    const tsp00_Int4          OptimOverflow           = Covering + RequiredLen - ((Covering + NeighborCovering + RequiredLen) >> 1);
    const tsp00_Int4          SumRecLen               = Covering + RequiredLen;
    bool                      bOptimDistributionFound = false;
    bool                      bNoMoreDistribution     = false;
    tsp00_Int4                StartRecIndex;
    tsp00_Int4                StopRecIndex;
    tsp00_Int4                AuxRecIndex;
    tsp00_Int4                Step;
    tsp00_Int4                Diff;
    tsp00_Int4                OptimDiff              = MAX_INT4_SP00;
    tsp00_Int4                SumOverFlow            = 0;
    tgg00_RecPtr              pRec                   = NULL;

    bDistributionFound      = false;
      bMoveRecordIntoNeighbor = false;
        
    /* set ranges */
      StopRecIndex  = RecIndex;
    if (bRightDistribution)
    {
        Step          = -1;
        StartRecIndex = bd600MaxRecIndex();
    }
    else
    {
        Step          = 1;
        StartRecIndex = FIRST_REC_INDEX_BD00;
    }
    
    for (AuxRecIndex = StartRecIndex; AuxRecIndex != StopRecIndex; AuxRecIndex += Step)
    {
        pRec = bd600RecPtr (AuxRecIndex);
      
        SumOverFlow +=  (bd102RecAlign(pRec->recLen_gg00()) + POINTERSIZE_BD00);
        
        if (SumRecLen - SumOverFlow < FULLCOVERING_BD00 )
        {
            if (NeighborCovering + SumOverFlow > FULLCOVERING_BD00)
            {
                bNoMoreDistribution = true;
                break;
            }
            
            Diff = abs (OptimOverflow - SumOverFlow); 
            if(Diff < OptimDiff) 
            {
                OptimRecIndex      = AuxRecIndex;
                OptimDiff          = Diff;
                bDistributionFound = true;
            }
            else
            {
                bOptimDistributionFound = true;
                break;
            }
        }
    }
    
    if (!bOptimDistributionFound && !bNoMoreDistribution)
    {
        SumOverFlow += RequiredLen;
        
            if (bRightDistribution)
            {
                  StartRecIndex = StopRecIndex;
                  StopRecIndex  = FIRST_REC_INDEX_BD00 - 1;
            }
            else
            {
                  StartRecIndex = StopRecIndex;
                  StopRecIndex  = bd600MaxRecIndex() + 1;
            }
            
        for (AuxRecIndex = StartRecIndex; AuxRecIndex != StopRecIndex; AuxRecIndex += Step)
        {
            pRec = bd600RecPtr (AuxRecIndex);
                  
            SumOverFlow +=  (bd102RecAlign(pRec->recLen_gg00()) + POINTERSIZE_BD00);
            
                  if (NeighborCovering + SumOverFlow > FULLCOVERING_BD00) 
                        break;
                  
                  Diff = abs (OptimOverflow - SumOverFlow); 
                  if(Diff < OptimDiff) 
                  {
                        OptimRecIndex           = AuxRecIndex;
                        OptimDiff               = Diff;
                        bDistributionFound      = true;
                        bMoveRecordIntoNeighbor = true;
                        
                  }
                  else
                  {
                        bOptimDistributionFound = true;
                        break;
                  }
        }
    }
      
#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
      t01bool   (bd_oflw, "distr found ", bDistributionFound);
      if (bDistributionFound)
      {
            t01int4   (bd_oflw, "break index ", OptimRecIndex);
            t01bool   (bd_oflw, "rec to neigh", bMoveRecordIntoNeighbor);
            t01p2int4 (bd_oflw, "Overflow    ", SumOverFlow, "New Cov Diff", 2 * OptimDiff);           
      }
#   endif
}    

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

void
cbd600_Node::bd620_MergeNodes (cbd600_Node &LeftNode)
{
      ROUTINE_DBG_MEO00 ("bd620_MergeNodes");

      const tsp00_Int4  MoveLen     = m_pNode->nd_bottom()   - BODY_BEG_BD00;
      const tsp00_Int4  RecPosDelta = LeftNode.m_pNode->nd_bottom() - BODY_BEG_BD00;
      
#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
      t01p2int4 (bd_oflw, "MoveLen     ", MoveLen, "RecPosDelta ", RecPosDelta);
      if (LeftNode.m_pNode->nd_right() != m_pNode->nd_id())
      {
            g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                  csp3_n_btree, "VBD620: Wrong Merge Dest", LeftNode.m_pNode->nd_id());
            g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                  csp3_n_btree, "VBD620: Wrong Merge Src ", m_pNode->nd_id());
            g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_2_illegal_entrypos,
                  csp3_n_btree, "VBD620: Dest->right ", LeftNode.m_pNode->nd_right());
      }
#   endif

      /* Move all records from src node to dest node */
      g10mv( __FILE__, 6,    
            sizeof (*m_pNode), sizeof (*LeftNode.m_pNode),
            m_pNode,          BODY_BEG_BD00,
            LeftNode.m_pNode, LeftNode.m_pNode->nd_bottom(),
            MoveLen, m_TrError);

      if (e_move_error == m_TrError)
      {
            m_TrError = e_data_page_corrupted;
            LeftNode.bd600Dump (csp3_bd_msg, "bd620_MergeNodes        ");
            return;
      }
      
      LeftNode.m_pNode->nd_bottom() += MoveLen; // MoveLen is aligned
      
      /* rebuild the new PointerList of merged node */
      LeftNode.bd610_Merge (*this, RecPosDelta);

      m_pNode->nd_bottom()        = BODY_BEG_BD00;
      m_pNode->nd_record_cnt()    = 0;

      /* update the LeafCount of the TargetNode and the SourceNode */
      /* PTS 1103885 AK 02-09-1999 */
      if (LEAF_LEVEL_BD00 == LeftNode.m_pNode->nd_level()) 
      {
            LeftNode.m_pNode->ndLeafCount_bd00() += (m_pNode->ndLeafCount_bd00() - 1);
            m_pNode->ndLeafCount_bd00() = 1;
      }
      else
      {
            LeftNode.m_pNode->ndLeafCount_bd00() += m_pNode->ndLeafCount_bd00();
            m_pNode->ndLeafCount_bd00() = 0;
      }
}



/*===========================================================================*
 *  END OF CODE                                                              *
 *===========================================================================*/

Generated by  Doxygen 1.6.0   Back to index