|
1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <e32std.h> |
|
17 #include <e32test.h> |
|
18 #include <e32math.h> |
|
19 #include <cntdb.h> |
|
20 #include <cntitem.h> |
|
21 #include <cntfldst.h> |
|
22 #include "t_utils2.h" |
|
23 #include "t_bench.h" |
|
24 #include "T_UTILS.H" |
|
25 |
|
26 |
|
27 // |
|
28 // Configuration. |
|
29 // |
|
30 |
|
31 #define __TxEST |
|
32 #define __VxERBOSE |
|
33 |
|
34 |
|
35 // |
|
36 // Constants. |
|
37 // |
|
38 |
|
39 _LIT(KTestName,"t_bench"); |
|
40 |
|
41 |
|
42 _LIT(KDbFileName,"c:contacts.cdb"); |
|
43 |
|
44 _LIT(KLogFileName,"t_bench.log"); |
|
45 _LIT(KBackSpace,"\x08"); |
|
46 _LIT(KVisualCounterFormat,"%S%d"); |
|
47 _LIT(KTimeProfileFormat,"Time taken (secs)"); |
|
48 _LIT(KSystemMemoryFormat,"System memory used (Kb)"); |
|
49 _LIT(KThreadMemoryFormat,"This thread memory used (Kb)"); |
|
50 _LIT(KFileSizeText,"File size (bytes)"); |
|
51 _LIT(KAverageTimeText,"Average time taken (secs)"); |
|
52 _LIT(KResultFormatTInt,"Result #%d.%d %S [%d]"); |
|
53 _LIT(KResultFormatTReal,"Result #%d.%d %S [%f]"); |
|
54 _LIT(KThreadNameFormat,"T_BenchCli%2d"); |
|
55 _LIT(KPhoneMatchFail,"6666666666666666"); |
|
56 _LIT(KNameMatchFail,"xxxxxxxxxxxxxxxx"); |
|
57 _LIT(KAsyncFindMatch,"a"); |
|
58 _LIT(KNewLine,"\n"); |
|
59 _LIT(KTextDefSeparator,"\t"); |
|
60 |
|
61 #ifdef __VERBOSE |
|
62 _LIT(KContactSummaryFormat,"%d\t%S\t%S\t%S"); |
|
63 _LIT(KAscendingSortOrder,"ascending"); |
|
64 _LIT(KDescendingSortOrder,"descending"); |
|
65 _LIT(KProfileResult,"Took %d\tmicrosecs for %d iteration(s)"); |
|
66 #endif |
|
67 |
|
68 const TInt KNumSortClients=10; |
|
69 const TInt KClientStackSize=KDefaultStackSize; |
|
70 const TInt KClientHeapSize=0x20000; |
|
71 |
|
72 #ifdef __TEST |
|
73 const TInt KNumTypicalContacts=10; |
|
74 const TInt KNumAtypicalContacts=2; |
|
75 const TInt KNumTypicalContactsCompact=0; |
|
76 const TInt KNumAtypicalContactsCompact=0; |
|
77 #else |
|
78 const TInt KNumTypicalContacts=100; |
|
79 const TInt KNumAtypicalContacts=50; |
|
80 const TInt KNumTypicalContactsCompact=150; |
|
81 const TInt KNumAtypicalContactsCompact=50; |
|
82 #endif // __TEST |
|
83 |
|
84 |
|
85 // |
|
86 // CBenchMarker. |
|
87 // |
|
88 |
|
89 CBenchMarker::CBenchMarker() : iTest(KTestName),iVisualCounter(-1),iNumTypicalContacts(-1),iNumAtypicalContacts(-1),iNumTypicalContactsCompact(-1),iNumAtypicalContactsCompact(-1) |
|
90 { |
|
91 } |
|
92 |
|
93 CBenchMarker::~CBenchMarker() |
|
94 { |
|
95 delete iGenerator; |
|
96 delete iDb; |
|
97 delete iTextDef; |
|
98 delete iLog; |
|
99 iTest.Close(); |
|
100 iFs.Close(); |
|
101 } |
|
102 |
|
103 void CBenchMarker::ConstructL(const TDesC& aCommandLine) |
|
104 { |
|
105 User::LeaveIfError(iFs.Connect()); |
|
106 DecodeCommandLineL(aCommandLine); |
|
107 iLog=CLog::NewL(iTest,iLogFileName); |
|
108 iGenerator=CRandomContactGenerator::NewL(); |
|
109 } |
|
110 |
|
111 void CBenchMarker::DecodeCommandLineL(const TDesC& aCommandLine) |
|
112 { |
|
113 _LIT(KArgContactsToAdd,"-a"); |
|
114 _LIT(KArgContactsToCompact,"-c"); |
|
115 _LIT(KArgDatabaseFileName,"-d"); |
|
116 _LIT(KArgNoDataGenerationTests,"-g"); |
|
117 _LIT(KArgLogFile,"-l"); |
|
118 _LIT(KArgHelp,"-h"); |
|
119 |
|
120 TLex cl(aCommandLine); |
|
121 while (cl.Remainder().Length()>0) |
|
122 { |
|
123 TPtrC token=cl.NextToken(); |
|
124 |
|
125 if (token.CompareF(KArgContactsToAdd)==0) |
|
126 { |
|
127 cl.SkipSpace(); |
|
128 User::LeaveIfError(cl.Val(iNumTypicalContacts)); |
|
129 cl.SkipSpace(); |
|
130 User::LeaveIfError(cl.Val(iNumAtypicalContacts)); |
|
131 } |
|
132 else if (token.CompareF(KArgContactsToCompact)==0) |
|
133 { |
|
134 cl.SkipSpace(); |
|
135 User::LeaveIfError(cl.Val(iNumTypicalContactsCompact)); |
|
136 cl.SkipSpace(); |
|
137 User::LeaveIfError(cl.Val(iNumAtypicalContactsCompact)); |
|
138 } |
|
139 else if (token.CompareF(KArgDatabaseFileName)==0) |
|
140 { |
|
141 iDbFileName=cl.NextToken(); |
|
142 } |
|
143 else if (token.CompareF(KArgNoDataGenerationTests)==0) |
|
144 { |
|
145 iNoDataGenerationTests=ETrue; |
|
146 } |
|
147 else if (token.CompareF(KArgLogFile)==0) |
|
148 { |
|
149 iLogFileName=cl.NextToken(); |
|
150 } |
|
151 else if (token.CompareF(KArgHelp)==0) |
|
152 { |
|
153 iTest.Printf(_L("Usage t_bench [options]\n\n")); |
|
154 iTest.Printf(_L("-a <num_typical> <num_atypical> (default: %d %d)\n"),KNumTypicalContacts,KNumAtypicalContacts); |
|
155 iTest.Printf(_L("-c <num_typical_comp> <num_atypical_comp> (default: %d %d)\n"),KNumTypicalContactsCompact,KNumAtypicalContactsCompact); |
|
156 iTest.Printf(_L("-d <db_name> (default: %S)\n"),&KDbFileName); |
|
157 iTest.Printf(_L("-l <log_name> (default: %S)\n"),&KLogFileName); |
|
158 iTest.Printf(_L("-g skip data generation tests\n")); |
|
159 iTest.Printf(_L("\n<hit any key>")); |
|
160 iTest.Getch(); |
|
161 User::Leave(KErrNone); |
|
162 } |
|
163 } |
|
164 |
|
165 if (iDbFileName.Length()==0) |
|
166 { |
|
167 iDbFileName=KDbFileName; |
|
168 } |
|
169 |
|
170 if (iLogFileName.Length()==0) |
|
171 { |
|
172 iLogFileName=KLogFileName; |
|
173 } |
|
174 |
|
175 if (iNoDataGenerationTests) |
|
176 { |
|
177 TUint att; |
|
178 if (iFs.Att(iDbFileName,att)==KErrNotFound) |
|
179 { |
|
180 iTest.Printf(_L("-g switch ignored, because %S not found\n"),&iDbFileName); |
|
181 iNoDataGenerationTests=EFalse; |
|
182 } |
|
183 } |
|
184 |
|
185 if (iNumTypicalContacts<0) |
|
186 { |
|
187 iNumTypicalContacts=KNumTypicalContacts; |
|
188 } |
|
189 |
|
190 if (iNumAtypicalContacts<0) |
|
191 { |
|
192 iNumAtypicalContacts=KNumAtypicalContacts; |
|
193 } |
|
194 |
|
195 if (iNumTypicalContactsCompact<0) |
|
196 { |
|
197 iNumTypicalContactsCompact=KNumTypicalContactsCompact; |
|
198 } |
|
199 |
|
200 if (iNumAtypicalContactsCompact<0) |
|
201 { |
|
202 iNumAtypicalContactsCompact=KNumAtypicalContactsCompact; |
|
203 } |
|
204 } |
|
205 |
|
206 void CBenchMarker::RunL() |
|
207 { |
|
208 iTest.Printf(_L("Starting CntModel benchmarks...\n")); // This forces the console to get loaded under WINS - would otherwise scew profiles. |
|
209 |
|
210 for (TInt i=0;i<ENumTests;++i) |
|
211 { |
|
212 StartProfile(); |
|
213 TInt timeMinorNumber=0; |
|
214 TRAPD(err,timeMinorNumber=DoTestL(TTest(i))); |
|
215 if (err) |
|
216 { |
|
217 iLog->LogLine(_L("Test %d left with %d"),i,err); |
|
218 break; |
|
219 } |
|
220 |
|
221 LogResult(i,timeMinorNumber,KTimeProfileFormat,EndProfile()); |
|
222 |
|
223 User::CompressAllHeaps(); |
|
224 TMemoryInfoV1Buf memoryBuf; |
|
225 UserHal::MemoryInfo(memoryBuf); |
|
226 TMemoryInfoV1 memory(memoryBuf()); |
|
227 const TInt totalK=memory.iTotalRamInBytes>>10; |
|
228 const TInt freeK=memory.iFreeRamInBytes>>10; |
|
229 const TInt usedK=totalK-freeK; |
|
230 LogResult(i,timeMinorNumber+1,KSystemMemoryFormat,usedK); |
|
231 |
|
232 TInt allocSize; |
|
233 User::Heap().AllocSize(allocSize);; |
|
234 allocSize>>=10; |
|
235 LogResult(i,timeMinorNumber+2,KThreadMemoryFormat,allocSize); |
|
236 } |
|
237 |
|
238 iTest.Printf(_L("Dump log to comm port? (y/n) ")); |
|
239 TKeyCode key=iTest.Getch(); |
|
240 if (key=='y' || key=='Y') |
|
241 { |
|
242 writelog: |
|
243 iLog->WriteLogToCommPortL(); |
|
244 } |
|
245 iTest.Printf(_L("\nAgain? (y/n)")); |
|
246 key=iTest.Getch(); |
|
247 if (key=='y' || key=='Y') |
|
248 { |
|
249 goto writelog; |
|
250 } |
|
251 } |
|
252 |
|
253 TInt CBenchMarker::DoTestL(TTest aTest) |
|
254 { |
|
255 TInt timeMinorNumber=0; |
|
256 iLog->Log(_L("Test #%d "),aTest); |
|
257 TPtrC match; |
|
258 |
|
259 switch (aTest) |
|
260 { |
|
261 case EOpenNewDb: |
|
262 iLog->LogLine(_L("Open new database")); |
|
263 if (iNoDataGenerationTests) |
|
264 { |
|
265 iDb=CContactDatabase::OpenL(iDbFileName); |
|
266 } |
|
267 else |
|
268 { |
|
269 iDb=CContactDatabase::ReplaceL(iDbFileName); |
|
270 LogResult(aTest,0,KFileSizeText,DbFileSize()); |
|
271 timeMinorNumber=1; |
|
272 } |
|
273 iGenerator->SetDbL(*iDb); |
|
274 break; |
|
275 case ECreateSecondaryClients: |
|
276 iLog->LogLine(_L("Create %d secondary client threads"),KNumSecondaryClients); |
|
277 CreateSecondaryClients(); |
|
278 break; |
|
279 case EAddContacts: |
|
280 iLog->LogLine(_L("Add %d typical and %d atypical contacts"),iNumTypicalContacts,iNumAtypicalContacts); |
|
281 if (!iNoDataGenerationTests) |
|
282 { |
|
283 LogResult(aTest,0,KAverageTimeText,AddContactsL()); |
|
284 LogResult(aTest,1,KFileSizeText,DbFileSize()); |
|
285 timeMinorNumber=2; |
|
286 } |
|
287 break; |
|
288 case ECompactDb: |
|
289 iLog->LogLine(_L("Compact database")); |
|
290 if (!iNoDataGenerationTests) |
|
291 { |
|
292 iDb->CompactL(); |
|
293 LogResult(aTest,0,KFileSizeText,DbFileSize()); |
|
294 timeMinorNumber=1; |
|
295 } |
|
296 break; |
|
297 case EAddAndCompact: |
|
298 iLog->LogLine(_L("Add %d typical and %d atypical contacts (compact after each)"),iNumTypicalContactsCompact,iNumAtypicalContactsCompact); |
|
299 if (!iNoDataGenerationTests) |
|
300 { |
|
301 LogResult(aTest,0,KAverageTimeText,AddContactsCompactL()); |
|
302 LogResult(aTest,1,KFileSizeText,DbFileSize()); |
|
303 timeMinorNumber=2; |
|
304 } |
|
305 break; |
|
306 case EGetSortedItems: |
|
307 iLog->LogLine(_L("Get sorted id array by firstname, lastname, company name")); |
|
308 DoSortL(); |
|
309 break; |
|
310 case ELogContactSummary: |
|
311 iLog->LogLine(_L("Log contact summary")); |
|
312 LogContactSummaryL(EFalse); |
|
313 break; |
|
314 case ELogContactSummaryFast: |
|
315 iLog->LogLine(_L("Log contact summary using TContactTextDefItem")); |
|
316 LogContactSummaryL(ETrue); |
|
317 break; |
|
318 case EOpenRContactView: |
|
319 iLog->LogLine(_L("Open RContactView")); |
|
320 OpenRContactViewL(); |
|
321 break; |
|
322 case ESetSortOrderOfRContactView: |
|
323 iLog->LogLine(_L("Set order of RContactView")); |
|
324 SetSortOrderOfRContactViewL(); |
|
325 break; |
|
326 case EGetSortOrderOfRContactView: |
|
327 iLog->LogLine(_L("Get order of RContactView")); |
|
328 GetSortOrderOfRContactViewL(); |
|
329 break; |
|
330 case ELogContactSummaryWithRContactView: |
|
331 iLog->LogLine(_L("Log contact summary using RContactView")); |
|
332 LogContactSummaryFromRContactViewL(EFalse); |
|
333 break; |
|
334 case ELogContactSummaryFastWithRContactView: |
|
335 iLog->LogLine(_L("Log contact summary using RContactView and TContactTextDefItem")); |
|
336 LogContactSummaryFromRContactViewL(ETrue); |
|
337 break; |
|
338 case EFindWithRContactView: |
|
339 iLog->LogLine(_L("Find TContactItemId from RContactView")); |
|
340 FindInRContactViewL(); |
|
341 break; |
|
342 case ECloseRContactView: |
|
343 iLog->LogLine(_L("Close RContactView")); |
|
344 #ifdef __USE_NEW_INTERFACES |
|
345 iSortedIdList.Close(); |
|
346 #endif |
|
347 break; |
|
348 case EFindFromLargeFieldSetSuceed: |
|
349 match.Set(iGenerator->NameMatch()); |
|
350 iLog->LogLine(_L("FindLC %S using large field set (will suceed)"),&match); |
|
351 FindFromLargeFieldSetL(match); |
|
352 break; |
|
353 case EFindFromLargeFieldSetFail: |
|
354 iLog->LogLine(_L("FindLC %S using large field set (will fail)"),&KNameMatchFail); |
|
355 FindFromLargeFieldSetL(KNameMatchFail); |
|
356 break; |
|
357 case EFindFromSmallFieldSetSuceed: |
|
358 match.Set(iGenerator->NameMatch()); |
|
359 iLog->LogLine(_L("FindLC %S using small field set (will suceed)"),&match); |
|
360 FindFromSmallFieldSetL(match); |
|
361 break; |
|
362 case EFindFromSmallFieldSetFail: |
|
363 iLog->LogLine(_L("FindLC %S using small field set (will fail)"),&KNameMatchFail); |
|
364 FindFromSmallFieldSetL(KNameMatchFail); |
|
365 break; |
|
366 case EFindPhoneNumberSuceed: |
|
367 match.Set(iGenerator->PhoneMatch()); |
|
368 iLog->LogLine(_L("FindLC %S using just phone field (will suceed)"),&match); |
|
369 FindPhoneNumberL(match); |
|
370 break; |
|
371 case EFindPhoneNumberFail: |
|
372 iLog->LogLine(_L("FindLC %S using just phone field (will fail)"),&KPhoneMatchFail); |
|
373 FindPhoneNumberL(KPhoneMatchFail); |
|
374 break; |
|
375 case EFindEmailAddressSuceed: |
|
376 match.Set(iGenerator->EmailMatch()); |
|
377 iLog->LogLine(_L("FindLC %S using just email field (will suceed)"),&match); |
|
378 FindEmailAddressL(match); |
|
379 break; |
|
380 case EFindEmailAddressFail: |
|
381 iLog->LogLine(_L("FindLC %S using just email field (will fail)"),&KNameMatchFail); |
|
382 FindEmailAddressL(KNameMatchFail); |
|
383 break; |
|
384 case EFindAsyncFromLargeFieldSet: |
|
385 iLog->LogLine(_L("FindAsyncL %S using large field set"),&KAsyncFindMatch); |
|
386 FindAsyncFromLargeFieldSetL(KAsyncFindMatch); |
|
387 break; |
|
388 case EFindAsyncFromSmallFieldSet: |
|
389 iLog->LogLine(_L("FindAsyncL %S using small field set"),&KAsyncFindMatch); |
|
390 FindAsyncFromSmallFieldSetL(KAsyncFindMatch); |
|
391 break; |
|
392 case ECloseDb: |
|
393 iLog->LogLine(_L("Close database")); |
|
394 delete iDb; |
|
395 iDb=NULL; |
|
396 break; |
|
397 case ECloseSecondaryClients: |
|
398 iLog->LogLine(_L("Close secondary clients")); |
|
399 CloseSecondaryClients(); |
|
400 break; |
|
401 case EOpenExistingDb: |
|
402 iLog->LogLine(_L("Open existing database")); |
|
403 iDb=CContactDatabase::OpenL(iDbFileName); |
|
404 break; |
|
405 case EMultiClientSort: |
|
406 iLog->LogLine(_L("%d client simultaneous sort"),KNumSortClients); |
|
407 CreateSortClients(); |
|
408 break; |
|
409 case ENumTests: |
|
410 ASSERT(EFalse); |
|
411 break; |
|
412 } |
|
413 |
|
414 return timeMinorNumber; |
|
415 } |
|
416 |
|
417 void CBenchMarker::StartProfile() |
|
418 { |
|
419 CCntTest::ProfileReset(0,1); // reset profiles 0-1 |
|
420 CCntTest::ProfileStart(0); |
|
421 } |
|
422 |
|
423 TReal CBenchMarker::EndProfile() |
|
424 { |
|
425 CCntTest::ProfileEnd(0); |
|
426 TCntProfile profile[1]; |
|
427 CCntTest::ProfileResult(profile,0,1); |
|
428 return TReal(profile[0].iTime/1000000.0); |
|
429 } |
|
430 |
|
431 void CBenchMarker::StartAverageProfile() |
|
432 { |
|
433 iAverageProfileCounter=0; |
|
434 iNumAverageProfiles=0; |
|
435 CCntTest::ProfileReset(1,1); |
|
436 CCntTest::ProfileStart(1); |
|
437 } |
|
438 |
|
439 void CBenchMarker::UpdateAverageProfile(TInt aNumIterations) |
|
440 { |
|
441 CCntTest::ProfileEnd(1); |
|
442 TCntProfile profile[1]; |
|
443 CCntTest::ProfileResult(profile,1,1); |
|
444 iAverageProfileCounter+=profile[0].iTime; |
|
445 iNumAverageProfiles+=aNumIterations; |
|
446 CCntTest::ProfileReset(1,1); |
|
447 CCntTest::ProfileStart(1); |
|
448 #ifdef __VERBOSE |
|
449 iLog->LogLineNoEcho(KProfileResult,profile[0].iTime,aNumIterations); |
|
450 #endif |
|
451 } |
|
452 |
|
453 TReal CBenchMarker::EndAverageProfile() |
|
454 { |
|
455 CCntTest::ProfileEnd(1); |
|
456 if (iNumAverageProfiles>0) |
|
457 { |
|
458 return TReal((iAverageProfileCounter/iNumAverageProfiles)/1000000.0); |
|
459 } |
|
460 |
|
461 return TReal(0.0); |
|
462 } |
|
463 |
|
464 TReal CBenchMarker::AddContactsL() |
|
465 { |
|
466 iTest.Printf(_L("Adding ")); |
|
467 StartAverageProfile(); |
|
468 |
|
469 TInt ii; |
|
470 for (ii=0;ii<iNumTypicalContacts;++ii) |
|
471 { |
|
472 IncVisualCounter(); |
|
473 iGenerator->AddTypicalRandomContactL(); |
|
474 UpdateAverageProfile(1); |
|
475 } |
|
476 |
|
477 for (ii=0;ii<iNumAtypicalContacts;++ii) |
|
478 { |
|
479 IncVisualCounter(); |
|
480 iGenerator->AddAtypicalRandomContactL(); |
|
481 UpdateAverageProfile(1); |
|
482 } |
|
483 |
|
484 EndVisualCounter(); |
|
485 return EndAverageProfile(); |
|
486 } |
|
487 |
|
488 TReal CBenchMarker::AddContactsCompactL() |
|
489 { |
|
490 iTest.Printf(_L("Adding ")); |
|
491 StartAverageProfile(); |
|
492 |
|
493 TInt ii; |
|
494 for (ii=0;ii<iNumTypicalContactsCompact;++ii) |
|
495 { |
|
496 IncVisualCounter(); |
|
497 iGenerator->AddTypicalRandomContactL(); |
|
498 iDb->CompactL(); |
|
499 UpdateAverageProfile(1); |
|
500 } |
|
501 |
|
502 for (ii=0;ii<iNumAtypicalContactsCompact;++ii) |
|
503 { |
|
504 IncVisualCounter(); |
|
505 iGenerator->AddAtypicalRandomContactL(); |
|
506 iDb->CompactL(); |
|
507 UpdateAverageProfile(1); |
|
508 } |
|
509 |
|
510 EndVisualCounter(); |
|
511 return EndAverageProfile(); |
|
512 } |
|
513 |
|
514 #ifdef __USE_NEW_INTERFACES |
|
515 void CBenchMarker::LogContactSummaryFromRContactViewL(TBool aFaster) |
|
516 { |
|
517 iTest.Printf(_L("Logging ")); |
|
518 const TInt numContacts(iSortedIdList.Count()); |
|
519 for (TInt ii=0;ii<numContacts;++ii) |
|
520 { |
|
521 IncVisualCounter(); |
|
522 LogContactSummaryL(aFaster,iSortedIdList.GetL(ii)); |
|
523 } |
|
524 EndVisualCounter(); |
|
525 } |
|
526 #else |
|
527 void CBenchMarker::LogContactSummaryFromRContactViewL(TBool) |
|
528 { |
|
529 } |
|
530 #endif |
|
531 |
|
532 void CBenchMarker::OpenRContactViewL() |
|
533 { |
|
534 #ifdef __USE_NEW_INTERFACES |
|
535 User::LeaveIfError(iSortedIdList.Open(*iDb)); |
|
536 #endif |
|
537 } |
|
538 |
|
539 void CBenchMarker::SetSortOrderOfRContactViewL() |
|
540 { |
|
541 #ifdef __USE_NEW_INTERFACES |
|
542 CArrayFix<CContactDatabase::TSortPref>* sortOrder=new(ELeave)CArrayFixFlat<CContactDatabase::TSortPref>(2); |
|
543 CleanupStack::PushL(sortOrder); |
|
544 sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldGivenName)); |
|
545 sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldFamilyName)); |
|
546 sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldCompanyName)); |
|
547 iSortedIdList.ChangeSortOrderL(*sortOrder); |
|
548 CleanupStack::PopAndDestroy(); // sortOrder |
|
549 #endif |
|
550 } |
|
551 |
|
552 void CBenchMarker::GetSortOrderOfRContactViewL() |
|
553 { |
|
554 #ifdef __USE_NEW_INTERFACES |
|
555 const CArrayFix<CContactDatabase::TSortPref>& sortOrder=iSortedIdList.SortOrderLC(); |
|
556 #ifdef __VERBOSE |
|
557 const TInt numSortPrefs=sortOrder.Count(); |
|
558 for (TInt ii=0;ii<numSortPrefs;++ii) |
|
559 { |
|
560 iLog->LogLineNoEcho(_L("Sort pref %d field type: %x order: %S"),ii,sortOrder[ii].iFieldType,(sortOrder[ii].iOrder==CContactDatabase::TSortPref::EAsc) ? &KAscendingSortOrder : &KDescendingSortOrder); |
|
561 } |
|
562 #else |
|
563 sortOrder.Count(); |
|
564 #endif |
|
565 CleanupStack::PopAndDestroy(); // sortOrder |
|
566 #endif |
|
567 } |
|
568 |
|
569 void CBenchMarker::FindInRContactViewL() |
|
570 { |
|
571 #ifdef __USE_NEW_INTERFACES |
|
572 const TContactItemId id=iSortedIdList.GetL(iSortedIdList.Count()-1); |
|
573 const TInt index=iSortedIdList.Find(id); |
|
574 ASSERT(index==iSortedIdList.Count()-1); |
|
575 iLog->LogLine(_L("Found TContactItemId %d for index %d"),id,index); |
|
576 #endif |
|
577 } |
|
578 |
|
579 void CBenchMarker::LogContactSummaryL(TBool aFaster) |
|
580 { |
|
581 iTest.Printf(_L("Logging ")); |
|
582 const TInt numContacts(iSortedItems->Count()); |
|
583 for (TInt ii=0;ii<numContacts;++ii) |
|
584 { |
|
585 IncVisualCounter(); |
|
586 LogContactSummaryL(aFaster,(*iSortedItems)[ii]); |
|
587 } |
|
588 EndVisualCounter(); |
|
589 } |
|
590 |
|
591 void CBenchMarker::LogContactSummaryL(TBool aFaster,TContactItemId aContactItemId) |
|
592 { |
|
593 if (aFaster) |
|
594 { |
|
595 if (iTextDef==NULL) |
|
596 { |
|
597 iTextDef=CContactTextDef::NewL(); |
|
598 iTextDef->AppendL(TContactTextDefItem(KUidContactFieldGivenName,KTextDefSeparator)); |
|
599 iTextDef->AppendL(TContactTextDefItem(KUidContactFieldFamilyName,KTextDefSeparator)); |
|
600 iTextDef->AppendL(TContactTextDefItem(KUidContactFieldCompanyName,KTextDefSeparator)); |
|
601 } |
|
602 |
|
603 TBuf<128> buf; |
|
604 iDb->ReadContactTextDefL(aContactItemId,buf,iTextDef); |
|
605 #ifdef __VERBOSE |
|
606 iLog->LogLineNoEcho(buf); |
|
607 #endif |
|
608 } |
|
609 else |
|
610 { |
|
611 CContactItem* thisContactItem=iDb->ReadContactLC(aContactItemId); |
|
612 CTestContact* thisContact=CTestContact::NewLC(*thisContactItem); |
|
613 |
|
614 #ifdef __VERBOSE |
|
615 const TPtrC firstName(thisContact->FirstNameL()); |
|
616 const TPtrC lastName(thisContact->LastNameL()); |
|
617 const TPtrC companyName(thisContact->CompanyNameL()); |
|
618 iLog->LogLineNoEcho(KContactSummaryFormat,thisContactItem->Id(),&firstName,&lastName,&companyName); |
|
619 #else |
|
620 thisContact->FirstNameL(); |
|
621 thisContact->LastNameL(); |
|
622 thisContact->CompanyNameL(); |
|
623 #endif |
|
624 CleanupStack::PopAndDestroy(2); // thisContact, thisContactItem. |
|
625 } |
|
626 } |
|
627 |
|
628 |
|
629 void CBenchMarker::DoSortL() |
|
630 { |
|
631 CContactTextDef* textDef=CContactTextDef::NewLC(); |
|
632 textDef->AppendL(TContactTextDefItem(KUidContactFieldGivenName)); |
|
633 textDef->AppendL(TContactTextDefItem(KUidContactFieldFamilyName)); |
|
634 textDef->AppendL(TContactTextDefItem(KUidContactFieldCompanyName)); |
|
635 iDb->SetTextDefinitionL(textDef); // Takes ownership. |
|
636 CleanupStack::Pop(); // textDef. |
|
637 CArrayFix<CContactDatabase::TSortPref>* sortOrder=new(ELeave)CArrayFixFlat<CContactDatabase::TSortPref>(2); |
|
638 CleanupStack::PushL(sortOrder); |
|
639 sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldDefinedText)); |
|
640 iDb->SortL(sortOrder); // Takes ownership. |
|
641 CleanupStack::Pop(); // sortOrder |
|
642 iSortedItems=iDb->SortedItemsL(); |
|
643 } |
|
644 |
|
645 void CBenchMarker::FindFromLargeFieldSetL(const TDesC& aTextToFind) |
|
646 { |
|
647 CContactItemFieldDef* def=new(ELeave) CContactItemFieldDef(); |
|
648 CleanupStack::PushL(def); |
|
649 def->AppendL(KUidContactFieldGivenName); |
|
650 def->AppendL(KUidContactFieldFamilyName); |
|
651 def->AppendL(KUidContactFieldCompanyName); |
|
652 def->AppendL(KUidContactFieldPhoneNumber); |
|
653 def->AppendL(KUidContactFieldFax); |
|
654 def->AppendL(KUidContactFieldEMail); |
|
655 def->AppendL(KUidContactFieldUrl); |
|
656 def->AppendL(KUidContactFieldAddress); |
|
657 def->AppendL(KUidContactFieldLocality); |
|
658 def->AppendL(KUidContactFieldRegion); |
|
659 def->AppendL(KUidContactFieldPostcode); |
|
660 def->AppendL(KUidContactFieldCountry); |
|
661 def->AppendL(KUidContactFieldNote); |
|
662 DoFindL(aTextToFind,*def); |
|
663 CleanupStack::PopAndDestroy(); // def. |
|
664 } |
|
665 |
|
666 void CBenchMarker::FindFromSmallFieldSetL(const TDesC& aTextToFind) |
|
667 { |
|
668 CContactItemFieldDef* def=new(ELeave) CContactItemFieldDef(); |
|
669 CleanupStack::PushL(def); |
|
670 def->AppendL(KUidContactFieldGivenName); |
|
671 def->AppendL(KUidContactFieldFamilyName); |
|
672 def->AppendL(KUidContactFieldCompanyName); |
|
673 DoFindL(aTextToFind,*def); |
|
674 CleanupStack::PopAndDestroy(); // def. |
|
675 } |
|
676 |
|
677 void CBenchMarker::FindPhoneNumberL(const TDesC& aTextToFind) |
|
678 { |
|
679 CContactItemFieldDef* def=new(ELeave) CContactItemFieldDef(); |
|
680 CleanupStack::PushL(def); |
|
681 def->AppendL(KUidContactFieldPhoneNumber); |
|
682 DoFindL(aTextToFind,*def); |
|
683 CleanupStack::PopAndDestroy(); // def. |
|
684 } |
|
685 |
|
686 void CBenchMarker::FindEmailAddressL(const TDesC& aTextToFind) |
|
687 { |
|
688 CContactItemFieldDef* def=new(ELeave) CContactItemFieldDef(); |
|
689 CleanupStack::PushL(def); |
|
690 def->AppendL(KUidContactFieldEMail); |
|
691 DoFindL(aTextToFind,*def); |
|
692 CleanupStack::PopAndDestroy(); // def. |
|
693 } |
|
694 |
|
695 TReal CBenchMarker::FindAsyncFromLargeFieldSetL(const TDesC& aTextToFind) |
|
696 { |
|
697 CContactItemFieldDef* def=new(ELeave) CContactItemFieldDef(); |
|
698 CleanupStack::PushL(def); |
|
699 def->AppendL(KUidContactFieldGivenName); |
|
700 def->AppendL(KUidContactFieldFamilyName); |
|
701 def->AppendL(KUidContactFieldCompanyName); |
|
702 def->AppendL(KUidContactFieldPhoneNumber); |
|
703 def->AppendL(KUidContactFieldFax); |
|
704 def->AppendL(KUidContactFieldEMail); |
|
705 def->AppendL(KUidContactFieldUrl); |
|
706 def->AppendL(KUidContactFieldAddress); |
|
707 def->AppendL(KUidContactFieldLocality); |
|
708 def->AppendL(KUidContactFieldRegion); |
|
709 def->AppendL(KUidContactFieldPostcode); |
|
710 def->AppendL(KUidContactFieldCountry); |
|
711 def->AppendL(KUidContactFieldNote); |
|
712 TReal averageTime=DoFindAsyncL(aTextToFind,*def); |
|
713 CleanupStack::PopAndDestroy(); // def. |
|
714 return averageTime; |
|
715 } |
|
716 |
|
717 TReal CBenchMarker::FindAsyncFromSmallFieldSetL(const TDesC& aTextToFind) |
|
718 { |
|
719 CContactItemFieldDef* def=new(ELeave) CContactItemFieldDef(); |
|
720 CleanupStack::PushL(def); |
|
721 def->AppendL(KUidContactFieldGivenName); |
|
722 def->AppendL(KUidContactFieldFamilyName); |
|
723 def->AppendL(KUidContactFieldCompanyName); |
|
724 TReal averageTime=DoFindAsyncL(aTextToFind,*def); |
|
725 CleanupStack::PopAndDestroy(); // def. |
|
726 return averageTime; |
|
727 } |
|
728 |
|
729 void CBenchMarker::DoFindL(const TDesC& aTextToFind,const CContactItemFieldDef& aFieldDef) |
|
730 { |
|
731 CContactIdArray* matchList=iDb->FindLC(aTextToFind,&aFieldDef); |
|
732 |
|
733 #ifdef __VERBOSE |
|
734 const TInt numIds=matchList->Count(); |
|
735 iLog->LogLine(_L("Matched %d contact(s)"),numIds); |
|
736 for (TInt ii=0;ii<numIds;++ii) |
|
737 { |
|
738 LogContactSummaryL(ETrue,(*matchList)[ii]); |
|
739 } |
|
740 #else |
|
741 matchList->Count(); |
|
742 #endif |
|
743 |
|
744 CleanupStack::PopAndDestroy(); // matchList. |
|
745 } |
|
746 |
|
747 TReal CBenchMarker::DoFindAsyncL(const TDesC& aTextToFind,const CContactItemFieldDef& aFieldDef) |
|
748 { |
|
749 iTest.Printf(_L("Found ")); |
|
750 StartAverageProfile(); |
|
751 iIdleFinder=iDb->FindAsyncL(aTextToFind,&aFieldDef,this); |
|
752 CleanupStack::PushL(iIdleFinder); // Handle on cleanup stack because object is very temporary. |
|
753 CActiveScheduler::Start(); |
|
754 |
|
755 EndVisualCounter(); |
|
756 #ifdef __VERBOSE |
|
757 CContactIdArray* matchList=iIdleFinder->TakeContactIds(); |
|
758 CleanupStack::PushL(matchList); |
|
759 const TInt numIds=matchList->Count(); |
|
760 iLog->LogLine(_L("Matched %d contact(s)"),numIds); |
|
761 for (TInt ii=0;ii<numIds;++ii) |
|
762 { |
|
763 LogContactSummaryL(ETrue,(*matchList)[ii]); |
|
764 } |
|
765 CleanupStack::PopAndDestroy(); // matchList. |
|
766 #endif |
|
767 |
|
768 CleanupStack::PopAndDestroy(); // iIdleFinder. |
|
769 return EndAverageProfile(); |
|
770 } |
|
771 |
|
772 void CBenchMarker::IdleFindCallback() |
|
773 { |
|
774 IncVisualCounter(); |
|
775 UpdateAverageProfile(1); |
|
776 if (iIdleFinder->IsComplete()) |
|
777 { |
|
778 CActiveScheduler::Stop(); |
|
779 } |
|
780 } |
|
781 |
|
782 #ifndef __USE_NEW_INTERFACES |
|
783 GLDEF_C void DoSortL(CContactDatabase& aDb) |
|
784 { |
|
785 CContactTextDef* textDef=CContactTextDef::NewLC(); |
|
786 textDef->AppendL(TContactTextDefItem(KUidContactFieldGivenName)); |
|
787 textDef->AppendL(TContactTextDefItem(KUidContactFieldFamilyName)); |
|
788 textDef->AppendL(TContactTextDefItem(KUidContactFieldCompanyName)); |
|
789 aDb.SetTextDefinitionL(textDef); // Takes ownership. |
|
790 CleanupStack::Pop(); // textDef. |
|
791 CArrayFix<CContactDatabase::TSortPref>* sortOrder=new(ELeave)CArrayFixFlat<CContactDatabase::TSortPref>(2); |
|
792 CleanupStack::PushL(sortOrder); |
|
793 sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldDefinedText)); |
|
794 aDb.SortL(sortOrder); // Takes ownership. |
|
795 CleanupStack::Pop(); // sortOrder |
|
796 } |
|
797 #endif |
|
798 |
|
799 GLDEF_C TInt T_BenchClientThreadStart(TAny* aPtr) |
|
800 { |
|
801 TThreadCommandLine* comLine=STATIC_CAST(TThreadCommandLine*, aPtr); |
|
802 RThread owningThread=comLine->iOwningThread; |
|
803 TRequestStatus* initialStatus=comLine->iInitialStatus; |
|
804 TRequestStatus* completionStatus=comLine->iCompletionStatus; |
|
805 TFileName dbFileName=comLine->iDbFileName; |
|
806 if (comLine->iExitAfterSort) |
|
807 { |
|
808 owningThread.RequestComplete(initialStatus,KErrNone); |
|
809 } |
|
810 |
|
811 __UHEAP_MARK; |
|
812 TInt err; |
|
813 CActiveScheduler* scheduler=new CActiveScheduler; |
|
814 if (scheduler) |
|
815 { |
|
816 CActiveScheduler::Install(scheduler); |
|
817 CTrapCleanup* cleanup=CTrapCleanup::New(); |
|
818 if (cleanup) |
|
819 { |
|
820 CContactDatabase* db=NULL; |
|
821 #ifdef __USE_NEW_INTERFACES |
|
822 RContactView sortedIdList; |
|
823 TRAP(err, |
|
824 db=CContactDatabase::OpenL(dbFileName); |
|
825 User::LeaveIfError(sortedIdList.Open(*db)); |
|
826 ); |
|
827 #else |
|
828 TRAP(err, |
|
829 db=CContactDatabase::OpenL(dbFileName); |
|
830 DoSortL(*db); |
|
831 ); |
|
832 #endif |
|
833 if (!comLine->iExitAfterSort) |
|
834 { |
|
835 owningThread.RequestComplete(initialStatus,KErrNone); |
|
836 CActiveScheduler::Start(); |
|
837 } |
|
838 #ifdef __USE_NEW_INTERFACES |
|
839 sortedIdList.Close(); |
|
840 #endif |
|
841 delete db; |
|
842 delete cleanup; |
|
843 } |
|
844 else |
|
845 { |
|
846 err=KErrNoMemory; |
|
847 } |
|
848 delete scheduler; |
|
849 } |
|
850 else |
|
851 { |
|
852 err=KErrNoMemory; |
|
853 } |
|
854 __UHEAP_MARKEND; |
|
855 |
|
856 if (comLine->iExitAfterSort) |
|
857 { |
|
858 owningThread.RequestComplete(completionStatus,err); |
|
859 } |
|
860 owningThread.Close(); |
|
861 return KErrNone; |
|
862 } |
|
863 |
|
864 void CBenchMarker::CreateSecondaryClients() |
|
865 { |
|
866 // Create a set of client threads. |
|
867 for (TInt ii=0;ii<KNumSecondaryClients;++ii) |
|
868 { |
|
869 TRequestStatus initialStatus(KRequestPending); |
|
870 TThreadCommandLine comLine(&initialStatus,NULL,iDbFileName,EFalse); |
|
871 TBuf<32> threadName; |
|
872 threadName.Format(KThreadNameFormat,ii); |
|
873 secondaryClient[ii].Create(threadName,T_BenchClientThreadStart,KClientStackSize,KClientHeapSize,KClientHeapSize,&comLine); |
|
874 comLine.iOwningThread.Duplicate(secondaryClient[ii]); |
|
875 secondaryClient[ii].Resume(); |
|
876 User::WaitForRequest(initialStatus); |
|
877 } |
|
878 } |
|
879 |
|
880 void CBenchMarker::CloseSecondaryClients() |
|
881 { |
|
882 for (TInt ii=0;ii<KNumSecondaryClients;++ii) |
|
883 { |
|
884 secondaryClient[ii].Kill(KErrNone); |
|
885 secondaryClient[ii].Close(); |
|
886 } |
|
887 } |
|
888 |
|
889 void CBenchMarker::CreateSortClients() |
|
890 { |
|
891 TRequestStatus completionStatus[KNumSortClients]; |
|
892 |
|
893 // Create a set of client threads. |
|
894 for (TInt ii=0;ii<KNumSortClients;++ii) |
|
895 { |
|
896 completionStatus[ii]=KRequestPending; |
|
897 TRequestStatus initialStatus(KRequestPending); |
|
898 TThreadCommandLine comLine(&initialStatus,&(completionStatus[ii]),iDbFileName,ETrue); |
|
899 RThread thread; |
|
900 TBuf<32> threadName; |
|
901 threadName.Format(KThreadNameFormat,ii); |
|
902 thread.Create(threadName,T_BenchClientThreadStart,KClientStackSize,KClientHeapSize,KClientHeapSize,&comLine); |
|
903 comLine.iOwningThread.Duplicate(thread); |
|
904 thread.Resume(); |
|
905 thread.Close(); |
|
906 User::WaitForRequest(initialStatus); |
|
907 } |
|
908 |
|
909 // Wait for all the clients to finish. |
|
910 TBool moreClientsToComplete; |
|
911 TInt numWaits=-1; |
|
912 do |
|
913 { |
|
914 ++numWaits; |
|
915 User::WaitForAnyRequest(); |
|
916 moreClientsToComplete=EFalse; |
|
917 for (TInt ii=0;ii<KNumSortClients;++ii) |
|
918 { |
|
919 if (completionStatus[ii].Int()==KRequestPending) |
|
920 { |
|
921 moreClientsToComplete=ETrue; |
|
922 break; |
|
923 } |
|
924 } |
|
925 } |
|
926 while (moreClientsToComplete); |
|
927 |
|
928 while (numWaits<(KNumSortClients-1)) |
|
929 { |
|
930 ++numWaits; |
|
931 User::WaitForAnyRequest(); |
|
932 } |
|
933 } |
|
934 |
|
935 void CBenchMarker::IncVisualCounter() |
|
936 { |
|
937 TBuf<8> backSpaceBuf; |
|
938 |
|
939 if (iVisualCounter>=0) |
|
940 { |
|
941 TInt numDigits=1; |
|
942 TInt divisor=10; |
|
943 |
|
944 FOREVER |
|
945 { |
|
946 if (iVisualCounter/divisor>0) |
|
947 { |
|
948 divisor*=10; |
|
949 ++numDigits; |
|
950 } |
|
951 else |
|
952 { |
|
953 break; |
|
954 } |
|
955 } |
|
956 |
|
957 for (TInt ii=0;ii<numDigits;++ii) |
|
958 { |
|
959 backSpaceBuf.Append(KBackSpace); |
|
960 } |
|
961 } |
|
962 |
|
963 iTest.Printf(KVisualCounterFormat,&backSpaceBuf,++iVisualCounter); |
|
964 } |
|
965 |
|
966 void CBenchMarker::EndVisualCounter() |
|
967 { |
|
968 iTest.Printf(KNewLine); |
|
969 iVisualCounter=-1; |
|
970 } |
|
971 |
|
972 TInt CBenchMarker::DbFileSize() |
|
973 { |
|
974 TEntry dbEntry; |
|
975 TInt err=iFs.Entry(iDbFileName,dbEntry); |
|
976 if (err==KErrNone) |
|
977 { |
|
978 return dbEntry.iSize; |
|
979 } |
|
980 |
|
981 return err; |
|
982 } |
|
983 |
|
984 void CBenchMarker::LogResult(TInt aMajorTestNum,TInt aMinorTestNum,const TDesC& aDescription,TInt aResult) |
|
985 { |
|
986 iLog->LogLine(KResultFormatTInt,aMajorTestNum,aMinorTestNum,&aDescription,aResult); |
|
987 } |
|
988 |
|
989 void CBenchMarker::LogResult(TInt aMajorTestNum,TInt aMinorTestNum,const TDesC& aDescription,TReal aResult) |
|
990 { |
|
991 iLog->LogLine(KResultFormatTReal,aMajorTestNum,aMinorTestNum,&aDescription,aResult); |
|
992 } |
|
993 |
|
994 |
|
995 // |
|
996 // Main. |
|
997 // |
|
998 |
|
999 GLDEF_C TInt E32Main() |
|
1000 { |
|
1001 RDebug::Print(_L("t_bench started")); |
|
1002 __UHEAP_MARK; |
|
1003 TBuf<256> commandLine; |
|
1004 User::CommandLine(commandLine); |
|
1005 |
|
1006 CActiveScheduler* scheduler=new CActiveScheduler; |
|
1007 if (scheduler) |
|
1008 { |
|
1009 CActiveScheduler::Install(scheduler); |
|
1010 CTrapCleanup* cleanup=CTrapCleanup::New(); |
|
1011 if (cleanup) |
|
1012 { |
|
1013 CBenchMarker* benchMarker=new CBenchMarker(); |
|
1014 if (benchMarker) |
|
1015 { |
|
1016 TRAPD(err, |
|
1017 benchMarker->ConstructL(commandLine); |
|
1018 benchMarker->RunL(); |
|
1019 ); |
|
1020 RDebug::Print(_L("t_bench finish with %d error"),err); |
|
1021 delete benchMarker; |
|
1022 } |
|
1023 delete cleanup; |
|
1024 } |
|
1025 delete scheduler; |
|
1026 } |
|
1027 __UHEAP_MARKEND; |
|
1028 return KErrNone; |
|
1029 } |