predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp
branchRCL_3
changeset 58 d4f567ce2e7c
parent 32 2828b4d142c0
child 64 c1e8ba0c2b16
equal deleted inserted replaced
57:2666d9724c76 58:d4f567ce2e7c
    21 #include "CPcsAlgorithm2Utils.h"
    21 #include "CPcsAlgorithm2Utils.h"
    22 #include "CPcsDefs.h"
    22 #include "CPcsDefs.h"
    23 #include <collate.h>
    23 #include <collate.h>
    24 #include <biditext.h>
    24 #include <biditext.h>
    25 
    25 
    26 // Compare functions
    26 
    27 TBool Compare2(const HBufC& aFirst, const HBufC& aSecond)
       
    28     {
       
    29     TPtrC t1(aFirst);
       
    30     TPtrC t2(aSecond);
       
    31     return (t1.Length() > t2.Length());
       
    32     }
       
    33 
       
    34 TBool Compare3(const TDesC& aFirst, const TDesC& aSecond)
       
    35     {
       
    36     return aFirst == aSecond;
       
    37     }
       
    38 
       
    39 TBool Compare4(const CPsQuery& aFirst, const CPsQuery& aSecond)
       
    40     {
       
    41     CPsQuery& first = const_cast<CPsQuery&> (aFirst);
       
    42     CPsQuery& second = const_cast<CPsQuery&> (aSecond);
       
    43     
       
    44     return (first.Count() > second.Count());
       
    45     }
       
    46 // ============================== MEMBER FUNCTIONS ============================
    27 // ============================== MEMBER FUNCTIONS ============================
    47 
    28 
    48 // ----------------------------------------------------------------------------
    29 // ----------------------------------------------------------------------------
    49 // CPcsAlgorithm2MultiSearchHelper::NewL
    30 // CPcsAlgorithm2MultiSearchHelper::NewL
    50 // Two Phase Construction
    31 // Two Phase Construction
    80 void CPcsAlgorithm2MultiSearchHelper::ConstructL(CPcsAlgorithm2* aAlgorithm)
    61 void CPcsAlgorithm2MultiSearchHelper::ConstructL(CPcsAlgorithm2* aAlgorithm)
    81     {
    62     {
    82     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    63     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    83 
    64 
    84     iAlgorithm = aAlgorithm;
    65     iAlgorithm = aAlgorithm;
    85     keyMap = iAlgorithm->GetKeyMap();
    66     iKeyMap = iAlgorithm->GetKeyMap();
    86 
    67     iMaxCount = 0;
       
    68     
    87     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    69     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    88     }
    70     }
    89 
    71 
    90 // ----------------------------------------------------------------------------
    72 // ----------------------------------------------------------------------------
    91 // CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2MultiSearchHelper
    73 // CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper
    92 // Destructor
    74 // Destructor
    93 // ----------------------------------------------------------------------------
    75 // ----------------------------------------------------------------------------
    94 CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper()
    76 CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper()
    95     {
    77     {
    96     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper") );
    78     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper") );
   114 //     data element has not matched for multiple queries.
    96 //     data element has not matched for multiple queries.
   115 // (9) Now include the element in the result.
    97 // (9) Now include the element in the result.
   116 // ----------------------------------------------------------------------------
    98 // ----------------------------------------------------------------------------
   117 void CPcsAlgorithm2MultiSearchHelper::SearchMultiL(const CPsSettings& aSettings, 
    99 void CPcsAlgorithm2MultiSearchHelper::SearchMultiL(const CPsSettings& aSettings, 
   118                                                    RPointerArray<CPsQuery>& aPsQuery,
   100                                                    RPointerArray<CPsQuery>& aPsQuery,
   119                                                    TBool isSearchInGroup, 
   101                                                    TBool aIsSearchInGroup, 
   120                                                    RArray<TInt>& aContactsInGroup, 
   102                                                    const RArray<TInt>& aContactsInGroup, 
   121                                                    RPointerArray<CPsData>& searchResults,
   103                                                    RPointerArray<CPsData>& aSearchResults,
   122                                                    RPointerArray<CPsPattern>& searchSeqs,
   104                                                    RPointerArray<CPsPattern>& aSearchSeqs)
   123                                                    TInt keyboardMode)
   105     {
   124     {
       
   125     __LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
       
   126     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   106     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   127 
   107 
       
   108     //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
       
   109 
       
   110     PRINTQUERYLIST ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL: "), aPsQuery );
       
   111 
       
   112     iMaxCount = aSettings.MaxResults();
   128     // Create CPcsAlgorithm2FilterHelper object to be used for filtering the results
   113     // Create CPcsAlgorithm2FilterHelper object to be used for filtering the results
   129     TSortType sortType = aSettings.GetSortType();
   114     TSortType sortType = aSettings.GetSortType();
   130     CPcsAlgorithm2FilterHelper* filterHelper = CPcsAlgorithm2FilterHelper::NewL(sortType);
   115     CPcsAlgorithm2FilterHelper* filterHelper = CPcsAlgorithm2FilterHelper::NewL(sortType);
       
   116     CleanupStack::PushL( filterHelper );
   131     RPointerArray<CPcsPoolElement> elements;
   117     RPointerArray<CPcsPoolElement> elements;
       
   118     CleanupClosePushL( elements );
   132 
   119 
   133     iMultiSearchResultsArr.ResetAndDestroy();
   120     iMultiSearchResultsArr.ResetAndDestroy();
   134 
   121 
   135     // Get the data stores  
   122     // Get the data stores  
   136     RPointerArray<TDesC> aDataStores;
   123     RPointerArray<TDesC> dataStores;
   137     aSettings.SearchUrisL(aDataStores);
   124     CleanupResetAndDestroyPushL( dataStores );
       
   125     aSettings.SearchUrisL(dataStores);
   138 
   126 
   139     // Get the required display fields from the client
   127     // Get the required display fields from the client
   140     RArray<TInt> requiredDataFields;
   128     RArray<TInt> requiredDataFields;
       
   129     CleanupClosePushL( requiredDataFields );
   141     aSettings.DisplayFieldsL(requiredDataFields);
   130     aSettings.DisplayFieldsL(requiredDataFields);
   142 
   131 
   143     // Search from cache based on first character
   132     // Search from cache based on first character of 1st item in query list
   144     const CPsQueryItem& firstCharItem = aPsQuery[0]->GetItemAtL(0);
   133     const CPsQueryItem& firstCharItem = aPsQuery[0]->GetItemAtL(0);
   145     TInt numValue  = keyMap->PoolIdForCharacter( firstCharItem.Character() );
   134     TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() );
   146     
   135 
   147     // Get the elements from all the databases
   136     // Get the elements from all the databases
   148     for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
   137     const TInt dataStoresCount = dataStores.Count(); 
       
   138     for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++)
   149         {
   139         {
   150         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
   140         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
   151         iMultiSearchResultsArr.Append(temp);
   141         iMultiSearchResultsArr.Append(temp);
   152 
   142 
   153         // Get the contents for this data store
   143         // Get the contents for this data store
   154         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
   144         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex]));
   155         if (arrayIndex < 0)
   145         if (arrayIndex < 0)
   156             {
   146             {
   157             continue;
   147             continue;
   158             }
   148             }
   159         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
   149         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
   160         cache->GetContactsForKeyL(numValue, elements);
   150         cache->GetContactsForKeyL(cachePoolId, elements);
   161 
   151 
   162         // Get the supported data fields for this data store
   152         // Get the supported data fields for this data store
   163         RArray<TInt> supportedDataFields;
   153         RArray<TInt> supportedDataFields;
       
   154         CleanupClosePushL( supportedDataFields );
   164         cache->GetDataFields(supportedDataFields);
   155         cache->GetDataFields(supportedDataFields);
   165 
   156 
   166         // Get the filtered data fields for this data store    		
   157         // Get the filtered data fields for this data store
   167         TUint8 filteredDataMatch = FilterDataFieldsL(requiredDataFields, supportedDataFields);
   158         TUint8 filteredDataMatch = CPcsAlgorithm2Utils::FilterDataFieldsL(
       
   159                 requiredDataFields, supportedDataFields);
   168 
   160 
   169         // Filter the results now
   161         // Filter the results now
   170         FilterResultsMultiL(filterHelper, elements, aPsQuery, filteredDataMatch, 
   162         FilterResultsMultiL(filterHelper, 
   171                             isSearchInGroup, aContactsInGroup, keyboardMode);
   163                             elements, 
   172 
   164                             aPsQuery, 
   173         // If alphabetical sorting, get the results for this datastore               
   165                             filteredDataMatch, 
       
   166                             aIsSearchInGroup, 
       
   167                             aContactsInGroup);
       
   168 
       
   169         // If alphabetical sorting, get the results for this datastore
   174         if (sortType == EAlphabetical)
   170         if (sortType == EAlphabetical)
   175             {
   171             {
   176             filterHelper->GetResults(*(iMultiSearchResultsArr[dsIndex]));
   172             filterHelper->GetResults(*(iMultiSearchResultsArr[dsIndex]));
   177             }
   173             }
   178 
   174 
   179         elements.Reset();
   175         elements.Reset();
   180         supportedDataFields.Reset();
   176         CleanupStack::PopAndDestroy( &supportedDataFields ); // Close
   181         }
   177         }
   182     aDataStores.ResetAndDestroy();
   178     CleanupStack::PopAndDestroy( &requiredDataFields ); // Close
   183     requiredDataFields.Reset();
   179     CleanupStack::PopAndDestroy( &dataStores );         // ResetAndDestroy
   184 
   180 
   185     // If alphabetical sorting, merge the result sets of all datastores
   181     // If alphabetical sorting, merge the result sets of all datastores
   186     if (sortType == EAlphabetical)
   182     if (sortType == EAlphabetical)
   187         {
   183         {
   188         // Form the complete searchResults array
   184         // Form the complete searchResults array
   189         CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, searchResults);
   185         CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, 
       
   186                                                         aSearchResults);
   190         }
   187         }
   191     else
   188     else
   192         {
   189         {
   193         // Results are already sorted patternbased
   190         // Results are already sorted patternbased
   194         filterHelper->GetResults(searchResults);
   191         filterHelper->GetResults(aSearchResults);
   195         }
   192         }
   196 
   193 
   197     // Get the sorted match sequence list
   194     // Get the sorted match sequence list
   198     filterHelper->GetPatternsL(searchSeqs);
   195     filterHelper->GetPatternsL(aSearchSeqs);
   199 
   196 
   200     PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
   197     PRINT1 ( _L("Number of search results = %d"), aSearchResults.Count() );
   201 
   198 
   202     // Cleanup             
   199     // Cleanup
   203     for (TInt i = 0; i < iMultiSearchResultsArr.Count(); i++)
   200     for (TInt i = 0; i < iMultiSearchResultsArr.Count(); i++)
   204         {
   201         {
   205         iMultiSearchResultsArr[i]->Reset();
   202         iMultiSearchResultsArr[i]->Reset();
   206         delete iMultiSearchResultsArr[i];
   203         delete iMultiSearchResultsArr[i];
   207         iMultiSearchResultsArr[i] = NULL;
   204         iMultiSearchResultsArr[i] = NULL;
   208         }
   205         }
   209 
   206 
   210     iMultiSearchResultsArr.Reset();
   207     iMultiSearchResultsArr.Reset();
   211     delete filterHelper;
   208     CleanupStack::PopAndDestroy( &elements ); // Close
       
   209     CleanupStack::PopAndDestroy( filterHelper );
       
   210 
       
   211     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   212 
   212 
   213     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   213     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   214     __LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   214     }
   215     }
   215 
   216 
   216 // ----------------------------------------------------------------------------
   217 // ----------------------------------------------------------------------------
   217 // CPcsAlgorithm1MultiSearchHelper::SearchMatchSeqMultiL
   218 // CPcsAlgorithm2MultiSearchHelper::SearchInputMultiL
   218 // Function adds matches, and locations based on multi query, and data
   219 // Function to search match sequences for multi query
   219 // Duplicate locations are allowed (as they are removed later anyway)
   220 // ----------------------------------------------------------------------------
   220 // Post condition locations in index order
   221 void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL(RPointerArray<CPsQuery>& aPsQuery, 
   221 // ----------------------------------------------------------------------------
   222                                                            TDesC& aData, 
   222 void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL( RPointerArray<CPsQuery>& aPsQuery,
   223                                                            RPointerArray<TDesC>& aMatchSet,
   223                                                             const TDesC& aData,
   224                                                            RArray<TPsMatchLocation>& aMatchLocation)
   224                                                             RPointerArray<TDesC>& aMatchSeq,
       
   225                                                             RArray<TPsMatchLocation>& aMatchLocation )
   225     {
   226     {
   226     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
   227     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
   227     CleanupResetAndDestroyPushL( aMatchSet );
   228 
   228     CleanupClosePushL( aMatchLocation );
   229     TLex lex(aData);
       
   230     while ( !lex.Eos() ) // Search thru all words
       
   231         {
       
   232         TPtrC currentWord = lex.NextToken(); // next word
       
   233 
       
   234         const TInt psQueryCount = aPsQuery.Count(); 
       
   235         for ( TInt queryIndex = 0; queryIndex < psQueryCount; ++queryIndex )
       
   236             {
       
   237             CPsQuery* currentQuery = aPsQuery[queryIndex];
       
   238 
       
   239             RArray<TInt> matchPos;
       
   240             CleanupClosePushL( matchPos );
       
   241             RArray<TInt> matchLen;
       
   242             CleanupClosePushL( matchLen );
       
   243             
       
   244             if ( iAlgorithm->FindUtilECE()->MatchRefineL( currentWord, *currentQuery, matchPos, matchLen, ETrue ) )
       
   245                 {
       
   246                 // Some matches found. Add all of them to result array.
       
   247                 ASSERT( matchPos.Count() == matchLen.Count() );
       
   248                 
       
   249                 TInt wordStartPos = lex.Offset() - currentWord.Length();
       
   250                 const TInt matchPosCount =  matchPos.Count(); 
       
   251                 for ( TInt i = 0 ; i < matchPosCount; ++i )
       
   252                     {
       
   253                     TPsMatchLocation newLocation = { wordStartPos + matchPos[i], matchLen[i], 
       
   254                             TBidiText::TextDirectionality(currentWord) };
       
   255                     aMatchLocation.AppendL( newLocation );
       
   256 
       
   257                     TPtrC matchPart = currentWord.Mid( matchPos[i], matchLen[i] );
       
   258                     CPcsAlgorithm2Utils::AppendMatchToSeqL( aMatchSeq, matchPart );
       
   259                     }
       
   260                 }
       
   261                 
       
   262             CleanupStack::PopAndDestroy( &matchLen );
       
   263             CleanupStack::PopAndDestroy( &matchPos );
       
   264             }
       
   265         }
       
   266 
       
   267     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
       
   268     }
       
   269 
       
   270 // ----------------------------------------------------------------------------
       
   271 // CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL
       
   272 // Subset search function. Refer the above function for more description.
       
   273 // ----------------------------------------------------------------------------
       
   274 void CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
       
   275                                                           RPointerArray<CPcsPoolElement>& aSearchSet,
       
   276                                                           RPointerArray<CPsQuery>& aSearchQuery, 
       
   277                                                           TUint8 aFilteredDataMatch,
       
   278                                                           TBool aIsSearchInGroup, 
       
   279                                                           const RArray<TInt>& aContactsInGroup)
       
   280     {
       
   281     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
       
   282 
       
   283     //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
       
   284 
       
   285     TInt maxcount = 0;
   229     
   286     
   230     RPointerArray<HBufC> queryList;
   287     // Convert the individual queries to string form
   231     ConvertQueryToListL(aPsQuery, queryList);
   288     RPointerArray<CPsQuery> mySearchQuery;
   232 
   289     CleanupResetAndDestroyPushL( mySearchQuery );
   233     RPointerArray<HBufC> tempqueryList;
   290 
   234     // Remember a temporary copy of query list
   291     // Remember a temporary copy of query list
   235     // since we sort the queries
   292     // Copy the content of searchQuery
   236     for (TInt i = 0; i < queryList.Count(); i++)
   293     const TInt searchQueryCount = aSearchQuery.Count(); 
   237         {
   294     for (TInt i=0; i < searchQueryCount; i++)
   238         tempqueryList.Append(queryList[i]);
   295         {
   239         }
   296         CPsQuery* tempQuery = CPsQuery::NewL();
       
   297         CleanupStack::PushL( tempQuery );
       
   298         iAlgorithm->FindUtilECE()->GetPartOfQueryL(
       
   299                 *(aSearchQuery[i]), 0, aSearchQuery[i]->Count()-1, *tempQuery );
       
   300         mySearchQuery.AppendL(tempQuery);
       
   301         CleanupStack::Pop(tempQuery); // ownership transferred
       
   302         }
       
   303 
       
   304     // Sort the query items according to the length of each query 
       
   305     TLinearOrder<CPsQuery> rule(CPcsAlgorithm2Utils::CompareLength);
       
   306     mySearchQuery.Sort(rule);
       
   307 
   240     // To hold the match results
   308     // To hold the match results
   241     RPointerArray<TDesC> tmpMatchSet;
   309     RPointerArray<TDesC> tmpMatchSet;
   242     TBool isMatch = ETrue;
   310     CleanupResetAndDestroyPushL( tmpMatchSet );
   243     TUint32 wordMatches = 0;
   311 
   244 
   312     // Parse thru each search set elements and filter the results
   245     // Sort the query items before we search them
   313     const TInt searchSetCount = aSearchSet.Count(); 
   246     TLinearOrder<HBufC> rule(Compare2);
   314     for (TInt index = 0; index < searchSetCount; index++)
   247     queryList.Sort(rule);
   315         {
   248 
   316         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (aSearchSet[index]);
   249     // Check for each query atleast one data element matches
       
   250     // Loop from the last query so that longest match is seen first
       
   251     for (TInt queryIndex = queryList.Count() - 1; queryIndex >= 0; queryIndex--)
       
   252         {
       
   253         TBool queryMatch = EFalse;
       
   254         HBufC* tmpQuery = queryList[queryIndex];
       
   255         // Get the original query mode corresponding to this query
       
   256         TInt modeIndex = tempqueryList.Find(tmpQuery);
       
   257 
       
   258         TLex lex(aData);
       
   259 
       
   260         // First word
       
   261         TPtrC tmpData = lex.NextToken();
       
   262 
       
   263         TInt beg = lex.Offset() - tmpData.Length(); // start index of match sequence
       
   264 
       
   265         TInt wordIndex = -1;
       
   266         // Search thru multiple words
       
   267         while ((tmpData.Length() != 0) && (!queryMatch))
       
   268             {
       
   269             wordIndex++;
       
   270 
       
   271             TPtr ptr = tmpQuery->Des();
       
   272 
       
   273             // Perform two checks.
       
   274             // 1. Ensure that the word is not matched against any previous query
       
   275             // 2. If it is the first match to the query
       
   276             TBool isWordMatch = EFalse;
       
   277             TReal val;
       
   278             Math::Pow(val, 2, wordIndex);
       
   279             isWordMatch = wordMatches & (TUint) val;
       
   280 
       
   281             if (!isWordMatch)
       
   282                 {
       
   283                 // Check if no word is matched till now for this query
       
   284                 if (!queryMatch)
       
   285                     {
       
   286                     queryMatch = ETrue;
       
   287                     //set the word match bit
       
   288                     TReal val;
       
   289                     Math::Pow(val, 2, wordIndex);
       
   290                     wordMatches |= (TUint) val;
       
   291                     }
       
   292 
       
   293                 TPsMatchLocation tempLocation;
       
   294                 // check for directionality of the text
       
   295                 TBool found(EFalse);
       
   296                 TBidiText::TDirectionality dir = TBidiText::TextDirectionality(tmpData, &found);
       
   297 
       
   298                 tempLocation.index = beg;
       
   299                 tempLocation.length = 0;
       
   300                 tempLocation.direction = dir;
       
   301 
       
   302                 // Add the match location to the data structure array
       
   303                 aMatchLocation.Append(tempLocation);
       
   304                 }
       
   305             }
       
   306         // Next word
       
   307         tmpData.Set(lex.NextToken());
       
   308         beg = lex.Offset() - tmpData.Length(); // start index of next word  
       
   309 
       
   310 
       
   311         // No data element matches the query. Ignore this result.
       
   312         if (queryMatch == EFalse)
       
   313             {
       
   314             isMatch = EFalse;
       
   315             break;
       
   316             }
       
   317         }
       
   318 
       
   319     // Count the number of bits set
       
   320     TInt matchCount = 0;
       
   321     matchCount = BitsSet32(wordMatches);
       
   322 
       
   323     // If match add the element to the result set
       
   324     // Before adding to the result set, check if there is atleast one match per query
       
   325     // Number of bits set in word matches is atleast equal to total number of queries.
       
   326     if ((isMatch) && (matchCount >= queryList.Count()))
       
   327         {
       
   328 
       
   329         // Include the match sequences in the final results
       
   330         for (int i = 0; i < tmpMatchSet.Count(); i++)
       
   331             {
       
   332             TIdentityRelation<TDesC> rule(Compare3);
       
   333             CleanupStack::PushL(tmpMatchSet[i]);
       
   334             if (aMatchSet.Find(tmpMatchSet[i], rule) == KErrNotFound)
       
   335                 {
       
   336                 aMatchSet.Append(tmpMatchSet[i]);
       
   337                 CleanupStack::Pop();
       
   338                 }
       
   339             else
       
   340                 {
       
   341                 CleanupStack::PopAndDestroy();
       
   342                 }
       
   343             }
       
   344 
       
   345         // Reset tmp match set
       
   346         tmpMatchSet.Reset();
       
   347         }
       
   348     else
       
   349         {
       
   350         tmpMatchSet.ResetAndDestroy();
       
   351         }
       
   352 
       
   353     // Free the query list
       
   354     queryList.ResetAndDestroy();
       
   355     tempqueryList.Reset();
       
   356     
       
   357     CleanupStack::Pop();
       
   358     CleanupStack::Pop( &aMatchSet );
       
   359 
       
   360     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
       
   361     }
       
   362 
       
   363 // ----------------------------------------------------------------------------
       
   364 // CPcsAlgorithm2MultiSearchHelper::ConvertQueryToList
       
   365 // Converts the multiple search queries to a list
       
   366 // ----------------------------------------------------------------------------
       
   367 void CPcsAlgorithm2MultiSearchHelper::ConvertQueryToListL(RPointerArray<CPsQuery>& aSearchQuery, 
       
   368                                                           RPointerArray<HBufC>& aQueryList)
       
   369     {
       
   370     for (int queryIndex = 0; queryIndex < aSearchQuery.Count(); queryIndex++)
       
   371         {
       
   372         CPsQuery* query = aSearchQuery[queryIndex];
       
   373 
       
   374         HBufC* tmpSearchQuery = HBufC::NewL(KPsQueryMaxLen);
       
   375         TPtr ptr = tmpSearchQuery->Des();
       
   376 
       
   377         if (query->KeyboardModeL() == EItut) // ITU
       
   378             {
       
   379             keyMap->GetNumericKeyString(query->QueryAsStringLC(), ptr);
       
   380             CleanupStack::PopAndDestroy();
       
   381             }
       
   382         else if (query->KeyboardModeL() == EQwerty) // QWERTY
       
   383             {
       
   384             ptr = query->QueryAsStringLC();
       
   385             ptr.LowerCase();
       
   386             CleanupStack::PopAndDestroy();
       
   387             }
       
   388         else // UNDEFINED
       
   389             {
       
   390             ExtractQueryL(*query, ptr);
       
   391             ptr.LowerCase();
       
   392             }
       
   393         aQueryList.Append(tmpSearchQuery);
       
   394         }
       
   395     }
       
   396 
       
   397 // ----------------------------------------------------------------------------
       
   398 // CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL
       
   399 // Converts the input data to the key board mode specified by the query
       
   400 // ----------------------------------------------------------------------------
       
   401 void CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL(CPsQuery* aQuery, 
       
   402                                                                   TPtrC aInputData, 
       
   403                                                                   TBuf<KPsQueryMaxLen>& aOutputData)
       
   404     {
       
   405     if (aQuery->KeyboardModeL() == EItut)
       
   406         {
       
   407         keyMap->GetNumericKeyString(aInputData, aOutputData);
       
   408         }
       
   409     else if (aQuery->KeyboardModeL() == EQwerty)
       
   410         {
       
   411         aOutputData = aInputData;
       
   412         aOutputData.LowerCase();
       
   413         }
       
   414     else
       
   415         {
       
   416         ExtractQueryL(aInputData, *aQuery, aOutputData);
       
   417         aOutputData.LowerCase();
       
   418         }
       
   419     }
       
   420 
       
   421 // ----------------------------------------------------------------------------
       
   422 // CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL
       
   423 // Subset search function. Refer the above function for more description.
       
   424 // ----------------------------------------------------------------------------
       
   425 void CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
       
   426                                                           RPointerArray<CPcsPoolElement>& searchSet,
       
   427                                                           RPointerArray<CPsQuery>& searchQuery, 
       
   428                                                           TUint8 aFilteredDataMatch,
       
   429                                                           TBool isSearchInGroup, 
       
   430                                                           RArray<TInt>& aContactsInGroup,
       
   431                                                           TInt keyboardMode)
       
   432     {
       
   433     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
       
   434 
       
   435     // Convert the individual queries to string form
       
   436     RPointerArray<CPsQuery> mySearchQuery;
       
   437 
       
   438     // Remember a temporary copy of query list
       
   439     // Copy the content of searchQuery
       
   440     for (TInt i=0; i<searchQuery.Count(); i++)
       
   441         {
       
   442         CPsQuery* tempQuery = CPsQuery::NewL();
       
   443         iAlgorithm->FindUtilECE()->GetPartOfQueryL(*(searchQuery[i]), 0, 
       
   444                                                    searchQuery[i]->Count()-1, *tempQuery);
       
   445         mySearchQuery.Append(tempQuery);
       
   446         }
       
   447 
       
   448     // Sort the query items according to the length of each query 
       
   449     TLinearOrder<CPsQuery> rule(Compare4);
       
   450     mySearchQuery.Sort(rule);
       
   451 
       
   452     // To hold the match results
       
   453     RPointerArray<TDesC> tmpMatchSet;
       
   454 
       
   455     // Parse thru each search set elements and filter the results    
       
   456     for (int index = 0; index < searchSet.Count(); index++)
       
   457         {
       
   458         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
       
   459         CPsData* psData = poolElement->GetPsData();
   317         CPsData* psData = poolElement->GetPsData();
   460         psData->ClearDataMatches();
   318         psData->ClearDataMatches();
   461 
   319 
       
   320         // Skip the contact if we are doing a group search and contact doesn't belong to the group
       
   321         if ( aIsSearchInGroup && 
       
   322              aContactsInGroup.Find( psData->Id() ) == KErrNotFound )
       
   323             {
       
   324             continue;
       
   325             }
       
   326         
   462         TBool isMatch = ETrue;
   327         TBool isMatch = ETrue;
   463         TUint8 wordMatches = 0;
   328         TInt wordMatches = 0;
   464 
   329 
   465         // Reset iWordMatches to zero 
   330         // Reset iWordMatches to zero 
   466         ClearWordMatches();
   331         ClearWordMatches();
   467 
   332 
   468         // Check for each query atleast one data element matches
   333         // Check for each query atleast one data element matches
   469         // Loop from the last query so that longest match is seen first
   334         // Loop from the last query so that longest match is seen first
   470         for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--)            
   335         for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--)
   471             {
   336             {
   472             TBool queryMatch = EFalse;
   337             TBool queryMatch = EFalse;
   473             CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
   338             CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
   474 
   339 
   475             for (TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++)
   340             const TInt dataElementCount = psData->DataElementCount();
       
   341             for (TInt dataIndex = 0; dataIndex < dataElementCount; dataIndex++)
   476                 {
   342                 {
   477                 // Filter off data fields not required in search
   343                 // Filter off data fields not required in search
   478                 TReal bitIndex;
   344                 TUint8 bitIndex = 1 << dataIndex;
   479                 Math::Pow(bitIndex, 2, dataIndex);
   345                 TUint8 filter = bitIndex & aFilteredDataMatch;
   480 
   346                 
   481                 TUint8 filter = (TUint8) bitIndex & aFilteredDataMatch;
   347                 // Omit the data fields which is not required in search
   482                 if (filter == 0x0)
   348                 // or not matched with the pool element
       
   349                 if ( filter == 0x0 ) 
   483                     {
   350                     {
   484                     // Move to next data
   351                     // Move to next data
   485                     continue;
   352                     continue;
   486                     }
   353                     }
   487 
   354 
   495                 // Search thru multiple words
   362                 // Search thru multiple words
   496                 while (tmpData.Length() != 0)
   363                 while (tmpData.Length() != 0)
   497                     {
   364                     {
   498                     wordIndex++;
   365                     wordIndex++;
   499                     
   366                     
   500                     TPtrC queryPtr = tmpPsQuery->QueryAsStringLC();
   367                     // Compare the data against query
   501                     TBool matched = EFalse;
   368                     TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery);
   502                     
   369                     
   503                     if (keyboardMode == EModeUndefined)
       
   504                         {
       
   505                         matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery);
       
   506                         }
       
   507                     else if (keyboardMode == EItut)
       
   508                         {
       
   509                         matched = iAlgorithm->FindUtil()->Interface()->
       
   510                                   MatchRefineL(tmpData, queryPtr, ECustomConverter, iAlgorithm);
       
   511                         }
       
   512                     else // Qwerty
       
   513                         {
       
   514                         matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(tmpData, queryPtr);
       
   515                         
       
   516                         }
       
   517                     
       
   518                     CleanupStack::PopAndDestroy(); // queryPtr
       
   519                     
       
   520                     // Compare the data against query
       
   521                     if (matched)
   370                     if (matched)
   522                         {
   371                         {
   523                         psData->SetDataMatch(dataIndex);
   372                         psData->SetDataMatch(dataIndex);
   524 
   373 
   525                         // Perform two checks.
   374                         // Perform two checks.
   538                                 SetWordMap(dataIndex, wordIndex);
   387                                 SetWordMap(dataIndex, wordIndex);
   539                                 }
   388                                 }
   540 
   389 
   541                             // Extract matched character sequence and fill in temp array
   390                             // Extract matched character sequence and fill in temp array
   542                             TInt len = tmpPsQuery->Count();
   391                             TInt len = tmpPsQuery->Count();
   543                             if (iAlgorithm->FindUtilECE()->IsChineseWord(tmpData))
   392                             if (iAlgorithm->FindUtilECE()->IsChineseWordIncluded(tmpData))
   544                                 {
   393                                 {
   545                                 len = 1;
   394                                 len = 1;
   546                                 }
   395                                 }
   547 
   396 
   548                             HBufC* seq = HBufC::NewL(len);
   397                             TPtrC seq = tmpData.Left(len);
   549                             *seq = tmpData.Mid(0, len);
   398                             CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet, seq );
   550 
   399                             
   551                             seq->Des().UpperCase();
   400                             // TODO: Match seqs could be extracted from actual
   552                             TIdentityRelation<TDesC> searchRule(Compare3);
   401                             //       match locations by using the other overload of
   553                             if (tmpMatchSet.Find(seq, searchRule) == KErrNotFound)
   402                             //       CFindUtilChineseECE::MatchRefineL().
   554                                 {
   403                             //       Currently, match seq data is not used by clients.
   555                                 tmpMatchSet.Append(seq);
       
   556                                 }
       
   557                             else
       
   558                                 {
       
   559                                 delete seq;
       
   560                                 seq = NULL;
       
   561                                 }
       
   562                             }
   404                             }
   563                         }
   405                         }
   564 
   406 
   565                     // Next word
   407                     // Next word
   566                     tmpData.Set(lex.NextToken());
   408                     tmpData.Set(lex.NextToken());
   572                 {
   414                 {
   573                 isMatch = EFalse;
   415                 isMatch = EFalse;
   574                 break;
   416                 break;
   575                 }
   417                 }
   576             }
   418             }
       
   419         
   577 
   420 
   578         // If match add the element to the result set
   421         // If match add the element to the result set
   579         //  And before adding to the result set, check if there is atleast one match per query
   422         //  And before adding to the result set, check if there is atleast one match per query
   580         if ((isMatch) && (wordMatches >= mySearchQuery.Count()))
   423         if ( isMatch && wordMatches >= mySearchQuery.Count() )
   581             {
   424             {
   582             if (isSearchInGroup)
   425             aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
   583                 {
   426             maxcount++;
   584                 if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
   427             }
   585                     {
   428         
   586                     aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
   429         if ( iMaxCount != -1 && maxcount > iMaxCount )
   587                     }
   430             {
   588                 }
   431             break;
   589             else
   432             }
   590                 {
   433         
   591                 aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
       
   592                 }
       
   593             }
       
   594 
       
   595         // Cleanup the match sequence array as 
   434         // Cleanup the match sequence array as 
   596         // they are stored in pattern details structure
   435         // they are stored in pattern details structure
   597         tmpMatchSet.ResetAndDestroy();
   436         tmpMatchSet.ResetAndDestroy();
   598         }
   437         }
   599 
   438 
   600     mySearchQuery.Reset();
   439     CleanupStack::PopAndDestroy( &tmpMatchSet );   // ResetAndDestroy
       
   440     CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy
       
   441 
       
   442     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
   601 
   443 
   602     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
   444     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
   603     }
   445     }
   604 
   446 
   605 // ----------------------------------------------------------------------------
   447 // ----------------------------------------------------------------------------
   606 // CPcsAlgorithm2MultiSearchHelper::SetWordMap()
   448 // CPcsAlgorithm2MultiSearchHelper::SetWordMap
   607 // ----------------------------------------------------------------------------
   449 // ----------------------------------------------------------------------------
   608 void CPcsAlgorithm2MultiSearchHelper::SetWordMap(TInt aIndex, TInt aPosition)
   450 void CPcsAlgorithm2MultiSearchHelper::SetWordMap(TInt aIndex, TInt aPosition)
   609     {
   451     {
   610     TReal val;
   452     TUint8 val = 1 << aPosition;
   611     Math::Pow(val, 2, aPosition);
   453     iWordMatches[aIndex] |= val;
   612 
   454     }
   613     iWordMatches[aIndex] |= (TUint8) val;
   455 
   614     }
   456 // ----------------------------------------------------------------------------
   615 
   457 // CPcsAlgorithm2MultiSearchHelper::IsWordMatch
   616 // ----------------------------------------------------------------------------
       
   617 // CPcsAlgorithm2MultiSearchHelper::IsWordMatch()
       
   618 // ----------------------------------------------------------------------------
   458 // ----------------------------------------------------------------------------
   619 TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex)
   459 TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex)
   620     {
   460     {
   621     TReal val;
   461     TUint8 val = 1 << aWordIndex;
   622     Math::Pow(val, 2, aWordIndex);
   462     return (iWordMatches[aDataIndex] & val);
   623 
       
   624     return (iWordMatches[aDataIndex] & (TUint8) val);
       
   625     }
       
   626 
       
   627 // ----------------------------------------------------------------------------
       
   628 // CPcsAlgorithm2MultiSearchHelper::ExtractQueryL()
       
   629 // Extracts the query as a string. If the mode of query item is ITU numeric
       
   630 // character is used. Else the character is used.
       
   631 // ----------------------------------------------------------------------------
       
   632 void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(CPsQuery& aQuery, TDes& aOutput)
       
   633     {
       
   634     for (int i = 0; i < aQuery.Count(); i++)
       
   635         {
       
   636         if (aQuery.GetItemAtL(i).Mode() == EItut)
       
   637             {
       
   638             TBuf<KPsQueryMaxLen> outBuf;
       
   639             keyMap->GetNumericKeyString(aQuery.QueryAsStringLC(), outBuf);
       
   640             aOutput.Append(outBuf[i]);
       
   641             CleanupStack::PopAndDestroy();
       
   642             }
       
   643         else
       
   644             {
       
   645             aOutput.Append(aQuery.GetItemAtL(i).Character());
       
   646             }
       
   647         }
       
   648     }
       
   649 
       
   650 // ----------------------------------------------------------------------------
       
   651 // CPcsAlgorithm2MultiSearchHelper::ExtractQueryL()
       
   652 // Converts the input data refering the modes in the query.
       
   653 // If the mode of query item is ITU numeric character is used. Else the character
       
   654 // is used.
       
   655 // ----------------------------------------------------------------------------
       
   656 void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(TDesC& aInput, CPsQuery& aQuery, TDes& aOutput)
       
   657     {
       
   658     TInt len = -1;
       
   659 
       
   660     // Always loop thru the lowest length
       
   661     if (aInput.Length() > aQuery.Count())
       
   662         {
       
   663         len = aQuery.Count();
       
   664         }
       
   665     else
       
   666         {
       
   667         len = aInput.Length();
       
   668         }
       
   669 
       
   670     for (int i = 0; i < len; i++)
       
   671         {
       
   672         if (aQuery.GetItemAtL(i).Mode() == EItut)
       
   673             {
       
   674             TBuf<KPsQueryMaxLen> outBuf;
       
   675             keyMap->GetNumericKeyString(aInput, outBuf);
       
   676             aOutput.Append(outBuf[i]);
       
   677             }
       
   678         else
       
   679             {
       
   680             aOutput.Append(aInput[i]);
       
   681             }
       
   682         }
       
   683     }
   463     }
   684 
   464 
   685 // ----------------------------------------------------------------------------
   465 // ----------------------------------------------------------------------------
   686 // CPcsAlgorithm2MultiSearchHelper::BitsSet32
   466 // CPcsAlgorithm2MultiSearchHelper::BitsSet32
   687 // Helper funtion to count the number of bits set
   467 // Helper funtion to count the number of bits set
   697 
   477 
   698     return count;
   478     return count;
   699     }
   479     }
   700 
   480 
   701 // ----------------------------------------------------------------------------
   481 // ----------------------------------------------------------------------------
   702 // CPcsAlgorithm2MultiSearchHelper::BitsSet32
   482 // CPcsAlgorithm2MultiSearchHelper::ClearWordMatches
   703 // Function to reset the iWordMatches
   483 // Function to reset the iWordMatches
   704 // ----------------------------------------------------------------------------
   484 // ----------------------------------------------------------------------------
   705 void CPcsAlgorithm2MultiSearchHelper::ClearWordMatches()
   485 void CPcsAlgorithm2MultiSearchHelper::ClearWordMatches()
   706     {
   486     {
   707     for (TInt i = 0; i < MAX_DATA_FIELDS; i++)
   487     for (TInt i = 0; i < MAX_DATA_FIELDS; i++)
   727         // Skip separators before next word	                
   507         // Skip separators before next word	                
   728         if (!aQuery.GetItemAtL(beg).Character().IsSpace())
   508         if (!aQuery.GetItemAtL(beg).Character().IsSpace())
   729             {
   509             {
   730             // Scan the end of the word
   510             // Scan the end of the word
   731             TInt end = beg;
   511             TInt end = beg;
   732             for (; end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace(); ++end)
   512             while ( end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace() )
   733                 {
   513                 {
       
   514                 end++;
   734                 }
   515                 }
   735 
   516 
   736             // Create a new query object and append
   517             // Create a new query object and append
   737             CPsQuery* newQuery = CPsQuery::NewL();
   518             CPsQuery* newQuery = CPsQuery::NewL();
   738             for (int i = beg; i < end; i++)
   519             for (TInt i = beg; i < end; i++)
   739                 {
   520                 {
   740                 CPsQueryItem* item = CPsQueryItem::NewL();
   521                 CPsQueryItem* item = CPsQueryItem::NewL();
   741                 item->SetCharacter(aQuery.GetItemAtL(i).Character());
   522                 item->SetCharacter(aQuery.GetItemAtL(i).Character());
   742                 item->SetMode(aQuery.GetItemAtL(i).Mode());
   523                 item->SetMode(aQuery.GetItemAtL(i).Mode());
   743                 newQuery->AppendL(*item);
   524                 newQuery->AppendL(*item);
   750         }
   531         }
   751 
   532 
   752     return query;
   533     return query;
   753     }
   534     }
   754 
   535 
   755 // ----------------------------------------------------------------------------
       
   756 // CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL()
       
   757 // Constructs a bit pattern using the required/supported data fields
       
   758 // For example, 6, 4 and 27 are supported fields <-- 00000111
       
   759 //              6 and 4 are required fields      <-- 00000011
       
   760 // Bit pattern returned is 00000011.
       
   761 // ----------------------------------------------------------------------------
       
   762 TUint8 CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL(RArray<TInt>& aRequiredDataFields, 
       
   763                                                           RArray<TInt>& aSupportedDataFields)
       
   764     {
       
   765     TUint8 filteredMatch = 0x0;
       
   766 
       
   767     for (int i = 0; i < aSupportedDataFields.Count(); i++)
       
   768         {
       
   769         for (int j = 0; j < aRequiredDataFields.Count(); j++)
       
   770             {
       
   771             if (aSupportedDataFields[i] == aRequiredDataFields[j])
       
   772                 {
       
   773                 TReal val;
       
   774                 Math::Pow(val, 2, i);
       
   775 
       
   776                 filteredMatch |= (TUint8) val;
       
   777                 }
       
   778             }
       
   779         }
       
   780 
       
   781     return filteredMatch;
       
   782     }
       
   783 
       
   784 // End of file
   536 // End of file
   785 
   537 
   786 
   538