1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/store/INC/U32PERM.H Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,431 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#if !defined(__U32PERM_H__)
1.20 +#define __U32PERM_H__
1.21 +#if !defined(__S32STD_H__)
1.22 +#include <s32std.h>
1.23 +#endif
1.24 +#if !defined(__U32FRAME_H__)
1.25 +#include "U32FRAME.H"
1.26 +#endif
1.27 +
1.28 +#if defined(_DEBUG)&&!defined(__SMALL_BUNDLE)
1.29 +//#define __SMALL_BUNDLE
1.30 +#endif
1.31 +
1.32 +//Forward declaratons
1.33 +class RPermanentFileStoreIter;
1.34 +class TDriveInfo;
1.35 +
1.36 +//The offset of the header of a permanent file store.
1.37 +//Since all permanent file store operations work in their own coordinate system, where physical file offset 32 is
1.38 +//logical offset 0, KPermanentStoreHeaderOffset is set with -16, which means that the physical file offset is 32 - 16 = 16.
1.39 +const TInt KPermanentStoreHeaderOffset=-16;
1.40 +
1.41 +//Permanent file store header length: sizeof(backup TOC ref) + sizeof(handle) + sizeof(TOC ref) + sizeof(crc) = 4 + 4 + 4 + 2 = 14
1.42 +const TInt KPermanentStoreHeaderLength=14;
1.43 +
1.44 +//Backup TOC ref length - 4 bytes
1.45 +const TInt KPermanentStoreBackupLength=4;
1.46 +
1.47 +//
1.48 +const TInt KMaskHandleHash=0xff000000;
1.49 +const TInt KHandleInvalid=0x80000000;
1.50 +const TInt KHandleTocBase=0x40000000;
1.51 +const TInt KMaskHandleClear=0x30000000;
1.52 +const TInt KMaskHandleGen=0x0f000000;
1.53 +const TInt KIncHandleGen=0x01000000;
1.54 +//
1.55 +const TInt KMaxHandleIndex=0x00ffffff;
1.56 +const TInt KMaskHandleIndex=0x00ffffff;
1.57 +const TInt KSizeHandleIndex=3;
1.58 +//
1.59 +const TInt KTocDeltaCap = 64; //up to 64 entries in a delta TOC
1.60 +const TInt KTocDeltaMagic = 2;
1.61 +const TInt KMaxTocDeltaMagic = KMaxTUint16;
1.62 +const TInt KTocDelta=KHandleInvalid;
1.63 +//
1.64 +const TInt KOffsetTocHeader=-12;
1.65 +const TInt KSizeTocEntry=5; //base toc entry size is 5 bytes (when stored in the file, 8 bytes when presented in memory)
1.66 +const TInt KSizeTocDeltaEntry=8;//delta toc entry size is 8 bytes
1.67 +const TInt KSizeTocDeltaExtra=7;
1.68 +const TInt KElementsTocBuf=48;
1.69 +const TInt KBackTocBuf=20*KSizeTocEntry;
1.70 +const TInt KSizeTocBuf=KElementsTocBuf*KSizeTocEntry;
1.71 +
1.72 +//TPermanentStoreHeader class.
1.73 +//
1.74 +//Represents the data kept in the permanent store file header.
1.75 +//Data members:
1.76 +// - iBackup - "backup TOC reference", 32-bits integer, which keeps the 31-bit file offset of the backup TOC.
1.77 +// Plays important role in the "store commit" procedure.
1.78 +// The LSB is a "dirty" bit. If during the store opening phase the dirty bit is found to be set,
1.79 +// then it means - the previous "store commit" operation has not been completed successfully and
1.80 +// the backup TOC shall be used instead of the TOC;
1.81 +// - iHandle - 32-bit stream handle (MSB - invalid/deleted, 3 bits - unused, 4 bits - generation counter, 24 bits - stream handle).
1.82 +// Plays important role in the "stream relocation" procedure during store compaction.
1.83 +// iHandle keeps the handle of the stream being relocated, so if the commit phase fails, the original stream entry
1.84 +// can be restored at the moment when the store is reopened;
1.85 +// - iRef - Current "TOC reference". Represents a file offset, where the current TOC is;
1.86 +// - iCrc - 16-bit CRC, protecting iBackup, iHandle, iRef;
1.87 +class TPermanentStoreHeader
1.88 + {
1.89 +public:
1.90 + TPermanentStoreHeader() {}
1.91 + inline TUint8* Ptr();
1.92 + inline const TUint8* Ptr() const;
1.93 + TBool IsValid() const;
1.94 +//
1.95 + inline TPermanentStoreHeader(TInt aToc);
1.96 + inline TPermanentStoreHeader(TInt aBackupToc,TInt aHandle,TInt aReference);
1.97 +//
1.98 + inline TBool IsDirty() const;
1.99 + inline void MarkDirty();
1.100 + inline void SetBackupToc(TInt aBackupToc);
1.101 + inline TInt BackupToc() const;
1.102 +//
1.103 + inline TInt Handle() const;
1.104 + inline TInt Reference() const;
1.105 +private:
1.106 + void Set(TInt aBackupToc,TInt aHandle,TInt aReference);
1.107 +private:
1.108 + TUint32 iBackup;
1.109 + TInt32 iHandle;
1.110 + TInt32 iRef;
1.111 + TUint16 iCrc;
1.112 + };
1.113 +
1.114 +//CPermanentStoreToc class.
1.115 +//
1.116 +//Represents the data kept in the permanent file store TOC (Table Of Content).
1.117 +//Each TOC consists of:
1.118 +// - TOC header - CPermanentStoreToc::STocHead structure;
1.119 +// - set of TOC entries - CPermanentStoreToc::TEntry structure;
1.120 +//
1.121 +//Each TOC entry consists of:
1.122 +// - A stream handle (32 bits: MSB - invalid/deleted, 3 bits - unused, 4 bits - generation counter, 24 bits - stream handle);
1.123 +// - A stream ref - the offset of the stream data in the permannet file store;
1.124 +NONSHARABLE_CLASS(CPermanentStoreToc) : public CBase
1.125 + {
1.126 +public:
1.127 + struct TEntry
1.128 + {
1.129 + TInt handle;
1.130 + TInt ref;
1.131 + static TInt Compare(const TEntry&, const TEntry&);
1.132 + };
1.133 + struct STocHead
1.134 + {
1.135 + TInt32 primary;
1.136 + TInt32 avail;
1.137 + TUint32 count;
1.138 + };
1.139 + enum TPut {EWrite,ETestBeforeWrite};
1.140 +public:
1.141 + static CPermanentStoreToc* NewL(TStreamPos aBase,TStreamExchange& aHost,TInt aToc,TInt aBaseReloc);
1.142 + ~CPermanentStoreToc();
1.143 +//
1.144 + inline TInt Extent() const;
1.145 + void Move(TInt aToc,TInt anExtent);
1.146 +//
1.147 + inline TBool IsVirtual() const;
1.148 + TInt RealizeL(TInt aPrimary,TInt anExtent) const;
1.149 + void Adopt(TInt aToc,TInt aPrimary);
1.150 +//
1.151 + inline TInt Primary() const;
1.152 + inline void Changed();
1.153 +//
1.154 + TInt AllocL(TInt anOffset);
1.155 + TInt AllocL();
1.156 + void Cancel(TInt aHandle);
1.157 + void FreeL(TInt aHandle);
1.158 + TInt AtL(TInt aHandle) const;
1.159 + void PutL(TInt aHandle,TInt anOffset,TPut aCheck);
1.160 + TInt GetL(TInt aHandle);
1.161 + TInt Set(TInt aHandle,TInt anOffset);
1.162 +//
1.163 + CPermanentStoreToc(TStreamPos aBase,TStreamExchange& aHost);
1.164 + void ConstructL(TInt aToc,TInt aBaseReloc);
1.165 +
1.166 + TInt RefSpan(TInt aHandle,TInt& aLength);
1.167 +
1.168 +private:
1.169 + inline TStreamPos Base() const;
1.170 + inline TStreamExchange& Host() const;
1.171 + inline const TEntry* Entry(TInt aHandle) const;
1.172 + TEntry* Entry(TInt aHandle);
1.173 + TEntry& FetchL(TInt aHandle);
1.174 + TEntry& DoAllocL();
1.175 + TInt DoAtL(TInt aHandle) const;
1.176 + void PutBaseL(TInt aHandle, TInt aReference);
1.177 + void PutDeltaL(TInt aPos, TInt aHandle, TInt aReference);
1.178 + void PutTocL(TInt aTocBase, TPut aCheck);
1.179 + inline TBool HasDelta() const;
1.180 + TBool IsDelta() const;
1.181 + TInt InternalizeL(RReadStream& aIn, TInt aBaseReloc);
1.182 + TInt DeltaL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
1.183 + TInt RewriteL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
1.184 + TInt SmallTocL(RFrame16Buf& aBuf,TInt aExtent,const STocHead& aHead) const;
1.185 +private:
1.186 + TInt iPrimary;
1.187 + TInt iAvail;
1.188 + TInt iCount;
1.189 + RArray<TEntry> iEntries;
1.190 +//
1.191 + TStreamPos iBase;
1.192 + TStreamExchange* iHost;
1.193 + TInt iMagic;
1.194 + TInt iOff;
1.195 + TInt iExt;
1.196 + TInt iTocOff;
1.197 + TInt iTocExt;
1.198 + __MUTABLE TInt iWindow;
1.199 + __MUTABLE TUint8 iBuf[KSizeTocBuf];
1.200 +private:
1.201 + friend class RPermanentStoreTocIter;
1.202 + };
1.203 +
1.204 +//
1.205 +class RPermanentStoreTocIter
1.206 + {
1.207 +public:
1.208 + typedef CPermanentStoreToc::TEntry TEntry;
1.209 + typedef CPermanentStoreToc::STocHead STocHead;
1.210 +public:
1.211 + RPermanentStoreTocIter(const CPermanentStoreToc& aTable);
1.212 + inline void Close();
1.213 + void Release();
1.214 +//
1.215 + void ResetL();
1.216 + TBool NextL(TEntry& anEntry);
1.217 +private:
1.218 + const CPermanentStoreToc& iTable;
1.219 + RFrame16Buf iBuf;
1.220 + TInt iIndex;
1.221 + TInt iCount;
1.222 + TInt iNext;
1.223 + const TEntry* iDelta;
1.224 + const TEntry* iDeltaEnd;
1.225 + };
1.226 +
1.227 +//
1.228 +class TPermanentStoreCache
1.229 + {
1.230 +public:
1.231 + struct TItem {TInt handle;TInt offset;TInt extent;};
1.232 +public:
1.233 + inline TPermanentStoreCache();
1.234 + const TItem* At(TInt aHandle) const;
1.235 + void Relocated(TInt aHandle,TInt anOffset);
1.236 + void Put(const TItem* anItem,TInt anOffset,TInt anExtent);
1.237 + void Add(TInt aHandle,TInt anOffset,TInt anExtent);
1.238 + void Remove(TInt aHandle);
1.239 + void Invalidate();
1.240 +private:
1.241 + enum {EItems=2*16-1};
1.242 +private:
1.243 + TItem iItems[EItems];
1.244 + };
1.245 +
1.246 +//
1.247 +NONSHARABLE_CLASS(CPermanentStoreCoord) : public CBase
1.248 + {
1.249 +private:
1.250 + enum {EReady,EBackup=0x1,EClip=0x2};
1.251 + enum TFileQoS
1.252 + {
1.253 + EUnknown, //
1.254 + ESimple, //File, "write byte" is an atomic operation
1.255 + EBlockAtomic, //File, "block write" is an atomic operation
1.256 + ETransactional //Transactional file system.
1.257 + };
1.258 + typedef TPermanentStoreCache::TItem TItem;
1.259 +public:
1.260 + inline TBool IsTrim() const;
1.261 + TStreamPos LimitL();
1.262 + inline void Clipped();
1.263 +//
1.264 + TStreamId PrimaryL();
1.265 + void ChangedL();
1.266 + TBool CommitL(TStreamId aPrimary);
1.267 + TBool RevertL(TStreamId& aPrimary);
1.268 +//
1.269 + TStreamId ExtendL();
1.270 + void DeleteL(TStreamId anId);
1.271 +//
1.272 + CPermanentStoreCoord(TStreamPos aBase,TStreamExchange& aHost);
1.273 + void InternalizeL(RReadStream& aStream);
1.274 + ~CPermanentStoreCoord();
1.275 +private:
1.276 + void CanExtendL();
1.277 + TInt DoCreateL();
1.278 + void DoReplaceL(TInt aHandle);
1.279 + TInt DoOpenL(TInt& anOffset,TInt aHandle);
1.280 + void DoRelease(TInt aHandle,TInt anOffset,TInt anExtent);
1.281 + TInt DoCommit(TInt aHandle,TInt anOffset,TInt anExtent);
1.282 +//
1.283 + inline TStreamPos Base() const;
1.284 + inline TStreamExchange& Host() const;
1.285 + inline TInt Toc() const;
1.286 + inline CPermanentStoreToc& Table() const;
1.287 + CPermanentStoreToc& TableL();
1.288 + CPermanentStoreToc& ConsolidateL();
1.289 + void RelocateL(TInt aHandle,TInt anOffset);
1.290 + void MoveL(TInt aToc,TInt anExtent);
1.291 + inline TUint Generation() const;
1.292 + inline void Inc();
1.293 + inline void Dec();
1.294 + inline TBool Accessed() const;
1.295 + TFileQoS FileQoSL();
1.296 + TBool IsBlockAtomicL(TInt aDriveNo) const;
1.297 +//
1.298 + MStreamBuf* BeginL(TPermanentStoreHeader& aHeader);
1.299 +private:
1.300 + TStreamPos iBase;
1.301 + TStreamExchange *iHost;
1.302 + TInt iToc;
1.303 + CPermanentStoreToc* iTable;
1.304 + TInt iReloc;
1.305 + TInt iTarget;
1.306 + TPermanentStoreCache iCache;
1.307 +//
1.308 + TUint iGen;
1.309 + TInt iRefs;
1.310 + TInt iAccess;
1.311 + TInt iExtend;
1.312 + TInt iState;
1.313 + TInt iExt;
1.314 + TFileQoS iFileQos;
1.315 +private:
1.316 + friend class HPermanentStoreBuf;
1.317 + friend class CPermanentStoreCollector;
1.318 + friend class RPermanentFileStoreIter;
1.319 + };
1.320 +//
1.321 +NONSHARABLE_CLASS(HPermanentStoreBuf) : public RFrame16Buf
1.322 + {
1.323 +public:
1.324 + static HPermanentStoreBuf* CreateL(CPermanentStoreCoord& aCoord,TStreamId& anId,TInt aMode=ERead|EWrite);
1.325 + static HPermanentStoreBuf* ReplaceL(CPermanentStoreCoord& aCoord,TStreamId anId,TInt aMode=ERead|EWrite);
1.326 + static HPermanentStoreBuf* OpenL(CPermanentStoreCoord& aCoord,TStreamId anId,TInt aMode=ERead|EWrite);
1.327 +//
1.328 + virtual ~HPermanentStoreBuf();
1.329 +private:
1.330 + static HPermanentStoreBuf* NewLC(CPermanentStoreCoord& aCoord);
1.331 + static HPermanentStoreBuf* ExtendLC(CPermanentStoreCoord& aCoord,TInt aMode);
1.332 + inline HPermanentStoreBuf(CPermanentStoreCoord& aCoord);
1.333 + inline CPermanentStoreCoord& Coord() const;
1.334 +//
1.335 + void DoRelease();
1.336 + void DoSynchL();
1.337 +private:
1.338 + CPermanentStoreCoord* iCoord;
1.339 + TInt iHandle;
1.340 + };
1.341 +//
1.342 +class TPermanentStoreStreamIter
1.343 + {
1.344 +#if defined(__SMALL_BUNDLE)
1.345 + enum {EBundleSize=8-1};
1.346 +#else
1.347 + enum {EBundleSize=64-1};
1.348 +#endif
1.349 +public:
1.350 + void Reset();
1.351 + TInt FillL(CPermanentStoreToc& aToc);
1.352 + TInt Next();
1.353 +//
1.354 + void Relocated(TInt aStream);
1.355 +private:
1.356 + static void Push(TInt* aHeap,TInt* aHole,TInt aValue);
1.357 + static TInt PopPush(TInt* aHeap,TInt* anEnd,TInt aValue);
1.358 +private:
1.359 + TInt* iNext;
1.360 + const TInt* iFinish;
1.361 + TInt iMore;
1.362 + TInt iPos;
1.363 + TInt iTable[EBundleSize];
1.364 + };
1.365 +
1.366 +class TPermanentStoreRelocator;
1.367 +NONSHARABLE_CLASS(CPermanentStoreCollector) : public CBase,public MIncrementalCollector
1.368 + {
1.369 + enum TState
1.370 + {
1.371 + EGetFree,ESkip,EInitRelocator,EFillRelocator,EEvalRelocator,EScanRelocator,ERelocateStream,ERelocateToc,
1.372 + EFastSort,EFastExtent,EFastRelocate
1.373 + };
1.374 + enum {EGranularity = 64};
1.375 + enum {EExtentStep = 64};
1.376 +public:
1.377 + struct TEntry
1.378 + {
1.379 + TInt len;
1.380 + RPermanentStoreTocIter::TEntry entry;
1.381 + };
1.382 +public:
1.383 + static CPermanentStoreCollector* CompactorL(CPermanentStoreCoord& aCoord);
1.384 + static CPermanentStoreCollector* ReclaimerL(CPermanentStoreCoord& aCoord);
1.385 +protected:
1.386 + CPermanentStoreCollector(CPermanentStoreCoord& aCoord);
1.387 + ~CPermanentStoreCollector();
1.388 +private:
1.389 + void DoRelease();
1.390 + void DoResetL(TInt& aCount);
1.391 + void DoNextL(TInt& aStep,TInt& aTotal);
1.392 +//
1.393 + TInt GetFreeL();
1.394 + TInt SkipL(TInt& aTotal);
1.395 + TInt InitRelocator();
1.396 + TInt FillRelocatorL();
1.397 + TInt EvalRelocatorL();
1.398 + TInt ScanRelocator();
1.399 + TInt RelocateStreamL();
1.400 + TBool HaveEnoughSpace() const;
1.401 + TInt ExtentL(TInt aStream);
1.402 +//
1.403 +// fast compaction
1.404 + TInt FastResetL();
1.405 + void FastSort();
1.406 + void FastExtentL(TInt& aTotal);
1.407 + void FastRelocateL(TInt& aTotal);
1.408 + TEntry* BestFit(TInt aPos, TInt aExt, TEntry* aFirst, TEntry* aLast);
1.409 +//
1.410 +// common utilities
1.411 + void RelocateTocL(TInt& aTotal);
1.412 + void RelocateStreamL(const TEntry& aReloc, TInt aExtent);
1.413 + TInt RelocateL(TInt aStream, TInt aLength, TFrameType16 aType, TInt aExtent);
1.414 +//
1.415 + inline TBool Compacting() const;
1.416 + inline CPermanentStoreCoord& Coord() const;
1.417 + inline TStreamExchange& Host() const;
1.418 +private:
1.419 + CPermanentStoreCoord* iCoord;
1.420 + TUint iCoordGen;
1.421 + TStreamExchange* iHost;
1.422 + TStreamMark iMark;
1.423 + TState iState;
1.424 + TInt iFree;
1.425 + TInt iEnd;
1.426 + TEntry* iNext;
1.427 + TEntry* iLast;
1.428 + RArray<TEntry> iStreams;
1.429 + TPermanentStoreRelocator* iReloc;
1.430 + TPermanentStoreStreamIter iIter;
1.431 + };
1.432 +
1.433 +#include "U32PERM.INL"
1.434 +#endif