// Copyright (c) 2007-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:+ −
// CMSVCACHEINDEXTABLEENTRY.CPP+ −
// HEADER FILES+ −
// + −
//+ −
+ −
#include "msvcacheindextableentry.h"+ −
#include "msventryfreepool.h"+ −
#include "msvcacheentry.h"+ −
+ −
#if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT) + −
#include "msvindexadapter.h"+ −
#endif+ −
+ −
/**+ −
* FUNCTION DEFINITION+ −
*/+ −
+ −
+ −
//****************************+ −
//CMsvCacheIndexTableEntry+ −
//****************************+ −
+ −
/**+ −
* NewL()+ −
* @param None.+ −
* @return The newly created index table entry+ −
* + −
* It returns an instance of the CMsvCacheIndexTableEntry class, i.e. a newly + −
* constructed index table with no entries in it.+ −
*/+ −
CMsvCacheIndexTableEntry* CMsvCacheIndexTableEntry::NewL()+ −
{+ −
CMsvCacheIndexTableEntry *self = new(ELeave) CMsvCacheIndexTableEntry();+ −
return self;+ −
}+ −
+ −
+ −
/**+ −
* NewL()+ −
* @param CMsvCacheEntry& : a new cache entry+ −
* @return The newly created index table entry+ −
* + −
* It returns an instance of the CMsvCacheIndexTableEntry class with the passed entry+ −
* added.+ −
*/+ −
CMsvCacheIndexTableEntry* CMsvCacheIndexTableEntry::NewL(CMsvCacheEntry*& aEntry)+ −
{+ −
CMsvCacheIndexTableEntry *self = CMsvCacheIndexTableEntry::NewLC(aEntry);+ −
CleanupStack::Pop();+ −
return self;+ −
}+ −
+ −
+ −
/**+ −
* NewLC()+ −
* @param CMsvCacheEntry& : a new cache entry+ −
* @return The newly created index table entry+ −
* + −
* It returns an instance of the CMsvCacheIndexTableEntry class + −
* with the passed entry added. It leaves the object into cleanup stack.+ −
*/+ −
CMsvCacheIndexTableEntry* CMsvCacheIndexTableEntry::NewLC(CMsvCacheEntry*& aEntry)+ −
{+ −
CMsvCacheIndexTableEntry *self = new(ELeave) CMsvCacheIndexTableEntry();+ −
CleanupStack::PushL(self);+ −
self->AddEntryL(aEntry);+ −
return self;+ −
}+ −
+ −
+ −
+ −
+ −
/**+ −
* NewL()+ −
* @param RPointerArrayCMsvCacheEntry>& : RPointerArray reference to child entries+ −
* @return The newly created index table entry+ −
* + −
* It returns an instance of the CMsvCacheIndexTableEntry class filled with child+ −
* entries.+ −
*/+ −
CMsvCacheIndexTableEntry* CMsvCacheIndexTableEntry::NewL(RPointerArray<CMsvCacheEntry>& aEntries, TInt aInitIndex /*(DEFALUT=0)*/, TInt aCount /* DEFAULT = -1*/)+ −
{+ −
CMsvCacheIndexTableEntry *self = CMsvCacheIndexTableEntry::NewLC(aEntries, aInitIndex, aCount);+ −
CleanupStack::Pop();+ −
return self;+ −
}+ −
+ −
+ −
+ −
+ −
/**+ −
* NewLC()+ −
* @param RPointerArrayCMsvCacheEntry>& : RPointerArray reference to child entries+ −
* @return The newly created index table entry+ −
* + −
* It returns an instance of the CMsvCacheIndexTableEntry class filled with child+ −
* entries. It leaves the object into cleanup stack.+ −
*/+ −
CMsvCacheIndexTableEntry* CMsvCacheIndexTableEntry::NewLC(RPointerArray<CMsvCacheEntry>& aEntries, TInt aInitIndex /*(DEFALUT=0)*/, TInt aCount /* DEFAULT = -1*/)+ −
{+ −
CMsvCacheIndexTableEntry *self = new(ELeave) CMsvCacheIndexTableEntry();+ −
CleanupStack::PushL(self);+ −
self->AddEntrySetL(aEntries, aInitIndex, aCount);+ −
return self;+ −
}+ −
+ −
+ −
+ −
+ −
/**+ −
* CMsvCacheIndexTableEntry()+ −
* @param None.+ −
* @return None.+ −
* + −
* Constructor+ −
*/+ −
CMsvCacheIndexTableEntry::CMsvCacheIndexTableEntry()+ −
:iMinMsvId(0), iMaxMsvId(0), iFlags(EMsvCacheIndexTableClearFlag)+ −
{+ −
iTimeStamp.HomeTime(); //set the timestamp to number of seconds since Epoc.+ −
iBlockPtr = NULL;+ −
}+ −
+ −
+ −
/**+ −
* ~CMsvCacheIndexTableEntry()+ −
* @param None.+ −
* @return None.+ −
* + −
* Destructor - releases the block to the cache free pool and sets it to NULL.+ −
*/+ −
CMsvCacheIndexTableEntry::~CMsvCacheIndexTableEntry()+ −
{+ −
//destructor should delete everything no matter if entries are locked or not+ −
ReleaseBlock(ETrue);+ −
}+ −
+ −
+ −
/**+ −
* AddEntryL()+ −
* @param CMsvCacheEntry& : reference to the CMsvCacheEntry to be added.+ −
* @return None.+ −
* + −
* The function adds an entry into the index table. The entity who passes the entry+ −
* to the function will give up ownership of the same and hence cannot modify or + −
* delete it.+ −
* 1. If the block is NULL, it creates a new one and appends the entry to the block+ −
* and accordingly sets the TMsvId ranges.+ −
* 2. If block is not NULL, then append the entry to it.+ −
* 2.1 If the entry already exists in the block then release the old entry from the block and+ −
* append the new one.+ −
* 2.2 If the entry fits only at the end of the last block then we need to change+ −
* the iMaxMsvid.+ −
* If the indextable has not been created and if the folder has just one block, and this block contains+ −
* random entries, then we may need to set the iMinMsvId.+ −
*/+ −
void CMsvCacheIndexTableEntry::AddEntryL(CMsvCacheEntry*& aEntry, TBool aReplace /* DEFAULT = EFalse*/)+ −
{+ −
TMsvId entryId = aEntry->GetId();+ −
// 1. If the block is NULL, it creates a new one and appends the entry to the block+ −
// and accordingly sets the TMsvId ranges.+ −
if(NULL == iBlockPtr)+ −
{+ −
iBlockPtr = new(ELeave) RPointerArray<CMsvCacheEntry>;+ −
iBlockPtr->AppendL(aEntry);+ −
SetMinMsvIdRange(entryId);+ −
SetMaxMsvIdRange(entryId);+ −
} //if(NULL == iBlockPtr)+ −
+ −
// 2. If block is not NULL:+ −
else+ −
{+ −
// 2.1 If the entry already exists in the block then release the old entry from the+ −
// block and append the new one.+ −
TInt blockSize = Size();+ −
for(TInt blockIndex = 0; blockIndex < blockSize; ++blockIndex)+ −
{+ −
if((*iBlockPtr)[blockIndex]->GetId() == aEntry->GetId())+ −
{+ −
if(!aReplace)+ −
{+ −
CMsvEntryFreePool::Instance()->ReleaseEntry(aEntry);+ −
aEntry = (*iBlockPtr)[blockIndex];+ −
return;+ −
}+ −
CMsvEntryFreePool::Instance()->ReleaseEntry((*iBlockPtr)[blockIndex]);+ −
iBlockPtr->Remove(blockIndex);+ −
iBlockPtr->Insert(aEntry, blockIndex);+ −
return;+ −
}+ −
}+ −
iBlockPtr->AppendL(aEntry);+ −
+ −
// 2.2 If the entry fits only at the end of the last block then we need to+ −
// change the iMaxMsvid.+ −
// If the indextable has not been created and if the folder has just+ −
// one block, and this block contains random entries, then we may need to + −
// set the iMinMsvId.+ −
if(entryId > iMaxMsvId)+ −
{+ −
SetMaxMsvIdRange(entryId);+ −
}+ −
+ −
if(entryId < iMinMsvId)+ −
{+ −
SetMinMsvIdRange(entryId);+ −
}+ −
} //else+ −
iTimeStamp.HomeTime();+ −
}+ −
+ −
+ −
+ −
+ −
/**+ −
* AddEntrySetL()+ −
* @param RPointerArray<CMsvCacheEntry>& : reference to the new entry set to be added.+ −
* These entries can either be immediate children+ −
* or non-immediate children, but not both.+ −
* @param TInt aInitIndex : Start index of the entry to be added in the entryList.+ −
* @param TInt aCount : Number of entries that should be added.+ −
* @return None.+ −
* + −
* The function adds a set of entries to the index table. The caller who passes the + −
* array of entries to the function will give up ownership of the entries in the array.+ −
* 1. When the block is NULL:+ −
* 1.1 If children of a non-immediate folder are present in the array then set the + −
* grandchildren and dirty flags.+ −
* 1.2 If there aren't, then clear the above two flags.+ −
* 1.3 Assign the new entry set to the block, but reset the passed set so that+ −
* the caller cannot modify or delete the cache entries.+ −
* 2. When the block is not NULL:+ −
* 2.1 If children of a non-immediate folder are present in the array then+ −
* set the grandchildren flag and simply append entries to the block.+ −
* 2.2 If there aren't, append entries avoiding duplication.+ −
* 2.2.1 Search for each entry that is present in the current block in the+ −
* new set passed. If the entry is present then release it from the+ −
* current block. If not then append to the new set.+ −
* 2.2.2 All entries are now in the passed array. Reset the current block,+ −
* allocate space for it and copy the entries to it. Also reset the + −
* passed array so that callers do not have access to the cache+ −
* entries after the addition.+ −
* 3. Calculate and set the maximum and minimum TMsvId ranges in the newly added set.+ −
*/+ −
void CMsvCacheIndexTableEntry::AddEntrySetL(RPointerArray<CMsvCacheEntry>& aEntries, TInt aInitIndex /*(DEFAULT=0)*/, TInt aCount /* DEFAULT=-1 */)+ −
{+ −
// Add all entries if aCount is -1.+ −
TInt arrSize = aEntries.Count();+ −
if(-1 == aCount)+ −
{+ −
aCount = arrSize;+ −
}+ −
if(aInitIndex < 0 || aInitIndex >= arrSize)+ −
{+ −
return;+ −
}+ −
+ −
// 1. When the block is NULL:+ −
if(NULL == iBlockPtr)+ −
{+ −
// Assign the new entry set to the block, but reset the passed set so that+ −
// the caller cannot modify or delete the cache entries.+ −
// Update the ranges of the block.+ −
+ −
iBlockPtr = new(ELeave) RPointerArray<CMsvCacheEntry>;+ −
for(TInt listIndex = 0; (listIndex < aCount) && (arrSize > listIndex+aInitIndex); ++listIndex)+ −
{+ −
iBlockPtr->AppendL(aEntries[listIndex+aInitIndex]);+ −
}+ −
+ −
} //if(NULL == iBlockPtr)+ −
+ −
// 2. When the block is not NULL append the entries. If there is a duplicate entry,+ −
// discard the new entry.+ −
else+ −
{+ −
TBool entryFound = EFalse;+ −
TInt blockSize = Size();+ −
for(TInt listCount = 0; (listCount < aCount) && (arrSize > listCount+aInitIndex); ++listCount)+ −
{+ −
entryFound = EFalse;+ −
for(TInt blockIndex = 0; blockIndex < blockSize; ++blockIndex)+ −
{+ −
if(aEntries[listCount+aInitIndex]->GetId() == (*iBlockPtr)[blockIndex]->GetId())+ −
{+ −
CMsvEntryFreePool::Instance()->ReleaseEntry(aEntries[listCount+aInitIndex]);+ −
aEntries.Remove(listCount+aInitIndex);+ −
aEntries.Insert((*iBlockPtr)[blockIndex], listCount+aInitIndex);+ −
entryFound = ETrue;+ −
break;+ −
}+ −
} //for()+ −
if(!entryFound)+ −
{+ −
iBlockPtr->AppendL(aEntries[listCount+aInitIndex]);+ −
} + −
} //for()+ −
} //else+ −
iTimeStamp.HomeTime();+ −
}+ −
+ −
+ −
+ −
+ −
/**+ −
* GetEntry()+ −
* @param TMsvId : the TMsvId of the entry to be fetched.+ −
* @param CMsvCacheEntry*& : output parameter for the entry.+ −
* @return TBool.+ −
* + −
* The function fetches the entry with the specified TMsvId.+ −
* 1. If the block is NULL, there is no entry that can be fetched. Return EFalse.+ −
* 2. Iterate through the block searching for the TMsvId and return ETrue for a hit+ −
* 3. Return EFalse if the entry is not present in the block.+ −
*/+ −
TBool CMsvCacheIndexTableEntry::GetEntry(TMsvId aId, CMsvCacheEntry*& aEntry)+ −
{+ −
// 1. If the block is NULL, there is no entry that can be fetched. Return EFalse.+ −
if(NULL == iBlockPtr)+ −
{+ −
aEntry = NULL;+ −
return EFalse;+ −
}+ −
+ −
// 2. Iterate through the block searching for the TMsvId and return ETrue for a hit.+ −
TInt blockSize = Size();+ −
for(TInt index = 0 ; index < blockSize ; ++index)+ −
{+ −
if((*iBlockPtr)[index]->GetId() == aId)+ −
{+ −
aEntry = (*iBlockPtr)[index];+ −
iTimeStamp.HomeTime();+ −
return ETrue;+ −
}+ −
} //for+ −
+ −
// 3. Return EFalse if the entry is not present in the block.+ −
return EFalse;+ −
}+ −
+ −
+ −
/**+ −
* GetChildrenL()+ −
* @param TMsvId : TMsvId of the parent entry of the entries to be fetched.+ −
* @param RPointerArray<CMsvCacheEntry>*& : output parameter for the entries to be+ −
* fetched.+ −
* @return None.+ −
* + −
* The function fetches a set of entries with the specified parent TMsvId.+ −
* 1. Check if there are grandchildren present in the block.+ −
* 1.1. If yes, then fetch only those entries with parent Id as aParentId.+ −
* If the array of entries is NULL, then allocate space for it.+ −
* 1.2. If not, then return a copy of the whole block.+ −
*/+ −
void CMsvCacheIndexTableEntry::GetChildrenL(TMsvId aParentId, RPointerArray<CMsvCacheEntry>& aEntries) /*const*/+ −
{ + −
// 1. Check if there are grandchildren present in the block.+ −
if(IsGrandChildPresent())+ −
{+ −
// 1.1 If yes, then fetch only those entries with parent Id as aParentId.+ −
// If the array of entries is NULL, then allocate space for it.+ −
TInt blockSize = Size();+ −
for(TInt index = 0 ; index < blockSize ; ++index)+ −
{+ −
if((*iBlockPtr)[index]->Entry().Parent() == aParentId)+ −
{+ −
aEntries.AppendL((*iBlockPtr)[index]);+ −
}+ −
}+ −
} //if(IsGrandChildPresent())+ −
+ −
else+ −
{+ −
// 1.2 If not, then return a copy of the whole block.+ −
TInt blockSize = Size();+ −
for(TInt index = 0 ; index < blockSize ; ++index)+ −
{+ −
aEntries.AppendL((*iBlockPtr)[index]);+ −
}+ −
} //else+ −
iTimeStamp.HomeTime();+ −
}+ −
+ −
+ −
/**+ −
* DeleteEntryL()+ −
* @param TMsvId : the TMsvId of the entry to be deleted.+ −
* @param aParentIdOfEntry+ −
* @param aForceDelete TBool, it indicates whether the entry needs to be locked while deleting.+ −
* @return None.+ −
* + −
* The function deletes an entry from the cache releasing the entry to the cache free+ −
* pool. The function is called when the entry is being deleted from both the DB and+ −
* cache.+ −
* 1. Return if the block is NULL.+ −
* 2. Iterate through the block searching for the TMsvId.+ −
* 2.1 If the entry exists, remove it and release to the free pool. Deletion+ −
* is possible only if the entry is locked in the cache, otherwise the function+ −
* returns KErrAccessDenied.+ −
* 2.1.1 If the entry deleted was the last entry in the block, delete the+ −
* block.+ −
* 3. Leave with KErrNotFound if the entry does not exist in the block. + −
*/+ −
void CMsvCacheIndexTableEntry::DeleteEntryL(TMsvId aId, TMsvId& aParentIdOfEntry /*DEFAULT = NULL*/, TBool aForceDelete /*DEFAULT=EFalse*/)+ −
{ + −
// 1. Return if the block is NULL.+ −
if(NULL == iBlockPtr)+ −
{+ −
User::Leave(KErrNotFound);+ −
}+ −
+ −
// 2. Iterate through the block searching for the TMsvId.+ −
TInt blockSize = Size();+ −
for(TInt index = 0 ; index < blockSize ; ++index)+ −
{+ −
// 2.1 If the entry exists, remove it and release to the free pool. Deletion+ −
// is possible only if the entry is locked in the cache.+ −
if((*iBlockPtr)[index]->GetId() == aId)+ −
{+ −
if(aForceDelete || (*iBlockPtr)[index]->IsEntryLocked())+ −
{+ −
aParentIdOfEntry = (*iBlockPtr)[index]->Entry().Parent();+ −
CMsvEntryFreePool::Instance()->ReleaseEntry((*iBlockPtr)[index]);+ −
iBlockPtr->Remove(index);+ −
// 2.1.1. If the entry deleted was the last entry in the block,+ −
// delete the block.+ −
if(iBlockPtr->Count() == 0)+ −
{+ −
iBlockPtr->Close();+ −
delete iBlockPtr;+ −
iBlockPtr = NULL;+ −
}+ −
iTimeStamp.HomeTime();+ −
}+ −
else+ −
{+ −
User::Leave(KErrAccessDenied);+ −
}+ −
return;+ −
}+ −
} //for+ −
// 3. Leave with KErrNotFound if the entry does not exist in the block.+ −
User::Leave(KErrNotFound);+ −
}+ −
+ −
+ −
/**+ −
* ReleaseBlock()+ −
* @param TBool: internally used flag which is used by destructor to forcibly swap out+ −
* the block even if entries have been locked.+ −
* @return TBool: EFalse if block cannot be released as a result of entries having been+ −
* locked in the cache, ETrue if otherwise.+ −
* + −
* The function releases a block to the cache free pool.+ −
* 1. Return EFalse if any of the entries in the block have been locked. Do not+ −
* swap out the block to the free pool if so.+ −
* 2. No entries are locked and/or the block is to be swapped out forcibly.+ −
* 2.1 Release the entries to the free pool.+ −
* 2.2 Free the memory allocated to the block itself.+ −
* 2.3 Set the dirty flag.+ −
*/+ −
TBool CMsvCacheIndexTableEntry::ReleaseBlock(TBool aForceRelease /*DEFAULT = EFalse*/)+ −
{ + −
if(NULL == iBlockPtr)+ −
{+ −
return ETrue;+ −
}+ −
// 1. Return EFalse if any of the entries in the block have been locked. Do not+ −
// swap out the block to the free pool if so.+ −
if(!aForceRelease)+ −
{+ −
TInt blockSize = Size();+ −
for(TInt index = 0; index < blockSize; ++index)+ −
{+ −
if(!(*iBlockPtr)[index]->IsEntrySwappable())+ −
{+ −
return EFalse;+ −
}+ −
}+ −
}+ −
+ −
// 2. No entries are locked and the block can be swapped out safely.+ −
CMsvEntryFreePool::Instance()->ReleaseEntrySet(*iBlockPtr);+ −
+ −
iBlockPtr->Close();+ −
delete iBlockPtr;+ −
iBlockPtr = NULL;+ −
SetDirty();+ −
return ETrue;+ −
}+ −
+ −
+ −
/**+ −
* CompareOrder()+ −
* @param const CMsvCacheEntry& : the first operand+ −
* @param const CMsvCacheEntry& : the second operand+ −
* @return TInt : the order (-1/0/+1)+ −
* + −
* The function returns the order for the sort operation.+ −
*/+ −
static TInt CompareOrder(const CMsvCacheEntry& aFirst, const CMsvCacheEntry& aSecond)+ −
{+ −
return aFirst.GetId() - aSecond.GetId();+ −
}+ −
+ −
+ −
/**+ −
* SortBlockL()+ −
* @param None.+ −
* @return None.+ −
* + −
* The function is called by a background active object to sort the index table+ −
* according to TMsvIds of the entries.+ −
* 1. Sort based on the order in the TLinearOrder package.+ −
*/+ −
void CMsvCacheIndexTableEntry::SortBlock()+ −
{+ −
if(iBlockPtr != NULL)+ −
{+ −
// 1. Sort based on the order in the TLinearOrder package.+ −
TLinearOrder<CMsvCacheEntry> order(CompareOrder);+ −
iBlockPtr->Sort(order);+ −
}+ −
}+ −
+ −
+ −
/**+ −
* EntryExists()+ −
* @param TMsvId : the Id of the entry to be checked for existence.+ −
* @return TBool : success/failure.+ −
* + −
* The function return EFalse if either the block is NULL or the entry does not exist.+ −
* ETrue is returned for a hit.+ −
*/+ −
TBool CMsvCacheIndexTableEntry::EntryExists(TMsvId aId) const+ −
{+ −
if(NULL == iBlockPtr)+ −
{+ −
return EFalse;+ −
}+ −
TInt blockSize = Size();+ −
for(TInt index = 0 ; index < blockSize ; ++index)+ −
{+ −
if(aId == (*iBlockPtr)[index]->GetId())+ −
{+ −
return ETrue;+ −
}+ −
} //for+ −
return EFalse;+ −
}+ −
+ −
+ −
/**+ −
* UpdateChildMsvIdsL()+ −
* @param TMsvId : TMsvId of the parent entry.+ −
* @param TMsvId : TMsvId of the child entry.+ −
* @param TBool : flag, set to ETrue if aChildId is to be added, and EFalse if it is+ −
* to be removed from the parent's child array.+ −
* @return None.+ −
* + −
* The function updates the child array of the parent entry if it is not NULL.+ −
* 1. Return if the block is NULL, i.e. the parent is not in the cache.+ −
* 2. Iterate through the block searching for the parent entry.+ −
* 2.1 If the iChildIdArray is not NULL:+ −
* 2.1.1 If the child has to be added as a consequence of it being+ −
* added to the cache, then append it to the child array.+ −
* 2.1.2 If the child has to be removed as a consequence to the child+ −
* entry being deleted, then remove it from the child array.+ −
*/+ −
void CMsvCacheIndexTableEntry::UpdateChildMsvIdsL(TMsvId aParentId, TMsvId aChildId, TBool aAdd /*DEFAULT = ETrue*/)+ −
{+ −
// 1. Return if the block is NULL, i.e. the parent is not in the cache.+ −
if(NULL == iBlockPtr)+ −
{+ −
return;+ −
}+ −
+ −
// 2. Iterate through the block searching for the parent entry.+ −
TInt blockSize = Size();+ −
for(TInt index = 0 ; index < blockSize ; ++index)+ −
{+ −
if((*iBlockPtr)[index]->GetId() == aParentId)+ −
{+ −
RArray<TMsvId>* childArr = (*iBlockPtr)[index]->ChildIdArray();+ −
// 2.1 If the iChildIdArray is not NULL: i.e GetChildren has been performed+ −
if(childArr != NULL)+ −
{+ −
// 2.1.1 If the child has to be added as a consequence of it being+ −
// added to the cache, then append it to the child array.+ −
TInt arrSize = childArr->Count();+ −
if(aAdd)+ −
{+ −
TInt index = childArr->Find(aChildId);+ −
if(index == KErrNotFound)+ −
{+ −
childArr->AppendL(aChildId);+ −
}+ −
}+ −
+ −
// 2.1.2 If the child has to be removed as a consequence to the child+ −
// entry being deleted, then remove it from the child array.+ −
else+ −
{+ −
TInt index = childArr->Find(aChildId);+ −
if(index != KErrNotFound)+ −
{+ −
childArr->Remove(index);+ −
}+ −
}+ −
} //if(((*iBlockPtr)[index]->ChildIdArray()) != NULL)+ −
return;+ −
} //if((*iBlockPtr)[index]->GetId() == aParentId)+ −
} //for(TInt index = 0 ; index < Size() ; index++)+ −
}+ −
+ −
+ −
/**+ −
* UpdateChildMsvIdsL()+ −
* @param RPointerArray<CMsvCacheEntry>& : array of complete set of child + −
* CMsvCacheEntries sorted by TMsvId.+ −
* @return None.+ −
* + −
* The function updates, or creates if necessary, a parent entry's iChildIdArray with+ −
* the children entries passed to it in the form of a RPointerArray.+ −
* 1. Return if the block is NULL, i.e. the parent is not in the cache.+ −
* 2. Otherwise, find the parent sequentially.+ −
* 2.1 If the parent is found:+ −
* 2.1.1 If the parent already has a iChildIdArray, i.e. if GetChildren() has+ −
* been performed on it, delete and create a new child array with the + −
* entries passed. If iChildIdArray is NULL then GetChildren() has not been+ −
* performed on the entry yet, in which case append the passed children.+ −
*/+ −
void CMsvCacheIndexTableEntry::UpdateChildMsvIdsL(RPointerArray<CMsvCacheEntry>& aEntries)+ −
{+ −
+ −
// 1. Return if the block is NULL, i.e. the parent is not in the cache.+ −
if(NULL == iBlockPtr)+ −
{+ −
return;+ −
}+ −
+ −
// 2. Otherwise, find the parent sequentially.+ −
TMsvId parentId = aEntries[0]->Entry().Parent();+ −
TInt blockSize = Size();+ −
for(TInt index = 0 ; index < blockSize ; ++index)+ −
{+ −
// 2.1 If the parent is found:+ −
if((*iBlockPtr)[index]->Entry().Id() == parentId)+ −
{+ −
// 2.1.1 If the parent already has a iChildIdArray, i.e. if GetChildren() has+ −
// been performed on it, delete and create a new child array with the + −
// entries passed. If iChildIdArray is NULL then GetChildren() has not been+ −
// performed on the entry yet, in which case append the passed children.+ −
RArray<TMsvId>* childArr = (*iBlockPtr)[index]->ChildIdArray();+ −
TInt entryCount = aEntries.Count();+ −
if(NULL == childArr)+ −
{+ −
childArr = new(ELeave) RArray<TMsvId>;+ −
(*iBlockPtr)[index]->SetChildIdArray(childArr);+ −
}+ −
else+ −
{+ −
childArr->Reset();+ −
}+ −
while(0 < entryCount)+ −
{+ −
TInt leave = childArr->Append(aEntries[--entryCount]->GetId());+ −
if(KErrNone != leave)+ −
{+ −
childArr->Close();+ −
delete childArr;+ −
(*iBlockPtr)[index]->SetChildIdArray(NULL);+ −
User::Leave(leave);+ −
}+ −
}+ −
return;+ −
} //if((*iBlockPtr)[index]->Entry().Parent() == parentId)+ −
} //for(TInt index = 0 ; index < blockSize ; ++index)+ −
}+ −
+ −
+ −
/**+ −
*SplitBlock+ −
*This will be called when the block size will be more than 120, this will split the block+ −
* into 2 blocks. + −
*@param aSplitBlock RPointerArray<CMsvCacheEntry>& that will be filled with CMsvCacheEntries,+ −
*@param aMaxId The maximum TMsvId of the first block. + −
*@return void+ −
* + −
*/+ −
void CMsvCacheIndexTableEntry::SplitBlockL(RPointerArray<CMsvCacheEntry>& aSplitBlock)+ −
{+ −
TInt size = Size();+ −
TInt i = size/2;+ −
while(i < size)+ −
{+ −
aSplitBlock.AppendL((*iBlockPtr)[size/2]);+ −
iBlockPtr->Remove(size/2);+ −
i++;+ −
}+ −
}+ −
+ −
+ −
+ −
+ −
+ −
#if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)+ −
#ifdef _DEBUG+ −
// To print message index cache.+ −
void CMsvCacheIndexTableEntry::Print(RFileLogger& aLogger)+ −
{+ −
_LIT(KId, " ID: ");+ −
_LIT(KParentId, " ParentId: ");+ −
TInt blockSize = Size();+ −
for(TInt index=0; index<blockSize; ++index)+ −
{+ −
RBuf text;+ −
text.Create(150);+ −
text.Append(KId);+ −
text.AppendNum((*iBlockPtr)[index]->Entry().Id());+ −
text.Append(KParentId);+ −
text.AppendNum((*iBlockPtr)[index]->Entry().Parent());+ −
text.Append(_L(" VisibleEntry: "));+ −
text.AppendNum((*iBlockPtr)[index]->Entry().VisibleFolderFlag());+ −
text.Append(_L(" Complete flag:"));+ −
text.AppendNum((*iBlockPtr)[index]->Entry().Complete());+ −
text.Append(_L(" Description:"));+ −
text.Append((*iBlockPtr)[index]->Entry().iDetails);+ −
aLogger.Write(text);+ −
text.Close();+ −
}+ −
}+ −
#endif // #ifdef _DEBUG+ −
#endif // #if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)+ −