predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2Utils.cpp
branchRCL_3
changeset 85 38bb213f60ba
parent 68 9da50d567e3c
equal deleted inserted replaced
74:6b5524b4f673 85:38bb213f60ba
    16 */
    16 */
    17 
    17 
    18 // INCLUDES
    18 // INCLUDES
    19 #include "CPcsAlgorithm2Utils.h"
    19 #include "CPcsAlgorithm2Utils.h"
    20 #include "CPsData.h"
    20 #include "CPsData.h"
    21 #include "CPsQuery.h"
       
    22 #include "CPcsDefs.h"
    21 #include "CPcsDefs.h"
    23 #include "CPcsCache.h"
    22 #include "CPcsCache.h"
    24 #include <collate.h>
    23 #include <collate.h>
    25 // CONSTANTS
    24 // CONSTANTS
    26 _LIT(KSpace, ' ');
    25 _LIT(KSpace, ' ');
    32 // ----------------------------------------------------------------------------
    31 // ----------------------------------------------------------------------------
    33 // CPcsAlgorithm2Utils::FormCompleteSearchResultsL()
    32 // CPcsAlgorithm2Utils::FormCompleteSearchResultsL()
    34 // Merges all the respective data store result sets to single set in sorted order.
    33 // Merges all the respective data store result sets to single set in sorted order.
    35 // ----------------------------------------------------------------------------
    34 // ----------------------------------------------------------------------------
    36 void CPcsAlgorithm2Utils::FormCompleteSearchResultsL(RPointerArray<CPSDATA_R_PTR_ARRAY>& aSearchResultsArr,
    35 void CPcsAlgorithm2Utils::FormCompleteSearchResultsL(RPointerArray<CPSDATA_R_PTR_ARRAY>& aSearchResultsArr,
    37                                                      RPointerArray<CPsData>& aSearchResults)
    36                                                      RPointerArray<CPsData>& SearchResults)
    38     {
    37     {
       
    38     CleanupClosePushL( SearchResults );
       
    39     
    39     TInt maxIndex = 0;
    40     TInt maxIndex = 0;
    40     TInt maxValue = aSearchResultsArr[maxIndex]->Count();
    41     TInt maxValue = aSearchResultsArr[maxIndex]->Count();
    41     TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrderL);
    42     TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrder);
    42 
    43 
    43     // Find the largest array in aSearchResultsArr
    44     // Find the largest array in aSearchResultsArr
    44     const TInt searchResultsArrCount = aSearchResultsArr.Count(); 
    45     for (TInt i = 1; i < aSearchResultsArr.Count(); i++)
    45     for (TInt i = 1; i < searchResultsArrCount; i++)
       
    46         {
    46         {
    47         if (aSearchResultsArr[i]->Count() > maxValue)
    47         if (aSearchResultsArr[i]->Count() > maxValue)
    48             {
    48             {
    49             maxIndex = i;
    49             maxIndex = i;
    50             maxValue = aSearchResultsArr[i]->Count();
    50             maxValue = aSearchResultsArr[i]->Count();
    51             }
    51             }
    52         }
    52         }
    53 
    53 
    54     // Assign the largets array to searchresults 
    54     // Assign the largets array to searchresults 
    55     const TInt cnt = aSearchResultsArr[maxIndex]->Count();
    55     for (TInt i = 0; i < aSearchResultsArr[maxIndex]->Count(); i++)
    56     for (TInt i = 0; i < cnt; i++)
    56         {
    57         {
    57         SearchResults.Append((*(aSearchResultsArr[maxIndex]))[i]);
    58         aSearchResults.Append((*(aSearchResultsArr[maxIndex]))[i]);
       
    59         }
    58         }
    60 
    59 
    61     // Merge the remaining result arrays to the largest array in sequential order
    60     // Merge the remaining result arrays to the largest array in sequential order
    62 
    61     for (TInt i = 0; i < aSearchResultsArr.Count(); i++)
    63     for (TInt i = 0; i < searchResultsArrCount; i++)
       
    64         {
    62         {
    65         // Check if we are not copying again the largest array
    63         // Check if we are not copying again the largest array
    66         if ((i != maxIndex) && ((aSearchResultsArr[i])->Count() != 0))
    64         if ((i != maxIndex) && ((aSearchResultsArr[i])->Count() != 0))
    67             {
    65             {
    68             TInt numElements = (aSearchResultsArr[i])->Count();
    66             TInt numElements = (aSearchResultsArr[i])->Count();
    69             for (TInt j = 0; j < numElements; j++)
    67             for (TInt j = 0; j < numElements; j++)
    70                 {
    68                 {
    71                 aSearchResults.InsertInOrderAllowRepeatsL((*(aSearchResultsArr[i]))[j], rule);
    69                 SearchResults.InsertInOrderAllowRepeatsL((*(aSearchResultsArr[i]))[j], rule);
    72                 }
    70                 }
    73             }
    71             }
    74         }
    72         }
       
    73     CleanupStack::Pop();
    75     }
    74     }
    76 
    75 
    77 // ----------------------------------------------------------------------------
    76 // ----------------------------------------------------------------------------
    78 // CPcsAlgorithm2Utils::MyCompareC()
    77 // CPcsAlgorithm2Utils::MyCompareC()
    79 // Lang specific MyCompareC
    78 // Lang specific MyCompareC
    97     TInt comparison(aLeft.CompareC(aRight, 3, &meth));
    96     TInt comparison(aLeft.CompareC(aRight, 3, &meth));
    98     return comparison;
    97     return comparison;
    99     }
    98     }
   100 
    99 
   101 // ----------------------------------------------------------------------------
   100 // ----------------------------------------------------------------------------
   102 // CPcsAlgorithm2Utils::CompareDataBySortOrderL()
   101 // CPcsAlgorithm2Utils::CompareDataBySortOrder()
   103 // TLinearOrder rule for comparison of data objects
   102 // TLinearOrder rule for comparison of data objects
   104 // ----------------------------------------------------------------------------
   103 // ----------------------------------------------------------------------------
   105 TInt CPcsAlgorithm2Utils::CompareDataBySortOrderL(const CPsData& aObject1,
   104 TInt CPcsAlgorithm2Utils::CompareDataBySortOrder(const CPsData& aObject1,
   106                                                   const CPsData& aObject2)
   105                                                  const CPsData& aObject2)
   107     {
   106     {
   108     TInt compareRes = 0;
   107     _LIT(KSpace, " ");
   109 
       
   110     if( CPsData::CompareById(aObject1, aObject2) )
       
   111         {
       
   112         return compareRes;
       
   113         }
       
   114 
   108 
   115     // Fetch the cache list stored in TLS to recover the sort order
   109     // Fetch the cache list stored in TLS to recover the sort order
   116     typedef RPointerArray<CPcsCache> PTR;
   110     typedef RPointerArray<CPcsCache> PTR;
   117     PTR* pcsCache = static_cast<PTR*>(Dll::Tls());
   111     PTR* pcsCache = static_cast<PTR*> (Dll::Tls());
   118     User::LeaveIfNull(pcsCache);
   112 
   119 
   113     // Data1
   120     CPcsCache* cache1 = (*pcsCache)[aObject1.UriId()];
   114     TBuf<255> data1(KNullDesC);
   121     CPcsCache* cache2 = (*pcsCache)[aObject2.UriId()];
   115     TInt uriId1 = aObject1.UriId();
   122     RArray<TInt> indexOrder1;
   116     CPcsCache* cache = (*pcsCache)[uriId1];
   123     RArray<TInt> indexOrder2;
   117 
       
   118     RArray<TInt> indexOrder;
   124 
   119 
   125     // Get the index order based on sort order from the cache
   120     // Get the index order based on sort order from the cache
   126     cache1->GetIndexOrder(indexOrder1);
   121     cache->GetIndexOrder(indexOrder);
   127     CleanupClosePushL(indexOrder1);
   122 
   128     cache2->GetIndexOrder(indexOrder2);
   123     // Append sort order elements first
   129     CleanupClosePushL(indexOrder2);
   124     for (int i = 0; i < indexOrder.Count(); i++)
   130 
   125         {
   131     // Check if Sort Order is identical (it must be for same cache)
   126         TInt index = indexOrder[i];
   132     TBool sameIndexOrder = ETrue;
   127         if (index < aObject1.DataElementCount() && aObject1.Data(index))
   133     if ( indexOrder1.Count() != indexOrder2.Count() )
   128             {
   134         {
   129             // Trim the unnecessary white spaces/special chars before we compare
   135         sameIndexOrder = EFalse;
   130             TBuf<255> str(KNullDesC);
   136         }
   131 
   137     else
   132             str = aObject1.Data(index)->Des();
   138         {
   133             CPcsAlgorithm2Utils::MyTrim(str);
   139         for ( TInt i = 0; i < indexOrder1.Count(); i++ )
   134 
   140             {
   135             data1 += str;
   141             if (indexOrder1[i] != indexOrder2[i])
   136             data1 += KSpace;
   142                 {
   137             }
   143                 sameIndexOrder = EFalse;
   138         }
   144                 break;
   139 
   145                 }
   140     /* --- NOT SURE IF THIS BEHAVIOR IS REQUIRED ---
   146             }
   141      // Append remaining elements in order
   147         }
   142      for ( int i = 0; i < aObject1.DataElementCount(); i++ )
   148 
   143      {
   149     // Sort Orders among diffent caches should be the same, anyway
   144      if ( indexOrder.Find(i) == KErrNone && aObject1.Data(i) )
   150     // if caches and SO are different we compare by cache URI index
   145      {
   151     if (!sameIndexOrder)
   146      data1 += aObject1.Data(i)->Des();
   152         {
   147      data1 += KSpace;
   153         compareRes = aObject1.UriId() - aObject2.UriId();
   148      }	     
   154 
   149      }
   155         CleanupStack::PopAndDestroy(&indexOrder2);
   150      */
   156         CleanupStack::PopAndDestroy(&indexOrder1);
   151 
   157         return compareRes;
   152     // Data2
   158         }
   153     TBuf<255> data2(KNullDesC);
   159 
   154     TInt uriId2 = aObject2.UriId();
   160     // The comparison between contacts data is done for the sort order
   155     cache = (*pcsCache)[uriId2];
   161     // fields skipping the ones that are empty
   156 
   162     TInt indexCount = indexOrder1.Count();
   157     indexOrder.Reset();
   163     TInt idx1 = 0;
   158 
   164     TInt idx2 = 0;
   159     // Get the index order based on sort order from the cache
   165     while ( compareRes == 0 && idx1 < indexCount && idx2 < indexCount )
   160     cache->GetIndexOrder(indexOrder);
   166         {
   161 
   167         // Get contact field of 1st contact
   162     // Append sort order elements first
   168         TInt object1Idx = indexOrder1[idx1];
   163     for (int i = 0; i < indexOrder.Count(); i++)
   169         HBufC* strCompare1 = aObject1.Data(object1Idx)->Des().AllocLC();
   164         {
   170         TPtr strCompare1Ptr( strCompare1->Des() );
   165         TInt index = indexOrder[i];
   171         CPcsAlgorithm2Utils::MyTrim( strCompare1Ptr );
   166         if (index < aObject2.DataElementCount() && aObject2.Data(index))
   172 
   167             {
   173         // Get contact field of 2nd contact
   168             // Trim the unnecessary white spaces/special chars before we compare
   174         TInt object2Idx = indexOrder2[idx2];
   169             TBuf<255> str(KNullDesC);
   175         HBufC* strCompare2 = aObject2.Data(object2Idx)->Des().AllocLC();
   170 
   176         TPtr strCompare2Ptr( strCompare2->Des() );
   171             str = aObject2.Data(index)->Des();
   177         CPcsAlgorithm2Utils::MyTrim( strCompare2Ptr );
   172             CPcsAlgorithm2Utils::MyTrim(str);
   178 
   173 
   179         if ( strCompare1->Length() > 0 && strCompare2->Length() > 0 )
   174             data2 += str;
   180             {
   175             data2 += KSpace;
   181             compareRes = CPcsAlgorithm2Utils::MyCompareC(*strCompare1, *strCompare2);
   176             }
   182             idx1++;
   177         }
   183             idx2++;
   178 
   184             }
   179     /* --- NOT SURE IF THIS BEHAVIOR IS REQUIRED ---
   185         else // Increment only the index of the contact with empty field
   180      // Append remaining elements in order
   186             {
   181      for ( int i = 0; i < aObject2.DataElementCount(); i++ )
   187             if ( strCompare1->Length() == 0 )
   182      {
   188                 idx1++;
   183      if ( indexOrder.Find(i) == KErrNone && aObject2.Data(i) )
   189             if ( strCompare2->Length() == 0 )
   184      {
   190                 idx2++;
   185      data2 += aObject2.Data(i)->Des();
   191             }
   186      data2 += KSpace;
   192 
   187      }	     
   193         CleanupStack::PopAndDestroy(strCompare2);
   188      }
   194         CleanupStack::PopAndDestroy(strCompare1);
   189      */
   195         }
   190 
   196 
   191     indexOrder.Reset();
   197     // We do not return that contacts are equal by SO
   192     data1.TrimAll();
   198     if ( compareRes == 0 )
   193     data2.TrimAll();
   199         {
   194     return (CPcsAlgorithm2Utils::MyCompareC(data1, data2));
   200         if ( idx1 != idx2 )
       
   201             {
       
   202             // Compare by index position
       
   203             // If idx1 > idx2 and SO is "FN LN" it means for instance that:
       
   204             //     Contact1=[FN:"",      LN:"Smith"],  idx1=2
       
   205             //     Contact2=[FN:"Smith", LN:"Donald"], idx2=1
       
   206             // Therefore Contact1="Smith" is < than Contact2="Smith Donald"
       
   207             // and the return value of this method has to be < 0 (idx2-idx1)
       
   208 
       
   209             compareRes = idx2 - idx1;
       
   210             }
       
   211         else
       
   212             {
       
   213             // Compare by URI ID as 1st choice and Contact ID as 2nd choice
       
   214 
       
   215             compareRes == ( aObject1.UriId() != aObject2.UriId() ) ?
       
   216                 aObject1.UriId() - aObject2.UriId() : aObject1.Id() - aObject2.Id();
       
   217             }
       
   218         }
       
   219 
       
   220     CleanupStack::PopAndDestroy(&indexOrder2);
       
   221     CleanupStack::PopAndDestroy(&indexOrder1);
       
   222 
       
   223     return compareRes;
       
   224     }
       
   225 
       
   226 // ----------------------------------------------------------------------------
       
   227 // CPcsAlgorithm2Utils::CompareExact()
       
   228 // 
       
   229 // ----------------------------------------------------------------------------
       
   230 TBool CPcsAlgorithm2Utils::CompareExact(const TDesC& aFirst, const TDesC& aSecond)
       
   231     {
       
   232     return aFirst == aSecond;
       
   233     }
       
   234 
       
   235 // ----------------------------------------------------------------------------
       
   236 // CPcsAlgorithm2Utils::CompareLength()
       
   237 // 
       
   238 // ----------------------------------------------------------------------------
       
   239 TInt CPcsAlgorithm2Utils::CompareLength(const CPsQuery& aFirst, const CPsQuery& aSecond)
       
   240     {
       
   241     CPsQuery& first = const_cast<CPsQuery&> (aFirst);
       
   242     CPsQuery& second = const_cast<CPsQuery&> (aSecond);
       
   243     
       
   244     return (first.Count() - second.Count());
       
   245     }
   195     }
   246 
   196 
   247 // ----------------------------------------------------------------------------
   197 // ----------------------------------------------------------------------------
   248 // CPcsAlgorithm2Utils::MyTrim()
   198 // CPcsAlgorithm2Utils::MyTrim()
   249 // Trim off all white spaces and special characters
   199 // Trim off all white spaces and special characters
   281         }
   231         }
   282 
   232 
   283     return ETrue;
   233     return ETrue;
   284     }
   234     }
   285 
   235 
   286 // ----------------------------------------------------------------------------
       
   287 // CPcsAlgorithm1Helper::FilterDataFieldsL()
       
   288 // Constructs a bit pattern using the required/supported data fields
       
   289 // For example, 6, 4 and 27 are supported fields <-- 00000111
       
   290 //              6 and 4 are required fields      <-- 00000011
       
   291 // Bit pattern returned is 00000011.
       
   292 // ----------------------------------------------------------------------------
       
   293 TUint8 CPcsAlgorithm2Utils::FilterDataFieldsL(const RArray<TInt>& aRequiredDataFields,
       
   294                                               const RArray<TInt>& aSupportedDataFields)
       
   295 {
       
   296     TUint8 filteredMatch = 0x0;
       
   297    const TInt supportedDataFieldsCount = aSupportedDataFields.Count();
       
   298    const TInt requiredDataFieldsCount = aRequiredDataFields.Count(); 
       
   299     for ( TInt i = 0; i < supportedDataFieldsCount; i++ )
       
   300     {
       
   301         for ( TInt j = 0; j < requiredDataFieldsCount; j++ )
       
   302         {
       
   303             if ( aSupportedDataFields[i] == aRequiredDataFields[j] )
       
   304             {
       
   305                 TUint8 val = 1 << i;
       
   306                 filteredMatch |= val;
       
   307             }
       
   308         }
       
   309     }
       
   310 
       
   311     return filteredMatch;
       
   312 }
       
   313 
       
   314 // ----------------------------------------------------------------------------
       
   315 // CPcsAlgorithm2Utils::AppendMatchToSeqL
       
   316 // ----------------------------------------------------------------------------
       
   317 void CPcsAlgorithm2Utils::AppendMatchToSeqL( 
       
   318         RPointerArray<TDesC>& aMatchSeq, const TDesC& aMatch )
       
   319     {
       
   320     HBufC* seq = aMatch.AllocLC();
       
   321     seq->Des().UpperCase();
       
   322     TIdentityRelation<TDesC> rule(CompareExact);
       
   323     if ( aMatchSeq.Find(seq, rule) == KErrNotFound )
       
   324         {
       
   325         aMatchSeq.AppendL(seq);
       
   326         CleanupStack::Pop( seq );
       
   327         }
       
   328     else 
       
   329         {
       
   330         CleanupStack::PopAndDestroy( seq );
       
   331         }
       
   332     }
       
   333 
       
   334 // ----------------------------------------------------------------------------
       
   335 // CPcsAlgorithm2Utils::MatchesOverlap
       
   336 // Check if two match location items have overlapping indices.
       
   337 // ----------------------------------------------------------------------------
       
   338 TBool CPcsAlgorithm2Utils::MatchesOverlap( const TPsMatchLocation& aFirst, 
       
   339                                            const TPsMatchLocation& aSecond )
       
   340     {
       
   341     TBool overlap = EFalse;
       
   342     
       
   343     if ( aFirst.index == aSecond.index )
       
   344         {
       
   345         overlap = ETrue;
       
   346         }
       
   347     else
       
   348         {
       
   349         // give arguments alias names where first begins before the second
       
   350         TInt firstPos( aFirst.index );
       
   351         TInt firstLen( aFirst.length );
       
   352         TInt secondPos( aSecond.index );
       
   353         if ( firstPos > secondPos )
       
   354             {
       
   355             firstPos = aSecond.index;
       
   356             firstLen = aSecond.length;
       
   357             secondPos = aFirst.index;
       
   358             }
       
   359         
       
   360         // there is an overlap if the end of the first comes after
       
   361         // beginning of the second
       
   362         if ( firstPos + firstLen > secondPos )
       
   363             {
       
   364             overlap = ETrue;
       
   365             }
       
   366         }
       
   367     
       
   368     return overlap;
       
   369     }
       
   370 
       
   371 // End of File
   236 // End of File
   372 
   237