/*!
  @file     Converter_Wrapper.cpp
  @author   TorstenS
  @author   AlexanderK
  @ingroup  Converter
  @brief    Wrapper of the Converter
*/

/*
    ========== licence begin  GPL
    Copyright (c) 2001-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 "ggg00.h"
#include "gbd00.h"
#include "gkb00.h"
#include "hbd10.h"
#include "hgg01.h"
#include "hgg01_3.h"

#include "Converter/Converter_Converter.hpp"

#include "IOManager/IOMan_BlockAddress.hpp"
#include "IOManager/IOMan_IDataIO.hpp"

#include "DataAccess/Data_Types.hpp"

#include "FrameControl/FrameCtrl_IRestartPage.hpp"

#include "KernelCommon/Kernel_RestartPage.hpp"
#include "KernelCommon/Kernel_DateTime.hpp"

#include "FreeBlockManagement/FBM_IManager.hpp"



/*===========================================================================*
 *  LOCAL FUNCTIONS                                                          *
 *===========================================================================*/

inline void
bd10_SnapShotHandling(
    const tsp00_TaskId       taskId,
    const SAPDB_UInt4        pascalSnapShotRestartAddr,
    IOMan_PackedBlockAddress &packedSnapShotRootBlockAddr,
    Converter_Version        &snapShotVersion,
    Kernel_DateTime          &snapShotCreationTimeStamp );

/*===========================================================================*
 *  GLOBAL FUNCTIONS                                                         *
 *===========================================================================*/

/// instance creation
externC void
bd10CreateConverterSingleton ()
{
    Converter_Converter::CreateInstance();
}

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

/*!
       @brief          Creates converter for restarting an existing database
       @param          TaskId [in] own TaskId
       @param          ConverterVersion [in] converter version from restart record
       @param          NumAllPages [in] maximum number of pages which can be stored in the data base. this
                       corresponds to the sum of size of all devices
       @param          IncrementConvVersion [in] indicates whether version must be
                       incremented after the restart
       @param          LastSaveDataSuccessful [in] indicates whether the last save data finished successfully
       @param          RestartParam [in] aggregation of restart parameters
       @return         none

       - The internal structures of the converter are created.
       - Converter pages are read from devices. The converter root
         page can be found at address 'rootaddr'.
       - The parameters 'MaxDynamicPageNo', 'MaxStaticPageNo' and  'NumAllPages'
         are used to determine the initial size of the  converter.
       - 'ConverterVersion' is the converter version of the database to be
         recovered. If 'bIncConverterVersion' is true, the converter version
         is incremented after a successful restart.
*/
externPascal void b10rc_restart_converter (
    tsp00_TaskId             TaskId,
    tsp00_Int4               ConverterVersion,
    tsp00_Int4               NumAllPages,
    pasbool                  IncrementConvVersion,
    pasbool                  LastSaveDataSuccessful,
    tkb00_ConfigRestartParam  &  RestartParam)
{
    const IOMan_PackedBlockAddress  packedRootBlockAddr( RestartParam.crConvRootBlockAddr_kb00 );

    // if a converter snapshot exist the values for the snapShot
    // converter version and the root of the snapshot converter
    // tree is stored within the frozen restart page

    IOMan_PackedBlockAddress  packedSnapShotRootBlockAddr;
    Converter_Version         snapShotVersion;
    Kernel_DateTime           snapShotCreationTimeStamp;

    if( 0 != RestartParam.crSnapShotRestartRecordAddr_kb00 )
    {
        bd10_SnapShotHandling( TaskId, RestartParam.crSnapShotRestartRecordAddr_kb00,
                               packedSnapShotRootBlockAddr, snapShotVersion,
                               snapShotCreationTimeStamp );
    }

    Converter_IManager::Instance().Restart( TaskId, ConverterVersion, packedRootBlockAddr,
                                            snapShotVersion, packedSnapShotRootBlockAddr,
                                            snapShotCreationTimeStamp, IncrementConvVersion,
                                            LastSaveDataSuccessful,
                                            RestartParam.crMaxDynamicPno_kb00,
                                            RestartParam.crMaxStaticPno_kb00, NumAllPages );
}

/*---------------------------------------------------------------------------*/
/*!
   @brief          Restart the converter for restore pages.
   @param          Trans [in] own Trans Context
   @param          ConverterVersion [in] converter version from restart record
   @param          NumAllPages [in] maximum number of pages which can be stored in the data base. this
                   corresponds to the sum of size of all devices
   @param          bLastSaveDataSuccessful [in] indicates whether the last save data finished successfully
   @param          RestartParam [in] aggregation of restart parameters
   @param          OldRestartParam [in] aggregation of old restart parameters
   @return         none

   - The internal structures of the converter are restarted
   - Converter pages are read from devices. The converter root
     page can be found at address 'rootaddr'.
   - The parameters 'MaxDynamicPageNo', 'MaxStaticPageNo' and
     'NumAllPages' are used to determine the initial size of
     the converter.
   - 'ConverterVersion' is the converter version of the database
     to be recovered. If 'bIncConverterVersion' is true, the converter
     version is incremented after a successful restart.
 */
externC void
b10restart_converter_for_restore (
    tgg00_TransContext        &Trans,
    tsp00_Int4                 ConverterVersion,
    tsp00_Int4                 NumAllPages,
    tsp00_Bool                 bLastSaveDataSuccessful,
    tkb00_ConfigRestartParam  &RestartParam,
    tkb00_ConfigRestartParam  &OldRestartParam)
{
    const IOMan_PackedBlockAddress packedRootBlockAddr (OldRestartParam.crConvRootBlockAddr_kb00);

    IOMan_PackedBlockAddress    packedSnapShotRootBlockAddr;
    Converter_Version           snapShotVersion;
    Kernel_DateTime             snapShotCreationTimeStamp;

    if( 0 != OldRestartParam.crSnapShotRestartRecordAddr_kb00 )
    {
        bd10_SnapShotHandling( Trans.trTaskId_gg00, OldRestartParam.crSnapShotRestartRecordAddr_kb00,
                               packedSnapShotRootBlockAddr, snapShotVersion, snapShotCreationTimeStamp );
    }

    Converter_IManager::Instance().RestartForRestore( Trans.trTaskId_gg00, ConverterVersion,
            packedRootBlockAddr, snapShotVersion, packedSnapShotRootBlockAddr, snapShotCreationTimeStamp,
            bLastSaveDataSuccessful, SAPDB_MAX (RestartParam.crMaxDynamicPno_kb00, OldRestartParam.crMaxDynamicPno_kb00),
            SAPDB_MAX (RestartParam.crMaxStaticPno_kb00,  OldRestartParam.crMaxStaticPno_kb00),
            NumAllPages );

    Converter_IBackUp::Instance().BeginRestoreUsedPageNos();
}

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

/*!
   @brief          Creates an empty converter for a new data base (needed for activate serverdb)
   @param          TaskId [in] task id
   @param          NumAllPages [in] maximum number of pages which can be stored in the data base.
                   this corresponds to the sum of size of all devices

   - The internal structures of the converter are created.
   - The parameter 'NumAllPages' is used to determine the initial size of the  converter.
*/
externC void
b10create_converter (
    tsp00_TaskId   TaskId,
    tsp00_Int4     NumAllPages )
{
    Converter_IManager::Instance().Create( TaskId, NumAllPages );
}

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

/*!
   @brief          Creates an empty converter for restoring existing database
   @param          TaskId [in] task id
   @param          ConverterVersion [in] converter version from restart record
   @param          NumAllPages [in] maximum number of pages which can be stored in the data base. this
                   corresponds to the sum of size of all device
   @param          bLastSaveDataSuccessful [in] indicates whether the last save data finished successfully
   @param          RestartParam [in] aggregation of restart parameters
   @return         none

   - The internal structures of the converter are created and initialized.
   - The parameters 'MaxDynamicPageNo', 'MaxStaticPageNo' and 'NumAllPages'
     are used to determine the initial size of the  converter.
   - 'ConverterVersion' is the converter version of the database to be recovered.
 */
externC void
b10create_converter_for_restore (
    tsp00_TaskId               TaskId,
    tsp00_Int4                 ConverterVersion,
    tsp00_Int4                 NumAllPages,
    tsp00_Bool                 bLastSaveDataSuccessful,
    tkb00_ConfigRestartParam  &RestartParam)
{
    Converter_IManager::Instance().CreateForRestore (
        TaskId,
        ConverterVersion,
        bLastSaveDataSuccessful,
        RestartParam.crMaxDynamicPno_kb00,
        RestartParam.crMaxStaticPno_kb00,
        NumAllPages );
}

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

/*!
   @brief   Returns the maximum possible temporary page number
   @return  (Data_PageNo)
 */

externC tsp00_PageNo
bd10MaxTempPno()
{
    return Converter_ICommon::Instance().MaxTempPageNo();
}

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

/*!
   @brief   Returns the maximum possible permanent, dynamic page number
   @return  (Data_PageNo)
 */
externC tsp00_PageNo
bd10MaxPermDynamicPno()
{
    return Converter_ICommon::Instance().MaxPermDynamicPageNo();
}

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

/*!
       @brief   Returns the maximum possible permanent, static page number
       @return  (Data_PageNo)
 */
externC tsp00_PageNo
bd10MaxStaticStaticPno()
{
    return Converter_ICommon::Instance().MaxPermStaticPageNo();
}

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

/*!
   @brief          Checks whether converter backup is active
   @return         (SAPDB_Bool) true if active
 */
externC tsp00_Bool
b10backup_active ()
{
    return Converter_ICommon::Instance().BackUpIsActive();
}

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

/*!
   @brief          Checks if the required count of pages is available.
   @note           Note this function does not reserve any number of pages for this tasks, i.e.
                   the information that a particular number is available  is dirty and may be
                   even false, when this task really tries to get wanted number of free pages.
   @param          trans [in/out] transaction context
   @param          numDataPagesRequested [in] number of pages wanted
                   data base to gain free pages
   @return         none

   - If the required count of pages is available this function returns true
*/
externC void
bd999CheckSpace (
    tgg00_TransContext  &trans,
    tsp00_Int4          numDataPagesRequested)
{
    Converter_IPageNoManager::Instance().HandleDBFull (trans, numDataPagesRequested);
}

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

/*!
   @brief          Finishes converter verification in "cold" database state
   @param          taskId [in] task id
   @param          NumPermPages [out] number of permanent pages used
   @param          NumReleasesBlocks [out] number of released blocks, which were
                   not accessed during verify
*/
externC void
bd10EndColdVerify (tsp00_TaskId taskId,
                   tsp00_Int4   &NumPermPages,
                   tsp00_Int4   &NumReleasesBlocks)
{
    Data_PageCount       NumStaticPermDataPages  = 0;
    Data_PageCount       NumDynamicPermDataPages = 0;
    Data_PageCount       NumPermConvPages        = 0;
    Data_PageCount       ReleasedBlocks          = 0;

    Converter_IVerify::Instance().EndCheckData (
        taskId,
        NumStaticPermDataPages,
        NumDynamicPermDataPages,
        NumPermConvPages,
        ReleasedBlocks);

    NumPermPages = NumStaticPermDataPages + NumDynamicPermDataPages + NumPermConvPages;
    NumReleasesBlocks = ReleasedBlocks;
}

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

/*!
   @brief          Finishes a failed converter verification
   @param          TaskId [in] task id
   @return         none

   - The converter is restored to the state it had before the verification
     was started by the BeginColdVerify
*/
externC void
bd10EndFailedColdVerify (tsp00_TaskId  TaskId)
{
    Converter_IVerify::Instance().EndFailedCheckData (TaskId);
}

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

/*!
@brief          Ends the backup of data or pages
@param          TaskId [in] current task id
@param          bBackUpSuccessfullyFinished [in] indicates whether the current back
                up finished successfully
@return         none

- The back up active flag in the converter is reset
- If  the current back up  did not finish successfully all blocks still marked
  as to be written to the back up files are unmarked.
*/
externC void
bd10EndSave (tsp00_TaskId    TaskId,
             tsp00_Bool      bBackUpSuccessfullyFinished)
{
    Converter_IBackUp::Instance().EndSave (TaskId, bBackUpSuccessfullyFinished);
}

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

/*!
@brief          Returns the number of of pages marked for back up
@return         Number of blocks marked for back up
*/
externC tsp00_Int4
b10bup_data_page_cnt (tsp00_TaskId TaskId)
{
    return Converter_IBackUp::Instance().GetNumPagesForBackUp();
}


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

/*!
@brief          Returns the number of converter pages required to address all
                static data pages
@return         Number of converter pages required to address all
                data pages which belong to the current backup

- Returns the number of converter pages required to address all
  data pages which belong to the current backup
*/
externC tsp00_Int4
bd10conv_page_cnt ()
{
    return Converter_IBackUp::Instance().GetNumConvPagesForBackUp();
}

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

/*!
   @brief          Returns the actual converter version
   @return         Converter_Version
 */
externPascal tsp00_Int4
bd10GetConverterVersion ()
{
    return Converter_ICommon::Instance().Version ();
}

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

/*!
   @brief          Marks a page in the converter as  used
   @param          Trans [in] trans context
   @param          PageNo [in] page number to be marked as used
   @return         none
 */
externC void
b10use_pno (tgg00_TransContext    &Trans,
            tsp00_PageNo           PageNo)
{
    Converter_IVerify::Instance().MarkPageNoAsUsed (Trans.trTaskId_gg00, PageNo, Data_Dynamic);
}


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

/*!
   @brief          Sets a block address in a converter entry
   @param          TaskId [in] current task id
   @param          PageNo [in] page number for which the converter entry has to be updated
   @param          dev_no [in] device number of new block
   @param          dev_offs [in] device offset of new block address which hast to be inserted in the converter
                   entry of the page defined by PageNo und PageRecoveryMode
   @param          bAddressingModeIsStatic [in] addressing mode
   @return         none

   - after a page was restored this command updates the converter entry, i.e the
     block address of the restored page is updated in the converter entry
 */
externC void
bd10conv_restore_entry (tsp00_TaskId TaskId,
                        tsp00_PageNo PageNo,
                        tsp00_Int2 dev_no,
                        tsp00_Int4 dev_offs,
                        tsp00_Bool bAddressingModeIsStatic)
{
    IOMan_BlockAddress BlockAddress (dev_no, dev_offs);
    const Data_AddressingMode  AddressingMode = (bAddressingModeIsStatic? Data_Static:Data_Dynamic);

    Converter_IBackUp::Instance().SetBlockAddressOfRestoredPage (TaskId, BlockAddress, PageNo, AddressingMode);
}


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

/*!
   @brief          Signals the converter that a given page was written into the back up file
   @param          Trans [in] current trans context
   @param          PageNo [in] page number which is to remove from the list of pages still to write to the back up device
   @param          dev_no [in] device number of block
   @param          dev_offs [in] device offset of block for which the back up file is to remove in the FBM
   @param          bAddressingModeIsStatic [in] addressing mode of the page for which the back up flags have to be removed
   @return         none

   - Resets the flag in the FBM which displays that the given page still has to be
     written to the back up file
   - Removes the page number from the list of page numbers still to inlclude in the back up
*/
externC void
bd10bup_pno_ready (tgg00_TransContext &Trans,
                   tsp00_PageNo PageNo ,
                   tsp00_Int2 dev_no ,
                   tsp00_Int4 dev_offs,
                   tsp00_Bool bAddressingModeIsStatic)
{
    IOMan_BlockAddress BlockAddress (dev_no, dev_offs);
    const Data_AddressingMode  AddressingMode = (bAddressingModeIsStatic? Data_Static:Data_Dynamic);

    if (! Converter_IBackUp::Instance().ResetDataPageAfterBackUp (Trans.trTaskId_gg00,
            BlockAddress, PageNo, AddressingMode))
    {
        Trans.trError_gg00 = e_invalid_fbm_mark;
    }
}

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

/*!
   @brief          Saves converter to devspace (sequential writing)
   @param          Trans [in] current trans context
   @param          ConverterVersion [out] new valid converter version
   @param          MaxStaticPageNo [out] maximun used static page number. This number has
                   to be stored in the restart page in order the calculate the
                   right size of the converter (static map) after a restart.
   @param          MaxDynamicPageNo [out] maximun used dynamic page number. This number has
                   to be stored in the restart page in order the calculate the
                   right size of the converter (dynamic map) after a restart.
   @param          PackedConvRootBlockAddress [out] Block address of the converter root
                   page (to be stored in the restart record
   @return         none
*/
externC void
bd10FlushConverterSerial (tgg00_TransContext  &Trans,
                          tsp00_Int4          &ConverterVersion,
                          tsp00_PageNo        &MaxStaticPageNo,
                          tsp00_PageNo        &MaxDynamicPageNo,
                          tsp00_Int4          &PackedConvRootBlockAddress)
{
    Converter_Version           _ConverterVersion;
    Data_PageNo                 _MaxStaticPageNo;
    Data_PageNo                 _MaxDynamicPageNo;
    IOMan_PackedBlockAddress    _packedRootBlockAddress;

    if( ! Converter_IManager::Instance().FlushSerial (Trans.trTaskId_gg00,
            _ConverterVersion,
            _MaxStaticPageNo,
            _MaxDynamicPageNo,
            _packedRootBlockAddress ))
    {
        Trans.trError_gg00 = e_shutdown;
    }

    ConverterVersion           = _ConverterVersion;
    MaxStaticPageNo            = _MaxStaticPageNo;
    MaxDynamicPageNo           = _MaxDynamicPageNo;
    PackedConvRootBlockAddress = _packedRootBlockAddress;
}

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

/*!
   @brief          Prepares converter verification in "cold" database state
   @return         none
 */
externC void
bd10BeginColdVerify ( tgg00_TransContext  &trans )
{
    const Converter_ReturnCode retCode =
        Converter_IVerify::Instance().BeginCheckData (trans.trTaskId_gg00);

    switch( retCode )
    {
    case Converter_Ok:
        return;
    case Converter_MemoryAllocationFailed:
        trans.trError_gg00 = e_no_more_memory;
    default:
        trans.trError_gg00 = e_system_error;
    }
}

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

/*!
   @brief          Shuts the converter down
   @param          TaskId [in,out] task id
   @return         none

   - All resources held by the converter are released and all
     member data are reseted to their initial values
   - All tasks waiting for the converter are resumed.
 */
externC void
bd10ShutdownConverter (tsp00_TaskId  TaskId)
{
    Converter_IManager::Instance().Shutdown(TaskId);
}

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

/*!
@brief          returns a number of data describing the filling state of the converter
@param          Trans [in] trans context
@param          DbSpaceInfo [out] collection of state data of the converter return value: none
*/
externC void
bd10dbspace_statistic (tgg00_TransContext &Trans,
                       tgg00_DbSpaceInfo  &DbSpaceInfo)
{
    Converter_ICommon::Instance().GetDbSpaceStatistics (Trans.trTaskId_gg00, DbSpaceInfo);
}

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

/*!
@brief          adds an event to the set of events
@param          EventId [in] id of event to add
@param          EventThreshold [in] relative filling level of the data base, whenever
                this critical value is passed an event is triggered
                critical value in 0.01 percent with respect to the total number of pages
                of the data base
@param          EventPrio [in] priority of the event
@return         none
*/
externC void
bd10AddDBFillingEvent (tsp31_event_ident_Param   EventId,
                       tsp00_Int4                EventThreshold,
                       tsp31_event_prio_Param    EventPrio)
{
    SAPDBERR_ASSERT_STATE ((sp31ei_db_filling_above_limit==EventId) || (sp31ei_db_filling_below_limit==EventId));
    SAPDB_Bool bOverflow = (sp31ei_db_filling_above_limit==EventId);
    Converter_IEvent::Instance().AddEvent(EventThreshold, bOverflow, EventPrio);
}

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

/*!
@brief          removes an event from the set of events
@param          EventId [in] id of event to delete
@param          EventThreshold [in] defines the critical value to be removed.
                The value is given in units of 0.01 percent with respect to the base unit
@return         none
*/
externC void
bd10DelDBFillingEvent (tsp31_event_ident_Param   EventId,
                       tsp00_Int4                EventThreshold)
{
    SAPDBERR_ASSERT_STATE ((sp31ei_db_filling_above_limit==EventId) || (sp31ei_db_filling_below_limit==EventId));
    SAPDB_Bool bOverflow = (sp31ei_db_filling_above_limit==EventId);
    Converter_IEvent::Instance().DelEvent(EventThreshold, bOverflow);
}

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

/*!
@brief          puts all events into an external structure in order to show them in a system view
@param          ShortEventDesc [out] structure to fill
@param          bGetOverflowEvents [in] if true  ShortEventDesc is filled with overflow events
                if false ShortEventDesc is filled with underflow events
@return         none

- The ShortEventDesc is filled with all events in order to show the events in a system view
*/
externC void
bd10GetDBFillingEventSet (tsp31_short_event_desc  &ShortEventDesc,
                          tsp00_Bool               bGetOverflowEvents)
{
    Converter_IEvent::Instance().GetEventSet(ShortEventDesc, bGetOverflowEvents);
}

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

/*!
   @brief
   @param          TaskId [in] own Task ID
   @param          CopyPage [out] container to return copied page to caller
   @param          bNoMorePages [out] pages are available
   @return         none
*/
externC void
bd10GetConverterArchivePage(
    tsp00_TaskId   taskId,
    tsp00_Page     &copyPage,
    tsp00_Bool     &bNoMorePages)
{
    bNoMorePages = false;

    Kernel_IPage::PageFrame   frame( &copyPage, sizeof( tsp00_Page ));
    Converter_LeafPage        leafPage( frame );

    if( ! Converter_IBackUp::Instance().GetStaticArchiveLeafPage( leafPage ))
    {
        if( ! Converter_IBackUp::Instance().GetDynamicArchiveLeafPage( leafPage ))
        {
            bNoMorePages = true;
            return;
        }
    }
    leafPage.PrepareForWrite();
    SAPDBERR_ASSERT_STATE( leafPage.CheckAfterRead());
}

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

/*!
   @brief
   @param          TaskId [in] own Task ID
   @param          CopyPage [out] container to return copied page to caller
   @param          bNoMorePages [out] pages are available
   @return         none
*/
externC void
bd10GetConverterBitMapPage(
    tsp00_TaskId   taskId,
    tsp00_Page     &copyPage,
    tsp00_Bool     &bNoMorePages)
{
    bNoMorePages = false;

    Kernel_IPage::PageFrame   frame( &copyPage, sizeof( tsp00_Page ));
    Converter_BitMapPage      bitMapPage( frame );

    if( ! Converter_IBackUp::Instance().GetStaticBitMapPage( bitMapPage ))
    {
        if( ! Converter_IBackUp::Instance().GetDynamicBitMapPage( bitMapPage ))
        {
            bNoMorePages = true;
            return;
        }
    }
    bitMapPage.PrepareForWrite();
    SAPDBERR_ASSERT_STATE( bitMapPage.CheckAfterRead());
}

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

/*!
   @brief          Clears the containers with copied converter leafpages
   @return         none

   - removes all copied converter leafpages which belong to a back up
 */
externC void
bd10RemoveConverterArchivePages ()
{
    Converter_IBackUp::Instance().RemoveArchiveLeafPages();
}

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

/*!
   @brief          Clears the containers with used static and dynamic page numbers
   @return         none

   - removes all page numbers stored in the containers of
     used dynamic and static page numbers which belong to a back up (save pages)
 */
externC void
bd10RemoveConverterBitMapPages ()
{
    Converter_IBackUp::Instance().RemoveBitMapPages();
}

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

/*!
@brief          Releases page numbers which do not belong to a restored data base
@param          TaskId [in] task id
@param          pPage [in] page with converter bitmap
@return         none

- for all page number which are not marked as used at the UsedPageNoBitMapPage
  the corresponding converter entry is set to free and the block is released
- for all page numbers which are marked as used in the UsedPageNoBitMapPage but not
  in the converter the correspondung page entry is reserved
- all converter pages which contain any used page number are marked as used
  (see also FreePageNosNotInConverterBitMapPages)
*/
externC void
bd10RestoreUsedPageNos (tsp00_TaskId   TaskId,
                        tsp00_PageAddr pPage)
{
    Kernel_Page::PageFrame frame (pPage, sizeof(*pPage));
    Converter_BitMapPage BitMapPage (frame);
    Converter_IBackUp::Instance().RestoreUsedPageNos (TaskId, BitMapPage);
}

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

/*!
@brief         integrate converter pages from backup
@param         taskId [in] own task id
@param         pPage [in] converter page from backup medium
@return        none

- integrate converter entries from backup into the current converter.
*/
externC void
bd10RestoreConverter (tsp00_TaskId   taskId,
                      tsp00_PageAddr pPage)
{
    Kernel_Page::PageFrame frame (pPage, sizeof(*pPage));
    Converter_LeafPage leafPage (frame);
    Converter_IBackUp::Instance().RestoreConverterPage (taskId, leafPage);
}

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

/*!
@brief          Releases page numbers which do not belong to a restored data base
@param          TaskId [in] task id
@return         none

- after all UsedPageNoBitMapPage of a back up are read this function
  scans the converter and removes all those converter leaf pages (and their entries)
  which are not marked as used. (see also FreeUnusedPageNo)
  This means all those converter entries which were neither marked as used nor as
  free in the UsedPageNoBitMapPage's (means not at all mentioned) are removed
*/
externC void
bd10FinishRestoreUsedPageNos (tsp00_TaskId TaskId)
{
    Converter_IBackUp::Instance().FinishRestoreUsedPageNos (TaskId);
}

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

/*!
   @brief    checks ConverterPage for consistency
   @param    Page [in] page to check
   @param    bPageIsDamaged [out] check result
   @return   none
*/
externC void
bd10CheckConverterPage(tsp00_Page     &Page,
                       tsp00_Bool     &bPageIsDamaged)
{
    Kernel_Page::PageFrame frame (&Page, sizeof(Page));
    Converter_LeafPage ConvPage (frame);
    bPageIsDamaged = (! ConvPage.CheckAfterRead());
}

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

/*!
   @brief    checks ConverterBitMapPage for consistency
   @param    Page [in] page to check
   @param    bPageIsDamaged [out] check result
   @return   none
*/
externC void
bd10CheckConverterBitMapPage(tsp00_Page     &Page,
                             tsp00_Bool     &bPageIsDamaged)
{
    Kernel_Page::PageFrame frame (&Page, sizeof(Page));
    Converter_BitMapPage BitMapPage (frame);
    bPageIsDamaged = (! BitMapPage.CheckAfterRead());
}

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

/*!
   @brief          Returns the numbers of all currently used converter pages
   @return         number of converter pages (perm and temp) currently used
 */
externC tsp00_Int4
bd10ConverterSize()
{
    return( Converter_ICommon::Instance().UsedConverterPages());
}


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

/*!
   @brief          Returns true if db is full.
   @param          taskId [in] task id
   @return         (bool)
 */
externC tsp00_Bool
bd10IsDbFull( tsp00_TaskId taskId )
{
    return( Converter_ICommon::Instance().IsDBFull( taskId ));
}

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

/*!
   @brief          If the database filling is nearly full and therefore a
                   sensible work is not possible this method returns a true
                   else false.
   @return         true if security is reached and database nearly full else false
 */
externC tsp00_Bool
bd10IsConnectAllowed()
{
    return( ! Converter_ICommon::Instance().SecuritySpaceReached() );
}

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

/*!
   @brief          If the number of changed converter pages and changed pages
                   within data cache is nearly to the number of free blocks within
                   FBM a savepoint is started. As long as this requested
                   savepoint is finished this method will not request a new savepoint.
                   This will be done only if the converter is online and not
                   in maintenance mode.
   @param          Trans [in] transaction context
   @return         none
 */
externC void
bd10CheckAndStartSavepoint(tgg00_TransContext & Trans )
{
    Converter_ICommon::Instance().StartSavepoint( Trans );
}

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

/*!
    @brief   Checks if the current back up finished successfully. Checks if
             all pages marked as to be included in the back up were fetched
             by the back up manager
    @param   taskId [in] current task id
    @return  true if the back was successful else false
*/

externC tsp00_Bool
bd10CheckBackup( tsp00_TaskId taskId )
{
    return Converter_IBackUp::Instance().CheckBackUp( taskId );
}

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

inline void
bd10_SnapShotHandling(
    const tsp00_TaskId       taskId,
    const SAPDB_UInt4        pascalSnapShotRestartAddr,
    IOMan_PackedBlockAddress &packedSnapShotRootBlockAddr,
    Converter_Version        &snapShotVersion,
    Kernel_DateTime          &snapShotCreationTimeStamp )
{
    // +++ Should be part of the restart page component! +++

    const IOMan_PackedBlockAddress  packedSnapShotRestartAddr( pascalSnapShotRestartAddr );
    const SAPDB_Int           volNoBitCount       = Converter_ICommon::Instance().GetVolumeNoBitCount();
    const IOMan_BlockAddress  snapShotRestartAddr = packedSnapShotRestartAddr.Unpack( volNoBitCount );

    FrameCtrl_IRestartPage  &frameControl = FrameCtrl_IRestartPage::GetInstance();
    Kernel_IPage::PageFrame pageFrame     = frameControl.NewRestartPageFrame( taskId );
    Kernel_RestartPage      snapShotRestartPage( pageFrame );

    IOMan_IDataIO::GetInstance().ReadSnapShotRestartPage( taskId, snapShotRestartPage, snapShotRestartAddr );

    // make sure that the block of the frozen restart record
    // will not be used by another page

    FBM_IManager::Instance().SetBlockStateToOccupied( taskId, snapShotRestartAddr, true );

    const tkb00_PagePtr   pPage = reinterpret_cast<tkb00_PagePtr>(snapShotRestartPage.GetFramePtr());

    snapShotVersion             = pPage->rstConverterVersion_kb00();
    packedSnapShotRootBlockAddr = pPage->rstConfigParam_kb00().crConvRootBlockAddr_kb00;

    Kernel_DateTime auxTime( pPage->rstLastSavept_kb00().svpDate_kb00, pPage->rstLastSavept_kb00().svpTime_kb00);

    snapShotCreationTimeStamp = auxTime;

    frameControl.FreeRestartPageFrame( taskId, pageFrame );
}

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