Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions

SharedSQL_CommandCache.cpp

Go to the documentation of this file.
/*!
    @file     SharedSQL_CommandCache.cpp
    @ingroup  SharedSQL
    @author   DirkT
    @brief    Cache for SQLCommands, shared
    @see            

\if EMIT_LICENCE
    ========== licence begin  GPL
    Copyright (c) 2000-2004 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_CommandCache.hpp"
#include "SQLManager/SharedSQL/SharedSQL_CommandCacheIterator.hpp"
#include "SQLManager/SharedSQL/SharedSQL_Command.hpp"
#include "SQLManager/SharedSQL/SharedSQL_Handles.hpp"
#include "SQLManager/SharedSQL/SharedSQL_Plan.hpp"
#include "SQLManager/SharedSQL/SharedSQL_Types.hpp"
#include "SQLManager/SharedSQL/SharedSQL_Messages.hpp"

#include "SQLManager/SQLMan_Context.hpp"

#if defined(FDIR_DEV)
#include "FileDirectory/FileDir_ISharedDirectory.hpp" /* &variant +fdir */
#include "FileDirectory/FileDir_Types.hpp"            /* &variant +fdir */
#include "stdlib.h"                                   /* nocheck */
#endif

#include "SAPDBCommon/SAPDB_MemCopyMove.hpp"
#include "SAPDBCommon/SAPDB_Singleton.hpp"
#include "SAPDBCommon/SAPDB_Types.hpp"
#include "SAPDBCommon/Algorithms/SAPDBAlgo_FNVHash.hpp"
#include "SAPDBCommon/ErrorsAndMessages/SAPDBErr_Assertions.hpp"
#include "SAPDBCommon/ErrorsAndMessages/SAPDBErr_MessageList.hpp"
#include "SAPDBCommon/MemoryManagement/SAPDBMem_NewDestroy.hpp"
#include "SAPDBCommon/MemoryManagement/SAPDBMem_SynchronizedRawAllocator.hpp"
#include "SAPDBCommon/Tracing/SAPDBTrace_Usage.hpp"

#include "KernelCommon/ParameterNames/KernelParam_SharedSQL.hpp"

#include "RunTime/MemoryManagement/RTEMem_RawAllocator.hpp"
#include "RunTime/MemoryManagement/RTEMem_BlockAllocator.hpp"
#include "RunTime/Configuration/RTEConf_ParameterAccessKernelInterface.hpp"
#include "RunTime/System/RTESys_AtomicOperation.hpp"
#include "RunTime/RTE_Message.hpp"

#include "ggg00.h"
#include "hgg04.h"
#include "hbd01.h"
#include "hbd02.h"
#include "heo58.h"

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

SharedSQL_ICommandCache* SharedSQL_CommandCache::mInstance = (SharedSQL_ICommandCache*) 0;

00079 SharedSQL_ICommandCache* SharedSQL_CommandCache::Instance( SAPDB_Bool Create )
{
    static RTESync_Spinlock lock;
    RTESync_LockedScope scope(lock);

    if ( !mInstance && Create )
    {
        // first read installation parameters from cserv.pcf
        SAPDBErr_MessageList        errMsg;
        RTEConf_Parameter::Integer  Param_CacheSizeKB;
        RTEConf_Parameter::Integer  Param_ExpectedStatements;

        if( RTEConf_ParameterAccess::Instance()->GetInteger( UTF8( KERNELPARAM_SHAREDSQL_COMMANDCACHESIZE ), Param_CacheSizeKB, errMsg ))
        {
            if( ! RTEConf_ParameterAccess::Instance()->GetInteger( UTF8( KERNELPARAM_SHAREDSQL_EXPECTEDSTATEMENTCOUNT ), Param_ExpectedStatements, errMsg ))
                RTE_Crash( errMsg );
        }
        else
        {
            RTE_Crash( errMsg );
        }

        // and then calculate the 'real' parameters...

        SAPDB_ULong Size    = (SAPDB_ULong)( Param_CacheSizeKB >= 8*1024L ? Param_CacheSizeKB : 8*1024L );

        int SizeCategory;
        if ( Param_ExpectedStatements > 1024 )           // > 2**10
        {
            if ( Param_ExpectedStatements > 4096 )       // > 2**12
            {
                if ( Param_ExpectedStatements > 8192 )   // > 2**13
                    SizeCategory = 14;
                else
                    SizeCategory = 13;
            }
            else                                         // <= 2**12
            {
                if ( Param_ExpectedStatements > 2048 )   // > 2**11
                    SizeCategory = 12;
                else
                    SizeCategory = 11;
            }
        }
        else                                             // <= 2**10
        {
            if ( Param_ExpectedStatements > 256 )        // > 2**8
            {
                if ( Param_ExpectedStatements > 512 )    // > 2**9
                    SizeCategory = 10;
                else
                    SizeCategory = 9;
            }
            else                                         // <= 2**8
            {
                if ( Param_ExpectedStatements > 128 )    // > 2**7
                    SizeCategory = 8;
                else
                    SizeCategory = 7;
            }
        }

        SharedSQL_HashValue Slots                       = (SharedSQL_HashValue) (1 << (SizeCategory+1)); // min:256 max:16384
        SharedSQL_HashValue SpinLockPoolForSlotsSize    = (SharedSQL_HashValue) (1 << (SizeCategory-2)); // min: 32 max:2048
        SharedSQL_HashValue SpinLockPoolForCommandsSize = (SharedSQL_HashValue) (1 << (SizeCategory-3)); // min: 16 max:1024
        
        mInstance = new(RTEMem_RawAllocator::Instance()) SharedSQL_CommandCache(Size, Slots, SpinLockPoolForSlotsSize, SpinLockPoolForCommandsSize);
        if ( !mInstance )        
            RTE_Crash(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_CREATE_INSTANCE));
    }
    return mInstance;
}

//----------------------------------------------------------------------------
00153 SharedSQL_CommandCache::SharedSQL_CommandCache( SAPDB_ULong KBSize, SharedSQL_HashValue Slots, 
                                                SharedSQL_HashValue SpinLockPoolSlotsSize,
                                                SharedSQL_HashValue SpinLockPoolCommandsSize ) :
    SAPDB_Singleton(),
    mAllocator(  (const SAPDB_UTF8 *) "CommandCacheAllocator",
                RTEMem_BlockAllocator::Instance(),
                KBSize*512,          // FirstBlockSize      = MaxCacheSize/2
                KBSize*256,          // SupplementBlockSize = MaxCacheSize/4
                SAPDBMem_RawAllocator::FREE_RAW_EXTENDS,
                KBSize*1024          // MaxCacheSize
              ),
    mTempFileState(NoFile),
    mActCommandID(0),
    //
      mHashTable(newarray(mHashTable, Slots, mAllocator)),
    //
    // RWRegions
    mSpinLockPoolForSlots((const SAPDB_UTF8 *)"CommandCache:SlotLock", SpinLockPoolSlotsSize, mAllocator),
    mSpinLockPoolForCommands((const SAPDB_UTF8 *)"CommandCache:CommandLock", SpinLockPoolCommandsSize, mAllocator),
    mSpinLockPoolForOthers((const SAPDB_UTF8 *)"CommandCache:DivLock", 2, mAllocator),
    mpLRULock(RTESync_CreateRWRegion(1, mSpinLockPoolForOthers, mAllocator)),
    mpCleanUpLock(RTESync_CreateRWRegion(2, mSpinLockPoolForOthers, mAllocator)),
    mpCreateFileLock(RTESync_CreateRWRegion(2, mSpinLockPoolForOthers, mAllocator)),
    mpStatisticsLock(RTESync_CreateRWRegion(3, mSpinLockPoolForOthers, mAllocator)),
    mpSlotLocks( (RTESync_IRWRegion**)mAllocator.Allocate(Slots * sizeof(RTESync_IRWRegion *) )),
    //
    mNumberOfSlots(Slots),
    mFirstLRUCommand(0),
    mLastLRUCommand(0),
    mMiddleLRUCommand(0),
    mLRUCounter(0),
    mCacheInfo(),
    mCacheInfoReset()
{
    if ( mpLRULock==NULL ||
         mpCleanUpLock==NULL ||
         mpCreateFileLock==NULL ||
         mpStatisticsLock==NULL )
    {
        RTE_Crash(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_CREATE_INSTANCE));
    }
    if ( mHashTable && mpSlotLocks )
    {
        for (SharedSQL_HashValue i=0; i<mNumberOfSlots; i++) 
        {
            mHashTable[i] = 0;
            mpSlotLocks[i] = RTESync_CreateRWRegion(i+1, mSpinLockPoolForSlots, mAllocator);
            if ( mpSlotLocks[i]==0 )
                RTE_Crash(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_CREATE_INSTANCE));
        }
    }
    else
    {
        RTE_Crash(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_CREATE_INSTANCE));
    }
    mAllocator.DisableOpMessages();

#if defined(FDIR_DEV)
    FileId fileId = FileDir_ISharedDirectory::Instance().GetNewTempFileId();
    SAPDB_MemCopyNoCheck( &mCacheTableId, &fileId, sizeof(fileId) );
#else
    mCacheTableId.rawAssign( cgg_sys3_commandcache_id );
#endif

#ifdef SHAREDSQL_PROTECT
    mAllocator.WriteProtect();  // DDT: has to be removed after testing !
#endif

    mErrorInitialising = SAPDB_FALSE;
}

00224 SharedSQL_CommandCache::~SharedSQL_CommandCache( void )
{
    if ( mHashTable )
    {
          for (SharedSQL_HashValue i=0; i<mNumberOfSlots; i++)
        {
                if ( SharedSQL_CachedCommand* Act = mHashTable[i] )
                {
                      SharedSQL_CachedCommand* Next;
                      do 
                      {
                            Next = Act->NextHashCommand();
                    if ( Act->SQLStmt().mStmt )
                    {
                        Deallocate(Act->SQLStmt().mStmt);
                        Act->SQLStmt().mStmt = 0;
                    }
                    destroy(Act, *this);                       
                      --mCacheInfo.CommandCount;
                            Act = Next;
                      }while(Act);
                }
        }
      destroyarray(mHashTable, mNumberOfSlots, mAllocator);
    }
    SAPDBERR_ASSERT_STATE( mCacheInfo.CommandCount == 0 ); // DDT
    mInstance = (SharedSQL_CommandCache*) 0;
    if ( mpLRULock )
        RTESync_DestroyRWRegion(mpLRULock, mAllocator);
    if ( mpCleanUpLock )
        RTESync_DestroyRWRegion(mpCleanUpLock, mAllocator);
    if ( mpCreateFileLock )
        RTESync_DestroyRWRegion(mpCreateFileLock, mAllocator);
    if ( mpStatisticsLock )
        RTESync_DestroyRWRegion(mpStatisticsLock, mAllocator);
    for (SharedSQL_HashValue j=0; j<mNumberOfSlots; j++)
    {
        if (mpSlotLocks[j])
            RTESync_DestroyRWRegion(mpSlotLocks[j], mAllocator);
    }
    //if ( mSlotLocks )
    //      destroyarray(mSlotLocks, mNumberOfSlots, mAllocator);
}

//----------------------------------------------------------------------------
00269 SharedSQL_IPrepareHandle* SharedSQL_CommandCache::NewPrepareHandle( SAPDBMem_IRawAllocator& Alloc, SharedSQL_SQLContext& Context, SharedSQL_SQLStmt& Stmt, SAPDB_Bool Internal )
{
    SAPDBTRACE_METHOD_DEBUG("SharedSQL_CommandCache::GetPrepareHandle", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Stmt.mStmt != 0 );

    ++mCacheInfoReset.AccessCountPrepare; 
      SharedSQL_HashValue Hash = CalcHashValue(Context, Stmt);
    SharedSQL_HashValue Slot = CalcSlot(Hash);
    SAPDB_Int2 ChainEntryCount = 0;

    if ( Internal )                   // Don't store userid for internal commands
        memset(Context.UserID, 0, sizeof(SharedSQL_UserID));

    SharedSQL_LockedScope Lock1((mpSlotLocks[Slot]), SharedSQL_LockedScope::Exclusive);
    if ( SharedSQL_CachedCommand* ActCommand = mHashTable[Slot] )
      {
            do
            {
            ++ChainEntryCount;
                  if (    ActCommand->GetHashValue()==Hash     && 
                    ActCommand->SQLContext()==Context &&        
                    ActCommand->SQLStmt().mStmtSize==Stmt.mStmtSize &&
                    ActCommand->SQLStmt().mDescriptionSize==Stmt.mDescriptionSize)  
            {
                ActCommand->EnterLock(1);
                if ( ActCommand->GetFlgExtern() )
                {
                    SQLMan_Context* pContext = (SQLMan_Context*) vGetAcvPtrFromCurrentTask();
                    tgg00_TransContext& TransContext = pContext->TransContext();

                    if (!ReloadSQLStmt(TransContext, ActCommand))
                    {
                        RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_COMPARE_COMMANDS));
                        // No return. Just continue!
                    }
                }
                        if ( ActCommand->SQLStmt() == Stmt )
                        {
                    SharedSQL_PrepareHandle* H = new(Alloc) SharedSQL_PrepareHandle(&Alloc, ActCommand);
                    ActCommand->LeaveLock(1);

                    ActCommand->Plan().EnterLock(0);
                    SharedSQL_CommandStatus OldStatus;
                    if ( (OldStatus=ActCommand->GetStatus()) != Prepared )
                    {
                        ActCommand->Plan().LeaveLock(0); 
                        ActCommand->Plan().EnterLock(1);
                        if ( (OldStatus=ActCommand->GetStatus()) != Prepared )  // check if still not prepared 
                        {
                                    ++mCacheInfoReset.UnSuccessfulAccessCountPrepare;
                            ActCommand->Plan().Drop(true);
                          ActCommand->Statistics().IncTotalPrepareCount();
                            ActCommand->SetStatus(Preparing);
                            H->SetMustPrepare(SAPDB_TRUE); 
                        }
                        else
                        {
                            ++mCacheInfoReset.SuccessfulAccessCountPrepare;
                            ActCommand->Plan().SwitchLockToNonExclusive();
                          H->SetMustPrepare(SAPDB_FALSE); 
                        }
                        H->SetOldStatus(OldStatus);
                    }
                    else
                    {
                              ++mCacheInfoReset.SuccessfulAccessCountPrepare;
                          H->SetMustPrepare(SAPDB_FALSE); 
                        H->SetOldStatus(OldStatus);
                    }
                    ActCommand->SetInternal(Internal);
                    SHARED_SQL_TRACE ("SharedSQL_CommandCache FoundCmd[" << ToStr(ActCommand->GetCommandID()) << "]");
                    return H;
                        }
                ActCommand->LeaveLock(1);
            }
        }while ( ActCommand = ActCommand->NextHashCommand() );
    }
      // Command is NOT in the list - create and insert at first position

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // Allocate Buffer for Stmt AND Description!!! 
    //  The Statement will start with Buffer[0], 
    //  the description will start with Buffer[mStmtSize] 
    // ATTENTION: Within SharedSQL it will be assumed that there was only one buffer allocated ! 
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    void* Buffer = 0;
    long  BuffLen = Stmt.mStmtSize + Stmt.mDescriptionSize;
    if ( Stmt.mStmtSize>0 && Stmt.mStmt )
    {
        Buffer = Allocate(BuffLen);
    }
    if ( Buffer )
    {
        void* StmtStr = Buffer;
        void* DescStr = 0;

        SAPDB_MemCopyNoCheck(StmtStr, Stmt.mStmt, Stmt.mStmtSize);

        if ( Stmt.mDescriptionSize>0 && Stmt.mDescription )
        {
            DescStr = ((char*)Buffer) + Stmt.mStmtSize;
            SAPDB_MemCopyNoCheck(DescStr, Stmt.mDescription, Stmt.mDescriptionSize);
        }

        SharedSQL_SQLStmt SQLStmt(StmtStr, Stmt.mStmtSize, DescStr, Stmt.mDescriptionSize);

        SharedSQL_CachedCommand* NewCommand = new(*this) SharedSQL_CachedCommand(NewCommandID(), Hash, Slot, *this, *this, Context, SQLStmt, Internal, mSpinLockPoolForCommands);
        if ( NewCommand )
        {
            if ( NewCommand->CompletelyConstructed() )
            {
                SHARED_SQL_TRACE ("SharedSQL_CommandCache InsertCmd[" << ToStr(NewCommand->GetCommandID()) << "]");

                ++mCacheInfo.CommandCount;
                if ( mCacheInfo.CommandCount > mCacheInfo.MaxCommandCount )
                    mCacheInfo.MaxCommandCount = mCacheInfo.CommandCount;
                ++mCacheInfoReset.InsertCommandCount;
                ++mCacheInfoReset.UnSuccessfulAccessCountPrepare;
                ++ChainEntryCount;
                if ( ChainEntryCount > mCacheInfoReset.HashTab_MaxChainEntryCount )
                {
                    mCacheInfoReset.HashTab_MaxChainEntryCount = ChainEntryCount;
                }
                {   // HastTable[Slot] is already locked !
                    SharedSQL_LockedScope Lock3(mpLRULock, SharedSQL_LockedScope::Exclusive);
                    AttachCommand(NewCommand);
                }
                SharedSQL_PrepareHandle* H = new(Alloc) SharedSQL_PrepareHandle(&Alloc, NewCommand);
                NewCommand->Plan().EnterLock(1);
                  NewCommand->Statistics().IncTotalPrepareCount();
                NewCommand->SetStatus(Preparing);
                H->SetOldStatus(New);
                H->SetMustPrepare(SAPDB_TRUE); 
                return H;
            }
            else
            {
                destroy(NewCommand, *this);
            }
        }
    }
    if ( Buffer )
        Deallocate(Buffer);

    RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_CREATE_COMMAND));
    return 0;
}

00417 void SharedSQL_CommandCache::DestroyPrepareHandle( SharedSQL_IPrepareHandle* PH )
{
    SharedSQL_PrepareHandle* Handle = REINTERPRET_CAST(SharedSQL_PrepareHandle*, PH);
    destroy(Handle, Handle->GetAllocator());
    PH = 0;
}

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

00426 void SharedSQL_CommandCache::IncAccessCountExecute( void )              
{ 
    ++mCacheInfoReset.AccessCountExecute; 
}

00431 void SharedSQL_CommandCache::IncSuccessfulAccessCountExecute( void )    
{ 
    ++mCacheInfoReset.SuccessfulAccessCountExecute; 
}

00436 void SharedSQL_CommandCache::IncUnSuccessfulAccessCountExecute( void )  
{ 
    ++mCacheInfoReset.UnSuccessfulAccessCountExecute; 
}

//----------------------------------------------------------------------------
00442 inline SharedSQL_CommandID SharedSQL_CommandCache::NewCommandID( void )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::NewCommandID", SharedSQL_Trace, 8);
    return RTESys_AtomicModify((SAPDB_UInt8&)mActCommandID, (SAPDB_Int8)1);
}

//----------------------------------------------------------------------------
00449 inline SharedSQL_HashValue    SharedSQL_CommandCache::CalcHashValue( const SharedSQL_SQLContext& Context, const SharedSQL_SQLStmt& Stmt )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::CalcHashValue", SharedSQL_Trace, 8);
    SAPDBERR_ASSERT_ARGUMENT( Stmt.mStmt != 0 && Stmt.mStmtSize > 0 );

    SharedSQL_HashValue Hash = FNV_32_INIT;
    FNV32Hash((void*)Stmt.mStmt, Stmt.mStmtSize, Hash); 
      if ( Stmt.mDescriptionSize > 0 )
            FNV32Hash((void*)Stmt.mDescription, Stmt.mDescriptionSize, Hash); 
    FNV32Hash((void*)&Context.UserID, sizeof(Context.UserID), Hash);
    return Hash;
}

//----------------------------------------------------------------------------
00463 void* SharedSQL_CommandCache::Allocate( SAPDB_ULong ByteCount )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::Allocate(ByteCount)", SharedSQL_Trace, 5);
    
    SharedSQL_LockedScope Lock1(mpCleanUpLock, SharedSQL_LockedScope::Exclusive);
    void* Mem = mAllocator.Allocate(ByteCount); 
    if ( !Mem )
    {
        SQLMan_Context* pContext = (SQLMan_Context*) vGetAcvPtrFromCurrentTask();
        tgg00_TransContext& TransContext = pContext->TransContext();

        SharedSQL_LockedScope Lock3(mpLRULock, SharedSQL_LockedScope::Exclusive);

        ++mCacheInfoReset.CleanUpCount;
        SharedSQL_CachedCommand* Act = mLastLRUCommand;
        SharedSQL_CachedCommand* Next;

        while ( !Mem && Act )
        {
            Next = Act->PrevLRUCommand();
            if ( Act->TryEnterLock(1) )
            {
                if (CleanUpCommand(TransContext, Act, SAPDB_TRUE))
                    Act->LeaveLock(1);
                Mem = mAllocator.Allocate(ByteCount);
            }
            Act = Next;
        };

        if ( !Mem )
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_ALLOCATE_MEMORY));
            ++mCacheInfoReset.FailedAllocateCount;
        }
    }
    return Mem;
}

//----------------------------------------------------------------------------
00502 void* SharedSQL_CommandCache::Allocate( SAPDB_ULong ByteCount, const void* Hint )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::Allocate(ByteCount,Hint)", SharedSQL_Trace, 5);
    return Allocate(ByteCount);
}

00508 void SharedSQL_CommandCache::Deallocate( void* p )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::Deallocate", SharedSQL_Trace, 5);

    mAllocator.Deallocate(p);
}

//----------------------------------------------------------------------------
00516 void SharedSQL_CommandCache::CleanUpAll( void )
{
    SHARED_SQL_TRACE ("SharedSQL_CommandCache::CleanUpAll");
    
    SQLMan_Context* pContext = (SQLMan_Context*) vGetAcvPtrFromCurrentTask();
    tgg00_TransContext& TransContext = pContext->TransContext();

    SharedSQL_LockedScope Lock1(mpCleanUpLock, SharedSQL_LockedScope::Exclusive);
    SharedSQL_LockedScope Lock3(mpLRULock, SharedSQL_LockedScope::Exclusive);

    ++mCacheInfoReset.CleanUpCount;
    SharedSQL_CachedCommand* Act = mLastLRUCommand;
    SharedSQL_CachedCommand* Next;

    while ( Act )
    {
        Next = Act->PrevLRUCommand();
        if ( Act->TryEnterLock(1) )
        {
            if ( CleanUpCommand(TransContext, Act, SAPDB_FALSE) )  // FALSE: No unload to tempfile
                Act->LeaveLock(1);
        }
        Act = Next;
    };
}

//----------------------------------------------------------------------------
00543 void SharedSQL_CommandCache::InvalidateAll( void )
{
    SHARED_SQL_TRACE ("SharedSQL_CommandCache::InvalidateAll");
    
    SharedSQL_LockedScope Lock3(mpLRULock, SharedSQL_LockedScope::Exclusive);

    ++mCacheInfoReset.InvalidateCount;
    SharedSQL_CachedCommand* Act = mFirstLRUCommand;

    while ( Act )
    {
        Act->SetStatus(Invalid);
        Act = Act->NextLRUCommand();
    };
}


00560 void SharedSQL_CommandCache::ResetCommandInfos( void )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::ResetCommandInfos", SharedSQL_Trace, 5);
    
    SharedSQL_LockedScope Lock3(mpLRULock, SharedSQL_LockedScope::Exclusive);

    SharedSQL_CachedCommand* Act = mLastLRUCommand;
    while ( Act )
    {
        Act->ResetStatisticsInfo();
        Act = Act->PrevLRUCommand();
    };
}

//----------------------------------------------------------------------------
00575 inline SAPDB_Bool SharedSQL_CommandCache::CleanUpCommand( tgg00_TransContext& TransContext, SharedSQL_CachedCommand* Command, SAPDB_Bool FlgUnload )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::FreeMaximumOfMemoryForCommand", SharedSQL_Trace, 8);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );

    ++mCacheInfoReset.CleanUpCommandCount; 
    if ( !Command->GetPrepareCount()   &&
         !Command->GetParseIDCount()   &&
         !Command->GetExecuteCount()     )           // No handles: Stmt can be deleted
    {
        SharedSQL_HashValue Slot = CalcSlot(Command->GetHashValue());
        if ( mpSlotLocks[Slot]->tryEnter(1) )
        {
            if ( Command->Plan().TryEnterLock(1) )
            {
                SHARED_SQL_TRACE ("SharedSQL_CommandCache DestroyCmd[" << ToStr(Command->GetCommandID()) << "]");
                if ( Command->SQLStmt().mStmt )
                {
                    Deallocate(Command->SQLStmt().mStmt);
                    Command->SQLStmt().mStmt = 0;
                }
                if ( Command->GetFlgExtern() )
                {
                    DeleteUnloadedSQLStmt(TransContext, Command);
                }
                DetachCommand(Command);
                Command->Plan().LeaveLock(1);
                mpSlotLocks[Slot]->leave(1);
                destroy(Command, *this);
                ++mCacheInfoReset.DeleteCommandCount;
              --mCacheInfo.CommandCount;
                return (SAPDB_FALSE);
            }
            mpSlotLocks[Slot]->leave(1);
        }
    }

    if ( !Command->GetExecuteCount() && 
         !Command->GetPrepareCount() )            // Plan can be deleted
    {
        if ( Command->Plan().TryEnterLock(1) )
        {
            DeletePlan(Command);
            Command->Plan().LeaveLock(1);
        }
    }
    if ( FlgUnload &&
        !Command->GetFlgExtern())                 // SQLStmt can be flushed
    {
        UnloadSQLStmt(TransContext, Command);
    }
    return (SAPDB_TRUE);
}


00630 SAPDBMem_RawAllocator* SharedSQL_CommandCache::GetBaseAllocator( void )
{
#ifdef SHAREDSQL_PROTECT
    return &mAllocator;
#else
    return 0;
#endif
}

//----------------------------------------------------------------------------
00640 void SharedSQL_CommandCache::GetBaseAllocatorCallStatistics( SAPDB_ULong &CountAlloc, SAPDB_ULong &CountDealloc ) const 
{
    mAllocator.GetBaseAllocatorCallStatistics(CountAlloc, CountDealloc);
}

//----------------------------------------------------------------------------
00646 void SharedSQL_CommandCache::GetCallStatistics( SAPDB_ULong &CountAlloc, SAPDB_ULong &CountDealloc ) const
{
    mAllocator.GetCallStatistics(CountAlloc, CountDealloc);
}

//----------------------------------------------------------------------------
00652 int SharedSQL_CommandCache::GetErrorCount( void ) const 
{
    return mCacheInfo.FailedAllocateCount; 
}

//----------------------------------------------------------------------------
00658 inline SAPDB_Bool SharedSQL_CommandCache::UnloadSQLStmt( tgg00_TransContext& TransContext, SharedSQL_CachedCommand* Command )
{
    // Command has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::FlushSQLStmt", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );

    if ( !Command->GetFlgExtern() )
    {
        if ( WriteSQLStmtToTempFile(TransContext,Command->GetCommandID(), &(Command->SQLStmt())) )
        {
            Deallocate(Command->SQLStmt().mStmt); // mStmt points to the memory allocated for mStmt+mDescription !!!
            Command->SQLStmt().mStmt = 0;
            Command->SQLStmt().mDescription = 0;
            Command->SetFlgExtern(SAPDB_TRUE);
            ++mCacheInfoReset.UnloadStmtCount; 
            ++mCacheInfoReset.CurrentUnloadStmtCount;
        }
        else
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_UNLOAD_DATA));
            return SAPDB_FALSE;
        }
    }
      return SAPDB_TRUE;
}

//----------------------------------------------------------------------------
00685 SAPDB_Bool SharedSQL_CommandCache::ReloadSQLStmt( tgg00_TransContext& TransContext, SharedSQL_ICachedCommand* Command )
{
    // Command has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::ReloadSQLStmt", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );

    if ( Command->GetFlgExtern() )
    {
        long BuffLen = Command->SQLStmt().mStmtSize + Command->SQLStmt().mDescriptionSize;
        Command->SQLStmt().mStmt = Allocate(BuffLen);
        if ( Command->SQLStmt().mStmt != 0 )
        {
            if ( ReadSQLStmtFromTempFile(TransContext, Command->GetCommandID(), &(Command->SQLStmt())) )
            {
                DeleteSQLStmtFromTempFile(TransContext, Command->GetCommandID(), &(Command->SQLStmt()));
                Command->SetFlgExtern(SAPDB_FALSE);     
                ++mCacheInfoReset.ReloadStmtCount; 
                --mCacheInfoReset.CurrentUnloadStmtCount;
                  return SAPDB_TRUE;
            }
            else
            {
                RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_RELOAD_DATA));
                Deallocate(Command->SQLStmt().mStmt);
                Command->SQLStmt().mStmt = 0;
            }
        }
        else
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_RELOAD_DATA));
        }
    }
    return SAPDB_FALSE;
}

//----------------------------------------------------------------------------
00721 SAPDB_Bool SharedSQL_CommandCache::DeleteUnloadedSQLStmt( tgg00_TransContext& TransContext, SharedSQL_ICachedCommand* Command )
{
    // Command has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::DeleteUnloadedSQLStmt", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );

    if ( Command->GetFlgExtern() )
    {
        if ( DeleteSQLStmtFromTempFile(TransContext, Command->GetCommandID(), &(Command->SQLStmt())) )
        {
            Command->SetFlgExtern(SAPDB_FALSE); 
            ++mCacheInfoReset.UnloadStmtCount;
        }
        else
        {
            // RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_DELETE_DATA));
            return SAPDB_FALSE;
        }
    }
      return SAPDB_TRUE;
}

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

/// ...
00746 #define MaxTempFileRecSize  MAX_RECLEN_GG00    // MaximumSize of One Record within the TempFile

//----------------------------------------------------------------------------
00749 inline void SharedSQL_CommandCache::GetTempFileID( tgg00_TransContext& TransContext, tgg00_FileId& FileID )
{
    g04build_temp_tree_id(FileID, TransContext);
    FileID.fileTabId_gg00() = mCacheTableId;
    FileID.fileTfn_gg00().becomes(tfnTemp_egg00);
    FileID.fileTfnTemp_gg00().becomes(ttfnPars_egg00);
    FileID.fileType_gg00().addElement(ftsTemp_egg00);
    FileID.fileType_gg00().addElement(ftsConcurrent_egg00);
    FileID.fileType_gg00().addElement(ftsShared_egg00);
}

//----------------------------------------------------------------------------
00761 inline void SharedSQL_CommandCache::GetLKey(SharedSQL_CommandID ID, int PartNo, tgg00_Lkey& Key, int& KeyLen)
{
    KeyLen = 2+sizeof(SharedSQL_CommandID);

    Key.keyRecLenSpace_gg00() = cgg_rec_key_offset+KeyLen;
    Key.keyLen_gg00() = KeyLen;
    Key.keyVarOffSpace_gg00() = 0;
    Key.keyVarCntSpace_gg00() = 0;
    char* Data = (char*) &(Key.keyVal_gg00());
    Data[0] = 0;
    SAPDB_MemCopyNoCheck(&(Data[1]), &ID, KeyLen-2);
    Data[KeyLen-1] = (SAPDB_Int1)PartNo;
}

//----------------------------------------------------------------------------
00776 inline SAPDB_Bool SharedSQL_CommandCache::CreateTempFile( tgg00_TransContext& TransContext )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::CreateTempFile", SharedSQL_Trace, 5);

    if ( mTempFileState == NoFile )
    {
        SharedSQL_LockedScope Lock(mpCreateFileLock, SharedSQL_LockedScope::Exclusive);
        if ( mTempFileState == NoFile )
        {
            tgg00_FileId FileID;
            GetTempFileID(TransContext, FileID);
            b01tcreate_file(TransContext, FileID);
            if (TransContext.trError_gg00 == e_ok)
            {
                mTempFileState = FileOk;
            }
            else
            {
                mTempFileState = FileError;
                RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_CREATE_TEMP_FILE));
            }
        }
    }
    return (mTempFileState==FileOk);
}

//----------------------------------------------------------------------------
00803 inline SAPDB_Bool SharedSQL_CommandCache::WriteSQLStmtToTempFile( tgg00_TransContext& TransContext, SharedSQL_CommandID ID, SharedSQL_SQLStmt* Stmt)
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::WriteSQLStmtToTempFile", SharedSQL_Trace, 5);

    tgg00_FileId FileID;
    GetTempFileID(TransContext,FileID);

    if ( CreateTempFile(TransContext) )
    {
        long BuffLen = Stmt->mStmtSize + Stmt->mDescriptionSize; // mStmt points to the memory allocated for mStmt+mDescription !!!
        SAPDB_Int1 RecordCount = (SAPDB_Int1) BuffLen/MaxTempFileRecSize + (BuffLen%MaxTempFileRecSize?1:0);
        for (int i = 1; i<=RecordCount; i++)
        {
            tgg00_Rec Rec;
            int CurrStmtPartLen = (i==RecordCount?BuffLen%MaxTempFileRecSize:MaxTempFileRecSize);
            int KeyLen = 2+sizeof(SharedSQL_CommandID);

            Rec.len() = cgg_rec_key_offset + KeyLen + CurrStmtPartLen;
            Rec.keylen() = KeyLen;
            Rec.space_var_offset() = 0;
            Rec.space_var_cnt() = 0;
            char* Data = (char*) &(Rec.info());
            Data[0] = 0;
            SAPDB_MemCopyNoCheck(&(Data[1]), &ID, KeyLen-2);
            Data[KeyLen-1] = (SAPDB_Int1) i;
            SAPDB_MemCopyNoCheck(&(Data[KeyLen]), &(((char*)Stmt->mStmt)[(i-1)*MaxTempFileRecSize]), CurrStmtPartLen);

            b02add_record(TransContext, FileID, Rec);
            if ( TransContext.trError_gg00 != e_ok )
            {
                RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_WRITE_TEMP_FILE));
                for (int k=i-1; k>0; k--)
                {
                    tgg00_Lkey Key;
                    int KeyLen;
                    GetLKey(ID, k, Key, KeyLen);
                    b02del_record(TransContext, FileID, Key);
                }
                return SAPDB_FALSE;
            }
        }
        return SAPDB_TRUE;
    }
    else
    {
        RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_WRITE_TEMP_FILE));
        return SAPDB_FALSE;
    }
}

//----------------------------------------------------------------------------
00854 inline SAPDB_Bool SharedSQL_CommandCache::ReadSQLStmtFromTempFile( tgg00_TransContext& TransContext, SharedSQL_CommandID ID, SharedSQL_SQLStmt* Stmt)
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::ReadSQLStmtFromTempFile", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT(Stmt->mStmt);

    tgg00_FileId FileID;
    GetTempFileID(TransContext,FileID);

    long BuffLen = Stmt->mStmtSize + Stmt->mDescriptionSize; // mStmt points to the memory allocated for mStmt+mDescription !!!
    SAPDB_Int1 RecordCount = (SAPDB_Int1) BuffLen/MaxTempFileRecSize + (BuffLen%MaxTempFileRecSize?1:0);
    for (int i = 1; i<=RecordCount; i++)
    {
        tgg00_Lkey Key;
        tgg00_Rec  Rec;
        int KeyLen;

        GetLKey(ID, i, Key, KeyLen);
        b02get_record(TransContext, FileID, Key, Rec);
        if ( TransContext.trError_gg00 == e_ok )
        {
            int CurrStmtPartLen = Rec.len() - cgg_rec_key_offset - KeyLen;
            char* Data = (char*) &(Rec.info());
            SAPDB_MemCopyNoCheck(&(((char*)Stmt->mStmt)[(i-1)*MaxTempFileRecSize]), &(Data[KeyLen]), CurrStmtPartLen);
        }
        else
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_READ_TEMP_FILE));
            return SAPDB_FALSE;
        }
    }
    if ( Stmt->mDescriptionSize )
        Stmt->mDescription = ((char*)Stmt->mStmt) + Stmt->mStmtSize; // mStmt point to the memory allocated for mStmt + mDescription !!!
    else
        Stmt->mDescription = 0;
    return SAPDB_TRUE;
}

//----------------------------------------------------------------------------
00892 inline SAPDB_Bool SharedSQL_CommandCache::DeleteSQLStmtFromTempFile( tgg00_TransContext& TransContext, SharedSQL_CommandID ID, SharedSQL_SQLStmt* Stmt)
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::DeleteSQLStmtFromTempFile", SharedSQL_Trace, 5);

    tgg00_FileId FileID;
    GetTempFileID(TransContext,FileID);

    long BuffLen = Stmt->mStmtSize + Stmt->mDescriptionSize; // mStmt points to the memory allocated for mStmt+mDescription !!!
    SAPDB_Int1 RecordCount = (SAPDB_Int1) BuffLen/MaxTempFileRecSize + (BuffLen%MaxTempFileRecSize?1:0);
    for (int i = 1; i<=RecordCount; i++)
    {
        tgg00_Lkey Key;
        int KeyLen;

        GetLKey(ID, i, Key, KeyLen);
        b02del_record(TransContext, FileID, Key);
        if ( TransContext.trError_gg00 != e_ok )
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_DELETE_TEMP_FILE));
            return SAPDB_FALSE;
        }
    }
    return SAPDB_TRUE;
}

//----------------------------------------------------------------------------
00918 inline SharedSQL_Error SharedSQL_CommandCache::DeletePlan( SharedSQL_ICachedCommand* Command )
{
    // Command has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::DeletePlan", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );

    Command->Plan().Drop(false);
    Command->SetStatus(Dropped);
    ++mCacheInfoReset.DeletePlanCount; 
      return SAPDB_TRUE;
}

00930 inline void SharedSQL_CommandCache::AttachCommand( SharedSQL_CachedCommand* Command )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::AttachCommand", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );
    LRUListAttachCommand(Command);
    HashTableAttachCommand(Command, CalcSlot(Command->GetHashValue()));
}

00938 inline void SharedSQL_CommandCache::DetachCommand( SharedSQL_CachedCommand* Command )
{
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::DetachCommand", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );
    LRUListDetachCommand(Command);
    HashTableDetachCommand(Command, CalcSlot(Command->GetHashValue()));
}

//----------------------------------------------------------------------------
00947 inline void SharedSQL_CommandCache::HashTableAttachCommand( SharedSQL_CachedCommand* Command, SharedSQL_HashValue Slot )
{
    // Command has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::HashTableAttachCommand", SharedSQL_Trace, 8);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );
    SAPDBERR_ASSERT_RANGE( Slot, 0, mNumberOfSlots-1 );

    // Attach Command at first position
    Command->PrevHashCommand() = 0;           
    if ( mHashTable[Slot] )
    {
        Command->NextHashCommand() = mHashTable[Slot];
        mHashTable[Slot]->PrevHashCommand() = Command;
        mHashTable[Slot] = Command;
    }
    else
    {
        mHashTable[Slot] = Command;
      ++mCacheInfoReset.HashTab_UsedSlotCount;
        if ( mCacheInfoReset.HashTab_UsedSlotCount > mCacheInfoReset.HashTab_MaxUsedSlotCount )
            mCacheInfoReset.HashTab_MaxUsedSlotCount = mCacheInfoReset.HashTab_UsedSlotCount;
    }
}

//----------------------------------------------------------------------------
00972 inline void SharedSQL_CommandCache::HashTableDetachCommand( SharedSQL_CachedCommand* Command, SharedSQL_HashValue Slot  )
{
    // Command has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::HashTableDetachCommand", SharedSQL_Trace, 8);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );
    SAPDBERR_ASSERT_RANGE( Slot, 0, mNumberOfSlots-1 );

    if ( Command->PrevHashCommand() )
            Command->PrevHashCommand()->NextHashCommand() = Command->NextHashCommand();
      else 
      {
            if ( mHashTable[Slot] == Command ) 
        {
            mHashTable[Slot] = Command->NextHashCommand();
                if ( mHashTable[Slot] )
                mHashTable[Slot]->PrevHashCommand() = 0;
            else
                --mCacheInfoReset.HashTab_UsedSlotCount;
        }
        else
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_HASHTABLE));
        }
      }
      if ( Command->NextHashCommand() )
            Command->NextHashCommand()->PrevHashCommand() = Command->PrevHashCommand();
      Command->NextHashCommand() = Command->PrevHashCommand() = 0;
}

01001 SharedSQL_ICachedCommand* SharedSQL_CommandCache::GetHashTableEntry(SharedSQL_HashValue i)
{
    return mHashTable[i];
}

//----------------------------------------------------------------------------
01007 inline void SharedSQL_CommandCache::LRUListMoveCommandToTop( SharedSQL_ICachedCommand* Cmd )
{
    // LRUList has NOT to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::LRUListMoveCommandToTop", SharedSQL_Trace, 5);
    SAPDBERR_ASSERT_ARGUMENT( Cmd != 0 );

    if ( Cmd->GetFlgLRUListOld() )  // dirty read
    {
        SharedSQL_LockedScope Lock(mpLRULock, SharedSQL_LockedScope::Exclusive);
        if ( Cmd->GetFlgLRUListOld() )  // double check
        {

            SharedSQL_CachedCommand* Command = REINTERPRET_CAST(SharedSQL_CachedCommand*, Cmd);

            if ( mFirstLRUCommand != Command )
            {
                // Detach
                if ( Command->PrevLRUCommand() )
                        Command->PrevLRUCommand()->NextLRUCommand() = Command->NextLRUCommand();
                  if ( Command->NextLRUCommand() )
                        Command->NextLRUCommand()->PrevLRUCommand() = Command->PrevLRUCommand();
                  else 
                  {
                        if ( mLastLRUCommand == Command ) 
                              mLastLRUCommand = Command->PrevLRUCommand();
                    else
                        RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_LRULIST));
                  }
                // Attach at first position
                  Command->PrevLRUCommand() = 0;
                  if ( mFirstLRUCommand )
                {
                    mFirstLRUCommand->PrevLRUCommand() = Command;
                  Command->NextLRUCommand() = mFirstLRUCommand;
                }
                mFirstLRUCommand = Command;
                if ( !mLastLRUCommand )
                    mLastLRUCommand = Command;

                Command->SetFlgLRUListOld(false);
                SAPDBERR_ASSERT_STATE( mMiddleLRUCommand != 0 );
                mMiddleLRUCommand->SetFlgLRUListOld(true);
                mMiddleLRUCommand = mMiddleLRUCommand->PrevLRUCommand();
            }
        }
    }
}

//----------------------------------------------------------------------------
01056 inline void SharedSQL_CommandCache::LRUListAttachCommand( SharedSQL_CachedCommand* Command )
{
    // LRUList has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::LRUListAttachCommand", SharedSQL_Trace, 8);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );

    if ( mFirstLRUCommand )
    {
        mFirstLRUCommand->PrevLRUCommand() = Command;
      Command->NextLRUCommand() = mFirstLRUCommand;
          Command->PrevLRUCommand() = 0;
    }
    mFirstLRUCommand = Command;
    if ( !mLastLRUCommand )
        mLastLRUCommand = Command;

    //
    if ( !mMiddleLRUCommand )
        mMiddleLRUCommand = Command;
    ++mLRUCounter;
    if ( mLRUCounter % SharedSQL_OldLRUPart == 0 )
    {
        SAPDBERR_ASSERT_STATE( mMiddleLRUCommand != 0 );
        mMiddleLRUCommand->SetFlgLRUListOld(true);
        mMiddleLRUCommand = mMiddleLRUCommand->PrevLRUCommand();
        SAPDBERR_ASSERT_STATE( mMiddleLRUCommand != 0 );
    }
}

//----------------------------------------------------------------------------
01086 inline void SharedSQL_CommandCache::LRUListDetachCommand( SharedSQL_CachedCommand* Command )
{
    // LRUList has to be locked before this method is called
    SAPDBTRACE_METHOD_DEBUG ("SharedSQL_CommandCache::LRUListDetachCommand", SharedSQL_Trace, 8);
    SAPDBERR_ASSERT_ARGUMENT( Command != 0 );

    if ( Command->GetFlgLRUListOld() )
    {
        if ( mLRUCounter % SharedSQL_OldLRUPart != 0 )
        {
            SAPDBERR_ASSERT_STATE( mMiddleLRUCommand != 0 );
            mMiddleLRUCommand->SetFlgLRUListOld(true);
            mMiddleLRUCommand = mMiddleLRUCommand->PrevLRUCommand();
            SAPDBERR_ASSERT_STATE( mMiddleLRUCommand != 0 );
        }
    }
    else
    {
        if ( mLRUCounter % SharedSQL_OldLRUPart == 0 )
        {
            SAPDBERR_ASSERT_STATE( mMiddleLRUCommand != 0 );
            if ( mMiddleLRUCommand = mMiddleLRUCommand->NextLRUCommand() )
                mMiddleLRUCommand->SetFlgLRUListOld(false);
        }
        if ( Command == (SharedSQL_CachedCommand*)mMiddleLRUCommand )
        {
            SAPDBERR_ASSERT_STATE( mMiddleLRUCommand != 0 );
            mMiddleLRUCommand = mMiddleLRUCommand->PrevLRUCommand();
        }
    }
      --mLRUCounter;

    if ( Command->PrevLRUCommand() )
            Command->PrevLRUCommand()->NextLRUCommand() = Command->NextLRUCommand();
      else 
      {
            if (mFirstLRUCommand == Command) 
                  mFirstLRUCommand = Command->NextLRUCommand();
        else
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_LRULIST));
        }
      }
      if ( Command->NextLRUCommand() )
            Command->NextLRUCommand()->PrevLRUCommand() = Command->PrevLRUCommand();
      else 
      {
            if (mLastLRUCommand == Command) 
                  mLastLRUCommand = Command->PrevLRUCommand();
        else
        {
            RTE_Message(SAPDBErr_MessageList("SharedSQL", __CONTEXT__, SHAREDSQL_ERR_LRULIST));
        }
      }
      Command->NextLRUCommand() = Command->PrevLRUCommand() = 0;
}

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

//----------------------------------------------------------------------------
01146 SharedSQL_CommandCacheIterator SharedSQL_CommandCache::Begin()
{ 
    SharedSQL_CachedCommand* Act = 0;
    SharedSQL_HashValue Slot;
      for (SharedSQL_HashValue i=0; (!Act && i<mNumberOfSlots); i++)
    {
        mpSlotLocks[i]->enter(0);
        if ( Act = mHashTable[i] )
        {
            Slot = i;
            Act->IncParseIDCount();
        }
        mpSlotLocks[i]->leave(0);
    }
    return SharedSQL_CommandCacheIterator(Act, Slot, mNumberOfSlots, this); 
}

//----------------------------------------------------------------------------
01164 SharedSQL_CommandCacheIterator SharedSQL_CommandCache::End()
{ 
    return SharedSQL_CommandCacheIterator(0, mNumberOfSlots-1, mNumberOfSlots, this); 
}

01169 void SharedSQL_CommandCache::NonExclusiveLockSlot(SharedSQL_HashValue i)
{
    mpSlotLocks[i]->enter(0);
}

01174 void SharedSQL_CommandCache::LeaveLockSlot(SharedSQL_HashValue i)
{
    mpSlotLocks[i]->leave(0);
}

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

Generated by  Doxygen 1.6.0   Back to index