diff -r 000000000000 -r bde4ae8d615e os/persistentdata/persistentstorage/store/INC/U32PERM.H --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/persistentdata/persistentstorage/store/INC/U32PERM.H Fri Jun 15 03:10:57 2012 +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 +#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 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 iStreams; + TPermanentStoreRelocator* iReloc; + TPermanentStoreStreamIter iIter; + }; + +#include "U32PERM.INL" +#endif