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

  module      : vkb560.cpp
  responsible : UweH
  special area: KB_Logging
  last changed: 2000-03-15
  copyright   : (c) 2000-2004 SAP AG
  see also    :
  description : interface to new Logging component



    ========== 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


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

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

#include "heo56.h"   // vsleep
#include "heo58.h"   // tsp0058_RTEInfo
#include "hgg01.h"   // g01is_livecache
#include "hgg01_3.h" // g01pid
#include "hbd91.h"   // bd91StartOMSGarbageCollection
#include "hkb57_1.h" // k57restartrec
#include "hkb57.h"   // save_restart_rec
#include "vsp0031.h" // needed by hkb560.h
#include "SAPDBCommon/SAPDB_ToString.hpp"
#include "SAPDBCommon/Tracing/SAPDBTrace_Usage.hpp"
#include "SAPDBCommon/ErrorsAndMessages/SAPDBErr_Assertions.hpp"
#include "SAPDBCommon/MemoryManagement/SAPDBMem_IRawAllocator.hpp"
#include "SAPDBCommon/MemoryManagement/SAPDBMem_NewDestroy.hpp"
#include "KernelCommon/Kernel_DateTime.hpp"
#include "KernelCommon/Kernel_Trace.hpp"
#include "RunTime/MemoryManagement/RTEMem_Allocator.hpp"
#include "RunTime/RTE_Crash.hpp"
#include "RunTime/RTE_Message.hpp"
#include "Logging/Log_Volume.hpp"
#include "Logging/Log_Transaction.hpp"
#include "Logging/Log_Savepoint.hpp"
#include "Logging/Log_History.hpp"
#include "Logging/Log_Exceptions.hpp"
#include "IOManager/IOMan_ILogInfo.hpp"

#include "hkb560.h"

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

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

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

static inline Log_SavepointReason MapToSavepointReason (tgg00_MessType2_Param MessType2)
{
    switch (MessType2)
    {
    case mm_user:
        return Log_SVPReasonUserRequested;
    case mm_trans:
        return Log_SVPReasonTransRequested;
    case mm_end_read_only:
        return Log_SVPReasonEndReadOnly;
    case mm_read:
        return Log_SVPReasonEndLoad;
    case mm_index:
        return Log_SVPReasonCreateIndex;
    case mm_test:
        return Log_SVPReasonCheckTable;
    case mm_config:
        return Log_SVPReasonCatalogMigration;
    default:
        return Log_SVPReasonUnknown;
    }
}

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

static inline Log_Transaction&
GetLogTrans (tgg00_TransContext &Trans,
                   const char *        Msg)
{
    Log_Transaction* LogTrans = REINTERPRET_CAST(Log_Transaction*,Trans.trLogContext_gg00);
    if ( LogTrans == NULL )
        RTE_Crash( SAPDBErr_Exception(__FILE__, __LINE__,
                                      SAPDBERR_ASSERT_STATE_FAILED, Msg) );
    return *LogTrans;
}

/*===========================================================================*
 *  GLOBAL FUNCTIONS                                                         *
 *===========================================================================*/

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560ResetStatistics (tsp00_TaskId taskid)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560ResetStatistics", LogVolume_Trace, 5);
    if ( ! Log_Volume::IsReadyForWriting() )
        return;
    Log_Volume::Instance().ResetStatistics(taskid);
}

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560GetStatistics (tsp00_TaskId         taskId,
                    tkb00_LogDeviceInfo &LogDeviceInfo,
                    tkb00_LogQueueInfo  &LogQueueInfo)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetStatistics", LogVolume_Trace, 5);

    LogDeviceInfo.ldiPagesUsed_kb00     = 0;
    LogDeviceInfo.ldiPagesNotSaved_kb00 = 0;
    LogDeviceInfo.ldiPagesSinceBup_kb00 = 0;
    LogDeviceInfo.ldiSaveptCount_kb00   = 0;

    LogQueueInfo.lqiCountGroup_kb00      = 0;
    LogQueueInfo.lqiCountInsert_kb00     = 0;
    LogQueueInfo.lqiCountRequest_kb00    = 0;
    LogQueueInfo.lqiCountWait_kb00       = 0;
    LogQueueInfo.lqiAvgSumPagewaits_kb00 = 0;
    LogQueueInfo.lqiLogQueueSize_kb00    = 0;
    LogQueueInfo.lqiMaxQueueUsed_kb00    = 0;
    LogQueueInfo.lqiMaxWaitLogpage_kb00  = 0;

    pasbool     available;
    SAPDB_UInt4 deviceSize;
    SAPDB_UInt4 auxUsed;
    SAPDB_UInt4 auxNotSaved;

    kb560GetArchiveLogDeviceInfo ( taskId, 0, available,
                                   deviceSize,
                                   auxUsed,
                                   auxNotSaved );
                                   
    LogDeviceInfo.ldiPagesUsed_kb00     = auxUsed;
    LogDeviceInfo.ldiPagesNotSaved_kb00 = auxNotSaved;
    LogDeviceInfo.ldiSaveptCount_kb00   = Log_Savepoint::GetLastSavepointId();

    if ( available == 0 )
        return;
        
    SAPDB_UInt4 auxWaitForQueueFree;
    SAPDB_UInt4 auxQueueSize;
    SAPDB_UInt4 auxMaxQueueUsed;
    SAPDB_UInt4 auxCountRequest;
    SAPDB_UInt4 auxCountWaitForIO;
    SAPDB_UInt4 auxMaxWait;
    SAPDB_UInt4 auxCountGroupCommit;
    
    kb560GetArchiveLogQueueInfo ( taskId, 0, available,
                                  auxQueueSize,
                                  auxMaxQueueUsed,
                                  auxCountRequest,
                                  auxCountWaitForIO,
                                  auxCountGroupCommit,
                                  auxWaitForQueueFree,
                                  auxMaxWait );

    LogQueueInfo.lqiLogQueueSize_kb00   = auxQueueSize;
    LogQueueInfo.lqiMaxQueueUsed_kb00   = auxMaxQueueUsed;
    LogQueueInfo.lqiCountInsert_kb00    = auxCountRequest;
    LogQueueInfo.lqiCountWait_kb00      = auxCountWaitForIO;
    LogQueueInfo.lqiCountRequest_kb00   = auxWaitForQueueFree;
    LogQueueInfo.lqiMaxWaitLogpage_kb00 = auxMaxWait;

    LogQueueInfo.lqiCountGroup_kb00     = auxCountGroupCommit;
    if ( auxCountRequest > 0 )
        LogQueueInfo.lqiAvgSumPagewaits_kb00 = auxCountWaitForIO / auxCountRequest;
} 

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560GetArchiveLogDeviceInfo (tsp00_TaskId   taskId,
                              SAPDB_UInt4    logno,
                              pasbool       &available,
                              SAPDB_UInt4   &deviceSize,
                              SAPDB_UInt4   &pagesUsed,
                              SAPDB_UInt4   &pagesNotSaved)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetArchiveLogDeviceInfo", LogVolume_Trace, 5);

    available             = 1;
    deviceSize            = 0;
    pagesUsed             = 0;
    pagesNotSaved         = 0;
    Log_Volume::Instance().GetDeviceUsage (deviceSize, pagesUsed, pagesNotSaved);
}

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560GetArchiveLogQueueInfo (tsp00_TaskId    taskId,
                             SAPDB_UInt4     logno,
                             pasbool        &available,
                             SAPDB_UInt4    &queueSize,
                             SAPDB_UInt4    &maxPagesUsedInQueue,
                             SAPDB_UInt4    &countReserveRequests,
                             SAPDB_UInt4    &countWaitForIO,
                             SAPDB_UInt4    &auxCountGroupCommit,
                             SAPDB_UInt4    &countWaitForQueueFree,
                             SAPDB_UInt4    &maxWaitForPageIO)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetArchiveLogQueueInfo", LogVolume_Trace, 5);

    available             = 1;
    queueSize             = 0;
    maxPagesUsedInQueue   = 0;
    countReserveRequests  = 0;
    countWaitForIO        = 0;
    countWaitForQueueFree = 0;
    maxWaitForPageIO      = 0;
    Log_Volume::Instance().GetQueueUsage ( queueSize,
                        maxPagesUsedInQueue,
                        countReserveRequests,
                        countWaitForIO,
                        auxCountGroupCommit,
                        countWaitForQueueFree,
                        maxWaitForPageIO );
}

/*-----------------------------------------------------------------------------------*/
externPascal void kb560GetLogDBIdent (             // PTS 1113550 mb 2002-03-22 new
    tsp00_Line            VAR_ARRAY_REF  dbident)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetLogDBIdent", LogVolume_Trace, 5);
    SAPDB_Char *auxdbident = reinterpret_cast<SAPDB_Char*>(&dbident);
    Log_Volume::Instance().GetLogDBIdent (auxdbident);
}    

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560DumpTransaction (Log_Transaction *pTrans,
                      void*           &pData,
                      SAPDB_UInt4     &dataLength)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560DumpTransaction", LogTrans_Trace, 5);
    Log_Transaction::GetDumpInfo (pTrans, pData, dataLength);
}
                            
/*-----------------------------------------------------------------------------------*/
externPascal pasbool
kb560VerifyOpenTransAndHistory (tgg00_TransContext &trans,
                                pasbool             isCold)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560VerifyOpenTransAndHistory", LogTrans_Trace, 5);
    bool result = Log_Savepoint::Verify (trans, isCold == 1);
    if ( g01is_livecache() == 1 )
    {
        result &= Log_History::GetInstance().Verify(trans, isCold == 1);
    }
    return result;
}
                            
/*-----------------------------------------------------------------------------------*/
externPascal void
kb560CreateHistoryManager (tgg00_TransContext &Trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560CreateHistoryManager", LogHistory_Trace, 5);
    if ( ! Log_History::CreateInstance (Trans) )
        RTE_Crash( SAPDBErr_Exception(__FILE__, __LINE__,
                                      SAPDBERR_ASSERT_STATE_FAILED,
                                      "Log_History::CreateInstance() failed") );
}

/*-----------------------------------------------------------------------------------*/
externPascal void kb560DropHistoryManager ()
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560DropHistoryManager", LogHistory_Trace, 5);
	Log_History::DropInstance();
}

/*-----------------------------------------------------------------------------------*/
externPascal tsp00_Int4 kb560GetNumOfUserUKTs ()
{
    tsp0058_RTEInfo RTEInfo;

    vgetrteinfo (RTEInfo);

    return RTEInfo.NumOfUserUKTs;
}

/*-----------------------------------------------------------------------------------*/
externPascal pasbool kb560TransactionIsOpen (void* TransPtr)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560TransactionIsOpen", LogTrans_Trace, 5);
    if ( NULL == TransPtr )
        RTE_Crash( SAPDBErr_Exception(__FILE__, __LINE__,
                                      SAPDBERR_ASSERT_STATE_FAILED,
                                      "kb560TransactionIsOpen(): TransPtr is null") );
	// PTS 1114125 UH 2002-02-12 use of IsOpenInRedo()
    Log_Transaction &trans = *(reinterpret_cast<Log_Transaction*>(TransPtr));
    return trans.IsOpenInRedo();
}

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560InitSavepointParam (tkb00_SaveptParam &param)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560InitSavepointParam", LogTrans_Trace, 5);

    param.svpId_kb00               = 0;
    param.svpReason_kb00           = Log_SVPReasonUnknown;
    param.svpFiller1_kb00          = 0;
    param.svpOpenTransCnt_kb00     = 0;

    param.svpIOsequence_kb00       = SAPDB_MAX_UINT4;
    param.svpStartOffset_kb00      = SAPDB_MAX_UINT4;

    param.svpStartEntryOffset_kb00 = 0;
    param.svpStartEntryType_kb00   = Log_NoOp;

    param.svpFiller2_kb00          = 0;
    param.svpFiller3_kb00          = 0;

    param.svpOpenTransRoot_kb00    = NIL_PAGE_NO_GG00;
    param.svpHistoryRoot_kb00      = NIL_PAGE_NO_GG00;

    param.svpDate_kb00             = KERNEL_INVALID_DATE;
    param.svpTime_kb00             = KERNEL_INVALID_TIME;

    param.svpStartEntryDate_kb00   = KERNEL_INVALID_DATE;
    param.svpStartEntryTime_kb00   = KERNEL_INVALID_TIME;

    memset (&param.svpFiller4_kb00, 0, sizeof(param.svpFiller4_kb00));

    param.svpFiller5_kb00          = 0;
    param.svpFiller6_kb00          = 0;
}

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560StartSavepoint (tgg00_TransContext    &Trans,
                     tgg00_MessType2_Param  MessType2)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560StartSavepoint", LogTrans_Trace, 5);
    Log_SavepointManager.StartSavepoint (Trans, MapToSavepointReason(MessType2));
}

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560StartSavepointAndWait (tgg00_TransContext    &Trans,
                            tgg00_MessType2_Param  MessType2)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560StartSavepointAndWait", LogTrans_Trace, 5);
    Log_SavepointManager.StartSavepointAndWait (Trans, MapToSavepointReason(MessType2));
}

/*-----------------------------------------------------------------------------------*/
externPascal void
kb560SavepointCoordinator (tgg00_TransContext &Trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560SavepointCoordinator", LogTrans_Trace, 5);
    Log_SavepointManager.Coordinator (Trans);
}

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

externPascal void
kb560LogWriter()
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560LogWriter", LogVolume_Trace, 5);
    Log_Volume::CreateInstance( RTEMem_Allocator::Instance(),
                                    Log_FrameAllocator::Instance(),
                                    Log_Queue::Synchronized,
                                    Log_DeviceMinimizeSpace );
    Log_Volume::Instance().GetWriter().Run();
}

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

externPascal void
kb560CreateLogTransaction (tgg00_TransContext &Trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560CreateLogTransaction", LogTrans_Trace, 5);

    SAPDBMem_IRawAllocator& Allocator =
        *(REINTERPRET_CAST (SAPDBMem_IRawAllocator*, Trans.trAllocator_gg00));

    Log_Transaction* LogTrans = new (Allocator) Log_Transaction ();

    if ( LogTrans == NULL )
        RTE_Crash( SAPDBErr_Exception(__FILE__, __LINE__,
                                      SAPDBERR_ASSERT_STATE_FAILED,
                                      "kb560CreateLogTransaction: allocate") );

    if ( ! LogTrans->Initialize(Trans) )
        RTE_Crash( SAPDBErr_Exception(__FILE__, __LINE__,
                                      SAPDBERR_ASSERT_STATE_FAILED,
                                      "kb560CreateLogTransaction: init") );
    
    Trans.trLogContext_gg00 = LogTrans;
}

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

externPascal void
kb560DeleteLogTransaction (tgg00_TransContext &Trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560DeleteLogTransaction", LogTrans_Trace, 5);

    Log_Transaction* LogTrans = REINTERPRET_CAST(Log_Transaction*,Trans.trLogContext_gg00);
    if ( LogTrans == NULL ) //PTS 1125799 mb 2003-12-02 tolerate NULL-transaction
    {
        Kernel_VTrace() << "kb560DeleteLogTransaction: trying to delete NULL transaction" 
                        << FlushLine;
    }
    else
    {
        SAPDBMem_IRawAllocator& allocator = LogTrans->Allocator();
        LogTrans->Delete();
        destroy(LogTrans, allocator);
        Trans.trLogContext_gg00 = NULL;
    }
}

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

externPascal void
kb560CommitLogTransaction (tgg00_TransContext &Trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560CommitLogTransaction", LogTrans_Trace, 5);
    GetLogTrans (Trans, "CommitLogTrans: ptr=nil ").Commit();
}

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

externPascal void
kb560RollbackLogTransAction (tgg00_TransContext    &Trans,
                             tgg00_MessType2_Param  RollbackKind,
                             tgg00_SubtransNo       SubtransNo)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560RollbackLogTransaction", LogTrans_Trace, 5);

    Log_Transaction::RollbackKind newRollbackKind;
    switch ( RollbackKind )
    {
    case mm_rollback:
        newRollbackKind = Log_Transaction::endOfTrans;
        break;
    case mm_nil:
        newRollbackKind = Log_Transaction::command;
        break;
    case mm_subtrans:
        newRollbackKind = Log_Transaction::subTrans;
        break;
    default:
        SAPDBTRACE_WRITELN (LogTrans_Trace, 6, "RollbackKind: " << RollbackKind);
        RTE_Crash( SAPDBErr_Exception(__FILE__, __LINE__,
                                      SAPDBERR_ASSERT_STATE_FAILED,
                                      "kb560RollbackLogTransAction: unknown RollbackKind") );
    }

    Trans.trState_gg00.addElement (tsRollback_egg00);

    Log_Transaction::RollbackResult Result =
        GetLogTrans (Trans, "RollbackLogTrans:ptr=nil").
            Rollback (newRollbackKind, SubtransNo);

    Trans.trState_gg00.delElement (tsRollback_egg00);

    Trans.trError_gg00 = kb560ConvertRollbackResultToBasisError (Result);
}

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

externPascal tgg00_BasisError kb560ConvertRollbackResultToBasisError (
    tsp00_Int4                           result)
{
    switch ( Log_Transaction::RollbackResult(result) )
    {
    case Log_Transaction::undoOk:
        return e_ok;
    case Log_Transaction::undoNoOpenSubtrans:
        return e_no_open_subtrans;
    case Log_Transaction::undoLogFull:
        return e_log_full;
    default:
        // case undoReadError, undoWrongEntry, undoExecuteError, undoWriteError
        return e_log_error;
    }
}

/*-----------------------------------------------------------------------------------*/
externPascal tgg00_BasisError kb560ConvertWriteRedoEntryResultToBasisError (
    tsp00_Int4                           result)
{
    switch ( Log_Transaction::LogState(result) )
    {
    case Log_Transaction::noError:
        return e_ok;
    case Log_Transaction::logFull:
        return e_log_full;
    case Log_Transaction::logError:
        return e_log_error;
    default:
        return e_log_error;
    }
}

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

externPascal void
kb560BeginSubtransLogTransaction (tgg00_TransContext &Trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560BeginSubtransLogTransaction", LogTrans_Trace, 5);
    GetLogTrans (Trans, "BeginSubtLogTrns:ptr=nil").BeginSubtrans();
}

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

externPascal void
kb560EndSubtransLogTransaction (tgg00_TransContext &Trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560EndSubtransLogTransaction", LogTrans_Trace, 5);
    if ( ! GetLogTrans (Trans, "EndSubtrLogTrans:ptr=nil").EndSubtrans() )
        Trans.trError_gg00 = e_no_open_subtrans;
}

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

externPascal void kb560GetFirstKnownIOSeqBeforeRestoreLog (
    Log_IOSequenceNo&                    FirstIOSeq,
    pasbool               VAR_VALUE_REF  firstIOSeqIsValid)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetFirstKnownIOSeqBeforeRestoreLog", LogVolume_Trace, 5);

    Log_Volume &log  = Log_Volume::Instance();
    
    Log_RawDeviceOffset     offset;
    log.GetFirstKnownBeforeRestoreLog(offset,FirstIOSeq);
    
    firstIOSeqIsValid = FirstIOSeq.IsValid();
}    

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

externPascal pasbool kb560GetLogInfo (
    tsp00_TaskId                         taskid,
    tsp00_Int4            VAR_VALUE_REF  date,
    tsp00_Int4            VAR_VALUE_REF  time,
    tsp00_Int4            VAR_VALUE_REF  flushmode,
    tsp00_Int4            VAR_VALUE_REF  devicestate,
    tsp00_Uint4           VAR_VALUE_REF  queuecount,
    tsp00_Uint4           VAR_VALUE_REF  cycleendoffset,
    tsp00_Uint4           VAR_VALUE_REF  oldestnotsavedoffset,
    Log_IOSequenceNo&                    oldestnotsavedsequence,
    tsp00_Uint4           VAR_VALUE_REF  lastknownoffset,
    Log_IOSequenceNo&                    lastknownsequence,
    tsp00_Uint4           VAR_VALUE_REF  backupcount,
    tsp00_Int4            VAR_VALUE_REF  untildate,
    tsp00_Int4            VAR_VALUE_REF  untiltime,
    tsp00_Uint4           VAR_VALUE_REF  untilclearloweroffset,
    tsp00_Uint4           VAR_VALUE_REF  untilclearupperoffset,
    Log_IOSequenceNo&                    untilsequenceafterredo,
    Log_IOSequenceNo&                    savepointsequence,
    tsp00_Uint4           VAR_VALUE_REF  savepointdevoffset,
    tsp00_Uint4           VAR_VALUE_REF  savepointoffset)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetLogInfo", LogVolume_Trace, 5);
    Log_Volume &log = Log_Volume::Instance();

    Kernel_Date              auxdate;
    Kernel_Time              auxtime;
    Log_FlushMode            auxflushmode;
    Log_DeviceState          auxdevicestate;
    SAPDB_UInt2              auxqueuecount;
    Log_RawDeviceOffset      auxcycleendoffset;
    Log_RawDeviceOffset      auxoldestnotsavedoffset;
    Log_IOSequenceNo         auxoldestnotsavedsequence;
    Log_RawDeviceOffset      auxlastknownoffset;
    Log_IOSequenceNo         auxlastknownsequence;
    SAPDB_UInt4              auxbackupcount;
    Kernel_Date              auxuntildate;
    Kernel_Time              auxuntiltime;
    Log_RawDeviceOffset      auxuntilclearloweroffset;
    Log_RawDeviceOffset      auxuntilclearupperoffset;
    Log_IOSequenceNo         auxuntilsequenceafterredo;
    Log_IOSequenceNo         auxsavepointsequence;
    Log_RawDeviceOffset      auxsavepointdevoffset;
    Kernel_IPage::OffsetType auxsavepointoffset;

    bool isvalid = log.GetLogInfo ( taskid,
                         auxdate,
                         auxtime,
                         auxflushmode,
                         auxdevicestate,
                         auxqueuecount,
                         auxcycleendoffset,
                         auxoldestnotsavedoffset,
                         auxoldestnotsavedsequence,
                         auxlastknownoffset,
                         auxlastknownsequence,
                         auxbackupcount,
                         auxuntildate,
                         auxuntiltime,
                         auxuntilclearloweroffset,
                         auxuntilclearupperoffset,
                         auxuntilsequenceafterredo,
                         auxsavepointsequence,
                         auxsavepointdevoffset,
                         auxsavepointoffset );
    
    if ( ! isvalid )
        return false;
        
    date                   = auxdate;
    time                   = auxtime;
    flushmode              = auxflushmode;
    devicestate            = auxdevicestate;
    queuecount             = auxqueuecount;
    cycleendoffset         = auxcycleendoffset;
    oldestnotsavedoffset   = auxoldestnotsavedoffset;
    oldestnotsavedsequence = auxoldestnotsavedsequence;
    lastknownoffset        = auxlastknownoffset;
    lastknownsequence      = auxlastknownsequence;
    backupcount            = auxbackupcount;
    untildate              = auxuntildate;
    untiltime              = auxuntiltime;
    untilclearloweroffset  = auxuntilclearloweroffset;
    untilclearupperoffset  = auxuntilclearupperoffset;
    untilsequenceafterredo = auxuntilsequenceafterredo;
    savepointsequence      = auxsavepointsequence;
    savepointdevoffset     = auxsavepointdevoffset;
    savepointoffset        = auxsavepointoffset;
    
    return true;
}

/*-----------------------------------------------------------------------------------*/
externPascal pasbool kb560LogIsFull ()
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560LogIsFull", LogVolume_Trace, 5);
    return Log_Volume::Instance().LogIsFull();
}


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

externPascal void k560check_logsave_allowed (
    tsp00_TaskId                         TaskId,
    tgg00_BasisError      VAR_VALUE_REF  BasisError)
{
    SAPDBTRACE_ROUTINE_DEBUG ("k560check_logsave_allowed", LogVolume_Trace, 5);

    Kernel_Date              date;
    Kernel_Time              time;
    Log_FlushMode            flushmode;
    Log_DeviceState          devicestate;
    SAPDB_UInt2              queuecount;
    Log_RawDeviceOffset      cycleendoffset;
    Log_RawDeviceOffset      oldestnotsavedoffset;
    Log_IOSequenceNo         oldestnotsavedsequence;
    Log_RawDeviceOffset      lastknownoffset;
    Log_IOSequenceNo         lastknownsequence;
    SAPDB_UInt4              backupcount;
    Kernel_Date              untildate;
    Kernel_Time              untiltime;
    Log_RawDeviceOffset      untilclearloweroffset;
    Log_RawDeviceOffset      untilclearupperoffset;
    Log_IOSequenceNo         untilsequenceafterredo;
    Log_IOSequenceNo         savepointsequence;
    Log_RawDeviceOffset      savepointdevoffset;
    Kernel_IPage::OffsetType savepointoffset;

    Log_Volume &log = Log_Volume::Instance();

    if (log.GetLogInfo (TaskId,
                              date,
                              time,
                              flushmode,
                              devicestate,
                              queuecount,
                              cycleendoffset,
                              oldestnotsavedoffset,
                              oldestnotsavedsequence,
                              lastknownoffset,
                              lastknownsequence,
                              backupcount,
                              untildate,
                              untiltime,
                              untilclearloweroffset,
                              untilclearupperoffset,
                              untilsequenceafterredo,
                              savepointsequence,
                              savepointdevoffset,
                              savepointoffset ))
    {
        if (Log_DeviceStateOkay == devicestate)
        {
            BasisError = e_ok;
        }
        else
        {
            BasisError = e_backup_history_lost;
            RTE_Message(Log_Exception(__FILE__,__LINE__,LOG_AUTOSAVE_ABORTED_HIST_LOST));
        }
    }
    else
    {
        RTE_Crash( SAPDBErr_Exception(__FILE__, __LINE__,
                                      SAPDBERR_ASSERT_STATE_FAILED,
                                      "k560check_logsave_allowed: ArchiveLog not initialized ") );
    }

    // PTS 1128223 mb 2004-04-03 check for AutoOverWrite 
    if (log.IsAutomaticOverwrite(TaskId))
    {
        BasisError = e_log_autooverwrite_on;
        RTE_Message(Log_Exception(__FILE__,__LINE__,LOG_SAVE_DENIED_AUTOOVERWRITE));
    }

    // PTS 1128223 mb 2004-04-03 check for LogWriting switched off
    if (! log.IsDevspaceEnabled(TaskId))
    {
        BasisError = e_log_writing_disabled;
        RTE_Message(Log_Exception(__FILE__,__LINE__,LOG_SAVE_DENIED_WRITING_OFF));
    }
}

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

externPascal tsp00_Int4 kb560GetLogDeviceSize ()
{
    return Log_Volume::Instance().GetDeviceSize();
}

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

externPascal void kb560SetDeviceStateOkay (
    tsp00_TaskId                         taskid,
    tgg00_BasisError      VAR_VALUE_REF  TrError)
{
    // PTS 1113190 UH 2001-12-19 new
    SAPDBTRACE_ROUTINE_DEBUG ("kb560SetDeviceStateOkay", LogVolume_Trace, 5);
    if ( ! Log_Volume::Instance().SetVolumeState(taskid, Log_DeviceStateOkay) )
        TrError = e_disk_not_accessible;
}

/* -------------------------------------------------------------------------------- */
externPascal void kb560GetHistFileInfo (
    tgg00_TransContext    VAR_VALUE_REF  Trans,
    tsp00_Int4            VAR_VALUE_REF  HistFileNo,
    tgg91_TransNo         VAR_VALUE_REF  FirstTransId,
    pasbool               VAR_VALUE_REF  FirstTransIsUsed,
    tgg91_TransNo         VAR_VALUE_REF  LastTransId,
    pasbool               VAR_VALUE_REF  LastTransIsUsed,
    tsp00_Int4            VAR_VALUE_REF  PageCount,
    pasbool               VAR_VALUE_REF  bFileIsEmpty)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetHistFileInfo", LogVolume_Trace, 5);
    Log_History::HistoryFileInfo  info;
    Log_History                  &history = Log_History::GetInstance();
    SAPDB_UInt                    pagecount;

    if ( HistFileNo >= tsp00_Int4(history.GetNumberOfHistoryFiles()) )
    {
        HistFileNo = -1;
        return;
    }

    history.GetInfo (Trans.trTaskId_gg00, HistFileNo, info, pagecount);

    FirstTransId     = info.oldestTransNo;
    FirstTransIsUsed = 0;
    LastTransId      = info.youngestTransNo;
    LastTransIsUsed  = 0;
    PageCount        = tsp00_Int4(pagecount); // ++++++++++
    bFileIsEmpty     = info.oldestTransNo.gg90IsNil()
                       &&
                       info.youngestTransNo.gg90IsNil();
                       
    HistFileNo       = HistFileNo + 1;
}

/*-----------------------------------------------------------------------------------*/
externPascal void kb560GetLogTransactionInfo (
    Log_Transaction*                     ptrans,
    tsp00_PageNo          VAR_VALUE_REF  undoroot,
    tsp00_PageNo          VAR_VALUE_REF  undolast,
    tsp00_Int4            VAR_VALUE_REF  undopagecount,
    tsp00_Int4            VAR_VALUE_REF  lastundosequence)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560GetLogTransactionInfo", LogTrans_Trace, 5);

    undoroot         = NIL_PAGE_NO_GG00;
    undolast         = NIL_PAGE_NO_GG00;
    undopagecount    = 0;
    lastundosequence = -1;

    if ( ptrans == NULL ) return;

    Data_PageNo       auxundoroot;
    Data_PageNo       auxundolast;
    SAPDB_UInt        auxundopagecount;
    Log_EntrySequence auxlastundosequence;

    ptrans->GetInfo ( auxundoroot,
                      auxundolast,
                      auxundopagecount,
                      auxlastundosequence );

    undoroot         = auxundoroot;
    undolast         = auxundolast;
    undopagecount    = auxundopagecount;
    lastundosequence = auxlastundosequence;
}

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

externPascal void kb560InvalidateIOSeq (
    Log_IOSequenceNo&                    ioSeq)
{
    // PTS 1116063 mb 2002-06-05 new
    ioSeq.Invalidate();
}

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

externPascal pasbool kb560IsValidIOSeq (
    const Log_IOSequenceNo&                 ioSeq)
{
    // PTS 1116063 mb 2002-06-05 new
    return ioSeq.IsValid();
}

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

externPascal pasbool kb560IsSuccessor (
    Log_IOSequenceNo&                    predecessor,
    Log_IOSequenceNo&                    successor)
// new with PTS 1126639 mb 2003-12-22
{
    if ((predecessor+1) == successor)
    {
        return true;
    }
    else
    {
        RTE_Message(Log_Exception(__CONTEXT__, LOG_NON_CONTINUOUS_IOSEQ,
                                  SAPDB_ToString(predecessor),
                                  SAPDB_ToString(successor)));
        return false;
    }
}

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

externPascal void kb560CheckForLogSaveAndSavepoint (
    tgg00_TransContext    VAR_VALUE_REF  trans)
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560CheckForLogSaveAndSavepoint", LogVolume_Trace, 5);
    
    if ( ! Log_Volume::IsReadyForWriting() )
        return;
    Log_Volume::Instance().CheckForLogSaveAndSavepoint(trans);
}

/*-----------------------------------------------------------------------------------*/
externPascal pasbool k560IsSavepointAllowed ()
{
    // PTS 1114053 UH 2002-10-22 new
    SAPDBTRACE_ROUTINE_DEBUG ("k560IsSavepointAllowed", LogVolume_Trace, 5);
	return Log_SavepointManager.IsSavepointAllowed();
}

/*-----------------------------------------------------------------------------------*/
externPascal void kb560GetSavepointStatistics (
    tsp00_Int4            VAR_VALUE_REF  lastDurationSec,
    tsp00_Int4            VAR_VALUE_REF  lastDurationMicroSec,
    tsp00_Int4            VAR_VALUE_REF  lastWrittenPages,
    tsp00_Int4            VAR_VALUE_REF  lastIOcount,
    tsp00_Int4            VAR_VALUE_REF  avgWrittenPages,
    tsp00_Int4            VAR_VALUE_REF  avgIOcount)
{
    // PTS 1119276 UH 2002-12-10 new
    Log_SavepointManager.GetSavepointStatistics (lastDurationSec,
                                                 lastDurationMicroSec,
                                                 lastWrittenPages,
                                                 lastIOcount,
                                                 avgWrittenPages,
                                                 avgIOcount);
}
/*-----------------------------------------------------------------------------------*/
externPascal void kb560GetSavepointReasonString (
    tsp00_Uint1                          reasonid,
    tsp00_C40             VAR_ARRAY_REF  resonstring)
{
    if ( reasonid >= Log_SavepointReason_DO_NOT_USE )
        return;
	memcpy (resonstring, Log_SavepointReasonStrings[reasonid], strlen(Log_SavepointReasonStrings[reasonid]));
}
/*-----------------------------------------------------------------------------------*/
externPascal void kb560InsertToWaitForPrepare (
    tsp00_TaskId                         taskid,
    tgg00_WaitContext     VAR_VALUE_REF  waitcontext)
{
    Log_SavepointManager.InsertToWaitForPrepare (taskid, waitcontext);
}
/*-----------------------------------------------------------------------------------*/
externPascal tsp00_Uint4 kb560LogQueueSize ()
{
    return Log_Volume::QueueSize();
}
/*-----------------------------------------------------------------------------------*/
externPascal void kb560SetTraceMaxBufferLength (
    tsp00_Int4                           length)
{
    if ( length > 0 )
        Kernel_TraceMaxBufferLength = length;
}
/*-----------------------------------------------------------------------------------*/
externPascal pasbool kb560AddLogFillingEvent (
    tsp00_Int4                           threshold,
    SAPDB_UInt4                          priority)
{
    // PTS 1124876 UH 2003-10-23 new
    return Log_Volume::IsReadyForWriting()
           &&
           Log_Volume::Instance().AddLogFillingEvent(threshold*100, tsp31_event_prio::fromInt(priority));
}
/*-----------------------------------------------------------------------------------*/
externPascal pasbool kb560DelLogFillingEvent (
    tsp00_Int4                           threshold)
{
    // PTS 1124876 UH 2003-10-23 new
    return Log_Volume::IsReadyForWriting()
           &&
           Log_Volume::Instance().DelLogFillingEvent(threshold*100);
}
/*-----------------------------------------------------------------------------------*/
externPascal void kb560GetEvents (
    void*                                events)
{
    // PTS 1124876 UH 2003-10-23 new
    if ( events == 0 || ! Log_Volume::IsReadyForWriting() )
        return;

    tsp31_short_event_desc* pEventDescription = reinterpret_cast<tsp31_short_event_desc*>(events);

    Log_Volume::Instance().GetLogFillingEvents(*pEventDescription);
}
/*-----------------------------------------------------------------------------------*/
externPascal void kb560DetermineLocalRedoBufferSizeForTransactions ()
{
    SAPDBTRACE_ROUTINE_DEBUG ("kb560DetermineLocalRedoBufferSizeForTransactions", LogVolume_Trace, 5);
	Log_Transaction::DetermineLocalRedoBufferSize();
}