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

Converter_Converter.cpp

Go to the documentation of this file.
/*!
  @file           Converter_Converter.cpp
  @author         TorstenS
  @author         AlexanderK
  @ingroup        Converter
  @brief          Implementation of all converter methods
*/

/* ========== licence begin  GPL
  Copyright (c) 2001-2004 SAP AG

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

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


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

#include "hgg01.h"    // g01is_livecache
#include "hgg08.h"    // g08convert0
#include "hbd20_6.h"  // bd20GetNumberOfChangedPages
#include "hbd91.h"    // garbage collector 
#include "Converter/Converter_Converter.hpp"
#include "Converter/Converter_Dump.hpp"
#include "Converter/Converter_LeafPage.hpp"
#include "Converter/Converter_Exception.hpp"
#include "Converter/Converter_MapError.hpp"
#include "Converter/Converter_Messages.hpp"
#include "Converter/Converter_PageFrameAllocator.hpp"
#include "Converter/Converter_Pager.hpp"
#include "Converter/Converter_BlockAddressIterator.hpp"
#include "FrameControl/FrameCtrl_ICommon.hpp"
#include "IOManager/IOMan_IDataInfo.hpp"
#include "Pager/Pager_IRestart.hpp"
#include "Pager/Pager_ISavepoint.hpp"
#include "Logging/Log_Types.hpp"
#include "KernelCommon/Kernel_IAdminRestartShutdown.hpp"
#include "KernelCommon/ParameterNames/KernelParam_Converter.hpp"
#include "RunTime/RTE_Message.hpp"
#include "RunTime/RTE_Crash.hpp"
#include "RunTime/Configuration/RTEConf_ParameterAccess.hpp"
#include "RunTime/Configuration/RTEConf_ParameterAccessKernelInterface.hpp"



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

/// Defines security space for database full handling

00066 #define CONV_NUM_SECURITY_PAGES 10


/*===========================================================================*
 *  STATIC/INLINE FUNCTION PROTOTYPES                                        *
 *===========================================================================*/

/* -----------------------------------------------------------------------*/
/*!
    @brief  This method is used to get the configured value for a given 
            integer configuration parameter from the configuration file.
    @return (SAPDB_UInt) configuration value
 */
/* -----------------------------------------------------------------------*/

static SAPDB_UInt
00082 GetConfiguredValue( const RTEConf_Parameter::Name paramName )
{
    RTEConf_Parameter::Integer  paramValue;
    SAPDBErr_MessageList        errMsg;

    if( ! RTEConf_ParameterAccess::Instance()->GetInteger(
                paramName, paramValue, errMsg ))
    {
        RTE_Crash( errMsg );
    }
    return( ( SAPDB_UInt ) paramValue );
}

/*===========================================================================*
 *  INSTANCE METHODS OF THE INTERFACE CLASSES  OF THE CONVERTER CLASS        *
 *===========================================================================*/

00099 Converter_IManager & Converter_IManager::Instance()
{
    return Converter_Converter::Instance();
}

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

00106 Converter_IMigration & Converter_IMigration::Instance()
{
    return Converter_Converter::Instance();
}

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

00113 Converter_IDiagnose & Converter_IDiagnose::Instance()
{
    return Converter_Converter::Instance();
}

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

00120 Converter_IDump & Converter_IDump::Instance()
{
    return Converter_Converter::Instance();
}

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

00127 Converter_IPageIO & Converter_IPageIO::Instance()
{
    return Converter_Converter::Instance();
}

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

00134 Converter_ISavePoint & Converter_ISavePoint::Instance()
{
    return Converter_Converter::Instance();
}

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

00141 Converter_IVerify & Converter_IVerify::Instance()
{
    return Converter_Converter::Instance();
}

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

00148 Converter_ICommon & Converter_ICommon::Instance()
{
    return Converter_Converter::Instance();
}

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

00155 Converter_IBackUp & Converter_IBackUp::Instance()
{
    return Converter_Converter::Instance();
}

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

00162 Converter_IPageNoMapping & Converter_IPageNoMapping::Instance()
{
    return Converter_Converter::Instance();
}

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

00169 Converter_IPageNoManager & Converter_IPageNoManager::Instance()
{
    return Converter_Converter::Instance();
}

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

00176 Converter_IEvent & Converter_IEvent::Instance()
{
    return Converter_Converter::Instance();
}


/*===========================================================================*
 *  METHODS OF THE CONVERTER CLASS                                           *
 *===========================================================================*/

Converter_Converter* Converter_Converter::m_Instance = NULL;

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

00190 Converter_Converter::Converter_Converter( SAPDBMem_IRawAllocator  &allocator )
        :
        m_Allocator( UTF8( "Converter_Manager" ), allocator),
        m_IsLiveCacheInstance( g01is_livecache()),
        m_MapBlockingSize( 8 ),
        m_VolumeNoBitCount( GetConfiguredValue( UTF8( KERNELPARAM_VOLUMENO_BIT_COUNT ))),
        m_NumRegions( GetConfiguredValue( UTF8( KERNELPARAM_CONVERTER_REGIONS ))),
        m_BaseRegionId( g08convert0 ),
        m_PageSize( FrameCtrl_ICommon::GetInstance().GetPageSize()),
        m_TempMapControl( m_Allocator, Data_PageRecoveryMode( Data_Dynamic, Data_NotRecoverable )),
        m_PermMapControl( m_Allocator, Data_PageRecoveryMode( Data_Dynamic, Data_Recoverable )),
        m_PermStaticMapControl( m_Allocator, Data_PageRecoveryMode( Data_Static, Data_Recoverable )),
        m_Index (m_Allocator),
        m_Active( false ),
        m_InMaintenanceMode( false ),
        m_DBFullWaitQueue( CONV_SUSPEND_HANDLE_DB_FULL ),
        m_FreePageNoWaitQueue( CONV_SUSPEND_FREE_PAGENO_WAIT_DURING_SVP ),
        m_ExpandConverterWaitQueue( CONV_SUSPEND_EXPAND_WAIT_DURING_SVP ),
        m_DBUsageMonitor (sp31ei_db_filling_above_limit, sp31ei_db_filling_below_limit),
        m_VolumeList(NULL)
{
    // initialize static member of the converter page defining
    // the number of bits used to address a volume

    Converter_Page::SetDevNoBitCount( m_VolumeNoBitCount );

    // the exceeding of the following limits will always be written
    // into the knldiag. all values are defined in units of 0.01 %

    m_DBUsageMonitor.EnableEventing();
    const SAPDB_Bool bOverFlowEvent          = true;
    const SAPDB_Bool bWriteAlwaysIntoKnldiag = true;

    m_DBUsageMonitor.AddEvent(8000, bOverFlowEvent, sp31ep_high, bWriteAlwaysIntoKnldiag);
    m_DBUsageMonitor.AddEvent(9000, bOverFlowEvent, sp31ep_high, bWriteAlwaysIntoKnldiag);
    m_DBUsageMonitor.AddEvent(9500, bOverFlowEvent, sp31ep_high, bWriteAlwaysIntoKnldiag);
    m_DBUsageMonitor.AddEvent(9600, bOverFlowEvent, sp31ep_high, bWriteAlwaysIntoKnldiag);
    m_DBUsageMonitor.AddEvent(9700, bOverFlowEvent, sp31ep_high, bWriteAlwaysIntoKnldiag);
    m_DBUsageMonitor.AddEvent(9800, bOverFlowEvent, sp31ep_high, bWriteAlwaysIntoKnldiag);
    m_DBUsageMonitor.AddEvent(9900, bOverFlowEvent, sp31ep_high, bWriteAlwaysIntoKnldiag);

    for (int Limit = 500; Limit < 10000; Limit+=500)
    {
        m_DBUsageMonitor.AddEvent(Limit, bOverFlowEvent,   sp31ep_low, ! bWriteAlwaysIntoKnldiag);
        m_DBUsageMonitor.AddEvent(Limit, ! bOverFlowEvent, sp31ep_low, ! bWriteAlwaysIntoKnldiag);
    }
}

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

Converter_Converter&
00241 Converter_Converter::CreateInstance ()
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::CreateInstance", Converter_Trace, 5 );

    if( m_Instance == NULL )
    {
        m_Instance = new (RTEMem_Allocator::Instance())
                     Converter_Converter( RTEMem_Allocator::Instance() );

        if( NULL == m_Instance )
        {
            Converter_Exception errMsg( __CONTEXT__, CONVERTER_NO_MEMORY_TO_BUILD_CONVERTER );
            RTE_Crash( errMsg );
        }
    }
    return *m_Instance;
}

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

void
00262 Converter_Converter::Restart(
    const tsp00_TaskId              TaskId,
    const Converter_Version         &ConverterVersion,
    const IOMan_PackedBlockAddress  &packedRootBlockAddr,
    const Converter_Version         &snapShotVersion,
    const IOMan_PackedBlockAddress  &packedSnapShotRootBlockAddr,
    const Kernel_DateTime           &snapShotCreationTimeStamp,
    const SAPDB_Bool                bIncConverterVersion,
    const SAPDB_Bool                bLastSaveDataSuccessful,
    const Data_PageNo               MaxDynamicPageNo,
    const Data_PageNo               MaxStaticPageNo,
    const SAPDB_UInt                NumAllPages )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::Restart", Converter_Trace, 5 );

    SAPDBTRACE_WRITELN( Converter_Trace, 5, "ConverterVersion: " << ConverterVersion );
    SAPDBTRACE_WRITELN( Converter_Trace, 5, "SnapShotVersion : " << snapShotVersion );

    const SAPDB_UInt numAllStaticPages = m_IsLiveCacheInstance ? NumAllPages : 0;

    if(
        ( ! m_TempMapControl.Initialize( TaskId, NumAllPages,
                                         m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
        ||
        ( ! m_PermMapControl.Initialize( TaskId, SAPDB_MAX( MaxDynamicPageNo, Data_PageNo( NumAllPages )),
                                         m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
        ||
        (! m_PermStaticMapControl.Initialize( TaskId, SAPDB_MAX( MaxStaticPageNo, Data_PageNo( numAllStaticPages )),
                                              m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
    )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_MAP_INIT_FAILED1,
                                    SAPDB_ToString( NumAllPages,      _T_d ),
                                    SAPDB_ToString( MaxDynamicPageNo, _T_d ),
                                    SAPDB_ToString( MaxStaticPageNo,  _T_d ));
        RTE_Crash( errMsg );
    }

    InitializeBase( NumAllPages );

    m_Version                   = ConverterVersion;
    m_RootBlockAddress          = packedRootBlockAddr.Unpack( m_VolumeNoBitCount );
    m_SnapShotVersion           = snapShotVersion;
    m_SnapShotCreationTimeStamp = snapShotCreationTimeStamp;
    m_LastSaveDataSuccessful    = bLastSaveDataSuccessful;

    /* the parent index is created starting with the data stored on the ConverterRootBlock */
    Converter_Pager pager( TaskId, m_SnapShotVersion );

    m_Index.Restart( m_RootBlockAddress, pager );

    /* create per device lists of all converter leaf nodes */
    VolumeList  volumeList( m_Allocator );

    m_Index.CreateInputQueues(volumeList, m_PageSize);

    m_VolumeList = &volumeList; // is used by the pager tasks

    /* read all converter leaf pages referenced by the converter tree */
    Pager_IRestart::GetInstance().ReadConverter( TaskId );

    m_VolumeList = NULL;

    volumeList.Delete(); // free occupied memory

    SAPDBERR_ASSERT_STATE( m_Index.Verify()); // PTS 1113242 TS 2001-12-21

    // Caused by the FBM handling it is necessary that
    // the current/working converter is read first.

    if( m_SnapShotVersion.IsValid()){
        RestartSnapShot( TaskId, packedSnapShotRootBlockAddr );
    }

    if( bIncConverterVersion )
        ++m_Version;
    else
        m_InMaintenanceMode = true;

    CheckDataAreaPeakFilling();

    SAPDBTRACE_WRITELN( Converter_Trace, 5, "PermPagesUsed: " << m_NumPermPagesUsed );
    SAPDBTRACE_WRITELN( Converter_Trace, 5, "UpdatedDynamicPages: " <<
                        m_PermMapControl.NumUpdatedPermPages( TaskId ));
    SAPDBTRACE_WRITELN( Converter_Trace, 5, "UpdatedStaticPages: " <<
                        m_PermStaticMapControl.NumUpdatedPermPages( TaskId ));
}

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

void
00353 Converter_Converter::ReadPages(
    const tsp00_TaskId  taskId,
    SAPDB_UInt          pagerIndex,
    SAPDB_UInt          &totalPages,
    SAPDB_UInt          &totalIO )
{

    SAPDBTRACE_ROUTINE_DEBUG( "Converter::ReadPages", Converter_Trace, 5 );

    SAPDBERR_ASSERT_STATE (NULL != m_VolumeList);

    Converter_Pager pager( taskId, m_SnapShotVersion );

    // loop over all converter leaf pages located in one data volume. This
    // will speed up the restart time of the converter. The leaf pages located
    // in the other data volumes are read by another pager task.

    while (pagerIndex < ((*m_VolumeList).GetSize())){
        Converter_Index::BlockVector::Iterator        iter    = (*m_VolumeList)[pagerIndex].Begin();
        const Converter_Index::BlockVector::Iterator  iterEnd = (*m_VolumeList)[pagerIndex].End();

        for( ; iter < iterEnd; iter++ )
        {
            SAPDB_UInt NumPermPagesUpdated        = 0;
            SAPDB_UInt NumPendingUpdatedPermPages = 0;

            Converter_LeafPage  leafPage;

            pager.Read( iter->GetBlockAddress(), leafPage );

            totalPages++;
            totalIO++;

            const Data_AddressingMode addrMode = leafPage.ReadPageRecoveryMode().GetAddressingMode();

            SAPDBERR_ASSERT_STATE (leafPage.ReadPageRecoveryMode().PageIsRecoverable());

            // write the address of the parent index page on the leaf page according the
            // iterator. This is needed for converter leaf page i/o to be able to update
            // the block address of the leaf in the corresponding converter index page.

            leafPage.WriteParentReference (iter->GetParentReference());

            SAPDB_UInt FreeEntryCount = 0;

            // mark all used blocks referenced by the current converter leaf pages as
            // occupied in the FBM. Moreover all reserved converter leaf page entries
            // are set to free.

            Converter_PageEntryIterator         pageEntryIter    = leafPage.Begin();
            const Converter_PageEntryIterator   pageEntryEndIter = leafPage.End();

            for( ; pageEntryIter != pageEntryEndIter; ++pageEntryIter )
            {
                if( ! pageEntryIter.EntryInUse())
                {
                    ++FreeEntryCount;
                    continue;
                }

                const Converter_PageEntryNo entryPos = pageEntryIter.GetPosition();

                if( pageEntryIter.GetPackedBlockAddress().IsReserved())
                {
                    leafPage.ReleaseEntry( entryPos );
                    ++FreeEntryCount;
                    continue;
                }

                m_NumPermPagesUsed.Increment();

                CheckFillingOfDataBase();

                // Update the number of changed data pages since the last save data

                if( leafPage.SavePagesPending( entryPos ) && !m_LastSaveDataSuccessful)
                    ++ NumPendingUpdatedPermPages;

                if( leafPage.SavePagesRequested( entryPos ))
                    ++ NumPermPagesUpdated;
            }

            Converter_BlockAddressIterator elements = leafPage.elements();

            if( SAPDB_TRUE != FBM_IManager::Instance().SetBlockStateToOccupied(
                        taskId, elements))
            {

                Converter_Exception errMsg( __CONTEXT__, CONVERTER_BAD_ENTRY_STATE,
                        (( Data_Dynamic == leafPage.ReadPageRecoveryMode().GetAddressingMode())
                        ? "permanent" : "static"),
                        SAPDB_ToString( leafPage.GetPageNo( elements.GetPosition()), _T_d ));

                RTE_Crash( errMsg );
            }

            if( Data_Static == addrMode )
            {
                m_PermStaticMapControl.IntegratePage( taskId, leafPage, FreeEntryCount, NumPermPagesUpdated,
                                                      NumPendingUpdatedPermPages );
            }
            else // Data_Dynamic
            {
                m_PermMapControl.IntegratePage( taskId, leafPage, FreeEntryCount, NumPermPagesUpdated,
                                                NumPendingUpdatedPermPages );
            }
        }
        pagerIndex += g01maxdatawriter();
    }
}

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

void
00467 Converter_Converter::ReadSnapShotPages(
    const tsp00_TaskId  taskId,
    const SAPDB_UInt    pagerIndex,
    SAPDB_UInt          &totalPages,
    SAPDB_UInt          &totalIO )
{

    SAPDBTRACE_ROUTINE_DEBUG( "Converter::ReadSnapShotPages", Converter_Trace, 5 );

    SAPDBERR_ASSERT_STATE (NULL != m_VolumeList);

    // check if Pager has something to do ..
    if ((*m_VolumeList).GetSize() <= pagerIndex){
        return;
    }

    Converter_PageFrameAllocator    frameAllocator( taskId );
    Converter_SnapShotPager         pager( taskId, m_SnapShotVersion, m_Index );
    Converter_LeafPage              leafPage;

    leafPage.SetFrame( frameAllocator.New());

    // loop over all converter leaf pages located in one data volume. This
    // will speed up the restart time of the converter. The leaf pages located
    // in the other data volumes are read by another pager task.

    Converter_Index::BlockVector::Iterator        iter    = (*m_VolumeList)[pagerIndex].Begin();
    const Converter_Index::BlockVector::Iterator  iterEnd = (*m_VolumeList)[pagerIndex].End();

    for( ; iter < iterEnd; iter++ )
    {
        pager.Read( iter->GetBlockAddress(), leafPage );

        totalPages++;
        totalIO++;

        const Data_PageRecoveryMode recMode  = leafPage.ReadPageRecoveryMode();
        const Data_AddressingMode   addrMode = recMode.GetAddressingMode();

        SAPDBERR_ASSERT_STATE( recMode.PageIsRecoverable());

        // mark all used blocks referenced by the current snapshot converter
        // leaf page as occupied in the FBM. Note that the corresponding FBM
        // block could be already set to occupied!

        Converter_PageEntryIterator         pageEntryIter    = leafPage.Begin();
        const Converter_PageEntryIterator   pageEntryEndIter = leafPage.End();

        for( ; pageEntryIter != pageEntryEndIter; ++pageEntryIter )
        {
            if( ! pageEntryIter.EntryInUse())
                continue;

            if( pageEntryIter.GetPackedBlockAddress().IsReserved())
                continue;


            const Data_PageNo        pageNo   = leafPage.GetPageNo( pageEntryIter.GetPosition());
            const IOMan_BlockAddress newBlock = pageEntryIter.GetBlockAddress(); // from snapShot
            IOMan_BlockAddress       block;

            const Converter_ReturnCode retCode = GetPositionForReading( taskId, pageNo, recMode, block );

            SAPDBERR_ASSERT_STATE( newBlock.IsValid());

            IncrementSnapShotSize();

            if(( Converter_Ok == retCode ) && ( block == newBlock ))
            {
                SAPDBTRACE_WRITELN( Converter_Trace, 7, "Snapshot: " << ((Data_Dynamic == addrMode) ?
                                    "Permanent" : "Static") << " pageNo: " << pageNo << " on block: " <<
                                    block.GetDeviceNo() << "/" << block.GetBlockNo() << " not marked as used ");

                continue; // given page(block) hasn't changed since snapshot creation
            }

            SAPDBTRACE_WRITELN( Converter_Trace, 7, "Snapshot: " << ((Data_Dynamic == addrMode) ?
                                "Permanent" : "Static") << " pageNo: " << pageNo << " on block: " <<
                                newBlock.GetDeviceNo() << "/" << newBlock.GetBlockNo() << " marked as used ");

            if( FBM_IManager::Instance().SetBlockStateToOccupied( taskId, newBlock ))
            {
                m_NumPermPagesUsed.Increment();
                continue;
            }

            Converter_Exception errMsg( __CONTEXT__, CONVERTER_BAD_ENTRY_STATE,
                                        (( Data_Dynamic == addrMode) ?
                                         "permanent" : "static"), SAPDB_ToString( pageNo, _T_d ));
            RTE_Crash( errMsg );
        }
    }
    if( leafPage.IsAssigned()){
        frameAllocator.Free( leafPage.GetFrame());
    }
}

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

void
00567 Converter_Converter::Create(
    const tsp00_TaskId taskId,
    const SAPDB_UInt   numAllPages )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::Create", Converter_Trace, 5 );

    const SAPDB_UInt numAllStaticPages = m_IsLiveCacheInstance ? numAllPages : 0;

    if(
        ( ! m_TempMapControl.Initialize( taskId, numAllPages,
                                         m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
        ||
        ( ! m_PermMapControl.Initialize( taskId, numAllPages,
                                         m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
        ||
        (! m_PermStaticMapControl.Initialize( taskId, numAllStaticPages,
                                              m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
    )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_MAP_INIT_FAILED2,
                                    SAPDB_ToString( numAllPages, _T_d ));
        RTE_Crash( errMsg );
    }

    InitializeBase( numAllPages );
    m_Version.SetToInitialVersion(); // corresponds to version 1

    m_Index.Create();
}

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

void
00600 Converter_Converter::CreateForRestore(
    const tsp00_TaskId      taskId,
    const Converter_Version &converterVersion,
    const SAPDB_Bool        bLastSaveDataSuccessful,
    const Data_PageNo       maxDynamicPageNo,
    const Data_PageNo       maxStaticPageNo,
    const SAPDB_UInt        numAllPages )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::CreateForRestore", Converter_Trace, 5 );

    const SAPDB_UInt numAllStaticPages = m_IsLiveCacheInstance ? numAllPages : 0;

    if(
        ( ! m_TempMapControl.Initialize( taskId, numAllPages,
                                         m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
        ||
        ( ! m_PermMapControl.Initialize( taskId, SAPDB_MAX( maxDynamicPageNo, Data_PageNo( numAllPages )),
                                         m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
        ||
        (! m_PermStaticMapControl.Initialize( taskId, SAPDB_MAX( maxStaticPageNo, Data_PageNo( numAllStaticPages )),
                                              m_BaseRegionId, m_NumRegions, m_MapBlockingSize, m_PageSize ))
    )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_MAP_INIT_FAILED1,
                                    SAPDB_ToString( numAllPages,      _T_d),
                                    SAPDB_ToString( maxDynamicPageNo, _T_d),
                                    SAPDB_ToString( maxStaticPageNo,  _T_d));
        RTE_Crash( errMsg );
    }

    InitializeBase( numAllPages );

    m_InMaintenanceMode      = true;
    m_RestoreDataActive      = true;
    m_Version                = converterVersion;
    m_LastSaveDataSuccessful = bLastSaveDataSuccessful;
    m_Index.Create();
}

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

void
00642 Converter_Converter::Shutdown( const tsp00_TaskId taskId )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::Shutdown", Converter_Trace, 5 );

    if( ! m_Active )
        return;

    m_NumPermPagesUsed     = 0;
    m_NumTempPagesUsed     = 0;
    m_NumPermConvPages     = 0;
    m_NumTempConvPages     = 0;
    m_NumSnapShotPages     = 0;
    m_TemporaryPeakFilling = 0;
    m_PermanentPeakFilling = 0;
    m_NumAllPages          = 0;
    m_SecuritySpaceLimit   = 0;
    m_Active               = false;
    m_InMaintenanceMode    = false;
    m_SavePagesIsActiv     = false;
    m_SaveDataIsActiv      = false;
    m_RestoreDataActive    = false;
    m_RestorePagesActive   = false;
    m_ColdVerifyIsActive   = false;
    m_Version.Invalidate();
    m_SnapShotVersion.Invalidate();
    m_SnapShotCreationTimeStamp.Invalidate();

    /* resume all tasks waiting for a converter resource */
    m_DBFullWaitQueue.ResumeAllWaitingTasks( taskId );
    m_FreePageNoWaitQueue.ResumeAllWaitingTasks( taskId );

    m_TempMapControl.Shutdown( taskId );
    m_PermMapControl.Shutdown( taskId );
    m_PermStaticMapControl.Shutdown( taskId );

    m_Index.Shutdown();
}

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

void
00683 Converter_Converter::FlushParallel (
    const tsp00_TaskId          taskId,
    Converter_Version           &ConverterVersion,
    Data_PageNo                 &MaxStaticPageNo,
    Data_PageNo                 &MaxDynamicPageNo,
    IOMan_PackedBlockAddress    &packedRootBlockAddr,
    SAPDB_UInt                  &NumPagesTotal,
    SAPDB_UInt                  &NumIOTotal)
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::FlushParallel", Converter_Trace, 5 );

    SAPDB_UInt  NumPages = 0;
    SAPDB_UInt  NumIO    = 0;

    if( ! m_Active )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_INFO_SHUTDOWN );
        RTE_Message( errMsg );

        Kernel_IAdminRestartShutdown::Instance().Offline();
    }

    // MapControls dealing with permanent pageId's remembers parentReferences
    // of empty converter leaf pages between converter flushes, now it's time
    // to drop these pages from the index

    m_PermMapControl.RemoveEmptyLeaves( taskId, m_SnapShotVersion, m_Index );
    m_PermStaticMapControl.RemoveEmptyLeaves( taskId, m_SnapShotVersion, m_Index );

    Pager_ISavepoint::GetInstance().FlushConverterParallel( taskId, NumPages, NumIO );

    NumPagesTotal += NumPages;
    NumIOTotal    += NumIO;

    Converter_Pager pager ( taskId, m_SnapShotVersion );

    MaxStaticPageNo    = m_MaxUsedStaticPageNo;
    MaxDynamicPageNo   = m_MaxUsedDynamicPageNo;

    m_RootBlockAddress = m_Index.Flush( pager, NumPages, NumIO );

    NumPagesTotal += NumPages;
    NumIOTotal    += NumIO;

    packedRootBlockAddr = m_RootBlockAddress.Pack( m_VolumeNoBitCount );;
    ConverterVersion    = m_Version;

    // Converter leaf pages are set to changed if a permanent data page is
    // removed or the block address is updated. Both operations are not
    // possible during the converter flush (savepoint) and therefore the
    // number of changed converter leaves has to be zero at the end of the
    // savepoint.

    SAPDBERR_ASSERT_STATE( 0 == GetNumberOfChangedConvPages());
}

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

void
00742 Converter_Converter::WritePages(
    const tsp00_TaskId  taskId,
    const SAPDB_UInt    iSection,
    SAPDB_UInt          &totalPages,
    SAPDB_UInt          &totalIO )
{
    totalPages = 0;
    totalIO    = 0;

    Converter_Pager pager( taskId, m_SnapShotVersion );

    m_PermMapControl.FlushSection( taskId, m_Index, pager, iSection, totalPages, totalIO );
    m_PermStaticMapControl.FlushSection( taskId, m_Index, pager, iSection, totalPages, totalIO );
}

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

SAPDB_Bool
00760 Converter_Converter::FlushSerial(
    const tsp00_TaskId          taskId,
    Converter_Version           &ConverterVersion,
    Data_PageNo                 &MaxStaticPageNo,
    Data_PageNo                 &MaxDynamicPageNo,
    IOMan_PackedBlockAddress    &packedRootBlockAddr )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::FlushSerial", Converter_Trace, 5 );

    SAPDB_UInt  NumPages = 0;
    SAPDB_UInt  NumIO    = 0;

    if( ! m_Active )
        return( SAPDB_FALSE );

    // MapControls dealing with permanent pageId's remembers parentReferences
    // of empty converter leaf pages between converter flushes, now it's time
    // to drop these pages from the index

    m_PermMapControl.RemoveEmptyLeaves( taskId, m_SnapShotVersion, m_Index );
    m_PermStaticMapControl.RemoveEmptyLeaves( taskId, m_SnapShotVersion, m_Index );

    Converter_Pager pager ( taskId, m_SnapShotVersion );

    MaxStaticPageNo     = m_PermStaticMapControl.Flush( taskId, m_Index, pager );
    MaxDynamicPageNo    = m_PermMapControl.Flush( taskId, m_Index, pager );

    m_RootBlockAddress  = m_Index.Flush( pager, NumPages, NumIO);

    packedRootBlockAddr = m_RootBlockAddress.Pack( m_VolumeNoBitCount );;
    ConverterVersion    = m_Version;

    return( SAPDB_TRUE );
}

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

SAPDB_Bool
00798 Converter_Converter::Expand(
    const tsp00_TaskId         TaskId,
    const IOMan_DeviceNo       &DevNo,
    const SAPDB_UInt           DevSize,
    const RTE_VolumeAccessMode VolMode,
    const SAPDB_UInt           NumPagesAdded )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::Expand", Converter_Trace, 5 );

    if( ! m_Active )
        return( SAPDB_FALSE );

    if( ! ExpandMap( TaskId, Data_PageRecoveryMode( Data_Dynamic, Data_NotRecoverable ),  NumPagesAdded ))
        return( SAPDB_FALSE );

    if( ! ExpandMap( TaskId, Data_PageRecoveryMode( Data_Dynamic, Data_Recoverable ), NumPagesAdded ))
        return( SAPDB_FALSE );

    if( m_IsLiveCacheInstance )
    {
        if( ! ExpandMap( TaskId, Data_PageRecoveryMode( Data_Static, Data_Recoverable ), NumPagesAdded ))
            return( SAPDB_FALSE );
    }

    // Add data volume to FBM before the capacity of the converter is enlarged,
    // because register device could fail. Furthermore the data base is available.

    if( ! FBM_IManager::Instance().AddVolume( TaskId, DevNo, DevSize, VolMode ))
        return( SAPDB_FALSE );

    m_NumAllPages +=NumPagesAdded;
    m_DBUsageMonitor.Rescale (m_NumAllPages);

    // PTS 1124331 TS 2003-09-23
    m_SecuritySpaceLimit = ( m_NumAllPages - SAPDB_MIN( m_NumAllPages/25, 4000));

    m_DBFullWaitQueue.ResumeAllWaitingTasks( TaskId );

    return( SAPDB_TRUE );
}

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

void
00842 Converter_Converter::BeginSaveData( const tsp00_TaskId  taskId )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::BeginSaveData", Converter_Trace, 5 );

    SAPDBERR_ASSERT_STATE (! BackUpIsActive());
    SAPDBERR_ASSERT_STATE (false == m_ColdVerifyIsActive);
    SAPDBERR_ASSERT_STATE (0     == m_NumStatConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumDynConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumPagesForBackUp);

    m_SaveDataIsActiv = true;
    SAPDB_UInt numPagesForBackUp = 0;

    m_PermStaticMapControl.MarkPermPagesForSaveData( taskId, m_LastSaveDataSuccessful,
            m_NumStatConvPagesForBackUp, numPagesForBackUp );

    m_NumPagesForBackUp = numPagesForBackUp;

    m_PermMapControl.MarkPermPagesForSaveData( taskId, m_LastSaveDataSuccessful,
            m_NumDynConvPagesForBackUp, numPagesForBackUp );

    m_NumPagesForBackUp += numPagesForBackUp;

    if (g01is_archive())
    {
        m_PermStaticMapControl.ExtractArchiveConverterForSaveData( taskId );

        m_PermMapControl.ExtractArchiveConverterForSaveData( taskId );
    }

    FBM_IManager::Instance().BeginReadingBlocksMarkedForBackUp( taskId );
}

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

void
00878 Converter_Converter::BeginSavePages( const tsp00_TaskId  taskId )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::BeginSavePages", Converter_Trace, 5 );

    SAPDBERR_ASSERT_STATE (! BackUpIsActive());
    SAPDBERR_ASSERT_STATE (false == m_ColdVerifyIsActive);
    SAPDBERR_ASSERT_STATE (0     == m_NumStatConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumDynConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumPagesForBackUp);

    m_SavePagesIsActiv           = true;
    SAPDB_UInt numPagesForBackUp = 0;

    m_PermStaticMapControl.MarkPermPagesForSavePages( taskId, m_LastSaveDataSuccessful,
            m_NumStatConvPagesForBackUp, numPagesForBackUp, Version() );

    m_NumPagesForBackUp = numPagesForBackUp;

    m_PermMapControl.MarkPermPagesForSavePages( taskId, m_LastSaveDataSuccessful,
            m_NumDynConvPagesForBackUp, numPagesForBackUp, Version());

    m_NumPagesForBackUp += numPagesForBackUp;

    FBM_IManager::Instance().BeginReadingBlocksMarkedForBackUp( taskId );
}

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

SAPDB_Bool
00907 Converter_Converter::ResetDataPageAfterBackUp(
    const tsp00_TaskId          &TaskId,
    const IOMan_BlockAddress    &BlockAddress,
    const Data_PageNo           &PageNo,
    const Data_AddressingMode   &AddressingMode )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::ResetDataPageAfterBackUp", Converter_Trace, 5 );

    SAPDB_Bool retCode = SAPDB_FALSE;

    if( m_Active )
    {
        if( Data_Dynamic == AddressingMode )
        {
            retCode = m_PermMapControl.RemovePageNoFromBackUpPageNoList( TaskId, PageNo );
        }
        else if( Data_Static == AddressingMode )
        {
            retCode = m_PermStaticMapControl.RemovePageNoFromBackUpPageNoList( TaskId, PageNo );
        }

        if( SAPDB_TRUE == retCode ){
            FBM_IManager::Instance().RestoreBlockStateMarkedForBackup( TaskId, BlockAddress );
        }
    }
    return( retCode );
}

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

void
00938 Converter_Converter::EndSave(
    const tsp00_TaskId taskId,
    const SAPDB_Bool   bBackUpSuccessfullyFinished )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::EndSave", Converter_Trace, 5 );

    if( ! m_Active )
        return;

    m_NumDynConvPagesForBackUp  = 0;
    m_NumStatConvPagesForBackUp = 0;
    m_NumPagesForBackUp         = 0;

    if (m_SaveDataIsActiv)
    {
        m_SaveDataIsActiv = false;

        if (!bBackUpSuccessfullyFinished){
            m_LastSaveDataSuccessful = false;
        }
        else
        {
            m_LastSaveDataSuccessful = true;
            m_PermMapControl.ResetCounterOfPagesStillMarkedForSavePages( taskId );
            m_PermStaticMapControl.ResetCounterOfPagesStillMarkedForSavePages( taskId );
        }
    }
    else
    {
        m_SavePagesIsActiv = false;
        m_PermMapControl.RemoveBitMapPages();
        m_PermStaticMapControl.RemoveBitMapPages();
    }

    /* remove all flags and clear all lists which indicate */
    /* that a page is marked for the current back up       */
    if ( !bBackUpSuccessfullyFinished){
        FBM_IManager::Instance().RestoreAllBlockStatesMarkedForBackup( taskId );
    }
    else
    {
        SAPDBERR_ASSERT_STATE( CheckBackUp( taskId ));
    }

    m_PermMapControl.ClearBackUpPageNoList();
    m_PermStaticMapControl.ClearBackUpPageNoList();
}

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

void
00989 Converter_Converter::RestoreConverterPage(
    const tsp00_TaskId  taskId,
    Converter_LeafPage  &leafPage )
{
    Converter_PageEntryIterator       start = leafPage.Begin();
    const Converter_PageEntryIterator end   = leafPage.End();

    const Data_AddressingMode addrMode = leafPage.ReadPageRecoveryMode().GetAddressingMode();

    while( start != end )
    {
        if (start.EntryInUse())
        {
            const Data_PageNo        pageNo       = leafPage.GetPageNo( start.GetPosition());
            const IOMan_BlockAddress blockAddress = start.GetBlockAddress();

            SetBlockAddressOfRestoredPage( taskId, blockAddress, pageNo, addrMode );
        }
        ++start;
    }
}

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

void
01014 Converter_Converter::EndSavepoint(
    const tsp00_TaskId    taskId,
    Converter_Version     &converterVersion )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::EndSavepoint", Converter_Trace, 5 );

    ++m_Version;

    converterVersion = m_Version;

    m_PermMapControl.ReSetSavepointActiveFlag( taskId );
    m_PermStaticMapControl.ReSetSavepointActiveFlag( taskId );

    CheckDataAreaPeakFilling();
}

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

void
01033 Converter_Converter::FreePageNosAfterSavepoint( const tsp00_TaskId taskId )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::FreePageNosAfterSavepoint", Converter_Trace, 5 );

    // release all PageNos stored in the FreePageNoList
    m_PermMapControl.FreePageNosAfterSavepoint( taskId, m_SnapShotVersion );
    m_PermStaticMapControl.FreePageNosAfterSavepoint( taskId, m_SnapShotVersion );

    // resume all tasks which were suspended during a savepoint since there
    // was no more space to insert the pageno to release into a freepagenolist
    if( ! m_FreePageNoWaitQueue.IsEmpty() )
        m_FreePageNoWaitQueue.ResumeAllWaitingTasks( taskId );

    // resume tasks which want to expand the converter and collidated with the savepoint
    if( ! m_ExpandConverterWaitQueue.IsEmpty() )
        m_ExpandConverterWaitQueue.ResumeAllWaitingTasks( taskId );

    // resume all tasks suspended because a FBM overflow occured
    if( ! m_DBFullWaitQueue.IsEmpty() )
        m_DBFullWaitQueue.ResumeAllWaitingTasks( taskId );

    // At this time all relevant FBM blocks are set to free and therefore the 
    // database filling could be changed although no pages are requested or released.
    CheckFillingOfDataBase(); 

}

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

void
01063 Converter_Converter::GetPositionForWriting(
    const tsp00_TaskId          taskId,
    const Data_PageNo           &pageNo,
    const Data_PageRecoveryMode &pageRecoveryMode,
    const Converter_Version     &pageConverterVersion,
    const SAPDB_Bool            bReqSequential,
    IOMan_BlockAddress          &block )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::GetPositionForWriting", Converter_Trace, 5 );


    if( ! m_Active )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_INFO_SHUTDOWN );
        RTE_Message( errMsg );

        Kernel_IAdminRestartShutdown::Instance().Offline();
    }

    const SAPDB_Bool     bIsPerm = pageRecoveryMode.PageIsRecoverable();
    Converter_ReturnCode retCode;

    if(( pageConverterVersion == m_Version ) || ( pageConverterVersion.IsValid()  && ( ! bIsPerm )))
    {
        // the currently occupied block can be reused

        if( bIsPerm )
        {
            if( pageRecoveryMode.UseDynamicPageAddressing() )
                retCode = m_PermMapControl.GetBlockAddress( taskId, pageNo, block );
            else
                retCode = m_PermStaticMapControl.GetBlockAddress( taskId, pageNo, block );
        }
        else
            retCode = m_TempMapControl.GetBlockAddress ( taskId, pageNo, block );
    }
    else // old block is not reusable
    {
        SAPDBERR_ASSERT_STATE (pageConverterVersion.IsInvalid() || (pageConverterVersion < m_Version));

        if( bIsPerm )
        {
            if( pageRecoveryMode.UseDynamicPageAddressing() )
                retCode = m_PermMapControl.GetNewPositionForWrite( taskId, pageNo,
                          pageConverterVersion, m_SnapShotVersion, bReqSequential, block );
            else
                retCode = m_PermStaticMapControl.GetNewPositionForWrite( taskId, pageNo,
                          pageConverterVersion, m_SnapShotVersion, bReqSequential, block );
        }
        else
            retCode = m_TempMapControl.GetNewPositionForWrite( taskId, pageNo, bReqSequential, block );
    }

    if( Converter_Ok == retCode )
    {
        // At this time all relevant FBM blocks are set to free and therefore the 
        // database filling could be changed although no pages are requested or released.
        CheckFillingOfDataBase(); 
        return;
    }

    Converter_MapError mapError( __CONTEXT__ , pageRecoveryMode, pageNo, retCode );
    RTE_Crash( mapError );
}

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

Converter_ReturnCode
01131 Converter_Converter::GetPositionForReading(
    const tsp00_TaskId          taskId,
    const Data_PageNo           pageNo,
    const Data_PageRecoveryMode &pageRecoveryMode,
    IOMan_BlockAddress          &block )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::GetPositionForReading", Converter_Trace, 5 );

    if( ! m_Active )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_INFO_SHUTDOWN );
        RTE_Message( errMsg );

        Kernel_IAdminRestartShutdown::Instance().Offline();
    }

    if( pageRecoveryMode.PageIsRecoverable() )
    {
        if( pageRecoveryMode.UseDynamicPageAddressing() )
            return( m_PermMapControl.GetBlockAddress( taskId, pageNo, block ));
        else
            return( m_PermStaticMapControl.GetBlockAddress( taskId, pageNo, block ));
    }
    else
        return( m_TempMapControl.GetBlockAddress ( taskId, pageNo, block ));
}

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

void
01161 Converter_Converter::SetPositionForWriting(
    const tsp00_TaskId          taskId,
    const Converter_Version     &pageConverterVersion,
    const Data_PageNo           &pageNo,
    const Data_PageRecoveryMode &pageRecoveryMode,
    const IOMan_BlockAddress    &block )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::SetPositionForWriting", Converter_Trace, 5 );

    if( ! m_Active )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_INFO_SHUTDOWN );
        RTE_Message( errMsg );

        Kernel_IAdminRestartShutdown::Instance().Offline();
    }

    if( pageRecoveryMode.PageIsRecoverable() )
    {
        if( pageRecoveryMode.UseDynamicPageAddressing() )
            m_PermMapControl.SetPositionForWriting( taskId, m_Version, pageConverterVersion,
                                                    m_SnapShotVersion, pageNo, block );
        else
            m_PermStaticMapControl.SetPositionForWriting( taskId, m_Version, pageConverterVersion,
                    m_SnapShotVersion, pageNo, block );
    }
    else
        m_TempMapControl.SetPositionForWriting ( taskId, pageConverterVersion, pageNo, block );

    // At this time all relevant FBM blocks are set to free and therefore the 
    // database filling could be changed although no pages are requested or released
    CheckFillingOfDataBase(); 
}

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

SAPDB_Bool
01198 Converter_Converter::RequestSpecificiedNewStaticPageNo(
    const tsp00_TaskId  taskId,
    const Data_PageNo   pageNo )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::RequestSpecificiedNewStaticPageNo", Converter_Trace, 5 );

    // PTS 1116298 UH 2002-06-21
    // Added the wait interface and the loop because RequestSpecifiedNewPageNo()
    // has to wait for a savepoint.
    // It may happen that there exists a pending Free for the requested pageno.

    SAPDB_Bool                          bWaitUntilSavepointFinished = SAPDB_FALSE;
    Converter_WaitQueue::WaitContext    waitContext;

    do
    {
        if( ! m_Active )
        {
            Converter_Exception errMsg( __CONTEXT__, CONVERTER_INFO_SHUTDOWN );
            RTE_Message( errMsg );

            Kernel_IAdminRestartShutdown::Instance().Offline();
        }

        if( ! m_PermStaticMapControl.RequestSpecifiedNewPageNo( taskId, pageNo,
                waitContext, m_FreePageNoWaitQueue, bWaitUntilSavepointFinished ))
        {
            // means that the page no is in use
            SAPDBTRACE_WRITELN( Converter_Trace, 5, "PageNo: " <<  pageNo << "not available" );
            return( SAPDB_FALSE );
        }

        if( bWaitUntilSavepointFinished )
            m_FreePageNoWaitQueue.Wait( taskId );
    }
    while( bWaitUntilSavepointFinished );

    m_NumPermPagesUsed.Increment();
    CheckFillingOfDataBase ();

    SAPDBTRACE_WRITELN( Converter_Trace, 7, "PermPagesUsed: " << m_NumPermPagesUsed );
    return( SAPDB_TRUE );
}

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

SAPDB_Bool
01245 Converter_Converter::FreeTempPageNo(
    const tsp00_TaskId  taskId,
    const Data_PageNo   pageNo )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::FreeTempPageNo", Converter_Trace, 5 );

    SAPDBTRACE_WRITELN( Converter_Trace, 5, "Free temp PageNo: " << pageNo );

    if( ! m_Active )
        return( SAPDB_FALSE );

    m_TempMapControl.FreePageNo( taskId, pageNo );

    m_NumTempPagesUsed.Decrement();
    SAPDBTRACE_WRITELN( Converter_Trace, 7, "TempPagesUsed: " << m_NumTempPagesUsed );

    CheckFillingOfDataBase();

    if( ! m_DBFullWaitQueue.IsEmpty() ){
        m_DBFullWaitQueue.ResumeAllWaitingTasks( taskId );
    }
    return( SAPDB_TRUE );
}

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

void
01272 Converter_Converter::HandleDBFull (
    tgg00_TransContext  &Trans,
    SAPDB_UInt          NumDataPagesRequested)
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::HandleDBFull", Converter_Trace, 6 );

    tgg00_BasisError    &trError = Trans.trError_gg00;

    NumDataPagesRequested += CONV_NUM_SECURITY_PAGES; // add some pages for security reasons

    while (m_Active)
    {
        const SAPDB_Int4 numChangedPages  = NumChangedPages();
        //const SAPDB_Bool pageNosExhausted = GetNumberOfUsedPages() + NumDataPagesRequested >= GetNumberOfAllPages();
        // PTS 1124331 TS 2003-09-23
        const SAPDB_Bool pageNosExhausted = ! IsSpaceAvailable( NumDataPagesRequested );
        const SAPDB_Bool blocksExhausted  = ! FBM_IManager::Instance().IsSpaceAvailable( numChangedPages + NumDataPagesRequested );

        if( ! pageNosExhausted && ! blocksExhausted )
            return; // comman way to leave this method

        if( blocksExhausted && SavepointIsPossible() && FBM_IManager::Instance().FreeAfterSVPExist() )
            StartSavepoint( Trans, numChangedPages ); // Do not check necessity of SVP

        if(( m_IsLiveCacheInstance ) && ( ! SavepointNeeded() ))
            bd91StartOMSGarbageCollection( Trans, false );

        if( ! TransactionIsSuspendable( Trans ))
            return; // the task is qualified to proceed with his job

        const SAPDB_Bool bAddVolumeIsPossible = IOMan_IDataInfo::GetInstance().AddDataVolumePossible();
        const SAPDB_Bool bIsRollback          = Trans.trState_gg00.includes( tsRollback_egg00 );

        if
        (
            (
                (
                    (SAPDB_UInt(Trans.trTempCount_gg00) > m_NumTempPagesUsed/20) &&
                    (m_NumTempPagesUsed                 > m_NumAllPages/100    ) &&
                    (SAPDB_UInt(Trans.trTempCount_gg00) > 100                  )
                )
                ||
                ( ! bAddVolumeIsPossible )
            )
            &&
            ( ! bIsRollback )
        )
        {
            trError = e_no_more_temp_space; // force rollback but do not suspend task

            if (! bAddVolumeIsPossible)
            {
                Converter_Exception errMsg (__CONTEXT__, CONVERTER_NO_ADD_DATA_DEVICE,
                                            SAPDB_ToString( Trans.trTaskId_gg00, _T_d ));
                RTE_Message( errMsg );
            }
            else
            {
                Converter_Exception errMsg(__CONTEXT__,CONVERTER_FORCE_ROLLBACK_DUE_TO_DB_FULL,
                                           SAPDB_ToString( Trans.trTaskId_gg00, _T_d ),
                                           SAPDB_ToString(m_NumAllPages, _T_d),
                                           SAPDB_ToString(m_NumTempPagesUsed, _T_d),
                                           SAPDB_ToString(Trans.trTempCount_gg00, _T_d));
                RTE_Message( errMsg );
            }
            return;
        }

        if( blocksExhausted )
        {
            Converter_Exception errMsg( __CONTEXT__,CONVERTER_SUSPEND_TASK_DUE_TO_FBM_FULL,
                                        SAPDB_ToString( Trans.trTaskId_gg00, _T_d ),
                                        SAPDB_ToString( numChangedPages + NumDataPagesRequested, _T_d ),
                                        SAPDB_ToString( FBM_IManager::Instance().GetNumberOfUsedBlocks(), _T_d ),
                                        SAPDB_ToString( FBM_IManager::Instance().GetNumberOfFreeBlocks(), _T_d ));
            RTE_Message( errMsg );

            SAPDBTrace_Stream   traceStream( &Converter_Trace.GetTracePrinter() );

            traceStream << "*** " << errMsg.DateTime( SAPDB_TRUE ) << " "
            << errMsg.Type( SAPDB_TRUE ) << " "
            << errMsg.ID() << " "
            << errMsg.Component() << " " << NewLine
            << "*** " << errMsg.Message() << NewLine;
        }
        else // pageNosExhausted
        {
            Converter_Exception errMsg( __CONTEXT__,CONVERTER_SUSPEND_TASK_DUE_TO_DB_FULL,
                                        SAPDB_ToString( Trans.trTaskId_gg00, _T_d ),
                                        SAPDB_ToString( GetNumberOfUsedPages(), _T_d ),
                                        SAPDB_ToString( NumDataPagesRequested, _T_d ),
                                        SAPDB_ToString( GetNumberOfAllPages(), _T_d ));
            RTE_Message( errMsg );

            SAPDBTrace_Stream   traceStream( &Converter_Trace.GetTracePrinter() );

            traceStream << "*** " << errMsg.DateTime( SAPDB_TRUE ) << " "
            << errMsg.Type( SAPDB_TRUE ) << " "
            << errMsg.ID() << " "
            << errMsg.Component() << " " << NewLine
            << "*** " << errMsg.Message() << NewLine;
        }

        m_DBFullWaitQueue.InsertTaskAndWait( Trans.trTaskId_gg00 );

        if(( Trans.trRteCommPtr_gg00->to_cancel ) && ( ! bIsRollback ))
        {
            Converter_Exception errMsg( __CONTEXT__,CONVERTER_INFO_CANCELLED_DURING_DB_FULL,
                                        SAPDB_ToString( Trans.trTaskId_gg00, _T_d ));
            RTE_Message( errMsg );

            SAPDBTrace_Stream   traceStream( &Converter_Trace.GetTracePrinter() );

            traceStream << "*** " << errMsg.DateTime( SAPDB_TRUE ) << " "
            << errMsg.Type( SAPDB_TRUE ) << " "
            << errMsg.ID() << " "
            << errMsg.Component() << " " << NewLine
            << "*** " << errMsg.Message() << NewLine;

            trError  = e_cancelled;
            return;
        }
    }
    if( ! m_Active )
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_INFO_SHUTDOWN );
        RTE_Message( errMsg );

        Kernel_IAdminRestartShutdown::Instance().Offline();
    }

    return;
}

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

void
01409 Converter_Converter::BeginColdVerify( const tsp00_TaskId    taskId )
{
    SAPDBERR_ASSERT_STATE (! BackUpIsActive());
    SAPDBERR_ASSERT_STATE (false == m_ColdVerifyIsActive);
    SAPDBERR_ASSERT_STATE (0     == m_NumStatConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumDynConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumPagesForBackUp);

    m_InMaintenanceMode  = true;
    m_ColdVerifyIsActive = true;

    m_PermMapControl.InitializeBackUpPageNoList( taskId );
    m_PermStaticMapControl.InitializeBackUpPageNoList( taskId );
}

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

void
01427 Converter_Converter::EndColdVerify(
    const tsp00_TaskId  taskId,
    Data_PageCount      &NumStaticPermDataPages,
    Data_PageCount      &NumDynamicPermDataPages,
    Data_PageCount      &NumPermConvPages,
    Data_PageCount      &NumReleaseBlocks )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::EndColdVerify", Converter_Trace, 5 );

    SAPDBERR_ASSERT_STATE (! BackUpIsActive());
    SAPDBERR_ASSERT_STATE (true == m_ColdVerifyIsActive);
    SAPDBERR_ASSERT_STATE (0     == m_NumStatConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumDynConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumPagesForBackUp);

    SAPDB_UInt NumPermStaticConvPages   = 0;
    SAPDB_UInt NumPermDynamicConvPages  = 0;
    SAPDB_UInt NumStaticTempDataPages   = 0;
    SAPDB_UInt NumDynamictempDataPages  = 0;
    SAPDB_UInt numStaticReleasedBlocks  = 0;
    SAPDB_UInt numDynamicReleasedBlocks = 0;

    m_PermStaticMapControl.ReleaseUnusedPageNos( taskId, m_SnapShotVersion,
            NumStaticPermDataPages, NumPermStaticConvPages, numStaticReleasedBlocks );

    m_PermMapControl.ReleaseUnusedPageNos( taskId, m_SnapShotVersion,
                                           NumDynamicPermDataPages, NumPermDynamicConvPages,
                                           numDynamicReleasedBlocks );

    NumPermConvPages = NumPermStaticConvPages + NumPermDynamicConvPages;
    NumReleaseBlocks = numStaticReleasedBlocks + numDynamicReleasedBlocks;

    m_NumPermPagesUsed = NumStaticPermDataPages + NumDynamicPermDataPages;

    m_PermStaticMapControl.ClearBackUpPageNoList();
    m_PermMapControl.ClearBackUpPageNoList();

    m_ColdVerifyIsActive = false;
    m_InMaintenanceMode  = false;
}

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

void
01471 Converter_Converter::EndFailedColdVerify ( const tsp00_TaskId  taskId )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::EndFailedColdVerify", Converter_Trace, 5 );

    SAPDBERR_ASSERT_STATE (! BackUpIsActive());
    SAPDBERR_ASSERT_STATE (true == m_ColdVerifyIsActive);
    SAPDBERR_ASSERT_STATE (0     == m_NumStatConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumDynConvPagesForBackUp);
    SAPDBERR_ASSERT_STATE (0     == m_NumPagesForBackUp);

    m_PermStaticMapControl.EndFailedColdVerify( taskId );
    m_PermMapControl.EndFailedColdVerify( taskId );

    m_ColdVerifyIsActive = false;
}

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

void
01490 Converter_Converter::GetDbSpaceStatistics(
    const tsp00_TaskId  taskId,
    tgg00_DbSpaceInfo   &dbSpaceInfo )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::GetDbSpaceStatistics", Converter_Trace, 5 );

    dbSpaceInfo.db_total_pages    = IOMan_IDataInfo::GetInstance().TotalDataPages();
    dbSpaceInfo.db_perm_pages     = IOMan_IDataInfo::GetInstance().TotalDataPages();
    dbSpaceInfo.db_real_perm_used = m_NumPermPagesUsed + m_NumPermConvPages;
    dbSpaceInfo.db_perm_percent   = (tsp00_Int2)((dbSpaceInfo.db_real_perm_used * 100.0)/dbSpaceInfo.db_total_pages);
    dbSpaceInfo.db_temp_pages     = m_NumTempPagesUsed;
    dbSpaceInfo.db_temp_percent   = (tsp00_Int2)((m_NumTempPagesUsed*100.0)/dbSpaceInfo.db_total_pages);
    dbSpaceInfo.db_used_pages     = GetNumberOfUsedPages();
    dbSpaceInfo.db_updated_pages  = UpdatedPagesSinceLastSaveData( taskId );
    dbSpaceInfo.db_max_perm_used  = GetPeakForPermPages();
    dbSpaceInfo.db_used_blocks    = FBM_IManager::Instance().GetNumberOfUsedBlocks();
}

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

SAPDB_Bool
01511 Converter_Converter::IsDBFull( const tsp00_TaskId taskId ) const
{
    if( ! m_DBFullWaitQueue.IsEmpty())
        return( SAPDB_TRUE ); // task is suspended because of db full

    const SAPDB_UInt numDataPagesRequested = CONV_NUM_SECURITY_PAGES * 2;// see HandledbFull

    // PTS 1124331 TS 2003-09-23
    if( ! IsSpaceAvailable( numDataPagesRequested ))
        return( SAPDB_TRUE ); // pageNos exhausted

    //if( GetNumberOfUsedPages() + numDataPagesRequested >= GetNumberOfAllPages())
    //    return( SAPDB_TRUE ); // pageNos exhausted

    if( ! FBM_IManager::Instance().IsSpaceAvailable( NumChangedPages() + numDataPagesRequested ))
        return( SAPDB_TRUE ); // blocks in FBM exhausted

    return( SAPDB_FALSE );
}

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

SAPDB_Bool
01534 Converter_Converter::SecuritySpaceReached() const
{
    // PTS 1124331 TS 2003-09-23

    if( ! IsSpaceAvailable( CONV_NUM_SECURITY_PAGES ))
        return( SAPDB_TRUE );

    if( ! FBM_IManager::Instance().IsSpaceAvailable( NumChangedPages()))
        return( SAPDB_TRUE );

    return( SAPDB_FALSE );
}

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

Converter_GarbageCollectionReturnCode
01550 Converter_Converter::GarbageCollectionNeeded() const // PTS 1116157 FF 2002-06-14
{
    if( ! SavepointIsPossible() )
        return( Converter_GCNotWanted );

    if( SavepointNeeded() ) // Savepoint will come immediately started by TimeOut Task
        return( Converter_GCNotWanted );

    // data base is filled up to 90 percent inclusive the changed pages of the data cache

    if( FBM_IManager::Instance().GarbageCollectionNeeded( NumChangedPages() ))
        return( Converter_GCNeeded );
    else
        return( Converter_GCNotNeeded );
}

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

void
01569 Converter_Converter::StartSavepoint( tgg00_TransContext &trans )
{
    if( ! SavepointNeeded() )
        return;

    StartSavepoint( trans, NumChangedPages() );
}

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

SAPDB_Bool
01580 Converter_Converter::SavepointNeeded() const
{
    if( ! SavepointIsPossible() )
        return( false );

    if( FBM_IManager::Instance().SavepointNeeded() ) // more blocks in state free after SVP than free
        return( true );

    if( NumChangedPages() > (( FBM_IManager::Instance().GetNumberOfFreeBlocks()) / 3 ))
        return( true );

    return( false );
}

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

void
01597 Converter_Converter::Dump(
    const tsp00_TaskId  TaskId,
    Kernel_Dump         &Dump,
    const SAPDB_Bool    bEnterRegion )
{
    struct ConverterManager   CM;

    CM.dmpVersion                         = m_Version;
    CM.dmpNumPermPagesUsed                = m_NumPermPagesUsed;
    CM.dmpNumTempPagesUsed                = m_NumTempPagesUsed;
    CM.dmpNumAllPages                     = m_NumAllPages;
    CM.dmpDeltaSnapShotPages              = m_NumSnapShotPages;
    CM.dmpNumPagesForBackup               = m_NumPagesForBackUp;
    CM.dmpNumStatConvPagesForBackup       = m_NumStatConvPagesForBackUp;
    CM.dmpNumDynConvPagesForBackup        = m_NumDynConvPagesForBackUp;
    CM.dmpNumPermConvPages                = m_NumPermConvPages;
    CM.dmpNumTempConvPages                = m_NumTempConvPages;
    CM.dmpMapBlockingSize                 = m_MapBlockingSize;
    CM.dmpConverterIsActive               = m_Active;
    CM.dmpSavePagesIsActive               = m_SavePagesIsActiv;
    CM.dmpSaveDataIsActive                = m_SaveDataIsActiv;
    CM.dmpRestoreDataIsActive             = m_RestoreDataActive;
    CM.dmpRestorePagesIsActive            = m_RestorePagesActive;
    CM.dmpColdVerifyIsActive              = m_ColdVerifyIsActive;
    CM.dmpLastSaveDataSuccessful          = m_LastSaveDataSuccessful;

    if( m_RootBlockAddress.IsValid() )
    {
        CM.dmpRootDevNo   = m_RootBlockAddress.GetDeviceNo();
        CM.dmpRootBlockNo = m_RootBlockAddress.GetBlockNo();
    }
    else
    {
        CM.dmpRootDevNo   = IOMan_DeviceNo();
        CM.dmpRootBlockNo = IOMan_BlockNo();
    }

    Dump.InsertEntry( Kernel_Dump::DmpConverterManager, Kernel_DumpPage::Entry( &CM, sizeof( CM )));

    m_Index.Dump( Dump );

    m_TempMapControl.Dump( TaskId, Dump, bEnterRegion );
    m_PermMapControl.Dump( TaskId, Dump, bEnterRegion );
    m_PermStaticMapControl.Dump( TaskId, Dump, bEnterRegion );
}

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

void
01646 Converter_Converter::SetBlockAddressForMigratedPage (
    const tsp00_TaskId          taskId,
    const IOMan_BlockAddress    &block,
    const Data_PageNo           &pageNo,
    const SAPDB_Bool            bSetToOccupied )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::SetBlockAddressForMigratedPage", Converter_Trace, 5 );

    SAPDBERR_ASSERT_STATE( m_RestoreDataActive );

    // At this time the corresponding converter page entry is invalid (initialized),
    // because the converter is build up the current migration step.

    m_PermMapControl.SetBlockAddressOfRestoredPage(
        taskId, pageNo, m_SnapShotVersion, block, m_RestoreDataActive);

    m_NumPermPagesUsed.Increment();

    CheckFillingOfDataBase();

    if( SAPDB_TRUE != bSetToOccupied )
        return;

    // After updating the converter page entry, the block is set to occupied within
    // the FBM. Note that the given block must not specify one of the reserved blocks
    // in the data volumes.

    if( SAPDB_TRUE != FBM_IManager::Instance().SetBlockStateToOccupied( taskId, block ))
    {
        Converter_Exception errMsg( __CONTEXT__, CONVERTER_BAD_ENTRY_STATE,
                                    "permanent", SAPDB_ToString( pageNo, _T_d ));
        RTE_Crash( errMsg );
    }
}

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

IOMan_BlockAddress
01684 Converter_Converter::DetermineAndSetBlockAddressForMigratedPage(
    const tsp00_TaskId  taskId,
    const Data_PageNo   &pageNo )
{
    const SAPDB_Bool         bSetToOccupied = SAPDB_FALSE;
    const SAPDB_Bool         bReqSequential = SAPDB_FALSE;
    const IOMan_BlockAddress newBlock       = FBM_IManager::Instance().GetFreeBlock( taskId , bReqSequential );

    // Note that the newBlock is set to occupied by the GetFreeBlock
    // method and therefore not set again to occupupied by the subsequent call.

    SetBlockAddressForMigratedPage( taskId, newBlock, pageNo, bSetToOccupied );

    return( newBlock );
}

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

SAPDB_Bool
01703 Converter_Converter::DeleteBlockAddress(
    const tsp00_TaskId          taskId,
    const Data_PageNo           &pageNo,
    const Data_PageRecoveryMode &recMode )
{
    SAPDBERR_ASSERT_STATE( m_Active );

    IOMan_BlockAddress          block;
    Converter_ReturnCode        retCode;
    const Data_AddressingMode   addrMode = recMode.GetAddressingMode();

    if( ! recMode.PageIsRecoverable())
        return( SAPDB_TRUE );
    
    if( Data_Dynamic == addrMode ){
        retCode = m_PermMapControl.GetBlockAddress( taskId, pageNo, block );
    }
    else if( Data_Static == addrMode ){
        retCode = m_PermStaticMapControl.GetBlockAddress( taskId, pageNo, block );
    }
    else{
        retCode = Converter_NoConverterEntry;
    }

    if( Converter_Ok != retCode )
        return( SAPDB_FALSE );
    
    Converter_Version  pageConverterVersion; // dummy version, not used in this case
    
    pageConverterVersion.SetToInitialVersion(); // set to a defined value, which will not influence the execution
    
    if( Data_Dynamic == addrMode )
        return( FreePermDynamicPageNo( taskId, pageNo, pageConverterVersion ));
    else
        return( FreePermStaticPageNo( taskId, pageNo, pageConverterVersion ));
}

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

SAPDB_Bool
01743 Converter_Converter::GetBlockAddress(
    const tsp00_TaskId          taskId,
    const Data_PageNo           &pageNo,
    const Data_PageRecoveryMode &recMode,
    IOMan_BlockAddress          &block )
{
    SAPDBERR_ASSERT_STATE( m_Active );

    Converter_ReturnCode        retCode;
    const Data_AddressingMode   addrMode = recMode.GetAddressingMode();

    if( Data_Dynamic == addrMode )
    {
        if( recMode.PageIsRecoverable())
            retCode = m_PermMapControl.GetBlockAddress( taskId, pageNo, block );
        else
            retCode = m_TempMapControl.GetBlockAddress( taskId, pageNo, block );
    }
    else if( Data_Static == addrMode ){
        retCode = m_PermStaticMapControl.GetBlockAddress( taskId, pageNo, block );
    }
    else{
        retCode = Converter_NoConverterEntry;
    }

    if( Converter_Ok == retCode )
        return( SAPDB_TRUE );

    block.Invalidate();

    return( SAPDB_FALSE );
}

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

SAPDB_Bool
01779 Converter_Converter::SetNewBlockAddress(
    const tsp00_TaskId          taskId,
    const Data_PageNo           &pageNo,
    const Data_PageRecoveryMode &recMode,
    const IOMan_BlockAddress    &blockAddr )
{
    SAPDBERR_ASSERT_STATE( m_Active );
    
    if( ! recMode.PageIsRecoverable())
        return( SAPDB_TRUE );
    
    if( recMode.UseStaticPageAddressing() )
        m_PermStaticMapControl.SetBlockAddressOfRestoredPage(
        taskId, pageNo, m_SnapShotVersion, blockAddr, m_RestoreDataActive );
    else
        m_PermMapControl.SetBlockAddressOfRestoredPage(
        taskId, pageNo, m_SnapShotVersion, blockAddr, m_RestoreDataActive );
    
    return( SAPDB_TRUE );
}

//----------------------------------------------------------------------------
//  private methods
//----------------------------------------------------------------------------

void
01805 Converter_Converter::InitializeBase( const SAPDB_UInt NumAllPages )
{
    m_SnapShotVersion.Invalidate();
    m_SnapShotCreationTimeStamp.Invalidate();

    m_NumPermPagesUsed                 = 0;
    m_NumTempPagesUsed                 = 0;
    m_NumPagesForBackUp                = 0;
    m_NumStatConvPagesForBackUp        = 0;
    m_NumDynConvPagesForBackUp         = 0;
    m_NumPermConvPages                 = 0;
    m_NumTempConvPages                 = 0;
    m_NumSnapShotPages                 = 0;
    m_TemporaryPeakFilling             = 0;
    m_PermanentPeakFilling             = 0;
    m_MaxUsedDynamicPageNo             = 0;
    m_MaxUsedStaticPageNo              = 0;
    m_NumAllPages                      = NumAllPages;
    // PTS 1124331 TS 2003-09-23
    m_SecuritySpaceLimit               = ( m_NumAllPages - SAPDB_MIN( m_NumAllPages/25, 4000));
    m_Active                           = true;
    m_InMaintenanceMode                = false;
    m_SavePagesIsActiv                 = false;
    m_SaveDataIsActiv                  = false;
    m_RestoreDataActive                = false;
    m_RestorePagesActive               = false;
    m_ColdVerifyIsActive               = false;
    m_LastSaveDataSuccessful           = true;
    m_DBUsageMonitor.Rescale (m_NumAllPages);
}

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

SAPDB_Bool
01839 Converter_Converter::ExpandMap(
    const tsp00_TaskId           taskId,
    const Data_PageRecoveryMode  &recoveryMode,
    const SAPDB_UInt             numPagesAdded )
{
    Converter_WaitQueue::WaitContext    waitContext;
    Converter_ReturnCode                retCode;
    const SAPDB_UInt                    newAllPages = m_NumAllPages + numPagesAdded;

    do
    {
        if( recoveryMode.PageIsRecoverable() )
        {
            if( recoveryMode.UseDynamicPageAddressing() ){
                retCode = m_PermMapControl.Expand( taskId, newAllPages,
                                                   waitContext, m_ExpandConverterWaitQueue );
            }
            else{
                retCode = m_PermStaticMapControl.Expand( taskId, newAllPages,
                          waitContext, m_ExpandConverterWaitQueue );
            }
        }
        else{
            retCode = m_TempMapControl.Expand( taskId, newAllPages );
        }


        switch( retCode )
        {
        case Converter_Ok:
            return( SAPDB_TRUE );
        case Converter_SavePointActive:
            m_ExpandConverterWaitQueue.Wait( taskId );
            break;
        default:
            {
                Converter_Exception ExpandFailed(__CONTEXT__,CONVERTER_EXPAND_FAILED,
                                                 SAPDB_ToString( m_NumAllPages, _T_d) ,
                                                 SAPDB_ToString( newAllPages, _T_d ));
                RTE_Message( ExpandFailed );
            }
            return( SAPDB_FALSE );
        }
    }
    while( m_Active );

    return( SAPDB_FALSE );
}

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

SAPDB_Bool
01891 Converter_Converter::FreePermPageNo(
    const tsp00_TaskId          taskId,
    Converter_PermMapControl    &mapControl,
    const Data_PageNo           pageNo,
    const Converter_Version     &pageConverterVersion )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::FreePermPageNo", Converter_Trace, 5 );

    SAPDBTRACE_WRITELN( Converter_Trace, 5, "Free perm PageNo: " << pageNo );

    if( ! m_Active ){
        return( SAPDB_FALSE );
    }

    SAPDB_Bool  bWaitUntilSavepointFinished  = false;
    SAPDB_Bool  bOldBlockIsUsableImmediately = false;
    SAPDB_Bool  bDoDecrementPermUseCount     = true;

    do
    {
        Converter_WaitQueue::WaitContext    waitContext;

        mapControl.FreePageNo( taskId, pageConverterVersion, m_SnapShotVersion, pageNo,
                               waitContext, m_FreePageNoWaitQueue, bWaitUntilSavepointFinished,
                               bOldBlockIsUsableImmediately, bDoDecrementPermUseCount );

        if( bWaitUntilSavepointFinished )
        {
            m_FreePageNoWaitQueue.Wait( taskId );

            if( ! m_Active ){
                return( SAPDB_FALSE );
            }
        }
    }
    while( bWaitUntilSavepointFinished );

    if( bDoDecrementPermUseCount )
        m_NumPermPagesUsed.Decrement();

    SAPDBTRACE_WRITELN( Converter_Trace, 7, "PermPagesUsed: " << m_NumPermPagesUsed );

    CheckFillingOfDataBase();

    if(( bOldBlockIsUsableImmediately ) && ( ! m_DBFullWaitQueue.IsEmpty() )){
        m_DBFullWaitQueue.ResumeAllWaitingTasks( taskId );
    }
    return( SAPDB_TRUE );
}

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

void
01944 Converter_Converter::StartSavepoint(
    tgg00_TransContext &trans,
    const SAPDB_Int4    numChangedPages )
{
    Converter_Exception errMsg( __CONTEXT__, CONVERTER_SAVEPOINT_NEEDED,
                                SAPDB_ToString( numChangedPages, _T_d ),
                                SAPDB_ToString( FBM_IManager::Instance().GetNumberOfUsedBlocks(), _T_d ),
                                SAPDB_ToString( FBM_IManager::Instance().GetNumberOfFreeBlocks(), _T_d ));
    RTE_Message( errMsg );

    Log_SavepointManager.StartSavepoint( trans, Log_SVPReasonConverter );
}

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

void
01960 Converter_Converter::RestartSnapShot(
    const tsp00_TaskId              taskId,
    const IOMan_PackedBlockAddress  &packedSnapShotRootBlock )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::RestartSnapShot", Converter_Trace, 6 );

    SAPDBERR_ASSERT_STATE( NULL == m_VolumeList );

    const SAPDB_Bool            bReadSnapShot     = SAPDB_TRUE;
    const IOMan_BlockAddress    snapShotRootBlock = packedSnapShotRootBlock.Unpack( m_VolumeNoBitCount );
    Converter_SnapShotPager     pager( taskId, m_SnapShotVersion, m_Index );
    Converter_Index             snapShotIndex( m_Allocator);
    VolumeList                  volumeList( m_Allocator );

    SAPDBERR_ASSERT_STATE( snapShotRootBlock.IsValid());

    snapShotIndex.Restart( snapShotRootBlock, pager );

    SAPDBERR_ASSERT_STATE( snapShotIndex.Verify());

    snapShotIndex.CreateInputQueues( volumeList, m_PageSize );

    m_VolumeList = &volumeList; // is used by the pager tasks

    Pager_IRestart::GetInstance().ReadConverter( taskId, bReadSnapShot );

    m_VolumeList = NULL;

    volumeList.Delete(); // free occupied memory

    snapShotIndex.Shutdown();
}

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

SAPDB_Int4
01996 Converter_Converter::NumChangedPages() const
{
    return( bd20GetNumberOfChangedPages() + GetNumberOfChangedConvPages());
}

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

SAPDB_Bool
02004 Converter_Converter::IsLeafPageMember(
    const tsp00_TaskId        taskId,
    const Converter_LeafPage  &page )
{
    SAPDBTRACE_ROUTINE_DEBUG( "Converter::IsLeafPageMember", Converter_Trace, 7 );


    const Data_PageRecoveryMode recMode    = page.ReadPageRecoveryMode();
    const Data_PageNo           basePageNo = page.ReadBasePageNo();
    const IOMan_BlockAddress    block      = page.ReadBlockAddress();

    if( recMode.UseDynamicPageAddressing())
        return( m_PermMapControl.IsMember( taskId, basePageNo, block ));

    if( recMode.UseStaticPageAddressing())
        return(m_PermStaticMapControl.IsMember( taskId, basePageNo, block ));

    return( SAPDB_FALSE );
}

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

Generated by  Doxygen 1.6.0   Back to index