zeroconf/cachemanager/src/cmdnscachemap.cpp
changeset 14 da856f45b798
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zeroconf/cachemanager/src/cmdnscachemap.cpp	Thu Jun 24 19:09:47 2010 +0530
@@ -0,0 +1,445 @@
+/*
+* Copyright (c) 2010 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: 
+*
+*/
+
+#include "cmdnscachemap.h"
+#include "mdnsrecordinfo.h"
+#include <mdns/crdtypesrv.h>
+#include <mdns/crdtypea.h>
+#include <mdns/crdtypeptr.h>
+#include <mdns/crdtypetxt.h>
+
+
+__FLOG_STMT(_LIT8(KComponent,"MDNSCache");)
+
+CMDNSCacheMap* CMDNSCacheMap::NewL(TUint aMaxCacheEntries)
+	{
+	CMDNSCacheMap* self = CMDNSCacheMap::NewLC(aMaxCacheEntries);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CMDNSCacheMap* CMDNSCacheMap::NewLC(TUint aMaxCacheEntries)
+	{
+	CMDNSCacheMap* self = new (ELeave)CMDNSCacheMap(aMaxCacheEntries);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+void CMDNSCacheMap::ConstructL()
+	{
+	__FLOG_OPEN(KMDNSSubsystem, KComponent);
+	__FLOG(_L8("ConstructL - Entry"));
+	
+	__FLOG(_L8("ConstructL - Exit")); 
+	}
+
+CMDNSCacheMap::CMDNSCacheMap(TUint aMaxCacheEntries):iCacheEntries(HashInfo::TPtrC8Hash,HashInfo::TPtrC8Ident),iterate(iCacheEntries)
+	{
+	iMaxCacheEntries = aMaxCacheEntries;
+	}
+
+
+CMDNSCacheMap::~CMDNSCacheMap()
+	{
+	__FLOG(_L8("Destructor - Entry"));
+	RHashMap<TPtrC8,CServiceInfo*>::TIter iter(iCacheEntries);
+	TInt count(0);
+	TInt entriesToDelete(iCacheEntries.Count());
+	for(count=0; count<entriesToDelete; count++)
+		{
+		 delete *iter.NextValue();
+		}
+		
+	iCacheEntries.Close();
+	__FLOG(_L8("Destructor - Exit"));
+	__FLOG_CLOSE;
+	}
+	
+TUint32 HashInfo::TPtrC8Hash(const TPtrC8& aPtr)
+	{
+	return DefaultHash::Des8(aPtr);
+	}
+
+TBool HashInfo::TPtrC8Ident(const TPtrC8& aL, const TPtrC8& aR)
+	{
+	return DefaultIdentity::Des8(aL, aR);
+	}
+		
+	
+void CMDNSCacheMap::UpdateL(const TDesC8& aName, CServiceInfo* aEntry)
+	{
+	__FLOG(_L8("Insert - Entry"));
+	TTime currentTime;
+	currentTime.UniversalTime();
+	aEntry->SetAccessTime(currentTime);
+	TBool authoritative = aEntry->IsAuthoritative();
+	
+	//Save the key
+	aEntry->SetKeyL(aName);
+	
+	if(NumberOfEntries()<=iMaxCacheEntries)
+		{
+		iCacheEntries.InsertL(aEntry->Key(),aEntry);
+		}
+	else
+	{
+		if(aEntry->IsAuthoritative() && DeleteLeastRecentlyUsed())
+			{
+			iCacheEntries.InsertL(aEntry->Key(),aEntry);		
+			}
+		else
+			{
+			delete aEntry;
+			__FLOG_VA((_L8("--------User::Leave on Insert  = %d--------"),KErrNoMemory));
+			User::Leave(KErrNoMemory);
+			}
+		}
+		
+	__FLOG(_L8("Insert - Exit"));
+
+	}
+
+CServiceInfo* CMDNSCacheMap::Find(const TDesC8& aName)
+	{
+	TTime currentTime;
+	RBuf8 key;
+	key.CreateL(aName);
+	
+	//All keys are in LowerCase
+	key.LowerCase();
+	
+	CServiceInfo** foundEntry = NULL;	
+	foundEntry = iCacheEntries.Find(key);
+	key.Close();
+	currentTime.UniversalTime();
+	if(foundEntry)
+		{		
+		(*foundEntry)->SetAccessTime(currentTime);
+		return *foundEntry;
+		}	
+	return NULL;	
+	}
+
+void CMDNSCacheMap::FindEntries(const TDesC8& aName,RPointerArray <const CServiceInfo> & aEntries)
+	{	
+	_LIT8(KRegExp,"*");
+	TInt error; 
+	TBuf8 <256> serviceType(KRegExp);
+	TTime currentTime;
+	serviceType.Append(aName);
+	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
+    TInt count;
+     for(count=0; count<iCacheEntries.Count(); count++)
+         {                        
+         TPtrC8 nextKey=*iter.NextKey();
+         //Match by the regular expression to get all Services by type
+         error=nextKey.MatchF(serviceType);
+         if( error != KErrNotFound)
+        	 {
+        	 CServiceInfo* currentEntry= *iter.CurrentValue();
+        	 aEntries.Append(currentEntry);
+        	 
+        	 currentTime.UniversalTime();
+        	 currentEntry->SetAccessTime(currentTime);
+        	 }         
+         }
+	}
+
+/*Not Used : Currently*/
+void CMDNSCacheMap::AuthoritativeRecordsL(RPointerArray <const CServiceInfo> & aEntries)
+	{
+	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
+    TInt count;
+    TTime currentTime;
+     for(count=0; count<iCacheEntries.Count(); count++)
+         {                        
+         CServiceInfo* entry=*iter.NextValue();
+         if(entry->IsAuthoritative())
+        	 {
+        	 aEntries.AppendL(entry);
+        	 currentTime.UniversalTime();
+        	 entry->SetAccessTime(currentTime);
+        	 }         
+         }
+	}
+
+TInt CMDNSCacheMap::DeleteL(const TDesC8& aName)
+	{
+	__FLOG(_L8("CMDNSCacheMap::DeleteL - Entry"));	
+	TInt error = KErrNone;
+	TBuf8 <256> key(aName);
+	
+	//All keys are in LowerCase
+	key.LowerCase();
+
+    #ifdef __FLOG_ACTIVE
+    
+        HBufC8* buf(HBufC8::NewLC(aName.Length()));
+        buf->Des().Copy(aName); 
+        __FLOG_VA((_L8("Deleted Entry = %S "),buf));        
+        CleanupStack::PopAndDestroy(buf);
+    
+    #endif
+	
+	CServiceInfo* entryToDelete = NULL;
+	TRAPD(err,entryToDelete=iCacheEntries.FindL(key));
+	if(err!=KErrNotFound)
+	    {
+	    error = iCacheEntries.Remove(key);
+	    delete entryToDelete;
+	    __FLOG(_L8("CMDNSCacheMap::DeleteL - Delete Cache Entry Successful"));  
+	    __FLOG(_L8("CMDNSCacheMap::DeleteL - Exit"));
+	    }
+	else
+	    {
+	    __FLOG(_L8("CMDNSCacheMap::DeleteL - Entry not found in Cache"));
+	    }
+	return error;
+	}
+
+void CMDNSCacheMap::DeleteAllEntries()
+	{
+	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
+	TInt count;
+	for(count=0; count<iCacheEntries.Count(); count++)
+		{                        
+		TPtrC8 key=*iter.NextKey();
+		/*TODO: check if object is properly deleted;
+		 * destructors are called*/
+		iCacheEntries.Remove(key);
+		delete *iter.NextValue();
+		}
+	}
+
+
+/* Scenarios:
+
+1. All are authoritative in Cache, authoritative record comes for insertion : No Memory
+2. All are authoritative in Cache, non-authoritative comes : No Memory
+3. One or more non-authoritative, non-authoritative comes : No Memory
+4. All are non-authoritative,authoritative comes, one of the records 
+	based on LRU (not accurate)of which is deleted, but authoritative WILL BE 
+   put into cache
+  */
+
+TBool CMDNSCacheMap::DeleteLeastRecentlyUsed()
+	{
+	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
+	TInt count;
+	TTime accessTime,timeOfLRUEntry;
+	CServiceInfo* entryToDelete = NULL;
+	TBuf8<255> keyToDelete;
+	TBool cacheFull = ETrue;
+
+	for(count=0; count<iCacheEntries.Count(); count++)
+		{                                 
+		CServiceInfo* nextEntry = *iter.NextValue();
+		accessTime = nextEntry->LastAccessTime();
+		
+		if(count==0)
+			{
+			timeOfLRUEntry = accessTime;
+			if(!nextEntry->IsAuthoritative())
+				{
+				keyToDelete = *iter.CurrentKey();
+				entryToDelete = nextEntry;
+				}
+			}
+			
+		else
+		  {
+		 	if((accessTime < timeOfLRUEntry) && !nextEntry->IsAuthoritative() )
+		 		{
+		 		timeOfLRUEntry = accessTime;
+		 		keyToDelete = *iter.CurrentKey();
+				entryToDelete = nextEntry;
+		 		}		 	
+		  }
+		
+		}
+	
+	TInt error = iCacheEntries.Remove(keyToDelete);	
+	
+	if(error !=  KErrNone)
+		{
+		cacheFull =  EFalse;								
+		}
+	else
+	{
+	#ifdef __FLOG_ACTIVE
+		
+		__FLOG_VA((_L8("Deleting Least Recently Used = %S "),&keyToDelete));
+	
+	#endif
+	}
+		
+		
+	delete entryToDelete;
+	
+	return cacheFull;
+	}
+
+TUint32 CMDNSCacheMap::NumberOfEntries()
+	{
+	return iCacheEntries.Count();
+	}
+
+
+CServiceInfo* CMDNSCacheMap::NextStaleEntry(TBool aActiveCacheMgmtEnabled,TBool aIteratorReset)
+	{
+/*
+	 if(aIteratorReset)
+	 	{
+	 	iterate.Reset();
+	 	}
+	 	
+	 CServiceInfo* nextEntry=*iterate.NextValue();
+	 	
+	 if(nextEntry->EntryExpired() || nextEntry->EntryToBeQueried())
+	 	{
+	 	__FLOG(_L8("Stale Entry Found"));
+	 	return nextEntry;
+	 	}
+
+	 return NULL;
+	 
+*/
+    THashMapIter<TPtrC8,CServiceInfo*> itr(iCacheEntries);
+	CServiceInfo*const* nextEntry=itr.NextValue();
+	
+	while(nextEntry!=NULL)
+	    {
+        if((*nextEntry)->EntryExpired())
+            {
+            __FLOG(_L8("Stale Entry Found"));
+            return (*nextEntry);
+            }	    
+        nextEntry=itr.NextValue();
+	    }
+	    
+	return NULL;
+    }
+
+void CMDNSCacheMap::DumpCacheL()
+	{
+	RHashMap<TPtrC8,CServiceInfo*>::TIter iter(iCacheEntries);
+
+	__FLOG(_L8("!!!!!!!!!!!!!!!!!!   BEGIN  CACHE DUMP   !!!!!!!!!!!!!!!!!!!!!"));
+	for(TInt count=0; count<iCacheEntries.Count(); count++)
+		{
+		CServiceInfo* entry = *iter.NextValue();
+
+
+		__FLOG_VA((_L8("--------------------Begin Entry = %d------------------"),count));	
+
+
+		TPtrC8 key(*iter.CurrentKey());
+		__FLOG_VA((_L8("--------------------Key is = %S------------------"),&key));
+
+		if(entry->ServiceRecord())
+			{
+			__FLOG(_L8("--------Service-Record Data-----"));
+			HBufC8* buf(HBufC8::NewLC(entry->ServiceRecord()->Name().Length()));
+			buf->Des().Copy(entry->ServiceRecord()->Name());
+			__FLOG_VA((_L8("Service Name = %S "),buf));	
+
+			HBufC8* target(HBufC8::NewLC(entry->ServiceRecord()->Target().Length()));
+			target->Des().Copy(entry->ServiceRecord()->Target());
+			__FLOG_VA((_L8("Target Machine = %S "),target));
+
+			__FLOG_VA((_L8("Priority = %d "),entry->ServiceRecord()->Priority()));
+			__FLOG_VA((_L8("Port = %d "),entry->ServiceRecord()->Port()));
+			__FLOG_VA((_L8("TTL = %d "),entry->ServiceRecord()->Ttl()));
+
+			CleanupStack::PopAndDestroy(target);
+			CleanupStack::PopAndDestroy(buf);
+			}
+
+		if(entry->AddressRecord())
+			{
+			__FLOG(_L8("-------Address-Record Data--------"));
+			HBufC8* buf(HBufC8::NewLC(entry->AddressRecord()->Name().Length()));
+			buf->Des().Copy(entry->AddressRecord()->Name());
+			__FLOG_VA((_L8("Host Name = %S "),buf));		
+			const TInetAddr addr(entry->AddressRecord()->Address());
+			TBuf <255> ipaddr;
+			addr.Output(ipaddr);
+
+			__FLOG_VA((_L("Inet Address = %S "),&ipaddr));
+
+			__FLOG_VA((_L8("TTL = %d "),entry->AddressRecord()->Ttl()));
+			CleanupStack::PopAndDestroy(buf);
+			}
+
+		if(entry->PtrRecord())
+			{
+			__FLOG(_L8("-------Ptr-Record Data-----------"));
+			HBufC8* buf(HBufC8::NewLC(entry->PtrRecord()->Name().Length()));
+			buf->Des().Copy(entry->PtrRecord()->Name());
+			__FLOG_VA((_L8("PTR  Name= %S "),buf));
+
+			HBufC8* domainName(HBufC8::NewLC(entry->PtrRecord()->DomainName().Length()));
+			domainName->Des().Copy(entry->PtrRecord()->DomainName());
+			__FLOG_VA((_L8("PTR Domain Name = %S "),domainName));	
+
+			__FLOG_VA((_L8("Type = %d "),entry->PtrRecord()->Type()));
+			__FLOG_VA((_L8("TTL = %d "),entry->PtrRecord()->Ttl()));
+
+			CleanupStack::PopAndDestroy(domainName);
+			CleanupStack::PopAndDestroy(buf);
+			}
+
+		if(entry->TxtRecord())
+			{
+			__FLOG(_L8("--------Txt-Record Data---------"));
+			const RArray <RBuf8>& array = entry->TxtRecord()->Text();
+
+			HBufC8* name(HBufC8::NewLC(entry->TxtRecord()->Name().Length()));
+			name->Des().Copy(entry->TxtRecord()->Name());
+			__FLOG_VA((_L8("Text Name= %S "),name));
+			CleanupStack::PopAndDestroy(name);
+
+
+			for (TInt count=0;count<array.Count();count++)
+				{
+				HBufC8* text(HBufC8::NewLC(array[count].Length()));
+				text->Des().Copy(array[count]);
+				__FLOG_VA((_L8("Text Info = %S "),text));
+				CleanupStack::PopAndDestroy(text);			
+				}			
+			__FLOG_VA((_L8("TTL = %d "),entry->TxtRecord()->Ttl()));
+			}
+
+		__FLOG_VA((_L8("--------Entry is Authoritative?? = %d--------"),entry->IsAuthoritative()));				
+
+		__FLOG_VA((_L8("--------Last Access Time = %ld--------"),entry->LastAccessTime()));
+
+		}
+	__FLOG_VA((_L8("--------Total number of entries = %d--------"),iCacheEntries.Count()));
+	}
+
+	
+
+
+	
+	
+	
+
+	
+
+