diff -r 2666d9724c76 -r d4f567ce2e7c predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsCache.cpp --- a/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsCache.cpp Thu Jul 15 18:22:55 2010 +0300 +++ b/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsCache.cpp Thu Aug 19 09:41:07 2010 +0300 @@ -22,6 +22,7 @@ // INCLUDE FILES #include +#include #include "FindUtilChineseECE.h" #include "CPsData.h" @@ -37,7 +38,7 @@ // CPcsCache::NewL // Two Phase Construction // ---------------------------------------------------------------------------- -CPcsCache* CPcsCache::NewL(CPcsAlgorithm2* aAlgorithm, TDesC& aURI, +CPcsCache* CPcsCache::NewL(CPcsAlgorithm2* aAlgorithm, const TDesC& aURI, CPcsKeyMap& aKeyMap, TUint8 aUriId) { PRINT ( _L("Enter CPcsCache::NewL") ); @@ -69,7 +70,7 @@ // CPcsCache::ConstructL // 2nd Phase Constructor // ---------------------------------------------------------------------------- -void CPcsCache::ConstructL(CPcsAlgorithm2* aAlgorithm, TDesC& aURI, +void CPcsCache::ConstructL(CPcsAlgorithm2* aAlgorithm, const TDesC& aURI, CPcsKeyMap& aKeyMap, TUint8 aUriId) { PRINT ( _L("Enter CPcsCache::ConstructL") ); @@ -80,13 +81,14 @@ //Update the caching status for this cache iCacheStatus = ECachingNotStarted; - keyMap = &aKeyMap; + iKeyMap = &aKeyMap; - // Populate keyArr - for (TInt i = 0; i < aKeyMap.PoolCount(); i++) + // Populate iKeyArr + const TInt keyMapPoolcount = aKeyMap.PoolCount(); + for (TInt i = 0; i < keyMapPoolcount; i++) { - RPointerArray *keyMap = new (ELeave) RPointerArray (1); - keyArr.InsertL(keyMap, i); + RPointerArray* keyMap = new (ELeave) RPointerArray (1); + iKeyArr.InsertL(keyMap, i); } PRINT ( _L("End CPcsCache::ConstructL") ); @@ -100,86 +102,15 @@ { PRINT ( _L("Enter CPcsCache::~CPcsCache") ); - if (iURI) - { - delete iURI; - } - - // Loop thru cache info and free and the data elements - THashMapIter iter(cacheInfo); - - do - { - TInt* id = const_cast (iter.NextKey()); - - if (id == NULL) - break; - - TInt* poolMap = iter.CurrentValue(); - - if (poolMap == NULL) - { - continue; - } - - CPsData *data = NULL; - for (int keyIndex = 0; keyIndex <= keyArr.Count(); keyIndex++) - { - TBool present = GetPoolMap(*poolMap, keyIndex); - - if (!present) - { - continue; - } + delete iURI; - RPointerArray tmpKeyMap = *(keyArr[keyIndex]); - for (int arrayIndex = 0; arrayIndex < tmpKeyMap.Count(); arrayIndex++) - { - CPcsPoolElement *element = tmpKeyMap[arrayIndex]; - TInt localId = element->GetPsData()->Id(); - if (*id == localId) - { - data = element->GetPsData(); - delete element; - keyArr[keyIndex]->Remove(arrayIndex); - } - } - }; - - // Remove this element from master pool - for (int arrayIndex = 0; arrayIndex < masterPool.Count(); arrayIndex++) - { - CPsData *dataElement = masterPool[arrayIndex]; - TInt localId = dataElement->Id(); - if (*id == localId) - { - masterPool.Remove(arrayIndex); - } - } - - if (data) - { - delete data; - } - - } - while (1); - - for (TInt i = 0; i < keyArr.Count(); i++) - { - keyArr[i]->ResetAndDestroy(); - delete keyArr[i]; - keyArr[i] = NULL; - } - - masterPool.ResetAndDestroy(); - - cacheInfo.Close(); - - keyArr.Reset(); + RemoveAllFromCache(); // cleans up iMasterPool and iCacheInfo + + iKeyArr.ResetAndDestroy(); iDataFields.Reset(); iSortOrder.Reset(); iIndexOrder.Reset(); + iMasterPoolBackup.Close(); PRINT ( _L("End CPcsCache::~CPcsCache") ); } @@ -191,15 +122,18 @@ void CPcsCache::GetContactsForKeyL(TInt aKeyId, RPointerArray& aData) { PRINT ( _L("Enter CPcsCache::GetContactsForKeyL") ); - CleanupClosePushL( aData ); - RPointerArray arr = *keyArr[aKeyId]; - for (int i = 0; i < arr.Count(); i++) + + if ( aKeyId >= 0 && aKeyId < iKeyArr.Count() ) { - CPcsPoolElement* value = arr[i]; - aData.AppendL(value); + const RPointerArray& arr = *iKeyArr[aKeyId]; + const TInt arrCount = arr.Count(); + for (TInt i = 0; i < arrCount; i++) + { + CPcsPoolElement* value = arr[i]; + aData.AppendL(value); + } } - CleanupStack::Pop(); PRINT ( _L("End CPcsCache::GetContactsForKeyL") ); } @@ -210,13 +144,14 @@ void CPcsCache::GetAllContentsL(RPointerArray& aData) { PRINT ( _L("Enter CPcsCache::GetAllContentsL") ); - CleanupClosePushL( aData ); - for (int i = 0; i < masterPool.Count(); i++) + + const TInt masterPoolCount = iMasterPool.Count(); + for (TInt i = 0; i < masterPoolCount; i++) { - CPsData* value = masterPool[i]; + CPsData* value = iMasterPool[i]; aData.AppendL(value); } - CleanupStack::Pop(); + PRINT ( _L("End CPcsCache::GetAllContentsL") ); } @@ -224,7 +159,7 @@ // CPcsCache::AddToPool // Adds a contact to cache // ---------------------------------------------------------------------------- -void CPcsCache::AddToPoolL(TInt& aPoolMap, CPsData& aData) +void CPcsCache::AddToPoolL(TUint64& aPoolMap, CPsData& aData) { // Temp hash to remember the location of pool elements // First TInt = Pool @@ -232,68 +167,43 @@ // Required for memory optimization so that more than one pool // element doesn't get added for the same data RHashMap elementHash; + CleanupClosePushL( elementHash ); TLinearOrder rule(CPcsPoolElement::CompareByData); - // Parse thru each data element - for (int dataIndex = 0; dataIndex < aData.DataElementCount(); dataIndex++) + // Parse thru each data element + const TInt dataElementCount = aData.DataElementCount(); + for (TInt dataIndex = 0; dataIndex < dataElementCount; dataIndex++) { // Stores first key for each word - RArray firstKey; + RArray firstCharArr; + CleanupClosePushL( firstCharArr ); // Recover the first character - if (aData.Data(dataIndex) && aData.Data(dataIndex)->Length() != 0) + if ( aData.Data(dataIndex) ) { - // Split the data into words - CWords* words = CWords::NewLC(*aData.Data(dataIndex)); + GetFirstCharsForDataL( *aData.Data(dataIndex), firstCharArr ); + } + + // Get the corresponding Pool IDs + RArray poolIdArr; + CleanupClosePushL( poolIdArr ); + GetPoolIdsForCharsL( firstCharArr, poolIdArr ); - // Store the first numeric key for each word - for (int i = 0; i < words->MdcaCount(); i++) - { - TChar firstChar; - for (int j = 0; j < words->MdcaPoint(i).Length(); j++) - { - firstChar = (words->MdcaPoint(i))[j]; - TBuf<20> word; - word.Append(firstChar); - if (iAlgorithm->FindUtilECE()->IsChineseWord(word)) - { - RPointerArray spellList; - if (iAlgorithm->FindUtilECE()->T9ChineseTranslationL(firstChar, spellList)) - { - for (int j = 0; j < spellList.Count(); j++) - { - firstKey.Append(keyMap->KeyForCharacter(*(spellList[j]->Ptr()))); - } - } - else - { - firstKey.Append( keyMap->KeyForCharacter(firstChar)); - } - spellList.ResetAndDestroy(); - } - else - { - firstKey.Append(keyMap->KeyForCharacter(firstChar)); - } - } - } - - CleanupStack::PopAndDestroy(words); - } - - for (TInt wordIndex = 0; wordIndex < firstKey.Count(); wordIndex++) + const TInt poolIdArrCount = poolIdArr.Count(); + for (TInt poolArrIndex = 0; poolArrIndex < poolIdArrCount ; poolArrIndex++) { - TInt arrayIndex = keyMap->PoolIdForCharacter(firstKey[wordIndex]); + + TInt poolId = poolIdArr[poolArrIndex]; CPcsPoolElement* element = NULL; // Check if an element already exists in the pool for this data TInt* loc = NULL; - loc = elementHash.Find(arrayIndex); + loc = elementHash.Find(poolId); if (loc != NULL) { // Exists. Then recover ... - RPointerArray tmpKeyMap = *(keyArr[arrayIndex]); + RPointerArray tmpKeyMap = *(iKeyArr[poolId]); element = tmpKeyMap[*loc]; } @@ -304,30 +214,31 @@ element->SetDataMatch(dataIndex); // Insert to pool - keyArr[arrayIndex]->InsertInOrderAllowRepeatsL(element, rule); - TInt index = keyArr[arrayIndex]->FindInOrderL(element, rule); + iKeyArr[poolId]->InsertInOrderAllowRepeatsL(element, rule); + TInt index = iKeyArr[poolId]->FindInOrderL(element, rule); - // Set the bit for this pool - SetPoolMap(aPoolMap, arrayIndex); + // Set the bit for this pool + SetPoolMap(aPoolMap, poolId); // Store the array index in the temp hash - elementHash.InsertL(arrayIndex, index); + elementHash.InsertL(poolId, index); } else // Pool element exists. Just alter the data match attribute { element->SetDataMatch(dataIndex); - // Set the bit for this pool - SetPoolMap(aPoolMap, arrayIndex); + // Set the bit for this pool + SetPoolMap(aPoolMap, poolId); } } // for 2 loop - firstKey.Reset(); + CleanupStack::PopAndDestroy( &poolIdArr ); // Close + CleanupStack::PopAndDestroy( &firstCharArr ); // Close } // for 1 loop - elementHash.Close(); + CleanupStack::PopAndDestroy( &elementHash ); // Close } // --------------------------------------------------------------------- @@ -337,19 +248,19 @@ void CPcsCache::AddToCacheL(CPsData& aData) { // Protect against duplicate items getting added - if (cacheInfo.Find(aData.Id()) != NULL) + if (iCacheInfo.Find(aData.Id()) != NULL) { return; } // Include this element in the pool - TInt poolMap = 0; + TUint64 poolMap = 0; AddToPoolL(poolMap, aData); - cacheInfo.InsertL(aData.Id(), poolMap); + iCacheInfo.InsertL(aData.Id(), poolMap); // Include this element in master pool TLinearOrder rule(CPcsAlgorithm2Utils::CompareDataBySortOrder); - masterPool.InsertInOrderAllowRepeatsL(&aData, rule); + iMasterPool.InsertInOrderAllowRepeatsL(&aData, rule); } // --------------------------------------------------------------------- @@ -360,7 +271,7 @@ { CPsData *data = NULL; - TInt* poolMap = cacheInfo.Find(aItemId); + TUint64* poolMap = iCacheInfo.Find(aItemId); if (poolMap == NULL) { @@ -368,7 +279,8 @@ } // Remove this element from pools - for (int keyIndex = 0; keyIndex <= keyArr.Count(); keyIndex++) + const TInt keyArrCount = iKeyArr.Count(); + for (TInt keyIndex = 0; keyIndex < keyArrCount; keyIndex++) { TBool present = GetPoolMap(*poolMap, keyIndex); @@ -377,8 +289,9 @@ continue; } - RPointerArray tmpKeyMap = *(keyArr[keyIndex]); - for (int arrayIndex = 0; arrayIndex < tmpKeyMap.Count(); arrayIndex++) + const RPointerArray& tmpKeyMap = *(iKeyArr[keyIndex]); + + for (TInt arrayIndex = 0; arrayIndex < tmpKeyMap.Count(); arrayIndex++) { CPcsPoolElement *element = tmpKeyMap[arrayIndex]; TInt id = element->GetPsData()->Id(); @@ -386,19 +299,19 @@ { data = element->GetPsData(); delete element; - keyArr[keyIndex]->Remove(arrayIndex); + iKeyArr[keyIndex]->Remove(arrayIndex); } } } // Remove this element from master pool - for (int arrayIndex = 0; arrayIndex < masterPool.Count(); arrayIndex++) + for (TInt arrayIndex = 0; arrayIndex < iMasterPool.Count(); arrayIndex++) { - CPsData *dataElement = masterPool[arrayIndex]; + CPsData *dataElement = iMasterPool[arrayIndex]; TInt id = dataElement->Id(); if (id == aItemId) { - masterPool.Remove(arrayIndex); + iMasterPool.Remove(arrayIndex); } } @@ -410,51 +323,178 @@ } // Clear up cache information - cacheInfo.Remove(aItemId); + iCacheInfo.Remove(aItemId); } // --------------------------------------------------------------------- // CPcsCache::RemoveAllFromCacheL // // --------------------------------------------------------------------- -void CPcsCache::RemoveAllFromCacheL() +void CPcsCache::RemoveAllFromCache() { - PRINT ( _L("Enter CPcsCache::RemoveAllFromCacheL") ); + PRINT ( _L("Enter CPcsCache::RemoveAllFromCache") ); - for (TInt i = 0; i < keyArr.Count(); i++) + const TInt keyArrCount = iKeyArr.Count(); + for ( TInt i = 0 ; i < keyArrCount ; i++ ) { - keyArr[i]->ResetAndDestroy(); - + iKeyArr[i]->ResetAndDestroy(); } - masterPool.ResetAndDestroy(); - cacheInfo.Close(); + iMasterPool.ResetAndDestroy(); + iCacheInfo.Close(); - PRINT ( _L("End CPcsCache::RemoveAllFromCacheL") ); + PRINT ( _L("End CPcsCache::RemoveAllFromCache") ); } // --------------------------------------------------------------------- // CPcsCache::SetPoolMap // // --------------------------------------------------------------------- -void CPcsCache::SetPoolMap(TInt& aPoolMap, TInt arrayIndex) +void CPcsCache::SetPoolMap(TUint64& aPoolMap, TInt aArrayIndex) { - TReal val; - Math::Pow(val, 2, arrayIndex); + __ASSERT_DEBUG( aArrayIndex < 64, User::Panic(_L("CPcsCache"), KErrOverflow ) ); - aPoolMap |= (TInt) val; + /* Some platforms do not support 64 bits shift operations. + * Split to two 32 bits operations. + */ + + TUint32 poolMapH = I64HIGH(aPoolMap); + TUint32 poolMapL = I64LOW(aPoolMap); + + TUint32 valH = 0; + TUint32 valL = 0; + if (aArrayIndex < 32) + { + valL = 1 << aArrayIndex; + } + else + { + valH = 1 << (aArrayIndex-32); + } + + poolMapH |= valH; + poolMapL |= valL; + + aPoolMap = MAKE_TUINT64(poolMapH, poolMapL); } // --------------------------------------------------------------------- // CPcsCache::GetPoolMap // // --------------------------------------------------------------------- -TBool CPcsCache::GetPoolMap(TInt& aPoolMap, TInt arrayIndex) +TBool CPcsCache::GetPoolMap(TUint64& aPoolMap, TInt aArrayIndex) + { + __ASSERT_DEBUG( aArrayIndex < 64, User::Panic(_L("CPcsCache"), KErrOverflow ) ); + + /* Some platforms do not support 64 bits shift operations. + * Split to two 32 bits operations. + */ + + TUint32 poolMapH = I64HIGH(aPoolMap); + TUint32 poolMapL = I64LOW(aPoolMap); + + TUint32 valH = 0; + TUint32 valL = 0; + if (aArrayIndex < 32) + { + valL = 1 << aArrayIndex; + } + else + { + valH = 1 << (aArrayIndex-32); + } + + TBool ret = (poolMapH & valH) || (poolMapL & valL); + + return (ret); + } + +// --------------------------------------------------------------------- +// CPcsCache::GetFirstCharsForDataL +// +// --------------------------------------------------------------------- +void CPcsCache::GetFirstCharsForDataL( const TDesC& aData, RArray& aFirstChars ) const { - TReal val; - Math::Pow(val, 2, arrayIndex); + // Split the data into words + CWords* words = CWords::NewLC(aData); - return (aPoolMap & (TInt) val); + // Find indexing characters for each word + for (TInt i = 0; i < words->MdcaCount(); i++) + { + TPtrC16 word = words->MdcaPoint(i); + TBool lastCharIsChinese = EFalse; + + // If the word contains any Chinese characters, then it is + // stored to cache according all the available spellings of + // all the Chinese characters + if ( iAlgorithm->FindUtilECE()->IsChineseWordIncluded(word) ) + { + const TInt wordLength = word.Length(); + for (TInt j = 0; j < wordLength; j++) + { + TText curChar = word[j]; + RPointerArray spellList; + CleanupResetAndDestroyPushL( spellList ); + if ( iAlgorithm->FindUtilECE()->DoTranslationL(curChar, spellList) ) + { + lastCharIsChinese = ETrue; + // Append first char of each spelling + const TInt spellListCount = spellList.Count(); + for (TInt k = 0; k < spellListCount; k++) + { + const HBufC* spelling = spellList[k]; + aFirstChars.AppendL( (*spelling)[0] ); + } + } + else + { + if ( lastCharIsChinese ) + { + aFirstChars.AppendL( word[j] ); + lastCharIsChinese = EFalse; + } + } + CleanupStack::PopAndDestroy( &spellList ); // ResetAndDestroy + } + } + + // If the first charcter of the word is non-Chinese, then it's stored to the + // cache according this first character. Other characters of the word may or + // may not be Chinese. + if ( !iAlgorithm->FindUtilECE()->IsChineseWordIncluded( word.Left(1) ) ) + { + aFirstChars.AppendL( word[0] ); + } + } + CleanupStack::PopAndDestroy(words); + } + +// --------------------------------------------------------------------- +// CPcsCache::GetPoolIdsForCharsL +// +// --------------------------------------------------------------------- +void CPcsCache::GetPoolIdsForCharsL( const RArray& aChars, RArray& aPoolIds ) const + { + // There can potentially be two pool IDs for each character. + // Reserve memory for this upfront to prevent unnecessary reallocations. + aPoolIds.ReserveL( aChars.Count() * 2 ); + + const TInt charsCount = aChars.Count() ; + for ( TInt i = 0 ; i < charsCount ; ++i ) + { + TChar character = aChars[i]; + TInt itutPoolId = iKeyMap->PoolIdForCharacter( character, EPredictiveItuT ); + if ( itutPoolId != KErrNotFound ) + { + aPoolIds.AppendL( itutPoolId ); + } + + TInt qwertyPoolId = iKeyMap->PoolIdForCharacter( character, EPredictiveQwerty ); + if ( qwertyPoolId != KErrNotFound ) + { + aPoolIds.AppendL( qwertyPoolId ); + } + } } // --------------------------------------------------------------------- @@ -472,7 +512,8 @@ // --------------------------------------------------------------------- void CPcsCache::SetDataFields(RArray& aDataFields) { - for (TInt i(0); i < aDataFields.Count(); i++) + const TInt dataFieldsCount = aDataFields.Count(); + for (TInt i(0); i < dataFieldsCount; i++) { iDataFields.Append(aDataFields[i]); } @@ -484,7 +525,8 @@ // --------------------------------------------------------------------- void CPcsCache::GetDataFields(RArray& aDataFields) { - for (TInt i(0); i < iDataFields.Count(); i++) + const TInt dataFieldsCount = iDataFields.Count(); + for (TInt i(0); i < dataFieldsCount; i++) { aDataFields.Append(iDataFields[i]); } @@ -535,8 +577,8 @@ PRINT ( _L("Enter CPcsCache::SetSortOrder") ); iSortOrder.Reset(); - - for (TInt i(0); i < aSortOrder.Count(); i++) + const TInt sortOrderCount = aSortOrder.Count(); + for (TInt i(0); i < sortOrderCount; i++) { iSortOrder.Append(aSortOrder[i]); } @@ -553,8 +595,8 @@ void CPcsCache::GetSortOrder(RArray& aSortOrder) { aSortOrder.Reset(); - - for (TInt i(0); i < iSortOrder.Count(); i++) + const TInt sortOrderCount = iSortOrder.Count(); + for (TInt i(0); i < sortOrderCount; i++) { aSortOrder.Append(iSortOrder[i]); } @@ -567,8 +609,8 @@ void CPcsCache::GetIndexOrder(RArray& aIndexOrder) { aIndexOrder.Reset(); - - for (TInt i(0); i < iIndexOrder.Count(); i++) + const TInt indexOrderCount = iIndexOrder.Count(); + for (TInt i(0); i < indexOrderCount; i++) { aIndexOrder.Append(iIndexOrder[i]); } @@ -582,9 +624,11 @@ { iIndexOrder.Reset(); - for (int i = 0; i < iSortOrder.Count(); i++) + const TInt sortOrderCount = iSortOrder.Count(); + const TInt dataFieldsCount = iDataFields.Count(); + for (TInt i = 0; i < sortOrderCount; i++) { - for (int j = 0; j < iDataFields.Count(); j++) + for (TInt j = 0; j ResetAndDestroy(); + iKeyArr[i]->ResetAndDestroy(); } - masterPool.Reset(); - cacheInfo.Close(); - //now add data again from the masterPoolBackup - for (TInt i = 0; i < masterPoolBackup.Count(); i++ ) + iMasterPool.Reset(); + iCacheInfo.Close(); + //now add data again from the iMasterPoolBackup + const TInt masterPoolBackupCount = iMasterPoolBackup.Count(); + for (TInt i = 0; i < masterPoolBackupCount; i++ ) { - CPsData* temp = static_cast(masterPoolBackup[i]); + CPsData* temp = iMasterPoolBackup[i]; AddToCacheL( *temp ); } - masterPoolBackup.Reset(); - } + iMasterPoolBackup.Reset(); + } + +// --------------------------------------------------------------------- +// CPcsCache::GetFirstNameIndex +// +// --------------------------------------------------------------------- +TInt CPcsCache::GetFirstNameIndex() const + { + TInt fnIndex = KErrNotFound; + const TInt dataFieldsCount = iDataFields.Count(); + for ( TInt i = 0 ; i < dataFieldsCount && fnIndex == KErrNotFound ; ++i ) + { + if ( iDataFields[i] == R_VPBK_FIELD_TYPE_FIRSTNAME ) + { + fnIndex = i; + } + } + return fnIndex; + } + +// --------------------------------------------------------------------- +// CPcsCache::GetLastNameIndex +// +// --------------------------------------------------------------------- +TInt CPcsCache::GetLastNameIndex() const + { + TInt lnIndex = KErrNotFound; + const TInt dataFieldsCount = iDataFields.Count(); + for ( TInt i = 0 ; i < dataFieldsCount && lnIndex == KErrNotFound ; ++i ) + { + if ( iDataFields[i] == R_VPBK_FIELD_TYPE_LASTNAME ) + { + lnIndex = i; + } + } + return lnIndex; + } + // End of file