zeroconf/cachemanager/src/cmdnscachemap.cpp
changeset 14 da856f45b798
equal deleted inserted replaced
12:78fbd574edf4 14:da856f45b798
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include "cmdnscachemap.h"
       
    19 #include "mdnsrecordinfo.h"
       
    20 #include <mdns/crdtypesrv.h>
       
    21 #include <mdns/crdtypea.h>
       
    22 #include <mdns/crdtypeptr.h>
       
    23 #include <mdns/crdtypetxt.h>
       
    24 
       
    25 
       
    26 __FLOG_STMT(_LIT8(KComponent,"MDNSCache");)
       
    27 
       
    28 CMDNSCacheMap* CMDNSCacheMap::NewL(TUint aMaxCacheEntries)
       
    29 	{
       
    30 	CMDNSCacheMap* self = CMDNSCacheMap::NewLC(aMaxCacheEntries);
       
    31 	CleanupStack::Pop(self);
       
    32 	return self;
       
    33 	}
       
    34 
       
    35 CMDNSCacheMap* CMDNSCacheMap::NewLC(TUint aMaxCacheEntries)
       
    36 	{
       
    37 	CMDNSCacheMap* self = new (ELeave)CMDNSCacheMap(aMaxCacheEntries);
       
    38 	CleanupStack::PushL(self);
       
    39 	self->ConstructL();
       
    40 	return self;
       
    41 	}
       
    42 
       
    43 void CMDNSCacheMap::ConstructL()
       
    44 	{
       
    45 	__FLOG_OPEN(KMDNSSubsystem, KComponent);
       
    46 	__FLOG(_L8("ConstructL - Entry"));
       
    47 	
       
    48 	__FLOG(_L8("ConstructL - Exit")); 
       
    49 	}
       
    50 
       
    51 CMDNSCacheMap::CMDNSCacheMap(TUint aMaxCacheEntries):iCacheEntries(HashInfo::TPtrC8Hash,HashInfo::TPtrC8Ident),iterate(iCacheEntries)
       
    52 	{
       
    53 	iMaxCacheEntries = aMaxCacheEntries;
       
    54 	}
       
    55 
       
    56 
       
    57 CMDNSCacheMap::~CMDNSCacheMap()
       
    58 	{
       
    59 	__FLOG(_L8("Destructor - Entry"));
       
    60 	RHashMap<TPtrC8,CServiceInfo*>::TIter iter(iCacheEntries);
       
    61 	TInt count(0);
       
    62 	TInt entriesToDelete(iCacheEntries.Count());
       
    63 	for(count=0; count<entriesToDelete; count++)
       
    64 		{
       
    65 		 delete *iter.NextValue();
       
    66 		}
       
    67 		
       
    68 	iCacheEntries.Close();
       
    69 	__FLOG(_L8("Destructor - Exit"));
       
    70 	__FLOG_CLOSE;
       
    71 	}
       
    72 	
       
    73 TUint32 HashInfo::TPtrC8Hash(const TPtrC8& aPtr)
       
    74 	{
       
    75 	return DefaultHash::Des8(aPtr);
       
    76 	}
       
    77 
       
    78 TBool HashInfo::TPtrC8Ident(const TPtrC8& aL, const TPtrC8& aR)
       
    79 	{
       
    80 	return DefaultIdentity::Des8(aL, aR);
       
    81 	}
       
    82 		
       
    83 	
       
    84 void CMDNSCacheMap::UpdateL(const TDesC8& aName, CServiceInfo* aEntry)
       
    85 	{
       
    86 	__FLOG(_L8("Insert - Entry"));
       
    87 	TTime currentTime;
       
    88 	currentTime.UniversalTime();
       
    89 	aEntry->SetAccessTime(currentTime);
       
    90 	TBool authoritative = aEntry->IsAuthoritative();
       
    91 	
       
    92 	//Save the key
       
    93 	aEntry->SetKeyL(aName);
       
    94 	
       
    95 	if(NumberOfEntries()<=iMaxCacheEntries)
       
    96 		{
       
    97 		iCacheEntries.InsertL(aEntry->Key(),aEntry);
       
    98 		}
       
    99 	else
       
   100 	{
       
   101 		if(aEntry->IsAuthoritative() && DeleteLeastRecentlyUsed())
       
   102 			{
       
   103 			iCacheEntries.InsertL(aEntry->Key(),aEntry);		
       
   104 			}
       
   105 		else
       
   106 			{
       
   107 			delete aEntry;
       
   108 			__FLOG_VA((_L8("--------User::Leave on Insert  = %d--------"),KErrNoMemory));
       
   109 			User::Leave(KErrNoMemory);
       
   110 			}
       
   111 		}
       
   112 		
       
   113 	__FLOG(_L8("Insert - Exit"));
       
   114 
       
   115 	}
       
   116 
       
   117 CServiceInfo* CMDNSCacheMap::Find(const TDesC8& aName)
       
   118 	{
       
   119 	TTime currentTime;
       
   120 	RBuf8 key;
       
   121 	key.CreateL(aName);
       
   122 	
       
   123 	//All keys are in LowerCase
       
   124 	key.LowerCase();
       
   125 	
       
   126 	CServiceInfo** foundEntry = NULL;	
       
   127 	foundEntry = iCacheEntries.Find(key);
       
   128 	key.Close();
       
   129 	currentTime.UniversalTime();
       
   130 	if(foundEntry)
       
   131 		{		
       
   132 		(*foundEntry)->SetAccessTime(currentTime);
       
   133 		return *foundEntry;
       
   134 		}	
       
   135 	return NULL;	
       
   136 	}
       
   137 
       
   138 void CMDNSCacheMap::FindEntries(const TDesC8& aName,RPointerArray <const CServiceInfo> & aEntries)
       
   139 	{	
       
   140 	_LIT8(KRegExp,"*");
       
   141 	TInt error; 
       
   142 	TBuf8 <256> serviceType(KRegExp);
       
   143 	TTime currentTime;
       
   144 	serviceType.Append(aName);
       
   145 	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
       
   146     TInt count;
       
   147      for(count=0; count<iCacheEntries.Count(); count++)
       
   148          {                        
       
   149          TPtrC8 nextKey=*iter.NextKey();
       
   150          //Match by the regular expression to get all Services by type
       
   151          error=nextKey.MatchF(serviceType);
       
   152          if( error != KErrNotFound)
       
   153         	 {
       
   154         	 CServiceInfo* currentEntry= *iter.CurrentValue();
       
   155         	 aEntries.Append(currentEntry);
       
   156         	 
       
   157         	 currentTime.UniversalTime();
       
   158         	 currentEntry->SetAccessTime(currentTime);
       
   159         	 }         
       
   160          }
       
   161 	}
       
   162 
       
   163 /*Not Used : Currently*/
       
   164 void CMDNSCacheMap::AuthoritativeRecordsL(RPointerArray <const CServiceInfo> & aEntries)
       
   165 	{
       
   166 	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
       
   167     TInt count;
       
   168     TTime currentTime;
       
   169      for(count=0; count<iCacheEntries.Count(); count++)
       
   170          {                        
       
   171          CServiceInfo* entry=*iter.NextValue();
       
   172          if(entry->IsAuthoritative())
       
   173         	 {
       
   174         	 aEntries.AppendL(entry);
       
   175         	 currentTime.UniversalTime();
       
   176         	 entry->SetAccessTime(currentTime);
       
   177         	 }         
       
   178          }
       
   179 	}
       
   180 
       
   181 TInt CMDNSCacheMap::DeleteL(const TDesC8& aName)
       
   182 	{
       
   183 	__FLOG(_L8("CMDNSCacheMap::DeleteL - Entry"));	
       
   184 	TInt error = KErrNone;
       
   185 	TBuf8 <256> key(aName);
       
   186 	
       
   187 	//All keys are in LowerCase
       
   188 	key.LowerCase();
       
   189 
       
   190     #ifdef __FLOG_ACTIVE
       
   191     
       
   192         HBufC8* buf(HBufC8::NewLC(aName.Length()));
       
   193         buf->Des().Copy(aName); 
       
   194         __FLOG_VA((_L8("Deleted Entry = %S "),buf));        
       
   195         CleanupStack::PopAndDestroy(buf);
       
   196     
       
   197     #endif
       
   198 	
       
   199 	CServiceInfo* entryToDelete = NULL;
       
   200 	TRAPD(err,entryToDelete=iCacheEntries.FindL(key));
       
   201 	if(err!=KErrNotFound)
       
   202 	    {
       
   203 	    error = iCacheEntries.Remove(key);
       
   204 	    delete entryToDelete;
       
   205 	    __FLOG(_L8("CMDNSCacheMap::DeleteL - Delete Cache Entry Successful"));  
       
   206 	    __FLOG(_L8("CMDNSCacheMap::DeleteL - Exit"));
       
   207 	    }
       
   208 	else
       
   209 	    {
       
   210 	    __FLOG(_L8("CMDNSCacheMap::DeleteL - Entry not found in Cache"));
       
   211 	    }
       
   212 	return error;
       
   213 	}
       
   214 
       
   215 void CMDNSCacheMap::DeleteAllEntries()
       
   216 	{
       
   217 	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
       
   218 	TInt count;
       
   219 	for(count=0; count<iCacheEntries.Count(); count++)
       
   220 		{                        
       
   221 		TPtrC8 key=*iter.NextKey();
       
   222 		/*TODO: check if object is properly deleted;
       
   223 		 * destructors are called*/
       
   224 		iCacheEntries.Remove(key);
       
   225 		delete *iter.NextValue();
       
   226 		}
       
   227 	}
       
   228 
       
   229 
       
   230 /* Scenarios:
       
   231 
       
   232 1. All are authoritative in Cache, authoritative record comes for insertion : No Memory
       
   233 2. All are authoritative in Cache, non-authoritative comes : No Memory
       
   234 3. One or more non-authoritative, non-authoritative comes : No Memory
       
   235 4. All are non-authoritative,authoritative comes, one of the records 
       
   236 	based on LRU (not accurate)of which is deleted, but authoritative WILL BE 
       
   237    put into cache
       
   238   */
       
   239 
       
   240 TBool CMDNSCacheMap::DeleteLeastRecentlyUsed()
       
   241 	{
       
   242 	THashMapIter<TPtrC8,CServiceInfo*> iter(iCacheEntries);
       
   243 	TInt count;
       
   244 	TTime accessTime,timeOfLRUEntry;
       
   245 	CServiceInfo* entryToDelete = NULL;
       
   246 	TBuf8<255> keyToDelete;
       
   247 	TBool cacheFull = ETrue;
       
   248 
       
   249 	for(count=0; count<iCacheEntries.Count(); count++)
       
   250 		{                                 
       
   251 		CServiceInfo* nextEntry = *iter.NextValue();
       
   252 		accessTime = nextEntry->LastAccessTime();
       
   253 		
       
   254 		if(count==0)
       
   255 			{
       
   256 			timeOfLRUEntry = accessTime;
       
   257 			if(!nextEntry->IsAuthoritative())
       
   258 				{
       
   259 				keyToDelete = *iter.CurrentKey();
       
   260 				entryToDelete = nextEntry;
       
   261 				}
       
   262 			}
       
   263 			
       
   264 		else
       
   265 		  {
       
   266 		 	if((accessTime < timeOfLRUEntry) && !nextEntry->IsAuthoritative() )
       
   267 		 		{
       
   268 		 		timeOfLRUEntry = accessTime;
       
   269 		 		keyToDelete = *iter.CurrentKey();
       
   270 				entryToDelete = nextEntry;
       
   271 		 		}		 	
       
   272 		  }
       
   273 		
       
   274 		}
       
   275 	
       
   276 	TInt error = iCacheEntries.Remove(keyToDelete);	
       
   277 	
       
   278 	if(error !=  KErrNone)
       
   279 		{
       
   280 		cacheFull =  EFalse;								
       
   281 		}
       
   282 	else
       
   283 	{
       
   284 	#ifdef __FLOG_ACTIVE
       
   285 		
       
   286 		__FLOG_VA((_L8("Deleting Least Recently Used = %S "),&keyToDelete));
       
   287 	
       
   288 	#endif
       
   289 	}
       
   290 		
       
   291 		
       
   292 	delete entryToDelete;
       
   293 	
       
   294 	return cacheFull;
       
   295 	}
       
   296 
       
   297 TUint32 CMDNSCacheMap::NumberOfEntries()
       
   298 	{
       
   299 	return iCacheEntries.Count();
       
   300 	}
       
   301 
       
   302 
       
   303 CServiceInfo* CMDNSCacheMap::NextStaleEntry(TBool aActiveCacheMgmtEnabled,TBool aIteratorReset)
       
   304 	{
       
   305 /*
       
   306 	 if(aIteratorReset)
       
   307 	 	{
       
   308 	 	iterate.Reset();
       
   309 	 	}
       
   310 	 	
       
   311 	 CServiceInfo* nextEntry=*iterate.NextValue();
       
   312 	 	
       
   313 	 if(nextEntry->EntryExpired() || nextEntry->EntryToBeQueried())
       
   314 	 	{
       
   315 	 	__FLOG(_L8("Stale Entry Found"));
       
   316 	 	return nextEntry;
       
   317 	 	}
       
   318 
       
   319 	 return NULL;
       
   320 	 
       
   321 */
       
   322     THashMapIter<TPtrC8,CServiceInfo*> itr(iCacheEntries);
       
   323 	CServiceInfo*const* nextEntry=itr.NextValue();
       
   324 	
       
   325 	while(nextEntry!=NULL)
       
   326 	    {
       
   327         if((*nextEntry)->EntryExpired())
       
   328             {
       
   329             __FLOG(_L8("Stale Entry Found"));
       
   330             return (*nextEntry);
       
   331             }	    
       
   332         nextEntry=itr.NextValue();
       
   333 	    }
       
   334 	    
       
   335 	return NULL;
       
   336     }
       
   337 
       
   338 void CMDNSCacheMap::DumpCacheL()
       
   339 	{
       
   340 	RHashMap<TPtrC8,CServiceInfo*>::TIter iter(iCacheEntries);
       
   341 
       
   342 	__FLOG(_L8("!!!!!!!!!!!!!!!!!!   BEGIN  CACHE DUMP   !!!!!!!!!!!!!!!!!!!!!"));
       
   343 	for(TInt count=0; count<iCacheEntries.Count(); count++)
       
   344 		{
       
   345 		CServiceInfo* entry = *iter.NextValue();
       
   346 
       
   347 
       
   348 		__FLOG_VA((_L8("--------------------Begin Entry = %d------------------"),count));	
       
   349 
       
   350 
       
   351 		TPtrC8 key(*iter.CurrentKey());
       
   352 		__FLOG_VA((_L8("--------------------Key is = %S------------------"),&key));
       
   353 
       
   354 		if(entry->ServiceRecord())
       
   355 			{
       
   356 			__FLOG(_L8("--------Service-Record Data-----"));
       
   357 			HBufC8* buf(HBufC8::NewLC(entry->ServiceRecord()->Name().Length()));
       
   358 			buf->Des().Copy(entry->ServiceRecord()->Name());
       
   359 			__FLOG_VA((_L8("Service Name = %S "),buf));	
       
   360 
       
   361 			HBufC8* target(HBufC8::NewLC(entry->ServiceRecord()->Target().Length()));
       
   362 			target->Des().Copy(entry->ServiceRecord()->Target());
       
   363 			__FLOG_VA((_L8("Target Machine = %S "),target));
       
   364 
       
   365 			__FLOG_VA((_L8("Priority = %d "),entry->ServiceRecord()->Priority()));
       
   366 			__FLOG_VA((_L8("Port = %d "),entry->ServiceRecord()->Port()));
       
   367 			__FLOG_VA((_L8("TTL = %d "),entry->ServiceRecord()->Ttl()));
       
   368 
       
   369 			CleanupStack::PopAndDestroy(target);
       
   370 			CleanupStack::PopAndDestroy(buf);
       
   371 			}
       
   372 
       
   373 		if(entry->AddressRecord())
       
   374 			{
       
   375 			__FLOG(_L8("-------Address-Record Data--------"));
       
   376 			HBufC8* buf(HBufC8::NewLC(entry->AddressRecord()->Name().Length()));
       
   377 			buf->Des().Copy(entry->AddressRecord()->Name());
       
   378 			__FLOG_VA((_L8("Host Name = %S "),buf));		
       
   379 			const TInetAddr addr(entry->AddressRecord()->Address());
       
   380 			TBuf <255> ipaddr;
       
   381 			addr.Output(ipaddr);
       
   382 
       
   383 			__FLOG_VA((_L("Inet Address = %S "),&ipaddr));
       
   384 
       
   385 			__FLOG_VA((_L8("TTL = %d "),entry->AddressRecord()->Ttl()));
       
   386 			CleanupStack::PopAndDestroy(buf);
       
   387 			}
       
   388 
       
   389 		if(entry->PtrRecord())
       
   390 			{
       
   391 			__FLOG(_L8("-------Ptr-Record Data-----------"));
       
   392 			HBufC8* buf(HBufC8::NewLC(entry->PtrRecord()->Name().Length()));
       
   393 			buf->Des().Copy(entry->PtrRecord()->Name());
       
   394 			__FLOG_VA((_L8("PTR  Name= %S "),buf));
       
   395 
       
   396 			HBufC8* domainName(HBufC8::NewLC(entry->PtrRecord()->DomainName().Length()));
       
   397 			domainName->Des().Copy(entry->PtrRecord()->DomainName());
       
   398 			__FLOG_VA((_L8("PTR Domain Name = %S "),domainName));	
       
   399 
       
   400 			__FLOG_VA((_L8("Type = %d "),entry->PtrRecord()->Type()));
       
   401 			__FLOG_VA((_L8("TTL = %d "),entry->PtrRecord()->Ttl()));
       
   402 
       
   403 			CleanupStack::PopAndDestroy(domainName);
       
   404 			CleanupStack::PopAndDestroy(buf);
       
   405 			}
       
   406 
       
   407 		if(entry->TxtRecord())
       
   408 			{
       
   409 			__FLOG(_L8("--------Txt-Record Data---------"));
       
   410 			const RArray <RBuf8>& array = entry->TxtRecord()->Text();
       
   411 
       
   412 			HBufC8* name(HBufC8::NewLC(entry->TxtRecord()->Name().Length()));
       
   413 			name->Des().Copy(entry->TxtRecord()->Name());
       
   414 			__FLOG_VA((_L8("Text Name= %S "),name));
       
   415 			CleanupStack::PopAndDestroy(name);
       
   416 
       
   417 
       
   418 			for (TInt count=0;count<array.Count();count++)
       
   419 				{
       
   420 				HBufC8* text(HBufC8::NewLC(array[count].Length()));
       
   421 				text->Des().Copy(array[count]);
       
   422 				__FLOG_VA((_L8("Text Info = %S "),text));
       
   423 				CleanupStack::PopAndDestroy(text);			
       
   424 				}			
       
   425 			__FLOG_VA((_L8("TTL = %d "),entry->TxtRecord()->Ttl()));
       
   426 			}
       
   427 
       
   428 		__FLOG_VA((_L8("--------Entry is Authoritative?? = %d--------"),entry->IsAuthoritative()));				
       
   429 
       
   430 		__FLOG_VA((_L8("--------Last Access Time = %ld--------"),entry->LastAccessTime()));
       
   431 
       
   432 		}
       
   433 	__FLOG_VA((_L8("--------Total number of entries = %d--------"),iCacheEntries.Count()));
       
   434 	}
       
   435 
       
   436 	
       
   437 
       
   438 
       
   439 	
       
   440 	
       
   441 	
       
   442 
       
   443 	
       
   444 
       
   445