persistentstorage/store/INC/U32PERM.H
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/store/INC/U32PERM.H	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,431 @@
+// Copyright (c) 1998-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(__U32PERM_H__)
+#define __U32PERM_H__
+#if !defined(__S32STD_H__)
+#include <s32std.h>
+#endif
+#if !defined(__U32FRAME_H__)
+#include "U32FRAME.H"
+#endif
+
+#if defined(_DEBUG)&&!defined(__SMALL_BUNDLE)
+//#define __SMALL_BUNDLE
+#endif
+
+//Forward declaratons
+class RPermanentFileStoreIter;
+class TDriveInfo;
+
+//The offset of the header of a permanent file store.
+//Since all permanent file store operations work in their own coordinate system, where physical file offset 32 is
+//logical offset 0, KPermanentStoreHeaderOffset is set with -16, which means that the physical file offset is 32 - 16 = 16.
+const TInt KPermanentStoreHeaderOffset=-16;
+
+//Permanent file store header length: sizeof(backup TOC ref) + sizeof(handle) + sizeof(TOC ref) + sizeof(crc) = 4 + 4 + 4 + 2 = 14
+const TInt KPermanentStoreHeaderLength=14;
+
+//Backup TOC ref length - 4 bytes
+const TInt KPermanentStoreBackupLength=4;
+
+//
+const TInt KMaskHandleHash=0xff000000;
+const TInt KHandleInvalid=0x80000000;
+const TInt KHandleTocBase=0x40000000;
+const TInt KMaskHandleClear=0x30000000;
+const TInt KMaskHandleGen=0x0f000000;
+const TInt KIncHandleGen=0x01000000;
+//
+const TInt KMaxHandleIndex=0x00ffffff;
+const TInt KMaskHandleIndex=0x00ffffff;
+const TInt KSizeHandleIndex=3;
+//
+const TInt KTocDeltaCap = 64;		//up to 64 entries in a delta TOC
+const TInt KTocDeltaMagic = 2;
+const TInt KMaxTocDeltaMagic = KMaxTUint16;
+const TInt KTocDelta=KHandleInvalid;
+//
+const TInt KOffsetTocHeader=-12;
+const TInt KSizeTocEntry=5;		//base toc entry size is 5 bytes (when stored in the file, 8 bytes when presented in memory)
+const TInt KSizeTocDeltaEntry=8;//delta toc entry size is 8 bytes
+const TInt KSizeTocDeltaExtra=7;
+const TInt KElementsTocBuf=48;
+const TInt KBackTocBuf=20*KSizeTocEntry;
+const TInt KSizeTocBuf=KElementsTocBuf*KSizeTocEntry;
+
+//TPermanentStoreHeader class.
+//
+//Represents the data kept in the permanent store file header.
+//Data members:
+// - iBackup - "backup TOC reference", 32-bits integer, which keeps the 31-bit file offset of the backup TOC.
+//             Plays important role in the "store commit" procedure.
+//             The LSB is a "dirty" bit. If during the store opening phase the dirty bit is found to be set,
+//             then it means - the previous "store commit" operation has not been completed successfully and
+//             the backup TOC shall be used instead of the TOC;
+// - iHandle - 32-bit stream handle (MSB - invalid/deleted, 3 bits - unused, 4 bits - generation counter, 24 bits - stream handle).
+//             Plays important role in the "stream relocation" procedure during store compaction.
+//             iHandle keeps the handle of the stream being relocated, so if the commit phase fails, the original stream entry
+//             can be restored at the moment when the store is reopened;
+// - iRef    - Current "TOC reference". Represents a file offset, where the current TOC is;
+// - iCrc    - 16-bit CRC, protecting iBackup, iHandle, iRef;
+class TPermanentStoreHeader
+	{
+public:
+	TPermanentStoreHeader() {}
+	inline TUint8* Ptr();
+	inline const TUint8* Ptr() const;
+	TBool IsValid() const;
+//
+	inline TPermanentStoreHeader(TInt aToc);
+	inline TPermanentStoreHeader(TInt aBackupToc,TInt aHandle,TInt aReference);
+//
+	inline TBool IsDirty() const;
+	inline void MarkDirty();
+	inline void SetBackupToc(TInt aBackupToc);
+	inline TInt BackupToc() const;
+//
+	inline TInt Handle() const;
+	inline TInt Reference() const;
+private:
+	void Set(TInt aBackupToc,TInt aHandle,TInt aReference);
+private:
+	TUint32 iBackup;
+	TInt32 iHandle;
+	TInt32 iRef;
+	TUint16 iCrc;
+	};
+	
+//CPermanentStoreToc class.
+//
+//Represents the data kept in the permanent file store TOC (Table Of Content).
+//Each TOC consists of:
+// - TOC header         - CPermanentStoreToc::STocHead structure;
+// - set of TOC entries - CPermanentStoreToc::TEntry structure;
+//
+//Each TOC entry consists of:
+// - A stream handle (32 bits: MSB - invalid/deleted, 3 bits - unused, 4 bits - generation counter, 24 bits - stream handle);
+// - A stream ref - the offset of the stream data in the permannet file store;
+NONSHARABLE_CLASS(CPermanentStoreToc) : public CBase
+	{
+public:
+	struct TEntry
+		{
+		TInt handle;
+		TInt ref;
+		static TInt Compare(const TEntry&, const TEntry&);
+		};
+	struct STocHead
+		{
+		TInt32 primary;
+		TInt32 avail;
+		TUint32 count;
+		};
+	enum TPut {EWrite,ETestBeforeWrite};
+public:
+	static CPermanentStoreToc* NewL(TStreamPos aBase,TStreamExchange& aHost,TInt aToc,TInt aBaseReloc);
+	~CPermanentStoreToc();
+//
+	inline TInt Extent() const;
+	void Move(TInt aToc,TInt anExtent);
+//
+	inline TBool IsVirtual() const;
+	TInt RealizeL(TInt aPrimary,TInt anExtent) const;
+	void Adopt(TInt aToc,TInt aPrimary);
+//
+	inline TInt Primary() const;
+	inline void Changed();
+//
+	TInt AllocL(TInt anOffset);
+	TInt AllocL();
+	void Cancel(TInt aHandle);
+	void FreeL(TInt aHandle);
+	TInt AtL(TInt aHandle) const;
+	void PutL(TInt aHandle,TInt anOffset,TPut aCheck);
+	TInt GetL(TInt aHandle);
+	TInt Set(TInt aHandle,TInt anOffset);
+//
+	CPermanentStoreToc(TStreamPos aBase,TStreamExchange& aHost);
+	void ConstructL(TInt aToc,TInt aBaseReloc);
+	
+	TInt RefSpan(TInt aHandle,TInt& aLength);
+	
+private:
+	inline TStreamPos Base() const;
+	inline TStreamExchange& Host() const;
+	inline const TEntry* Entry(TInt aHandle) const;
+	TEntry* Entry(TInt aHandle);
+	TEntry& FetchL(TInt aHandle);
+	TEntry& DoAllocL();
+	TInt DoAtL(TInt aHandle) const;
+	void PutBaseL(TInt aHandle, TInt aReference);
+	void PutDeltaL(TInt aPos, TInt aHandle, TInt aReference);
+	void PutTocL(TInt aTocBase, TPut aCheck);
+	inline TBool HasDelta() const;
+	TBool IsDelta() const;
+	TInt InternalizeL(RReadStream& aIn, TInt aBaseReloc);
+	TInt DeltaL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
+	TInt RewriteL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
+	TInt SmallTocL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
+private:
+	TInt iPrimary;
+	TInt iAvail;
+	TInt iCount;
+	RArray<TEntry> iEntries;
+//
+	TStreamPos iBase;
+	TStreamExchange* iHost;
+	TInt iMagic;
+	TInt iOff;
+	TInt iExt;
+	TInt iTocOff;
+	TInt iTocExt;
+	__MUTABLE TInt iWindow;
+	__MUTABLE TUint8 iBuf[KSizeTocBuf];
+private:
+	friend class RPermanentStoreTocIter;
+	};
+
+//	
+class RPermanentStoreTocIter
+	{
+public:
+	typedef CPermanentStoreToc::TEntry TEntry;
+	typedef CPermanentStoreToc::STocHead STocHead;
+public:
+	RPermanentStoreTocIter(const CPermanentStoreToc& aTable);
+	inline void Close();
+	void Release();
+//
+	void ResetL();
+	TBool NextL(TEntry& anEntry);
+private:
+	const CPermanentStoreToc& iTable;
+	RFrame16Buf iBuf;
+	TInt iIndex;
+	TInt iCount;
+	TInt iNext;
+	const TEntry* iDelta;
+	const TEntry* iDeltaEnd;
+	};
+	
+//
+class TPermanentStoreCache
+	{
+public:
+	struct TItem {TInt handle;TInt offset;TInt extent;};
+public:
+	inline TPermanentStoreCache();
+	const TItem* At(TInt aHandle) const;
+	void Relocated(TInt aHandle,TInt anOffset);
+	void Put(const TItem* anItem,TInt anOffset,TInt anExtent);
+	void Add(TInt aHandle,TInt anOffset,TInt anExtent);
+	void Remove(TInt aHandle);
+	void Invalidate();
+private:
+	enum {EItems=2*16-1};
+private:
+	TItem iItems[EItems];
+	};
+	
+//
+NONSHARABLE_CLASS(CPermanentStoreCoord) : public CBase
+	{
+private:
+	enum {EReady,EBackup=0x1,EClip=0x2};
+	enum TFileQoS 
+		{
+		EUnknown,		//
+		ESimple,		//File, "write byte" is an atomic operation
+		EBlockAtomic,	//File, "block write" is an atomic operation
+		ETransactional	//Transactional file system.
+		};
+	typedef TPermanentStoreCache::TItem TItem;
+public:
+	inline TBool IsTrim() const;
+	TStreamPos LimitL();
+	inline void Clipped();
+//
+	TStreamId PrimaryL();
+	void ChangedL();
+	TBool CommitL(TStreamId aPrimary);
+	TBool RevertL(TStreamId& aPrimary);
+//
+	TStreamId ExtendL();
+	void DeleteL(TStreamId anId);
+//
+ 	CPermanentStoreCoord(TStreamPos aBase,TStreamExchange& aHost);
+	void InternalizeL(RReadStream& aStream);
+	~CPermanentStoreCoord();
+private:
+	void CanExtendL();
+	TInt DoCreateL();
+	void DoReplaceL(TInt aHandle);
+	TInt DoOpenL(TInt& anOffset,TInt aHandle);
+	void DoRelease(TInt aHandle,TInt anOffset,TInt anExtent);
+	TInt DoCommit(TInt aHandle,TInt anOffset,TInt anExtent);
+//
+	inline TStreamPos Base() const;
+	inline TStreamExchange& Host() const;
+	inline TInt Toc() const;
+	inline CPermanentStoreToc& Table() const;
+	CPermanentStoreToc& TableL();
+	CPermanentStoreToc& ConsolidateL();
+	void RelocateL(TInt aHandle,TInt anOffset);
+	void MoveL(TInt aToc,TInt anExtent);
+	inline TUint Generation() const;
+	inline void Inc();
+	inline void Dec();
+	inline TBool Accessed() const;
+	TFileQoS FileQoSL();
+	TBool IsBlockAtomicL(TInt aDriveNo) const;
+//
+	MStreamBuf* BeginL(TPermanentStoreHeader& aHeader);
+private:
+	TStreamPos iBase;
+	TStreamExchange *iHost;
+	TInt iToc;
+	CPermanentStoreToc* iTable;
+	TInt iReloc;
+	TInt iTarget;
+	TPermanentStoreCache iCache;
+//
+	TUint iGen;
+	TInt iRefs;
+	TInt iAccess;
+	TInt iExtend;
+	TInt iState;
+	TInt iExt;
+	TFileQoS iFileQos;
+private:
+	friend class HPermanentStoreBuf;
+	friend class CPermanentStoreCollector;
+	friend class RPermanentFileStoreIter;
+	};
+//
+NONSHARABLE_CLASS(HPermanentStoreBuf) : public RFrame16Buf
+	{
+public:
+	static HPermanentStoreBuf* CreateL(CPermanentStoreCoord& aCoord,TStreamId& anId,TInt aMode=ERead|EWrite);
+	static HPermanentStoreBuf* ReplaceL(CPermanentStoreCoord& aCoord,TStreamId anId,TInt aMode=ERead|EWrite);
+	static HPermanentStoreBuf* OpenL(CPermanentStoreCoord& aCoord,TStreamId anId,TInt aMode=ERead|EWrite);
+//
+	virtual ~HPermanentStoreBuf();
+private:
+	static HPermanentStoreBuf* NewLC(CPermanentStoreCoord& aCoord);
+	static HPermanentStoreBuf* ExtendLC(CPermanentStoreCoord& aCoord,TInt aMode);
+	inline HPermanentStoreBuf(CPermanentStoreCoord& aCoord);
+	inline CPermanentStoreCoord& Coord() const;
+//
+	void DoRelease();
+	void DoSynchL();
+private:
+	CPermanentStoreCoord* iCoord;
+	TInt iHandle;
+	};
+//
+class TPermanentStoreStreamIter
+	{
+#if defined(__SMALL_BUNDLE)
+	enum {EBundleSize=8-1};
+#else
+	enum {EBundleSize=64-1};
+#endif
+public:
+	void Reset();
+	TInt FillL(CPermanentStoreToc& aToc);
+	TInt Next();
+//
+	void Relocated(TInt aStream);
+private:
+	static void Push(TInt* aHeap,TInt* aHole,TInt aValue);
+	static TInt PopPush(TInt* aHeap,TInt* anEnd,TInt aValue);
+private:
+	TInt* iNext;
+	const TInt* iFinish;
+	TInt iMore;
+	TInt iPos;
+	TInt iTable[EBundleSize];
+	};
+
+class TPermanentStoreRelocator;
+NONSHARABLE_CLASS(CPermanentStoreCollector) : public CBase,public MIncrementalCollector
+	{
+	enum TState
+		{
+		EGetFree,ESkip,EInitRelocator,EFillRelocator,EEvalRelocator,EScanRelocator,ERelocateStream,ERelocateToc,
+		EFastSort,EFastExtent,EFastRelocate
+		};
+	enum {EGranularity = 64};
+	enum {EExtentStep = 64};
+public:
+	struct TEntry
+		{
+		TInt len;
+		RPermanentStoreTocIter::TEntry entry;
+		};
+public:
+	static CPermanentStoreCollector* CompactorL(CPermanentStoreCoord& aCoord);
+	static CPermanentStoreCollector* ReclaimerL(CPermanentStoreCoord& aCoord);
+protected:
+	CPermanentStoreCollector(CPermanentStoreCoord& aCoord);
+	~CPermanentStoreCollector();
+private:
+	void DoRelease();
+	void DoResetL(TInt& aCount);
+	void DoNextL(TInt& aStep,TInt& aTotal);
+//
+	TInt GetFreeL();
+	TInt SkipL(TInt& aTotal);
+	TInt InitRelocator();
+	TInt FillRelocatorL();
+	TInt EvalRelocatorL();
+	TInt ScanRelocator();
+	TInt RelocateStreamL();
+	TBool HaveEnoughSpace() const;
+	TInt ExtentL(TInt aStream);
+//
+// fast compaction
+	TInt FastResetL();
+	void FastSort();
+	void FastExtentL(TInt& aTotal);
+	void FastRelocateL(TInt& aTotal);
+	TEntry* BestFit(TInt aPos, TInt aExt, TEntry* aFirst, TEntry* aLast);
+//
+// common utilities
+	void RelocateTocL(TInt& aTotal);
+	void RelocateStreamL(const TEntry& aReloc, TInt aExtent);
+	TInt RelocateL(TInt aStream, TInt aLength, TFrameType16 aType, TInt aExtent);
+//
+	inline TBool Compacting() const;
+	inline CPermanentStoreCoord& Coord() const;
+	inline TStreamExchange& Host() const;
+private:
+	CPermanentStoreCoord* iCoord;
+	TUint iCoordGen;
+	TStreamExchange* iHost;
+	TStreamMark iMark;
+	TState iState;
+	TInt iFree;
+	TInt iEnd;
+	TEntry* iNext;
+	TEntry* iLast;
+	RArray<TEntry> iStreams;
+	TPermanentStoreRelocator* iReloc;
+	TPermanentStoreStreamIter iIter;
+	};
+
+#include "U32PERM.INL"
+#endif