predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsCache.cpp
changeset 0 e686773b3f54
child 6 e8e3147d53eb
--- /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 <MVPbkContactLink.h>
+
+#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 <aKeyMap.PoolCount();i++ )
+        {
+        RPointerArray<CPcsPoolElement> *keyMap = new (ELeave) RPointerArray<CPcsPoolElement>(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<TInt, TInt> iter(cacheInfo);
+    
+    do
+    {
+    	TInt* id = const_cast<TInt*>(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<CPcsPoolElement> 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();
+    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<CPcsPoolElement>& aData)
+{
+    PRINT ( _L("Enter CPcsCache::GetContactsForKeyL") );
+        	
+	RPointerArray<CPcsPoolElement> 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<CPsData>& 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<TInt, TInt> elementHash;     
+     TLinearOrder<CPcsPoolElement> rule( CPcsPoolElement::CompareByData );
+              
+     // Parse thru each data element    
+     for ( int dataIndex = 0; dataIndex < aData.DataElementCount(); dataIndex++ )
+     {     	
+     	// Stores first key for each word
+		RArray<TUint> 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<CPcsPoolElement> 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<CPsData> 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<CPcsPoolElement> 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 <keyArr.Count();i++ )
+            {
+            keyArr[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<TInt>& aDataFields)
+{
+	for (TInt i(0); i < aDataFields.Count(); i++)
+	{
+		iDataFields.Append(aDataFields[i]);
+	}
+}
+
+// ---------------------------------------------------------------------
+// CPcsCache::GetDataFields
+// 
+// ---------------------------------------------------------------------
+void CPcsCache::GetDataFields(RArray<TInt>& 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<TInt>& 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<TInt>& aSortOrder)
+{
+    aSortOrder.Reset();
+    
+	for (TInt i(0); i < iSortOrder.Count(); i++)
+	{
+		aSortOrder.Append(iSortOrder[i]);
+	}	
+}
+
+
+// ---------------------------------------------------------------------
+// CPcsCache::GetIndexOrder
+// 
+// ---------------------------------------------------------------------
+void CPcsCache::GetIndexOrder(RArray<TInt>& 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<CPsData*>(masterPoolBackup[i]);
+        AddToCacheL( *temp );
+        }
+    masterPoolBackup.Reset();
+    } 
+// End of file