diff -r 88ee4cf65e19 -r 1aa8c82cb4cb remotestoragefw/remotefileengine/src/rsfwlruprioritylist.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remotestoragefw/remotefileengine/src/rsfwlruprioritylist.cpp Wed Sep 01 12:15:08 2010 +0100 @@ -0,0 +1,219 @@ +/* +* Copyright (c) 2005-2006 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: LRU priority list for the file cache +* +*/ + + +#include "rsfwlruprioritylist.h" +#include "rsfwlrulistnode.h" +#include "rsfwfileentry.h" +#include "mdebug.h" +#include "rsfwvolumetable.h" +#include "rsfwvolume.h" +#include "rsfwfileengine.h" +#include "rsfwfiletable.h" + +// ---------------------------------------------------------------------------- +// CRsfwLruPriorityList::CRsfwLruPriorityList +// +// ---------------------------------------------------------------------------- +// +CRsfwLruPriorityList::CRsfwLruPriorityList() + : iHdr(CRsfwLruListNode::iOffset),iIter(iHdr) //construct header & iterator + {} + +// ---------------------------------------------------------------------------- +// CRsfwLruPriorityList::~CRsfwLruPriorityList +// +// ---------------------------------------------------------------------------- +// +CRsfwLruPriorityList::~CRsfwLruPriorityList() + { + CRsfwLruListNode* node; + + iIter.SetToFirst(); + node = iIter++; + while (node) + { + node->iLink.Deque(); + delete node; + node = iIter++; + } + } + +// ---------------------------------------------------------------------------- +// CRsfwLruPriorityList::AddNodeL +// +// ---------------------------------------------------------------------------- +// +void CRsfwLruPriorityList::AddNodeL(CRsfwFileEntry *aFe, TInt aPriority) + { + CRsfwLruListNode* currentNode; + + iIter.SetToFirst(); + + currentNode = iIter++; + while (currentNode) + { + if (currentNode->iEntryPtr->Fid() == aFe->Fid()) + { + DEBUGSTRING(("LRU list: '%d' already exists on the list", + aFe->Fid().iNodeId)); + return; + } + currentNode = iIter++; + } + + // Inserts the specified list element in descending priority order. + // If there is an existing list element with the same priority, + // then the new element is added after the existing element. + CRsfwLruListNode* newNode = CRsfwLruListNode::NewL(aFe, aPriority); + iHdr.Add(*newNode); + DEBUGSTRING(("LRU list: added fid '%d' to the list", + aFe->Fid().iNodeId)); + } + + +// ---------------------------------------------------------------------------- +// CRsfwLruPriorityList::RemoveNode +// +// ---------------------------------------------------------------------------- +// +TInt CRsfwLruPriorityList::RemoveNode(CRsfwFileEntry *aFe) + { + DEBUGSTRING(("CRsfwLruPriorityList::RemoveNode")); + // When file is opened, it must be removed from LRU list + // as it is not candidate for removal from cache. + // Returns KErrNotFound if the file is not found at all + + TInt err = KErrNotFound; + CRsfwLruListNode* currentNode; + + iIter.SetToFirst(); + + currentNode = iIter++; + while (currentNode) + { + if (currentNode->iEntryPtr->Fid() == aFe->Fid()) + { + currentNode->iLink.Deque(); + delete currentNode; + err = KErrNone; + DEBUGSTRING(("LRU list: removed fid '%d' from the list", + aFe->Fid().iNodeId)); + break; + } + currentNode = iIter++; + } + return err; + } + +// ---------------------------------------------------------------------------- +// CRsfwLruPriorityList::GetAndRemoveFirstEntry +// +// ---------------------------------------------------------------------------- +// +CRsfwFileEntry* CRsfwLruPriorityList::GetAndRemoveFirstEntry() + { + + CRsfwLruListNode* firstNode = iHdr.First(); + CRsfwFileEntry* firstEntry = NULL; + + if (iHdr.IsHead(firstNode)) + { + return NULL; // the head has been reached, and must not be removed + } + + if (firstNode) + { + firstEntry = firstNode->iEntryPtr; + firstNode->iLink.Deque(); + delete firstNode; + } + + DEBUGSTRING(("LRU list: first fid on the list removed, '%d'", + firstEntry->Fid().iNodeId)); + return firstEntry; + } + +// ---------------------------------------------------------------------------- +// CRsfwFileEntry::ExternalizeL +// ---------------------------------------------------------------------------- +// +void CRsfwLruPriorityList::ExternalizeL(RWriteStream& aStream) + { + // start from the end! + iIter.SetToLast(); + CRsfwLruListNode* currentNode = iIter--; + while (currentNode) + { + CRsfwFileEntry* currentEntry = currentNode->iEntryPtr; + if (currentEntry) + { + TFid fid = currentEntry->Fid(); + aStream.WriteInt32L(fid.iNodeId); + aStream.WriteInt32L(fid.iVolumeId); + } + currentNode = iIter--; + } + } + +// ---------------------------------------------------------------------------- +// CRsfwFileEntry::InternalizeL +// ---------------------------------------------------------------------------- +// +void CRsfwLruPriorityList::InternalizeL(RReadStream& aStream, CRsfwVolumeTable* aVolumeTable) + { + if ( !aVolumeTable ) + { + User::Leave(KErrArgument); + } + + // reset existing list + iHdr.Reset(); + + // get stream size + MStreamBuf* streamBuf = aStream.Source(); + TInt streamSize = streamBuf->SizeL(); + + TInt i; + // note i+8 as one entry takes two TInt32 (2 times 4 bytes) + for ( i = 0; i < streamSize; i = i+8 ) + { + TFid fid; + fid.iNodeId = aStream.ReadInt32L(); + fid.iVolumeId = aStream.ReadInt32L(); + + // check whether there is no trash in the data being internalized + if (fid.iVolumeId >= 0 && fid.iVolumeId < KMaxVolumes && fid.iNodeId > 0) + { + // find existing CRsfwFileEntry object based on TFid + CRsfwVolume* volume = aVolumeTable->iVolumes[fid.iVolumeId]; + if ( volume ) + { + CRsfwFileEntry* entry = volume->iFileEngine->iFileTable->Root()->Lookup(fid); + if ( entry ) + { + AddNodeL(entry, ECachePriorityNormal); + } + } + } + else + { + DEBUGSTRING(("LRU List: wrong item on the list being internalized!")); + } + } + } +