os/persistentdata/persistentstorage/store/INC/U32PERM.H
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#if !defined(__U32PERM_H__)
sl@0
    17
#define __U32PERM_H__
sl@0
    18
#if !defined(__S32STD_H__)
sl@0
    19
#include <s32std.h>
sl@0
    20
#endif
sl@0
    21
#if !defined(__U32FRAME_H__)
sl@0
    22
#include "U32FRAME.H"
sl@0
    23
#endif
sl@0
    24
sl@0
    25
#if defined(_DEBUG)&&!defined(__SMALL_BUNDLE)
sl@0
    26
//#define __SMALL_BUNDLE
sl@0
    27
#endif
sl@0
    28
sl@0
    29
//Forward declaratons
sl@0
    30
class RPermanentFileStoreIter;
sl@0
    31
class TDriveInfo;
sl@0
    32
sl@0
    33
//The offset of the header of a permanent file store.
sl@0
    34
//Since all permanent file store operations work in their own coordinate system, where physical file offset 32 is
sl@0
    35
//logical offset 0, KPermanentStoreHeaderOffset is set with -16, which means that the physical file offset is 32 - 16 = 16.
sl@0
    36
const TInt KPermanentStoreHeaderOffset=-16;
sl@0
    37
sl@0
    38
//Permanent file store header length: sizeof(backup TOC ref) + sizeof(handle) + sizeof(TOC ref) + sizeof(crc) = 4 + 4 + 4 + 2 = 14
sl@0
    39
const TInt KPermanentStoreHeaderLength=14;
sl@0
    40
sl@0
    41
//Backup TOC ref length - 4 bytes
sl@0
    42
const TInt KPermanentStoreBackupLength=4;
sl@0
    43
sl@0
    44
//
sl@0
    45
const TInt KMaskHandleHash=0xff000000;
sl@0
    46
const TInt KHandleInvalid=0x80000000;
sl@0
    47
const TInt KHandleTocBase=0x40000000;
sl@0
    48
const TInt KMaskHandleClear=0x30000000;
sl@0
    49
const TInt KMaskHandleGen=0x0f000000;
sl@0
    50
const TInt KIncHandleGen=0x01000000;
sl@0
    51
//
sl@0
    52
const TInt KMaxHandleIndex=0x00ffffff;
sl@0
    53
const TInt KMaskHandleIndex=0x00ffffff;
sl@0
    54
const TInt KSizeHandleIndex=3;
sl@0
    55
//
sl@0
    56
const TInt KTocDeltaCap = 64;		//up to 64 entries in a delta TOC
sl@0
    57
const TInt KTocDeltaMagic = 2;
sl@0
    58
const TInt KMaxTocDeltaMagic = KMaxTUint16;
sl@0
    59
const TInt KTocDelta=KHandleInvalid;
sl@0
    60
//
sl@0
    61
const TInt KOffsetTocHeader=-12;
sl@0
    62
const TInt KSizeTocEntry=5;		//base toc entry size is 5 bytes (when stored in the file, 8 bytes when presented in memory)
sl@0
    63
const TInt KSizeTocDeltaEntry=8;//delta toc entry size is 8 bytes
sl@0
    64
const TInt KSizeTocDeltaExtra=7;
sl@0
    65
const TInt KElementsTocBuf=48;
sl@0
    66
const TInt KBackTocBuf=20*KSizeTocEntry;
sl@0
    67
const TInt KSizeTocBuf=KElementsTocBuf*KSizeTocEntry;
sl@0
    68
sl@0
    69
//TPermanentStoreHeader class.
sl@0
    70
//
sl@0
    71
//Represents the data kept in the permanent store file header.
sl@0
    72
//Data members:
sl@0
    73
// - iBackup - "backup TOC reference", 32-bits integer, which keeps the 31-bit file offset of the backup TOC.
sl@0
    74
//             Plays important role in the "store commit" procedure.
sl@0
    75
//             The LSB is a "dirty" bit. If during the store opening phase the dirty bit is found to be set,
sl@0
    76
//             then it means - the previous "store commit" operation has not been completed successfully and
sl@0
    77
//             the backup TOC shall be used instead of the TOC;
sl@0
    78
// - iHandle - 32-bit stream handle (MSB - invalid/deleted, 3 bits - unused, 4 bits - generation counter, 24 bits - stream handle).
sl@0
    79
//             Plays important role in the "stream relocation" procedure during store compaction.
sl@0
    80
//             iHandle keeps the handle of the stream being relocated, so if the commit phase fails, the original stream entry
sl@0
    81
//             can be restored at the moment when the store is reopened;
sl@0
    82
// - iRef    - Current "TOC reference". Represents a file offset, where the current TOC is;
sl@0
    83
// - iCrc    - 16-bit CRC, protecting iBackup, iHandle, iRef;
sl@0
    84
class TPermanentStoreHeader
sl@0
    85
	{
sl@0
    86
public:
sl@0
    87
	TPermanentStoreHeader() {}
sl@0
    88
	inline TUint8* Ptr();
sl@0
    89
	inline const TUint8* Ptr() const;
sl@0
    90
	TBool IsValid() const;
sl@0
    91
//
sl@0
    92
	inline TPermanentStoreHeader(TInt aToc);
sl@0
    93
	inline TPermanentStoreHeader(TInt aBackupToc,TInt aHandle,TInt aReference);
sl@0
    94
//
sl@0
    95
	inline TBool IsDirty() const;
sl@0
    96
	inline void MarkDirty();
sl@0
    97
	inline void SetBackupToc(TInt aBackupToc);
sl@0
    98
	inline TInt BackupToc() const;
sl@0
    99
//
sl@0
   100
	inline TInt Handle() const;
sl@0
   101
	inline TInt Reference() const;
sl@0
   102
private:
sl@0
   103
	void Set(TInt aBackupToc,TInt aHandle,TInt aReference);
sl@0
   104
private:
sl@0
   105
	TUint32 iBackup;
sl@0
   106
	TInt32 iHandle;
sl@0
   107
	TInt32 iRef;
sl@0
   108
	TUint16 iCrc;
sl@0
   109
	};
sl@0
   110
	
sl@0
   111
//CPermanentStoreToc class.
sl@0
   112
//
sl@0
   113
//Represents the data kept in the permanent file store TOC (Table Of Content).
sl@0
   114
//Each TOC consists of:
sl@0
   115
// - TOC header         - CPermanentStoreToc::STocHead structure;
sl@0
   116
// - set of TOC entries - CPermanentStoreToc::TEntry structure;
sl@0
   117
//
sl@0
   118
//Each TOC entry consists of:
sl@0
   119
// - A stream handle (32 bits: MSB - invalid/deleted, 3 bits - unused, 4 bits - generation counter, 24 bits - stream handle);
sl@0
   120
// - A stream ref - the offset of the stream data in the permannet file store;
sl@0
   121
NONSHARABLE_CLASS(CPermanentStoreToc) : public CBase
sl@0
   122
	{
sl@0
   123
public:
sl@0
   124
	struct TEntry
sl@0
   125
		{
sl@0
   126
		TInt handle;
sl@0
   127
		TInt ref;
sl@0
   128
		static TInt Compare(const TEntry&, const TEntry&);
sl@0
   129
		};
sl@0
   130
	struct STocHead
sl@0
   131
		{
sl@0
   132
		TInt32 primary;
sl@0
   133
		TInt32 avail;
sl@0
   134
		TUint32 count;
sl@0
   135
		};
sl@0
   136
	enum TPut {EWrite,ETestBeforeWrite};
sl@0
   137
public:
sl@0
   138
	static CPermanentStoreToc* NewL(TStreamPos aBase,TStreamExchange& aHost,TInt aToc,TInt aBaseReloc);
sl@0
   139
	~CPermanentStoreToc();
sl@0
   140
//
sl@0
   141
	inline TInt Extent() const;
sl@0
   142
	void Move(TInt aToc,TInt anExtent);
sl@0
   143
//
sl@0
   144
	inline TBool IsVirtual() const;
sl@0
   145
	TInt RealizeL(TInt aPrimary,TInt anExtent) const;
sl@0
   146
	void Adopt(TInt aToc,TInt aPrimary);
sl@0
   147
//
sl@0
   148
	inline TInt Primary() const;
sl@0
   149
	inline void Changed();
sl@0
   150
//
sl@0
   151
	TInt AllocL(TInt anOffset);
sl@0
   152
	TInt AllocL();
sl@0
   153
	void Cancel(TInt aHandle);
sl@0
   154
	void FreeL(TInt aHandle);
sl@0
   155
	TInt AtL(TInt aHandle) const;
sl@0
   156
	void PutL(TInt aHandle,TInt anOffset,TPut aCheck);
sl@0
   157
	TInt GetL(TInt aHandle);
sl@0
   158
	TInt Set(TInt aHandle,TInt anOffset);
sl@0
   159
//
sl@0
   160
	CPermanentStoreToc(TStreamPos aBase,TStreamExchange& aHost);
sl@0
   161
	void ConstructL(TInt aToc,TInt aBaseReloc);
sl@0
   162
	
sl@0
   163
	TInt RefSpan(TInt aHandle,TInt& aLength);
sl@0
   164
	
sl@0
   165
private:
sl@0
   166
	inline TStreamPos Base() const;
sl@0
   167
	inline TStreamExchange& Host() const;
sl@0
   168
	inline const TEntry* Entry(TInt aHandle) const;
sl@0
   169
	TEntry* Entry(TInt aHandle);
sl@0
   170
	TEntry& FetchL(TInt aHandle);
sl@0
   171
	TEntry& DoAllocL();
sl@0
   172
	TInt DoAtL(TInt aHandle) const;
sl@0
   173
	void PutBaseL(TInt aHandle, TInt aReference);
sl@0
   174
	void PutDeltaL(TInt aPos, TInt aHandle, TInt aReference);
sl@0
   175
	void PutTocL(TInt aTocBase, TPut aCheck);
sl@0
   176
	inline TBool HasDelta() const;
sl@0
   177
	TBool IsDelta() const;
sl@0
   178
	TInt InternalizeL(RReadStream& aIn, TInt aBaseReloc);
sl@0
   179
	TInt DeltaL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
sl@0
   180
	TInt RewriteL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
sl@0
   181
	TInt SmallTocL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
sl@0
   182
private:
sl@0
   183
	TInt iPrimary;
sl@0
   184
	TInt iAvail;
sl@0
   185
	TInt iCount;
sl@0
   186
	RArray<TEntry> iEntries;
sl@0
   187
//
sl@0
   188
	TStreamPos iBase;
sl@0
   189
	TStreamExchange* iHost;
sl@0
   190
	TInt iMagic;
sl@0
   191
	TInt iOff;
sl@0
   192
	TInt iExt;
sl@0
   193
	TInt iTocOff;
sl@0
   194
	TInt iTocExt;
sl@0
   195
	__MUTABLE TInt iWindow;
sl@0
   196
	__MUTABLE TUint8 iBuf[KSizeTocBuf];
sl@0
   197
private:
sl@0
   198
	friend class RPermanentStoreTocIter;
sl@0
   199
	};
sl@0
   200
sl@0
   201
//	
sl@0
   202
class RPermanentStoreTocIter
sl@0
   203
	{
sl@0
   204
public:
sl@0
   205
	typedef CPermanentStoreToc::TEntry TEntry;
sl@0
   206
	typedef CPermanentStoreToc::STocHead STocHead;
sl@0
   207
public:
sl@0
   208
	RPermanentStoreTocIter(const CPermanentStoreToc& aTable);
sl@0
   209
	inline void Close();
sl@0
   210
	void Release();
sl@0
   211
//
sl@0
   212
	void ResetL();
sl@0
   213
	TBool NextL(TEntry& anEntry);
sl@0
   214
private:
sl@0
   215
	const CPermanentStoreToc& iTable;
sl@0
   216
	RFrame16Buf iBuf;
sl@0
   217
	TInt iIndex;
sl@0
   218
	TInt iCount;
sl@0
   219
	TInt iNext;
sl@0
   220
	const TEntry* iDelta;
sl@0
   221
	const TEntry* iDeltaEnd;
sl@0
   222
	};
sl@0
   223
	
sl@0
   224
//
sl@0
   225
class TPermanentStoreCache
sl@0
   226
	{
sl@0
   227
public:
sl@0
   228
	struct TItem {TInt handle;TInt offset;TInt extent;};
sl@0
   229
public:
sl@0
   230
	inline TPermanentStoreCache();
sl@0
   231
	const TItem* At(TInt aHandle) const;
sl@0
   232
	void Relocated(TInt aHandle,TInt anOffset);
sl@0
   233
	void Put(const TItem* anItem,TInt anOffset,TInt anExtent);
sl@0
   234
	void Add(TInt aHandle,TInt anOffset,TInt anExtent);
sl@0
   235
	void Remove(TInt aHandle);
sl@0
   236
	void Invalidate();
sl@0
   237
private:
sl@0
   238
	enum {EItems=2*16-1};
sl@0
   239
private:
sl@0
   240
	TItem iItems[EItems];
sl@0
   241
	};
sl@0
   242
	
sl@0
   243
//
sl@0
   244
NONSHARABLE_CLASS(CPermanentStoreCoord) : public CBase
sl@0
   245
	{
sl@0
   246
private:
sl@0
   247
	enum {EReady,EBackup=0x1,EClip=0x2};
sl@0
   248
	enum TFileQoS 
sl@0
   249
		{
sl@0
   250
		EUnknown,		//
sl@0
   251
		ESimple,		//File, "write byte" is an atomic operation
sl@0
   252
		EBlockAtomic,	//File, "block write" is an atomic operation
sl@0
   253
		ETransactional	//Transactional file system.
sl@0
   254
		};
sl@0
   255
	typedef TPermanentStoreCache::TItem TItem;
sl@0
   256
public:
sl@0
   257
	inline TBool IsTrim() const;
sl@0
   258
	TStreamPos LimitL();
sl@0
   259
	inline void Clipped();
sl@0
   260
//
sl@0
   261
	TStreamId PrimaryL();
sl@0
   262
	void ChangedL();
sl@0
   263
	TBool CommitL(TStreamId aPrimary);
sl@0
   264
	TBool RevertL(TStreamId& aPrimary);
sl@0
   265
//
sl@0
   266
	TStreamId ExtendL();
sl@0
   267
	void DeleteL(TStreamId anId);
sl@0
   268
//
sl@0
   269
 	CPermanentStoreCoord(TStreamPos aBase,TStreamExchange& aHost);
sl@0
   270
	void InternalizeL(RReadStream& aStream);
sl@0
   271
	~CPermanentStoreCoord();
sl@0
   272
private:
sl@0
   273
	void CanExtendL();
sl@0
   274
	TInt DoCreateL();
sl@0
   275
	void DoReplaceL(TInt aHandle);
sl@0
   276
	TInt DoOpenL(TInt& anOffset,TInt aHandle);
sl@0
   277
	void DoRelease(TInt aHandle,TInt anOffset,TInt anExtent);
sl@0
   278
	TInt DoCommit(TInt aHandle,TInt anOffset,TInt anExtent);
sl@0
   279
//
sl@0
   280
	inline TStreamPos Base() const;
sl@0
   281
	inline TStreamExchange& Host() const;
sl@0
   282
	inline TInt Toc() const;
sl@0
   283
	inline CPermanentStoreToc& Table() const;
sl@0
   284
	CPermanentStoreToc& TableL();
sl@0
   285
	CPermanentStoreToc& ConsolidateL();
sl@0
   286
	void RelocateL(TInt aHandle,TInt anOffset);
sl@0
   287
	void MoveL(TInt aToc,TInt anExtent);
sl@0
   288
	inline TUint Generation() const;
sl@0
   289
	inline void Inc();
sl@0
   290
	inline void Dec();
sl@0
   291
	inline TBool Accessed() const;
sl@0
   292
	TFileQoS FileQoSL();
sl@0
   293
	TBool IsBlockAtomicL(TInt aDriveNo) const;
sl@0
   294
//
sl@0
   295
	MStreamBuf* BeginL(TPermanentStoreHeader& aHeader);
sl@0
   296
private:
sl@0
   297
	TStreamPos iBase;
sl@0
   298
	TStreamExchange *iHost;
sl@0
   299
	TInt iToc;
sl@0
   300
	CPermanentStoreToc* iTable;
sl@0
   301
	TInt iReloc;
sl@0
   302
	TInt iTarget;
sl@0
   303
	TPermanentStoreCache iCache;
sl@0
   304
//
sl@0
   305
	TUint iGen;
sl@0
   306
	TInt iRefs;
sl@0
   307
	TInt iAccess;
sl@0
   308
	TInt iExtend;
sl@0
   309
	TInt iState;
sl@0
   310
	TInt iExt;
sl@0
   311
	TFileQoS iFileQos;
sl@0
   312
private:
sl@0
   313
	friend class HPermanentStoreBuf;
sl@0
   314
	friend class CPermanentStoreCollector;
sl@0
   315
	friend class RPermanentFileStoreIter;
sl@0
   316
	};
sl@0
   317
//
sl@0
   318
NONSHARABLE_CLASS(HPermanentStoreBuf) : public RFrame16Buf
sl@0
   319
	{
sl@0
   320
public:
sl@0
   321
	static HPermanentStoreBuf* CreateL(CPermanentStoreCoord& aCoord,TStreamId& anId,TInt aMode=ERead|EWrite);
sl@0
   322
	static HPermanentStoreBuf* ReplaceL(CPermanentStoreCoord& aCoord,TStreamId anId,TInt aMode=ERead|EWrite);
sl@0
   323
	static HPermanentStoreBuf* OpenL(CPermanentStoreCoord& aCoord,TStreamId anId,TInt aMode=ERead|EWrite);
sl@0
   324
//
sl@0
   325
	virtual ~HPermanentStoreBuf();
sl@0
   326
private:
sl@0
   327
	static HPermanentStoreBuf* NewLC(CPermanentStoreCoord& aCoord);
sl@0
   328
	static HPermanentStoreBuf* ExtendLC(CPermanentStoreCoord& aCoord,TInt aMode);
sl@0
   329
	inline HPermanentStoreBuf(CPermanentStoreCoord& aCoord);
sl@0
   330
	inline CPermanentStoreCoord& Coord() const;
sl@0
   331
//
sl@0
   332
	void DoRelease();
sl@0
   333
	void DoSynchL();
sl@0
   334
private:
sl@0
   335
	CPermanentStoreCoord* iCoord;
sl@0
   336
	TInt iHandle;
sl@0
   337
	};
sl@0
   338
//
sl@0
   339
class TPermanentStoreStreamIter
sl@0
   340
	{
sl@0
   341
#if defined(__SMALL_BUNDLE)
sl@0
   342
	enum {EBundleSize=8-1};
sl@0
   343
#else
sl@0
   344
	enum {EBundleSize=64-1};
sl@0
   345
#endif
sl@0
   346
public:
sl@0
   347
	void Reset();
sl@0
   348
	TInt FillL(CPermanentStoreToc& aToc);
sl@0
   349
	TInt Next();
sl@0
   350
//
sl@0
   351
	void Relocated(TInt aStream);
sl@0
   352
private:
sl@0
   353
	static void Push(TInt* aHeap,TInt* aHole,TInt aValue);
sl@0
   354
	static TInt PopPush(TInt* aHeap,TInt* anEnd,TInt aValue);
sl@0
   355
private:
sl@0
   356
	TInt* iNext;
sl@0
   357
	const TInt* iFinish;
sl@0
   358
	TInt iMore;
sl@0
   359
	TInt iPos;
sl@0
   360
	TInt iTable[EBundleSize];
sl@0
   361
	};
sl@0
   362
sl@0
   363
class TPermanentStoreRelocator;
sl@0
   364
NONSHARABLE_CLASS(CPermanentStoreCollector) : public CBase,public MIncrementalCollector
sl@0
   365
	{
sl@0
   366
	enum TState
sl@0
   367
		{
sl@0
   368
		EGetFree,ESkip,EInitRelocator,EFillRelocator,EEvalRelocator,EScanRelocator,ERelocateStream,ERelocateToc,
sl@0
   369
		EFastSort,EFastExtent,EFastRelocate
sl@0
   370
		};
sl@0
   371
	enum {EGranularity = 64};
sl@0
   372
	enum {EExtentStep = 64};
sl@0
   373
public:
sl@0
   374
	struct TEntry
sl@0
   375
		{
sl@0
   376
		TInt len;
sl@0
   377
		RPermanentStoreTocIter::TEntry entry;
sl@0
   378
		};
sl@0
   379
public:
sl@0
   380
	static CPermanentStoreCollector* CompactorL(CPermanentStoreCoord& aCoord);
sl@0
   381
	static CPermanentStoreCollector* ReclaimerL(CPermanentStoreCoord& aCoord);
sl@0
   382
protected:
sl@0
   383
	CPermanentStoreCollector(CPermanentStoreCoord& aCoord);
sl@0
   384
	~CPermanentStoreCollector();
sl@0
   385
private:
sl@0
   386
	void DoRelease();
sl@0
   387
	void DoResetL(TInt& aCount);
sl@0
   388
	void DoNextL(TInt& aStep,TInt& aTotal);
sl@0
   389
//
sl@0
   390
	TInt GetFreeL();
sl@0
   391
	TInt SkipL(TInt& aTotal);
sl@0
   392
	TInt InitRelocator();
sl@0
   393
	TInt FillRelocatorL();
sl@0
   394
	TInt EvalRelocatorL();
sl@0
   395
	TInt ScanRelocator();
sl@0
   396
	TInt RelocateStreamL();
sl@0
   397
	TBool HaveEnoughSpace() const;
sl@0
   398
	TInt ExtentL(TInt aStream);
sl@0
   399
//
sl@0
   400
// fast compaction
sl@0
   401
	TInt FastResetL();
sl@0
   402
	void FastSort();
sl@0
   403
	void FastExtentL(TInt& aTotal);
sl@0
   404
	void FastRelocateL(TInt& aTotal);
sl@0
   405
	TEntry* BestFit(TInt aPos, TInt aExt, TEntry* aFirst, TEntry* aLast);
sl@0
   406
//
sl@0
   407
// common utilities
sl@0
   408
	void RelocateTocL(TInt& aTotal);
sl@0
   409
	void RelocateStreamL(const TEntry& aReloc, TInt aExtent);
sl@0
   410
	TInt RelocateL(TInt aStream, TInt aLength, TFrameType16 aType, TInt aExtent);
sl@0
   411
//
sl@0
   412
	inline TBool Compacting() const;
sl@0
   413
	inline CPermanentStoreCoord& Coord() const;
sl@0
   414
	inline TStreamExchange& Host() const;
sl@0
   415
private:
sl@0
   416
	CPermanentStoreCoord* iCoord;
sl@0
   417
	TUint iCoordGen;
sl@0
   418
	TStreamExchange* iHost;
sl@0
   419
	TStreamMark iMark;
sl@0
   420
	TState iState;
sl@0
   421
	TInt iFree;
sl@0
   422
	TInt iEnd;
sl@0
   423
	TEntry* iNext;
sl@0
   424
	TEntry* iLast;
sl@0
   425
	RArray<TEntry> iStreams;
sl@0
   426
	TPermanentStoreRelocator* iReloc;
sl@0
   427
	TPermanentStoreStreamIter iIter;
sl@0
   428
	};
sl@0
   429
sl@0
   430
#include "U32PERM.INL"
sl@0
   431
#endif