// Copyright (c) 2004-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:
// This is a performance test harness measuring a sync deletion of
// a proportion of Contacts in the default database.
//
//
#include <cntvcard.h>
#include <cntitem.h>
#include <f32file.h>
#include <s32mem.h>
#include "T_PerfSyncDelete.h"
#include "../T_UTILS.H"
// Constants
_LIT(KDbName,"C:Contacts.cdb");
const TPtrC KDbPath((KDbName));
const TInt KCompactResolution = 16;
_LIT(KOutputFormat,"Sync Delete took: %d s %03d deleting %d of %d Contacts\n");
CSyncDelete::CSyncDelete(TInt64 aSeed)
{
iRandSeed = aSeed;
}
CSyncDelete::~CSyncDelete()
{
delete iDb;
iFs.Close();
}
CSyncDelete* CSyncDelete::NewLC(RTest& aTest, TInt64 ranSeed)
{;
CSyncDelete* self = new (ELeave) CSyncDelete(ranSeed);
CleanupStack::PushL(self);
self->ConstructL(aTest);
return(self);
}
void CSyncDelete::ConstructL(RTest& aTest)
{
iTest = &aTest;
iDb = CContactDatabase::OpenL(KDbPath);
User::LeaveIfError(iFs.Connect());
CCntTest::ProfileReset(0, 59);
}
TBool CSyncDelete::ExistsInArray(const CArrayFix<TInt>& aArr, TInt aSize, TInt aNum)
/**
Returns whether aNum exists in aArr from 0 to aSize in the aArr array
*/
{
for(TInt i = 0; i < aSize; ++i)
{
if (aNum == aArr[i])
{
return ETrue;
}
}
return EFalse;
}
void CSyncDelete::CreateRandomIdArray(CArrayFix<TInt>& aUids, TInt aNumIds, TInt aNumEntriesInDb)
/*
Creates a random array of numbers corresponding to the uids in the
Contacts model. No UID is repeated
*/
{
for(TInt i = 0; i < aNumIds; ++i)
{
TInt uid = Math::Rand(iRandSeed)%(aNumEntriesInDb-1)+1;
while(ExistsInArray(aUids,i,uid))
{
uid = Math::Rand(iRandSeed)%(aNumEntriesInDb-1)+1;
}
aUids[i] = uid;
}
}
void CSyncDelete::CleanupPtrArray(TAny* aCArrayPtr)
/**
Static convenience cleanup method copied from CSmlContactsDba
*/
{
CArrayPtr<CContactItem>* array = reinterpret_cast<CArrayPtr<CContactItem>*>(aCArrayPtr);
array->ResetAndDestroy();
delete array;
}
void CSyncDelete::DoSyncL(TInt aEntryCount, TInt aNumEntriesInDb)
/** This routine deleted aEntryCount of aNumEntriesInDb where the Ids to delete are
generated at random. This harness does not tests Sync Update
*/
{
// create an array of random, non-repeating contact ids
CArrayFixFlat<TInt>* uids = new(ELeave) CArrayFixFlat<TInt>(aEntryCount);
CleanupStack::PushL(uids);
uids->ResizeL(aEntryCount);
CreateRandomIdArray(*uids,aEntryCount,aNumEntriesInDb);
// Most SML servers perform all the delete operations followed by all the
// update operations (or vice verca) rather than intermingling the 2
// operations. We are only interested in the deletion aspect at this state.
//
CCntTest::ProfileStart(0);
for (TInt i = 0; i < aEntryCount; ++i)
{ ;
const TContactItemId KEntryId = static_cast<TContactItemId>((*uids)[i]);
iDb->DeleteContactL(KEntryId);
if ((i > 0) && ((i % KCompactResolution) == 0))
{
iDb->CompactL();
}
}
CleanupStack::PopAndDestroy(uids);
CCntTest::ProfileEnd(0);
TCntProfile p[1];
TBuf<64> formattable;
TInt sec;
TInt msec;
CCntTest::ProfileResult(&p[0],0,1);
sec = p[0].iTime/1000000;
msec = (p[0].iTime/1000)%1000;
formattable.Format(KOutputFormat, sec, msec, aEntryCount, aNumEntriesInDb);
iTest->Printf(formattable);
}