persistentstorage/dbms/tdbms/t_dbbench.cpp
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/tdbms/t_dbbench.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,294 @@
+// Copyright (c) 1998-2009 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"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <d32dbms.h>
+#include <s32file.h>
+#include <e32test.h>
+#include <e32math.h>
+#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
+
+class TTimer
+	{
+public:
+	void Start();
+	TReal Stop() const;
+private:
+	TUint iTicks;
+	};
+
+LOCAL_D RTest test(_L("t_dbbench"));
+LOCAL_D CTrapCleanup* TheTrapCleanup;
+LOCAL_D RDbNamedDatabase TheDatabase;
+LOCAL_D RDbView TheView;
+LOCAL_D RFs TheFs;
+
+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;
+		}
+	}
+
+struct TTest
+	{
+	const TText* iName;
+	const TText* iQuery;
+	};
+const TTest KQuery[]=
+	{
+	{_S("project"),_S("select cluster,xcluster,random,xrandom from test")},
+	{_S("restrict 1"),_S("select * from test where cluster=0")},
+	{_S("restrict 2"),_S("select * from test where xrandom=0")},
+	{_S("restrict 3"),_S("select * from test where xcluster<500 and xrandom <500")},
+	{_S("order 1"),_S("select * from test order by xrandom")},
+	{_S("order 2"),_S("select * from test order by cluster")},
+	{_S("all 1"),_S("select * from test where random<500 order by xrandom")},
+	{_S("all 2"),_S("select * from test where xcluster<500 order by xrandom")},
+	{_S("all 3"),_S("select * from test where xcluster<500 order by xcluster")},
+	{_S("all 4"),_S("select * from test where xcluster<500 and xrandom<200 order by xcluster")}
+	};
+
+/**
+@SYMTestCaseID          SYSLIB-DBMS-CT-0578
+@SYMTestCaseDesc        Benchmark Test.Querying a local Database Test
+@SYMTestPriority        Medium
+@SYMTestActions        	Evaluate SELECT queries on the created database
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+LOCAL_C void Queries()
+	{
+	test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0578 "));
+	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);
+		}
+	}
+
+//
+// Benchmark tests
+//
+LOCAL_C void BenchTestL()
+	{
+	CreateDatabaseL();
+	Queries();
+	CloseDatabase();
+	}
+
+//
+// Prepare the test directory.
+//
+LOCAL_C void setupTestDirectory()
+    {
+	TInt r=TheFs.Connect();
+	test(r==KErrNone);
+//
+#if 0
+	TDriveList drives;
+	TheFs.DriveList(drives);
+	if (drives[EDriveK] == KDriveAbsent)
+		{
+		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);
+		}
+#endif
+//
+	r=TheFs.MkDir(KTestDatabase);
+	test(r==KErrNone || r==KErrAlreadyExists);
+	}
+
+//
+// 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);
+	}
+
+//
+// entry point
+//
+GLDEF_C TInt E32Main()
+    {
+	test.Title();
+	setupTestDirectory();
+	setupCleanup();
+	__UHEAP_MARK;
+//
+	test.Start(_L("Benchmarking..."));
+	TRAPD(r,BenchTestL());
+	test(r==KErrNone);
+	test.End();
+//
+	__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;
+    }