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

vbd92.cpp

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

  module      : vbd92.cpp

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

  responsible : FerdiF

  special area: BD_AuxilleryFunctionsForObjectHandling
  description : description ...


  version     : 7.4.0.0
  last changed: 2002-02-15  8:27
  see also    : 

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

  copyright:    (c) 1998-2004 SAP AG



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

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end


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


/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/
 
#include "hbd92.h"

#include "gsp03.h"
#include "gsp03_3.h"
#include "ggg12.h"
#include "gbd05.h"
#include "gbd900.h"
#include "gbd910.h"
#include "gbd930.h"

#include "hbd06.h"
#include "hbd22.h"
#include "hbd90.h"
#include "hgg01.h"
#include "hgg01_1.h"
#include "hgg04.h"
#include "hkb50.h"

#include "Converter/Converter_IVerify.hpp"
#include "Logging/Log_History.hpp"
#include "Trace/Trace_Entry.hpp"
#include "KernelCommon/Kernel_OpMsg.hpp"  /* PTS 1114891 FF 2002-03-14 */
#include "KernelCommon/Kernel_IAdminInfo.hpp"

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

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

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

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

struct  tbd92_ObjPageChainStat
{
    int    FreePageCnt;           
    int    PageWithFreeLabelCnt;          
    int    FreePageInFreeChainCnt;           
    int    PageInFreeChainCnt;                    
    int    PageWithFreeLabelInFreeChainCnt;       
    int    FreePageWithFreeLabelInFreeChainCnt;    
    
    int    FeotPageCnt;
    
    int    Filler0;
    int    Filler1;       // PageWithEmptyLabelCnt
    int    Filler2;       // PageWithEmptyLabelInFreeChainCnt
    int    Filler3;
    int    Filler4;       // EmptyPageWithEmptyLabelInFreeChainCnt
    
    int    AllPageCnt; 
    
    int    FreeObjCnt;
    int    FeotObjCnt;
    int    OccObjCnt;
    int    ResObjCnt;
    
    inline void ResetAllCountersToZero ()       
    {
        FreePageCnt                          = 0;
        PageWithFreeLabelCnt                 = 0;
        FreePageInFreeChainCnt               = 0;
        PageInFreeChainCnt                   = 0;
        PageWithFreeLabelInFreeChainCnt      = 0;
        FreePageWithFreeLabelInFreeChainCnt  = 0;      
        FeotPageCnt                          = 0;
        Filler0                              = 0;
        Filler1                              = 0;
        Filler2                              = 0;
        Filler3                              = 0;
        Filler4                              = 0;
        AllPageCnt                           = 0; 
        FreeObjCnt                           = 0;
        FeotObjCnt                           = 0;
        OccObjCnt                            = 0;
        ResObjCnt                            = 0;
    };
};

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

struct tbd92_ObjPageContainerStat
{
    int FreeObjCnt;
    int FeotObjCnt;
    int OccObjCnt;      
    int ResObjCnt;
    int AllPageCnt;
    int FreePageCnt;
    int FeotPageCnt;
    int Filler0;
    
    tbd92_ObjPageContainerStat ()         
        :FreeObjCnt(0),
        FeotObjCnt(0),
        OccObjCnt(0),
        ResObjCnt (0),
        AllPageCnt(0),
        FreePageCnt(0),
        FeotPageCnt(0),
        Filler0(0)
    {};
};

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

extern cbd900_ObjFileDir          bd90ObjFileDir;
extern cbd900_ContObjFileDir      bd93ContObjFileDir;
extern cbd930_GarbCollController  bd91GarbCollController;

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

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

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


static void
bd92_CheckBeforeImage (tgg00_TransContext   &Trans,      
                       tgg92_KernelOid       WantedOid,
                       tgg00_ObjTransInfo   &ObjTransInfo);  

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

static void
bd92_CheckConsistencyOfChain (tgg00_TransContext             &Trans,
                              const  tbd92_ObjPageChainStat  &ChainStat,
                              cbd900_SubRootPageInfo         &SubRootPageInfo);

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

static void
bd92_CheckHashEntry (tbd_current_tree       &Current, 
                     tbd900_ObjFrame         *pObjFrame, 
                     tgg92_KernelOid        &CurrentOId,
                     int                    ObjFrameLen,
                     int                    ObjKeyLen); 

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

static void
bd92_CheckAndUpdObjChainStatistics (tgg00_TransContext           &Trans,
                                    tgg00_ObjFileNo               ObjFileNo,
                                    int                           ChainNo,
                                    const tbd92_ObjPageChainStat &ChainStat,
                                    cbd900_ObjFileInfo           *pObjFileInfo);

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

static void
bd92_VerifyObjPageChain (tbd_current_tree        &Current,
                         boolean                  bConverterUpdate,
                         tsp00_PageNo             SubRoot,
                         tbd92_ObjPageChainStat  &ChainStat,
                         const tsp00_Bool         bChainIsDeleted);

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

static void
bd92_VerifyObjRootPage (tbd_current_tree  &Current,
                        tbd_node_ptrs     &NptrsRoot);

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

static void
bd92_VerifyObjSubRootPage (tbd_current_tree  &Current,
                           tbd_node_ptrs     &NptrsSubRoot);

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

static void
bd92_VerifyContObjDataPage (tbd_current_tree &Current,
                            tbd_nodeptr       pPage);

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

static void
bd92_VerifyObjDataPage (tbd_current_tree &Current,
                        tbd_nodeptr       pPage,
                        tsp00_Int4       &ResObjCnt,
                        const tsp00_Bool bChainIsDeleted);

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

static void
bd92_VerifyObjPage (tbd_current_tree  &Current,
                    tbd_node_ptrs     &NptrsPage,
                    tsp00_Int4        &ResObjCnt,
                    const tsp00_Bool   bChainIsDeleted);

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

static void
bd92_VerifyObjPageHeader (tbd_current_tree  &Current,
                          tbd_nodeptr        pPage);

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

static void
bd92_WriteContainerStateToVtrace (tbd_current_tree                  &Current, 
                                  const  tbd92_ObjPageContainerStat &ContainerStat,
                                  const  cbd900_ObjFileInfo         *pObjFileInfo);

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

static void
bd92_WriteChainStateToVtrace (tbd_current_tree                &Current, 
                              const  tbd92_ObjPageChainStat   &ChainStat,
                              cbd910_SubRootNode              &NptrsSubRoot,
                              const tsp00_Bool                 bChainIsDeleted);

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

static void
bd92_WritePageStateToVtrace (tgg00_TransContext    &Trans,
                             tbd_nodeptr            pPage,
                             tsp00_Int4             ResObjCnt);

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

externCpp bool 
bd92ObjPosIsValid (tgg00_ObjPagePos  ObjPos,
                   tgg00_ObjPagePos  FirstObjPos,
                   tsp00_Uint2       ObjFrameLen)
{
    ROUTINE_DBG_MEO00 ("bd92ObjPosIsValid");
    
    /* This function returns true if the ObjPos points    */
    /* onto a valid position of an object otherwise false */
    /* is returned.                                       */
    
    bool      bValidPos;
    const int AlignedObjFrameLen = BD92ALIGN_OBJ_FRAME (ObjFrameLen);
    
    bValidPos = (
        (FirstObjPos >= NODE_HEADER_MXBD00                     ) &&  /* PTS 1107145 AK 10/07/2000 */
        (ObjPos >= FirstObjPos                                 ) &&
        ((ObjPos + ObjFrameLen) <= BODY_END_BD00               ) &&
        (((ObjPos - FirstObjPos) % AlignedObjFrameLen)     == 0) &&
        ((FirstObjPos - BD92ALIGN_OBJ_FRAME (FirstObjPos)) == 0) 
        );
    
    if (! bValidPos)
        bd92WriteWrongPosToVtrace ("bd92ObjPosIsValid",ObjPos, FirstObjPos,  ObjFrameLen);
    
    return (bValidPos);
}

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

externC void
bd92VerifyObjFile (tbd_current_tree       &Current,
                   boolean                 bConverterUpdate)
{
    ROUTINE_DBG_MEO00 ("bd92VerifyObjFile");
    
    /* This function checks all object page chains which */
    /* belong to the current object file.      if any    */
    /* error is detected an op message is sent           */
    /* Moreover, if bConverterUpdate = true all pages    */
    /* of the container are flaged in the FBM as used    */
    
    tbd92_ObjPageContainerStat ContainerStat;
    tbd92_ObjPageChainStat     ChainStat;
    tsp00_PageNo               SubRoot;
    int                        iChain;
    const tgg00_ObjFileNo     &FileNo       = Current.curr_tree_id.fileObjFileNo_gg00();
    const int                  ContFileNo   = Current.curr_tree_id.fileContObjFileNo_gg00();
    cbd900_ObjFileInfo        *pObjFileInfo = NULL;
    
    b06file_opmsg (csp3_check_file, Current.curr_tree_id);
    
    /* check if the file to be checked is really an object file */
    if ((Current.curr_tree_id.fileTfn_gg00() != tfnObj_egg00) &&
        (Current.curr_tree_id.fileTfn_gg00() != tfnContObj_egg00))
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjFile - file with root:" << Current.curr_tree_id.fileRoot_gg00()
            << " is not an obj file! File type:"
            << Current.curr_tree_id.fileTfn_gg00();
        Current.curr_trans->trError_gg00 = e_invalid_filetype;
        return;
    }
    
    /* get shortcut to the object file info */
    if (PRIM_CONT_OBJ_FILE_NO_BD900 == ContFileNo)
        pObjFileInfo = &(bd90ObjFileDir[FileNo]);
    else
        pObjFileInfo = &(bd93ContObjFileDir[FileNo][ContFileNo]);
    
    /* check if the  root is correctly stored in the ObjFileInfo */
    if (pObjFileInfo->GetRootPage() != Current.curr_tree_id.fileRoot_gg00())
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjFile - fileno:" << FileNo;
        if (PRIM_CONT_OBJ_FILE_NO_BD900 != ContFileNo)
            opErrMsg   << " cont fileno:" << ContFileNo;
        opErrMsg << " ObjFileInfo.root:" << pObjFileInfo->GetRootPage()
            << " NEQ Current.root:" << Current.curr_tree_id.fileRoot_gg00();
        Current.curr_trans->trError_gg00 = e_invalid_root;
        return;
    }
    
    /* check each container chain of the file */
    const int       &MaxChain       = pObjFileInfo->GetChainCount(); 
    const tsp00_Bool bFileIsDeleted = pObjFileInfo->ofiRelFileIsReq_bd900 || 
        ( NIL_PAGE_NO_GG00 == pObjFileInfo->GetRootPage() ); // PTS 1122723  
    
    for (iChain=0; (iChain<MaxChain) && (e_ok == Current.curr_trans->trError_gg00); ++iChain)
    { 
        SubRoot = pObjFileInfo->ofiChain_bd900[iChain].ociSubRoot_bd900;
        
        if (NIL_PAGE_NO_GG00 == SubRoot)
        {
            if (!bFileIsDeleted)
            {
                Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                opErrMsg << "BD92VerObjFile - fileno:"  << FileNo;
                if (PRIM_CONT_OBJ_FILE_NO_BD900 != ContFileNo)
                    opErrMsg << " cont fileno:" << ContFileNo;
                opErrMsg << " root:" << pObjFileInfo->GetRootPage()
                    << " subroot is NIL";
                Current.curr_trans->trError_gg00 = e_data_page_corrupted; // PTS 1121056
                return;
            }     
        }
        else 
        {   
            bd92_VerifyObjPageChain (Current, bConverterUpdate, SubRoot, ChainStat, bFileIsDeleted);
            
            /* count objects */
            ContainerStat.FreeObjCnt    += ChainStat.FreeObjCnt;
            ContainerStat.FeotObjCnt    += ChainStat.FeotObjCnt;
            ContainerStat.OccObjCnt     += ChainStat.OccObjCnt;
            ContainerStat.ResObjCnt     += ChainStat.ResObjCnt;
            
            /* count pages */
            ContainerStat.AllPageCnt    += ChainStat.AllPageCnt;
            ContainerStat.FreePageCnt   += ChainStat.FreePageCnt;
            ContainerStat.FeotPageCnt   += ChainStat.FeotPageCnt;
            
            /* check the number of pages and objects stored in ObjFileInfo */
            bd92_CheckAndUpdObjChainStatistics (*Current.curr_trans, FileNo, iChain, ChainStat, pObjFileInfo);
        }
    }
    
    /* write a vtrace entry */
    bd92_WriteContainerStateToVtrace (Current, ContainerStat, pObjFileInfo);
    
    /* verify continuation files PTS 1106716 Alexander Kley 01/06/2000 */
    if ((oftVarLenObjFile_egg00 == Current.curr_tree_id.fileObjFileType_gg00()) &&
        (PRIM_CONT_OBJ_FILE_NO_BD900 == ContFileNo))                              // PTS 1107352 AK 01/08/2000
    {
        cbd900_ContObjFileInfo &ContObjFileInfo = bd93ContObjFileDir[FileNo];
        cbd05_Current ContCurrent (*Current.curr_trans, m_select);
            for (int iContFileNo = 1; (iContFileNo <= ContObjFileInfo.cfiNumContFiles_bd900) &&
                  (e_ok == ContCurrent.curr_trans->trError_gg00);                                // PTS 1121056
                  ++iContFileNo)
        {
            if (NIL_PAGE_NO_GG00 != ContObjFileInfo[iContFileNo].GetRootPage())  // PTS 1107306 AK 01/08/2000
            {
                ContObjFileInfo.bd900BuildFileId (FileNo,iContFileNo,ContCurrent.curr_tree_id);
                bd92VerifyObjFile (ContCurrent,bConverterUpdate);
            }
        }
    }
}

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

externCpp void
bd92VerifyObjPage (tbd_current_tree  &Current,
                   tbd_node_ptrs     &NptrsPage)
{
    ROUTINE_DBG_MEO00 ("bd92VerifyObjPage");
    
    /* This routine checks the consistency */
    /* of the contents of an object page   */
    
    /* declare dummy return */
    
    tsp00_Int4 DummyResObjCnt = 0;
    
    /* true signals that no before-image-check is needed ) */
    bd92_VerifyObjPage (Current, NptrsPage, DummyResObjCnt, true );
}

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

externCpp void
bd92VtraceObjKey (tgg00_TransContext    &Trans, 
                  tgg00_ObjFileNo        ObjFileNo,
                  tsp00_Int4             KeyLen,
                  void                  *pKey,
                  tgg00_VtraceType_Enum  TraceObject)
{
    /*  This function writes the fileno and the key of a   */
    /*  BD-function at the KB-BD interface into the trace  */
    
    const int         MaxVtraceKey = sizeof (tsp00_Line) - sizeof (tgg12_OmsTraceKeyHeader);   
    tgg12_OmsKeyTrace TrLineOut;
    int               OutKeyLen;
    
    TrLineOut.okyHead_gg12.okhTrType_gg12.becomes  ( otKey_egg12);
    TrLineOut.okyHead_gg12.okhTrType2_gg12.becomes ( ot2Nil_egg12);
    TrLineOut.okyHead_gg12.okhObjFileNo_gg12       = ObjFileNo;
    TrLineOut.okyHead_gg12.okhConsView_gg12        = Trans.trConsistView_gg00;
    
    TrLineOut.okyHead_gg12.okhKeyLen_gg12 = 
        ((KeyLen >= 0) && (KeyLen <= MAX_UINT1_SP00)) ? KeyLen : MAX_UINT1_SP00;
    
    OutKeyLen = (TrLineOut.okyHead_gg12.okhKeyLen_gg12 > MaxVtraceKey)
        ? MaxVtraceKey : TrLineOut.okyHead_gg12.okhKeyLen_gg12;
    
    if (OutKeyLen > 0)
    {
        SAPDB_MemCopyNoCheck (&TrLineOut.okyKey_gg12, pKey, OutKeyLen);
    }
    Trace_CommonEntry( Trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(TraceObject), 
        REINTERPRET_CAST( tsp00_BytePtr, &TrLineOut ), 
        (tsp00_Int2)(sizeof (TrLineOut.okyHead_gg12) + OutKeyLen) );
}

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

externCpp void
bd92WriteWrongPosToConsole (const char * funcName,
                            tgg00_ObjPagePos  ObjPos,
                            tgg00_ObjPagePos  FirstObjPos,
                            tsp00_Uint2       ObjFrameLen)
{
    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
    opErrMsg << funcName << " - invalid oid.pos "
        << " oid.pos:" << ObjPos 
        << " First Pos:" << FirstObjPos 
        << " FrameLen:" << ObjFrameLen 
        << " AlignedFrameLen:" << BD92ALIGN_OBJ_FRAME (ObjFrameLen);
        Kernel_VTrace() << funcName << " - invalid oid.pos "
        << " oid.pos:" << ObjPos 
        << " First Pos:" << FirstObjPos 
        << " FrameLen:" << ObjFrameLen 
        << " AlignedFrameLen:" << BD92ALIGN_OBJ_FRAME (ObjFrameLen);
}

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

externCpp void
bd92WriteWrongPosToVtrace (const char * funcName,
                            tgg00_ObjPagePos  ObjPos,
                            tgg00_ObjPagePos  FirstObjPos,
                            tsp00_Uint2       ObjFrameLen)
{
    if (g01vtrace.vtrBdObject_gg00)
    {
        Kernel_VTrace() << funcName << " - invalid oid.pos "
            << " oid.pos:" << ObjPos 
            << " First Pos:" << FirstObjPos 
            << " FrameLen:" << ObjFrameLen 
            << " AlignedFrameLen:" << BD92ALIGN_OBJ_FRAME (ObjFrameLen);
    }
}

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

externCpp void
bd92WriteWrongOidToConsole (const char *             funcName, 
                            const tgg92_KernelOid   &OId)
{
    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
    opErrMsg << funcName << " - invalid oid "
        << OId.gg92GetPno() << "." << OId.gg92GetPos() 
        << " (vers " << OId.gg92GetFrameVers() << ")";
    Kernel_VTrace() << funcName << " - invalid oid "
        << OId.gg92GetPno() << "." << OId.gg92GetPos() 
        << " (vers " << OId.gg92GetFrameVers() << ")";
};

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

externCpp void
bd92WriteWrongOidToVtrace (const char *             funcName, 
                            const tgg92_KernelOid   &OId)
{
    if (g01vtrace.vtrBdObject_gg00)
    {
        Kernel_VTrace() << funcName << " - invalid oid "
            << OId.gg92GetPno() << "." << OId.gg92GetPos() 
            << " (vers " << OId.gg92GetFrameVers() << ")";
    }
};

/*===========================================================================*
*  LOCAL FUNCTIONS (CODE)                                                   *
*===========================================================================*/

static void
bd92_CheckBeforeImage (tgg00_TransContext   &Trans,      
                       tgg92_KernelOid       WantedOid,
                       tgg00_ObjTransInfo   &ObjTransInfo)                                   
{
    /* check if there exists an before image. for */
    /* a feot object there must always exist one  */
    tsp00_Bool bIsActive;

    tgg00_BasisError    saveError = Trans.trError_gg00; // PTS 1121056
    Trans.trError_gg00            = e_ok;               // PTS 1121056   

    /* PTS 1127493 FF 2004-FEB-02       */
    /* check if lock collision occurred */
    if (ObjTransInfo.otrLockTransId_gg00.gg90IsDummy())
        bIsActive = true;
    else
        kb50CheckActiveTrans (Trans.trTaskId_gg00, 
        ObjTransInfo.otrLockTransId_gg00,
        ObjTransInfo.otrLockTransIndex_gg00,
        bIsActive);

    if (! bIsActive)
    {
        if ( ! Log_History::GetInstance().BeforeImageExists ( Trans,
            WantedOid,
            ObjTransInfo.otrBeforeRef_gg00 )) 
        {
            Kernel_OpError  ( csp3_bd_msg, csp3_n_obj )
                << __FILE__ << ":" << __LINE__ 
                << " BD92_CheckBeforeImage - before image not found OID "
                << WantedOid.gg92GetPno() << "." << WantedOid.gg92GetPos() 
                << " (vers " << WantedOid.gg92GetFrameVers() << ")"
                /* PTS 1127493 FF 2004-FEB-02       */
                << " BeforeRefPno:" << ObjTransInfo.otrBeforeRef_gg00.gg91RefPno()
                << " BeforeRefPos:" << ObjTransInfo.otrBeforeRef_gg00.gg91RefPos();
            if (e_ok == Trans.trError_gg00)
                Trans.trError_gg00 = e_obj_history_not_found;
        }
    }

    if ( e_ok != saveError )
        Trans.trError_gg00 = saveError;                 
}

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

static void
bd92_CheckConsistencyOfChain (tgg00_TransContext             &Trans,
                              const  tbd92_ObjPageChainStat  &ChainStat,
                              cbd900_SubRootPageInfo         &SubRootPageInfo)
{
    ROUTINE_DBG_MEO00 ("bd92_CheckConsistencyOfChain");
    
    /* this routine checks if the data collected in the ChainStat and   */
    /* on the subroot page are consistent, if not an op-message is sent */
    
    if (ChainStat.AllPageCnt != SubRootPageInfo.bd900AllPageCnt())
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92_CheckConsistencyOfChain - odd allpage count:"
            << ChainStat.AllPageCnt
            << " SubRootPageInfo.cnt:" << SubRootPageInfo.bd900AllPageCnt();
        if (e_ok == Trans.trError_gg00)
            Trans.trError_gg00 = e_wrong_obj_count;
    }
    
    if ((ChainStat.FreePageWithFreeLabelInFreeChainCnt !=  ChainStat.FreePageInFreeChainCnt)         ||
        (ChainStat.FreePageInFreeChainCnt              !=  ChainStat.FreePageCnt)                    ||
        (ChainStat.FreePageCnt                         !=  ChainStat.PageWithFreeLabelInFreeChainCnt) ||
        (ChainStat.PageWithFreeLabelInFreeChainCnt     != SubRootPageInfo.bd900FreePageCnt())        ||
        (SubRootPageInfo.bd900FreePageCnt()            != ChainStat.PageWithFreeLabelCnt)            ||
        (ChainStat.PageWithFreeLabelCnt                != ChainStat.PageInFreeChainCnt ))
    {
        if (abs( ChainStat.FreePageCnt - SubRootPageInfo.bd900FreePageCnt()) > 1 )
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92_CheckConsistencyOfChain - odd freepage count:"
                << ChainStat.FreePageCnt
                << " SubRootPageInfo.cnt:" << SubRootPageInfo.bd900FreePageCnt();
            if (e_ok == Trans.trError_gg00)
                Trans.trError_gg00 = e_wrong_obj_count;
        }
    }
}

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


static void
bd92_CheckHashEntry (tbd_current_tree       &Current, 
                     tbd900_ObjFrame         *pObjFrame, 
                     tgg92_KernelOid        &CurrentOId,
                     int                    ObjFrameLen,
                     int                    ObjKeyLen)                      
{
    ROUTINE_DBG_MEO00 ("bd92_CheckHashEntry");
    
    /* This function checks if the OId found from the hash        */
    /* by using the key of the current object points at           */ 
    /* the current object                                         */
    /* Note, for an object of the feot state one cannot check     */
    /* the hash since there can exist an object with the same key */
    /* which was reused. In this case the current object was      */
    /* deleted and is of the state free after eot now.            */
    /* The Version ist not checked because it is not any more     */
    /* correct after an object is reused                          */
    
    tgg00_BasisError    &TrError  = Current.curr_trans->trError_gg00;
    tgg00_BasisError    saveError = TrError;            // PTS 1121056
    tgg92_KernelOid     HashOId;

    TrError = e_ok;                                     // PTS 1121056
    
    void * pObjKey = (void *) ((tsp00_Byte *) pObjFrame  + ObjFrameLen - ObjKeyLen);
    
    if  (pObjFrame->objHeader_bd900.ohdState_gg92 == obsOccupied_egg00)
    {
        bd22GetOId (*Current.curr_trans, Current.curr_tree_id.fileObjFileNo_gg00(), ObjKeyLen, pObjKey, HashOId);        
        if (TrError != e_ok) {
            if (saveError != e_ok) TrError = saveError; // PTS 1121056
            return;
        }
        
        if (! HashOId.gg92IsEqIgnoreFrameVers(CurrentOId) )
        {
            /*-----------------------------------*/
            /* an error is detected in the hash  */
            /*-----------------------------------*/
            
            /* write a message into knldiag */
            {
                Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                opErrMsg << " bd92_CheckHashEntry - wrong OId in KeyIndex: OID "
                    << HashOId.gg92GetPno() << "." << HashOId.gg92GetPos() 
                    << " (vers " << HashOId.gg92GetFrameVers() << ")"
                    << " expected OID "
                    << CurrentOId.gg92GetPno() << "." << CurrentOId.gg92GetPos() 
                    << " (vers " << CurrentOId.gg92GetFrameVers() << ")";
                if (e_ok == TrError)
                    TrError = e_invalid_index_structure;
            }
            
            /* output of input OId and input key into vtrace */
            
            tgg12_OmsOidTrace TrLineOId;
            
            TrLineOId.ooidTrType_gg12.becomes(otOid_egg12);
            TrLineOId.ooidTrType2_gg12.becomes(ot2Input_egg12);
            TrLineOId.ooidObjId_gg12   = CurrentOId;
            
            Trace_CommonEntry( *Current.curr_trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(b92check_hash), 
                REINTERPRET_CAST( tsp00_BytePtr, &TrLineOId ), sizeof (TrLineOId) );
            
            bd92VtraceObjKey (*Current.curr_trans,
                Current.curr_tree_id.fileObjFileNo_gg00(), ObjKeyLen, pObjKey, b92check_hash);
            
            /* output of output OId or error reason into vtrace */
            
            if (Current.curr_trans->trError_gg00 == e_ok) 
            {
                TrLineOId.ooidObjId_gg12   = HashOId;
                TrLineOId.ooidTrType2_gg12.becomes(ot2Output_egg12);
                
                Trace_CommonEntry( *Current.curr_trans, tgg00_Debug::fromConst(bd), 
                    tgg00_VtraceType::fromConst(b92check_hash), 
                    REINTERPRET_CAST( tsp00_BytePtr, &TrLineOId ), sizeof (TrLineOId) );
            }
            else
            {
                tgg12_OmsErrorTrace TrLineOut;
                
                TrLineOut.oerrTrType_gg12.becomes  ( otError_egg12);
                TrLineOut.oerrTrType2_gg12.becomes ( ot2Nil_egg12);
                TrLineOut.oerrRoot_gg12            = Current.curr_tree_id.fileRoot_gg00();
                TrLineOut.oerrObjFileNo_gg12       = Current.curr_tree_id.fileObjFileNo_gg00();
                TrLineOut.oerrError_gg12           = Current.curr_trans->trError_gg00;
                
                Trace_CommonEntry( *Current.curr_trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(b92check_hash), 
                    REINTERPRET_CAST( tsp00_BytePtr, &TrLineOut ), sizeof (TrLineOut) );
            }
        }
    }
    if (saveError != e_ok) TrError = saveError; // PTS 1121056
}

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

static  void
bd92_CheckAndUpdObjChainStatistics (tgg00_TransContext           &Trans,
                                    tgg00_ObjFileNo               ObjFileNo,
                                    int                           ChainNo,
                                    const tbd92_ObjPageChainStat &ChainStat,
                                    cbd900_ObjFileInfo           *pObjFileInfo)
{
    ROUTINE_DBG_MEO00 ("bd92_CheckAndUpdObjChainStatistics");
    
    /* Since the ociAllObjCnt_bd900 is updated dirty it may differ from the  */ 
    /* counted number of all occupied object frames. Here ociAllObjCnt_bd900 */
    /* is given again a reasonable value. PTS 1103239 AK 08-09-1999          */
    const tsp00_Int4 AllObjCnt = ChainStat.FeotObjCnt + ChainStat.OccObjCnt + ChainStat.ResObjCnt;
    pObjFileInfo->ofiChain_bd900[ChainNo].SetAllObjCnt(AllObjCnt);
    
    /* The number of pages in ObjFileInfo is checked  */
    if (ChainStat.AllPageCnt != pObjFileInfo->ofiChain_bd900[ChainNo].ociAllPageCnt_bd900)
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "bd92_CheckAndUpdObjChainStatistics - FileNo:" << ObjFileNo
            << " ChainNo:" << ChainNo
            << " ChainStat.AllPageCnt:" << ChainStat.AllPageCnt
            << " FileInfo.AllPageCnt:" << pObjFileInfo->ofiChain_bd900[ChainNo].ociAllPageCnt_bd900;
        if (e_ok == Trans.trError_gg00) Trans.trError_gg00 = e_wrong_obj_count;
    };
}

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

static void
bd92_VerifyObjPageChain (tbd_current_tree        &Current,
                         boolean                  bConverterUpdate,
                         tsp00_PageNo             SubRoot,
                         tbd92_ObjPageChainStat  &ChainStat,
                         const tsp00_Bool         bChainIsDeleted)
{
    ROUTINE_DBG_MEO00 ("bd92_VerifyObjPageChain");
    
    /* This function checks the counter of  empty, free,          */
    /* free_after_eot and all pages contained in the info         */
    /* block on the root page. The counters of occupied, free and */ 
    /* free_after_eot objects are verified for each page          */
    /* in the chain, too. In case the chain does not belong to a  */
    /* file which is marked as to be deleted it is also checked   */
    /* if the chains of free and free_after eot pages and objects */
    /* are consistent                                             */
    
    tgg00_BasisError        &TrError      = Current.curr_trans->trError_gg00;
    tgg00_BasisError        saveError;              // PTS 1121056
    teo00_Uint8             PrevPageSeqNo = MAX_LOCK_REQUEST_SEQ_NO_BD900;
    tsp00_Int4              ResObjCnt;
    tsp00_PageNo            NextPageNo;
    tsp00_PageNo            PrevPageNo;
    
    ChainStat.ResetAllCountersToZero();
    
    /*------------------------------------------------------------*/
    /* go through chains of all pages following the right pointer */
    /* and count the number of free, empty and free_after_eot     */
    /* pages. For each page the object counters are verified      */
    /* as well as the free object chain on each page              */
    /*------------------------------------------------------------*/
    
    /* keep subroot to avoid any change of the chain structure    */
    cbd910_SubRootNode   NptrsSubRoot (Current, SubRoot, nr_for_read);
    if (TrError != e_ok) 
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjPageChain - " 
            << " Error:" << TrError 
            << " trying read access to subroot:" << SubRoot;
        return;
    }
    
    cbd900_SubRootPageInfo SubRootPageInfo (NptrsSubRoot);
    const tsp00_Int4  ChainNo  = NptrsSubRoot.np_ptr()->nd_chain_no();  
    
    /* create page handler which runs over all pages of  */
    /* this chain and set it to the subroot (start) page */
    cbd910_ObjDataNode    NptrsPage (Current, nr_for_read);
    NptrsPage.bd910SetTo (NptrsSubRoot);
    
    /* traverse chain of all pages  */
    do
    {
        if (bConverterUpdate)
        {
            Converter_IVerify::Instance().MarkPageNoAsUsed (
                Current.curr_trans->trTaskId_gg00, NptrsPage.np_ptr()->nd_id(), 
                (gg04IsPermStaticTfn (Current.curr_tree_id.fileTfn_gg00())? Data_Static:Data_Dynamic));
        }
        
        /* check that the page sequence numbers decreases */
        if ((bd900GetPageSeqNo(NptrsPage.np_ptr()->ndLockRequestSeqNoHigh_bd00(), 
            NptrsPage.np_ptr()->ndLockRequestSeqNoLow_bd00()) >= PrevPageSeqNo) &&
            (NptrsPage.np_ptr()->nd_id() != NptrsPage.np_ptr()->nd_sub_root()))           
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPageChain - root:" << NptrsPage.np_ptr()->nd_root()
                << " subroot:" << NptrsPage.np_ptr()->nd_sub_root()
                << " PageSeqNo not decreasing";
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }
        
        PrevPageSeqNo = bd900GetPageSeqNo(NptrsPage.np_ptr()->ndLockRequestSeqNoHigh_bd00(),
            NptrsPage.np_ptr()->ndLockRequestSeqNoLow_bd00());

        /* check that the page has the same chain_no as the subroot */
        if (NptrsPage.np_ptr()->nd_chain_no() != ChainNo)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPageChain - root:" << NptrsPage.np_ptr()->nd_id()
                << " wrong chainno:" << NptrsPage.np_ptr()->nd_chain_no()
                << " expected:" << ChainNo;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }
        
        /* check object counters and object chains on current page */
        bd92_VerifyObjPage (Current, NptrsPage, ResObjCnt, bChainIsDeleted);
        
        /* update page and object counter */
        ++ChainStat.AllPageCnt;        
        
        if (NptrsPage.np_ptr()->nd_free_obj_cnt() > 0)      
            ++ChainStat.FreePageCnt;
        if (NptrsPage.np_ptr()->nd_free_eot_obj_cnt() > 0)      
            ++ChainStat.FeotPageCnt;
        
        if (NptrsPage.np_ptr()->nd_in_free_chain())     
            ++ChainStat.PageWithFreeLabelCnt;
        
        ChainStat.FreeObjCnt += NptrsPage.np_ptr()->nd_free_obj_cnt();
        ChainStat.FeotObjCnt += NptrsPage.np_ptr()->nd_free_eot_obj_cnt();
        ChainStat.OccObjCnt  += NptrsPage.np_ptr()->nd_occ_obj_cnt();
        ChainStat.ResObjCnt  += ResObjCnt;
        
        /* goto next page in chain */
        NextPageNo = NptrsPage.np_ptr()->nd_right();
        PrevPageNo = NptrsPage.np_ptr()->nd_id();
        
        if (NIL_PAGE_NO_GG00 == NextPageNo)
        {
            break;
        }
        else
        {
            saveError = TrError;                            // PTS 1121056
            TrError = e_ok;                                 // PTS 1121056
            NptrsPage.bd910MoveToNextPage();
            if (e_ok != TrError) 
            {
                Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                opErrMsg << "BD92VerObjPageChain - root:" 
                    << SubRoot                                                // NptrsPage.np_ptr()->nd_root() PTS 1121106  FF 
                    << " page:" <<PrevPageNo                      // NptrsPage.np_ptr()->nd_id()       PTS 1121106  FF 
                    << " :" << TrError 
                    << " trying access to next page:"  << NextPageNo;
                if (e_ok != saveError) TrError = saveError; // PTS 1121056
                return;
            }
            if (e_ok != saveError) TrError = saveError;     // PTS 1121056
            if (PrevPageNo != NptrsPage.np_ptr()->nd_left())
            {
                Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                opErrMsg << "BD92VerObjPageChain - root:" 
                    << NptrsPage.np_ptr()->nd_root()
                    << " page:" << NptrsPage.np_ptr()->nd_id()
                    << " back pointer wrong"
                    << " nd_left:" << NptrsPage.np_ptr()->nd_left(); 
                if (e_ok != TrError) 
                    TrError = e_data_page_corrupted; // PTS 1121056
            }
        }
    }
    while (ChainStat.AllPageCnt <= SubRootPageInfo.bd900AllPageCnt());
    
    if ( ChainStat.AllPageCnt < SubRootPageInfo.bd900AllPageCnt() )
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjPageChain - root:" << NptrsSubRoot.np_ptr()->nd_root()
            << " wrong AllPageCount SubRootInfo:" << SubRootPageInfo.bd900AllPageCnt()
            << " ChainStat:" << ChainStat.AllPageCnt;
        if (e_ok == TrError) TrError = e_wrong_all_page_count;
    }
    
      /* PTS 1121106 FF 2003-MAR-13 */
      /* bd910MoveToNextPage may have marked NptrsPage with 'm_PrimaryReference = true;' */
    saveError = TrError;                            // PTS 1121056
    TrError = e_ok;                                 // PTS 1121056
    NptrsPage.bd910ReleasePage();   

      /* traverse chain of free pages (= pages with free object frames ) */
    if (! bChainIsDeleted)
    {       
        /* set page handler to fisrt page of free page chain */
        NptrsPage.bd910SetTo (NptrsSubRoot);
        do
        {   
            if ((NptrsPage.np_ptr()->nd_id() != NptrsPage.np_ptr()->nd_sub_root()) ||
                (NptrsPage.np_ptr()->nd_free_obj_cnt() > 0)) 
                ++ChainStat.PageInFreeChainCnt;
            
            if (NptrsPage.np_ptr()->nd_free_obj_cnt() > 0)
                ++ChainStat.FreePageInFreeChainCnt;
            
            if (NptrsPage.np_ptr()->nd_in_free_chain()) 
            {
                ++ChainStat.PageWithFreeLabelInFreeChainCnt;
                if (NptrsPage.np_ptr()->nd_free_obj_cnt() > 0) 
                    ++ChainStat.FreePageWithFreeLabelInFreeChainCnt;
            }
            
            /* goto next page in free chain */
            NextPageNo = NptrsPage.np_ptr()->nd_next_free();
              PrevPageNo = NptrsPage.np_ptr()->nd_id();   // PTS 1121106  FF 
            NptrsPage.bd910ReleasePage();
            
            if (NIL_PAGE_NO_GG00 == NextPageNo)
                break;
            else
            {
                if (e_ok == saveError) saveError = TrError;     
                TrError = e_ok;
                NptrsPage.bd910AssignToPage (NextPageNo);
                if (e_ok != TrError) 
                {
                    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                    opErrMsg << "BD92VerObjPageChain - root:" 
                          << SubRoot                              // NptrsPage.np_ptr()->nd_root() PTS 1121106  FF 
                        << " page:" << PrevPageNo   // NptrsPage.np_ptr()->nd_id()   PTS 1121106  FF
                        << " error:" << TrError 
                        << " trying access to next free page:" << NextPageNo;
                    if (e_ok != saveError) TrError = saveError;     // PTS 1121056
                    return;
                }
            }
        }
        while (ChainStat.PageInFreeChainCnt <= ChainStat.AllPageCnt);
    }
    if (e_ok != saveError) TrError = saveError;     // PTS 1121056
    
    /* check consistency of the infos in page chain info */ 
    if (!bChainIsDeleted)
        bd92_CheckConsistencyOfChain (*Current.curr_trans, ChainStat, SubRootPageInfo);
    else
    {
        /* note: if a file is droped only the number of all pages is updated */
        /* during the drop procedures all other counters are dirty           */
        if (ChainStat.AllPageCnt != SubRootPageInfo.bd900AllPageCnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPageChain - root:" << NptrsSubRoot.np_ptr()->nd_root()
                << " wrong AllPageCount SubRootInfo:" << SubRootPageInfo.bd900AllPageCnt()
                << " ChainStat:" << ChainStat.AllPageCnt;
            if (e_ok == TrError) 
                TrError = e_wrong_all_page_count;
        }
    }
    
    /* write vtrace entry */
    bd92_WriteChainStateToVtrace (Current, ChainStat, NptrsSubRoot, bChainIsDeleted);
}

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

static void
bd92_VerifyContObjDataPage (tbd_current_tree &Current,
                            tbd_nodeptr       pPage)
{
    ROUTINE_DBG_MEO00 ("bd92_VerifyContObjDataPage");
    
    /* This function checks the counter of free, free_after_eot */
    /* and occupied objects for continuation object data pages. */
    /* Moreover, the free object chain is verified              */
    
    tgg00_BasisError      &TrError           = Current.curr_trans->trError_gg00;
    const int             MaxObjCnt          = pPage->nd_max_obj_cnt();
    const int             ObjFrameLen        = pPage->nd_obj_frame_len();
    const int             AlignedObjFrameLen = BD92ALIGN_OBJ_FRAME(ObjFrameLen);
    const int             NoReservedObjects  = 0;
    int                   ObjPos             = pPage->nd_first_obj();
    int                   NextFreeObjPos;
    int                   OccObjCnt          = 0;
    int                   FreeObjCnt         = 0;
    int                   FreeChainObjCnt    = 0;
    tbd900_ContObjFrame   *pContObjFrame;  
    
    /* recalculate object counters */     
    for (int ObjCnt=1; ObjCnt <= MaxObjCnt; ++ObjCnt)
    {
        /*  construct position of the object frame  header             */           
        pContObjFrame = (tbd900_ContObjFrame *) ((tsp00_Byte*) pPage + ObjPos);
        
        /* count occurence of the various object  states */
        if (pContObjFrame->cofHeader_bd900.cvoRootOIdPno_bd900  != NIL_PAGE_NO_GG00      &&
            pContObjFrame->cofHeader_bd900.cvoRootOIdPos_bd900  != NIL_OBJ_PAGE_POS_GG92 &&
            pContObjFrame->cofHeader_bd900.cvoNextFreeObj_bd900 == NIL_OBJ_PAGE_POS_GG92)
        {
            ++OccObjCnt;
        };  
        ObjPos += AlignedObjFrameLen;
    }
    FreeObjCnt = MaxObjCnt - OccObjCnt;
    
    
    /* traverse free obj chain */   
    NextFreeObjPos = pPage->nd_first_free_obj();
    
    while (NextFreeObjPos != NIL_OBJ_PAGE_POS_GG92)
    {
        ++FreeChainObjCnt;
        
        if (!bd92ObjPosIsValid (NextFreeObjPos, pPage->nd_first_obj(), ObjFrameLen))
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, NoReservedObjects);  
            opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong first free object pos:" << NextFreeObjPos;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }
        
        pContObjFrame = (tbd900_ContObjFrame *) ((tsp00_Byte*) pPage + NextFreeObjPos);
        
        if (pContObjFrame->cofHeader_bd900.cvoRootOIdPno_bd900  != NIL_PAGE_NO_GG00      ||
            pContObjFrame->cofHeader_bd900.cvoRootOIdPos_bd900  != NIL_OBJ_PAGE_POS_GG92 )
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, NoReservedObjects); 
            opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong cont obj" << NextFreeObjPos;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }
        
        if (FreeChainObjCnt > FreeObjCnt)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, NoReservedObjects); 
            opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong freechain obj count";
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
            break;
        }
        
        NextFreeObjPos = pContObjFrame->cofHeader_bd900.cvoNextFreeObj_bd900;
    }
    
    
    /* compare calculated counters with counters on page */
    if (FreeObjCnt        != pPage->nd_free_obj_cnt()     ||
        FreeChainObjCnt   != pPage->nd_free_obj_cnt()     ||
        0                 != pPage->nd_free_eot_obj_cnt() ||
        OccObjCnt         != pPage->nd_occ_obj_cnt())
    {
        bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, NoReservedObjects);  
        
        if (FreeObjCnt != pPage->nd_free_obj_cnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong free count:" << FreeObjCnt;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }       
        
        if (0  != pPage->nd_free_eot_obj_cnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong feot count:" << pPage->nd_free_eot_obj_cnt();
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }       
        
        if (OccObjCnt  != pPage->nd_occ_obj_cnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong occupied count:" << OccObjCnt;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056;
        }       
        
        if (FreeChainObjCnt != pPage->nd_free_obj_cnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong freeobj count:" << FreeChainObjCnt;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056;
        }       
    }
}

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


static void
bd92_VerifyObjDataPage (tbd_current_tree &Current,
                        tbd_nodeptr       pPage,
                        tsp00_Int4       &ResObjCnt,
                        const tsp00_Bool  bChainIsDeleted)  /* PTS XXXXXXX FF */
{
    ROUTINE_DBG_MEO00 ("bd92_VerifyObjDataPage");
    
    /* This function checks the counter of free, free_after_eot */
    /* and occupied objects for primary object data pages.      */
    /* Moreover, the free object chain is verified              */
    
    tgg00_BasisError  &TrError           = Current.curr_trans->trError_gg00;
    const int         MaxObjCnt          = pPage->nd_max_obj_cnt();
    const int         ObjFrameLen        = pPage->nd_obj_frame_len();
    const int         ObjKeyLen          = pPage->nd_obj_key_len();
    const int         AlignedObjFrameLen = BD92ALIGN_OBJ_FRAME(ObjFrameLen);
    int               ObjPos             = pPage->nd_first_obj();
    int               NextFreeObjPos;
    int               OccObjCnt          = 0;
    int               FreeObjCnt         = 0;
    int               FeotObjCnt         = 0;
    int               FreeChainObjCnt    = 0;
    ResObjCnt          = 0;
    bool              bThisTaskIsAGarbColl = bd91GarbCollController.bd930CheckIfTaskIsAGC (Current.curr_trans->trTaskId_gg00);
    tsp00_Bool        bIsActive;
    tbd900_ObjFrame  *pObjFrame;
    tgg92_KernelOid   OId;
    
    /* preset common parameters of OId */
    OId.gg92SetPno    (pPage->nd_id());
    
    /* recalculate  object counters */
    
    if (ObjKeyLen <= 0)
    {
        /* check data page without keys */            
        for (int ObjCnt=1; ObjCnt <= MaxObjCnt; ++ObjCnt)
        {
            /*  construct position of the object frame  header */       
            pObjFrame = cbd910_ObjDataNode::bd910ObjFramePtr ((tsp00_Byte *) pPage, ObjPos);  
            
            /* create OId for this object frame */
            OId.gg92SetPos       (ObjPos);
            OId.gg92SetFrameVers (pObjFrame->objHeader_bd900.ohdFrameVersion_gg92);
            
            /* count occurence of the various object  states */
            switch (pObjFrame->objHeader_bd900.ohdState_gg92)
            {
            case obsOccupied_egg00     : ++OccObjCnt  ;     break; 
            case obsFree_egg00         : ++FreeObjCnt ; break;
            case obsFreeAfterEot_egg00 : 
                ++FeotObjCnt ;
                /* the following check isn't permitted, because if a GC is working actually on */
                /* an entry, then this entry may be marked as deleted within the history,      */
                /* but the object frame remains still unchanged             FF 2004-FEB-02     */
                break; 
                if (!bThisTaskIsAGarbColl && // a GC could create a dead lock
                    Kernel_IAdminInfo::Instance().KernelStateIsOnline() && // PTS 1121056  LockList not yet initialized
                    !bChainIsDeleted )     /* PTS XXXXXXX FF */
                {
                    bd92_CheckBeforeImage (*Current.curr_trans, OId, 
                        pObjFrame->objHeader_bd900.ohdTransInfo_gg92);
                }
                break;
            case obsReserved_egg00     : 
                ++OccObjCnt; 
                ++ResObjCnt;
                if (( !bChainIsDeleted ) &&
                    Kernel_IAdminInfo::Instance().KernelStateIsOnline())      // PTS 1121056
                {
                    /* since reserved and commited objects must not exist */ 
                    /* reserved objects must belong to open transactions  */


                    /* PTS 1127493 FF 2004-FEB-02       */
                    /* check if lock collision occurred */
                    if (pObjFrame->objHeader_bd900.ohdTransInfo_gg92.otrLockTransId_gg00.gg90IsDummy())
                        bIsActive = true;
                    else
                        kb50CheckActiveTrans (Current.curr_trans->trTaskId_gg00, 
                        pObjFrame->objHeader_bd900.ohdTransInfo_gg92.otrLockTransId_gg00,
                        pObjFrame->objHeader_bd900.ohdTransInfo_gg92.otrLockTransIndex_gg00,
                        bIsActive);
                    if (!bIsActive)
                    {
                        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                        opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                            << " page:" << pPage->nd_id()
                            << " obj pos:" << ObjPos
                            << " committed obj with state reserved";
                        if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
                    }
                }
                break;  
            case obsKeyReserved_egg00  :
                {
                    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                    opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                        << " page:" << pPage->nd_id()
                        << " obj pos:" << ObjPos
                        << " wrong state KeyReserved";
                    if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
                }
                break;
            default                         :
                {
                    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                    opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                        << " page:" << pPage->nd_id()
                        << " obj pos:" << ObjPos
                        << " unknown state:" << pObjFrame->objHeader_bd900.ohdState_gg92;
                    if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
                }
                break; 
            };
            ObjPos += AlignedObjFrameLen;
        }
    }
    else
    {
        /* check data page with keys */         
        for (int ObjCnt=1; ObjCnt <= MaxObjCnt; ++ObjCnt)
        {
            /*  construct position of the object frame  header */
            pObjFrame = cbd910_ObjDataNode::bd910ObjFramePtr ((tsp00_Byte *) pPage, ObjPos);  
            
            /* create OId for this object frame */
            OId.gg92SetPos       (ObjPos);
            OId.gg92SetFrameVers (pObjFrame->objHeader_bd900.ohdFrameVersion_gg92);
            
            /* count occurence of the various object  states and check the hash entries */
            switch (pObjFrame->objHeader_bd900.ohdState_gg92)
            {
            case obsOccupied_egg00     : 
                bd92_CheckHashEntry (Current, pObjFrame, OId, ObjFrameLen, ObjKeyLen);
                ++OccObjCnt;
                break; 
            case obsFreeAfterEot_egg00 :
                /* the hash is not tested because of the objects     */
                /* created temporaly  when an older object is reused */
                ++FeotObjCnt;
                /* the following check isn't permitted, because if a GC is working actually on */
                /* an entry, then this entry may be marked as deleted within the history,      */
                /* but the object frame remains still unchanged             FF 2004-FEB-02     */
                break; 
                if (!bThisTaskIsAGarbColl && // a GC could create a dead lock
                    Kernel_IAdminInfo::Instance().KernelStateIsOnline() && // PTS 1121056 LockList not yet initialized
                    !bChainIsDeleted )     
                {
                    bd92_CheckBeforeImage (*Current.curr_trans, OId, 
                        pObjFrame->objHeader_bd900.ohdTransInfo_gg92);
                }
                break;
            case obsFree_egg00         : 
                ++FreeObjCnt;
                break;
            case obsKeyReserved_egg00  :
                /* The hash is not tested since an object could be Keyreserved  */ 
                /* but not yet inserted into the hash (see NewObj in vkb04.cpp) */
                ++OccObjCnt;
                ++ResObjCnt;
                if ( !bChainIsDeleted && 
                    Kernel_IAdminInfo::Instance().KernelStateIsOnline())      // PTS 1121056
                {
                    tgg00_BasisError      saveError = TrError;                // PTS 1121056
                    TrError = e_ok;
                    /* since reserved and commited objects must not exist */ 
                    /* reserved objects must belong to open transactions  */

                    /* PTS 1127493 FF 2004-FEB-02       */
                    /* check if lock collision occurred */
                    if (pObjFrame->objHeader_bd900.ohdTransInfo_gg92.otrLockTransId_gg00.gg90IsDummy())
                        bIsActive = true;
                    else
                        kb50CheckActiveTrans (Current.curr_trans->trTaskId_gg00, 
                        pObjFrame->objHeader_bd900.ohdTransInfo_gg92.otrLockTransId_gg00,
                        pObjFrame->objHeader_bd900.ohdTransInfo_gg92.otrLockTransIndex_gg00,
                        bIsActive);
                    if ( e_ok != saveError ) TrError = saveError;                                      
                    if (!bIsActive)
                    {
                        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                        opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                            << " page:" << pPage->nd_id()
                            << " obj pos:" << ObjPos
                            << " committed obj with state reserved";
                        if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
                    }
                }
                break;  
            case obsReserved_egg00     : 
                {
                    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                    opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                        << " page:" << pPage->nd_id()
                        << " obj pos:" << ObjPos
                        << " wrong state Reserved Keylen:" << ObjKeyLen;
                    if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
                }
                break; 
            default                        :
                {
                    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                    opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                        << " page:" << pPage->nd_id()
                        << " obj pos:" << ObjPos
                        << " unknown state:" << pObjFrame->objHeader_bd900.ohdState_gg92;
                    if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
                }
                break; 
            }                 
            ObjPos += AlignedObjFrameLen;
        }
    }
    
    /* compare object counters */
    if (FreeObjCnt != pPage->nd_free_obj_cnt()     ||
        FeotObjCnt != pPage->nd_free_eot_obj_cnt() ||
        OccObjCnt  != pPage->nd_occ_obj_cnt()     )
    {
        bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, ResObjCnt);  
        
        if (FreeObjCnt != pPage->nd_free_obj_cnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong free count:" << FreeObjCnt;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }       
        
        if (FeotObjCnt != pPage->nd_free_eot_obj_cnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong feot count:" << FeotObjCnt;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }       
        
        if (OccObjCnt  != pPage->nd_occ_obj_cnt())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong occupied count:" << OccObjCnt;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }
    }
    
    /* check if all pages with free  objects are             */
    /* contained in the corresponding object page chains     */
    /* note that it may happen that the GC has changed the   */
    /* page state to free but the page is still not icluded  */
    /* in the free list since the GC was interupted by an    */
    /* user. This user finds the page free but not included  */
    /* in the free chain.                                    */
    
    /* traverse free obj chain */   
    NextFreeObjPos = pPage->nd_first_free_obj();
    
    while (NextFreeObjPos != NIL_OBJ_PAGE_POS_GG92)
    {
        ++FreeChainObjCnt;
        
        if (!bd92ObjPosIsValid (NextFreeObjPos, pPage->nd_first_obj(), ObjFrameLen))
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, ResObjCnt);  
            opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong next free object pos:" << NextFreeObjPos;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }
        
        pObjFrame = cbd910_ObjDataNode::bd910ObjFramePtr ((tsp00_Byte *) pPage, NextFreeObjPos);  
        
        if (pObjFrame->objHeader_bd900.ohdState_gg92 != obsFree_egg00)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, ResObjCnt); 
            opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong object state:" << pObjFrame->objHeader_bd900.ohdState_gg92;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
        }
        
        if (FreeChainObjCnt > FreeObjCnt)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            bd92_WritePageStateToVtrace (*Current.curr_trans, pPage, ResObjCnt); 
            opErrMsg << "BD92VerObjDataPage - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id()
                << " wrong freechain obj count:" << FreeObjCnt;
            if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
            break;
        }
        
        NextFreeObjPos = pObjFrame->objHeader_bd900.ohdNextFreeObj_gg92;
    }
    
    /* compare calculated counters with counters on page */
    if (FreeChainObjCnt != pPage->nd_free_obj_cnt())
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerContObjPage - root:" << pPage->nd_root()
            << " page:" << pPage->nd_id()
            << " wrong free chain len:" << FreeChainObjCnt;
        if (e_ok == TrError) TrError = e_data_page_corrupted; // PTS 1121056
    }       
}

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

static void
bd92_VerifyObjPage (tbd_current_tree  &Current,
                    tbd_node_ptrs     &NptrsPage,
                    tsp00_Int4        &ResObjCnt,
                    const tsp00_Bool  bChainIsDeleted)  
{
    ROUTINE_DBG_MEO00 ("bd92_VerifyObjPage");
    
    /* This routine checks the consistency */
    /* of the contents of an object page   */
    
    /* initialize return parameter */
    ResObjCnt = 0;
    tgg00_BasisError        &TrError      = Current.curr_trans->trError_gg00;
    
    tbd_nodeptr   & pPage = NptrsPage.np_ptr();
    
    /* check page type */
    if (pPage->nd_pt()   !=  ptData_egg00        ||
        (pPage->nd_pt2() !=  pt2Object_egg00     &&
        pPage->nd_pt2()  !=  pt2VarObject_egg00  && 
        pPage->nd_pt2()  !=  pt2ContObject_egg00)) 
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjPage - root:" << NptrsPage.np_ptr()->nd_root()
            << " actual page:" << NptrsPage.np_ptr()->nd_id()
            << " wrong page type nd_pt:" << pPage->nd_pt()
            << " nd_pt2:" << pPage->nd_pt2();
        if ( e_ok == TrError )                  // PTS 1121056
            TrError = e_data_page_corrupted;    // PTS 1121056
    }
    else
    {
        /* perform some general checks */
        
        /* check that the page has no next free page */
        /* if it is not a member of the free chain   */
        if (!pPage->nd_in_free_chain()                      && 
            (pPage->nd_id()        != pPage->nd_sub_root()) &&
            (pPage->nd_next_free() != NIL_PAGE_NO_GG00))
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPage - root:" << NptrsPage.np_ptr()->nd_root()
                << " actual page:" << NptrsPage.np_ptr()->nd_id()
                << " bad NextFree pointer ";
                  if ( e_ok == TrError )
                        TrError = e_data_page_corrupted;    // PTS 1121056
        }
        
        /* check that the page has no next free page */
        /* if it is not a member of the free chain   */
        if (!pPage->nd_in_free_chain() && (pPage->nd_free_obj_cnt() > 1)
            && !pPage->nd_assigned_to_spec_trans())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPage - root:" << pPage->nd_root()
                << " actual page:" << pPage->nd_id()
                << " bad FreeCount:" << pPage->nd_free_obj_cnt();
            if ( e_ok == TrError )
                TrError = e_data_page_corrupted; // PTS 1121056
        }
        
        /* check page header */
        bd92_VerifyObjPageHeader (Current, pPage);
        
        /* check page contents */
        if (pPage->nd_id() == pPage->nd_root()) 
            bd92_VerifyObjRootPage (Current, NptrsPage);    
        
        if (pPage->nd_id() == pPage->nd_sub_root())
            bd92_VerifyObjSubRootPage (Current, NptrsPage);
        
        if (pPage->nd_pt2()  ==  pt2ContObject_egg00)
            bd92_VerifyContObjDataPage (Current, pPage ); 
        else
            bd92_VerifyObjDataPage (Current, pPage, ResObjCnt, bChainIsDeleted ); /* PTS XXXXXXX FF */
    }
}

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

static void
bd92_VerifyObjPageHeader (tbd_current_tree  &Current,
                          tbd_nodeptr        pPage)
{                                     
    /* check if the data in the page header are consistent */
    /* with those in the object file directory             */
    
    const tsp00_Int4      FileNo        = pPage->nd_obj_file_no();
    cbd900_ObjFileInfo   *pObjFileInfo  = NULL;
    bool                  bHeaderOk     = true;
    tgg00_BasisError      &TrError      = Current.curr_trans->trError_gg00;
    
    /* get shortcut to the appropriate ObjFileInfo */
    if (pPage->nd_pt2() == pt2ContObject_egg00)
    {
        const int ContFileNo = Current.curr_tree_id.fileContObjFileNo_gg00();
        pObjFileInfo         = &(bd93ContObjFileDir[FileNo][ContFileNo]);
    }
    else
        pObjFileInfo = &(bd90ObjFileDir[FileNo]);
    
    /* check root */
    if ((pPage->nd_root() != pObjFileInfo->GetRootPage()) &&
        ( NIL_PAGE_NO_GG00 != pObjFileInfo->GetRootPage()))  // PTS 1122723
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjPageHdr - root:" << pObjFileInfo->GetRootPage()
            << " page" << pPage->nd_id()
            << " root on page:" << pPage->nd_root() 
            << " is wrong";
        if ( e_ok == TrError ) TrError = e_invalid_root;
        bHeaderOk = false;
    }
    
    /* check maximum number of objects and position of first object */ 
    if (pPage->nd_root() == pPage->nd_id() || pPage->nd_sub_root() == pPage->nd_id() )
    {
        if (pPage->nd_max_obj_cnt() > pObjFileInfo->GetObjPerPageCount())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPageHdr - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id() 
                << " wrong MaxObjCnt:" << pPage->nd_max_obj_cnt()
                << " ObjFileInfo.MaxObjCnt:" << pObjFileInfo->GetObjPerPageCount(); 
            if ( e_ok == TrError ) TrError = e_invalid_root;
            bHeaderOk = false;
        }
        
        if (pPage->nd_first_obj() != BD92ALIGN_OBJ_FRAME (NODE_HEADER_MXBD00 + sizeof (cbd900_RootAndSubRootPageData)))
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPageHdr - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id() 
                << " wrong FirstObjPos:" << pPage->nd_first_obj();
            if ( e_ok == TrError ) TrError = e_invalid_root;
            bHeaderOk = false;
        }
    }
    else
    {
        if (pPage->nd_max_obj_cnt() != pObjFileInfo->GetObjPerPageCount())
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPageHdr - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id() 
                << " wrong MaxObjCnt:" << pPage->nd_max_obj_cnt()
                << " ObjFileInfo.MaxObjCnt:" << pObjFileInfo->GetObjPerPageCount(); 
            if ( e_ok == TrError ) TrError = e_invalid_root;
            bHeaderOk = false;
        }
        
        if (pPage->nd_first_obj() != NODE_HEADER_MXBD00)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjPageHdr - root:" << pPage->nd_root()
                << " page:" << pPage->nd_id() 
                << " wrong FirstObjPos:" << pPage->nd_first_obj();
            if ( e_ok == TrError ) TrError = e_invalid_root;
            bHeaderOk = false;
        }
    }
    
    if ((pPage->nd_first_free_obj() != NIL_OBJ_PAGE_POS_GG92) && 
        !bd92ObjPosIsValid (pPage->nd_first_free_obj(),  pPage->nd_first_obj(), pPage->nd_obj_frame_len()))
        bHeaderOk = false;
    
    /* check page type */
    if (((pPage->nd_pt2() == pt2VarObject_egg00)        &&
        !(cbd900_ObjFileInfo::omsVariableFile == pObjFileInfo->GetFileType())) ||
        (((pPage->nd_pt2() == pt2Object_egg00) ||
        (pPage->nd_pt2() == pt2ContObject_egg00))    &&
        (cbd900_ObjFileInfo::omsVariableFile == pObjFileInfo->GetFileType())))
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjPage - root:" << pPage->nd_root()
            << " actual page:" << pPage->nd_id()
            << " wrong page type nd_pt:" << pPage->nd_pt()
            << " nd_pt2:" << pPage->nd_pt2()
            << " FileType:" << pObjFileInfo->GetFileType();
        if ( e_ok == TrError ) TrError = e_data_page_corrupted; // PTS 1121056
        bHeaderOk = false;
    }
}
                          
/*---------------------------------------------------------------------------*/

static void
bd92_VerifyObjRootPage (tbd_current_tree  &Current,
                        tbd_node_ptrs     &NptrsRoot)
{
    ROUTINE_DBG_MEO00 ("bd92VerifyObjRootPage");
    
    /* check root page and compare data with ObjFileInfo */
    
    int iChain;
    cbd900_RootPageInfo   RootPageInfo (NptrsRoot); 
    tbd_nodeptr          &pRoot         = NptrsRoot.np_ptr();
    const tsp00_Int4      MaxChain      = RootPageInfo.bd900NumChains();
    const tsp00_Int4      FileNo        = pRoot->nd_obj_file_no();
    cbd900_ObjFileInfo   *pObjFileInfo  = NULL;
    tgg00_BasisError      &TrError      = Current.curr_trans->trError_gg00;
    
    /* get shortcut to the appropriate ObjFileInfo */
    if (pRoot->nd_pt2() == pt2ContObject_egg00)
    {
        cbd900_ContObjFileInfo & ContObjFileInfo = bd93ContObjFileDir[FileNo];
        
        for (int iContFileNo=1; iContFileNo<=ContObjFileInfo.cfiNumContFiles_bd900; ++iContFileNo)           
        {
            if (pRoot->nd_root() == ContObjFileInfo[iContFileNo].GetRootPage())
            {
                pObjFileInfo = &(ContObjFileInfo [iContFileNo]);
                break;
            }
        }
        if (pObjFileInfo == NULL)
            g01abort (csp3_bd_msg, csp3_n_obj,"BD92_VER:ContRoot NoReg ",pRoot->nd_id());
    }
    else
        pObjFileInfo = &(bd90ObjFileDir[FileNo]);
    
    /* check number of subroots */
    if (MaxChain != pObjFileInfo->GetChainCount())
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "BD92VerObjRootPage - root:" << pRoot->nd_id()
            << " wrong MaxChain:" << MaxChain
            << " ObjFileInfo:" << pObjFileInfo->GetChainCount();
        if ( e_ok == TrError ) TrError = e_data_page_corrupted; // PTS 1121056
    }
    
    /* check that the drop info on the root page ist consistent */
    /* with those in the objfiledir , PTS 1106900 14/06/2000 AK */
    if (RootPageInfo.bd900FileIsDeleted() != pObjFileInfo->ofiDropFile_bd900)       
    {
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjRootPage - root:" << pRoot->nd_id()
                << " wrong DropInfo:" << RootPageInfo.bd900FileIsDeleted()
                << " ObjFileInfo:" << pObjFileInfo->ofiDropFile_bd900;
            if ( e_ok == TrError ) TrError = e_inconsistent_drop_info; 
        }
    }
    
    /* check each entry in subroot list on root page */
    for (iChain=0; iChain < MaxChain; ++iChain)
    {
        if (pObjFileInfo->ofiRelFileIsReq_bd900)
        {
            /* note: if a chain is deleted the subroot entry on the root  */
            /* page is not updated automatically but the object file info */
            if ((NIL_PAGE_NO_GG00                  != pObjFileInfo->ofiChain_bd900[iChain].ociSubRoot_bd900) &&
                (RootPageInfo.bd900SubRoot(iChain) != pObjFileInfo->ofiChain_bd900[iChain].ociSubRoot_bd900))
            {
                Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                opErrMsg << "BD92VerObjRootPage - root:" << pRoot->nd_id()
                    << " iChain:" << iChain
                    << " wrong subroot:" << pObjFileInfo->ofiChain_bd900[iChain].ociSubRoot_bd900;
                if ( e_ok == TrError ) TrError = e_data_page_corrupted; // PTS 1121056 
            }
        }
        else
        {
            if (RootPageInfo.bd900SubRoot(iChain) == NIL_PAGE_NO_GG00)
            {
                Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                opErrMsg << "BD92VerObjRootPage - root:" << pRoot->nd_id()
                    << " iChain:" << iChain
                    << " NIL subroot:" << RootPageInfo.bd900SubRoot(iChain);
                if ( e_ok == TrError ) TrError = e_data_page_corrupted; // PTS 1121056 
            }
            else
            {   /* compare subroot list on root and in object file info */ 
                if (RootPageInfo.bd900SubRoot(iChain) != pObjFileInfo->ofiChain_bd900[iChain].ociSubRoot_bd900)
                {
                    Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                    opErrMsg << "BD92VerObjRootPage - root:" << pRoot->nd_id()
                        << " iChain:" << iChain
                        << " PageInfo.subroot:" << RootPageInfo.bd900SubRoot(iChain)
                        << " ObjFileInfo.subroot:" << pObjFileInfo->ofiChain_bd900[iChain].ociSubRoot_bd900;
                    if ( e_ok == TrError ) TrError = e_data_page_corrupted; // PTS 1121056 
                }
            }
        }
    }
    
    for (iChain=MaxChain; iChain<MAX_NUM_CHAINS_PER_CONTAINER_BD900; ++iChain)
    {
        if (RootPageInfo.bd900SubRoot(iChain) != NIL_PAGE_NO_GG00)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "BD92VerObjRootPage - root:" << pRoot->nd_id()
                << " maxChain:" << MaxChain
                << " iChain:" << iChain
                << " too many subroots:" << RootPageInfo.bd900SubRoot(iChain);
            if ( e_ok == TrError ) TrError = e_data_page_corrupted; // PTS 1121056 
        }
    }
}

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

static void
bd92_VerifyObjSubRootPage (tbd_current_tree  &Current,
                           tbd_node_ptrs     &NptrsSubRoot)
{
    ROUTINE_DBG_MEO00 ("bd92VerifyObjSubRootPage");
    
    tgg00_BasisError       &TrError       = Current.curr_trans->trError_gg00;
    cbd900_SubRootPageInfo  SubRootPageInfo (NptrsSubRoot);
    cbd900_ObjChainInfo    *pObjChainInfo = NULL;
    tbd_nodeptr            &pSubRoot      = NptrsSubRoot.np_ptr();
    const tsp00_Int4        FileNo        = pSubRoot->nd_obj_file_no();
    const tsp00_Int4        ChainNo       = pSubRoot->nd_chain_no();
    tsp00_Bool              RelFileIsReq  = false;
    
    /* get shortcut to the appropriate ObjChainInfo */
    if (pSubRoot->nd_pt2() == pt2ContObject_egg00)
    {
        cbd900_ContObjFileInfo & ContObjFileInfo = bd93ContObjFileDir[FileNo];
        
        for (int iContFileNo=1; iContFileNo<=ContObjFileInfo.cfiNumContFiles_bd900; ++iContFileNo)    
        {
            if (pSubRoot->nd_root() == ContObjFileInfo[iContFileNo].GetRootPage())
            {
                pObjChainInfo = &(ContObjFileInfo[iContFileNo][ChainNo]);
                RelFileIsReq  = ContObjFileInfo[iContFileNo].ofiRelFileIsReq_bd900;
                break;
            }
        }
        if (pObjChainInfo == NULL)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "bd92_VerifyObjSubRootPage - subroot:" << pSubRoot->nd_id()
                << " not found in directory";
            if ( e_ok == TrError ) TrError = e_data_page_corrupted; // PTS 1121056 
        }
    }
    else
    {
        cbd900_ObjFileInfo & ObjFileInfo = bd90ObjFileDir[FileNo];
        pObjChainInfo = &(ObjFileInfo[ChainNo]);
        RelFileIsReq  =   ObjFileInfo.ofiRelFileIsReq_bd900;
    }
    
    /* compare number of all pages on subroot and in ObjChainInfo */
    if (pObjChainInfo->ociAllPageCnt_bd900 != SubRootPageInfo.bd900AllPageCnt())
    { 
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "bd92_VerifyObjSubRootPage - subroot:" << pSubRoot->nd_id()
            << " wrong AllPageCount SubRootInfo:" << SubRootPageInfo.bd900AllPageCnt()
            << " ChainInfo:" << pObjChainInfo->ociAllPageCnt_bd900;
        if (e_ok == TrError)  TrError = e_wrong_all_page_count;
    }
    
    /* check ranges of page counters */   
    if (SubRootPageInfo.bd900AllPageCnt() < 0)
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "bd92_VerifyObjSubRootPage - subroot:" << pSubRoot->nd_id()
            << " wrong AllPageCount SubRootInfo:" << SubRootPageInfo.bd900AllPageCnt();
        if (e_ok == TrError)  TrError = e_wrong_all_page_count;
    }
    
    if ((SubRootPageInfo.bd900FreePageCnt() < 0) ||
        (SubRootPageInfo.bd900FreePageCnt() > SubRootPageInfo.bd900AllPageCnt()))
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg << "bd92_VerifyObjSubRootPage - subroot:" << pSubRoot->nd_id()
            << " wrong FreePageCount SubRootInfo:" << SubRootPageInfo.bd900FreePageCnt();
        if (e_ok == TrError)  TrError = e_wrong_all_page_count;
    }
    
    const tsp00_Int4 FreePageCnt = (pSubRoot->nd_in_free_chain()? 1:0);
    if (pSubRoot->nd_next_free() == NIL_PAGE_NO_GG00) 
    {
        if (SubRootPageInfo.bd900FreePageCnt() != FreePageCnt)
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg << "bd92_VerifyObjSubRootPage - subroot:" << pSubRoot->nd_id()
                << " wrong FreePageCount SubRootInfo:" << SubRootPageInfo.bd900FreePageCnt()
                << " != " << FreePageCnt;
            if (e_ok == TrError)  TrError = e_wrong_all_page_count;
        }
    }
    else
    {
        if (SubRootPageInfo.bd900FreePageCnt() <= FreePageCnt)
        {
            /* when the is chain is dropped the next_free chain is not updated. therefore,   */
            /* this approximation need not be fulfilled. see bd930_ReleaseAllPagesOfOneChain */
            if (!RelFileIsReq)
            {
                Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
                opErrMsg << "bd92_VerifyObjSubRootPage - subroot:" << pSubRoot->nd_id()
                    << " wrong FreePageCount SubRootInfo:" << SubRootPageInfo.bd900FreePageCnt()
                    << " != " << FreePageCnt;
                if (e_ok == TrError)  TrError = e_wrong_all_page_count;
            }
        }
    }
}

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

static void
bd92_WriteChainStateToVtrace (tbd_current_tree                &Current, 
                              const  tbd92_ObjPageChainStat   &ChainStat,
                              cbd910_SubRootNode              &NptrsSubRoot,
                              const tsp00_Bool                 bChainIsDeleted)
{
    ROUTINE_DBG_MEO00 ("bd92_WriteChainStateToVtrace");
    
    tgg12_OmsFilenameTrace TrLineIn;
    
    cbd900_SubRootPageInfo SubRootPageInfo (NptrsSubRoot);
    
    TrLineIn.ofnTrType_gg12.becomes(otFilename_egg12);
    TrLineIn.ofnTrType2_gg12.becomes(ot2Nil_egg12);
    TrLineIn.ofnFileName_gg12 = Current.curr_tree_id.fileName_gg00();
    
    Trace_CommonEntry( *Current.curr_trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(b92verify), 
        REINTERPRET_CAST( tsp00_BytePtr, &TrLineIn ), sizeof (TrLineIn) );
    
    
    tgg12_OmsPageChainStatTrace TrLineChain;
    
    TrLineChain.opctSubRoot_gg12             =  NptrsSubRoot.np_ptr()->nd_id();
    TrLineChain.opctTrType_gg12.becomes(otPageChainStat_egg12);
    TrLineChain.opctAllPageCnt_gg12          =  ChainStat.AllPageCnt;
    TrLineChain.opctEmptyPageCnt_gg12        =  0;
    TrLineChain.opctFreePageCnt_gg12         =  ChainStat.FreePageCnt;
    TrLineChain.opctFeotPageCnt_gg12         =  ChainStat.FeotPageCnt;
    
    TrLineChain.opctAllPageRootCnt_gg12      =  SubRootPageInfo.bd900AllPageCnt();
    TrLineChain.opctEmptyPageRootCnt_gg12    =  0;
    TrLineChain.opctFreePageRootCnt_gg12     =  SubRootPageInfo.bd900FreePageCnt();
    
    TrLineChain.opctPageInFreeChainCnt_gg12  =  ChainStat.PageInFreeChainCnt;
    
    TrLineChain.opctFreePageInFreeChainCnt_gg12  = ChainStat.FreePageInFreeChainCnt; 
    TrLineChain.opctEmptyPageInFreeChainCnt_gg12 = 0;
    
    TrLineChain.opctPageWithEmptyLabelCnt_gg12 = 0;
    TrLineChain.opctPageWithFreeLabelCnt_gg12  = ChainStat.PageWithFreeLabelCnt;
    
    TrLineChain.opctPageWithFreeLabelInFreeChainCnt_gg12 = ChainStat.PageWithFreeLabelInFreeChainCnt;
    
    TrLineChain.opctFreePageWithFreeLabelInFreeChainCnt_gg12 = ChainStat.FreePageWithFreeLabelInFreeChainCnt;
    
    TrLineChain.opctFreeObjCnt_gg12 = ChainStat.FreeObjCnt;
    TrLineChain.opctFeotObjCnt_gg12 = ChainStat.FeotObjCnt;
    TrLineChain.opctOccObjCnt_gg12  = ChainStat.OccObjCnt;
    TrLineChain.opctResObjCnt_gg12  = ChainStat.ResObjCnt;
    
    TrLineChain.opctIsChainDeleted_gg12 = bChainIsDeleted;
    
    Trace_CommonEntry( *Current.curr_trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(b92verify), 
        REINTERPRET_CAST( tsp00_BytePtr, &TrLineChain ), sizeof (TrLineChain) );
}


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

static void
bd92_WriteContainerStateToVtrace (tbd_current_tree                     &Current, 
                                  const  tbd92_ObjPageContainerStat    &ContainerStat,
                                  const  cbd900_ObjFileInfo            *pObjFileInfo)
{ 
    ROUTINE_DBG_MEO00 ("bd92_WriteContainerStateToVtrace");
    
    tgg12_OmsFilenameTrace TrLineIn;
    
    TrLineIn.ofnTrType_gg12.becomes(otFilename_egg12);
    TrLineIn.ofnTrType2_gg12.becomes(ot2Nil_egg12);
    TrLineIn.ofnFileName_gg12 = Current.curr_tree_id.fileName_gg00();
    
    Trace_CommonEntry( *Current.curr_trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(b92verify), 
        REINTERPRET_CAST( tsp00_BytePtr, &TrLineIn ), sizeof (TrLineIn) );
    
    tgg12_OmsPageContainerStatTrace TrLineCon;
    
    TrLineCon.opcoTrType_gg12.becomes(otPageContainerStat_egg12);
    TrLineCon.opcoFreeObjCnt_gg12    =  ContainerStat.FreeObjCnt;       
    TrLineCon.opcoFeotObjCnt_gg12    =  ContainerStat.FeotObjCnt; 
    TrLineCon.opcoOccObjCnt_gg12     =  ContainerStat.OccObjCnt;
    TrLineCon.opcoResObjCnt_gg12     =  ContainerStat.ResObjCnt;
    TrLineCon.opcoAllPageCnt_gg12    =  ContainerStat.AllPageCnt; 
    TrLineCon.opcoEmptyPageCnt_gg12  =  0;
    TrLineCon.opcoFreePageCnt_gg12   =  ContainerStat.FreePageCnt;
    TrLineCon.opcoFeotPageCnt_gg12   =  ContainerStat.FeotPageCnt;
    TrLineCon.opcoNumSubRoots_gg12   =  pObjFileInfo->GetChainCount();
    TrLineCon.opcoIsFileDeleted_gg12 =  pObjFileInfo->ofiRelFileIsReq_bd900;
    
    Trace_CommonEntry( *Current.curr_trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(b92verify), 
        REINTERPRET_CAST( tsp00_BytePtr, &TrLineCon ), sizeof (TrLineCon) );
}

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

static void
bd92_WritePageStateToVtrace (tgg00_TransContext     &Trans,
                             tbd_nodeptr             pPage,
                             tsp00_Int4              ResObjCnt)
{                             
    ROUTINE_DBG_MEO00 ("bd92_WritePageStateToVtrace");
    
    tgg12_OmsPageStatTrace     TrLinePage;
    
    TrLinePage.opsTrType_gg12.becomes(otPageStat_egg12);
    TrLinePage.opsPno_gg12           = pPage->nd_id();
    TrLinePage.opsOccObjCnt_gg12     = pPage->nd_occ_obj_cnt();
    TrLinePage.opsFreeObjCnt_gg12    = pPage->nd_free_obj_cnt();
    TrLinePage.opsFreeEotObjCnt_gg12 = pPage->nd_free_eot_obj_cnt();
    TrLinePage.opsResObjCnt_gg12     = ResObjCnt;                
    
    Trace_CommonEntry(Trans, tgg00_Debug::fromConst(bd), tgg00_VtraceType::fromConst(b92verify), 
        REINTERPRET_CAST( tsp00_BytePtr, &TrLinePage ), sizeof (TrLinePage) );
}

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

Generated by  Doxygen 1.6.0   Back to index