257 // ---------------------------------------------------------------------------- |
246 // ---------------------------------------------------------------------------- |
258 // CPcsAlgorithm1MultiSearchHelper::AppendMatchToSeqL |
247 // CPcsAlgorithm1MultiSearchHelper::AppendMatchToSeqL |
259 // ---------------------------------------------------------------------------- |
248 // ---------------------------------------------------------------------------- |
260 void CPcsAlgorithm1MultiSearchHelper::AppendMatchToSeqL( |
249 void CPcsAlgorithm1MultiSearchHelper::AppendMatchToSeqL( |
261 RPointerArray<TDesC>& aMatchSeq, const TDesC& aMatch ) |
250 RPointerArray<TDesC>& aMatchSeq, const TDesC& aMatch ) |
262 { |
251 { |
263 HBufC* seq = aMatch.AllocLC(); |
252 HBufC* seq = aMatch.AllocLC(); |
264 seq->Des().UpperCase(); |
253 seq->Des().UpperCase(); |
265 TIdentityRelation<TDesC> rule(Compare3); |
254 TIdentityRelation<TDesC> rule(CPcsAlgorithm1Utils::CompareExact); |
266 if ( aMatchSeq.Find(seq, rule) == KErrNotFound ) |
255 if ( aMatchSeq.Find(seq, rule) == KErrNotFound ) |
267 { |
256 { |
268 aMatchSeq.Append(seq); |
257 aMatchSeq.Append(seq); |
269 CleanupStack::Pop( seq ); |
258 CleanupStack::Pop( seq ); |
270 } |
259 } |
271 else |
260 else |
272 { |
261 { |
273 CleanupStack::PopAndDestroy( seq ); |
262 CleanupStack::PopAndDestroy( seq ); |
274 } |
263 } |
275 } |
264 } |
276 |
265 |
277 // ---------------------------------------------------------------------------- |
266 // ---------------------------------------------------------------------------- |
278 // CPcsAlgorithm1MultiSearchHelper::LookupMatchL |
267 // CPcsAlgorithm1MultiSearchHelper::LookupMatchL |
279 // ---------------------------------------------------------------------------- |
268 // ---------------------------------------------------------------------------- |
280 void CPcsAlgorithm1MultiSearchHelper::LookupMatchL( CPsQuery& aSearchQuery, |
269 void CPcsAlgorithm1MultiSearchHelper::LookupMatchL( CPsQuery& aSearchQuery, |
281 const TDesC& aData, |
270 const TDesC& aData, |
282 TDes& aMatchedData ) |
271 TDes& aMatchedData ) |
283 { |
272 { |
284 RPointerArray<CPsQuery> queryList = MultiQueryL(aSearchQuery); |
273 RPointerArray<CPsQuery> queryList = MultiQueryL(aSearchQuery); |
285 TBuf<KPsQueryMaxLen> queryAsString = aSearchQuery.QueryAsStringLC(); |
274 TBuf<KPsQueryMaxLen> queryAsString = aSearchQuery.QueryAsStringLC(); |
286 TBuf<KPsQueryMaxLen> convertedQuery; |
275 TBuf<KPsQueryMaxLen> convertedQuery; |
287 iKeyMap->GetMixedKeyStringForDataL( aSearchQuery, queryAsString, convertedQuery ); |
276 iKeyMap->GetMixedKeyStringForDataL( aSearchQuery, queryAsString, convertedQuery ); |
288 |
277 |
289 RArray<TInt> dataWordIndexes; |
278 RArray<TInt> dataWordIndexes; |
290 RArray<TInt> dataWordLengths; |
279 RArray<TInt> dataWordLengths; |
291 TLex lex( aData ); |
280 TLex lex( aData ); |
292 while ( !lex.Eos() ) |
281 while ( !lex.Eos() ) |
293 { |
282 { |
294 TPtrC currentWord = lex.NextToken(); |
283 TPtrC currentWord = lex.NextToken(); |
295 PRINT2( _L("idx len: %d %d"), lex.Offset() - currentWord.Length(), currentWord.Length() ); |
284 PRINT2( _L("idx len: %d %d"), lex.Offset() - currentWord.Length(), currentWord.Length() ); |
296 dataWordIndexes.AppendL( lex.Offset() - currentWord.Length() ); |
285 dataWordIndexes.AppendL( lex.Offset() - currentWord.Length() ); |
297 dataWordLengths.AppendL( currentWord.Length() ); |
286 dataWordLengths.AppendL( currentWord.Length() ); |
298 } |
287 } |
299 |
288 |
300 RArray<TInt> queryIndexes; |
289 RArray<TInt> queryIndexes; |
301 RArray<TPtrC> convertedQueriesAsDes; |
290 RArray<TPtrC> convertedQueriesAsDes; |
302 lex.Assign( queryAsString ); |
291 lex.Assign( queryAsString ); |
303 while ( !lex.Eos() ) |
292 while ( !lex.Eos() ) |
304 { |
293 { |
305 TPtrC currentWord = lex.NextToken(); |
294 TPtrC currentWord = lex.NextToken(); |
306 convertedQueriesAsDes.AppendL( |
295 convertedQueriesAsDes.AppendL( |
307 convertedQuery.Mid( lex.Offset() - currentWord.Length(), currentWord.Length()) ); |
296 convertedQuery.Mid( lex.Offset() - currentWord.Length(), currentWord.Length()) ); |
308 queryIndexes.AppendL( lex.Offset() - currentWord.Length() ); |
297 queryIndexes.AppendL( lex.Offset() - currentWord.Length() ); |
309 } |
298 } |
310 |
299 |
311 RPointerArray< RArray<TBool> > possibleMatches; |
300 RPointerArray< RArray<TBool> > possibleMatches; |
312 for ( TInt i(0); i < queryList.Count(); ++i ) |
301 for ( TInt i(0); i < queryList.Count(); ++i ) |
313 { |
302 { |
314 RArray<TBool>* matchesForCurrentQuery = new (ELeave) RArray<TBool>; |
303 RArray<TBool>* matchesForCurrentQuery = new (ELeave) RArray<TBool>; |
315 possibleMatches.AppendL( matchesForCurrentQuery ); |
304 possibleMatches.AppendL( matchesForCurrentQuery ); |
316 CPsQuery* currentQuery = queryList[i]; |
305 CPsQuery* currentQuery = queryList[i]; |
317 for ( TInt j(0); j < dataWordIndexes.Count(); j++ ) |
306 for ( TInt j(0); j < dataWordIndexes.Count(); j++ ) |
318 { |
307 { |
319 TPtrC currentDataWord = aData.Mid( dataWordIndexes[j], dataWordLengths[j] ); |
308 TPtrC currentDataWord = aData.Mid( dataWordIndexes[j], dataWordLengths[j] ); |
320 RBuf convertedDataWord; |
309 RBuf convertedDataWord; |
321 convertedDataWord.CreateL( currentDataWord.Length() ); |
310 convertedDataWord.CreateL( currentDataWord.Length() ); |
322 CleanupClosePushL( convertedDataWord ); |
311 CleanupClosePushL( convertedDataWord ); |
|
312 |
323 iKeyMap->GetMixedKeyStringForDataL( *currentQuery, currentDataWord.Left(currentQuery->Count()), convertedDataWord ); |
313 iKeyMap->GetMixedKeyStringForDataL( *currentQuery, currentDataWord.Left(currentQuery->Count()), convertedDataWord ); |
324 if ( CPcsAlgorithm1Utils::MyCompareC( convertedQueriesAsDes[i], convertedDataWord ) == 0 ) |
314 |
325 { |
315 if ( CPcsAlgorithm1Utils::MyCompareKeyAndString(convertedQueriesAsDes[i], convertedDataWord, *currentQuery) ) |
|
316 { |
326 matchesForCurrentQuery->AppendL( ETrue ); |
317 matchesForCurrentQuery->AppendL( ETrue ); |
327 } |
318 } |
328 else |
319 else |
329 { |
320 { |
330 matchesForCurrentQuery->AppendL( EFalse ); |
321 matchesForCurrentQuery->AppendL( EFalse ); |
331 } |
322 } |
332 PRINT3( _L("CPcsAlgorithm1MultiSearchHelper::LookupMatchL: possibleMatches[%d][%d]=%d"),i,j, (*(possibleMatches[i]))[j] ) |
323 PRINT3( _L("CPcsAlgorithm1MultiSearchHelper::LookupMatchL: possibleMatches[%d][%d]=%d"),i,j, (*(possibleMatches[i]))[j] ) |
333 CleanupStack::PopAndDestroy( &convertedDataWord ); |
324 CleanupStack::PopAndDestroy( &convertedDataWord ); |
334 } |
|
335 } |
325 } |
|
326 } |
336 |
327 |
337 const TInt KUnapplied(-1); |
328 const TInt KUnapplied(-1); |
338 RArray<TInt> appliedMatches; |
329 RArray<TInt> appliedMatches; |
339 appliedMatches.ReserveL( queryList.Count() ); |
330 appliedMatches.ReserveL( queryList.Count() ); |
340 for ( TInt i(0); i < queryList.Count(); ++i ) |
331 for ( TInt i(0); i < queryList.Count(); ++i ) |
341 { |
332 { |
342 appliedMatches.AppendL( KUnapplied ); |
333 appliedMatches.AppendL( KUnapplied ); |
343 } |
334 } |
344 |
335 |
345 //backtrack algorithm starts here to find fully applied match |
336 //backtrack algorithm starts here to find fully applied match |
346 TInt currentQueryIndex(0); |
337 TInt currentQueryIndex(0); |
347 while ( currentQueryIndex < queryList.Count() |
338 while ( currentQueryIndex < queryList.Count() && currentQueryIndex >= 0 ) |
348 && currentQueryIndex >= 0 ) |
339 { |
349 { |
|
350 TInt currentDataIndex = appliedMatches[ currentQueryIndex ] + 1; |
340 TInt currentDataIndex = appliedMatches[ currentQueryIndex ] + 1; |
351 appliedMatches[ currentQueryIndex ] = KUnapplied; |
341 appliedMatches[ currentQueryIndex ] = KUnapplied; |
352 RArray<TBool>& matchesForCurrentQuery = *(possibleMatches[currentQueryIndex]); |
342 RArray<TBool>& matchesForCurrentQuery = *(possibleMatches[currentQueryIndex]); |
353 TBool doBacktrack( ETrue ); |
343 TBool doBacktrack( ETrue ); |
354 while ( currentDataIndex < dataWordIndexes.Count() ) |
344 while ( currentDataIndex < dataWordIndexes.Count() ) |
355 { |
345 { |
356 PRINT2(_L("CPcsAlgorithm1MultiSearchHelper::LookupMatchL: matchesForCurrentQuery[%d] = %d"), |
346 PRINT2(_L("CPcsAlgorithm1MultiSearchHelper::LookupMatchL: matchesForCurrentQuery[%d] = %d"), |
357 currentDataIndex, matchesForCurrentQuery[ currentDataIndex ] ); |
347 currentDataIndex, matchesForCurrentQuery[ currentDataIndex ] ); |
358 |
348 |
359 if ( matchesForCurrentQuery[ currentDataIndex ] |
349 if ( matchesForCurrentQuery[ currentDataIndex ] |
360 && (appliedMatches.Find( currentDataIndex ) == KErrNotFound) ) |
350 && (appliedMatches.Find( currentDataIndex ) == KErrNotFound) ) |
361 { |
351 { |
362 appliedMatches[ currentQueryIndex ] = currentDataIndex; |
352 appliedMatches[ currentQueryIndex ] = currentDataIndex; |
363 doBacktrack = EFalse; |
353 doBacktrack = EFalse; |
364 break; |
354 break; |
365 } |
355 } |
366 ++currentDataIndex; |
356 ++currentDataIndex; |
367 } |
357 } |
368 if ( doBacktrack ) |
358 if ( doBacktrack ) |
369 { |
359 { |
370 --currentQueryIndex; |
360 --currentQueryIndex; |
371 } |
361 } |
372 else |
362 else |
373 { |
363 { |
374 ++currentQueryIndex; |
364 ++currentQueryIndex; |
375 } |
|
376 } |
365 } |
|
366 } |
377 |
367 |
378 if ( currentQueryIndex >= 0 ) //found |
368 if ( currentQueryIndex >= 0 ) //found |
379 { |
369 { |
380 aMatchedData = queryAsString; |
370 aMatchedData = queryAsString; |
381 for ( TInt i(0); i < appliedMatches.Count(); ++i ) |
371 for ( TInt i(0); i < appliedMatches.Count(); ++i ) |
382 { |
372 { |
383 TInt matchedDataIndex = appliedMatches[i]; |
373 TInt matchedDataIndex = appliedMatches[i]; |
384 TPtr resultFragment = aMatchedData.MidTPtr( |
374 TPtr resultFragment = aMatchedData.MidTPtr( |
385 queryIndexes[ i ], |
375 queryIndexes[ i ], |
386 convertedQueriesAsDes[i].Length() ); |
376 convertedQueriesAsDes[i].Length() ); |
387 resultFragment = aData.Mid( |
377 resultFragment = aData.Mid( |
388 dataWordIndexes[ matchedDataIndex ], |
378 dataWordIndexes[ matchedDataIndex ], |
389 convertedQueriesAsDes[i].Length() ); |
379 convertedQueriesAsDes[i].Length() ); |
390 } |
380 } |
391 } |
381 } |
392 else |
382 else |
393 { |
383 { |
394 aMatchedData.Zero(); |
384 aMatchedData.Zero(); |
395 } |
385 } |
396 |
386 |
397 for ( TInt i(0); i < possibleMatches.Count(); ++i ) |
387 for ( TInt i(0); i < possibleMatches.Count(); ++i ) |
398 { |
388 { |
399 RArray<TBool>* pointerToDelete = possibleMatches[i]; |
389 RArray<TBool>* pointerToDelete = possibleMatches[i]; |
400 pointerToDelete->Close(); |
390 pointerToDelete->Close(); |
401 delete pointerToDelete; |
391 delete pointerToDelete; |
402 } |
392 } |
403 possibleMatches.Close(); |
393 possibleMatches.Close(); |
404 dataWordIndexes.Close(); |
394 dataWordIndexes.Close(); |
405 dataWordLengths.Close(); |
395 dataWordLengths.Close(); |
406 |
396 |
407 queryIndexes.Close(); |
397 queryIndexes.Close(); |
408 convertedQueriesAsDes.Close(); |
398 convertedQueriesAsDes.Close(); |
409 queryList.Close(); |
399 queryList.Close(); |
410 appliedMatches.Close(); |
400 appliedMatches.Close(); |
411 |
401 |
412 CleanupStack::PopAndDestroy(); //result of queryAsStringLC |
402 CleanupStack::PopAndDestroy(); //result of queryAsStringLC |
413 } |
403 } |
414 |
404 |
415 // ---------------------------------------------------------------------------- |
405 // ---------------------------------------------------------------------------- |
416 // CPcsAlgorithm1MultiSearchHelper::ConvertQueryToList |
406 // CPcsAlgorithm1MultiSearchHelper::ConvertQueryToList |
417 // Converts the multiple search queries to a list |
407 // Converts the multiple search queries to a list |
418 // ---------------------------------------------------------------------------- |
408 // ---------------------------------------------------------------------------- |
486 |
476 |
487 // Check for each query atleast one data element matches |
477 // Check for each query atleast one data element matches |
488 // Loop from the last query so that longest match is seen first |
478 // Loop from the last query so that longest match is seen first |
489 for ( TInt queryIndex = queryList.Count() - 1; queryIndex >= 0; queryIndex-- ) |
479 for ( TInt queryIndex = queryList.Count() - 1; queryIndex >= 0; queryIndex-- ) |
490 { |
480 { |
491 TBool queryMatch = EFalse; |
481 TBool queryMatch = EFalse; |
492 HBufC* tmpQuery = queryList[queryIndex]; |
482 HBufC* tmpQuery = queryList[queryIndex]; |
493 // Get the original query mode corresponding to this query |
483 // Get the original query mode corresponding to this query |
494 TInt modeIndex = tempqueryList.Find(tmpQuery); |
484 TInt modeIndex = tempqueryList.Find(tmpQuery); |
495 |
485 |
496 for ( TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++ ) |
486 for ( TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++ ) |
497 { |
487 { |
498 // Filter off data fields not required in search |
488 // Filter off data fields not required in search |
499 TReal bitIndex; |
489 TReal bitIndex; |
500 Math::Pow(bitIndex, 2, dataIndex); |
490 Math::Pow(bitIndex, 2, dataIndex); |
501 |
491 |
502 TUint8 filter = (TUint8)bitIndex & aFilteredDataMatch; |
492 TUint8 filter = (TUint8)bitIndex & aFilteredDataMatch; |
503 if ( filter == 0x0 ) |
493 if ( filter == 0x0 ) |
504 { |
494 { |
505 // Move to next data |
495 // Move to next data |
506 continue; |
496 continue; |
507 } |
497 } |
508 |
498 |
509 TInt wordIndex = -1; |
499 TInt wordIndex = -1; |
510 |
500 |
511 TLex lex(psData->Data(dataIndex)->Des()); |
501 TLex lex(psData->Data(dataIndex)->Des()); |
512 |
502 |
513 // First word |
503 // First word |
514 TPtrC tmpData = lex.NextToken(); |
504 TPtrC tmpData = lex.NextToken(); |
515 |
505 |
516 // Search thru multiple words |
506 // Search thru multiple words |
517 while ( tmpData.Length() != 0 ) |
507 while ( tmpData.Length() != 0 ) |
518 { |
508 { |
519 wordIndex++; |
509 wordIndex++; |
520 |
510 |
521 TBuf<KPsQueryMaxLen> data; |
511 TBuf<KPsQueryMaxLen> data; |
522 |
512 |
523 // Convert the data to required form (mode specific) |
513 // Convert the data to required form (mode specific) |
524 iKeyMap->GetMixedKeyStringForDataL(*searchQuery[modeIndex], tmpData, data); |
514 iKeyMap->GetMixedKeyStringForDataL(*searchQuery[modeIndex], tmpData, data); |
525 |
515 |
526 // Compare the data against query |
516 // Compare the data against query |
527 if ( CPcsAlgorithm1Utils::MyCompareC(data.Left(tmpQuery->Length()), |
517 if ( CPcsAlgorithm1Utils::MyCompareKeyAndString(data, *tmpQuery, *searchQuery[modeIndex]) ) |
528 *tmpQuery) == 0 ) |
518 { |
529 { |
|
530 psData->SetDataMatch(dataIndex); |
519 psData->SetDataMatch(dataIndex); |
531 |
520 |
532 // Perform two checks. |
521 // Perform two checks. |
533 // 1. Ensure that the word is not matched against any previous query |
522 // 1. Ensure that the word is not matched against any previous query |
534 // 2. If it is the first match to the query |
523 // 2. If it is the first match to the query |
535 TBool isWordMatch = IsWordMatch(dataIndex, wordIndex); |
524 TBool isWordMatch = IsWordMatch(dataIndex, wordIndex); |
536 |
525 |
537 // Check if the current word is not matched to any query |
526 // Check if the current word is not matched to any query |
538 if( !isWordMatch ) |
527 if( !isWordMatch ) |
539 { |
528 { |
540 // Check if no word is matched for this query till now |
529 // Check if no word is matched for this query till now |
541 if ( !queryMatch ) |
530 if ( !queryMatch ) |
542 { |
531 { |
543 wordMatches++; |
532 wordMatches++; |
544 queryMatch = ETrue; |
533 queryMatch = ETrue; |
545 SetWordMap(dataIndex, wordIndex); |
534 SetWordMap(dataIndex, wordIndex); |
546 } |
535 } |
547 |
536 |
548 // Extract matched character sequence and fill in temp array |
537 // Extract matched character sequence and fill in temp array |
549 TInt len = tmpQuery->Length(); |
538 TInt len = tmpQuery->Length(); |
550 HBufC* seq = HBufC::NewL(len); |
539 HBufC* seq = HBufC::NewL(len); |
551 *seq = tmpData.Mid(0, len); |
540 *seq = tmpData.Mid(0, len); |
552 |
541 |
553 seq->Des().UpperCase(); |
542 seq->Des().UpperCase(); |
554 TIdentityRelation<TDesC> searchRule(Compare3); |
543 TIdentityRelation<TDesC> searchRule(CPcsAlgorithm1Utils::CompareExact); |
555 if ( tmpMatchSet.Find(seq, searchRule) == KErrNotFound ) |
544 if ( tmpMatchSet.Find(seq, searchRule) == KErrNotFound ) |
556 { |
545 { |
557 tmpMatchSet.Append(seq); |
546 tmpMatchSet.Append(seq); |
558 } |
547 } |
559 else |
548 else |
560 { |
549 { |
561 delete seq; |
550 delete seq; |
562 seq = NULL; |
551 seq = NULL; |
563 } |
552 } |
564 } |
553 } |
565 } |
554 } |
566 |
555 |
567 // Next word |
556 // Next word |
568 tmpData.Set(lex.NextToken()); |
557 tmpData.Set(lex.NextToken()); |
569 } |
558 } |
570 } |
559 } |
571 |
560 |
572 // No data element matches the query. Ignore this result. |
561 // No data element matches the query. Ignore this result. |
573 if ( queryMatch == EFalse ) |
562 if ( queryMatch == EFalse ) |
574 { |
563 { |
575 isMatch = EFalse; |
564 isMatch = EFalse; |
576 break; |
565 break; |
577 } |
566 } |
578 } |
567 } |
579 |
568 |
580 // If match add the element to the result set |
569 // If match add the element to the result set |
581 // And before adding to the result set, check if there is atleast one match per query |
570 // And before adding to the result set, check if there is atleast one match per query |
582 if (( isMatch ) && ( wordMatches >= queryList.Count())) |
571 if (( isMatch ) && ( wordMatches >= queryList.Count())) |