--- a/persistentstorage/dbms/tdbms/t_dbbench.cpp Mon Sep 27 11:59:56 2010 +0100
+++ b/persistentstorage/dbms/tdbms/t_dbbench.cpp Tue Oct 19 16:26:13 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -20,157 +20,32 @@
#include <e32svr.h>
#include <hal.h>
#include <d32dbmsconstants.h>
-
-// MSVC++ up to 5.0 has problems with expanding inline functions
-// This disables the mad warnings for the whole project
-#if defined(NDEBUG) && defined(__VC32__) && _MSC_VER<=1100
-#pragma warning(disable : 4710) // function not expanded. MSVC 5.0 is stupid
-#endif
+#include "t_dbcmdlineutil.h"
-class TTimer
- {
-public:
- void Start();
- TReal Stop() const;
-private:
- TUint iTicks;
- };
+TCmdLineParams TheCmdLineParams;
+TFileName TheDbFileName;
+RFile TheLogFile;
+RTest TheTest(_L("t_dbbench"));
+RDbNamedDatabase TheDatabase;
+RDbView TheView;
+RFs TheFs;
-LOCAL_D RTest test(_L("t_dbbench"));
-LOCAL_D CTrapCleanup* TheTrapCleanup;
-LOCAL_D RDbNamedDatabase TheDatabase;
-LOCAL_D RDbView TheView;
-LOCAL_D RFs TheFs;
+TBuf<250> TheLogLine;
+TBuf8<250> TheLogLine8;
-const TInt KTestCleanupStack=0x20;
-//T_BENCH file shall not be deleted at the end of the test! It will be used by T_COMP test.
-const TPtrC KTestDatabase=_S("\\DBMS-TST\\T_BENCH.DB");
const TPtrC KTableName=_S("Test");
const TPtrC KColCluster=_S("Cluster");
const TPtrC KColXcluster=_S("xCluster");
const TPtrC KColRandom=_S("Random");
const TPtrC KColXrandom=_S("xRandom");
-const TInt KRecords=2000;
-
-static TTimer TheTimer;
-
-void TTimer::Start()
- {
- iTicks=User::FastCounter();
- }
-
-TReal TTimer::Stop() const
- {
- TUint ticks = User::FastCounter() - iTicks;
- TInt freq = 0;
- test(HAL::Get(HAL::EFastCounterFrequency, freq) == KErrNone);
- const TInt KMicroSecIn1Sec = 1000000;
- const TInt KMsIn1Sec = 1000;
- double v = ((double)ticks * KMicroSecIn1Sec) / (double)freq; TInt v2 = (TInt)v;
- return v2 / KMsIn1Sec;
- }
-
-LOCAL_C void CloseDatabase()
- {
- TheDatabase.Close();
- }
-
-/**
-Create the database: keep the code 050 compatible
-
-@SYMTestCaseID SYSLIB-DBMS-CT-0577
-@SYMTestCaseDesc Benchmark Tests. Creation of a local Database test
-@SYMTestPriority Medium
-@SYMTestActions Attempt to test RDbNamedDatabase::CreateTable(),RDbNamedDatabase::CreateIndex(),
- RDbNamedDatabase::Compact(),RDbView::Prepare() functions
-@SYMTestExpectedResults Test must not fail
-@SYMREQ REQ0000
-*/
-LOCAL_C void CreateDatabaseL()
- {
- test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0577 "));
- User::LeaveIfError(TheDatabase.Replace(TheFs,KTestDatabase));
- CDbColSet& set=*CDbColSet::NewLC();
- TDbCol col(KColCluster,EDbColInt32);
- col.iAttributes=col.ENotNull;
- set.AddL(col);
- col.iName=KColXcluster;
- set.AddL(col);
- col.iName=KColRandom;
- set.AddL(col);
- col.iName=KColXrandom;
- set.AddL(col);
- TInt r=TheDatabase.CreateTable(KTableName,set);
- test (r==KErrNone);
- CleanupStack::PopAndDestroy();
- TheTimer.Start();
- r=TheView.Prepare(TheDatabase,_L("select * from test"),TheView.EInsertOnly);
- TheDatabase.Begin();
- test (r==KErrNone);
- TInt jj=0;
- for (TInt ii=0;ii<KRecords;++ii)
- {
- TheView.InsertL();
- jj=(jj+23);
- if (jj>=KRecords)
- jj-=KRecords;
- TheView.SetColL(1,ii);
- TheView.SetColL(2,ii);
- TheView.SetColL(3,jj);
- TheView.SetColL(4,jj);
- TheView.PutL();
- }
- r=TheDatabase.Commit();
- test (r==KErrNone);
- TheView.Close();
- test.Printf(_L("Build table: %7.1f ms\n"),TheTimer.Stop());
- TheTimer.Start();
- CDbKey& key=*CDbKey::NewLC();
- key.AddL(KColXcluster);
- key.MakeUnique();
- r=TheDatabase.CreateIndex(KColXcluster,KTableName,key);
- test (r==KErrNone);
- test.Printf(_L("Cluster index: %7.1f ms\n"),TheTimer.Stop());
- TheTimer.Start();
- key.Clear();
- key.AddL(KColXrandom);
- r=TheDatabase.CreateIndex(KColXrandom,KTableName,key);
- test (r==KErrNone);
- CleanupStack::PopAndDestroy();
- test.Printf(_L("Random index: %7.1f ms\n"),TheTimer.Stop());
- TheTimer.Start();
- r = TheDatabase.Compact();
- test.Printf(_L("Compact: %7.1f ms\n"),TheTimer.Stop());
- test (r == KErrNone);
- }
-
-LOCAL_C TReal Evaluate(const TDesC& aSql)
- {
- TInt m=1;
- for (;;)
- {
- TheTimer.Start();
- for (TInt ii=0;ii<m;++ii)
- {
- TInt r=TheView.Prepare(TheDatabase,aSql,KDbUnlimitedWindow,TheView.EReadOnly);
- if (r<0)
- return r;
- r=TheView.EvaluateAll();
- test (r==KErrNone);
- TheView.Close();
- }
- TReal t=TheTimer.Stop();
- if (t>=100.0)
- return t/m;
- m*=4;
- }
- }
+const TInt KRecords=2000;
struct TTest
{
const TText* iName;
const TText* iQuery;
};
+
const TTest KQuery[]=
{
{_S("project"),_S("select cluster,xcluster,random,xrandom from test")},
@@ -185,6 +60,200 @@
{_S("all 4"),_S("select * from test where xcluster<500 and xrandom<200 order by xcluster")}
};
+///////////////////////////////////////////////////////////////////////////////////////
+
+void TestEnvDestroy()
+ {
+ TheView.Close();
+ TheDatabase.Close();
+ if(TheCmdLineParams.iLogFileName.Length() > 0)
+ {
+ (void)TheLogFile.Flush();
+ TheLogFile.Close();
+ }
+ //T_BENCH.DB cannot be deleted here, because it is used by T_DBCOMP test!
+ TheFs.Close();
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+//Test macros and functions
+void Check1(TInt aValue, TInt aLine)
+ {
+ if(!aValue)
+ {
+ TestEnvDestroy();
+ TheTest.Printf(_L("*** Line %d. Expression evaluated to false\r\n"), aLine);
+ TheTest(EFalse, aLine);
+ }
+ }
+void Check2(TInt aValue, TInt aExpected, TInt aLine)
+ {
+ if(aValue != aExpected)
+ {
+ TestEnvDestroy();
+ TheTest.Printf(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
+ TheTest(EFalse, aLine);
+ }
+ }
+#define TEST(arg) ::Check1((arg), __LINE__)
+#define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+TInt FastCounterFrequency()
+ {
+ static TInt freq = 0;
+ if(freq == 0)
+ {
+ TEST2(HAL::Get(HAL::EFastCounterFrequency, freq), KErrNone);
+ }
+ return freq;
+ }
+
+//Prints the test case title and execution time in microseconds
+void PrintResult(const TDesC& aTitle, TUint32 aStartTicks, TUint32 aEndTicks, TInt aIterations = 0)
+ {
+ TInt freq = FastCounterFrequency();
+ TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
+ if(diffTicks < 0)
+ {
+ diffTicks = KMaxTUint32 + diffTicks + 1;
+ }
+ const TInt KMicroSecIn1Sec = 1000000;
+ TInt32 us = (diffTicks * KMicroSecIn1Sec) / freq;
+ if(aIterations > 0)
+ {
+ us /= aIterations;
+ }
+ TheTest.Printf(_L("%S: %d us\r\n"), &aTitle, us);
+ if(TheCmdLineParams.iLogFileName.Length() > 0)
+ {
+ TheLogLine.Format(_L("%S¬%d¬us\r\n"), &aTitle, us);
+ TheLogLine8.Copy(TheLogLine);
+ (void)TheLogFile.Write(TheLogLine8);
+ }
+ }
+
+//Calculates time in microseconds
+TInt CalcTime(TUint32 aStartTicks, TUint32 aEndTicks)
+ {
+ TInt freq = FastCounterFrequency();
+ TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
+ if(diffTicks < 0)
+ {
+ diffTicks = KMaxTUint32 + diffTicks + 1;
+ }
+ const TInt KMicroSecIn1Sec = 1000000;
+ TInt32 us = (diffTicks * KMicroSecIn1Sec) / freq;
+ return us;
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+/**
+Create the database: keep the code 050 compatible
+
+@SYMTestCaseID SYSLIB-DBMS-CT-0577
+@SYMTestCaseDesc Benchmark Tests. Creation of a local Database test
+@SYMTestPriority Medium
+@SYMTestActions Attempt to test RDbNamedDatabase::CreateTable(),RDbNamedDatabase::CreateIndex(),
+ RDbNamedDatabase::Compact(),RDbView::Prepare() functions
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void CreateDatabaseL()
+ {
+ TInt err = TheDatabase.Replace(TheFs, TheDbFileName);
+ TEST2(err, KErrNone);
+
+ CDbColSet* set = CDbColSet::NewLC();
+ TDbCol col(KColCluster,EDbColInt32);
+ col.iAttributes=col.ENotNull;
+ set->AddL(col);
+ col.iName=KColXcluster;
+ set->AddL(col);
+ col.iName=KColRandom;
+ set->AddL(col);
+ col.iName=KColXrandom;
+ set->AddL(col);
+
+ err = TheDatabase.CreateTable(KTableName, *set);
+ TEST2(err, KErrNone);
+ CleanupStack::PopAndDestroy(set);
+
+ TUint32 ticksStart = User::FastCounter();
+ err = TheView.Prepare(TheDatabase,_L("select * from test"),TheView.EInsertOnly);
+ TEST2(err, KErrNone);
+ TheDatabase.Begin();
+ TInt jj=0;
+ for (TInt ii=0;ii<KRecords;++ii)
+ {
+ TheView.InsertL();
+ jj=(jj+23);
+ if (jj>=KRecords)
+ jj-=KRecords;
+ TheView.SetColL(1,ii);
+ TheView.SetColL(2,ii);
+ TheView.SetColL(3,jj);
+ TheView.SetColL(4,jj);
+ TheView.PutL();
+ }
+ err = TheDatabase.Commit();
+ TEST2(err, KErrNone);
+ TheView.Close();
+ TUint32 ticksEnd = User::FastCounter();
+ PrintResult(_L("Build table"), ticksStart, ticksEnd);
+
+ ticksStart = User::FastCounter();
+ CDbKey* key = CDbKey::NewLC();
+ key->AddL(KColXcluster);
+ key->MakeUnique();
+ err = TheDatabase.CreateIndex(KColXcluster,KTableName,*key);
+ TEST2(err, KErrNone);
+ ticksEnd = User::FastCounter();
+ PrintResult(_L("Cluster index"), ticksStart, ticksEnd);
+
+ ticksStart = User::FastCounter();
+ key->Clear();
+ key->AddL(KColXrandom);
+ err = TheDatabase.CreateIndex(KColXrandom,KTableName,*key);
+ TEST2(err, KErrNone);
+ CleanupStack::PopAndDestroy(key);
+ ticksEnd = User::FastCounter();
+ PrintResult(_L("Random index"), ticksStart, ticksEnd);
+
+ ticksStart = User::FastCounter();
+ err = TheDatabase.Compact();
+ ticksEnd = User::FastCounter();
+ PrintResult(_L("Compact"), ticksStart, ticksEnd);
+ TEST2(err, KErrNone);
+ }
+
+void Evaluate(const TDesC& aTitle, const TDesC& aSql)
+ {
+ TInt m = 1;
+ for(;;)
+ {
+ TUint32 ticksStart = User::FastCounter();
+ for(TInt i=0; i<m; ++i)
+ {
+ TInt err = TheView.Prepare(TheDatabase,aSql,KDbUnlimitedWindow,TheView.EReadOnly);
+ TEST2(err, KErrNone);
+ err = TheView.EvaluateAll();
+ TEST2(err, KErrNone);
+ TheView.Close();
+ }
+ TUint32 ticksEnd = User::FastCounter();
+ TInt us = CalcTime(ticksStart, ticksEnd);
+ if(us > 100000)
+ {
+ PrintResult(aTitle, ticksStart, ticksEnd, m);
+ return;
+ }
+ m *= 4;
+ }
+ }
+
/**
@SYMTestCaseID SYSLIB-DBMS-CT-0578
@SYMTestCaseDesc Benchmark Test.Querying a local Database Test
@@ -193,102 +262,68 @@
@SYMTestExpectedResults Test must not fail
@SYMREQ REQ0000
*/
-LOCAL_C void Queries()
+void Queries()
{
- test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0578 "));
- for (TUint ii=0;ii<sizeof(KQuery)/sizeof(KQuery[0]);++ii)
+ for(TUint ii=0;ii<sizeof(KQuery)/sizeof(KQuery[0]);++ii)
{
- test.Printf(_L("%15s: "),KQuery[ii].iName);
- TReal t=Evaluate(TPtrC(KQuery[ii].iQuery));
- if (t<0.0)
- test.Printf(_L("-\n"));
- else
- test.Printf(_L("%7.1f ms\n"),t);
+ Evaluate(TPtrC(KQuery[ii].iName), TPtrC(KQuery[ii].iQuery));
}
}
-//
-// Benchmark tests
-//
-LOCAL_C void BenchTestL()
+void BenchTestL()
{
+ TheTest.Start(_L("@SYMTestCaseID:SYSLIB-DBMS-CT-0577 RDbNamedDatabase performance test"));
CreateDatabaseL();
+
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0578 SQL queries performance test"));
Queries();
- CloseDatabase();
+
+ TheDatabase.Close();
}
-//
-// Prepare the test directory.
-//
-LOCAL_C void setupTestDirectory()
+void TestEnvInit()
{
- TInt r=TheFs.Connect();
- test(r==KErrNone);
-//
-#if 0
- TDriveList drives;
- TheFs.DriveList(drives);
- if (drives[EDriveK] == KDriveAbsent)
+ TInt err = TheFs.Connect();
+ TEST2(err, KErrNone);
+
+ err = TheFs.MkDirAll(TheDbFileName);
+ TEST(err == KErrNone || err == KErrAlreadyExists);
+
+ if(TheCmdLineParams.iLogFileName.Length() > 0)
{
- TInt r = TheFs.AddFileSystem(_L("ELFFS"));
- test (r == KErrNone);
- r = TheFs.MountFileSystem(_L("Lffs"),EDriveK);
- if (r == KErrCorrupt || r == KErrNotReady)
- {
- RFormat format;
- TInt count;
- r = format.Open(TheFs, _L("K:\\"), EHighDensity, count);
- test (r == KErrNone);
- while (count)
- format.Next(count);
- format.Close();
- }
- else
- test (r == KErrNone);
+ err = TheLogFile.Replace(TheFs, TheCmdLineParams.iLogFileName, EFileRead | EFileWrite);
+ TEST2(err, KErrNone);
+ LogConfig(TheLogFile, TheCmdLineParams);
}
-#endif
-//
- r=TheFs.MkDir(KTestDatabase);
- test(r==KErrNone || r==KErrAlreadyExists);
- }
+ }
+
+TInt E32Main()
+ {
+ TheTest.Title();
+
+ CTrapCleanup* tc = CTrapCleanup::New();
+ TheTest(tc != NULL);
-//
-// Initialise the cleanup stack.
-//
-LOCAL_C void setupCleanup()
- {
- TheTrapCleanup=CTrapCleanup::New();
- test(TheTrapCleanup!=NULL);
- TRAPD(r,\
- {\
- for (TInt i=KTestCleanupStack;i>0;i--)\
- CleanupStack::PushL((TAny*)0);\
- CleanupStack::Pop(KTestCleanupStack);\
- });
- test(r==KErrNone);
- }
+ GetCmdLineParams(TheTest, _L("t_dbbench"), TheCmdLineParams);
+ _LIT(KDbName, "c:\\dbms-tst\\t_bench.db");
+ PrepareDbName(KDbName, TheCmdLineParams.iDriveName, TheDbFileName);
+ TheTest.Printf(_L("==Database: %S\r\n"), &TheDbFileName);
-//
-// entry point
-//
-GLDEF_C TInt E32Main()
- {
- test.Title();
- setupTestDirectory();
- setupCleanup();
__UHEAP_MARK;
-//
- test.Start(_L("Benchmarking..."));
- TRAPD(r,BenchTestL());
- test(r==KErrNone);
- test.End();
-//
+
+ TestEnvInit();
+ TRAPD(err, BenchTestL());
+ TEST2(err, KErrNone);
+ TestEnvDestroy();
+
__UHEAP_MARKEND;
- delete TheTrapCleanup;
- //T_BENCH.DB cannot be deleted here, because it is used by T_COMP test!
-
- TheFs.Close();
- test.Close();
- return 0;
+ User::Heap().Check();
+
+ TheTest.End();
+ TheTest.Close();
+
+ delete tc;
+
+ return KErrNone;
}