/*!
    @file           IOMan_ClusterAddress.hpp
    @author         TorstenS
    @author         TillL
    @ingroup        IOManagement
    @brief          This class is used to offer a handler for a
                    collection of block addresses callled cluster.
                    A cluster consists of a number of related block 
                    addresses. A start block address defines the 
                    beginning of the cluster and a block count the 
                    end, i.e. all blocks of the cluster belong to the 
                    same volume and the offsets are contiguous. 
                    (see also IOMan_BlockAddress.hpp)

\if EMIT_LICENCE

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

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

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

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



\endif
*/



#ifndef IOMAN_CLUSTERADDRESS_HPP
#define IOMAN_CLUSTERADDRESS_HPP


#include "IOManager/IOMan_BlockAddress.hpp"
#include "IOManager/IOMan_Types.hpp"
#include "SAPDBCommon/ErrorsAndMessages/SAPDBErr_Assertions.hpp"

/* -----------------------------------------------------------------------*/
/*!
    @class  IOMan_ClusterAddress
    @brief  Defines a handle to a cluster of logical block addresses for i/o. 
            This handle contains a logical volume number, a start block 
            offset and a block count. All blocks of a cluster are related.
            The begin of the clustes is defined by the start address and 
            the end could be calculated by the start address and the block
            count.
 */
/* -----------------------------------------------------------------------*/

class IOMan_ClusterAddress
{
public:

    /*------------------------------------------------------------------------*/
    /*!
       @brief   Block index number within cluster
     */
    /*------------------------------------------------------------------------*/

    typedef SAPDB_UInt2 BlockIndex;

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   Default constructor
       @return  none
     */
    /* -----------------------------------------------------------------------*/

    IOMan_ClusterAddress()
    : m_BlockCount(0)
    {}

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   Constructor
       @param   startAddr [in] block address of first block
       @param   blockCount [in] count of blocks in cluster
       @return  none
     */
    /* -----------------------------------------------------------------------*/

    IOMan_ClusterAddress(
        const IOMan_BlockAddress    &startAddr,
        const IOMan_BlockCount      blockCount )
    :m_StartAddr( startAddr ),
    m_BlockCount( blockCount )
    {}

    /* -----------------------------------------------------------------------*/
    /*!
        @brief   Assigns cluster
        @param   startAddr  [in] block address of first block
        @param   blockCount [in] count of blocks in cluster
        @return  none
     */
    /* -----------------------------------------------------------------------*/

    void SetCluster(
        const IOMan_BlockAddress    &startAddr,
        const IOMan_BlockCount      blockCount )
    {
        m_StartAddr  = startAddr;
        m_BlockCount = blockCount;
    }

    /* -----------------------------------------------------------------------*/
    /*!
        @brief  Returns count of blocks in the cluster
        @return (IOMan_BlockCount) block count
     */
    /* -----------------------------------------------------------------------*/

    IOMan_BlockCount GetBlockCount() const
    {
        return m_BlockCount;
    }

    /* -----------------------------------------------------------------------*/
    /*!
        @brief  Returns block address of requested block in cluster
        @param  index [in] block number within cluster (first block = 0)
        @return (IOMan_BlockAddress) block address
     */
    /* -----------------------------------------------------------------------*/

    IOMan_BlockAddress GetBlockAddress( const BlockIndex index ) const
    {
        SAPDBERR_ASSERT_ARGUMENT( index < m_BlockCount );

        return IOMan_BlockAddress(
                   m_StartAddr.GetDeviceNo(),
                   m_StartAddr.GetBlockNo() + index );
    }

    /* -----------------------------------------------------------------------*/
    /*!
        @brief  Returns device number of actual cluster address
        @return (IOMan_DeviceNo) device number
     */
    /* -----------------------------------------------------------------------*/

    const IOMan_DeviceNo& GetDeviceNo() const
    {
        return m_StartAddr.GetDeviceNo();
    }

    /* -----------------------------------------------------------------------*/
    /*!
        @brief  Returns block pos of requested block in cluster
        @param  index [in] block number within cluster (first block = 0)
        @return (IOMan_BlockNo) block position on device
     */
    /* -----------------------------------------------------------------------*/

    IOMan_BlockNo GetBlockNo( const BlockIndex index ) const
    {
        SAPDBERR_ASSERT_ARGUMENT( index < m_BlockCount );

        return IOMan_BlockNo
               ( m_StartAddr.GetBlockNo() + index );
    }

private:

    /* -----------------------------------------------------------------------*/
    /*!
        @brief  block address of first block in cluster
     */
    /* -----------------------------------------------------------------------*/

    IOMan_BlockAddress  m_StartAddr;

    /* -----------------------------------------------------------------------*/
    /*!
        @brief  count of blocks in sequence
     */
    /* -----------------------------------------------------------------------*/

    IOMan_BlockCount m_BlockCount;
};


#endif // IOMAN_CLUSTERADDRESS_HPP

