// Copyright (c) 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"
// 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: MDS harvesting performance test
//
#include <e32test.h>
#include <e32math.h>
#include <bautils.h>
#include <hal.h>
#include <sqldb.h>
#include "t_sqlcmdlineutil.h"
RTest TheTest(_L("t_sqlperformance5 test"));
RSqlDatabase TheDb;
_LIT(KDbName, "c:\\test\\t_sqlperformance5.db");
TFileName TheDbFileName;
TBuf<200> TheTestTitle;
TCmdLineParams TheCmdLineParams(TCmdLineParams::EDbUtf16, 16384, 32);
TBuf8<200> TheSqlConfigString;
_LIT(KUtf8, "UTF8 ");
_LIT(KUtf16, "UTF16");
const TInt KThumbnailCount = 60;
const TInt KMaxThumbnailSize = 40 * 1024;
const TInt KThumbnailSizes[KThumbnailCount] =
{
//1 2 3 4 5 6 7 8 9 10
22054, 24076, 33281, 24733, 33094, 31443, 29264, 28725, 31798, 29322, //1
25002, 26926, 31097, 21988, 33659, 29081, 33050, 36857, 37686, 24034, //2
21093, 28314, 20186, 27222, 28600, 32735, 27279, 31898, 31380, 36316, //3
34295, 31642, 21829, 32912, 31584, 32557, 36601, 22744, 32808, 26130, //4
31222, 21545, 35899, 22257, 25856, 31169, 34893, 23496, 23034, 30381, //5
25810, 27123, 33442, 22275, 30260, 31028, 32415, 27345, 26614, 33704 //6
};
TInt TheFastCounterFreq = 0;
TInt TheCreateDbTime = 0;
TInt TheCreateTablesTime = 0;
TInt TheBindParamsTime = 0;
TInt TheStmtExecTime = 0;
TInt TheStmtResetTime = 0;
TInt ThePopulateTempTableTime = 0;
TInt TheFlushTime = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////
void TestEnvDestroy()
{
TheDb.Close();
(void)RSqlDatabase::Delete(TheDbFileName);
ResetSoftHeapLimit();
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
//Test macros and functions
void Check1(TInt aValue, TInt aLine)
{
if(!aValue)
{
TestEnvDestroy();
TheTest.Printf(_L("*** Line %d\r\n"), aLine);
TheTest(EFalse, aLine);
}
}
void Check2(TInt aValue, TInt aExpected, TInt aLine)
{
if(aValue != aExpected)
{
TSqlRetCodeClass cl = SqlRetCodeClass(aValue);
if(cl == ESqlDbError)
{
TPtrC errmsg = TheDb.LastErrorMessage();
TheTest.Printf(_L("*** SQLite err=\"%S\"\r\n"), &errmsg);
}
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__)
///////////////////////////////////////////////////////////////////////////////////////
void TestEnvInit()
{
RFs fs;
TInt err = fs.Connect();
TEST2(err, KErrNone);
err = fs.MkDirAll(TheDbFileName);
TEST(err == KErrNone || err == KErrAlreadyExists);
fs.Close();
}
TInt TimeDiffUs(TUint32 aStartTicks, TUint32 aEndTicks)
{
if(TheFastCounterFreq == 0)
{
TEST2(HAL::Get(HAL::EFastCounterFrequency, TheFastCounterFreq), KErrNone);
TheTest.Printf(_L("==Fast counter frequency: %d Hz\r\n"), TheFastCounterFreq);
}
TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
if(diffTicks < 0)
{
diffTicks = KMaxTUint32 + diffTicks + 1;
}
const TInt KMicroSecIn1Sec = 1000000;
TInt us = (diffTicks * KMicroSecIn1Sec) / TheFastCounterFreq;
return us;
}
void PrintTime(const TDesC& aFmt, TUint32 aStartTicks, TUint32 aEndTicks)
{
TInt us = TimeDiffUs(aStartTicks, aEndTicks);
TheTest.Printf(aFmt, us);
}
//=============================================================================
/**
@SYMTestCaseID PDS-SQL-CT-4205
@SYMTestCaseDesc Thumbnail database performance test.
@SYMTestPriority Medium
@SYMTestActions The test executes statements to create the thumbnail database.
@SYMTestExpectedResults The test must not fail
@SYMDEF ou1cimx1#362240
*/
void CreateDb()
{
(void)RSqlDatabase::Delete(TheDbFileName);
TUint32 fc1 = User::FastCounter();
TInt err = TheDb.Create(TheDbFileName, &TheSqlConfigString);
TUint32 fc2 = User::FastCounter();
TheCreateDbTime = TimeDiffUs(fc1, fc2);
TEST2(err, KErrNone);
fc1 = User::FastCounter();
err = TheDb.Exec(_L("CREATE TABLE ThumbnailInfo (Path TEXT COLLATE NOCASE,TNId INTEGER,Size INTEGER,Format INTEGER,TNPath TEXT COLLATE NOCASE,Width INTEGER,Height INTEGER,OrigWidth INTEGER,OrigHeight INTEGER,Flags INTEGER,VideoPosition INTEGER,Orientation INTEGER,humbFromPath INTEGER,Modified LARGEINT);"));
TEST(err >= 0);
err = TheDb.Exec(_L("CREATE TABLE ThumbnailInfoData(Data BLOB);"));
TEST(err >= 0);
err = TheDb.Exec(_L("CREATE TABLE ThumbnailDeleted(Path TEXT UNIQUE COLLATE NOCASE);"));
TEST(err >= 0);
err = TheDb.Exec(_L("CREATE INDEX idx1 ON ThumbnailInfo(Path, Size);"));
TEST(err >= 0);
err = TheDb.Exec(_L("CREATE INDEX idx4 ON ThumbnailDeleted(Path);"));
TEST(err >= 0);
err = TheDb.Exec(_L("CREATE TABLE ThumbnailVersion (Major INTEGER,Minor INTEGER,IMEI TEXT COLLATE NOCASE);"));
TEST(err >= 0);
fc2 = User::FastCounter();
TheCreateTablesTime = TimeDiffUs(fc1, fc2);
TheDb.Close();
}
void PoulateTempTables(RSqlStatement& aStmt1, RSqlStatement& aStmt2)
{
HBufC8* thumbnailBuf = HBufC8::New(KMaxThumbnailSize);
TEST(thumbnailBuf != NULL);
TPtr8 thumbnailData = thumbnailBuf->Des();
thumbnailData.SetLength(KMaxThumbnailSize);
thumbnailData.Fill(TChar('A'));
TUint32 fc3 = User::FastCounter();
for(TInt i=0;i<KThumbnailCount;++i)
{
TUint32 fc1 = User::FastCounter();
TInt paramIndex = aStmt1.ParameterIndex(_L(":Path"));
TEST(paramIndex >= 0);
TInt err = aStmt1.BindText(paramIndex, _L("c:\\test\\abcdefgh123456789.jpg"));
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":Width"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 50);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":Height"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 40);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":OrigWidth"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 1000);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":OrigHeight"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 2000);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":Format"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 10);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":Flags"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 0x1E);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":Size"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 1200);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":Orient"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 2);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":ThumbFromPath"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt(paramIndex, 1);
TEST2(err, KErrNone);
paramIndex = aStmt1.ParameterIndex(_L(":Modified"));
TEST(paramIndex >= 0);
err = aStmt1.BindInt64(paramIndex, 3212398543392LL);
TEST2(err, KErrNone);
TUint32 fc2 = User::FastCounter();
TheBindParamsTime += TimeDiffUs(fc1, fc2);
fc1 = User::FastCounter();
err = aStmt1.Exec();
fc2 = User::FastCounter();
TheStmtExecTime += TimeDiffUs(fc1, fc2);
TEST2(err, 1);
fc1 = User::FastCounter();
err = aStmt1.Reset();
fc2 = User::FastCounter();
TheStmtResetTime += TimeDiffUs(fc1, fc2);
TEST2(err, KErrNone);
thumbnailData.SetLength(KThumbnailSizes[i]);
fc1 = User::FastCounter();
paramIndex = aStmt2.ParameterIndex(_L(":Data"));
TEST(paramIndex >= 0);
err = aStmt2.BindBinary(paramIndex, thumbnailData);
TEST2(err, KErrNone);
fc2 = User::FastCounter();
TheBindParamsTime += TimeDiffUs(fc1, fc2);
fc1 = User::FastCounter();
err = aStmt2.Exec();
fc2 = User::FastCounter();
TheStmtExecTime += TimeDiffUs(fc1, fc2);
TEST2(err, 1);
fc1 = User::FastCounter();
err = aStmt2.Reset();
fc2 = User::FastCounter();
TheStmtResetTime += TimeDiffUs(fc1, fc2);
TEST2(err, KErrNone);
}
TUint32 fc4 = User::FastCounter();
ThePopulateTempTableTime += TimeDiffUs(fc3, fc4);
delete thumbnailBuf;
}
void FlushTemptTables()
{
TUint32 fc1 = User::FastCounter();
TInt err = TheDb.Exec(_L("BEGIN TRANSACTION"));
TEST(err >= 0);
err = TheDb.Exec(_L("INSERT INTO ThumbnailInfo SELECT * FROM TempThumbnailInfo;"));
TEST2(err, KThumbnailCount);
err = TheDb.Exec(_L("INSERT INTO ThumbnailInfoData SELECT * FROM TempThumbnailInfoData;"));
TEST2(err, KThumbnailCount);
err = TheDb.Exec(_L("DELETE FROM TempThumbnailInfo;"));
TEST(err >= 0);
err = TheDb.Exec(_L("DELETE FROM TempThumbnailInfoData;"));
TEST(err >= 0);
err = TheDb.Exec(_L("COMMIT;"));
TEST(err >= 0);
TUint32 fc2 = User::FastCounter();
TheFlushTime += TimeDiffUs(fc1, fc2);
}
/**
@SYMTestCaseID PDS-SQL-CT-4206
@SYMTestCaseDesc Thumbnail database performance test.
@SYMTestPriority Medium
@SYMTestActions The test inserts 60 thumbnails with summary size of 1.7Mb into the thumbnail database.
@SYMTestExpectedResults The test must not fail
@SYMDEF ou1cimx1#362240
*/
void PopulateDb()
{
TInt dataToCommit = 0;
for(TInt i=0;i<KThumbnailCount;++i)
{
dataToCommit += KThumbnailSizes[i];
}
TReal d = dataToCommit / 1024.0;
TheTest.Printf(_L("==dataToCommit=%d bytes (%8.2lf Mb)\r\n"), dataToCommit, d);
TInt err = TheDb.Open(TheDbFileName, &TheSqlConfigString);
TEST2(err, KErrNone);
err = TheDb.Exec(_L("CREATE TEMP TABLE TempThumbnailInfo (Path TEXT COLLATE NOCASE,TNId INTEGER,Size INTEGER,Format INTEGER,TNPath TEXT COLLATE NOCASE,Width INTEGER,Height INTEGER,OrigWidth INTEGER,OrigHeight INTEGER,Flags INTEGER,VideoPosition INTEGER,Orientation INTEGER,ThumbFromPath INTEGER,Modified LARGEINT);"));
TEST(err >= 0);
err = TheDb.Exec(_L("CREATE TEMP TABLE TempThumbnailInfoData (Data BLOB);"));
TEST(err >= 0);
RSqlStatement stmt1;
err = stmt1.Prepare(TheDb, _L("INSERT INTO TempThumbnailInfo(Path,Size,Format,Width,Height,OrigWidth,OrigHeight,Flags,Orientation,ThumbFromPath,Modified) VALUES (:Path,:Size,:Format,:Width,:Height,:OrigWidth,:OrigHeight,:Flags,:Orient,:ThumbFromPath,:Modified);"));
TEST2(err, KErrNone);
RSqlStatement stmt2;
err = stmt2.Prepare(TheDb, _L("INSERT INTO TempThumbnailInfoData (Data) VALUES (:Data);"));
TEST2(err, KErrNone);
PoulateTempTables(stmt1, stmt2);
FlushTemptTables();
stmt2.Close();
stmt1.Close();
TheDb.Close();
TheTest.Printf(_L("==Create database, time=%d microseconds\r\n"), TheCreateDbTime);
TheTest.Printf(_L("==Create tables, time=%d microseconds\r\n"), TheCreateTablesTime);
TheTest.Printf(_L("==Bind parameters time, time=%d microseconds\r\n"), TheBindParamsTime);
TheTest.Printf(_L("==Temp tables, statement exec, time=%d microseconds\r\n"), TheStmtExecTime);
TheTest.Printf(_L("==Temp tables, statement reset, time=%d microseconds\r\n"), TheStmtResetTime);
TheTest.Printf(_L("==Populate temp tables, time=%d microseconds\r\n"), ThePopulateTempTableTime);
TheTest.Printf(_L("==Copy temp tables to main tables, time=%d microseconds\r\n"), TheFlushTime);
}
void DoTestsL()
{
TheTestTitle.Format(_L("@SYMTestCaseID:PDS-SQL-CT-4205 Create database, encoding: \"%S\", page size: %d\r\n"),
TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize);
TheTest.Start(TheTestTitle);
CreateDb();
TheTestTitle.Format(_L("@SYMTestCaseID:PDS-SQL-CT-4206 Populate database, encoding: \"%S\", page size: %d\r\n"),
TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize);
TheTest.Next(TheTestTitle);
PopulateDb();
(void)RSqlDatabase::Delete(TheDbFileName);
}
TInt E32Main()
{
TheTest.Title();
CTrapCleanup* tc = CTrapCleanup::New();
TheTest(tc != NULL);
__UHEAP_MARK;
GetCmdLineParamsAndSqlConfigString(TheTest, _L("t_sqlperformance5"), TheCmdLineParams, TheSqlConfigString);
PrepareDbName(KDbName, TheCmdLineParams.iDriveName, TheDbFileName);
SetSoftHeapLimit(TheCmdLineParams.iSoftHeapLimitKb);
TheTest.Printf(_L("==Databases: %S\r\n"), &TheDbFileName);
TestEnvDestroy();
TestEnvInit();
TRAPD(err, DoTestsL());
TestEnvDestroy();
TEST2(err, KErrNone);
__UHEAP_MARKEND;
TheTest.End();
TheTest.Close();
delete tc;
User::Heap().Check();
return KErrNone;
}