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 |
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 |