pimappservices/calendar/server/src/agsuidindex.cpp
changeset 0 f979ecb2b13e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappservices/calendar/server/src/agsuidindex.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,296 @@
+// Copyright (c) 1997-2009 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 "agsuidindex.h"
+
+#include "agmsimpleentry.h"
+
+const TInt KAgnIndexGranularity = 64;
+
+//
+// class TAgnUidIndexKey
+//
+
+TInt CAgnLocalUidIndex::TAgnUidIndexKey::Compare(TInt aLeft, TInt aRight) const
+/**	Sorted array comparison function
+	
+@internalComponent	
+*/
+	{
+	const CAgnSimpleEntry* KLeft = *static_cast<CAgnSimpleEntry**>( At(aLeft) );
+	const CAgnSimpleEntry* KRight = *static_cast<CAgnSimpleEntry**>( At(aRight) );
+	
+	if ( KLeft->LocalUid() == KRight->LocalUid() )
+		{
+		return ( 0 );
+		}
+
+	return ( ( KLeft->LocalUid() < KRight->LocalUid() ) ? -1 : 1 );
+	}
+
+
+//
+// class CAgnLocalUidIndex
+//
+
+CAgnLocalUidIndex* CAgnLocalUidIndex::NewL(CAgnSimpleEntryAllocator& aAllocator)
+/**	Static constructor
+	
+@internalComponent	
+*/
+	{
+	CAgnLocalUidIndex* self = new (ELeave) CAgnLocalUidIndex(aAllocator);
+	
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	
+	return ( self );
+	}
+
+void CAgnLocalUidIndex::ConstructL()
+/**	Construct array with granularity of 64
+	
+@internalComponent	
+*/
+	{
+	iSearchEntry = iAllocator.CreateSimpleEntryL(CCalEntry::EAppt);	
+	
+	iIndex = new (ELeave) CArrayPtrSeg<CAgnSimpleEntry>(KAgnIndexGranularity);
+	}
+
+
+void CAgnLocalUidIndex::AddL(const CAgnSimpleEntry* aEntry)
+/**	Add a CAgnSimpleEntry reference
+
+@internalComponent
+*/
+	{
+	TInt pos = DoFindByLocalUid(aEntry->LocalUid());
+	if (pos >= 0)
+		{
+		if ((*iIndex)[pos]->EntryId().Value() != aEntry->EntryId().Value())
+			{
+			User::Leave(KErrAlreadyExists);
+			}
+		// in this case entry is already in database
+		}
+	else
+		{
+		iIndex->InsertIsqL( const_cast<CAgnSimpleEntry*>(aEntry), iKey);
+		}
+	}
+
+
+void CAgnLocalUidIndex::Delete(const CAgnSimpleEntry* aEntry)
+/**	Delete a CAgnSimpleEntry reference
+
+@internalComponent
+*/
+	{
+	const TInt KIndex = DoFindByLocalUid(aEntry->LocalUid());
+
+	if ( KIndex != KErrNotFound )
+		{
+		iIndex->Delete(KIndex);
+		}
+	}
+
+
+TInt CAgnLocalUidIndex::DoFindByLocalUid(TCalLocalUid aLocalUid) const
+/**	Get the index of the specified LocalUid, or KErrNotFound if not found
+
+@internalComponent
+@return Index of the specified LocalUid or KErrNotFound if not found
+*/
+	{
+	iSearchEntry->SetLocalUid(aLocalUid);
+	iSearchEntry->SetEntryId(TAgnEntryId());
+
+	TInt pos = 0;	
+
+	if ( iIndex->FindIsq(iSearchEntry, (TKeyArrayFix&) iKey, pos) == 0 )
+		{
+		return ( pos );
+		}		
+
+	return ( KErrNotFound );
+	}
+
+
+TAgnEntryId CAgnLocalUidIndex::FindByLocalUid(TCalLocalUid aLocalUid) const
+/**	Find EntryId by LocalUid 
+
+@internalComponent
+@return Agenda entry id matching the passed unique id
+*/
+	{
+	const TInt KIndex = DoFindByLocalUid(aLocalUid);
+
+	if ( KIndex != KErrNotFound )
+		{
+		return ( (*iIndex)[KIndex]->EntryId() );
+		}
+
+	return TAgnEntryId();
+	}
+
+
+//
+// class TGsGuidHashIndexKey
+//
+
+TInt CGsGuidHashIndex::TGsGuidHashIndexKey::Compare(TInt aLeft, TInt aRight) const
+/**	Sorted array comparison function
+	
+@internalComponent	
+*/
+	{
+	const CAgnSimpleEntry* KLeft = *static_cast<CAgnSimpleEntry**>( At(aLeft) );
+	const CAgnSimpleEntry* KRight = *static_cast<CAgnSimpleEntry**>( At(aRight) );
+
+	// the sort order is by GuidHash first and by LocalUid second
+	// NOTE: don't change this logic, otherwise FindHash won't work correctly
+
+	if ( KLeft->GuidHash() == KRight->GuidHash() )
+		{
+		if ( KLeft->LocalUid() == KRight->LocalUid() )
+			{
+			return ( 0 );
+			}
+			
+		return ( ( KLeft->LocalUid() < KRight->LocalUid() ) ? -1 : 1 );
+		}
+		
+	return ( ( KLeft->GuidHash() < KRight->GuidHash() ) ? -1 : 1 );		
+	}
+
+
+//
+// class CGsGuidHashIndex
+//
+
+CGsGuidHashIndex* CGsGuidHashIndex::NewL(CAgnSimpleEntryAllocator& aAllocator)
+/**	Static constructor
+	
+@internalComponent	
+*/
+	{
+	CGsGuidHashIndex* self = new (ELeave) CGsGuidHashIndex(aAllocator);
+	
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	
+	return ( self );
+	}
+
+
+void CGsGuidHashIndex::ConstructL()
+/**	Construct array with granularity of 64
+
+@internalComponent
+*/
+	{
+	iSearchEntry = iAllocator.CreateSimpleEntryL(CCalEntry::EAppt);	
+	
+	iIndex = new (ELeave) CArrayPtrSeg<CAgnSimpleEntry>(KAgnIndexGranularity);
+	}
+
+void CGsGuidHashIndex::AddL(const CAgnSimpleEntry* aEntry)
+/**	Add a CAgnSimpleEntry reference
+
+@internalComponent
+*/
+	{
+	TInt pos = DoFind(aEntry);
+	if (pos == KErrNotFound)
+		{
+		// in this case entry is not already in database
+		iIndex->InsertIsqL( const_cast<CAgnSimpleEntry*>(aEntry), iKey);	
+		}
+	}
+
+
+void CGsGuidHashIndex::Delete(const CAgnSimpleEntry* aEntry)
+/**	Delete a CAgnSimpleEntry reference
+
+@internalComponent
+*/
+	{
+	const TInt KIndex = DoFind(aEntry);
+
+	if ( KIndex != KErrNotFound )
+		{
+		iIndex->Delete(KIndex);
+		}
+	}
+
+
+TInt CGsGuidHashIndex::DoFind(const CAgnSimpleEntry* aEntry) const
+/**	Get the index of the specified LocalUid / GuidHash, or KErrNotFound if not found
+
+@internalComponent
+@return Index of the specified LocalUid / GuidHash, or KErrNotFound if not found
+*/
+	{
+	TInt pos = 0;	
+
+	if ( iIndex->FindIsq(const_cast<CAgnSimpleEntry*>(aEntry), (TKeyArrayFix&) iKey, pos) == 0 )
+		{
+		return ( pos );
+		}		
+
+	return ( KErrNotFound );	
+	}
+
+
+void CGsGuidHashIndex::FindByHashL(const TUint32& aGuidHash, RArray<TAgnEntryId>& aFoundIdList) const
+/**	Get all the LocalUid matching the passed GuidHash
+
+@internalComponent
+*/
+	{
+	iSearchEntry->SetGuidHash(aGuidHash);
+	iSearchEntry->SetLocalUid(0);
+
+	// The array is sorted by GuidHash first and LocalUid second
+	// The FindIsq in this case looks for the first occurence of GuidHash (because LocalUid is 0)
+	// We ignore the return value by purpose because it will negative anyway and nothing bad will happen.
+
+	TInt pos = 0;
+	// coverity[check_return] coverity[unchecked_value]
+	iIndex->FindIsq(iSearchEntry, (TKeyArrayFix&) iKey, pos);	
+	
+	const TInt KSize = iIndex->Count();
+	for ( ; pos < KSize; ++pos )
+		{
+		const CAgnSimpleEntry* KEntry = (*iIndex)[pos];
+
+		if ( aGuidHash == KEntry->GuidHash() )
+			{
+			// append to the passed array any LocalUid related to the GuidHash match
+			
+			aFoundIdList.AppendL(KEntry->EntryId());
+			}
+		else
+			{
+			// there are no more items in the array matching the GuidHash
+			// break the for-loop and exit
+			break;
+			}
+		}	
+	}