/*!
    @file     SharedSQL_SQLCache.cpp
    @ingroup  SharedSQL
    @author   DirkT
    @brief    SQLCache for calling SharedSQL from SQLManager
    @see            

\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
*/

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

#include "SQLManager/SharedSQL/SharedSQL_SQLCache.hpp"
#include "SQLManager/SharedSQL/SharedSQL_CommandCache.hpp"
#include "SQLManager/SharedSQL/SharedSQL_CommandCacheStatistics.hpp"
#include "SQLManager/SharedSQL/SharedSQL_CommandCacheIterator.hpp"
#include "SAPDB/SQLManager/SharedSQL/SharedSQL_Messages.hpp"

#include "SAPDBCommon/SAPDB_Types.hpp"
#include "SAPDBCommon/ErrorsAndMessages/SAPDBErr_Assertions.hpp"
#include "SAPDBCommon/Tracing/SAPDBTrace_Usage.hpp"

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

//----------------------------------------------------------------------------
/*!
    @brief       constructor
    @param       Alloc        [in]
*/
SharedSQL_SQLCache::SharedSQL_SQLCache( SAPDBMem_IRawAllocator& Alloc ) :
//        mCommandCache(0),
        mParseIDCache(Alloc)
{
}

//----------------------------------------------------------------------------
/*!
    @brief       destructor - does nothing
*/
SharedSQL_SQLCache::~SharedSQL_SQLCache( void )
{
}

SharedSQL_PrepareHandle* SharedSQL_SQLCache::NewPrepareHandle( SAPDBMem_IRawAllocator& Alloc, SharedSQL_SQLContext& Context, SharedSQL_SQLStmt& Stmt, SAPDB_Bool Internal, SAPDB_Bool ParseAgain )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetPrepareHandle", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_TRUE))
        return CommandCache->NewPrepareHandle(Alloc, Context, Stmt, Internal, ParseAgain);
    else
        return 0;
}

void SharedSQL_SQLCache::DestroyPrepareHandle( SharedSQL_PrepareHandle* PH )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::DestroyPrepareHandle", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
      	CommandCache->DestroyPrepareHandle(PH);
    else
    {
        // this must never happen !!!
        RTE_Crash(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_ILLEGAL_OPERATION));
    }
}

SharedSQL_ExecuteHandle* SharedSQL_SQLCache::NewExecuteHandle( SAPDBMem_IRawAllocator& Alloc, const SharedSQL_ParseID& PID, bool CountExecuting, SAPDB_Bool& Valid, SAPDB_Bool& M9 )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetExecuteHandle", SharedSQL_Trace, 8);

	return mParseIDCache.NewExecuteHandle(Alloc, PID, CountExecuting, Valid, M9);
}

void SharedSQL_SQLCache::DestroyExecuteHandle( SharedSQL_ExecuteHandle* EH  )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::DestroyExecuteHandle", SharedSQL_Trace, 8);

	mParseIDCache.DestroyExecuteHandle(EH);
}

SAPDB_Bool SharedSQL_SQLCache::PutParseID( const SharedSQL_PrepareHandle* PH, const SharedSQL_ParseID& PID, const SharedSQL_ModuleName& ModuleName, const SAPDB_Bool M9 )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::PutParseID", SharedSQL_Trace, 8);

	return mParseIDCache.PutParseID(PH, PID, ModuleName, M9);
}

SAPDB_Bool SharedSQL_SQLCache::DropParseID( const SharedSQL_ParseID& PID )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::DropParseID", SharedSQL_Trace, 8);

	return mParseIDCache.DropParseID(PID);
}

const SharedSQL_ModuleName* SharedSQL_SQLCache::GetModuleName( const SharedSQL_ParseID& PID )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetModuleName", SharedSQL_Trace, 8);

	return mParseIDCache.GetModuleName(PID);
}

SAPDB_Bool SharedSQL_SQLCache::SetExecuteStatisticData(
                                    const SharedSQL_ParseID& PID,
                                    SharedSQL_CommandID& CommandID,
                                    SAPDB_UInt8 ExecuteTimeSec, SAPDB_UInt8 ExecuteTimeMicroSec,
                                    SAPDB_Int8 ReadRowCount, SAPDB_Int8 QualifiedRowCount,
                                    SAPDB_Int8 VirtualReadCount, SAPDB_Int8 PhysicalReadCount,
                                    SAPDB_Int8 FetchRowCount, 
                                    SAPDB_Int8 SuspendCount, SAPDB_Int8 WaitCount )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::SetExecuteStatisticData", SharedSQL_Trace, 8);

    return mParseIDCache.SetExecuteStatisticData(
                                        PID, CommandID,
                                        ExecuteTimeSec, ExecuteTimeMicroSec,
                                        ReadRowCount, QualifiedRowCount,
                                        VirtualReadCount, PhysicalReadCount,
                                        FetchRowCount, 
                                        SuspendCount, WaitCount);
}

void SharedSQL_SQLCache::GetCommandCacheInfo( SharedSQL_CommandCacheInfo& S )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetCommandCacheInfo", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->GetCacheInfo(S);
    else
        S = SharedSQL_CommandCacheInfo();
}

void SharedSQL_SQLCache::GetCommandCacheInfoReset( SharedSQL_CommandCacheInfo& S )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetCommandCacheInfoReset", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->GetCacheInfoReset(S);
    else
        S = SharedSQL_CommandCacheInfo();
}

void SharedSQL_SQLCache::ResetCommandCacheInfo( void )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::ResetCommandCacheInfo", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->ResetCacheInfo();
}

void SharedSQL_SQLCache::ResetCommandInfos( void )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::ResetCommandCacheInfo", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->ResetCommandInfos();
}

SharedSQL_CommandCacheIterator SharedSQL_SQLCache::GetCommandCacheIterator( void )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetCommandCacheIterator", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        return CommandCache->Begin();
    else
        return SharedSQL_CommandCacheIterator();
}

void SharedSQL_SQLCache::EnterLockForStatisticsIterator( void )
{
	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
	{
		SAPDB_UInt2& N = mParseIDCache.LocksForCommandCacheIterator();
		if ( !N )
		{
			++N;
			CommandCache->EnterLockForStatisticsIterator();
		}
	}
}

void SharedSQL_SQLCache::LeaveLockForStatisticsIterator( void )
{
	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
	{
		SAPDB_UInt2& N = mParseIDCache.LocksForCommandCacheIterator();
		--N;
		if ( !N )
		{
			CommandCache->LeaveLockForStatisticsIterator();
		}
	}
}

SAPDBMem_RawAllocator* SharedSQL_SQLCache::GetCommandCacheBaseRawAllocator( void )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetCommandCacheBaseRawAllocator", SharedSQL_Trace, 8);

#ifdef SHAREDSQL_PROTECT
	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_TRUE))
        return CommandCache->GetBaseAllocator();
    else
        return 0;
#else
    return 0;
#endif
}

void* SharedSQL_SQLCache::Allocate(SAPDB_ULong ByteCount)
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::Allocate", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_TRUE))
        return CommandCache->Allocate(ByteCount);
    else
        return 0;
}

void* SharedSQL_SQLCache::Allocate(SAPDB_ULong ByteCount, const void* Hint)
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::Allocate", SharedSQL_Trace, 8);

	if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_TRUE))
        return CommandCache->Allocate(ByteCount, Hint);
    else
        return 0;
}

void SharedSQL_SQLCache::Deallocate(void* p)
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::Deallocate", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->Deallocate(p);
    else
    {
        // this must never happen !!!
        RTE_Crash(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_ILLEGAL_OPERATION));
    }
}

void SharedSQL_SQLCache::CleanUpAll( void )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::CleanUpAll", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->CleanUpAll();
}

void SharedSQL_SQLCache::Invalidate( bool NotifyApplication )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::Invalidate", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->Invalidate(NotifyApplication);
}

void SharedSQL_SQLCache::Invalidate( SharedSQL_Schema Schema, bool NotifyApplication )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::Invalidate", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->Invalidate(Schema, NotifyApplication);
}

void SharedSQL_SQLCache::Invalidate( SharedSQL_TableTree* Tables, bool NotifyApplication )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::Invalidate", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->Invalidate(Tables, NotifyApplication);
}

void SharedSQL_SQLCache::GetBaseAllocatorCallStatistics( SAPDB_ULong &CountAlloc, SAPDB_ULong &CountDealloc ) const
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetBaseAllocatorCallStatistics", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->GetBaseAllocatorCallStatistics(CountAlloc, CountDealloc);
    else
        CountAlloc = CountDealloc = 0L;
}

void SharedSQL_SQLCache::GetCallStatistics( SAPDB_ULong &CountAlloc, SAPDB_ULong &CountDealloc ) const
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetCallStatistics", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        CommandCache->GetCallStatistics(CountAlloc, CountDealloc);
    else
        CountAlloc = CountDealloc = 0L;
}

SAPDB_ULong SharedSQL_SQLCache::GetAllocFailedCount( void ) const
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_SQLCache::GetAllocFailedCount", SharedSQL_Trace, 8);

    if (SharedSQL_CommandCache* CommandCache = SharedSQL_CommandCache::Instance(SAPDB_FALSE))
        return CommandCache->GetAllocFailedCount();
    else
        return 0;
}

//----------------------------------------------------------------------------
