/*!
  @file           FBM_IManager.hpp
  @author         TorstenS
  @ingroup        FBM
  @brief          Interface definition of the FBM

\if EMIT_LICENCE
    ========== 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

\endif
*/



#ifndef FBM_IMANAGER_HPP
#define FBM_IMANAGER_HPP

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

#include "RunTime/RTE_Types.h"
#include "FreeBlockManagement/FBM_Types.hpp"
#include "IOManager/IOMan_BlockAddress.hpp"
#include "IOManager/IOMan_IBlockAddressIterator.hpp"
#include "IOManager/IOMan_ReservedBlockAddress.hpp"
#include "IOManager/IOMan_ClusterAddress.hpp"

// forward
class Kernel_Dump;

/*!
  @class          FBM_IManager
 */


class FBM_IManager
{

public:

    /*!
       @brief          returns the reference to the sigelton instance of FBM_Manager
       @return         (FBM_Manager&amp;) reference to the instance of FBM_Manager
     */
    static FBM_IManager& Instance ();
    
    /*!
       @brief          Sets the state of block to 'occupied'
       @param          TaskId [in] task id
       @param          BlockIterator [in] iterator of I/O adresses with the blocks to change
       @param          bAbortIfErrorOccured [in] terminate kernel if an error occure.
                                        default is set to no. Therefore
                                        the calling method has to make the
                                        error handlig.
       @return         (SAPDB_Bool) SAPDB_TRUE if operation was executed successful

       - If the state could not be changed successfully the kernel aborts if
      the given parameter bAbortIfErrorOccured is set to SAPDB_TRUE.
     */
    virtual SAPDB_Bool SetBlockStateToOccupied(
        const tsp00_TaskId                 TaskId,
              IOMan_IBlockAddressIterator &BlockIterator,
        const SAPDB_Bool                   bAbortIfErrorOccured = ! FBM_ABORT_IF_ERROR) = 0;

    /*!
       @brief          Sets the state of block to 'occupied'
       @param          TaskId [in] task id
       @param          BlockAddress [in] I/O adress of the block to change
       @param          bAbortIfErrorOccured [in] terminate kernel if an error occure.
                                        default is set to no. Therefore
                                        the calling method has to make the
                                        error handlig.
       @return         (SAPDB_Bool) SAPDB_TRUE if operation was executed successful

       - If the state could not be changed successfully the kernel aborts if
      the given parameter bAbortIfErrorOccured is set to SAPDB_TRUE.
     */
    virtual SAPDB_Bool SetBlockStateToOccupied (
        const tsp00_TaskId        TaskId,
        const IOMan_BlockAddress &BlockAddress,
        const SAPDB_Bool          bAbortIfErrorOccured = ! FBM_ABORT_IF_ERROR) = 0;

    /*!
       @brief          add volume to the FBM
       @param          TaskId [in] task id
       @param          DevNo [in] device number
       @param          DevSize [in] number of pages the device can accomodate
       @param          DevMode [in] access mode of the volume 
       @return         true if successful executed else false
     */
    virtual bool AddVolume(
        const tsp00_TaskId                  TaskId,
        const SAPDB_Int2                    DevNo,
        const SAPDB_Int4                    DevSize,
        const RTE_VolumeAccessMode          DevMode) = 0;


    /*!
       @brief          The iterator supplying the blocks marked for back up is set to the first block
       @param          TaskId [in] task id
       @return         none

       - This function has to be called prior to the call of the function
      GetNextBlocksForBackUp which returns each time it is executed another
    block marked for backup. The function BeginReadingBlocksMarkedForBackUp
    initializes this iterator and sets it onto the very first block marked for backup
     */
    virtual void BeginReadingBlocksMarkedForBackUp( const tsp00_TaskId TaskId ) = 0;

    /*!
       @brief          Removes for all blocks the flags indicating that this block must be saved
       @param          TaskId [in] task id
       @return         none

       - The original state of the blocks is restored.
     */
    virtual void RestoreAllBlockStatesMarkedForBackup( const tsp00_TaskId TaskId ) = 0;

    /*!
       @brief          Returns the number of all blocks marked for back up
       @param          TaskId [in] task id
       @return         number of all blocks marked for back up
     */
    virtual SAPDB_Int4 NumBlocksMarkedForBackup( const tsp00_TaskId TaskId ) const = 0;

    /*!
       @brief          Checks if the given number of blocks is storable within the
                       data volumes.
       @param          numBlocksRequested [in] number of blocks to be written into
                       the data volumes.
       @return         true is given number of blocks is storable within data
     */
    virtual bool IsSpaceAvailable( const SAPDB_Int4 numBlocksRequested ) const = 0;

    /*!
        @brief  Returns true if the number of blocks in state free after savepoint is greater than zero.
        @return (SAPDB_Bool) 
     */
    virtual SAPDB_Bool FreeAfterSVPExist() const = 0;

    /*!
       @brief          Returns the number of blocks in state free. Note that the
                       blocks in state free after savepoint are treated as blocks
                       in state occupied, because the are not available at this 
                       moment.
       @return         (SAPDB_Int4) Number of free blocks
     */
    virtual SAPDB_Int4 GetNumberOfFreeBlocks() const = 0;

    /*!
       @brief          Returns the number of all used blocks. Used means all blocks
                       not in state free. Note that blocks in state free after savepoint 
                       are handled as occupied blocks because there are not available
                       at this moment.
       @return         (SAPDB_Int4) Number of used blocks
     */
    virtual SAPDB_Int4 GetNumberOfUsedBlocks() const = 0;


    /*!
       @brief          If the data volume filling is about 90 percent and the fbm
                       is in online mode, this method returns true to signalize that 
                       garbage collector support is needed.
       @param          numChangedPages [in] number of changed pages within data cache
                       and converter
       @return         true if garbage collector support is needed; else false
     */
    virtual bool GarbageCollectionNeeded( const SAPDB_Int4 numChangedPages ) const = 0;

    /*!
       @brief          If the number of blocks in state free after savepoint is greater
                       than the number of blocks in state free a savepoint is needed.
       @return         true if a savepoint is needed; else false
     */
    virtual bool SavepointNeeded() const = 0;

    /*!
       @brief          Supplies a set of free and neighbouring blocks
       @param          taskId [in] task id
       @param          NumFreeBlocksWanted [in] wanted number of blocks
       @param          bReqSequential [in] request access to sequential volume
       @param          trError [out] errors state of the function. if everything worked fine it is e_ok
       @return         (IOMan_ClusterAddress) address of the supplied cluster

       - Supplies a set of free and neighbouring blocks and sets these blocks
      to the state 'occupied'
     */

    virtual IOMan_ClusterAddress GetMultFreeBlocks(
        const tsp00_TaskId  taskId,
        const SAPDB_Int4    NumFreeBlocksWanted,
        const SAPDB_Bool    bReqSequential,
        tgg00_BasisError   &trError) = 0;

    /*!
       @brief          Supplies a free block
       @param          taskId [in] task id
       @param          bReqSequential [in] request access to sequential volume
       @return         (IOMan_BlockAddress) block address of the supplied block

       - Supplies a single free block and marks this block as 'occupied'
      if no free block could be found than an emergency shutdown will
    be executed.
     */
    virtual IOMan_BlockAddress GetFreeBlock( 
        const tsp00_TaskId  taskId ,
        const SAPDB_Bool    bReqSequential) = 0;

    /*!
       @brief          Removes the flags indicating that a block must be saved
       @param          TaskId [in] task id
       @param          BlockAddress [in] address of the block to restore
       @return         true if the block was really marked for back up

       - The original state of the block is restored.
       - If the state could not be restored successfully since the block to be restored
      was not at all marked for backup the kernel aborts
     */
    virtual void RestoreBlockStateMarkedForBackup(
        const tsp00_TaskId       TaskId,
        const IOMan_BlockAddress &BlockAddress ) = 0;

    /*!
       @brief   Sets the state of block to 'free after completion of the next save point'
       @param   blockAddress [in] I/O adress of the block to change
       @return  none

       - If the state could not be changed successfully the kernel aborts
    */

    /*!
       @brief          Sets the state of block to 'free'
       @param          TaskId [in] task id
       @param          BlockAddress [in] I/O adress of the block to change
       @return         none

       - If the state could not be changed successfully the kernel aborts
     */
    virtual void SetBlockStateToFree(
        const tsp00_TaskId       TaskId,
        const IOMan_BlockAddress &BlockAddress ) = 0;

    /*!
       @brief          Sets the state of cluster to 'free'
       @param          TaskId [in] task id
       @param          ClusterAddress [in] I/O adress and length of the cluster to change
       @return         none

       - If the state could not be changed successfully the kernel aborts
     */
    virtual void SetClusterStateToFree(
        const tsp00_TaskId         TaskId,
        const IOMan_ClusterAddress &ClusterAddress ) = 0;


    /*!
       @brief   Sets the state of block to 'free'
       @param   blockAddress [in] I/O adress of the block to change
       @return  none

       - If the state could not be changed successfully the kernel aborts
     */

    virtual inline void SetBlockStateToFree( const IOMan_BlockAddress &blockAddress ) = 0;

    /*!
       @brief          Sets the state of block to 'free after completion of the next save point'
       @param          TaskId [in] task id
       @param          BlockAddress [in] I/O adress of the block to change
       @return         none

       - If the state could not be changed successfully the kernel aborts
     */

    virtual void SetBlockStateToFreeAfterSVP(
        const tsp00_TaskId       TaskId,
        const IOMan_BlockAddress &BlockAddress ) = 0;

    
    virtual inline void SetBlockStateToFreeAfterSVP( const IOMan_BlockAddress &blockAddress ) = 0;

    /*!
       @brief          All Blocks marked as 'free after savepoint' are released
       @param          TaskId [in] task id
       @return         none
     */
    virtual void SetAllBlocksMarkedAsFreeAfterSVPToFree( const tsp00_TaskId TaskId ) = 0;

    /*!
       @brief          Sets the state of block to 'marked for backup'
       @param          TaskId [in] task id
       @param          BlockAddress [in] I/O adress of the block to change
       @param          bAbortIfErrorOccured [in] terminate kernel if an error occure.
                                        default is set to no. Therefore
                                        the calling method has to make the
                                        error handlig.
       @return         (SAPDB_Bool) SAPDB_TRUE if operation was executed successfully

       - If the state could not be changed successfully the kernel aborts, if
      the given parameter bAbortIfErrorOccured is set to SAPDB_TRUE.
     */
    virtual SAPDB_Bool SetBlockStateToBackup(
        const tsp00_TaskId        TaskId,
        const IOMan_BlockAddress &BlockAddress,
        const SAPDB_Bool          bAbortIfErrorOccured = ! FBM_ABORT_IF_ERROR ) = 0;

    virtual SAPDB_Bool SetBlockStateToBackup(
        const tsp00_TaskId        TaskId,
        IOMan_IBlockAddressIterator &BlockIterator,
        const SAPDB_Bool          bAbortIfErrorOccured = ! FBM_ABORT_IF_ERROR ) = 0;

    /*!
       @brief          Returns the number of all used blocks on a device
       @param          DevNo [in] number of the device for which the number of used blocks is requested
       @return         number of all blocks used

       - Returns the number of all used blocks on a device. A block is considered to be used if it is not in the state free.
     */
    virtual SAPDB_Int4 NumBlocksUsed( const SAPDB_Int2 DevNo ) const = 0;

    /*!
       @brief          Returns the volume mode of a device
       @param          DevNo [in] number of the device for which the volume mode is requested
       @return         volume mode

       - Returns the volume mode of a device.
     */
    virtual RTE_VolumeAccessMode GetVolMode( const SAPDB_Int2 DevNo ) const = 0;

    /*!
       @brief          all memory resources are released and members set to their initial values
       @param          TaskId [in] task id
       @return         one
     */
    virtual void Shutdown( const tsp00_TaskId TaskId ) = 0;

    /*!
       @brief          restarts the FBM
       @param          TaskId [in] task id
       @param          MaxNumDev [in] maximum number of devices which can be handled 
                                   by the FBM_Manager
       @param          ReservedBlocks [in] collection of reserved block address
       @return         true if successful executed else false
     */
    virtual bool Restart(
        const tsp00_TaskId                  TaskId,
        const SAPDB_Int4                    MaxNumDev,
        const IOMan_ReservedBlockAddress    &ReservedBlocks ) = 0;

    /*!
       @brief          inserts all important memory structures of the FBM into the 
                       kernel dump file
       @param          taskId [in] identification of the calling task
       @param          dump [in/out] kernel dump file
       @return         none
     */
    virtual void Dump(
        const tsp00_TaskId  taskId,
        Kernel_Dump         &dump ) const  = 0;

};


#endif //FBM_IMANAGER_HPP
