/****************************************************************************

  module      : vbd499.cpp

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

  author      : AlexanderK,TorstenS
  responsible : UweH

  special area: IndexMemoryManagementUnit
  description : 


  last changed: 1999-07-22  10:00
  see also    : 

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

  copyright:    (c) 1999-2004 SAP AG



    ========== licence begin  GPL
    Copyright (c) 1999-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                                                                 *
 *===========================================================================*/

                      // Content of include files
#include "gbd499.h"
#include "gbd496.h"   // CPP   : FileHandling
#include "gbd495.h"   // CPP   : DoubleQueueHandling
#include "gbd494.h"   // CPP   : FunnelHandling
#include "gsp03.h"    // PASCAL: SP_message_constants_and_types
#include "gsp03_3.h"  // PASCAL: SP_message_constants_and_types
#include "hbd20_1.h"  // PASCAL: bd20GetCacheSize
#include "heo55k.h"   // RTE   : Vbegexcl/Vendexcl 
#include "heo57.h"    // RTE   : Vallocat
#include "hgg01.h"    // PASCAL: Configuration_Parameter
#include "hgg01_1.h"  // PASCAL: Configuration_Parameter
#include "hgg08.h"    // PASCAL: Regions_and_Longwaits


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

#ifdef BIT64
#define CSERV_FUNNEL_ITEM_SIZE_BD499    16 
#define CSERV_QUEUE_ITEM_SIZE_BD499     64
#define CSERV_SORT_ITEM_SIZE_BD499      24
#else
#define CSERV_FUNNEL_ITEM_SIZE_BD499    8
#define CSERV_QUEUE_ITEM_SIZE_BD499     36
#define CSERV_SORT_ITEM_SIZE_BD499      16
#endif
#define CSERV_FILE_LIST_ITEM_SIZE_BD499 8

#define MEMORY_MSG_1_BD499          "FileListSize Too Small  "
#define MEMORY_MSG_2_BD499          "FunnelItemSize Too Small"
#define MEMORY_MSG_3_BD499          "QueueItemSize Too Small "

     
/*===========================================================================*
 *  MACROS                                                                   *
 *===========================================================================*/



/*===========================================================================*
 *  LOCAL CLASSES, STRUCTURES, TYPES, UNIONS ...                             *
 *===========================================================================*/



/*===========================================================================*
 *  EXTERNAL VARIABLES                                                       *
 *===========================================================================*/



/*===========================================================================*
 *  GLOBAL VARIABLES                                                         *
 *===========================================================================*/

bool          cbd499_IndexMemoryManagementUnit::m_MemoryAllocated       = false;
void         *cbd499_IndexMemoryManagementUnit::m_pFileList             = NULL;
void         *cbd499_IndexMemoryManagementUnit::m_pFunnelStack          = NULL;
tsp00_TaskId  cbd499_IndexMemoryManagementUnit::m_FileListUsedByTask    = cgg_nil_pid;
tsp00_TaskId  cbd499_IndexMemoryManagementUnit::m_FunnelStackUsedByTask = cgg_nil_pid;

/*===========================================================================*
 *  LOCAL VARIABLES                                                          *
 *===========================================================================*/



/*===========================================================================*
 *  LOCAL FUNCTIONS (PROTOTYPES)                                             *
 *===========================================================================*/



/*===========================================================================*
 *  GLOBAL FUNCTIONS (CODE)                                                  *
 *===========================================================================*/



/*===========================================================================*
 *  LOCAL FUNCTIONS (CODE)                                                   *
 *===========================================================================*/



/*===========================================================================*
 *  DEFINITION OF METHODS DECLARED IN gbd499.h (CODE)                        * 
 *===========================================================================*/

cbd499_IndexMemoryManagementUnit::cbd499_IndexMemoryManagementUnit ()
{
    ROUTINE_DBG_MEO00 ("cbd499_IndexMemoryManagementUnit");
}

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

bool cbd499_IndexMemoryManagementUnit::bd499GetFileListMemory (
							  tsp00_TaskId      TaskId,
							  tsp00_BytePtr    &pFileList,
							  tsp00_Int4       &FileListItems
							  )
{
    ROUTINE_DBG_MEO00 ("bd499GetFileListMemory");
	

	bool       bSuccessful = false;
    tsp00_Int4 totalPages  = 0;
    tsp00_Int4 unMapPages  = 0;

    bd20GetCacheSize( totalPages, unMapPages );

    vbegexcl (TaskId, g08permfdir);
	
    if (
        (m_MemoryAllocated                                   ) && 
        (cgg_nil_pid == m_FileListUsedByTask                 ) &&
        (g01index_file_list() * 3 < (totalPages - unMapPages))
        )
    {
        m_FileListUsedByTask = TaskId;
        pFileList            = tsp00_BytePtr (m_pFileList);
        FileListItems        = g01index_file_list();
		bSuccessful           = true;
    }
    vendexcl (TaskId, g08permfdir);
    
    return (bSuccessful);
}

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

bool cbd499_IndexMemoryManagementUnit::bd499GetFunnelStackMemory (
							 tsp00_TaskId      TaskId,
                             tsp00_BytePtr    &pFunnelStack,
                             tsp00_Int4       &FunnelStackItems
                             )
{
    ROUTINE_DBG_MEO00 ("bd499GetFunnelStackMemory");
    

	bool       bSuccessful = false;
    tsp00_Int4 totalPages  = 0;
    tsp00_Int4 unMapPages  = 0;

    bd20GetCacheSize( totalPages, unMapPages );

    vbegexcl (TaskId, g08permfdir);
    
    if (
        (m_MemoryAllocated                                   ) && 
        (cgg_nil_pid == m_FunnelStackUsedByTask              ) &&
        (g01index_file_list() * 3 < (totalPages - unMapPages))
        )
    {
        m_FunnelStackUsedByTask = TaskId;
        pFunnelStack            = tsp00_BytePtr (m_pFunnelStack);
        FunnelStackItems        = g01index_file_list();
		bSuccessful              = true;
    }
    vendexcl (TaskId, g08permfdir);
    
    return (bSuccessful);
}

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

void cbd499_IndexMemoryManagementUnit::bd499Init (tgg00_TransContext &Trans)
{
    ROUTINE_DBG_MEO00 ("bd499Init");
    
    tgg00_BasisError   &TrError = Trans.trError_gg00;
    /* */
    tsp00_Bool  bOkay;
    /* */
    const tsp00_Int4 ListItems        = g01index_file_list();
    const tsp00_Int4 FileListItemSize = cbd496_FileHandling::bd496GetFileListItemSize();
    const tsp00_Int4 FunnelItemSize   = cbd494_Funnel::bd494GetFunnelItemSize();
	const tsp00_Int4 QueueItemPtrSize = sizeof (tbd495_InvQueuePtr);
	const tsp00_Int4 QueueItemSize    = cbd495_DoubleReadQueue::bd495GetSize();
    const tsp00_Int4 SortItemSize     = sizeof (tbd494_SortItem);
	const tsp00_Int4 TotalFunnelSize  =	FunnelItemSize + QueueItemPtrSize + QueueItemSize + SortItemSize;

    // SizeofCheck: Code-Structure-Size versus Cserv.pcf-Size

    g01check (BD499_SIZEOFCHECK_SP03, csp3_n_memory, MEMORY_MSG_1_BD499, FileListItemSize,
        CSERV_FILE_LIST_ITEM_SIZE_BD499 == FileListItemSize);

    g01check (BD499_SIZEOFCHECK_SP03, csp3_n_memory, MEMORY_MSG_2_BD499, FunnelItemSize,
        CSERV_FUNNEL_ITEM_SIZE_BD499 == FunnelItemSize);

    g01check (BD499_SIZEOFCHECK_SP03, csp3_n_memory, MEMORY_MSG_3_BD499, QueueItemSize,
        CSERV_QUEUE_ITEM_SIZE_BD499 == QueueItemSize);

    g01check (BD499_SIZEOFCHECK_SP03, csp3_n_memory, MEMORY_MSG_3_BD499, SortItemSize,
        CSERV_SORT_ITEM_SIZE_BD499 == SortItemSize);

    if ((e_ok != TrError) || (ListItems <= 0) || (m_MemoryAllocated)) return;
    
    g01allocate_msg (csp3_n_dynpool, "INDEX FileListItemSize :", FileListItemSize);  
    
    g01allocate_msg (csp3_n_dynpool, "INDEX NumFileListItems :", ListItems);
    
    g01allocate_msg (csp3_n_dynpool, "INDEX FileListSizeAll  :", ListItems * FileListItemSize);
    
    vallocat (ListItems * FileListItemSize, &m_pFileList, &bOkay);
    
    if (bOkay) 
    {
        g01allocate_msg (csp3_n_dynpool, "INDEX FunnelItemSize   :", FunnelItemSize);
        
        g01allocate_msg (csp3_n_dynpool, "INDEX QueueItemPtrSize :", QueueItemPtrSize);
        
        g01allocate_msg (csp3_n_dynpool, "INDEX QueueItemSize    :", QueueItemSize);
        
        g01allocate_msg (csp3_n_dynpool, "INDEX SortItemSize     :", SortItemSize);
        
        g01allocate_msg (csp3_n_dynpool, "INDEX NumFunnelItems   :", ListItems);
        
        g01allocate_msg (csp3_n_dynpool, "INDEX FunnelSizeAll    :", ListItems * TotalFunnelSize);
        
        vallocat (ListItems * TotalFunnelSize, &m_pFunnelStack, &bOkay);
    }
    
    if (bOkay)
    {
        m_MemoryAllocated = true;
        
        g01allocate_msg (csp3_n_dynpool, "DYNP_B49_IDXSIZE       :",
            ListItems * (FileListItemSize + TotalFunnelSize));
        return;
    }
    TrError = e_sysbuf_storage_exceeded;
}

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

void cbd499_IndexMemoryManagementUnit::bd499ReleaseFileListMemory (tsp00_TaskId	TaskId)
{
    ROUTINE_DBG_MEO00 ("bd499ReleaseFileListMemory");
    

    vbegexcl (TaskId, g08permfdir);

    if ((m_MemoryAllocated) && (TaskId == m_FileListUsedByTask))
    {
        m_FileListUsedByTask = cgg_nil_pid;
    }
    vendexcl (TaskId, g08permfdir);
}

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

void cbd499_IndexMemoryManagementUnit::bd499ReleaseFunnelStackMemory (tsp00_TaskId	TaskId)
{
    ROUTINE_DBG_MEO00 ("bd499ReleaseFunnelStackMemory");
    

    vbegexcl (TaskId, g08permfdir);
    
	if ((m_MemoryAllocated) && (TaskId == m_FunnelStackUsedByTask))
    {
        m_FunnelStackUsedByTask = cgg_nil_pid;
    }
    vendexcl (TaskId, g08permfdir);
}

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

externC void bd499InitIndexMemory (tgg00_TransContext &Trans)
{
    cbd499_IndexMemoryManagementUnit::bd499Init (Trans);
}

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