From 587b534ec383c9ced74370cd04fa55f4f0d3dd24 Mon Sep 17 00:00:00 2001 From: dsandersoremutah Date: Tue, 26 Sep 2006 14:55:33 +0000 Subject: [PATCH] Added methods for collecting statistics to C# classes. Also made needed changes in C++ code. git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@909 0109f412-320b-0410-ab79-c3e0c5ffbbe6 --- xflaim/csharp/cstest/StatsTests.cs | 291 +++++++++++++++++ xflaim/csharp/cstest/cstest.cs | 8 + xflaim/csharp/xflaim/CacheInfo.cs | 6 +- xflaim/csharp/xflaim/DbSystem.cpp | 73 +++++ xflaim/csharp/xflaim/DbSystem.cs | 117 ++++++- xflaim/csharp/xflaim/DbSystemStats.cpp | 168 ++++++++++ xflaim/csharp/xflaim/DbSystemStats.cs | 416 +++++++++++++++++++++++++ xflaim/csharp/xflaim/dbCheck.cs | 4 +- xflaim/csharp/xflaim/dbRebuild.cs | 2 +- xflaim/java/jni/jdbsystem.cpp | 6 +- xflaim/src/flmstat.cpp | 6 +- xflaim/src/scache.cpp | 10 +- xflaim/src/xflaim.h | 16 +- 13 files changed, 1096 insertions(+), 27 deletions(-) create mode 100644 xflaim/csharp/cstest/StatsTests.cs create mode 100644 xflaim/csharp/xflaim/DbSystemStats.cpp create mode 100644 xflaim/csharp/xflaim/DbSystemStats.cs diff --git a/xflaim/csharp/cstest/StatsTests.cs b/xflaim/csharp/cstest/StatsTests.cs new file mode 100644 index 0000000..9f6b766 --- /dev/null +++ b/xflaim/csharp/cstest/StatsTests.cs @@ -0,0 +1,291 @@ +//------------------------------------------------------------------------------ +// Desc: Statistics tests +// +// Tabs: 3 +// +// Copyright (c) 2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id$ +//------------------------------------------------------------------------------ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using xflaim; + +namespace cstest +{ + + //-------------------------------------------------------------------------- + // Statistics tests. + //-------------------------------------------------------------------------- + public class StatsTests : Tester + { + private const uint LABEL_LEN = 35; + + private string makeIndentStr( + uint uiIndent) + { + string sIndent = null; + + for (uint uiLoop = 0; uiLoop < uiIndent; uiLoop++) + { + sIndent += " "; + } + return( sIndent); + } + + private string makeLabel( + uint uiIndent, + string sLabel) + { + string sNewLabel = makeIndentStr( uiIndent) + sLabel; + + while (sNewLabel.Length < LABEL_LEN) + { + sNewLabel += "."; + } + sNewLabel += " "; + return( sNewLabel); + } + + private void printStrStat( + uint uiIndent, + string sLabel, + string sStat) + { + System.Console.WriteLine( "{0}{1}", makeLabel( uiIndent, sLabel), sStat); + } + + private void printUIntStat( + uint uiIndent, + string sLabel, + uint uiStat) + { + System.Console.WriteLine( "{0}{1}", makeLabel( uiIndent, sLabel), uiStat); + } + + private void printULongStat( + uint uiIndent, + string sLabel, + ulong ulStat) + { + System.Console.WriteLine( "{0}{1}", makeLabel( uiIndent, sLabel), ulStat); + } + + private void printCountTimeStat( + uint uiIndent, + string sLabel, + F_COUNT_TIME_STAT stat) + { + ulong ulAvgMilli = (stat.ulCount != 0) + ? stat.ulElapMilli / stat.ulCount + : 0; + System.Console.WriteLine( "{0}Count={1},ElapMilli={2},AvgMilli={3}", + makeLabel( uiIndent, sLabel), + stat.ulCount, stat.ulElapMilli, ulAvgMilli); + } + + private void printDiskIOStats( + uint uiIndent, + string sLabel, + XFLM_DISKIO_STAT diskIOStat) + { + ulong ulAvgMilli = (diskIOStat.ulCount != 0) + ? diskIOStat.ulElapMilli / diskIOStat.ulCount + : 0; + System.Console.WriteLine( "{0}Count={1},Bytes={2},ElapMilli={3},AvgMilli={4}", + makeLabel( uiIndent, sLabel), + diskIOStat.ulCount, diskIOStat.ulTotalBytes, + diskIOStat.ulElapMilli, ulAvgMilli); + } + + private void printBlockIOStats( + uint uiIndent, + string sLabel, + XFLM_BLOCKIO_STATS blockIOStats) + { + System.Console.WriteLine( "{0}{1}", makeIndentStr( uiIndent), sLabel); + printDiskIOStats( uiIndent + 1, "Block Reads", blockIOStats.BlockReads); + printDiskIOStats( uiIndent + 1, "Block Writes", blockIOStats.BlockWrites); + printDiskIOStats( uiIndent + 1, "Old View Block Reads", blockIOStats.OldViewBlockReads); + printUIntStat( uiIndent + 1, "Block Checksum Errors", blockIOStats.uiBlockChkErrs); + printUIntStat( uiIndent + 1, "Old Block Checksum Errors", blockIOStats.uiOldViewBlockChkErrs); + printUIntStat( uiIndent + 1, "Old View Errors", blockIOStats.uiOldViewErrors); + } + + public bool statsTests( + string sDbName, + DbSystem dbSystem) + { + Db db = null; + DbSystemStats stats = null; + uint uiNumDatabases; + uint uiStartTime; + uint uiStopTime; + CS_XFLM_DB_STATS dbStats = null; + CS_XFLM_LFILE_STATS lFileStats = null; + + beginTest( "Start statistics"); + + try + { + dbSystem.startStats(); + } + catch (XFlaimException ex) + { + endTest( false, ex, "starting statistics"); + return( false); + } + endTest( false, true); + + // Open a database to make some statistics happen + + beginTest( "Open Database Test (" + sDbName + ")"); + + try + { + db = dbSystem.dbOpen( sDbName, null, null, null, false); + } + catch (XFlaimException ex) + { + endTest( false, ex, "opening database"); + return( false); + } + if (db != null) + { + db.close(); + db = null; + } + endTest( false, true); + + // Stop collecting statistics + + beginTest( "Stop statistics"); + + try + { + dbSystem.stopStats(); + } + catch (XFlaimException ex) + { + endTest( false, ex, "stopping statistics"); + return( false); + } + endTest( false, true); + + // Get statistics + + beginTest( "Get statistics"); + + try + { + stats = dbSystem.getStats(); + } + catch (XFlaimException ex) + { + endTest( false, ex, "getting statistics"); + return( false); + } + endTest( false, true); + + // Get general statistics + + beginTest( "Get general statistics"); + + try + { + stats.getGeneralStats( out uiNumDatabases, out uiStartTime, + out uiStopTime); + } + catch (XFlaimException ex) + { + endTest( false, ex, "getting statistics"); + return( false); + } + endTest( false, true); + printUIntStat( 0, "Databases", uiNumDatabases); + printUIntStat( 0, "Start Time", uiStartTime); + printUIntStat( 0, "Stop Time", uiStopTime); + + // Get Database statistics + + for (uint uiLoop = 0; uiLoop < uiNumDatabases; uiLoop++) + { + beginTest( "Get database statistics for DB#" + uiLoop); + + try + { + dbStats = stats.getDbStats( uiLoop, dbStats); + } + catch (XFlaimException ex) + { + endTest( false, ex, "getting database statistics"); + return( false); + } + endTest( false, true); + printStrStat( 0, "Database Name", dbStats.sDbName); + printUIntStat( 0, "Logical File Count", dbStats.uiNumLFiles); + System.Console.WriteLine( "Read Transactions"); + printCountTimeStat( 1, "Committed Transactions", dbStats.ReadTransStats.CommittedTrans); + printCountTimeStat( 1, "Aborted Transactions", dbStats.ReadTransStats.AbortedTrans); + System.Console.WriteLine( "Update Transactions"); + printCountTimeStat( 1, "Committed Transactions", dbStats.UpdateTransStats.CommittedTrans); + printCountTimeStat( 1, "Aborted Transactions", dbStats.UpdateTransStats.AbortedTrans); + printCountTimeStat( 1, "Group Completes", dbStats.UpdateTransStats.GroupCompletes); + printULongStat( 1, "Group Finished", dbStats.UpdateTransStats.ulGroupFinished); + printBlockIOStats( 0, "LFH Block Stats", dbStats.LFHBlockStats); + printBlockIOStats( 0, "Avail Block Stats", dbStats.AvailBlockStats); + printDiskIOStats( 0, "Database Header Writes", dbStats.DbHdrWrites); + printDiskIOStats( 0, "Log Block Writes", dbStats.LogBlockWrites); + printDiskIOStats( 0, "Log Block Restores", dbStats.LogBlockRestores); + printDiskIOStats( 0, "Log Block Reads", dbStats.LogBlockReads); + printUIntStat( 0, "Log Block Checksum Errors", dbStats.uiLogBlockChkErrs); + printUIntStat( 0, "Read Errors", dbStats.uiReadErrors); + printCountTimeStat( 0, "No Locks", dbStats.LockStats.NoLocks); + printCountTimeStat( 0, "Waiting For Lock", dbStats.LockStats.WaitingForLock); + printCountTimeStat( 0, "Held Lock", dbStats.LockStats.HeldLock); + + for (uint uiLoop2 = 0; uiLoop2 < dbStats.uiNumLFiles; uiLoop2++) + { + beginTest( " Get database statistics for DB#" + uiLoop + ", LFile#" + uiLoop2); + + try + { + lFileStats = stats.getLFileStats( uiLoop, uiLoop2, lFileStats); + } + catch (XFlaimException ex) + { + endTest( false, ex, "getting logical file statistics"); + return( false); + } + endTest( false, true); + System.Console.WriteLine( " LOGICAL FILE {0} ({1})", + lFileStats.uiLFileNum, lFileStats.eLfType); + printBlockIOStats( 2, "Root Block Stats", lFileStats.RootBlockStats); + printBlockIOStats( 2, "Middle Block Stats", lFileStats.MiddleBlockStats); + printBlockIOStats( 2, "Leaf Block Stats", lFileStats.LeafBlockStats); + printULongStat( 2, "Block Splits", lFileStats.ulBlockSplits); + printULongStat( 2, "Block Combines", lFileStats.ulBlockCombines); + } + } + + return( true); + } + } +} diff --git a/xflaim/csharp/cstest/cstest.cs b/xflaim/csharp/cstest/cstest.cs index 44d43c9..8f49e39 100644 --- a/xflaim/csharp/cstest/cstest.cs +++ b/xflaim/csharp/cstest/cstest.cs @@ -177,6 +177,14 @@ namespace cstest return; } + // Statistics test + + StatsTests statsTests = new StatsTests(); + if (!statsTests.statsTests( CREATE_DB_NAME, dbSystem)) + { + return; + } + // Database copy test CopyDbTest copyDb = new CopyDbTest(); diff --git a/xflaim/csharp/xflaim/CacheInfo.cs b/xflaim/csharp/xflaim/CacheInfo.cs index 2cfb25f..a3646bb 100644 --- a/xflaim/csharp/xflaim/CacheInfo.cs +++ b/xflaim/csharp/xflaim/CacheInfo.cs @@ -34,7 +34,7 @@ namespace xflaim /// IMPORTANT NOTE: This structure must be kept in sync /// with the corresponding structure in ftk.h /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class FLM_SLAB_USAGE { /// Total slabs currently allocated. @@ -53,7 +53,7 @@ namespace xflaim /// IMPORTANT NOTE: This structure must be kept in sync /// with the corresponding structure in xflaim.h /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class CS_XFLM_CACHE_USAGE { /// Total bytes allocated for current versions of objects @@ -81,7 +81,7 @@ namespace xflaim /// IMPORTANT NOTE: This structure must be kept in sync /// with the corresponding structure in xflaim.h /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class CS_XFLM_CACHE_INFO { /// Current limit for cache diff --git a/xflaim/csharp/xflaim/DbSystem.cpp b/xflaim/csharp/xflaim/DbSystem.cpp index fc26b23..0d56be7 100644 --- a/xflaim/csharp/xflaim/DbSystem.cpp +++ b/xflaim/csharp/xflaim/DbSystem.cpp @@ -1600,3 +1600,76 @@ FLMEXTC FLMEXP void FLMAPI xflaim_DbSystem_getCacheInfo( copyCacheUsage( &pCacheInfo->NodeCache, &cacheInfo.NodeCache); pCacheInfo->bPreallocatedCache = cacheInfo.bPreallocatedCache; } + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_DbSystem_closeUnusedFiles( + FLMUINT64 ui64This, + FLMUINT32 ui32Seconds) +{ + IF_DbSystem * pDbSystem = ((IF_DbSystem *)(FLMUINT)ui64This); + + return( pDbSystem->closeUnusedFiles( (FLMUINT)ui32Seconds)); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP void FLMAPI xflaim_DbSystem_startStats( + FLMUINT64 ui64This) +{ + IF_DbSystem * pDbSystem = ((IF_DbSystem *)(FLMUINT)ui64This); + + pDbSystem->startStats(); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP void FLMAPI xflaim_DbSystem_stopStats( + FLMUINT64 ui64This) +{ + IF_DbSystem * pDbSystem = ((IF_DbSystem *)(FLMUINT)ui64This); + + pDbSystem->stopStats(); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP void FLMAPI xflaim_DbSystem_resetStats( + FLMUINT64 ui64This) +{ + IF_DbSystem * pDbSystem = ((IF_DbSystem *)(FLMUINT)ui64This); + + pDbSystem->resetStats(); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_DbSystem_getStats( + FLMUINT64 ui64This, + FLMUINT64 * pui64Stats) +{ + RCODE rc = NE_XFLM_OK; + IF_DbSystem * pDbSystem = ((IF_DbSystem *)(FLMUINT)ui64This); + XFLM_STATS * pStats = NULL; + + if (RC_BAD( rc = f_calloc( sizeof( XFLM_STATS), &pStats))) + { + goto Exit; + } + + if (RC_BAD( rc = pDbSystem->getStats( pStats))) + { + f_free( &pStats); + goto Exit; + } + +Exit: + + *pui64Stats = (FLMUINT64)((FLMUINT)pStats); + return( rc); +} diff --git a/xflaim/csharp/xflaim/DbSystem.cs b/xflaim/csharp/xflaim/DbSystem.cs index a513f6c..586934c 100644 --- a/xflaim/csharp/xflaim/DbSystem.cs +++ b/xflaim/csharp/xflaim/DbSystem.cs @@ -144,7 +144,7 @@ namespace xflaim /// IMPORTANT NOTE: This needs to be kept in sync with the same /// structure that is defined in xflaim.h /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class XFLM_CREATE_OPTS { @@ -2025,11 +2025,11 @@ namespace xflaim //----------------------------------------------------------------------------- /// - /// Determine if dynamic cache limits are supported on this platform. + /// Get cache information. /// /// - /// Flag indicating whether or not dynamic cache limits are - /// supported on this platform. + /// Returns a object which contains + /// information about cache. /// public CS_XFLM_CACHE_INFO getCacheInfo() { @@ -2040,10 +2040,115 @@ namespace xflaim } [DllImport("xflaim")] - private static extern int xflaim_DbSystem_getCacheInfo( - ulong pDbSystem, + private static extern void xflaim_DbSystem_getCacheInfo( + ulong pDbSystem, [Out] CS_XFLM_CACHE_INFO cacheInfo); +//----------------------------------------------------------------------------- +// closeUnusedFiles +//----------------------------------------------------------------------------- + + /// + /// Close all file descriptors that have are not currently in use and + /// have been out of use for at least n seconds. + /// + /// + /// Specifies the number of seconds. File descriptors that are not currently + /// in use and have been out of use for at least this amount of time will be + /// closed and released. A value of zero will cause all file descriptors not + /// currently in use to be closed and released. + /// + public void closeUnusedFiles( + uint uiSeconds) + { + RCODE rc; + + if ((rc = xflaim_DbSystem_closeUnusedFiles( m_pDbSystem, uiSeconds)) != 0) + { + throw new XFlaimException( rc); + } + } + + [DllImport("xflaim")] + private static extern RCODE xflaim_DbSystem_closeUnusedFiles( + ulong pDbSystem, + uint uiSeconds); + +//----------------------------------------------------------------------------- +// startStats +//----------------------------------------------------------------------------- + + /// + /// Start collecting of statistics. + /// + public void startStats() + { + xflaim_DbSystem_startStats( m_pDbSystem); + } + + [DllImport("xflaim")] + private static extern RCODE xflaim_DbSystem_startStats( + ulong pDbSystem); + +//----------------------------------------------------------------------------- +// stopStats +//----------------------------------------------------------------------------- + + /// + /// Stop collecting of statistics. NOTE: Statistics collected from the time + /// the method was called will still be available to + /// retrieve from the method. + /// + public void stopStats() + { + xflaim_DbSystem_stopStats( m_pDbSystem); + } + + [DllImport("xflaim")] + private static extern RCODE xflaim_DbSystem_stopStats( + ulong pDbSystem); + +//----------------------------------------------------------------------------- +// resetStats +//----------------------------------------------------------------------------- + + /// + /// Reset statistics. All current statistics are started over - as if the + /// method had been called. + /// + public void resetStats() + { + xflaim_DbSystem_resetStats( m_pDbSystem); + } + + [DllImport("xflaim")] + private static extern RCODE xflaim_DbSystem_resetStats( + ulong pDbSystem); + +//----------------------------------------------------------------------------- +// getStats +//----------------------------------------------------------------------------- + + /// + /// Retrieve the current statistics that have been collected so far. + /// + public DbSystemStats getStats() + { + RCODE rc; + ulong pDbSystemStats; + + if ((rc = xflaim_DbSystem_getStats( m_pDbSystem, out pDbSystemStats)) != 0) + { + throw new XFlaimException( rc); + } + return( new DbSystemStats( pDbSystemStats, this)); + } + + [DllImport("xflaim")] + private static extern RCODE xflaim_DbSystem_getStats( + ulong pDbSystem, + out ulong ppDbSystemStats); + } } diff --git a/xflaim/csharp/xflaim/DbSystemStats.cpp b/xflaim/csharp/xflaim/DbSystemStats.cpp new file mode 100644 index 0000000..82a0f29 --- /dev/null +++ b/xflaim/csharp/xflaim/DbSystemStats.cpp @@ -0,0 +1,168 @@ +//------------------------------------------------------------------------------ +// Desc: Native C routines to support C# DbSystemStats class +// +// Tabs: 3 +// +// Copyright (c) 2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id$ +//------------------------------------------------------------------------------ + +#include "xflaim.h" + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP void FLMAPI xflaim_DbSystemStats_freeStats( + FLMUINT64 ui64DbSystem, + FLMUINT64 ui64This) +{ + IF_DbSystem * pDbSystem = (IF_DbSystem *)((FLMUINT)ui64DbSystem); + XFLM_STATS * pStats = (XFLM_STATS *)((FLMUINT)ui64This); + + if (pStats) + { + pDbSystem->freeStats( pStats); + f_free( &pStats); + } +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP void FLMAPI xflaim_DbSystemStats_getGeneralStats( + FLMUINT64 ui64This, + FLMUINT32 * pui32NumDatabases, + FLMUINT32 * pui32StartTime, + FLMUINT32 * pui32StopTime) +{ + XFLM_STATS * pStats = (XFLM_STATS *)((FLMUINT)ui64This); + + *pui32NumDatabases = (FLMUINT32)pStats->uiNumDbStats; + *pui32StartTime = (FLMUINT32)pStats->uiStartTime; + *pui32StopTime = (FLMUINT32)pStats->uiStopTime; +} + +// IMPORTANT NOTE: This structure needs to stay in sync with the +// corresponding class in the C# code. +typedef struct +{ + char * pszDbName; + FLMUINT32 ui32NumLFiles; + XFLM_RTRANS_STATS ReadTransStats; + XFLM_UTRANS_STATS UpdateTransStats; + XFLM_BLOCKIO_STATS LFHBlockStats; + XFLM_BLOCKIO_STATS AvailBlockStats; + XFLM_DISKIO_STAT DbHdrWrites; + XFLM_DISKIO_STAT LogBlockWrites; + XFLM_DISKIO_STAT LogBlockRestores; + XFLM_DISKIO_STAT LogBlockReads; + FLMUINT32 ui32LogBlockChkErrs; + FLMUINT32 ui32ReadErrors; + FLMUINT32 ui32WriteErrors; + F_LOCK_STATS LockStats; +} CS_XFLM_DB_STATS; + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_DbSystemStats_getDbStats( + FLMUINT64 ui64This, + FLMUINT32 ui32DatabaseNum, + CS_XFLM_DB_STATS * pCSDbStats) +{ + RCODE rc = NE_XFLM_OK; + XFLM_STATS * pStats = (XFLM_STATS *)((FLMUINT)ui64This); + XFLM_DB_STATS * pDbStat; + + if ((FLMUINT)ui32DatabaseNum > pStats->uiNumDbStats - 1) + { + rc = RC_SET( NE_XFLM_INVALID_PARM); + goto Exit; + } + pDbStat = &pStats->pDbStats [ui32DatabaseNum]; + pCSDbStats->pszDbName = pDbStat->pszDbName; + pCSDbStats->ui32NumLFiles = (FLMUINT32)pDbStat->uiNumLFileStats; + f_memcpy( &pCSDbStats->ReadTransStats, &pDbStat->ReadTransStats, sizeof( XFLM_RTRANS_STATS)); + f_memcpy( &pCSDbStats->UpdateTransStats, &pDbStat->UpdateTransStats, sizeof( XFLM_UTRANS_STATS)); + f_memcpy( &pCSDbStats->LFHBlockStats, &pDbStat->LFHBlockStats, sizeof( XFLM_BLOCKIO_STATS)); + f_memcpy( &pCSDbStats->AvailBlockStats, &pDbStat->AvailBlockStats, sizeof( XFLM_BLOCKIO_STATS)); + f_memcpy( &pCSDbStats->DbHdrWrites, &pDbStat->DbHdrWrites, sizeof( XFLM_DISKIO_STAT)); + f_memcpy( &pCSDbStats->LogBlockWrites, &pDbStat->LogBlockWrites, sizeof( XFLM_DISKIO_STAT)); + f_memcpy( &pCSDbStats->LogBlockRestores, &pDbStat->LogBlockRestores, sizeof( XFLM_DISKIO_STAT)); + f_memcpy( &pCSDbStats->LogBlockReads, &pDbStat->LogBlockReads, sizeof( XFLM_DISKIO_STAT)); + pCSDbStats->ui32LogBlockChkErrs = (FLMUINT32)pDbStat->uiLogBlockChkErrs; + pCSDbStats->ui32ReadErrors = (FLMUINT32)pDbStat->uiReadErrors; + pCSDbStats->ui32WriteErrors = (FLMUINT32)pDbStat->uiWriteErrors; + f_memcpy( &pCSDbStats->LockStats, &pDbStat->LockStats, sizeof( F_LOCK_STATS)); + +Exit: + return( rc); +} + +// IMPORTANT NOTE: This structure needs to stay in sync with the +// corresponding class in the C# code. +typedef struct +{ + XFLM_BLOCKIO_STATS RootBlockStats; + XFLM_BLOCKIO_STATS MiddleBlockStats; + XFLM_BLOCKIO_STATS LeafBlockStats; + FLMUINT64 ui64BlockSplits; + FLMUINT64 ui64BlockCombines; + FLMUINT32 ui32LFileNum; + FLMINT32 i32LfType; +} CS_XFLM_LFILE_STATS; + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMEXTC FLMEXP RCODE FLMAPI xflaim_DbSystemStats_getLFileStats( + FLMUINT64 ui64This, + FLMUINT32 ui32DatabaseNum, + FLMUINT32 ui32LFileNum, + CS_XFLM_LFILE_STATS * pCSLFileStats) +{ + RCODE rc = NE_XFLM_OK; + XFLM_STATS * pStats = (XFLM_STATS *)((FLMUINT)ui64This); + XFLM_DB_STATS * pDbStat; + XFLM_LFILE_STATS * pLFileStat; + + if (ui32DatabaseNum > pStats->uiNumDbStats - 1) + { + rc = RC_SET( NE_XFLM_INVALID_PARM); + goto Exit; + } + pDbStat = &pStats->pDbStats [ui32DatabaseNum]; + if ((FLMUINT)ui32LFileNum > pDbStat->uiNumLFileStats) + { + rc = RC_SET( NE_XFLM_INVALID_PARM); + goto Exit; + } + pLFileStat = &pDbStat->pLFileStats [ui32LFileNum]; + f_memcpy( &pCSLFileStats->RootBlockStats, &pLFileStat->RootBlockStats, sizeof( XFLM_BLOCKIO_STATS)); + f_memcpy( &pCSLFileStats->MiddleBlockStats, &pLFileStat->MiddleBlockStats, sizeof( XFLM_BLOCKIO_STATS)); + f_memcpy( &pCSLFileStats->LeafBlockStats, &pLFileStat->LeafBlockStats, sizeof( XFLM_BLOCKIO_STATS)); + pCSLFileStats->ui64BlockSplits = pLFileStat->ui64BlockSplits; + pCSLFileStats->ui64BlockCombines = pLFileStat->ui64BlockCombines; + pCSLFileStats->ui32LFileNum = (FLMUINT32)pLFileStat->uiLFileNum; + pCSLFileStats->i32LfType = (FLMINT32)pLFileStat->eLfType; + +Exit: + + return( rc); +} diff --git a/xflaim/csharp/xflaim/DbSystemStats.cs b/xflaim/csharp/xflaim/DbSystemStats.cs new file mode 100644 index 0000000..bdb1fa7 --- /dev/null +++ b/xflaim/csharp/xflaim/DbSystemStats.cs @@ -0,0 +1,416 @@ +//------------------------------------------------------------------------------ +// Desc: System statistics +// +// Tabs: 3 +// +// Copyright (c) 2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id$ +//------------------------------------------------------------------------------ +using System; +using System.Runtime.InteropServices; + +namespace xflaim +{ + + /// + /// Structure used in gathering statistics to hold an operation count elapsed time. + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in ftk.h + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class F_COUNT_TIME_STAT + { + /// Number of times operation was performed + public ulong ulCount; + /// Total elamsed time (milliseconds) for the operations + public ulong ulElapMilli; + } + + /// + /// Lock statistics. + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in ftk.h + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class F_LOCK_STATS + { + /// Statistics on times when nobody was holding a lock on the database. + public F_COUNT_TIME_STAT NoLocks; + /// Statistics on times threads were waiting to obtain a database lock. + public F_COUNT_TIME_STAT WaitingForLock; + /// Statistics on times when a thread was holding a lock on the database. + public F_COUNT_TIME_STAT HeldLock; + } + + /// + /// Read transaction statistics + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in xflaim.h + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class XFLM_RTRANS_STATS + { + /// Committed read transaction statistics + public F_COUNT_TIME_STAT CommittedTrans; + /// Aborted read transaction statistics + public F_COUNT_TIME_STAT AbortedTrans; + } + + /// + /// Update transaction statistics. + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in xflaim.h + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class XFLM_UTRANS_STATS + { + /// Committed update transaction statistics + public F_COUNT_TIME_STAT CommittedTrans; + /// Group complete statistics + public F_COUNT_TIME_STAT GroupCompletes; + /// Transactions that finished in a group + public ulong ulGroupFinished; + /// Aborted update transaction statistics + public F_COUNT_TIME_STAT AbortedTrans; + } + + /// + /// Disk IO statistics. + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in xflaim.h + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class XFLM_DISKIO_STAT + { + /// Number of times read or write operation was performed. + public ulong ulCount; + /// Total number of bytes read or written. + public ulong ulTotalBytes; + /// Total elapsed time (milliseconds) for the read or write operations. + public ulong ulElapMilli; + } + + /// + /// Block statistics. + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in xflaim.h + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class XFLM_BLOCKIO_STATS + { + /// Statistics on block reads + public XFLM_DISKIO_STAT BlockReads; + /// Statistics on block writes + public XFLM_DISKIO_STAT BlockWrites; + /// Statistics on old view block reads + public XFLM_DISKIO_STAT OldViewBlockReads; + /// Number of checksum errors reading blocks. + public uint uiBlockChkErrs; + /// Number of checksum errors reading old versions of blocks. + public uint uiOldViewBlockChkErrs; + /// Number of times we had an old view error when reading + public uint uiOldViewErrors; + } + + /// + /// Logical file statistics + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in DbSystemStats.cpp + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class CS_XFLM_LFILE_STATS + { + /// Block statistics for root blocks in this logical file. + public XFLM_BLOCKIO_STATS RootBlockStats; + /// Block statistics for middle blocks in this logical file. + public XFLM_BLOCKIO_STATS MiddleBlockStats; + /// Block statistics for leaf blocks in this logical file. + public XFLM_BLOCKIO_STATS LeafBlockStats; + /// Total blocks splits that have been done in this logical file. + public ulong ulBlockSplits; + /// Total block combines that have been done in this logical file. + public ulong ulBlockCombines; + /// Logical file number. + public uint uiLFileNum; + /// Type of logical file. + public eLFileType eLfType; + } + + /// + /// Database statistics + /// IMPORTANT NOTE: This needs to be kept in sync with the + /// corresponding definition in DbSystemStats.cpp + /// + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] + public class CS_XFLM_DB_STATS + { + /// Database name + [MarshalAs(UnmanagedType.LPStr)] + public string sDbName; + /// Number of logical files we have statistics for + public uint uiNumLFiles; + /// Read transaction statistics + public XFLM_RTRANS_STATS ReadTransStats; + /// Update transaction statistics + public XFLM_UTRANS_STATS UpdateTransStats; + /// Block statistics for Logical File Header blocks + public XFLM_BLOCKIO_STATS LFHBlockStats; + /// Block statistics for avail blocks + public XFLM_BLOCKIO_STATS AvailBlockStats; + /// Disk IO statistics for database header writes + public XFLM_DISKIO_STAT DbHdrWrites; + /// Disk IO statistics for log block writes + public XFLM_DISKIO_STAT LogBlockWrites; + /// Disk IO statistics for log block restores + public XFLM_DISKIO_STAT LogBlockRestores; + /// Disk IO statistics for log block reads + public XFLM_DISKIO_STAT LogBlockReads; + /// Log block checksum errors + public uint uiLogBlockChkErrs; + /// Total read errors + public uint uiReadErrors; + /// Total write errors + public uint uiWriteErrors; + /// Lock statistics + public F_LOCK_STATS LockStats; + } + + /// + /// The DbSystemStats class provides a number of methods that allow C# + /// applications to access statistics that have been requested. A + /// DbSystemStats object is obtained by calling . + /// + public class DbSystemStats + { + private ulong m_pStats; // Pointer to XFLM_STATS object in unmanaged space + private DbSystem m_dbSystem; + + /// + /// Constructor. + /// + /// + /// Pointer to an XFLM_STATS object in unmanaged space. + /// + /// + /// DbSystem object that this DbSystemStats object is associated with. + /// + internal DbSystemStats( + ulong pStats, + DbSystem dbSystem) + { + if (pStats == 0) + { + throw new XFlaimException( "Invalid pointer to XFLM_STATS structure"); + } + + m_pStats = pStats; + + if (dbSystem == null) + { + throw new XFlaimException( "Invalid DbSystem reference"); + } + + m_dbSystem = dbSystem; + + // Must call something inside of DbSystem. Otherwise, the + // m_dbSystem object gets a compiler warning on linux because + // it is not used anywhere. Other than that, there is really + // no need to make the following call. + if (m_dbSystem.getDbSystem() == 0) + { + throw new XFlaimException( "Invalid DbSystem.IF_DbSystem object"); + } + } + + /// + /// Destructor. + /// + ~DbSystemStats() + { + freeStats(); + } + + /// + /// Free the statistics assocated with this object. + /// + public void freeStats() + { + // Free the unmanaged XFLM_STATS structure. + + if (m_pStats != 0) + { + xflaim_DbSystemStats_freeStats( m_dbSystem.getDbSystem(), m_pStats); + m_pStats = 0; + } + + // Remove our reference to the dbSystem so it can be released. + + m_dbSystem = null; + } + + [DllImport("xflaim")] + private static extern void xflaim_DbSystemStats_freeStats( + ulong pDbSystem, + ulong pStats); + +//----------------------------------------------------------------------------- +// getGeneralStats +//----------------------------------------------------------------------------- + + /// + /// Retrieve some general statistics. + /// + /// + /// Returns number of databases there are statistics for. + /// + /// + /// Returns time statistics were started. + /// + /// + /// Returns time statistics were stopped. + /// + public void getGeneralStats( + out uint uiNumDatabases, + out uint uiStartTime, + out uint uiStopTime) + { + xflaim_DbSystemStats_getGeneralStats( m_pStats, + out uiNumDatabases, out uiStartTime, out uiStopTime); + } + + [DllImport("xflaim")] + private static extern void xflaim_DbSystemStats_getGeneralStats( + ulong pStats, + out uint puiNumDatabases, + out uint puiStartTime, + out uint puiStopTime); + +//----------------------------------------------------------------------------- +// getDbStats +//----------------------------------------------------------------------------- + + /// + /// Retrieve statistics for a particular database. + /// + /// + /// Number of the database for which statistics are to be returned. + /// This number should be between 0 and N - 1, where N = Number of + /// databases for which we have statistics. + /// The number of databases may be determined by calling the + /// method. + /// + /// + /// A object to return the requested + /// database statistics in. If null, an object will be allocated. + /// + /// + /// A object is returned which + /// holds statistics for the specified database. + /// + public CS_XFLM_DB_STATS getDbStats( + uint uiDatabaseNum, + CS_XFLM_DB_STATS dbStats) + { + RCODE rc; + + if (dbStats == null) + { + dbStats = new CS_XFLM_DB_STATS(); + } + + if ((rc = xflaim_DbSystemStats_getDbStats( m_pStats, uiDatabaseNum, + dbStats)) != 0) + { + throw new XFlaimException( rc); + } + return( dbStats); + } + + [DllImport("xflaim")] + private static extern RCODE xflaim_DbSystemStats_getDbStats( + ulong pStats, + uint uiDatabaseNum, + [Out] + CS_XFLM_DB_STATS pDbStats); + +//----------------------------------------------------------------------------- +// getLFileStats +//----------------------------------------------------------------------------- + + /// + /// Retrieve statistics for a particular logical file in a particular + /// database. + /// + /// + /// Number of the database for which logical file + /// statistics are to be returned. + /// This number should be between 0 and N - 1, where N = Number of + /// databases for which we have statistics. + /// The number of databases may be determined by calling the + /// method. + /// + /// + /// Number of the logical file for which logical file + /// statistics are to be returned. + /// This number should be between 0 and N - 1, where N = Number of + /// logical files for the specified database. The number of logical + /// files for a particular database is found in the + /// member of the + /// object, which is returned from the + /// method. + /// + /// + /// A object to return the requested + /// statistics in. If null, an object will be allocated. + /// + /// + /// A object is returned which + /// holds statistics for the specified logical file of the + /// specified database. + /// + public CS_XFLM_LFILE_STATS getLFileStats( + uint uiDatabaseNum, + uint uiLFileNum, + CS_XFLM_LFILE_STATS lFileStats) + { + RCODE rc; + + if (lFileStats == null) + { + lFileStats = new CS_XFLM_LFILE_STATS(); + } + + if ((rc = xflaim_DbSystemStats_getLFileStats( m_pStats, uiDatabaseNum, + uiLFileNum, lFileStats)) != 0) + { + throw new XFlaimException( rc); + } + return( lFileStats); + } + + [DllImport("xflaim")] + private static extern RCODE xflaim_DbSystemStats_getLFileStats( + ulong pStats, + uint uiDatabaseNum, + uint uiLFileNum, + [Out] + CS_XFLM_LFILE_STATS pLFileStats); + + } +} diff --git a/xflaim/csharp/xflaim/dbCheck.cs b/xflaim/csharp/xflaim/dbCheck.cs index 5d8e32c..d466c81 100644 --- a/xflaim/csharp/xflaim/dbCheck.cs +++ b/xflaim/csharp/xflaim/dbCheck.cs @@ -287,7 +287,7 @@ namespace xflaim /// IMPORTANT NOTE: This structure needs to stay in sync with the XFLM_CORRUPT_INFO /// structure defined in xflaim.h /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class XFLM_CORRUPT_INFO { /// Corruption error code being reported. @@ -358,7 +358,7 @@ namespace xflaim /// IMPORTANT NOTE: This structure needs to stay in sync with the XFLM_PROGRESS_CHECK_INFO /// structure defined in xflaim.h /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class XFLM_PROGRESS_CHECK_INFO { /// diff --git a/xflaim/csharp/xflaim/dbRebuild.cs b/xflaim/csharp/xflaim/dbRebuild.cs index 1e82bf4..1ab109b 100644 --- a/xflaim/csharp/xflaim/dbRebuild.cs +++ b/xflaim/csharp/xflaim/dbRebuild.cs @@ -48,7 +48,7 @@ namespace xflaim /// IMPORTANT NOTE: This structure needs to stay in sync with the XFLM_REBUILD_INFO /// structure defined in xflaim.h /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class XFLM_REBUILD_INFO { /// Current phase of the rebuild operation diff --git a/xflaim/java/jni/jdbsystem.cpp b/xflaim/java/jni/jdbsystem.cpp index 11d0433..7b19b21 100644 --- a/xflaim/java/jni/jdbsystem.cpp +++ b/xflaim/java/jni/jdbsystem.cpp @@ -2857,11 +2857,11 @@ FSTATIC jobject NewBlockIOStats( pEnv->SetObjectField( jBlockIOStats, fid_BlockIOStats_oldViewBlockReads, jOldViewBlockReads); pEnv->SetIntField( jBlockIOStats, fid_BlockIOStats_iBlockChkErrs, - (jint)pBlockIOStats->uiBlockChkErrs); + (jint)pBlockIOStats->ui32BlockChkErrs); pEnv->SetIntField( jBlockIOStats, fid_BlockIOStats_iOldViewBlockChkErrs, - (jint)pBlockIOStats->uiOldViewBlockChkErrs); + (jint)pBlockIOStats->ui32OldViewBlockChkErrs); pEnv->SetIntField( jBlockIOStats, fid_BlockIOStats_iOldViewErrors, - (jint)pBlockIOStats->uiOldViewErrors); + (jint)pBlockIOStats->ui32OldViewErrors); pEnv->SetObjectField( jBlockIOStats, fid_BlockIOStats_blockWrites, jBlockWrites); diff --git a/xflaim/src/flmstat.cpp b/xflaim/src/flmstat.cpp index 0687fa8..e086f40 100644 --- a/xflaim/src/flmstat.cpp +++ b/xflaim/src/flmstat.cpp @@ -593,9 +593,9 @@ void flmUpdateBlockIOStats( flmUpdateDiskIOStats( &pDest->BlockReads, &pSrc->BlockReads); flmUpdateDiskIOStats( &pDest->OldViewBlockReads, &pSrc->OldViewBlockReads); - pDest->uiBlockChkErrs += pSrc->uiBlockChkErrs; - pDest->uiOldViewBlockChkErrs += pSrc->uiOldViewBlockChkErrs; - pDest->uiOldViewErrors += pSrc->uiOldViewErrors; + pDest->ui32BlockChkErrs += pSrc->ui32BlockChkErrs; + pDest->ui32OldViewBlockChkErrs += pSrc->ui32OldViewBlockChkErrs; + pDest->ui32OldViewErrors += pSrc->ui32OldViewErrors; flmUpdateDiskIOStats( &pDest->BlockWrites, &pSrc->BlockWrites); } diff --git a/xflaim/src/scache.cpp b/xflaim/src/scache.cpp index e0a4828..efeef94 100644 --- a/xflaim/src/scache.cpp +++ b/xflaim/src/scache.cpp @@ -3262,14 +3262,14 @@ Exit: flmUpdateDiskIOStats( &pBlockIOStats->OldViewBlockReads, &TmpReadStats.OldViewBlockReads); - pBlockIOStats->uiBlockChkErrs += - TmpReadStats.uiBlockChkErrs; + pBlockIOStats->ui32BlockChkErrs += + (FLMUINT32)TmpReadStats.uiBlockChkErrs; - pBlockIOStats->uiOldViewBlockChkErrs += - TmpReadStats.uiOldViewBlockChkErrs; + pBlockIOStats->ui32OldViewBlockChkErrs += + (FLMUINT32)TmpReadStats.uiOldViewBlockChkErrs; if (rc == NE_XFLM_OLD_VIEW || bIncrOldViewCnt) { - pBlockIOStats->uiOldViewErrors++; + pBlockIOStats->ui32OldViewErrors++; } } } diff --git a/xflaim/src/xflaim.h b/xflaim/src/xflaim.h index 8de9e69..78bef9e 100644 --- a/xflaim/src/xflaim.h +++ b/xflaim/src/xflaim.h @@ -638,6 +638,8 @@ FLMBOOL bPreallocatedCache; } CS_XFLM_CACHE_INFO; + // IMPORTANT NOTE: This structure needs to stay in sync with + // corresponding structures in java and C# code. typedef struct { FLMUINT64 ui64Count; // Number of times read or @@ -650,12 +652,16 @@ // read or write operations. } XFLM_DISKIO_STAT; + // IMPORTANT NOTE: This structure needs to stay in sync with + // corresponding structures in java and C# code. typedef struct { F_COUNT_TIME_STAT CommittedTrans; // Transactions committed F_COUNT_TIME_STAT AbortedTrans; // Transactions aborted } XFLM_RTRANS_STATS; + // IMPORTANT NOTE: This structure needs to stay in sync with + // corresponding structures in java and C# code. typedef struct { F_COUNT_TIME_STAT CommittedTrans; // Transactions committed @@ -664,21 +670,23 @@ F_COUNT_TIME_STAT AbortedTrans; // Transactions aborted } XFLM_UTRANS_STATS; + // IMPORTANT NOTE: This structure needs to stay in sync with + // corresponding structures in java and C# code. typedef struct { XFLM_DISKIO_STAT BlockReads; // Statistics on block reads. + XFLM_DISKIO_STAT BlockWrites; // Statistics on Block writes. XFLM_DISKIO_STAT OldViewBlockReads; // Statistics on old view // block reads. - FLMUINT uiBlockChkErrs; // Number of times we had + FLMUINT32 ui32BlockChkErrs; // Number of times we had // check errors reading // blocks. - FLMUINT uiOldViewBlockChkErrs; // Number of times we had + FLMUINT32 ui32OldViewBlockChkErrs;// Number of times we had // check errors reading an // old view of a block. - FLMUINT uiOldViewErrors; // Number of times we had an + FLMUINT32 ui32OldViewErrors; // Number of times we had an // old view error when // reading. - XFLM_DISKIO_STAT BlockWrites; // Statistics on Block writes. } XFLM_BLOCKIO_STATS; typedef struct