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

vbd93.cpp

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

  module      : vbd93.cpp

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

  responsible : FerdiF

  special area: continuation files for handling objects of variable length
  description : description ...


  version     : 7.4.4.1
  last changed: 2003-09-08  11:49
  see also    : example.html ...

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

  copyright:    (c) 1998-2004 SAP AG



    ========== licence begin  GPL
    Copyright (c) 1998-2004 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 "hbd93.h"

#include "gsp03.h"
#include "gsp03_3.h"
#include "gbd05.h"
#include "hbd06.h"      /* PTS 1127804 FF 2004-FEB-17 */
#include "gbd900.h"
#include "gbd910.h"
#include "gbd930.h"

#include "hbd90.h"
#include "hbd91.h"
#include "heo66.h"
#include "hgg01_1.h"
#include "hgg01_3.h"
#include "SAPDB/SAPDBCommon/SAPDB_RangeCode.hpp" // Kernel_move_and_fill
#include "hgg10.h"
#include "hkb67.h" 

#include "liveCache/LVC_Types.hpp"
#include "Converter/Converter_IPageNoManager.hpp"
#include "KernelCommon/Kernel_OpMsg.hpp"            /* PTS 1114891 FF 2002-03-14 */

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

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

#ifdef NO_INLINES
# define _INLINE
#else
# define _INLINE    inline
#endif

#define NO_ALIGNMENT 1

#if defined (BIT64)
# define  ALIGNMENT 8
#else
# define  ALIGNMENT 4
#endif

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

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

extern cbd900_ObjFileDir          bd90ObjFileDir;
extern cbd930_GarbCollController  bd91GarbCollController;

/*===========================================================================*
 *  LOCAL VARIABLES                                                          *
 *===========================================================================*/
 
cbd900_ContObjFileDir bd93ContObjFileDir;

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

static _INLINE void
bd93_CheckContObjRoot (const tgg92_KernelOid      &RootOId,         //[inp] 
                                 const tbd900_ContObjHeader &ContObjHeader    //[inp]
                                 );

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

_INLINE static void
bd93_FindFileNoForThisObjBodySize (
                                                   const tsp00_Uint4      NewObjBodySize, //[inp]  
                                                   const tgg00_ObjFileNo  ObjFileNo,      //[inp] 
                                                   tsp00_Int4            &ContFileNo,     //[out]
                                                   tgg00_BasisError      &TrError);       //[out]

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

_INLINE static void
bd93_GetContObjBodyPointer (tbd_current_tree       &Current,         //[inp/out]
                                        const tsp00_Int4        ContObjFileNo,   //[inp]     
                                        const tsp00_PageNo      ContObjPno,      //[inp] 
                                        const tgg00_ObjPagePos  ContObjPos ,     //[inp]
                                        const tgg92_KernelOid  &OId,             //[inp] 
                                        tgg00_MessType_Enum     MessType,        //[inp]
                                        cbd05_Current          &ContCurrent,     //[out]
                                        cbd910_ContObjDataNode &NptrsBody,       //[out]
                                          tsp00_MoveObjPtr       &pObjBody);       //[out]

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

static void 
bd93_NewContObj (tbd_current_tree        &Current,                 // [inp]
                         tsp00_Int4               ContFileNo,              // [inp]
                         const tgg92_KernelOid   &RootOId,                 // [inp] 
                         cbd900_ContObjFileInfo  &ContObjFileInfo,         // [inp]
                         cbd05_Current           &ContCurrent,             // [out]
                         cbd910_ContObjDataNode  &NptrsBody,               // [out]
                         tgg00_ObjPagePos        &ContObjPos,              // [out]
                         bool                    &bNewContFileWasCreated); // [out]

/*---------------------------------------------------------------------------*/
                  
_INLINE static void 
bd93_NewContObjFromThisPage (tbd_current_tree        &Current,                  // [inp]
                                           cbd910_ContObjDataNode  &NptrsBody,                // [inp]
                                           const tgg92_KernelOid   &RootOId,                  // [inp]
                                           tgg00_ObjPagePos        &ContObjPos);              // [out]

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

_INLINE static double
bd93_OccupancyRate (int ObjBodyLen,
                              int Alignment);

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

_INLINE static void
bd93_ReleaseContObjFrame (tbd_current_tree       &Current,
                                      const tgg92_KernelOid  &OId,            
                                      cbd910_ContObjDataNode &NptrsPage,
                                      const tgg00_ObjPagePos  ContObjPos);
      
/*===========================================================================*
 *  GLOBAL FUNCTIONS (CODE)                                                  *
 *===========================================================================*/

externCpp void
bd93GetContObjFileStatistics (tbd_current_tree  &Current,
                                            tsp00_Int4        &NumAllContPages,
                                            tsp00_Int4        &NumFreeContPages,
                                            tsp00_Int4        &NumEmptyContPages)
{
    ROUTINE_DBG_MSP00 ("bd93GetContObjFileStatistics");
      
      /* the number of pages in all continuation files is calculated */
      
      tgg00_BasisError       &TrError         = Current.curr_trans->trError_gg00;
      tsp00_PageNo            SubRoot;
      const tgg00_ObjFileNo   ObjFileNo       = Current.curr_tree_id.fileObjFileNo_gg00();  //PTS 1111901 AK 24/09/2001
      cbd900_ContObjFileInfo &ContObjFileInfo = bd93ContObjFileDir[ObjFileNo];

      NumAllContPages   = 0;
      NumFreeContPages  = 0;
      NumEmptyContPages = 0;
      
      /* go trough all continuation files */
      for (int iContFileNo=1;
      (iContFileNo <= ContObjFileInfo.cfiNumContFiles_bd900) && (TrError == e_ok);
           ++iContFileNo)
      {
            /* construct Current */
        cbd05_Current ContCurrent (*Current.curr_trans, m_select);      
            ContObjFileInfo.bd900BuildFileId(ObjFileNo, iContFileNo, ContCurrent.curr_tree_id);
                         
            /* go trough all subroots of the file and sum the page counters */      
            const int & MaxNumChains = ContObjFileInfo[iContFileNo].GetChainCount();
                   
            for (int iChain=0; iChain<MaxNumChains; ++iChain)
            {
                  SubRoot = ContObjFileInfo[iContFileNo][iChain].ociSubRoot_bd900;       
                  cbd910_SubRootNode  NptrsSubRoot (ContCurrent, SubRoot, nr_for_read);               
                  if (TrError != e_ok) return;
                  
                  cbd900_SubRootPageInfo SubRootPageInfo (NptrsSubRoot);
                  
                  NumAllContPages     += SubRootPageInfo.bd900AllPageCnt();
                  NumFreeContPages    += SubRootPageInfo.bd900FreePageCnt();
            }
      }
}

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

externCpp void
bd93GetVarObjBody (tbd_current_tree      &Current,            //[inp\out] 
                           const tgg92_KernelOid &OId,                //[inp] 
                           tsp00_Int4             ExtObjBodySize,     //[inp]
                           void                  *pExtObjBody,        //[inp]
                           tbd900_ObjFrame       *pObjFrame)          //[inp]
{
      
  ROUTINE_DBG_MSP00 ("bd93GetVarObjBody");
      
      /* this function copies the object body identified by       */ 
      /* the OId at the position given by the pointer pExtObjBody */
      
  tgg00_BasisError      &TrError    = Current.curr_trans->trError_gg00;
      
  if (pObjFrame->objHeader_bd900.ohdState_gg92 != obsOccupied_egg00)
  {
    SAPDB_RangeFill (__FILE__, 1, 
            ExtObjBodySize, pExtObjBody, 1, 
            ExtObjBodySize, NIL_OBJ_FILLCHAR_BD900, 
            TrError);
  }
      else
  {
            /*  move object body into output array assigned by pExtObjBody */

            /*  get pointer to the object body*/
            tsp00_MoveObj          *pObjBody;
            cbd05_Current           ContObjCurrent;   
            cbd910_ContObjDataNode  NptrsBody (ContObjCurrent, nr_for_read);
            tbd900_VarObjBody      &VarObjBody    = *((tbd900_VarObjBody*) (pObjFrame->objBody_bd900));
            const tsp00_Int4       &ObjBodySize   = VarObjBody.vbdHeader_bd900.vhdObjSize_bd900;
            const tsp00_Int4       &ContObjFileNo = VarObjBody.vbdHeader_bd900.vhdContObjFileNo_bd900;
                  tsp00_Int4        MaxObjBodySize;
      const tgg00_ObjFileNo   ObjFileNo     = Current.curr_tree_id.fileObjFileNo_gg00(); //PTS 1111901 AK 24/09/2001
            const tsp00_Bool       &ObjectIsSplit = VarObjBody.vbdHeader_bd900.vhdObjectIsSplit_bd900; // PTS 1121823

            /* check if the given memory is large enough to accomodate the object */
    if (ExtObjBodySize < ObjBodySize)
    {
        Kernel_OpWarning  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "bd90_GetObjBody:ExtObjBodySize:" << ExtObjBodySize 
            << " ObjBodySize:" << ObjBodySize
            << " ObjFileNo:" << ObjFileNo
            << " ContObjFileNo:" << ContObjFileNo
            << " OID=" << OId.gg92GetPno() << "." << OId.gg92GetPos() << " (vers " << OId.gg92GetFrameVers() << ")";
        TrError = e_wrong_object_version; //e_buffer_limit PTS 1114891 FF 2002-03-15 ;
        return;
      }

    /*  get pointer to the var object body */
            if (0==ContObjFileNo)
            {
      // Object is completely stored in the primary container
      pObjBody       = (tsp00_MoveObj*) VarObjBody.vbdBody_bd900;
      MaxObjBodySize = bd90ObjFileDir[ObjFileNo].GetObjBodySize();

      SAPDB_RangeMove( __FILE__, 21, 
            MaxObjBodySize, ExtObjBodySize,
            pObjBody,    1,
            pExtObjBody, 1,
            ObjBodySize, 
            TrError);
            }
            else if (!ObjectIsSplit)
            {
      // Object is completely stored in the continuation container. This case should only occur
      // for objects which have been stored before the modification of PTS 1121823
                  const tsp00_PageNo     &ContObjPno    = VarObjBody.vbdHeader_bd900.vhdContObjPno_bd900;
                  const tgg00_ObjPagePos &ContObjPos    = VarObjBody.vbdHeader_bd900.vhdContObjPos_bd900;
      MaxObjBodySize = bd93ContObjFileDir[ObjFileNo][ContObjFileNo].GetObjBodySize();
                  
      bd93_GetContObjBodyPointer (Current, ContObjFileNo, ContObjPno, ContObjPos, OId,
                        m_select, ContObjCurrent, NptrsBody, pObjBody);
                  if (TrError != e_ok) return;

      SAPDB_RangeMove( __FILE__, 22, 
            MaxObjBodySize, ExtObjBodySize,
            pObjBody,    1,
            pExtObjBody, 1,
            ObjBodySize, 
            TrError);
            }
    else 
    {
      // Object is split across the primary and the continuation container
      tsp00_Int4  PrimBodySize = bd90ObjFileDir[ObjFileNo].GetObjBodySize();

      // First read the portion stored in the primary container...
      pObjBody       = (tsp00_MoveObj*) VarObjBody.vbdBody_bd900;
      MaxObjBodySize = bd90ObjFileDir[ObjFileNo].GetObjBodySize();

      SAPDB_RangeMove( __FILE__, 23, 
            MaxObjBodySize, ExtObjBodySize,
            pObjBody,    1,
            pExtObjBody, 1,
            PrimBodySize, 
            TrError);
   
      // ... then read portion stored in the continuation container and copy it
      // beyond the data of the primary container
                  const tsp00_PageNo     &ContObjPno    = VarObjBody.vbdHeader_bd900.vhdContObjPno_bd900;
                  const tgg00_ObjPagePos &ContObjPos    = VarObjBody.vbdHeader_bd900.vhdContObjPos_bd900;
      MaxObjBodySize = bd93ContObjFileDir[ObjFileNo][ContObjFileNo].GetObjBodySize();
                  
      bd93_GetContObjBodyPointer (Current, ContObjFileNo, ContObjPno, ContObjPos, OId,
                        m_select, ContObjCurrent, NptrsBody, pObjBody);
                  if (TrError != e_ok) return;

      SAPDB_RangeMove( __FILE__, 24, 
            MaxObjBodySize, ExtObjBodySize,
            pObjBody,    1,
            pExtObjBody, 1 + PrimBodySize,
            ObjBodySize-PrimBodySize, 
            TrError);
    }
  }
}

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

externCpp void 
bd93LogDelVarObj (
                          tbd_current_tree  &Current,
                          tgg92_KernelOid    OId, 
                          tgg91_PageRef      WantedObjVers,      //[inp]
                          tbd_nodeptr        pPage, 
                          tbd900_ObjFrame   *pObjFrame
                          )
{
      ROUTINE_DBG_MSP00 ("bd93LogDelVarObj");
      
  char buffer[8100];  // PTS 1121823

      /* This function writes the removing on var object into the log */
      
  /*  determine  pointer to the object body */
      cbd05_Current           ContObjCurrent;   
      cbd910_ContObjDataNode  NptrsBody (ContObjCurrent, nr_for_read);
      tbd900_VarObjBody      &VarObjBody    = *((tbd900_VarObjBody*) (pObjFrame->objBody_bd900));
      tsp00_Int4              ObjBodySize   = VarObjBody.vbdHeader_bd900.vhdObjSize_bd900;
      tsp00_Int4              ContObjFileNo = VarObjBody.vbdHeader_bd900.vhdContObjFileNo_bd900;
      tsp00_MoveObj          *pObjBody;
  const tsp00_Bool       &ObjectIsSplit = VarObjBody.vbdHeader_bd900.vhdObjectIsSplit_bd900; // PTS 1121823
      
  if (0==ContObjFileNo)
    // Object is completely stored in the primary container
            pObjBody = (tsp00_MoveObj*) VarObjBody.vbdBody_bd900;
      else if (!ObjectIsSplit)
      {
    // Object is completely stored in the continuation container
    const tsp00_PageNo     &ContObjPno = VarObjBody.vbdHeader_bd900.vhdContObjPno_bd900;
    const tgg00_ObjPagePos &ContObjPos = VarObjBody.vbdHeader_bd900.vhdContObjPos_bd900;
    bd93_GetContObjBodyPointer (Current, ContObjFileNo, ContObjPno, ContObjPos, OId,
                                m_select, ContObjCurrent,  NptrsBody, pObjBody);
      }
  else 
  {
    // Object is split across the primary and the continuation container (see PTS 1121823)

    const tgg00_ObjFileNo  ObjFileNo  = Current.curr_tree_id.fileObjFileNo_gg00(); 
    tsp00_Int4  PrimBodySize = bd90ObjFileDir[ObjFileNo].GetObjBodySize();

    // First read the portion stored in the primary container...
    pObjBody  = (tsp00_MoveObj*) VarObjBody.vbdBody_bd900;
    SAPDB_MemCopyNoCheck (&buffer[0], pObjBody, PrimBodySize);
   
    // ... then read portion stored in the continuation container and copy it
    // beyond the data of the primary container
            const tsp00_PageNo     &ContObjPno    = VarObjBody.vbdHeader_bd900.vhdContObjPno_bd900;
            const tgg00_ObjPagePos &ContObjPos    = VarObjBody.vbdHeader_bd900.vhdContObjPos_bd900;
                  
    bd93_GetContObjBodyPointer (Current, ContObjFileNo, ContObjPno, ContObjPos, OId,
                                            m_select, ContObjCurrent, NptrsBody, pObjBody);

    SAPDB_MemCopyNoCheck (&buffer[PrimBodySize], pObjBody, ObjBodySize-PrimBodySize); 

    pObjBody = (tsp00_MoveObj*) &buffer[0];
  }
      
      /* check if object is locked and create a log entry  */ 
    
  kb67DelUpdObj (*Current.curr_trans, m_delete, Current.curr_tree_id,
        OId, pPage->nd_obj_key_len(), WantedObjVers,
        pObjFrame->objHeader_bd900, ObjBodySize, pObjBody);     
}

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

externCpp bool
bd93NextContObjBodyLen (tsp00_Int4  &ObjBodyLen)  // [inp/out]
{
      ROUTINE_DBG_MSP00 ("bd93NextContObjBodyLen");
      
      /* This function returns the ObjBodyLen which is about    */
      /* CONT_FRAME_ENLARGE_FACTOR_BD900 (in %) larger than the */
      /* input ObjBodyLen, fills the page as good as possible   */
      /* and is alligend                                        */
      
      double    LastOccupancy;
      double    LastLastOccupancy;
      double    Occupancy;
      int       iLen;
      int       StartSearchLen;
      int       r_ObjBodyLen;
      int       l_ObjBodyLen;
      bool      r_NextLenExists = false;
      bool      l_NextLenExists = false;
      const int MaxObjBodySize  = FULLCOVERING_BD00 - sizeof(tbd900_ContObjHeader);

      /* find the optimum size on the right side         */
      /* of ObjBodyLen * CONT_FRAME_ENLARGE_FACTOR_BD900 */ 
      LastOccupancy     = 0;
      LastLastOccupancy = 0;
      StartSearchLen    = (ObjBodyLen * CONT_FRAME_ENLARGE_FACTOR_BD900)/100;
      for (iLen=StartSearchLen-2; iLen<= MaxObjBodySize + 1; ++iLen)
      {
            Occupancy = bd93_OccupancyRate (iLen, NO_ALIGNMENT);  
            if((Occupancy < LastOccupancy) && (LastLastOccupancy < LastOccupancy))
            {
                  r_NextLenExists = true;
                  r_ObjBodyLen    = iLen-1;
                  break;
            }
            LastLastOccupancy = LastOccupancy;
            LastOccupancy     = Occupancy;
      }

      /* align the the optimum object length */
      r_ObjBodyLen    = (r_ObjBodyLen/ALIGNMENT) * ALIGNMENT;
      if (r_ObjBodyLen <= ObjBodyLen) r_ObjBodyLen += ALIGNMENT;
      r_NextLenExists = r_NextLenExists && (r_ObjBodyLen > ObjBodyLen) && (r_ObjBodyLen <= MaxObjBodySize);

      
      /* find the optimum size on the left side          */
      /* of ObjBodyLen * CONT_FRAME_ENLARGE_FACTOR_BD900 */ 
      LastOccupancy     = 100.0;
      LastLastOccupancy = 100.0;
      StartSearchLen    = MIN_EO00 ((ObjBodyLen * CONT_FRAME_ENLARGE_FACTOR_BD900)/100, MaxObjBodySize);

      if (StartSearchLen > ObjBodyLen)
      {
            l_NextLenExists = true;
            l_ObjBodyLen    = StartSearchLen;
      }

      for (iLen=StartSearchLen+2; iLen> ObjBodyLen; iLen--)
      {
            Occupancy = bd93_OccupancyRate (iLen, NO_ALIGNMENT);
            if(Occupancy < LastOccupancy && LastLastOccupancy < LastOccupancy)
            {
                  l_NextLenExists = true;
                  l_ObjBodyLen    = iLen+1;
                  break;
            }
            LastLastOccupancy = LastOccupancy;
            LastOccupancy     = Occupancy;
      }     
      
      /* align the the optimum object length */
    l_ObjBodyLen    = (l_ObjBodyLen/ALIGNMENT) * ALIGNMENT;
      l_NextLenExists = l_NextLenExists && (l_ObjBodyLen > ObjBodyLen);
      
      if (r_NextLenExists && ! l_NextLenExists)
            ObjBodyLen = r_ObjBodyLen;
      else
            if (!r_NextLenExists && l_NextLenExists)
                  ObjBodyLen = l_ObjBodyLen;
            else
                  if (r_NextLenExists && l_NextLenExists)
                  {
                        if (abs(l_ObjBodyLen - StartSearchLen) < abs (r_ObjBodyLen - StartSearchLen))
                              ObjBodyLen = l_ObjBodyLen;
                        else
                              ObjBodyLen = r_ObjBodyLen;
                  }

    return (l_NextLenExists || r_NextLenExists);
}

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

externCpp void
bd93RemoveContObj (
                          tbd_current_tree       &Current,        //[inp]
                          tgg92_KernelOid        &OId,            //[inp]    
                          const tsp00_Int4        ContObjFileNo,  //[inp]     
                          const tsp00_PageNo      ContObjPno,     //[inp] 
                          const tgg00_ObjPagePos  ContObjPos      //[inp]
                          )
{
      ROUTINE_DBG_MSP00 ("bd93RemoveContObj");
      
      /* This function removes an  continuation object */
      
      tgg00_BasisError      &TrError   = Current.curr_trans->trError_gg00;
      const tgg00_ObjFileNo  ObjFileNo = Current.curr_tree_id.fileObjFileNo_gg00(); //PTS 1111901 AK 24/09/2001

      /* construct currrent for the continuation objects */
      cbd05_Current ContCurrent (*Current.curr_trans, m_update);
      cbd900_ContObjFileInfo &ContObjFileInfo = bd93ContObjFileDir[ObjFileNo];
      ContObjFileInfo.bd900BuildFileId (ObjFileNo, ContObjFileNo, ContCurrent.curr_tree_id);
      
      /* get pointer to the page where the object is located */
      cbd910_ContObjDataNode  NptrsBody(ContCurrent, ContObjPno, nr_for_update);                                                                      
      if (TrError != e_ok) return;

      const tsp00_Int2 ChainNo = NptrsBody.np_ptr()->nd_chain_no();

      /* release continuation object which is not used any more, the Nptrs are released too */
      bd93_ReleaseContObjFrame (ContCurrent, OId, NptrsBody, ContObjPos);
}

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

externCpp void
bd93UpdateVarObjBody (tbd_current_tree        &Current,
                                tgg92_KernelOid          OId,
                                tgg91_PageRef              ObjVers,
                                cbd910_PrimObjDataNode  &NptrsAnchor,
                                tbd900_ObjFrame        *&pObjFrame, 
                                tsp00_Int4               NewObjBodySize,
                                void                    *pNewObjBody,
                                bool                     bRollBack,
                                bool                    &bNewContFileWasCreated,
                                bool                    &bTooManyEmptyPagesInContFile,
                                tsp00_Int4              &NewContObjFileNo,
                                tsp00_Int4              &ContObjFileNo,
                                tsp00_Int4              &ContObjChainNo,
                                const Log_EntrySequence &RedoEntrySequence,
                        const tgg91_TransNo     &RedoUpdTransNo)
{
      /* This function moves the object given by the pointer  */
      /* pNewObjBody into the object frame given by the OId   */

  char Buffer[8100];  // PTS 1121823

  tgg00_BasisError      &TrError    = Current.curr_trans->trError_gg00;
      const tgg00_ObjFileNo  ObjFileNo  = Current.curr_tree_id.fileObjFileNo_gg00(); //PTS 1111901 AK 24/09/2001
  bNewContFileWasCreated            = false;

      /* check frame state */
#   if COMPILEMODE_MEO00 >= QUICK_MEO00 
    if ((pObjFrame->objHeader_bd900.ohdState_gg92  != obsReserved_egg00   ) &&
        (pObjFrame->objHeader_bd900.ohdState_gg92  != obsOccupied_egg00   ))
    {   
        TrError = e_wrong_object_state;
        return;
    }
#   endif

      bool                     bMoveBodyToAnotherContFile = false;
  tsp00_Int4               MaxObjBodySize = 0;
  tsp00_Int4               MinObjBodySize = 0;
      tsp00_MoveObj           *pObjBody       = NULL;
      tsp00_MoveObj           *pOldObjBody    = NULL;

  cbd05_Current            ContObjCurrent;      
      cbd910_ContObjDataNode   NptrsBody (ContObjCurrent, nr_for_update);

  cbd900_ObjFileInfo      &ObjFileInfo     = bd90ObjFileDir[ObjFileNo];
      cbd900_ContObjFileInfo  &ContObjFileInfo = bd93ContObjFileDir[ObjFileNo];
  tbd900_VarObjBodyHeader *pHdr            = &(((tbd900_VarObjBody*) pObjFrame->objBody_bd900)->vbdHeader_bd900);
  tsp00_MoveObj           *pPrimBody       = (tsp00_MoveObj*) &(((tbd900_VarObjBody*) pObjFrame->objBody_bd900)->vbdBody_bd900);
  tsp00_Int4               PrimBodySize    = ObjFileInfo.GetObjBodySize();

  ContObjFileNo = pHdr->vhdContObjFileNo_bd900;

      if (PRIM_CONT_OBJ_FILE_NO_BD900 == pHdr->vhdContObjFileNo_bd900)
      {
    // Old object is stored completely in the primary container
            pObjBody       = pPrimBody;
            MaxObjBodySize = ObjFileInfo.GetObjBodySize();
            MinObjBodySize = 0;
      }
      else if (!pHdr->vhdObjectIsSplit_bd900)
      {
    // Old object is stored completely in the continuation container
            bd93_GetContObjBodyPointer (Current, 
      pHdr->vhdContObjFileNo_bd900, 
      pHdr->vhdContObjPno_bd900, 
      pHdr->vhdContObjPos_bd900, 
      OId, m_update, 
      ContObjCurrent, NptrsBody, pOldObjBody);
            if (TrError != e_ok) return;

            MaxObjBodySize =  ContObjFileInfo[pHdr->vhdContObjFileNo_bd900].GetObjBodySize();
            if (ContObjFileNo > 1)        
                  //MinObjBodySize = (ContObjFileInfo[pHdr->vhdContObjFileNo_bd900-1].GetObjBodySize()*BALANCE_LIMIT_BD900)/100;
                  MinObjBodySize = ContObjFileInfo[pHdr->vhdContObjFileNo_bd900-1].GetObjBodySize() + 1;
            else
                  //MinObjBodySize = (ObjFileInfo.GetObjBodySize()*BALANCE_LIMIT_BD900)/100;
                  MinObjBodySize = ObjFileInfo.GetObjBodySize() + 1;

            /* store current ChainNo, for a later call of the garbage collector */ 
    ContObjChainNo = NptrsBody.np_ptr()->nd_chain_no();

    pObjBody = pOldObjBody;  // PTS 1123494
      }
  else
  {
    // Old object is split across the primary and the continuation container.
    // Therefore the object must be merged. (PTS 1121823)

            bd93_GetContObjBodyPointer (Current, 
      pHdr->vhdContObjFileNo_bd900, 
      pHdr->vhdContObjPno_bd900, 
      pHdr->vhdContObjPos_bd900, 
      OId, m_update, 
      ContObjCurrent, NptrsBody, pOldObjBody);
            if (TrError != e_ok) return;

            MaxObjBodySize =  ContObjFileInfo[pHdr->vhdContObjFileNo_bd900].GetObjBodySize();
            if (pHdr->vhdContObjFileNo_bd900 > 1)           
                  //MinObjBodySize = (ContObjFileInfo[pHdr->vhdContObjFileNo_bd900-1].GetObjBodySize()*BALANCE_LIMIT_BD900)/100;
                  MinObjBodySize = ContObjFileInfo[pHdr->vhdContObjFileNo_bd900-1].GetObjBodySize() + 1;
            else
                  //MinObjBodySize = (ObjFileInfo.GetObjBodySize()*BALANCE_LIMIT_BD900)/100;
                  MinObjBodySize = ObjFileInfo.GetObjBodySize() + 1;

            /* store current ChainNo, for a later call of the garbage collector */ 
    ContObjChainNo = NptrsBody.np_ptr()->nd_chain_no();

    if (!bRollBack)
    {
      // First copy portion of primary container...
      SAPDB_MemCopyNoCheck(&Buffer[0], pPrimBody, PrimBodySize);

      // ...then copy portion of continuation container
      SAPDB_MemCopyNoCheck(&Buffer[PrimBodySize], pOldObjBody, pHdr->vhdObjSize_bd900 - PrimBodySize);

      pObjBody = (tsp00_MoveObj*) &Buffer[0];
    }
  }

      // find out where the new obj body has to be accomodated 
  // If the object fits into the primary container, the object is always (independend of
  // the setting of BALANCE_LIMIT_BD900) moved completely into the primary container
  NewContObjFileNo = pHdr->vhdContObjFileNo_bd900;
      if ((NewObjBodySize > MaxObjBodySize) || (NewObjBodySize < MinObjBodySize))
      {
            bMoveBodyToAnotherContFile = true;

    if (NewObjBodySize <= PrimBodySize)
      NewContObjFileNo = PRIM_CONT_OBJ_FILE_NO_BD900; 
    else if (NewObjBodySize <= 2*PrimBodySize)
      // Problem: If the remainder of the object (without the portion which is stored in
      //   the primary container is smaller than the upper bound for the primary container,
      //   then the following function would return the primary container.
      // Workaround: If the size is between PrimBodySize and 2*PrimBodySize, then the function
      //   is called with the original size. This prevent, that the primary container is returned
      bd93_FindFileNoForThisObjBodySize (NewObjBodySize, ObjFileNo, NewContObjFileNo, TrError);       
    else
      // Get a container which is large enough to store the remainder of the object
      bd93_FindFileNoForThisObjBodySize (NewObjBodySize-PrimBodySize, ObjFileNo, NewContObjFileNo, TrError);            
    if (TrError != e_ok) return;

            /* check if enough space is available */
            const tsp00_Int4 NumPagesProbablyNeeded = 1; 
            if (PRIM_CONT_OBJ_FILE_NO_BD900 != NewContObjFileNo)
            {
                  Converter_IPageNoManager::Instance().HandleDBFull (*Current.curr_trans, NumPagesProbablyNeeded);
            }
            if (TrError != e_ok) return;
      }
    
      if (!bRollBack)
  {
            /* update object transinfo and write a log entry */
            kb67UpdObj (*Current.curr_trans, Current.curr_tree_id,
                  OId, NptrsAnchor.np_ptr()->nd_obj_key_len(), ObjVers,
                  pObjFrame->objHeader_bd900, pHdr->vhdObjSize_bd900, pObjBody,
                  RedoEntrySequence, RedoUpdTransNo);       
    if (TrError != e_ok) return;
  }

  if (PRIM_CONT_OBJ_FILE_NO_BD900 == NewContObjFileNo)
      {
        if (bMoveBodyToAnotherContFile)
            {
                  /* release the current body frame and page pointer     */ 
                  bd93_ReleaseContObjFrame (ContObjCurrent, OId, NptrsBody, pHdr->vhdContObjPos_bd900);

      // Reset pointer to continuation container
              pHdr->vhdContObjFileNo_bd900 = PRIM_CONT_OBJ_FILE_NO_BD900;
                  pHdr->vhdContObjPno_bd900    = NIL_PAGE_NO_GG00;
                  pHdr->vhdContObjPos_bd900    = NIL_OBJ_PAGE_POS_GG92;
            }

        // update var object header 
        pHdr->vhdObjSize_bd900       = NewObjBodySize;
        pHdr->vhdObjectIsSplit_bd900 = false;  // PTS 1121823
      
      if ( NewObjBodySize > 0 )
      {
          
          // update object in primary container
          SAPDB_RangeMove( __FILE__, 31,
              NewObjBodySize,  ObjFileInfo.GetObjBodySize(), 
              pNewObjBody,  1, 
              pPrimBody,    1,
              NewObjBodySize,  
              TrError); 
      }
  }
  else
      {
    // First update data in primary container
        SAPDB_RangeMove( __FILE__, 32,
              PrimBodySize,  ObjFileInfo.GetObjBodySize(), 
              pNewObjBody, 1, 
      pPrimBody,   1,
              PrimBodySize,  
      TrError); 

    // Update data in continuation container
    if (bMoveBodyToAnotherContFile)
    {
                  /* release the current body frame and page pointer     */ 
                  if (PRIM_CONT_OBJ_FILE_NO_BD900 != pHdr->vhdContObjFileNo_bd900)
                        bd93_ReleaseContObjFrame (ContObjCurrent, OId, NptrsBody, pHdr->vhdContObjPos_bd900);
                  
                  /* get a new object frame of an appropriate length */
                  bd93_NewContObj (Current, NewContObjFileNo, OId, ContObjFileInfo, 
                        ContObjCurrent, NptrsBody, pHdr->vhdContObjPos_bd900, bNewContFileWasCreated);
                  if (TrError != e_ok) return;
                  
          /* update var object header */
                  pHdr->vhdContObjPno_bd900    = NptrsBody.np_ptr()->nd_id();
                  //pHdr->vhdContObjPos_bd900  = ;  // changed already by call of bd93_NewContObj
              pHdr->vhdContObjFileNo_bd900 = NewContObjFileNo;

      // Get pointer to new destination
                  const tbd900_ContObjFrame *pContObjFrame = (tbd900_ContObjFrame *) ((char*) NptrsBody.np_ptr() + pHdr->vhdContObjPos_bd900);
      pObjBody       = (tsp00_MoveObj *) (pContObjFrame->cofBody_bd900);
                  MaxObjBodySize = ContObjFileInfo[NewContObjFileNo].GetObjBodySize();
            }
    else
    {
      // Get pointer to old destination
              pObjBody = pOldObjBody;
                  MaxObjBodySize = ContObjFileInfo[pHdr->vhdContObjFileNo_bd900].GetObjBodySize();
    }
            
    // Update header
            pHdr->vhdObjectIsSplit_bd900 = true;   // PTS 1121823
        pHdr->vhdObjSize_bd900       = NewObjBodySize;
      
        // Update object
        SAPDB_RangeMove( __FILE__, 33,
              NewObjBodySize-PrimBodySize,  MaxObjBodySize, 
              (tsp00_MoveObj*) pNewObjBody + PrimBodySize, 1, 
      pObjBody,                                    1,
              NewObjBodySize-PrimBodySize,  
      TrError); 
      }
}

/*===========================================================================*
 *  LOCAL FUNCTIONS (CODE)                                                   *
 *===========================================================================*/
                         
static _INLINE void
bd93_CheckContObjRoot (
                                 const tgg92_KernelOid      &RootOId,         //[inp] 
                                 const tbd900_ContObjHeader &ContObjHeader    //[inp]
                                 )
{
      ROUTINE_DBG_MSP00 ("bd93_CheckContObjRoot");
      
      /* This function checks if the given RootOid is really */ 
      /* the root of the given continuation object frame     */   
      
      if ((RootOId.gg92GetPos()  != ContObjHeader.cvoRootOIdPos_bd900) ||
            (RootOId.gg92GetPno()  != ContObjHeader.cvoRootOIdPno_bd900) ||
            (NIL_OBJ_PAGE_POS_GG92 != ContObjHeader.cvoNextFreeObj_bd900))
      {
            /* report error in knldiag and vtrace */
            g01optextmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                  "BD93_Check: RootOId <> ContObj.RootOId  ");
            
            g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                  "           RootOId.Page=", RootOId.gg92GetPno() );
            g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                  "   ContObj.RootOId.Page=",  ContObjHeader.cvoRootOIdPno_bd900);
            g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                  "            RootOId.Pos=", RootOId.gg92GetPos() );
            g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                  "    ContObj.RootOId.Pos=", ContObjHeader.cvoRootOIdPos_bd900);
            g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                  "  ContObj.RootOId.NextF=", ContObjHeader.cvoRootOIdPos_bd900);
      }
}

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

_INLINE static void
bd93_FindFileNoForThisObjBodySize (const tsp00_Uint4      NewObjBodySize, //[inp]  
                                                   const tgg00_ObjFileNo  ObjFileNo,      //[inp] 
                                                   tsp00_Int4            &ContFileNo,     //[out]
                                                   tgg00_BasisError      &TrError)        //[out]
{
      ROUTINE_DBG_MSP00 ("bd93_FindFileNoForNewBody");
      
      /* This function determines the number of the file which has the right  */
      /* object frames to accomodate objects of the given size NewObjBodySize */
      
    /* check if the object fits into the primary var object file */
      if (NewObjBodySize <= bd90ObjFileDir[ObjFileNo].GetObjBodySize())
      {
            ContFileNo = PRIM_CONT_OBJ_FILE_NO_BD900;
            return;
      }
      else
      {
            /* find the suiting continuation file */
            cbd900_ContObjFileInfo & ContObjFileInfo = bd93ContObjFileDir[ObjFileNo];

            /* check if there really exists an entry in the continuation file directory */
#       if COMPILEMODE_MEO00 >= QUICK_MEO00 
            if (ContObjFileInfo.cfiNumContFiles_bd900 <1)
                  g01abort (csp3_bd_msg, csp3_n_obj, "BD93_FindFileNo:No Entry", ObjFileNo);
#       endif

                  ContFileNo = (ContObjFileInfo.cfiNumContFiles_bd900+1)/2;
            bool        bFound = false;   
            tsp00_Int4  Delta  = ContFileNo;
            
            do
            {   
                  if (NewObjBodySize <= ContObjFileInfo[ContFileNo].GetObjBodySize())
                  {
                        if ((ContFileNo==1) ||
                              (NewObjBodySize > ContObjFileInfo[ContFileNo-1].GetObjBodySize()))
                        {
                              bFound = true;
                        }
                        else
                        {
                              Delta       = (Delta+1)/2;
                              ContFileNo -=  Delta;
                        }
                  }
                  else
                  {
                        Delta       = (Delta+1)/2;
                        ContFileNo +=  Delta;
                        if (ContFileNo > ContObjFileInfo.cfiNumContFiles_bd900)
                        {
                              g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                                    "BD93_Find:WrongVarObjLen", NewObjBodySize);
                              TrError = e_illegal_object_length;
                              return;
                        }
                  }
            }
            while (!bFound);
      }
}
            
            
/*---------------------------------------------------------------------------*/

_INLINE static void
bd93_GetContObjBodyPointer (
                              tbd_current_tree       &Current,         //[inp/out]
                                    const tsp00_Int4        ContObjFileNo,   //[inp]     
                                    const tsp00_PageNo      ContObjPno,      //[inp] 
                                    const tgg00_ObjPagePos  ContObjPos ,     //[inp]
                                    const tgg92_KernelOid  &OId,             //[inp] 
                                    tgg00_MessType_Enum     MessType,        //[inp]
                                    cbd05_Current          &ContCurrent,     //[out]
                                    cbd910_ContObjDataNode &NptrsBody,       //[out]
                                    tsp00_MoveObjPtr       &pObjBody         //[out]
                                 )
{
      ROUTINE_DBG_MSP00 ("bd93_GetContObjBodyPointer");
      
      /* this function supplies the pointer to an continuation object body     */
      /* which is derived from the page number and page position of the object */
      
      tbd900_ContObjFrame     *pContObjFrame; 
      tgg00_BasisError        &TrError   = Current.curr_trans->trError_gg00;
      const tgg00_ObjFileNo    ObjFileNo = Current.curr_tree_id.fileObjFileNo_gg00(); //PTS 1111901 AK 24/09/2001
      tgg00_FileId             ObjFileId; 
    cbd900_ContObjFileInfo  &ContObjFileInfo = bd93ContObjFileDir[ObjFileNo]; 

    ContObjFileInfo.bd900BuildFileId(ObjFileNo, ContObjFileNo, ObjFileId);

    /* construct currrent for the continuation objects */
    ContCurrent.bd05SetCurrent (*Current.curr_trans, MessType,  ObjFileId);

      /* get page pointer */
      NptrsBody.bd910AssignToPage (ContObjPno);
      if (TrError != e_ok) return;
      
      /* get object pointer */
      pContObjFrame = (tbd900_ContObjFrame *) ((char*) NptrsBody.np_ptr() + ContObjPos);
      pObjBody      = (tsp00_MoveObj *) (pContObjFrame->cofBody_bd900);
      
      /* check if the found object frame belongs to the root OId */
      if (g01vtrace.vtrCheck_gg00)
        bd93_CheckContObjRoot (OId, pContObjFrame->cofHeader_bd900); 
}

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

static void 
bd93_NewContObj (tbd_current_tree        &Current,                 // [inp]
                         tsp00_Int4               ContFileNo,              // [inp]
                         const tgg92_KernelOid   &RootOId,                 // [inp] 
                         cbd900_ContObjFileInfo  &ContObjFileInfo,         // [inp]
                         cbd05_Current           &ContCurrent,             // [out]
                         cbd910_ContObjDataNode  &NptrsBody,               // [out]
                         tgg00_ObjPagePos        &ContObjPos,              // [out]
                         bool                    &bNewContFileWasCreated)  // [out]
{
    ROUTINE_DBG_MSP00 ("bd93_NewContObj");
    
    /* This function yields a new continuation object frame */
      /* which is identified by ContObjPno and ContObjPos     */
    /* The new frame is searched in the the free chain.     */
      
    tgg00_BasisError      &TrError      = Current.curr_trans->trError_gg00;
      const tgg00_ObjFileNo  ObjFileNo    = Current.curr_tree_id.fileObjFileNo_gg00(); 
      /*cbd900_ObjFileInfo    &ObjFileInfo  = ContObjFileInfo[ContFileNo];            PTS 1127279 FF 2004-01-26  */
      tgg00_FileId           ObjFileId;
      
      /* construct currrent for the continuation objects */ 
    ContObjFileInfo.bd900BuildFileId(ObjFileNo, ContFileNo, ObjFileId);
    ContCurrent.bd05SetCurrent (*Current.curr_trans, m_update, ObjFileId);
      
      /* check if the new continuation file exists already  */
      /* if the file does not exist so far create it        */
      if (NIL_PAGE_NO_GG00 != ContObjFileInfo[ContFileNo].GetRootPage())
            bNewContFileWasCreated = false;
      else
      {
        /* PTS 1127279 FF 2004-01-26                                  */
        /* use region to avoid the continous file to be created twice */
        vbegexcl (Current.curr_trans->trTaskId_gg00, g08objcontf); 
        if (NIL_PAGE_NO_GG00 != ContObjFileInfo[ContFileNo].GetRootPage())
            bNewContFileWasCreated = false;
        else
        {                                 
            const int cZeroKeyLen          = 0;
            const int MaxObjBodySize       = ContObjFileInfo[ContFileNo].GetObjBodySize();
            const tsp00_Bool cNoObjKeyFile = false;
            bNewContFileWasCreated         = true;
            LVC_RootPageNoArray DummyRootPageNoArray;

            bd90CreateObjFile (ContCurrent, MaxObjBodySize, cZeroKeyLen, cNoObjKeyFile, DummyRootPageNoArray);

            if (e_ok == TrError)
                bd90CreateEntryInPersFileDirectory (ContCurrent);
            else
            {
                if (e_duplicate_filename == TrError)
                    TrError = e_ok;
                else
                {
                    Kernel_OpError( csp3_bd_msg, csp3_n_obj ) << __FILE__ << " : " << __LINE__ 
                        << " TrError:" << TrError
                        << " FileNo:" << ObjFileNo
                        << " ContFileNo:" << ContFileNo;
                    if ((g01vtrace.vtrBdObject_gg00) || (g01vtrace.vtrOmsUpd_gg00 ))
                    {
                        Kernel_VTrace() << __FILE__ << " : " << __LINE__ 
                            << " TrError:" << TrError
                            << " FileNo:" << ObjFileNo
                            << " ContFileNo:" << ContFileNo;
                    }
                    vendexcl (Current.curr_trans->trTaskId_gg00, g08objcontf); /* PTS 1127279 FF 2004-01-26 */
                    return;
                }
            }     
        }
        vendexcl (Current.curr_trans->trTaskId_gg00, g08objcontf); /* PTS 1127279 FF 2004-01-26 */
    }

      /* get handle for the current subroot */
      cbd900_ObjFileInfo    &ObjFileInfo     = ContObjFileInfo[ContFileNo];
      const tsp00_Int4            ChainNo    = ObjFileInfo.bd900CurrChain();
          cbd900_ObjChainInfo  &ChainInfo  = ObjFileInfo[ChainNo];
    const tsp00_PageNo          SubRoot    = ChainInfo.ociSubRoot_bd900; 
    cbd910_SubRootNode   NptrsSubRoot (ContCurrent, SubRoot, nr_for_update);
    if (TrError != e_ok) 
    {
        Kernel_OpError( csp3_bd_msg, csp3_n_obj ) << __FILE__ << " : " << __LINE__ 
            << " TrError:" << TrError
            << " FileNo:" << ObjFileNo
            << " ContFileNo:" << ContFileNo
            << " Root:" << ObjFileInfo.GetRootPage()
            << " SubRoot:" << SubRoot;
        if ((g01vtrace.vtrBdObject_gg00) || (g01vtrace.vtrOmsUpd_gg00 ))
        {
            Kernel_VTrace() << __FILE__ << " : " << __LINE__ 
                << " TrError:" << TrError
                << " FileNo:" << ObjFileNo
                << " ContFileNo:" << ContFileNo
                << " Root:" << ObjFileInfo.GetRootPage()
                << " SubRoot:" << SubRoot;
        }
        return;
    }
      
#   if COMPILEMODE_MEO00 >= QUICK_MEO00 
      /* check if this subroot page belongs really to this file */
      if ((NptrsSubRoot.np_ptr()->nd_root()        != ObjFileInfo.GetRootPage()) || 
            (NptrsSubRoot.np_ptr()->nd_obj_file_no() != ObjFileNo)                 ||
            (NptrsSubRoot.np_ptr()->nd_sub_root()    != SubRoot)                   ||
            (NptrsSubRoot.np_ptr()->nd_chain_no()    != ChainNo))
      {
            g01abort (csp3_bd_msg, csp3_n_obj, 
                  "BD93_NewObj:wrong SRoot ", NptrsSubRoot.np_ptr()->nd_id());
    }
#   endif

      /* get page handle for the first page with free objects */
      /* CRS 1106534 Alexander Kley 2000-05-11                */
#   ifdef STORE_OBJECTS_ON_SUBROOT_BD900   
      if (NptrsSubRoot.np_ptr()->nd_free_obj_cnt() > 0)
            NptrsBody.bd910SetTo (NptrsSubRoot, true /*movePrimary PTS 1130598*/);
      else
#   endif
      {
            if (NIL_PAGE_NO_GG00 != NptrsSubRoot.np_ptr()->nd_next_free())
                  NptrsBody.bd910AssignToPage (NptrsSubRoot.np_ptr()->nd_next_free());
            else
                  NptrsBody.bd910AssignToNewPageInDataChain (NptrsSubRoot);
            if (e_ok != TrError) return;
      }
      
      /* get a new OId and initialize the corresponding object */
      bd93_NewContObjFromThisPage (ContCurrent, NptrsBody, RootOId, ContObjPos);
    if (e_ok != TrError) return;

      /* remove page from free page chain if there are no more free object frame on the page */
    NptrsSubRoot.bd910RestoreFreePageChain (NptrsBody, ChainInfo); 
}

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

_INLINE static void 
bd93_NewContObjFromThisPage (tbd_current_tree        &Current,                  // [inp]
                                           cbd910_ContObjDataNode  &NptrsBody,                // [inp]
                                           const tgg92_KernelOid   &RootOId,                  // [inp]
                                           tgg00_ObjPagePos        &ContObjPos)               // [out]  
{
      ROUTINE_DBG_MSP00 ("bd93_NewContObjFromThisPage");
      
      /*  This routine finds a free frame on a page presuming that at least one free  */
      /*  object frame exists. Moreover all pointers are restored corresponding       */
      /*  to changing the state of the frame whichs OId is returned                   */
      
      tbd900_ContObjFrame   *pContObjFrame; 
      tgg00_BasisError      &TrError   = Current.curr_trans->trError_gg00;
    tbd_nodeptr           &pPage     = NptrsBody.np_ptr();
      
    /* check if the object frame is really free    PTS 1127804 FF 2004-FEB-17 */
    if ( NIL_OBJ_PAGE_POS_GG92 == pPage->nd_first_free_obj())
    {
        Kernel_OpError ( csp3_bd_msg, csp3_n_obj ) << __FILE__ << ":" << __LINE__
            << " bd93_NewContObjFromThisPage:Objectframe freelist empty"
            << " page:" << pPage->nd_id()
            << " first free pos: " << pPage->nd_first_free_obj()
            << " page dumped into: d" 
            << pPage->nd_id() << ".obj"; 

        b06dump_bad_page (Current.curr_trans->trTaskId_gg00,'d', ".obj", pPage->nd_id(), 
            (void *) NptrsBody.np_ptr(), 1);
        g01abort (csp3_bd_msg, csp3_n_obj, "bd90_NewObjFromThisPage:", pPage->nd_root());
    }
      
      /*  construct position of the object frame  header             */
      pContObjFrame = (tbd900_ContObjFrame *)   ((char*) pPage + pPage->nd_first_free_obj());
      
      /*  get position of free object frame */
      ContObjPos   = pPage->nd_first_free_obj();
      
      /*  update page header */
      --pPage->nd_free_obj_cnt();
      ++pPage->nd_occ_obj_cnt();
      pPage->nd_first_free_obj() = pContObjFrame->cofHeader_bd900.cvoNextFreeObj_bd900;
      
      /*  update object frame header */
      pContObjFrame->cofHeader_bd900.cvoNextFreeObj_bd900 = NIL_OBJ_PAGE_POS_GG92;
      pContObjFrame->cofHeader_bd900.cvoRootOIdPno_bd900  = RootOId.gg92GetPno();
      pContObjFrame->cofHeader_bd900.cvoRootOIdPos_bd900  = RootOId.gg92GetPos();
      
      /*   initialize the object body, i.e. the first four bytes     */
      /*   of the body are filled with hex zeros and the body header */
      /*   of variable length objects are initialized                */
      const int  MaxObjBodySize = pPage->nd_obj_frame_len() - sizeof (tbd900_ContObjHeader);
      char       InitString[5]  = "\x00\x00\x00\x00";
      SAPDB_MemCopyNoCheck (pContObjFrame->cofBody_bd900, InitString, MIN_EO00 (4,MaxObjBodySize)); 

      /* increase global counter of used object frames in the current chain */   
      const tsp00_Int4  ContObjFileNo  = Current.curr_tree_id.fileContObjFileNo_gg00();
      const tsp00_Int2 &ChainNo        = pPage->nd_chain_no();
};

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

_INLINE static double
bd93_OccupancyRate (int ObjBodyLen,
                              int Alignment)
{
      ROUTINE_DBG_MSP00 ("bd93_OccupancyRate");

      /* this function returns the occupancy rate of an object page  */
      /* occupied with continuation objects of the length ObjBodylen */
      /* The calculation considers the  alignment                    */ 

      const int ObjDistance = (((sizeof(tbd900_ContObjHeader)+ObjBodyLen-1)/Alignment)+1)*Alignment; 
      const int NumObj      = FULLCOVERING_BD00/ObjDistance;      
      return ((100.0*NumObj*ObjBodyLen)/FULLCOVERING_BD00);
}

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

_INLINE static void
bd93_ReleaseContObjFrame (tbd_current_tree       &Current,
                                      const tgg92_KernelOid  &OId,            
                                      cbd910_ContObjDataNode &NptrsContObjPage,
                                      const tgg00_ObjPagePos  ContObjPos)
{
      ROUTINE_DBG_MSP00 ("bd93_ReleaseContObjFrame");
      
      /* release an  continuation object, i.e. change its    */
      /* state to free and introduce the frame into the free */
      /* frame chain. Moreover the page pointer is released  */

      tbd_nodeptr           &pContObjPage = NptrsContObjPage.np_ptr(); 
    tgg00_BasisError      &TrError      = Current.curr_trans->trError_gg00;
      const tgg00_ObjFileNo  ObjFileNo    = Current.curr_tree_id.fileObjFileNo_gg00();

    /* get pointer to subroot page */     
      cbd910_SubRootNode   NptrsSubRoot (Current, nr_for_update);  

      if ( NptrsContObjPage.bd910LockSubRootBeforeReleasingFrame() ) 
    {
        NptrsSubRoot.bd910AssignToSubroot (NptrsContObjPage);
            if (e_ok != TrError) 
            {
                  /* check if the error is due to a drop of the file */
                  if ((e_page_in_wrong_tree == TrError) || (e_no_converter_entry == TrError))
                  {
                        if ((NIL_PAGE_NO_GG00 == bd90ObjFileDir[ObjFileNo].GetRootPage()) ||
                              (bd90ObjFileDir[ObjFileNo].ofiRelFileIsReq_bd900))
                        {
                              TrError = e_ok;
                        }
                return;
            }
        }

        /* check if chaining will still be needed ( meahnwhile the page may have changed a lot */
            if ( !NptrsContObjPage.bd910LockSubRootBeforeReleasingFrame() ) 
            {     
                  /* no chaining will be needed anymore ==> release subroot */
                  NptrsSubRoot.bd910ReleasePage();
            }
    }


      /* get pointer to the continuation object */    
      tbd900_ContObjHeader & ContObjHeader  = *(tbd900_ContObjHeader *) ((char *) pContObjPage+ContObjPos);

      /* check if the found object frame belongs to the root OId */
      if (g01vtrace.vtrCheck_gg00)
            bd93_CheckContObjRoot (OId, ContObjHeader); 

      /* insert object frame into chain of free frames      */    
      ContObjHeader.cvoNextFreeObj_bd900 = pContObjPage->nd_first_free_obj();
      pContObjPage->nd_first_free_obj()  = ContObjPos;

      /* reset frame header */
      ContObjHeader.cvoRootOIdPno_bd900 = NIL_PAGE_NO_GG00;
    ContObjHeader.cvoRootOIdPos_bd900 = NIL_OBJ_PAGE_POS_GG92;

      /* update page header */  
      ++pContObjPage->nd_free_obj_cnt();
    --pContObjPage->nd_occ_obj_cnt();

      /* update global counter of all objects */
      const tsp00_Int4 ContObjFileNo  = Current.curr_tree_id.fileContObjFileNo_gg00();
      const tsp00_Int2 &ChainNo       = pContObjPage->nd_chain_no();
    cbd900_ObjChainInfo  &ChainInfo = bd93ContObjFileDir[ObjFileNo][ContObjFileNo][ChainNo];
      --ChainInfo.ociAllObjCnt_bd900;

#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
    // check if the number of objects is within reasonable limits  
      if((0>ChainInfo.ociAllObjCnt_bd900) ||
            (ChainInfo.ociAllObjCnt_bd900 >
            ChainInfo.ociAllPageCnt_bd900 * bd93ContObjFileDir[ObjFileNo][ContObjFileNo].GetObjPerPageCount()))
      {
            g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj, 
                  "bd93RelCon:odd AllObjCnt",   ChainInfo.ociAllObjCnt_bd900 );
      }
#   endif
      
    
    /*--------------------------------------------------------------------*/
    /* if the page becomes an empty page by removing the object it is     */ 
    /* released                                                           */
    /*--------------------------------------------------------------------*/
    if ( NptrsContObjPage.bd910IsEmptyPage())
    {
        NptrsSubRoot.bd910RemovePageFromChainOfAllPages(NptrsContObjPage);         
    }
    else 
    {
        /* update free chain and free page counter */ 
        if (NptrsContObjPage.bd910PageMustBeInsertedIntoFreeChain())
        {   
            NptrsSubRoot.bd910InsertPageIntoFreeChain (NptrsContObjPage);    
            
            /* refresh the counter of used objects on the subroot. Note; that                 */
            /* ociAllObjCnt_bd900 is updated  dirty and need not be correct.Here it is tried  */
            /* to keep the trivial restriction that the number of all objects must be >=0     */
            cbd900_SubRootPageInfo  SubRootPageInfo (NptrsSubRoot);
            SubRootPageInfo.bd900AllObjCnt() = SAPDB_MAX (ChainInfo.ociAllObjCnt_bd900, 0);
        }    
        
        /* release pointer to continuation page */
        NptrsContObjPage.bd910ReleasePage();
    }
}

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

Generated by  Doxygen 1.6.0   Back to index