diff -r 000000000000 -r e686773b3f54 predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsCache.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsCache.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,606 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Holds the contact information in memory. It maintains a +* master array of all contacts. It also has 10 pools corresponding +* to each key id in the keyboard. Based on numeric key char of +* first char of firstname/ lastname a contact is added to one of the +* pools. Implements MDataStoreObserver interface functions to +* add/ remove contacts. +* +*/ + + +// INCLUDE FILES +#include + +#include "CPsData.h" +#include "CPcsCache.h" +#include "CPcsDebug.h" +#include "CWords.h" +#include "CPcsAlgorithm1Utils.h" + + +// ============================== MEMBER FUNCTIONS ============================ + +// ---------------------------------------------------------------------------- +// CPcsCache::NewL +// Two Phase Construction +// ---------------------------------------------------------------------------- +CPcsCache* CPcsCache::NewL(TDesC& aURI, CPcsKeyMap& aKeyMap, TUint8 aUriId) +{ + PRINT ( _L("Enter CPcsCache::NewL") ); + + CPcsCache* instance= new ( ELeave ) CPcsCache(); + + CleanupStack::PushL( instance ); + + instance->ConstructL(aURI, aKeyMap, aUriId); + + CleanupStack::Pop( instance ); + + PRINT ( _L("End CPcsCache::NewL") ); + + return instance; +} + +// ---------------------------------------------------------------------------- +// CPcsCache::CPcsCache +// Constructor +// ---------------------------------------------------------------------------- +CPcsCache::CPcsCache() +{ + PRINT ( _L("Enter CPcsCache::CPcsCache") ); + PRINT ( _L("End CPcsCache::CPcsCache") ); +} + +// ---------------------------------------------------------------------------- +// CPcsCache::ConstructL +// 2nd Phase Constructor +// ---------------------------------------------------------------------------- +void CPcsCache::ConstructL(TDesC& aURI, CPcsKeyMap& aKeyMap, TUint8 aUriId) +{ + PRINT ( _L("Enter CPcsCache::ConstructL") ); + + iURI = aURI.AllocL(); + iUriId = aUriId; + //Update the caching status for this cache + iCacheStatus = ECachingNotStarted; + + keyMap = &aKeyMap; + + // Populate keyArr + for(TInt i= 0; i *keyMap = new (ELeave) RPointerArray(1); + keyArr.InsertL(keyMap,i); + } + + + PRINT ( _L("End CPcsCache::ConstructL") ); +} + +// ---------------------------------------------------------------------------- +// CPcsCache::~CPcsCache +// Destructor +// ---------------------------------------------------------------------------- +CPcsCache::~CPcsCache() +{ + 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; + } + + 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 ResetAndDestroy(); + delete keyArr[i]; + keyArr[i] = NULL; + } + + masterPool.ResetAndDestroy(); + + cacheInfo.Close(); + + keyArr.Reset(); + iDataFields.Reset(); + iSortOrder.Reset(); + iIndexOrder.Reset(); + + PRINT ( _L("End CPcsCache::~CPcsCache") ); +} + +// ---------------------------------------------------------------------------- +// CPcsCache::GetContactsForKeyL +// Get list of pool elements specific to a pool +// ---------------------------------------------------------------------------- +void CPcsCache::GetContactsForKeyL(TInt aKeyId, RPointerArray& aData) +{ + PRINT ( _L("Enter CPcsCache::GetContactsForKeyL") ); + + RPointerArray arr = *keyArr[aKeyId]; + for ( int i = 0; i < arr.Count(); i++ ) + { + CPcsPoolElement* value = arr[i]; + aData.AppendL(value); + } + + PRINT ( _L("End CPcsCache::GetContactsForKeyL") ); +} + +// ---------------------------------------------------------------------------- +// CPcsCache::GetAllContentsL +// Get all data elements in this cache +// ---------------------------------------------------------------------------- +void CPcsCache::GetAllContentsL(RPointerArray& aData) +{ + PRINT ( _L("Enter CPcsCache::GetAllContentsL") ); + + for ( int i = 0; i < masterPool.Count(); i++ ) + { + CPsData* value = masterPool[i]; + aData.AppendL(value); + } + + PRINT ( _L("End CPcsCache::GetAllContentsL") ); +} + + +// ---------------------------------------------------------------------------- +// CPcsCache::AddToPool +// Adds a contact to cache +// ---------------------------------------------------------------------------- +void CPcsCache::AddToPoolL(TInt& aPoolMap, CPsData& aData) +{ + // Temp hash to remember the location of pool elements + // First TInt = Pool + // Second TInt = Location in the pool + // Required for memory optimization so that more than one pool + // element doesn't get added for the same data + RHashMap elementHash; + TLinearOrder rule( CPcsPoolElement::CompareByData ); + + // Parse thru each data element + for ( int dataIndex = 0; dataIndex < aData.DataElementCount(); dataIndex++ ) + { + // Stores first key for each word + RArray firstKey; + + // Recover the first character + if ( aData.Data(dataIndex) && aData.Data(dataIndex)->Length() != 0 ) + { + // Split the data into words + CWords* words = CWords::NewLC(*aData.Data(dataIndex)); + + // Store the first numeric key for each word + for ( int i = 0; i < words->MdcaCount(); i++ ) + { + TChar firstChar = (words->MdcaPoint(i))[0]; + firstKey.Append(firstChar); + } + + CleanupStack::PopAndDestroy(words); + } + + for ( TInt wordIndex = 0; wordIndex < firstKey.Count(); wordIndex++ ) + { + TInt arrayIndex =keyMap->PoolIdForCharacter(firstKey[wordIndex]); + + CPcsPoolElement* element = NULL; + + // Check if an element already exists in the pool for this data + TInt* loc = NULL; + loc = elementHash.Find(arrayIndex); + if ( loc != NULL ) + { + // Exists. Then recover ... + RPointerArray tmpKeyMap = *(keyArr[arrayIndex]); + element = tmpKeyMap[*loc]; + } + + if ( element == NULL ) // Pool element doesn't exist. Create new ... + { + element = CPcsPoolElement::NewL(aData); + element->ClearDataMatchAttribute(); + element->SetDataMatch(dataIndex); + + // Insert to pool + keyArr[arrayIndex]->InsertInOrderAllowRepeatsL(element, rule); + TInt index = keyArr[arrayIndex]->FindInOrderL(element, rule); + + // Set the bit for this pool + SetPoolMap(aPoolMap, arrayIndex); + + // Store the array index in the temp hash + elementHash.InsertL(arrayIndex, index ); + } + else // Pool element exists. Just alter the data match attribute + { + element->SetDataMatch(dataIndex); + + // Set the bit for this pool + SetPoolMap(aPoolMap, arrayIndex); + } + + + } // for 2 loop + + firstKey.Reset(); + + } // for 1 loop + + elementHash.Close(); +} + +// --------------------------------------------------------------------- +// CPcsCache::AddToCacheL +// +// --------------------------------------------------------------------- +void CPcsCache::AddToCacheL( CPsData& aData ) +{ + // Protect against duplicate items getting added + if ( cacheInfo.Find(aData.Id()) != NULL ) + { + return; + } + + // Include this element in the pool + TInt poolMap = 0; + AddToPoolL(poolMap, aData); + cacheInfo.InsertL(aData.Id(), poolMap); + + // Include this element in master pool + TLinearOrder rule( CPcsAlgorithm1Utils::CompareDataBySortOrderL ); + masterPool.InsertInOrderAllowRepeatsL(&aData, rule); +} + +// --------------------------------------------------------------------- +// CPcsCache::RemoveContactL +// +// --------------------------------------------------------------------- +void CPcsCache::RemoveFromCacheL( TInt aItemId ) +{ + CPsData *data = NULL; + + TInt* poolMap = cacheInfo.Find(aItemId); + + if ( poolMap == NULL ) + { + return; + } + + // Remove this element from pools + for ( int keyIndex = 0; keyIndex < keyArr.Count(); keyIndex++ ) + { + TBool present = GetPoolMap(*poolMap, keyIndex); + + if ( ! present ) + { + continue; + } + + RPointerArray tmpKeyMap = *(keyArr[keyIndex]); + for ( int arrayIndex = 0; + arrayIndex < tmpKeyMap.Count(); + arrayIndex++ ) + { + CPcsPoolElement *element = tmpKeyMap[arrayIndex]; + TInt id = element->GetPsData()->Id(); + if ( id == aItemId ) + { + 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 id = dataElement->Id(); + if ( id == aItemId ) + { + masterPool.Remove(arrayIndex); + } + } + + // Delete data + if ( data ) + { + delete data; + data = NULL; + } + + // Clear up cache information + cacheInfo.Remove(aItemId); +} + +// --------------------------------------------------------------------- +// CPcsCache::RemoveAllFromCacheL +// +// --------------------------------------------------------------------- +void CPcsCache::RemoveAllFromCacheL() +{ + PRINT ( _L("Enter CPcsCache::RemoveAllFromCacheL") ); + + + for(TInt i= 0; i ResetAndDestroy(); + + } + + masterPool.ResetAndDestroy(); + cacheInfo.Close(); + + PRINT ( _L("End CPcsCache::RemoveAllFromCacheL") ); +} + +// --------------------------------------------------------------------- +// CPcsCache::SetPoolMap +// +// --------------------------------------------------------------------- +void CPcsCache::SetPoolMap(TInt& aPoolMap, TInt arrayIndex) +{ + TReal val; + Math::Pow(val, 2, arrayIndex); + + aPoolMap |= (TInt)val; +} + +// --------------------------------------------------------------------- +// CPcsCache::GetPoolMap +// +// --------------------------------------------------------------------- +TBool CPcsCache::GetPoolMap(TInt& aPoolMap, TInt arrayIndex) +{ + TReal val; + Math::Pow(val, 2, arrayIndex); + + return (aPoolMap & (TInt)val); +} + +// --------------------------------------------------------------------- +// CPcsCache::GetURI +// +// --------------------------------------------------------------------- +TDesC& CPcsCache::GetURI() +{ + return (*iURI); +} + +// --------------------------------------------------------------------- +// CPcsCache::SetDataFields +// +// --------------------------------------------------------------------- +void CPcsCache::SetDataFields(RArray& aDataFields) +{ + for (TInt i(0); i < aDataFields.Count(); i++) + { + iDataFields.Append(aDataFields[i]); + } +} + +// --------------------------------------------------------------------- +// CPcsCache::GetDataFields +// +// --------------------------------------------------------------------- +void CPcsCache::GetDataFields(RArray& aDataFields) +{ + for (TInt i(0); i < iDataFields.Count(); i++) + { + aDataFields.Append(iDataFields[i]); + } +} + +// --------------------------------------------------------------------- +// CPcsCache::UpdateCacheStatus +// +// --------------------------------------------------------------------- +void CPcsCache::UpdateCacheStatus(TInt aStatus) +{ + iCacheStatus = aStatus; +} + +// --------------------------------------------------------------------- +// CPcsCache::GetCacheStatus +// +// --------------------------------------------------------------------- +TInt CPcsCache::GetCacheStatus() +{ + return iCacheStatus; +} + +// --------------------------------------------------------------------- +// CPcsCache::GetUriId +// +// --------------------------------------------------------------------- +TUint8 CPcsCache::GetUriId() +{ + return iUriId; +} + +// --------------------------------------------------------------------- +// CPcsCache::GetUri +// +// --------------------------------------------------------------------- +HBufC* CPcsCache::GetUri() +{ + return iURI; +} + +// --------------------------------------------------------------------- +// CPcsCache::SetSortOrder +// +// --------------------------------------------------------------------- +void CPcsCache::SetSortOrder(RArray& aSortOrder) +{ + PRINT ( _L("Enter CPcsCache::SetSortOrder") ); + + iSortOrder.Reset(); + + for (TInt i(0); i < aSortOrder.Count(); i++) + { + iSortOrder.Append(aSortOrder[i]); + } + + ComputeIndexOrder(); + + PRINT ( _L("End CPcsCache::SetSortOrder") ); +} + +// --------------------------------------------------------------------- +// CPcsCache::GetSortOrder +// +// --------------------------------------------------------------------- +void CPcsCache::GetSortOrder(RArray& aSortOrder) +{ + aSortOrder.Reset(); + + for (TInt i(0); i < iSortOrder.Count(); i++) + { + aSortOrder.Append(iSortOrder[i]); + } +} + + +// --------------------------------------------------------------------- +// CPcsCache::GetIndexOrder +// +// --------------------------------------------------------------------- +void CPcsCache::GetIndexOrder(RArray& aIndexOrder) +{ + aIndexOrder.Reset(); + + for (TInt i(0); i < iIndexOrder.Count(); i++) + { + aIndexOrder.Append(iIndexOrder[i]); + } +} + +// --------------------------------------------------------------------- +// CPcsCache::ComputeIndexOrder +// +// --------------------------------------------------------------------- +void CPcsCache::ComputeIndexOrder() +{ + iIndexOrder.Reset(); + + for ( int i = 0; i < iSortOrder.Count(); i++ ) + { + for ( int j = 0; j < iDataFields.Count(); j++ ) + { + if ( iSortOrder[i] == iDataFields[j] ) + { + iIndexOrder.Append(j); + break; + } + } + } +} + +// --------------------------------------------------------------------- +// CPcsCache::ResortdataInPools +// +// --------------------------------------------------------------------- +void CPcsCache::ResortdataInPoolsL() + { + // copy masterPool data into masterPoolBackup + for (TInt i = 0; i < masterPool.Count(); i++ ) + { + masterPoolBackup.Append( masterPool[i] ); + } + //Now reset the key array + for (TInt i = 0; i < keyArr.Count(); i++ ) + { + keyArr[i]->ResetAndDestroy(); + } + masterPool.Reset(); + cacheInfo.Close(); + //now add data again from the masterPoolBackup + for (TInt i = 0; i < masterPoolBackup.Count(); i++ ) + { + CPsData* temp = static_cast(masterPoolBackup[i]); + AddToCacheL( *temp ); + } + masterPoolBackup.Reset(); + } +// End of file