appfw/apparchitecture/apserv/APSRECCACHE.h
author William Roberts <williamr@symbian.org>
Fri, 23 Apr 2010 14:37:17 +0100
branchRCL_3
changeset 22 c82a39b81a38
parent 0 2e3d3ce01487
permissions -rw-r--r--
Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414) Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can arrange to use the same source file name in sfimage, without having to export over the original Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.

// 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:
//

#if !defined(__APSRECCACHE_H__)
#define __APSRECCACHE_H__

#include <e32base.h>
#include <apmrec.h>
#include "APSRECUTIL.H"

const TUint KFileHashMapEntries = 40;

/**
An entry for a recognized file in the recognition cache.
The entries is organized as single-linked list.
The recognition result itself is reference-counted.
@internalComponent
*/
class CRecognitionResultHashMapEntry : public CBase
	{
public:
	static CRecognitionResultHashMapEntry* NewL(const TDesC& aFileName, TTime aLastModified, const TDataRecognitionResult& aResult, CRecognitionResultHashMapEntry* aNext);
	~CRecognitionResultHashMapEntry();
	
	inline const CRecognitionResultHashMapEntry* Next() const { return iNext; }
	inline CRecognitionResultHashMapEntry* Next() { return iNext; }
	inline TTime LastModified() const { return iLastModified; }
	inline const TDesC& FileName() const { return iResult->FileName(); }
	inline CRecognitionResult* Result() const { iResult->Open(); return iResult; }
		
	void UpdateL(TTime aLastModified, const TDataRecognitionResult& aResult);
private:
	CRecognitionResultHashMapEntry(TTime aLastModified, CRecognitionResult* aResult, CRecognitionResultHashMapEntry* aNext);
private:
	TTime iLastModified;
	CRecognitionResult* iResult;
	CRecognitionResultHashMapEntry* iNext;
	};

/**
A hash map for finding and adding recognition results.

@internalComponent
*/
class CRecognitionResultHashMap : public CBase
	{
public:
	CRecognitionResultHashMap();
	~CRecognitionResultHashMap();
	CRecognitionResult* Get(const TDesC& aKey, TTime& aLastModified) const;
	TBool AddL(const TDesC& aKey, TTime aLastModified, const TDataRecognitionResult& aResult);
	inline TUint NumberOfEntries() const { return iNumberOfEntries; }
protected:
	TUint GetIndex(const TDesC& aKey) const;
private:
	inline CRecognitionResultHashMapEntry* Entry(TUint aIndex);
	inline const CRecognitionResultHashMapEntry* Entry(TUint aIndex) const;
	inline void SetEntry(TUint aIndex, CRecognitionResultHashMapEntry* aEntry);
private:
	TUint iNumberOfEntries;
	CRecognitionResultHashMapEntry* iEntries[KFileHashMapEntries];
	};

/**
A directory entry in the cache.
Such an entry doesn't necessarily hold all files of a directory, but
only the ones that have been recognized so far.
@internalComponent
*/
class CCacheDirectoryEntry : public CBase
	{
public:
	static CCacheDirectoryEntry* NewL(const TDesC& aDirectory);
	~CCacheDirectoryEntry();
	inline const TDesC& Directory() const { return *iDirectory; }
	inline CRecognitionResultHashMap& Files() { return iFiles; } //lint !e1536 Suppress exposing low access member
	inline TUint NumberOfEntries() const { return iFiles.NumberOfEntries(); }
private:
	CCacheDirectoryEntry();
public:
	static const TInt iOffset;
private:
	HBufC* iDirectory; // own copy!
	CRecognitionResultHashMap iFiles;
	TDblQueLink iDlink;
	friend class CApsRecognitionCache;
	};

/**
A recognition result cache.
The cache holds a list of directories (stored as an RPointerArray). Recently
used directories are stored on top of the list, rarely used directories are
stored at the bottom. 

This strategy improves performance: 
search for files is started at the top (principle of locality) 
and cleanup is done from the bottom.

The files themselves are stored in a hash map (within directories).
@internalComponent
*/
class CApsRecognitionCache : public CBase
	{
public:
	CApsRecognitionCache(RFs& aFs);
	~CApsRecognitionCache();
	void AddL(const TDesC& aDirectory, const TDesC& aFileName, const TDataRecognitionResult& aRecognitionResult);
	void AddL(const RFile& aFile, const TDesC& aDirectory, const TDesC& aFileName, const TDataRecognitionResult& aRecognitionResult);
	TBool Get(const TDesC& aDirectory, const TDesC& aFileName, TDataRecognitionResult& aRecognitionResult);
	CRecognitionResult* Get(const RFile& aFile, const TDesC& aDirectory, const TDesC& aFileName);
	void Flush();
private:
	void DoAddL(const TDesC& aDirectory, const TDesC& aFileName, const TTime& aLastModified, const TDataRecognitionResult& aRecognitionResult);
	CRecognitionResult* DoGet(const TDesC& aDirectory, const TDesC& aFileName, const TTime& aLastModified);
	TBool CompareDirectories(const TDesC& aDir1, const TDesC& aDir2) const;
	void Cleanup();
private: // data
	RFs& iFs;
	TDblQue<CCacheDirectoryEntry> iDirectoryHeader;
	TDblQueIter<CCacheDirectoryEntry> iIter;
	TUint iNumberOfEntries;
	};


//inlines

inline CRecognitionResultHashMapEntry* CRecognitionResultHashMap::Entry(TUint aIndex)
	{
	ASSERT(aIndex < KFileHashMapEntries);
	return iEntries[aIndex];
	}  //lint !e1762 Suppress member function could be made const

inline const CRecognitionResultHashMapEntry* CRecognitionResultHashMap::Entry(TUint aIndex) const
	{
	ASSERT(aIndex < KFileHashMapEntries);
	return iEntries[aIndex];
	}

inline void CRecognitionResultHashMap::SetEntry(TUint aIndex, CRecognitionResultHashMapEntry* aEntry)
	{
	ASSERT(Entry(aIndex) == aEntry->Next());
	iEntries[aIndex] = aEntry;
	}

#endif // __APSRECCACHE_H__