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

  module      : vbd494.cpp

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

  author      : TorstenS
  responsible : TorstenS

  special area: FunnelHandling
  description : 


  last changed: 1999-10-20  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 "gbd494.h"

#include "gsp03.h"   // PASCAL: SP_message_constants_and_types
#include "gsp03_3.h" // PASCAL: SP_message_constants_and_types_for_bd_layer
#include "hgg01_1.h" // PASCAL: Configuration_Parameter

#include "heo56.h"   // RTE   : Vsleep


#if COMPILEMODE_MEO00 >= SLOW_MEO00 
#include "hta99.h"
#endif

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

#define OUT_OF_MEMORY_MSG_1_BD494   "Funnel Memory Exhausted                 "

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



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



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



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



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



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



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



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



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

void 
cbd494_Funnel::bd494Add(
                        bool            bIsQueue,
                        tsp00_PageNo    PrimQueuePno,
                        tsp00_PageNo    SecQueuePno)
{
    ROUTINE_DBG_MEO00 ("bd494Add");
    
    
    const tsp00_Int4    ObjSize = (bIsQueue) ? cbd495_DoubleReadQueue::bd495GetSize() : 
                                               cbd495_TempInvTree::bd495GetSize();
   	tsp00_Int4          RetryCount = 0;
    
    if (e_ok != m_TrError) return;
    
    if (m_Trans.trRteCommPtr_gg00->to_cancel)
    {
        m_TrError = e_cancelled;
        g01optextmsg (sp3p_knldiag, sp3m_info, BD494_CANCEL_1_SP03,
            csp3_n_index, CANCEL_MSG_1_BD494);
        return;
    }

    if (0 > m_QueueSpaceAvailable - ObjSize)
    {
        m_TrError = e_no_more_memory;
        g01optextmsg (sp3p_knldiag, sp3m_info, BD494_OUT_OF_MEMORY_SP03,
            csp3_n_index, OUT_OF_MEMORY_MSG_1_BD494);
        return;
    }
    
    do
    {
        if (e_sysbuffer_overflow == m_TrError)
        {
            ++RetryCount;
            m_TrError = e_ok;
            (*(m_ppQueue + m_NumMergeQueues))->~cbd495_InvQueue();
            
            vsleep (m_Trans.trTaskId_gg00, 1);
            g01optextmsg (sp3p_knldiag, sp3m_warning, BD494_OVERFLOW_2_SP03,
                csp3_n_index, MERGE_MSG_1_BD494);
        }

        if (bIsQueue)
        {
            *(m_ppQueue + m_NumMergeQueues) = 
                REINTERPRET_CAST (tbd495_InvQueuePtr, new (m_pQueue + m_QueuePos)	
                cbd495_DoubleReadQueue (m_QueueCurrent, PrimQueuePno, SecQueuePno));
        }
        else
        {
            tgg00_FileId    TempFileId = bd495InitTempFileId (PrimQueuePno);
            
            *(m_ppQueue + m_NumMergeQueues) = 
                REINTERPRET_CAST (tbd495_InvQueuePtr, new (m_pQueue + m_QueuePos)
                cbd495_TempInvTree (m_Trans, TempFileId, !DROP_TREE_BD495));
        }
    }
    while 
        (
        (e_sysbuffer_overflow == m_TrError) && (RetryCount < MAX_RETRIES_BD494)
        );

    if (e_ok != m_TrError)
    {
        (*(m_ppQueue + m_NumMergeQueues))->~cbd495_InvQueue(); // PTS 1105716 TS 2000-02-23
    }
    else
    {
        ++m_NumMergeQueues;
        m_QueuePos += ObjSize;
        m_QueueSpaceAvailable -= ObjSize;
    }
}

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

void 
cbd494_Funnel::bd494Merge(
                          cgg200_MergeTarget <tbd494_SortItemPtr> &DestinationFile)
{
    ROUTINE_DBG_MEO00 ("bd494Merge");
    
    
    if ((e_ok != m_TrError) || (0 > m_NumMergeQueues)) return;
    
    // Because of the cleverness of IBMs AIX SizeOfWorkingSpace and the
    // REINTERPRET_CAST is necessary
    
    const tsp00_Uint4 SizeOfWorkingSpace = bd494GetFunnelItemSize() * m_NumFunnelItems;
    
    bool bSuccess = gg200Merge (*this, DestinationFile, m_CompareOperator, 
        REINTERPRET_CAST (void*, m_pFunnel), SizeOfWorkingSpace);
    
    if ((!bSuccess) && (e_ok == m_TrError))
    {
        g01opmsg (sp3p_knldiag, sp3m_warning, BD494_ALLOCATE_1_SP03,
            csp3_n_index, MERGE_MSG_2_BD494 , SizeOfWorkingSpace);
        
        m_TrError = e_no_more_memory;
    }
}

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

bool 
cbd494_Funnel::gg200GetCurrentListElement(
                                          unsigned int		     CurrQueueIndex, 
                                          tbd494_SortItemPtr	&pSortItem)
{
    ROUTINE_DBG_MEO00 ("bd494GetCurrentListElement");
    
    
    pSortItem = m_pSortItem + CurrQueueIndex;

    return (*(m_ppQueue + CurrQueueIndex))->bd495GetCurrentItem(
        pSortItem->pPrimKey_bd494,
        pSortItem->pSecKey_bd494,
        pSortItem->PrimKeyLen_bd494,
        pSortItem->SecKeyLen_bd494,
        pSortItem->bNextSecKey_bd494,
        pSortItem->bLastPrimKey_bd494,
        pSortItem->bInvListRefNeeded_bd494);
    
     // Return false if no more key pair is available
}

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

bool
cbd494_SortableDoubleWriteQueue::gg200SetNextElement (tbd494_SortItemPtr    pSortItem)
{
    ROUTINE_DBG_MEO00 ("bd494SetNextDWQ");

/*
#	if COMPILEMODE_MEO00 >= SLOW_MEO00 
    
    t01sname (bd_idx_create, "Sec Key     ");
    t01buf   (bd_idx_create, pSortItem->pSecKey_bd494, 
        POS_OFF_DIFF_BD00, pSortItem->SecKeyLen_bd494);
    
    t01sname (bd_idx_create, "Prim Key    ");
    t01buf   (bd_idx_create, pSortItem->pPrimKey_bd494, 
        POS_OFF_DIFF_BD00, pSortItem->PrimKeyLen_bd494);
#   endif    
*/
    if (e_ok == m_TrError) 	
    {
        ++m_NumPrimKeys;
        m_MinRequiredPrimKeySpace += pSortItem->PrimKeyLen_bd494;
        
        bd494_PushPrimKey (pSortItem->pPrimKey_bd494, pSortItem->PrimKeyLen_bd494);
        
        if (pSortItem->bLastPrimKey_bd494)
        {
/*
#           if COMPILEMODE_MEO00 >= SLOW_MEO00 
            t01bool (bd_idx_create, "LastPrimKey ", true);
            t01int4 (bd_idx_create, "NumPrimKeys ", m_NumPrimKeys);
#           endif
*/            
            bd495PushNumPrimKeys (m_NumPrimKeys);
            bd495PushMinRequiredPrimKeySpace (m_MinRequiredPrimKeySpace);
            
            bd494_PushSecKey (pSortItem->pSecKey_bd494, pSortItem->SecKeyLen_bd494);
            
            m_NumPrimKeys             = 0;
            m_MinRequiredPrimKeySpace = 0;
        }
    }
#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
    t01basis_error (bd_idx_create, "SetNextDWQ  ", m_TrError);
#   endif
    

    return e_ok == m_TrError;
}

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

bool
cbd494_SortableInvTree::gg200SetNextElement (tbd494_SortItemPtr    pSortItem)
{
    ROUTINE_DBG_MEO00 ("bd494SetNextInvTree");
    
/*    
#	if COMPILEMODE_MEO00 >= SLOW_MEO00 
    
    t01sname (bd_idx_create, "Sec Key     ");
    t01buf   (bd_idx_create, pSortItem->pSecKey_bd494, 
        POS_OFF_DIFF_BD00, pSortItem->SecKeyLen_bd494);
    
    t01sname (bd_idx_create, "Prim Key    ");
    t01buf   (bd_idx_create, pSortItem->pPrimKey_bd494, 
        POS_OFF_DIFF_BD00, pSortItem->PrimKeyLen_bd494);
#   endif    
*/    
    if (e_ok == m_TrError) 	
    {
/*
#       if COMPILEMODE_MEO00 >= SLOW_MEO00 
        t01bool (bd_idx_create, "NextSecKey  ", pSortItem->bNextSecKey_bd494);
#       endif
*/
        if (pSortItem->bNextSecKey_bd494)
        {
            ++m_SecKeyCount;
/*            
#           if COMPILEMODE_MEO00 >= SLOW_MEO00 
            t01bool (bd_idx_create, "InvListRef  ", pSortItem->bInvListRefNeeded_bd494);
#           endif
*/
        }
        
        if (m_SubTreeCurrent.curr_trans->trRteCommPtr_gg00->to_cancel)
        {
            m_TrError = e_cancelled;
            g01optextmsg (sp3p_knldiag, sp3m_info, BD494_CANCEL_2_SP03,
                csp3_n_index, CANCEL_MSG_2_BD494);
        }
        else
            this->bd400AppendPrimKey (
            pSortItem->pSecKey_bd494, pSortItem->SecKeyLen_bd494,
            pSortItem->pPrimKey_bd494, pSortItem->PrimKeyLen_bd494,
            0 != pSortItem->bNextSecKey_bd494,       /* PTS 1104438 UH 03-12-1999 */
            0 != pSortItem->bInvListRefNeeded_bd494, /* PTS 1104438 UH 03-12-1999 */
            m_InvRecIndex);
    }
#   if COMPILEMODE_MEO00 >= SLOW_MEO00 
    t01basis_error (bd_idx_create, "SetNextInv  ", m_TrError);
#   endif
    
    return e_ok == m_TrError;
}

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