/*!***************************************************************************

  module:       RTEMem_RawAllocator.hpp

  responsible : JoergM

  special area: RunTime

  description:  RunTime RawAllocator interface for memory management.

                This is a base allocator used by all other allocators to get memory

  last changed: 2000-12-06  19:03
  see also    :

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





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

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

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

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




*****************************************************************************/
#ifndef RTEMEM_RAWALLOCATOR_HPP
#define RTEMEM_RAWALLOCATOR_HPP

#include "SAPDBCommon/MemoryManagement/SAPDBMem_IRawAllocator.hpp"
#include "RunTime/Synchronisation/RTESync_InterlockedCounter.hpp"
/*! 
  class: RTEMem_RawAllocator

  description: 'Synchronized' allocator interface for 'raw' memory. 

    Class implementing the interface to provide methods for reserving
    and freeing 'raw' memory. The reserved memory always is suitably
    (platform dependent) aligned such that any object type can be put
    there. Implementations shall meet the requirements of the C++
    Standard, par.3.7.3 'Dynamic storage duration
    [basic.stc.dynamic]'.  
 */
class SAPDBMem_IBlockAllocator;

class RTEMem_RawAllocator : public SAPDBMem_IRawAllocator
{
public: 
    /*!----------------------------------------------------------------------
      Function: Instance
      Description: Return instance of RTEMem_RawAllocator

      i.e. RTEMem_RawAllocator::Instance().allocate(NumberOfBytes);

      NOTE To reduce overhead use this class only to allocate big chunks
      of memory (> 16 KByte). If smaller pieces are wanted, wrap this allocator with a
      suitable allocator (i.e. SAPDB_BuddyAllocator) or use RTEMem_Allocator instead.
      -----------------------------------------------------------------------*/
    static SAPDBMem_IRawAllocator & Instance();

    /*!----------------------------------------------------------------------
      Declaration: AlignType

	  Description: Type requiring maximal alignment on the given platform. 
      -----------------------------------------------------------------------*/
      typedef union { void* p; long l; double d; } AlignType;

    /*!----------------------------------------------------------------------
      Function: Allocate

      Description: Allocates contiguous memory for 'count' bytes.

	  The memory is suitably aligned for all types.

	  The memory is not initialised.  

      If compiled with -DSAPDB_COMPILE_WITHOUT_EXCEPTION_HANDLING a (void *)0 is returned on failure.

      If compiled without this switch an SAPDBMem_BadAllocException exception is thrown on failure.

      Arguments: count[in] The number of Bytes to allocate
        
      Return value: Pointer to allocated memory area
      -----------------------------------------------------------------------*/
    virtual void* Allocate(SAPDB_ULong count);

    /*!----------------------------------------------------------------------
	  Function: allocate
	  Description: Allocates contiguous memory for 'count' bytes,
          while trying to keep locality with a given memory location.

	    If possible, the allocator tries to reserve the memory near
	    a specified location.

	    The memory is suitably aligned for all types.

	    The memory is not initialised.  

        If compiled with -DSAPDB_COMPILE_WITHOUT_EXCEPTION_HANDLING a (void *)0 is returned on failure.

        If compiled without this switch an SAPDBMem_BadAllocException exception is thrown on failure.

        Arguments: count[in] The number of Bytes to allocate
                   hint [in] A hint where to allocate the memory

      Return value: Pointer to allocated memory area
      -----------------------------------------------------------------------*/
    virtual void* Allocate(SAPDB_ULong count, const void * hint);

    /*!----------------------------------------------------------------------
      Function: Deallocate
	  Description: Frees the memory. 

	  The pointer must have been obtained by a previous call to 'allocate'.

	  Arguments: p [in] Pointer to the memory to be deallocated
      -----------------------------------------------------------------------*/
    virtual void Deallocate(void * p);

    /*!----------------------------------------------------------------------
      Function: GetIdentifier
      Description: Return identifier
      Return value: const SAPDB_UTF8 * "RTE_RawAllocator"
      -----------------------------------------------------------------------*/
      virtual const SAPDB_UTF8 * GetIdentifier() const 
          { return (const SAPDB_UTF8 *)"RTE_RawAllocator"; }

    /*!----------------------------------------------------------------------
      Function: GetOverhead
      Description:  Return number of bytes needed as overhead to store size info

      This value can be used to optimize access of this allocator, minimizing the
      overhead needed for each allocation.

      Return value: Minimum number of bytes overhead
      -----------------------------------------------------------------------*/
    static SAPDB_ULong GetOverhead();

    /*!----------------------------------------------------------------------
      Function: CalcStatistics
      Description:  Outputs statistics about the memory usage of the allocator.
      Arguments:    BytesUsed [out]
                    The number of bytes used by this allocater.
                    MaxBytesUsed [out] 
                    The maximum number of bytes usedd by this allocator so far
                    BytesControlled [out]
                    The number of bytes controlled by this allocator.

                    The default implementation returns GetInvalidSize() for 
                    both values.
      Return value: none
      -----------------------------------------------------------------------*/
    virtual void CalcStatistics( SAPDB_ULong &BytesUsed,
                                 SAPDB_ULong &MaxBytesUsed,
                                 SAPDB_ULong &BytesControlled);

	/*!----------------------------------------------------------------------
     Function: GetBaseAllocatorCallStatistics
     Ddescription:  Outputs statistics about the number of Allocate and Deallocate calls of
                   the allocator to the underlying base allocator.
     Arguments:    CountAlloc [out]
                   The number of calls of method Allocate of the base allocator.
                   CountDealloc [out]
                   The number of calls of method Deallocate of the base.

     Return value: none
     -----------------------------------------------------------------------*/

    virtual void GetBaseAllocatorCallStatistics(SAPDB_ULong &CountAlloc,
                                  SAPDB_ULong &CountDealloc) const;

    /*!----------------------------------------------------------------------
     Function: GetCallStatistics
     Description:  Outputs statistics about the number of Allocate and Deallocate calls.
     Arguments:    CountAlloc [out]
                 The number of calls of method Allocate.
                 CountDealloc [out]
                 The number of calls of method Deallocate.

     Return value: none
     -----------------------------------------------------------------------*/

    virtual void GetCallStatistics(SAPDB_ULong &CountAlloc,
                                   SAPDB_ULong &CountDealloc) const;

    /*!----------------------------------------------------------------------
      Function: GetErrorCount
      Description:  Returns the number of errors found and corrected by the allocator

                    The derived class is responsible to implement this feature (but must not do so...)

      Return value: integer
      -----------------------------------------------------------------------*/

     virtual int GetErrorCount() const;

private:
      RTEMem_RawAllocator();

      SAPDBMem_IBlockAllocator & m_MemoryPageAllocator;

      RTESync_InterlockedCounter<SAPDB_ULong> m_BytesUsed;
      RTESync_InterlockedCounter<SAPDB_ULong> m_MaxBytesUsed;
      RTESync_InterlockedCounter<SAPDB_ULong> m_BytesControlled;
      RTESync_InterlockedCounter<SAPDB_ULong> m_CountAlloc;
      RTESync_InterlockedCounter<SAPDB_ULong> m_CountDealloc;

      static RTEMem_RawAllocator *m_Instance;
};
/*!   endclass: RTEMem_RawAllocator */


#endif /* RTEMEM_RAWALLOCATOR_HPP */
