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