/*!
  @defgroup       ObjContainer       persistent object container
*/
/*!
  @ingroup        ObjContainer
  @file           gbd900.h
  @author         FerdiF
  @brief          constants and types needed for the implementation of 
                  persistent object containers
*/

/*

    ========== licence begin  GPL
    Copyright (c) 2000-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 GBD900_H
#define GBD900_H

/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/
 
#include "ggg92.h"
#include "gbd00.h"
#include "gbd920.h"

#include "hbd01_1.h" // b01niltree_id
#include "hbd92.h"
#include "heo57.h"   // vmalloc
#include "hgg01_1.h" // g01abort
#include "hgg01_3.h" // g01tabid
#include "gsp03.h" 
#include "gsp03_3.h" 
#include "RunTime/MemoryManagement/RTEMem_Allocator.hpp" 
#include "Container/Container_Vector.hpp"
#include "SAPDBCommon/SAPDB_Types.hpp"
#include "KernelCommon/Kernel_OpMsg.hpp"        /* PTS 1114951 FF 2002-04-19 */
#include "SAPDB/SAPDBCommon/SAPDB_MemCopyMove.hpp"
#include "KernelCommon/Kernel_IAdminInfo.hpp"
#include "RunTime/System/RTESys_AtomicOperation.hpp"
#include "RunTime/System/RTESys_MemoryBarrier.h" 

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

/*! 
    gives the maximum number of object page chains in one object container   
    may be used for container striping                                      
*/
#define MAX_NUM_CHAINS_PER_CONTAINER_BD900          1

/*! 
    if a variable long persistent object is shortened by an update so that it 
    occupies less than the object frame length of the currrent file times 
    BALANCE_LIMIT_GGbd900 (in %) divided by CONT_FRAME_ENLARGE_FACTOR_BD900 
    an other file with smaler frames is choosen to accomodate the the object  
    \attention: not used anymore (PTS 1121823)
*/
#define BALANCE_LIMIT_BD900                         50
   
/*! 
    factor (in %) by which the obj frames in the continuation files increase 
    from a file to the file with next larger frames  
*/
#define CONT_FRAME_ENLARGE_FACTOR_BD900             200

/*!
    maximum number of continuation files which belong to a file containing 
    variable long persistent objects                  
*/
#define MAX_NUM_CONT_OBJ_FILES_BD900                12

/*! 
    this numbers is used in the fileid if the file contains no continuation 
    object. i.e the object frames contain the object header with lock and 
    log infos        
*/
#define PRIM_CONT_OBJ_FILE_NO_BD900                 0

/*!
    number of entry slots of the hash container which accomodated the object 
    file infos                  
*/
#define  HASH_WIDTH_BD900                           50000
     
/*!
    number of ObjFileInfo frames the hash allocates if a new ObjFileInfo 
    should be inserted but no empty frame is available 
*/
#define  NUM_OBJ_FILE_INFOS_TO_ALLOCATE_BD900       500 

/*!
    number of ContObjFileInfo frames the hash allocates if a new       
    ContObjFileInfo should be inserted but no empty frame is available 
*/
#define  NUM_CONT_OBJ_FILE_INFOS_TO_ALLOCATE_BD900  50

/*! 
    if this variable is defined objects are stored on the subroots too 
*/
#define STORE_OBJECTS_ON_SUBROOT_BD900 YES

/*!
    character used to fill the body of a persistent object, if the no
    data has been stored yet into the object body
*/
#define NIL_OBJ_FILLCHAR_BD900                  0

/*!
    indicating that no garbagecolletor is working on a substructure
    the corresponding controlblock if flagged with NIL_GC_INDEX_BD900
*/
#define NIL_GC_INDEX_BD900                     -1

/*!
    size of the marker for container entries within the dump
*/
#define DUMPMARKSIZE_BD900                      8

/*!
    a 8 byte integer containing the value of MAX_UINT4
*/
#define MAX_UINT4_BD900                         STATIC_CAST(teo00_Uint8,STATIC_CAST(teo00_Uint4,-1))

/*!
    a 8 byte integer containing the value of MAX_UINT8
*/
#define MAX_UINT8_BD900                         STATIC_CAST(teo00_Uint8,-1)

/*!
    pages within a object container are sorted by sequence numbers
    biggest sequence number possible for pages is MAX_LOCK_REQUEST_SEQ_NO_BD900
*/
#define MAX_LOCK_REQUEST_SEQ_NO_BD900           MAX_UINT8_BD900


class cbd900_ObjFileInfo;       /// forward declaration

/*!
    @brief     get the 8 byte unsigned int sequence number out of the page
    header
    @param     hi [in]            high 4 bytes
    @param     lo [in]             low 4 bytes
    @return    unsigned 8 bytes sequence number
*/
static teo00_Uint8 bd900GetPageSeqNo(const tbd00_LockRequestSeqNo &hi, 
                                     const tbd00_LockRequestSeqNo &lo)
{
    return ((STATIC_CAST(teo00_Uint4,hi) * (MAX_UINT4_BD900 + 1)) + 
        STATIC_CAST(teo00_Uint4,lo));
};

/*!
    @brief     set the 8 byte unsigned int sequence number out of the page
               header
    @param     seqno [in]         unsigned 8 bytes sequence number
    @param     hi [out]           high 4 bytes
    @param     lo [out]           low 4 bytes
    @return    none
*/
static void bd900SetPageSeqNo(const teo00_Uint8         seqno,
                              tbd00_LockRequestSeqNo   &hi, 
                              tbd00_LockRequestSeqNo   &lo)
{
    hi = STATIC_CAST(tbd00_LockRequestSeqNo,seqno / (MAX_UINT4_BD900 + 1));
    lo = STATIC_CAST(tbd00_LockRequestSeqNo,seqno % (MAX_UINT4_BD900 + 1));
};

/*!
    defines the structure of an persistent object frame
*/
struct tbd900_ObjFrame
{
    tgg92_ObjHeader     objHeader_bd900;    /*!< object frame header */
    tgg91_ObjAnyBody    objBody_bd900;      /*!< object frame body   */

    /*!
        initialize object header when object frame is allocated by 
        application
        @param ObjFrameLen [in] size of the object frame
        @param KeyLen [in]  key length if omsKeyedObject else 0         
        @param ObjFrameVers [in] frame version 
        @param bFrameIsForVarObjects [in] flag: variable long object 
        @return none
    */
    inline void  bd900SetToReservedFrame (tsp00_Int4         ObjFrameLen,
                                          tsp00_Int4         KeyLen,
                                          tgg00_ObjFrameVers ObjFrameVers,
                                          tsp00_Bool         bFrameIsForVarObjects);
};

/*!
    defines the structure of a persistent object header for 
    variable objects ( used within continuous container ) 
*/
struct tbd900_ContObjHeader
{
    /*! 
        page number of the OID of the variable persistent object
        ( page number within primary container )
    */
    tsp00_PageNo        cvoRootOIdPno_bd900;    
    /*! 
        page position of the OID of the variable persistent object    
    */
    tgg00_ObjPagePos    cvoRootOIdPos_bd900;
    /*! 
        chain of free frames           
    */
    tgg00_ObjPagePos    cvoNextFreeObj_bd900;   
};

/*!
    defines the structure of a persistent object frame for 
    variable objects ( within continuous container )  
*/
struct tbd900_ContObjFrame
{
    tbd900_ContObjHeader cofHeader_bd900; /*!< header */
    tgg91_ObjAnyBody     cofBody_bd900;   /*!< body   */
};

/*!
    defines the structure of the body of variable object
    frames within the primary container
*/
class tbd900_VarObjBodyHeader
{
public:
    tsp00_Int4          vhdObjSize_bd900;           /*!< object size                  */
    tsp00_Int4          vhdContObjFileNo_bd900;     /*!< continue object container no */
    /*! 
        page number of page within continous container where variable 
        object body is stored
        if object is stored within primary container cvoRootOIdPno_bd900
        is set to NIL_PAGE_NO_GG00
    */
    tsp00_PageNo        vhdContObjPno_bd900;        
    /*! 
        position on page cvoRootOIdPno_bd900 where variable object 
        frame is stored 
        if object is stored within primary container cvoRootOIdPno_bd900
        is set to NIL_OBJ_PAGE_POS_GG92
    */
    tgg00_ObjPagePos    vhdContObjPos_bd900;
    /*!
        variable is set to true, if an object, which is too large to be stored 
        completely in the primary container, is split across the primary and the 
        continuation container.
        if the object is either stored completely in the primary or the continuation
        container, then the variable is set to false.
        \since PTS 1121823
    */
    tsp00_Bool          vhdObjectIsSplit_bd900;
    tsp00_Uint1         vhdFiller_bd900;            /*!< filler                       */

    /*!
        initialize header for variable objects 
        @return none
    */
    void bd900SetToEmptyHeader()
    {
        vhdContObjPno_bd900    = NIL_PAGE_NO_GG00;
        vhdContObjPos_bd900    = NIL_OBJ_PAGE_POS_GG92;
        vhdContObjFileNo_bd900 = PRIM_CONT_OBJ_FILE_NO_BD900;
        vhdObjSize_bd900       = 0;
        vhdObjectIsSplit_bd900 = false;   // PTS 1121823
        vhdFiller_bd900        = 0;
    }
};

/*!
    defines the structure of the body of variable object
    frames within the primary container
*/
struct tbd900_VarObjBody
{
    tbd900_VarObjBodyHeader vbdHeader_bd900;    /*!< header */
    tgg91_ObjAnyBody        vbdBody_bd900;      /*!< body   */
};

typedef tsp00_Int4       tbd900_PageCounter;    /*!< page counter  */

/*!
    defines the structure of the chain info
    each object container may use more than one page chain for 
    performance reasons ( striping )
*/
class  cbd900_ObjChainInfo
{
    friend class cbd900_ObjFileInfo;
    
public:
    tsp00_PageNo    ociSubRoot_bd900;       /*!< page number of subroot  */
    //PTS 1130998 tsp00_PageNo    ociFiller2_bd900;       /*!< page number out of freepage */              
    tsp00_Int4      ociFreePageCnt_bd900;   /*!< # of free pages in chain starting at the subroot     PTS 1130998 */ 
private:
    tsp00_Int4      ociAllObjCnt_bd900;     /*!< # of all object frames which are not free */          
public:
    tsp00_Int4      ociAllPageCnt_bd900;    /*!< # of all pages in chain starting at the subroot */   
    tsp00_Int2      ociCurrActivGC_bd900;   /*!< index of the GC currently active on this chain */
    tsp00_Bool      ociFiller0_bd900;       /*!< filler */
    tsp00_Bool      ociFiller1_bd900;       /*!< filler */
    tsp00_Int4      ociAllObjCntOnSubRoot_bd900; /*!< # of all objects */ /*PTS 1111390 AK 14/08/2001 */
    
public:
    friend SAPDB_OStream& operator<<(SAPDB_OStream& os, const cbd900_ObjChainInfo& chaininfo);
    void IncrementAllObjCnt();
    void DecrementAllObjCnt();
    tsp00_Int4 GetAllObjCnt() const;
    void SetAllObjCnt(tsp00_Int4 num);

    cbd900_ObjChainInfo();          /*!< ctor */
    /*!
        initialize chain info
        @param NptrsSubRoot [in]    subroot information
        @return none
    */
    void  bd900SetChainInfo   (tbd_node_ptrs   &NptrsSubRoot); 
    void  bd900ResetChainInfo ();  /*!< reset chain info information */      

private:
    void ModifyAllObjCnt(tsp00_Int4 diff, bool bIncrement);
    /*!
        dump chain info into buffer
        @param BufferSize [in]  size of buffer provided
        @param Buffer [in]  buffer address 
        @param OutPos [in]  position within buffer where to store information
        @return none
    */
    void  bd900DumpChainInfo (tsp00_Int4          BufferSize,
                              tsp00_Page         &Buffer,
                              tsp00_Int4         &OutPos);

    /*!
        check size of structure
        note that the dump routines in vxt08 rely on the size of this structure 
    */
    CHECK_MAPPABLE_CLASS_GIVEN_SIZE_SP00 (cbd900_ObjChainInfo, 24)
};

/*!
    defines the structure of the object file information held
    within the object file directory for each file 
*/
class cbd900_ObjFileInfo
{
public:
    enum eFileType {omsFixedFile, omsKeyedFile, omsVariableFile, omsContinousFile};

private:
 	// tsp00_Int4         ofiCurrChain_bd900;       /*!< current chain index *PTS 1134645 */
    tsp00_Bool         ofiRecreateIndex_bd900;      // PTS 1134645
    tsp00_Uint1        ofiNumKeyPartitions_bd900;   // PTS 1134645
    tgg00_BasisError   ofiRecreateIndexError_bd900; // PTS 1134645
    tsp00_Int4         ofiMaxChain_bd900;           /*!< max. number of chains       */
    tsp00_Int4         ofiMaxObjPerPageCnt_bd900;   /*!< max. object frames per page */
    tsp00_Int4         ofiMaxObjBodySize_bd900;     /*!< max. object body size       */
public: 
    Container_Vector <tsp00_PageNo> ofiKeyRoots_bd900; /*!< vector of key roots      */
private:
    tsp00_PageNo       ofiRoot_bd900;               /*!< container root page number  */    
    tsp00_Bool         ofiFileIsForVarObj_bd900;    /*!< var. object container       */
public: 
    tsp00_Bool         ofiRelFileIsReq_bd900;       /*!< release pages because of drop container */
    tsp00_Bool         ofiFiller1_bd900;            /*!< before ofiOldFile_bd900;   not used anymore */ //(see CRS 1109486)
    tsp00_Bool         ofiDropFile_bd900;           /*!< container has been dropped but not yet removed */ // PTS 1119647 FF 2002-DEC-05
    tgg91_TransNo      ofiTransNo;                  /*!< transno of drop container   */ // PTS 1119647 FF 2002-DEC-05
    tsp00_Int2         ofiFiller2_bd900;            /*!< filler                      */ // PTS 1119647 FF 2002-DEC-05
    /*!
        vector of chain infos of container
    */
    ARRAY_VAR_MSP00 (ofiChain_bd900, cbd900_ObjChainInfo, MAX_NUM_CHAINS_PER_CONTAINER_BD900);    

    /* PTS 1109980 AK 11/04/2001                                                        */
    /* note, that all fillers in the structure due to aligning have to be initialized   */
    /* since objects of this type are compared in bd920Verify via memcmp therefore this */
    /* macro checks that no implicite filler sneaks into the structure                  */
    /*!
        check size of structure
        note that the dump routines in vxt08 rely on the size of this structure 
    */
#   ifdef BIT64
    CHECK_MAPPABLE_CLASS_GIVEN_SIZE_SP00 (cbd900_ObjFileInfo, 56 + MAX_NUM_CHAINS_PER_CONTAINER_BD900 * sizeof(cbd900_ObjChainInfo))
#   else
    CHECK_MAPPABLE_CLASS_GIVEN_SIZE_SP00 (cbd900_ObjFileInfo, 48 + MAX_NUM_CHAINS_PER_CONTAINER_BD900 * sizeof(cbd900_ObjChainInfo))
#   endif

public: 
  cbd900_ObjFileInfo ();        //!< ctor */
  /*!
        ctor
        @param Current [in] file current
        @param NptrsRoot [in] pointer to root page 
        @param MaxObjBodySize [in]  max. body size
        @param MaxObjPerPageCnt [in] max. # of object frames per page
  */
  cbd900_ObjFileInfo (tbd_current_tree  &Current,
                      tbd_node_ptrs     &NptrsRoot,
                      tsp00_Int4         MaxObjBodySize,
                      tsp00_Int4         MaxObjPerPageCnt);
  /*!
        current chain in which the next new object will be inserted 
  */
  tsp00_Int4   bd900CurrChain ();         
  tsp00_Bool&  bd900RecreateIndex ();            // PTS 1134645
  tsp00_Uint1  bd900NumKeyPartitions () const;   // PTS 1134645
  tgg00_BasisError& bd900RecreateIndexError ();  // PTS 1134645
  /*!
        reset object file info
  */
  void         bd900ResetFileInfo (); 
  /*!
        object file info entry not used
  */
  bool         bd900FileInfoIsEmpty() const; 
  /*!
        Number of all pages in the object container
  */
  tsp00_Int4   bd900NumAllPages()     const; 
  /*!
        Number of pages required to accomodate all none free object frames 
        @return number of pages
  */
  tsp00_Longreal bd900NumOccPages()     const; // PTS 1114534 FF 2002-02-28
  /*!
        get number of garbage collectors active on container 
        @param NumReqGC [in]    number of garbage collectors requested   
        @param NumActiveGC [in] number of garbage collectors active 
        @return none
  */
  void         bd900GetNumOfActiveGCs (tsp00_Int4 & NumReqGC,
                                       tsp00_Int4 & NumActiveGC);
  /*!
        re-initialize object file info 
        @param Current [in] file current
        @param NptrsRoot [in] pointer to root page 
        @param MaxObjBodySize [in]  max. body size
        @param MaxObjPerPageCnt [in] max. # of object frames per page
  */
  void         bd900SetFileInfo (tbd_current_tree     &Current,
                                 tbd_node_ptrs        &NptrsRoot,
                                 tsp00_Int4            MaxObjBodySize,
                                 tsp00_Int4            MaxObjPerPageCnt);
  /*!
        dump object file info (NOT USED ANYMORE)
  */
  void         bd900DumpFileInfo (tgg00_VfFileref    &HostFile,
                                  tsp00_Uint4         BufferSize,
                                  tsp00_Page         &Buffer,
                                  tsp00_Int4         &OutPno,
                                  tsp00_Int4         &OutPos,
                                  tsp00_VfReturn     &HostError,
                                  tsp00_ErrText      &ErrText,
                                  tsp00_Int2         &ElemsOnThisPage,
                                  tsp00_Int4         &NumElemPos,
                                  tsp00_Int4          FileNo,
                                  tsp00_Int4          ContFileNo,
                                  tsp00_Int2          DumpCode,
                                  char               *DumpMark,
                                  tgg00_BasisError   &MoveError);

  /*!
        access one chain info by index
  */
  cbd900_ObjChainInfo & operator[] (tsp00_Int4 i) { return ofiChain_bd900[i]; };

  friend SAPDB_OStream& operator<< (SAPDB_OStream& os, const cbd900_ObjFileInfo& fileinfo);

  /*!
        copy object file info 
        @param right [in] source
        @param TrError [out] error code
        @return destination 
  */
  const cbd900_ObjFileInfo & assign(const cbd900_ObjFileInfo& right, tgg00_BasisError &TrError) 
  {
      int ix;
      //ofiCurrChain_bd900         = right.ofiCurrChain_bd900;        // PTS 1134645
      ofiRecreateIndex_bd900     = right.ofiRecreateIndex_bd900;      // PTS 1134645
      ofiRecreateIndexError_bd900= right.ofiRecreateIndexError_bd900; // PTS 1134645
      ofiNumKeyPartitions_bd900  = right.ofiNumKeyPartitions_bd900;   // PTS 1134645
      ofiMaxChain_bd900          = right.ofiMaxChain_bd900;
      ofiMaxObjPerPageCnt_bd900  = right.ofiMaxObjPerPageCnt_bd900;
      ofiMaxObjBodySize_bd900    = right.ofiMaxObjBodySize_bd900;
      int numKeys = right.GetKeyPartitionCount(); 
      if (0 < numKeys) {
          if (!ofiKeyRoots_bd900.Resize(numKeys)) {
              ofiKeyRoots_bd900.Clear();
              TrError = e_sysbuf_storage_exceeded;
          }
          else
          for ( ix=0; ix < numKeys; ix++ )
              ofiKeyRoots_bd900[ix] = right.ofiKeyRoots_bd900[ix];
      }
      else
        ofiKeyRoots_bd900.Clear();
      ofiRoot_bd900              = right.ofiRoot_bd900;
      ofiFileIsForVarObj_bd900   = right.ofiFileIsForVarObj_bd900;
      ofiRelFileIsReq_bd900      = right.ofiRelFileIsReq_bd900;
      ofiFiller1_bd900           = right.ofiFiller1_bd900;  
      ofiDropFile_bd900          = right.ofiDropFile_bd900; // PTS 1119647 FF 2002-DEC-05
      ofiTransNo                 = right.ofiTransNo;        // PTS 1119647 FF 2002-DEC-05 
      ofiFiller2_bd900           = right.ofiFiller2_bd900;  // PTS 1119647 FF 2002-DEC-05
      for ( ix=0; ix < ofiMaxChain_bd900; ix++ ) {
          ofiChain_bd900[ix] = right.ofiChain_bd900[ix];
      }
      return *this;
  };
  
  /*!
        create file id 
        @param FileNo [in] file number
        @param ObjFileId [out] object file id
        @return destination 
  */
  void  bd900BuildFileId    (tgg00_ObjFileNo       FileNo,    //PTS 1111901 AK 24/09/2001
                             tgg00_FileId         &ObjFileId);

  /*!
        get number of container chains used for striping  
        @return number of container chains
  */

  tsp00_Uint2 GetChainCount() const;

  /*!
        get file type
        @return file type
  */

  eFileType GetFileType() const;
  /*!
        get number of key index trees
        @return get number of key index trees
  */

  tsp00_Uint2 GetKeyPartitionCount() const;

  /*!
        get size of persistent objects stored  
        @return size of persistent objects stored
  */
  tsp00_Uint4 GetObjBodySize() const;

  /*!
        get number of object frames per page  
        @return number of object frames per page
  */

  tsp00_Uint2 GetObjPerPageCount() const;

  /*!
        get root page number  
        @return root page number  
  */
  tsp00_PageNo GetRootPage() const;

  /*!
        set size of persistent objects stored  
  */
  void SetObjBodySize(tsp00_Uint4 bodysize);

  /*!
        set root page number  
  */
  void SetRootPage(tsp00_PageNo pageNo);
};

inline cbd900_ObjFileInfo::eFileType cbd900_ObjFileInfo::GetFileType() const {
    if (ofiFileIsForVarObj_bd900) return (omsVariableFile);
    if (GetKeyPartitionCount() > 0) return (omsKeyedFile);
    return (omsFixedFile);
};

inline tsp00_Uint2 cbd900_ObjFileInfo::GetKeyPartitionCount() const {
 	return ofiNumKeyPartitions_bd900;   // PTS 1134645 
    //return STATIC_CAST(tsp00_Uint2, ofiKeyRoots_bd900.GetSize());
};

inline tsp00_Uint2 cbd900_ObjFileInfo::GetChainCount() const {
    return STATIC_CAST(tsp00_Uint2, ofiMaxChain_bd900);
};

inline tsp00_Uint4 cbd900_ObjFileInfo::GetObjBodySize() const {
    return STATIC_CAST(tsp00_Uint4, ofiMaxObjBodySize_bd900);
};

inline tsp00_Uint2 cbd900_ObjFileInfo::GetObjPerPageCount() const {
    return STATIC_CAST(tsp00_Uint2, ofiMaxObjPerPageCnt_bd900);
};

inline tsp00_PageNo cbd900_ObjFileInfo::GetRootPage() const {
    return ofiRoot_bd900;
};

inline void cbd900_ObjFileInfo::SetObjBodySize(tsp00_Uint4 bodysize) {
    ofiMaxObjBodySize_bd900 = STATIC_CAST(tsp00_Int4, bodysize);
};

inline void cbd900_ObjFileInfo::SetRootPage(tsp00_PageNo pageNo) {
    ofiRoot_bd900 = pageNo;
};

/* --- local class CSynchObject --- */
class cbd900_FDirSynchObject
{
private:
    tsp00_TaskId m_TaskId;
public:
    cbd900_FDirSynchObject  (tsp00_TaskId TaskId) :m_TaskId(TaskId) {vbegexcl (m_TaskId, g08garbage);};
    ~cbd900_FDirSynchObject ()                                      {vendexcl (m_TaskId, g08garbage);}; 
};

/*!
    object file directory
*/
class  cbd900_ObjFileDir : 
public cbd920_ChainedListHash <tgg00_ObjFileNo, cbd900_ObjFileInfo, cbd900_FDirSynchObject, HASH_WIDTH_BD900, NUM_OBJ_FILE_INFOS_TO_ALLOCATE_BD900>

{
public://methods 
  /*!
        dump object file directory (NOT USED ANYMORE)
  */
  void  bd900DumpObjFileDir (tgg00_VfFileref      &HostFile,
                             tsp00_Int4            BufferSize,
                             tsp00_Page           &Buffer,
                             tsp00_Int4           &OutPno,
                             tsp00_Int4           &OutPos,
                             tsp00_VfReturn       &HostError,
                             tsp00_ErrText        &ErrText,
                             tgg00_BasisError     &MoveError);
};

/*!
    iterator for object file directory
*/
typedef cbd920_HashIter <tgg00_ObjFileNo, cbd900_ObjFileInfo, cbd900_FDirSynchObject, HASH_WIDTH_BD900, NUM_OBJ_FILE_INFOS_TO_ALLOCATE_BD900> 
cbd900_ObjFileDirIter;

/*!
    continous container object file information
*/
class  cbd900_ContObjFileInfo
{
public: 
    tsp00_Int4          cfiNumContFiles_bd900;    /*!< number of continous files for container */

#   ifdef BIT64
    tsp00_Int4          cfiFiller_bd900;		 /*!< filler because of alignment       */
#   endif

private:
	/*!
		vector of object file information of each continous container 
	*/
    ARRAY_VAR_MSP00    (cfiContFile_bd900, cbd900_ObjFileInfo, MAX_NUM_CONT_OBJ_FILES_BD900);

    /* PTS 1109980 AK 11/04/2001                                                        */
    /* note, that all fillers in the structure due to aligning have to be initialized   */
    /* since objects of this type are compared in bd920Verify via memcmp therefore this */
    /* macro checks that no implicite filler sneaks into the structure                  */
    /*!
        check size of structure
        note that the dump routines in vxt08 rely on the size of this structure 
    */
#   ifdef BIT64
    CHECK_MAPPABLE_CLASS_GIVEN_SIZE_SP00 (cbd900_ContObjFileInfo, 8 + MAX_NUM_CONT_OBJ_FILES_BD900 * sizeof(cbd900_ObjFileInfo))
#   else
    CHECK_MAPPABLE_CLASS_GIVEN_SIZE_SP00 (cbd900_ContObjFileInfo, 4 + MAX_NUM_CONT_OBJ_FILES_BD900 * sizeof(cbd900_ObjFileInfo))
#   endif
    
public:
    friend SAPDB_OStream& operator<<(SAPDB_OStream& os, cbd900_ObjChainInfo& chaininfo);
  /*!
        copy continous object file info 
        @param right [in] source
        @param TrError [out] error code
        @return destination 
  */
  const cbd900_ContObjFileInfo & assign(const cbd900_ContObjFileInfo& right, tgg00_BasisError &TrError) 
  {
      int ix;
      cfiNumContFiles_bd900         = right.cfiNumContFiles_bd900;
#     ifdef BIT64
      cfiFiller_bd900               = right.cfiFiller_bd900;
#     endif
      for ( ix=0; (ix < cfiNumContFiles_bd900) && (e_ok == TrError); ix++ ) {
          cfiContFile_bd900[ix].assign(right.cfiContFile_bd900[ix], TrError);
      }
      return *this;
  };
  /*!   
        ctor
  */
  cbd900_ContObjFileInfo() 
        :cfiNumContFiles_bd900(0)
#       ifdef BIT64
        ,cfiFiller_bd900(0)
#       endif   
    {}; cbd900_ObjFileInfo & operator[] (tsp00_Int4 i) {return cfiContFile_bd900[i-1];};

  /*!
        create file id 
        @param FileNo [in] file number
        @param ContFileNo [in] continous container index
        @param ContObjFileId [out] continous container object file id
        @return destination 
  */
    void bd900BuildFileId (tgg00_ObjFileNo  FileNo,         //PTS 1111901 AK 24/09/2001
                           tsp00_Int4       ContFileNo,
                           tgg00_FileId    &ContObjFileId);
};

inline SAPDB_OStream& operator<<(SAPDB_OStream& os, cbd900_ContObjFileInfo& continfo)
{
    os << NewLine << " #ContFiles:" << continfo.cfiNumContFiles_bd900;
#   ifdef BIT64
    os << " Filler:" << continfo.cfiFiller_bd900;
#   endif
    for ( int ix=1; ix <= MAX_NUM_CONT_OBJ_FILES_BD900; ix++ ) {
        os << NewLine << " ***contfile:" << ix << "*** " << continfo[ix];
    }
    return os;
};

/*!
    continous object file directory
*/
class  cbd900_ContObjFileDir : 
public cbd920_ChainedListHash <tgg00_ObjFileNo, cbd900_ContObjFileInfo, cbd900_FDirSynchObject, HASH_WIDTH_BD900, NUM_CONT_OBJ_FILE_INFOS_TO_ALLOCATE_BD900>
{
public:
  /*!
        dump continous object file directory (NOT USED ANYMORE)
  */
  void bd900DumpContObjFileDir (tgg00_VfFileref      &HostFile,
                                tsp00_Int4            BufferSize,
                                tsp00_Page           &Buffer,
                                tsp00_Int4           &OutPno,
                                tsp00_Int4           &OutPos,
                                tsp00_VfReturn       &HostError,
                                tsp00_ErrText        &ErrText,
                                tgg00_BasisError     &MoveError);
};

/*!
    iterator for continous object file directory
*/
typedef cbd920_HashIter <tgg00_ObjFileNo, cbd900_ContObjFileInfo, cbd900_FDirSynchObject, HASH_WIDTH_BD900, NUM_CONT_OBJ_FILE_INFOS_TO_ALLOCATE_BD900>
cbd900_ContObjFileDirIter;

/*!
    file id for key tree
*/
class cbd900_ObjKeyFileId : public tgg00_FileId
{
public:
	/*!
		ctor
    */
    cbd900_ObjKeyFileId() {};
	/*!
		ctor
        @param ObjFileInfo [in] object file info
        @param ObjFileNo [in] object file no
        @param ObjKeyFileIndex [in] key index
	*/
    cbd900_ObjKeyFileId (cbd900_ObjFileInfo		   &ObjFileInfo, 
                         const tgg00_ObjFileNo      ObjFileNo,    //PTS 1111901 AK 24/09/2001
                         const tsp00_Int4           ObjKeyFileIndex);

    void bd900SetObjKeyFileId (cbd900_ObjFileInfo  &ObjFileInfo, 
        const tgg00_ObjFileNo ObjFileNo,    
        const tsp00_Int4      ObjKeyFileIndex);
};

/*!
    root page header information
*/
class cbd900_RootPageData
{
    friend class cbd900_RootPageInfo;

    tsp00_Uint2   rpdNumChains_bd900;                                        //!< # of chains in this container
    tsp00_Bool    rbdFileIsDeleted_bd900;                                    //!< file is marked for delete
    tsp00_Uint1   rpdNumObjKeyFiles_bd900;                                   //!< # of key files 
    tsp00_Uint2   rpdNumContFile_bd900;                                      //!< # of continuation files
    tsp00_Uint2   rpdFiller1_bd900;											 //!< filler 
    tsp00_PageNo  rpdSubRoot_bd900  [MAX_NUM_CHAINS_PER_CONTAINER_BD900];    //!< list of subroots of this root
    tsp00_PageNo  rpdContRoot_bd900 [MAX_NUM_CONT_OBJ_FILES_BD900];          //!< list of roots of continuation files
};

/*!
    subroot page header information
*/
class cbd900_SubRootPageData
{
    friend class cbd900_SubRootPageInfo;
    
    tbd900_PageCounter     spdAllPageCnt_bd900;        //!< # all pages in chain starting at the subroot 
    tbd900_PageCounter     spdFiller0;                 //!< # spdEmptyPageCnt_bd900 empty pages       PTS 115760
    tbd900_PageCounter     spdFreePageCnt_bd900;       //!< # pages with free objetcs 
    tsp00_Int4             spdAllObjCnt_bd900;         //!< dirty counter of all objects which are not free  
    /* spdMaxPageSeqNo_bd900 can't be defined as teo00_Uint8 because this would result in wrong */
    /* record position because of higher alignment with 32 Bit environments                     */
    tsp00_Int4             spdMaxPageSeqNo1_bd900;     //!< max page sequence number
    tsp00_Int4             spdMaxPageSeqNo2_bd900;     //!< max page sequence number
};

/*!
    root & subroot page header information
*/
class cbd900_RootAndSubRootPageData
{
    friend class cbd900_RootPageInfo;
    friend class cbd900_SubRootPageInfo;

    cbd900_SubRootPageData rsdSubRootPageData_bd900;	//!< sub root information
    cbd900_RootPageData    rsdRootPageData_bd900;		//!< root information

    /*!
        check size of structure
        note that the dump routines in vxt08 rely on the size of this structure 
    */
    CHECK_MAPPABLE_CLASS_UPPER_SIZE_SP00 (cbd900_RootAndSubRootPageData,  FULLCOVERING_BD00)
};

/*!
    root & subroot page information handler
*/
class cbd900_RootAndSubRootPageInfo
{
    friend class cbd900_RootPageInfo;
    friend class cbd900_SubRootPageInfo;

private:
    cbd900_RootAndSubRootPageData * rsiRootAndSubRootPageDataPtr_bd900; //!< pointer on root&subroot information
    cbd900_RootAndSubRootPageInfo (tbd_node_ptrs  &Nptrs);				//!< ctor
};

/*!
    root page information handler
*/
class cbd900_RootPageInfo : public cbd900_RootAndSubRootPageInfo
{
public:
    cbd900_RootPageInfo (tbd_node_ptrs   &Nptrs);					//!< ctor
    tsp00_Uint2          &bd900NumChains();							//!< get # of chains
    tsp00_Uint1          &bd900NumObjKeyFiles();					//!< get # of key files
    tsp00_Bool           &bd900FileIsDeleted();						//!< dropped
    const tsp00_PageNo   &bd900SubRoot (const int ChainNo);			//!< get sub root page number
    tsp00_Uint2          &bd900NumContFiles();						//!< number of continous container
    tsp00_PageNo         &bd900ContRoot (const int ContFileNo);		//!< get root of continous container
    void                  bd900InitRootPageInfo();					//!< initialize root page info
    void                  bd900AddSubRoot (tsp00_PageNo SubRootPageNo); //!< add a subroot to root
    
private:
    tsp00_PageNo         &bd900_SubRoot (const int ChainNo);		//!< get sub root page number
};

/*!
    subroot page information handler
*/
class cbd900_SubRootPageInfo : public cbd900_RootAndSubRootPageInfo
{
public:
    cbd900_SubRootPageInfo (tbd_node_ptrs  &Nptrs);				   //!< ctor
    tsp00_Int4              &bd900AllPageCnt ();				   //!< get # of pages
    tsp00_Int4              &bd900Filler0 ();					   //!< get filler
    tsp00_Int4              &bd900FreePageCnt ();				   //!< get free page count
    tsp00_Int4              &bd900AllObjCnt ();					   //!< get # of objects in use 
    teo00_Uint8              bd900GetMaxPageSeqNo ();			   //!< get actual sequence number
    void                     bd900SetMaxPageSeqNo (teo00_Uint8 seqno); //!< set actual sequence number
    void                     bd900InitSubRootPageInfo();		   //!< init sub root 
};

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

inline void
tbd900_ObjFrame::bd900SetToReservedFrame (tsp00_Int4         ObjFrameLen,
                                          tsp00_Int4         KeyLen,
                                          tgg00_ObjFrameVers ObjFrameVers,
                                          tsp00_Bool         bFrameIsForVarObjects)
{
    objHeader_bd900.ohdNextFreeObj_gg92  = NIL_OBJ_PAGE_POS_GG92;
    objHeader_bd900.ohdFrameVersion_gg92 = ObjFrameVers;
    objHeader_bd900.ohdState_gg92.becomes((KeyLen==0)?obsReserved_egg00:obsKeyReserved_egg00);
    
    /* initialize the object body, i.e. the first four bytes  */
    /* of the body are filled with                            */
    const int InitStringLen             = 11;
    char      InitString[InitStringLen] = "AAAAAAAAAA";
    int       ObjSize                   = ObjFrameLen - KeyLen - sizeof(tgg92_ObjHeader);
    
    if (bFrameIsForVarObjects)
    {
        ObjSize -= sizeof (tbd900_VarObjBodyHeader);
        tbd900_VarObjBody & VarObjBody = *((tbd900_VarObjBody*) (objBody_bd900));
        VarObjBody.vbdHeader_bd900.bd900SetToEmptyHeader();
        SAPDB_MemCopyNoCheck (VarObjBody.vbdBody_bd900, InitString, SAPDB_MIN (InitStringLen, ObjSize));
    }
    else
        SAPDB_MemCopyNoCheck (objBody_bd900, InitString, SAPDB_MIN (InitStringLen, ObjSize));  
}



/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ObjChainInfo                                            */
/*---------------------------------------------------------------------------*/
inline SAPDB_OStream& operator<<(SAPDB_OStream& os, const cbd900_ObjChainInfo& chaininfo)
{
    os << " SubRoot:" << chaininfo.ociSubRoot_bd900
        << " #FreePage:" << chaininfo.ociFreePageCnt_bd900
        << " #AllObjs:" << chaininfo.ociAllObjCnt_bd900
        << " ActGC:" << chaininfo.ociCurrActivGC_bd900
        << " Filler0:" << chaininfo.ociFiller0_bd900
        << " Filler1:" << chaininfo.ociFiller1_bd900
        << " #AllObjOnSubRoot:" << chaininfo.ociAllObjCntOnSubRoot_bd900;
    return os;
};

inline  void
cbd900_ObjChainInfo::bd900DumpChainInfo (tsp00_Int4          BufferSize,
                                         tsp00_Page         &Buffer,
                                         tsp00_Int4         &OutPos)
{
    ROUTINE_DBG_MEO00 ("bd900DumpChainInfo");
    
    // PTS 1111702 AK 10/09/2001
    if ((OutPos - 1 + tsp00_Int4(sizeof(*this))) > BufferSize)
    {
        /* PTS 1114951 FF 2002-04-19  */
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "bd900DumpChainInfo: not enough space within dump-buffer !";   
    }
    else
    {
        SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, this,  sizeof(*this));
        OutPos += sizeof(*this);
    }
}

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

inline void 
cbd900_ObjChainInfo::ModifyAllObjCnt(tsp00_Int4 diff, bool bIncrement) 
{
    tsp00_Int4 expectedVal = ociAllObjCnt_bd900;
    tsp00_Int4 newVal;
    tsp00_Int4 oldVal = 0;
    if (bIncrement)
        newVal = expectedVal + diff;
    else 
        newVal = diff;

    while ( ! RTESys_CompareAndExchange( ociAllObjCnt_bd900, expectedVal, newVal, oldVal))
    {
        expectedVal = oldVal;
        if (bIncrement)
            newVal = expectedVal + diff;
        else 
            newVal = diff;
        oldVal = 0;
    }
};

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

inline void 
cbd900_ObjChainInfo::IncrementAllObjCnt() 
{
    //ModifyAllObjCnt(+1, true);
    ++ociAllObjCnt_bd900;
};

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

inline void 
cbd900_ObjChainInfo::DecrementAllObjCnt() 
{
    //ModifyAllObjCnt(-1, true);
    --ociAllObjCnt_bd900;
};

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

inline tsp00_Int4 
cbd900_ObjChainInfo::GetAllObjCnt() const 
{ 
    //RTESys_ReadMemoryBarrier();
    return ociAllObjCnt_bd900; 
};

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

inline void 
cbd900_ObjChainInfo::SetAllObjCnt(tsp00_Int4 num) 
{
    ModifyAllObjCnt(num, false);
    ociAllObjCnt_bd900 = num;
};

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

inline void
cbd900_ObjChainInfo::bd900ResetChainInfo()
{
    ociFiller0_bd900            = false;
    ociFiller1_bd900            = false;
    ociSubRoot_bd900            = NIL_PAGE_NO_GG00;
    SetAllObjCnt(0);
    ociAllPageCnt_bd900         = 0;   
    ociCurrActivGC_bd900        = NIL_GC_INDEX_BD900;
    ociAllObjCntOnSubRoot_bd900 = 0;
    ociFreePageCnt_bd900        = 0;            /* PTS 1130998 */
}

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

inline void  
cbd900_ObjChainInfo::bd900SetChainInfo (tbd_node_ptrs   &NptrsSubRoot)
{    
    bd900ResetChainInfo();
    cbd900_SubRootPageInfo SubRootPageInfo (NptrsSubRoot);
    ociSubRoot_bd900            = NptrsSubRoot.np_ptr()->nd_id();
    SetAllObjCnt(SubRootPageInfo.bd900AllObjCnt());
    ociAllPageCnt_bd900         = SubRootPageInfo.bd900AllPageCnt();  
    ociAllObjCntOnSubRoot_bd900 = SubRootPageInfo.bd900AllObjCnt();
    ociFreePageCnt_bd900        = SubRootPageInfo.bd900FreePageCnt();   /* PTS 1130998 */
}

/*---------------------------------------------------------------------------*/
inline
cbd900_ObjChainInfo::cbd900_ObjChainInfo()
{
    bd900ResetChainInfo();
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ObjFileInfo                                             */
/*---------------------------------------------------------------------------*/
inline
cbd900_ObjFileInfo::cbd900_ObjFileInfo (tbd_current_tree     &Current,
                                        tbd_node_ptrs        &NptrsRoot,
                                        tsp00_Int4            MaxObjBodySize,
                                        tsp00_Int4            MaxObjPerPageCnt)
: ofiKeyRoots_bd900 (RTEMem_Allocator::Instance())
{ 
    bd900SetFileInfo (Current, NptrsRoot, MaxObjBodySize, MaxObjPerPageCnt);
}

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

inline
cbd900_ObjFileInfo::cbd900_ObjFileInfo()
:ofiKeyRoots_bd900 (RTEMem_Allocator::Instance())
{    
    bd900ResetFileInfo();
}

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

inline tsp00_Int4
cbd900_ObjFileInfo::bd900CurrChain ()
{ 
    //tsp00_Int4 CurrChain (ofiCurrChain_bd900);        PTS 1134645
    //CurrChain  = (++CurrChain % ofiMaxChain_bd900);
    //ofiCurrChain_bd900 = CurrChain;
    //return (CurrChain);
    return 0;
};

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

inline tsp00_Bool&   
cbd900_ObjFileInfo::bd900RecreateIndex ()      // PTS 1134645
{ 
    return ofiRecreateIndex_bd900;
};

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

inline tsp00_Uint1  
cbd900_ObjFileInfo::bd900NumKeyPartitions () const  // PTS 1134645
{ 
    return ofiNumKeyPartitions_bd900;
};

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

inline tgg00_BasisError& 
cbd900_ObjFileInfo::bd900RecreateIndexError () // PTS 1134645
{ 
    return ofiRecreateIndexError_bd900;
};

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

inline  bool         
cbd900_ObjFileInfo::bd900FileInfoIsEmpty() const
{
    return (ofiRoot_bd900 == NIL_PAGE_NO_GG00);
};

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ObjFileInfo                                             */
/*---------------------------------------------------------------------------*/

inline externCpp void
cbd900_ObjFileInfo::bd900BuildFileId (tgg00_ObjFileNo   FileNo ,       //[inp] PTS 1111901 AK 24/09/2001
                                      tgg00_FileId     &ObjFileId)     //[out]
{
    ROUTINE_DBG_MSP00 ("bd900BuildFileId");
    
    ObjFileId = b01niltree_id;
    ObjFileId.fileRoot_gg00()          = ofiRoot_bd900;
    ObjFileId.fileObjFileNo_gg00()     = FileNo;
    ObjFileId.fileContObjFileNo_gg00() = PRIM_CONT_OBJ_FILE_NO_BD900;
    ObjFileId.fileTfn_gg00().becomes(tfnObj_egg00); 
    ObjFileId.fileType_gg00().clear();
    ObjFileId.fileType_gg00().addElement (ftsObject_egg00);      
    ObjFileId.fileType_gg00().addElement (ftsConcurrent_egg00); 
    ObjFileId.fileType_gg00().addElement (ftsPerm_egg00);
    ObjFileId.fileNumObjKeyFiles_gg00() = STATIC_CAST(tsp00_Uint1,GetKeyPartitionCount());

    if (this->ofiFileIsForVarObj_bd900)
        ObjFileId.fileObjFileType_gg00().becomes (oftVarLenObjFile_egg00);
    else
        ObjFileId.fileObjFileType_gg00().becomes (oftFixLenObjFile_egg00);
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ContObjFileInfo                                         */
/*---------------------------------------------------------------------------*/
inline void 
cbd900_ContObjFileInfo::bd900BuildFileId (tgg00_ObjFileNo  FileNo,  //PTS 1111901 AK 24/09/2001
                                          tsp00_Int4       ContFileNo,
                                          tgg00_FileId    &ContObjFileId)
{
    ROUTINE_DBG_MSP00 ("bd900BuildFileId");
    
    ContObjFileId = b01niltree_id;
    ContObjFileId.fileRoot_gg00()          = operator[](ContFileNo).GetRootPage(); 
    ContObjFileId.fileObjFileNo_gg00()     = FileNo;
    ContObjFileId.fileContObjFileNo_gg00() = ContFileNo;
    ContObjFileId.fileRootCheck_gg00()     = ROOT_CHECK_GG00;
    ContObjFileId.fileTfn_gg00().becomes(tfnContObj_egg00); 
    ContObjFileId.fileType_gg00().delElement (ftsTemp_egg00);
    ContObjFileId.fileType_gg00().addElement (ftsObject_egg00);      
    ContObjFileId.fileType_gg00().addElement (ftsConcurrent_egg00); 
    ContObjFileId.fileType_gg00().addElement (ftsPerm_egg00);
    ContObjFileId.fileObjFileType_gg00().becomes (oftVarLenObjFile_egg00);
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ObjKeyFileId                                            */
/*---------------------------------------------------------------------------*/

inline
cbd900_ObjKeyFileId:: cbd900_ObjKeyFileId (      cbd900_ObjFileInfo  &ObjFileInfo, 
                                           const tgg00_ObjFileNo      ObjFileNo, //PTS 1111901 AK 24/09/2001
                                           const tsp00_Int4           ObjKeyFileIndex)
//:tgg00_FileId (g01tabid.obj_hash) /* PTS 1105458 AK 26/01/2000 */ 
{
    SAPDB_MemCopyNoCheck (STATIC_CAST (tgg00_FileId *, this), &(g01tabid.obj_hash), sizeof (g01tabid.obj_hash));
    fileRoot_gg00()            = ObjFileInfo.ofiKeyRoots_bd900[ObjKeyFileIndex];
    fileObjFileNo_gg00()       = ObjFileNo;
    fileObjKeyFileIndex_gg00() = ObjKeyFileIndex;
}

inline void
cbd900_ObjKeyFileId::bd900SetObjKeyFileId (cbd900_ObjFileInfo &ObjFileInfo, 
                         const tgg00_ObjFileNo      ObjFileNo,    
                         const tsp00_Int4           ObjKeyFileIndex)
{
    SAPDB_MemCopyNoCheck (STATIC_CAST (tgg00_FileId *, this), &(g01tabid.obj_hash), sizeof (g01tabid.obj_hash));
    fileRoot_gg00()            = NIL_PAGE_NO_GG00;
    fileObjFileNo_gg00()       = ObjFileNo;
    fileObjKeyFileIndex_gg00() = ObjKeyFileIndex;
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_RootAndSubRootPageInfo                                  */
/*---------------------------------------------------------------------------*/

inline
cbd900_RootAndSubRootPageInfo::cbd900_RootAndSubRootPageInfo (tbd_node_ptrs  &Nptrs)
{
  /* CRS 1109348 AK 26/02/2001 */
  rsiRootAndSubRootPageDataPtr_bd900 = reinterpret_cast<cbd900_RootAndSubRootPageData *>  (&(Nptrs.np_ptr()->nd_body()));
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_RootPageInfo                                             */
/*---------------------------------------------------------------------------*/

inline
cbd900_RootPageInfo::cbd900_RootPageInfo(tbd_node_ptrs  &Nptrs)
:
cbd900_RootAndSubRootPageInfo (Nptrs)

{
#   if COMPILEMODE_MSP00 >= QUICK_MSP00 
    if (Nptrs.np_ptr()->nd_root() != Nptrs.np_ptr()->nd_id())
        g01abort (csp3_bd_msg, csp3_n_obj, "BD900RPI: no root       ", Nptrs.np_ptr()->nd_id());
#   endif
}

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

inline tsp00_PageNo &
cbd900_RootPageInfo::bd900ContRoot (const int ContFileNo)
{
    SAPDBERR_ASSERT_STATE ((ContFileNo > 0) && (ContFileNo <= MAX_NUM_CONT_OBJ_FILES_BD900));
    return rsiRootAndSubRootPageDataPtr_bd900->rsdRootPageData_bd900.rpdContRoot_bd900 [ContFileNo-1];
}

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

inline tsp00_Uint2 &        
cbd900_RootPageInfo::bd900NumChains()
{
   return rsiRootAndSubRootPageDataPtr_bd900->rsdRootPageData_bd900.rpdNumChains_bd900;
}

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

inline tsp00_Uint1 &        
cbd900_RootPageInfo::bd900NumObjKeyFiles()
{
   return rsiRootAndSubRootPageDataPtr_bd900->rsdRootPageData_bd900.rpdNumObjKeyFiles_bd900;
}

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

inline tsp00_Uint2 &        
cbd900_RootPageInfo::bd900NumContFiles()
{
   return rsiRootAndSubRootPageDataPtr_bd900->rsdRootPageData_bd900.rpdNumContFile_bd900;
}
/*---------------------------------------------------------------------------*/

inline tsp00_Bool &        
cbd900_RootPageInfo::bd900FileIsDeleted()
{
    return rsiRootAndSubRootPageDataPtr_bd900->rsdRootPageData_bd900.rbdFileIsDeleted_bd900;
}

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


inline tsp00_PageNo &
cbd900_RootPageInfo::bd900_SubRoot (const int ChainNo)
{
    SAPDBERR_ASSERT_STATE ((ChainNo >= 0) && (ChainNo < MAX_NUM_CHAINS_PER_CONTAINER_BD900));
    return rsiRootAndSubRootPageDataPtr_bd900->rsdRootPageData_bd900.rpdSubRoot_bd900 [ChainNo];
}

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

inline const tsp00_PageNo &
cbd900_RootPageInfo::bd900SubRoot (const int ChainNo)
{
    return bd900_SubRoot (ChainNo);
}

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

inline void
cbd900_RootPageInfo::bd900AddSubRoot (tsp00_PageNo SubRootPageNo)
{
    bd900_SubRoot (bd900NumChains()) = SubRootPageNo;
    ++bd900NumChains();
}

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

inline void 
cbd900_RootPageInfo::bd900InitRootPageInfo()
{
    bd900FileIsDeleted()                                                       = false;
    bd900NumChains()                                                           = 0;
    bd900NumObjKeyFiles()                                                      = 0;
    bd900NumContFiles()                                                        = 0;   
    rsiRootAndSubRootPageDataPtr_bd900->rsdRootPageData_bd900.rpdFiller1_bd900 = 0;
    
    for (int iChain=0; iChain<MAX_NUM_CHAINS_PER_CONTAINER_BD900; ++iChain)           
        bd900_SubRoot(iChain) = NIL_PAGE_NO_GG00;
    
    for (int iContFile=1; iContFile<=MAX_NUM_CONT_OBJ_FILES_BD900; ++iContFile)           
        bd900ContRoot(iContFile) = NIL_PAGE_NO_GG00;
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_SubRootPageInfo                                         */
/*---------------------------------------------------------------------------*/

inline
cbd900_SubRootPageInfo::cbd900_SubRootPageInfo(tbd_node_ptrs  &Nptrs)
:
cbd900_RootAndSubRootPageInfo (Nptrs)
{
#   if COMPILEMODE_MSP00 >= QUICK_MSP00 
    if (Nptrs.np_ptr()->nd_sub_root() != Nptrs.np_ptr()->nd_id())
        g01abort (csp3_bd_msg, csp3_n_obj, "BD900RPI: no sub root   ", Nptrs.np_ptr()->nd_id());
#   endif
}

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

inline tsp00_PageNo &
cbd900_SubRootPageInfo::bd900AllPageCnt ()
{
    return rsiRootAndSubRootPageDataPtr_bd900->rsdSubRootPageData_bd900.spdAllPageCnt_bd900;
}

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

inline tsp00_PageNo &
cbd900_SubRootPageInfo::bd900Filler0 ()
{
    return rsiRootAndSubRootPageDataPtr_bd900->rsdSubRootPageData_bd900.spdFiller0;
}

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

inline tsp00_PageNo &
cbd900_SubRootPageInfo::bd900FreePageCnt ()
{
    return rsiRootAndSubRootPageDataPtr_bd900->rsdSubRootPageData_bd900.spdFreePageCnt_bd900;
}

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

inline teo00_Uint8 
cbd900_SubRootPageInfo::bd900GetMaxPageSeqNo ()
{
    teo00_Uint8 seqno;
    SAPDB_MemCopyNoCheck( &seqno, 
        &rsiRootAndSubRootPageDataPtr_bd900->rsdSubRootPageData_bd900.spdMaxPageSeqNo1_bd900, 
        sizeof(teo00_Uint8));
    return seqno;
}

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

inline void 
cbd900_SubRootPageInfo::bd900SetMaxPageSeqNo (teo00_Uint8 seqno)
{
    SAPDB_MemCopyNoCheck(&rsiRootAndSubRootPageDataPtr_bd900->rsdSubRootPageData_bd900.spdMaxPageSeqNo1_bd900,
        &seqno,  
        sizeof(teo00_Uint8));
    return;
}

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

inline tsp00_Int4 &
cbd900_SubRootPageInfo::bd900AllObjCnt ()
{
    return rsiRootAndSubRootPageDataPtr_bd900->rsdSubRootPageData_bd900.spdAllObjCnt_bd900;
}

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

inline void
cbd900_SubRootPageInfo::bd900InitSubRootPageInfo()
{
    bd900AllPageCnt()       = 1;
    bd900Filler0()          = 0;
    bd900FreePageCnt()      = 0;
    bd900AllObjCnt()        = 0; 
    bd900SetMaxPageSeqNo(0);
}

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

#endif  /* GBD900_H */
