williamr@2: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). williamr@2: // All rights reserved. williamr@2: // This component and the accompanying materials are made available williamr@4: // under the terms of "Eclipse Public License v1.0" williamr@2: // which accompanies this distribution, and is available williamr@4: // at the URL "http://www.eclipse.org/legal/epl-v10.html". williamr@2: // williamr@2: // Initial Contributors: williamr@2: // Nokia Corporation - initial contribution. williamr@2: // williamr@2: // Contributors: williamr@2: // williamr@2: // Description: williamr@2: // williamr@2: williamr@2: #if !defined(__S32STOR_H__) williamr@2: #define __S32STOR_H__ williamr@2: #if !defined(__S32STD_H__) williamr@2: #include williamr@2: #endif williamr@2: #if !defined(__S32SHARE_H__) williamr@2: #include williamr@2: #endif williamr@2: #if !defined(__S32PAGE_H__) williamr@2: #include williamr@2: #endif williamr@2: williamr@2: class MIncrementalCollector; williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Provides the core abstract framework for stores allowing streams to be williamr@2: created and manipulated. williamr@2: */ williamr@2: class CStreamStore : public CBase williamr@2: { williamr@2: public: williamr@2: inline TStreamId ExtendL(); williamr@2: IMPORT_C void Delete(TStreamId anId); williamr@2: IMPORT_C void DeleteL(TStreamId anId); williamr@2: // williamr@2: IMPORT_C TInt Commit(); williamr@2: inline void CommitL(); williamr@2: IMPORT_C void Revert(); williamr@2: inline void RevertL(); williamr@2: // williamr@2: IMPORT_C TInt ReclaimL(); williamr@2: IMPORT_C TInt CompactL(); williamr@2: private: williamr@2: virtual IMPORT_C TStreamId DoExtendL(); williamr@2: virtual IMPORT_C void DoDeleteL(TStreamId anId); williamr@2: williamr@2: /** Opens the requested stream for reading. The function should return a williamr@2: stream buffer positioned at the beginning of this stream. williamr@2: williamr@2: This function is called by the OpenL() and OpenLC() member functions of williamr@2: RStoreReadStream. williamr@2: williamr@2: @param anId The stream to be read. williamr@2: @return A stream buffer positioned at the beginning of the stream to be read. williamr@2: @see RStoreReadStream::OpenL() williamr@2: @see RStoreReadStream::OpenLC() */ williamr@2: virtual MStreamBuf* DoReadL(TStreamId anId) const=0; williamr@2: williamr@2: /** Creates a new stream in the store. The function gets the allocated williamr@2: stream id in the anId parameter. A stream buffer for the stream should be williamr@2: returned, ready to write into the new stream. This provides the williamr@2: implementation for the RStoreWriteStream::CreateL() functions. williamr@2: williamr@2: @param anId On return, contains the allocated stream id. williamr@2: @return The stream buffer to be written to. */ williamr@2: virtual MStreamBuf* DoCreateL(TStreamId& anId)=0; williamr@2: virtual IMPORT_C MStreamBuf* DoWriteL(TStreamId anId); williamr@2: virtual IMPORT_C MStreamBuf* DoReplaceL(TStreamId anId); williamr@2: virtual IMPORT_C void DoCommitL(); williamr@2: virtual IMPORT_C void DoRevertL(); williamr@2: virtual IMPORT_C MIncrementalCollector* DoReclaimL(); williamr@2: virtual IMPORT_C MIncrementalCollector* DoCompactL(); williamr@2: private: williamr@2: friend class RStoreReadStream; williamr@2: friend class RStoreWriteStream; williamr@2: friend class RStoreReclaim; williamr@2: }; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Persistent store abstract base class. It provides the behaviour for setting williamr@2: and retrieving the root stream id. williamr@2: williamr@2: Before closing a persistent store, the root stream id must be set. After opening williamr@2: a persistent store, the first thing done is to look up the root stream id. williamr@2: The root stream can then be opened and data read from the store. williamr@2: williamr@2: @see CFileStore williamr@2: */ williamr@2: class CPersistentStore : public CStreamStore williamr@2: { williamr@2: public: williamr@2: inline TStreamId Root() const; williamr@2: inline void SetRootL(TStreamId anId); williamr@2: protected: williamr@2: inline CPersistentStore(); williamr@2: private: williamr@2: virtual IMPORT_C void DoSetRootL(TStreamId anId); williamr@2: protected: williamr@2: TStreamId iRoot; williamr@2: }; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Performs space reclamation or compaction on a permanent file store in williamr@2: incremental steps. williamr@2: williamr@2: Reclaiming unused space makes it available for re-use by the store. Compacting williamr@2: makes unused space available for re-use by the relevant system pool — for williamr@2: example, the filing system in the case of file-based stores. williamr@2: williamr@2: Once compaction is complete, the store must be committed. williamr@2: williamr@2: Notes: williamr@2: williamr@2: Space reclamation and compaction are only supported by the file store williamr@2: CPermanentFileStore and are not supported by embedded or direct file stores. williamr@2: williamr@2: Use active objects when implementing space reclamation or compaction williamr@2: asynchronously. williamr@2: williamr@2: This class performs incremental compaction/reclamation. These operations can williamr@2: be performed in a possibly long running single step using CStreamStore williamr@2: functions. williamr@2: */ williamr@2: class RStoreReclaim williamr@2: { williamr@2: public: williamr@2: inline RStoreReclaim(); williamr@2: IMPORT_C void OpenL(CStreamStore& aStore,TInt& aCount); williamr@2: IMPORT_C void OpenLC(CStreamStore& aStore,TInt& aCount); williamr@2: IMPORT_C void CompactL(CStreamStore& aStore,TInt& aCount); williamr@2: IMPORT_C void CompactLC(CStreamStore& aStore,TInt& aCount); williamr@2: inline void Close(); williamr@2: IMPORT_C void Release(); williamr@2: // williamr@2: IMPORT_C void ResetL(TInt& aCount); williamr@2: IMPORT_C void NextL(TInt& aStep); williamr@2: IMPORT_C void Next(TPckgBuf& aStep,TRequestStatus& aStatus); williamr@2: IMPORT_C void NextL(TPckgBuf& aStep,TRequestStatus& aStatus); williamr@2: IMPORT_C TInt Next(TInt& aStep); williamr@2: // williamr@2: inline TInt Available() const; williamr@2: private: williamr@2: MIncrementalCollector* iCol; williamr@2: TPckgBuf iAvail; williamr@2: }; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Encapsulates an embedded store. williamr@2: williamr@2: The embedded store may contain an arbitrarily complex network of streams, williamr@2: but is viewed as simply another stream by the embedding store. This means williamr@2: that the embedded store can dealt with as a single stream for purposes of williamr@2: copying or deleting. williamr@2: williamr@2: Once streams within the embedded store have been committed and closed, they williamr@2: cannot subsequently be changed, i.e. streams cannot be replaced, deleted, williamr@2: extended or changed in any way. williamr@2: williamr@2: @see CPersistentStore williamr@2: */ williamr@2: class CEmbeddedStore : public CPersistentStore williamr@2: { williamr@2: public: williamr@2: IMPORT_C static CEmbeddedStore* FromL(RReadStream& aHost); williamr@2: IMPORT_C static CEmbeddedStore* FromLC(RReadStream& aHost); williamr@2: IMPORT_C static CEmbeddedStore* NewL(RWriteStream& aHost); williamr@2: IMPORT_C static CEmbeddedStore* NewLC(RWriteStream& aHost); williamr@2: // williamr@2: inline static TStreamPos Position(TStreamId anId); williamr@2: // williamr@2: IMPORT_C void Detach(); williamr@2: inline void Reattach(MStreamBuf* aHost); williamr@2: inline MStreamBuf* Host() const; williamr@2: inline TStreamPos Start() const; williamr@2: // williamr@2: IMPORT_C CEmbeddedStore(MStreamBuf* aHost); williamr@2: IMPORT_C void MarshalL(RReadStream& aStream); williamr@2: IMPORT_C void ConstructL(RWriteStream& aStream); williamr@2: IMPORT_C ~CEmbeddedStore(); williamr@2: protected: williamr@2: IMPORT_C MStreamBuf* DoReadL(TStreamId anId) const; williamr@2: IMPORT_C MStreamBuf* DoCreateL(TStreamId& anId); williamr@2: private: williamr@2: IMPORT_C void DoSetRootL(TStreamId anId); williamr@2: IMPORT_C void DoCommitL(); williamr@2: // williamr@2: static CEmbeddedStore* DoNewLC(MStreamBuf* aHost); williamr@2: private: williamr@2: __MUTABLE TStreamExchange iHost; williamr@2: TStreamPos iStart; williamr@2: }; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Dictionary store interface. williamr@2: williamr@2: This is an abstract class which provides the necessary interface for using williamr@2: concrete dictionary stores. williamr@2: williamr@2: A dictionary store is a store where a stream is accessed by UID (TUid), rather williamr@2: than directly by stream id (TStreamId). williamr@2: williamr@2: This type of store contains streams in the usual way but, in addition, the williamr@2: root stream is a stream dictionary. The stream dictionary provides a list williamr@2: of two-way associations between unique identifiers and stream ids. williamr@2: williamr@2: Note that a dictionary store object does not derive from CStreamStore, but williamr@2: owns a persistent store and a stream dictionary as part of its implementation. williamr@2: williamr@2: @see CStreamDictionary williamr@2: @see CPersistentStore williamr@2: @see CDictionaryFileStore williamr@2: @see TUid williamr@2: @see TStreamId williamr@2: */ williamr@2: class CDictionaryStore : public CBase williamr@2: { williamr@2: public: williamr@2: IMPORT_C TBool IsNullL() const; williamr@2: IMPORT_C TBool IsPresentL(TUid aUid) const; williamr@2: IMPORT_C void Remove(TUid aUid); williamr@2: IMPORT_C void RemoveL(TUid aUid); williamr@2: // williamr@2: IMPORT_C TInt Commit(); williamr@2: IMPORT_C void CommitL(); williamr@2: IMPORT_C void Revert(); williamr@2: IMPORT_C void RevertL(); williamr@2: // williamr@2: IMPORT_C ~CDictionaryStore(); williamr@2: protected: williamr@2: IMPORT_C void ConstructL(); williamr@2: private: williamr@2: CStreamDictionary* DictionaryL() const; williamr@2: MStreamBuf* GetSourceL(TUid aUid) const; williamr@2: MStreamBuf* GetSinkL(TUid aUid); williamr@2: protected: williamr@2: CPersistentStore* iStore; williamr@2: private: williamr@2: __MUTABLE CStreamDictionary* iDictionary; williamr@2: TBool iDictionaryHasChanged; williamr@2: private: williamr@2: friend class RDictionaryReadStream; williamr@2: friend class RDictionaryWriteStream; williamr@2: friend class HDictionaryStoreBuf; williamr@2: }; williamr@2: // williamr@2: const TInt KDictionaryCommitThreshold = 1024; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Supports the opening and manipulation of a stream in a dictionary store. williamr@2: williamr@2: Construct an object of this type to open an existing stream in a dictionary williamr@2: store for reading. williamr@2: williamr@2: @see CDictionaryStore williamr@2: */ williamr@2: class RDictionaryReadStream : public RReadStream williamr@2: { williamr@2: public: williamr@2: IMPORT_C void OpenL(const CDictionaryStore& aDictStore,TUid aUid); williamr@2: IMPORT_C void OpenLC(const CDictionaryStore& aDictStore,TUid aUid); williamr@2: }; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Supports the creation or replacement of a stream a dictionary store. williamr@2: williamr@2: @see CDictionaryStore williamr@2: */ williamr@2: class RDictionaryWriteStream : public RWriteStream williamr@2: { williamr@2: public: williamr@2: /** Constructs an uninitialised object. It is necessary because there are williamr@2: also non-default constructors in this class. */ williamr@2: RDictionaryWriteStream() {} williamr@2: inline RDictionaryWriteStream(const MExternalizer& anExter); williamr@2: IMPORT_C void AssignL(CDictionaryStore& aDictStore,TUid aUid); williamr@2: IMPORT_C void AssignLC(CDictionaryStore& aDictStore,TUid aUid); williamr@2: }; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Persistent settings to use for a RStorePagePool. williamr@2: williamr@2: @see RStorePagePool williamr@2: */ williamr@2: class TStorePagePoolToken williamr@2: { williamr@2: public: williamr@2: /** Provides a TStorePagePoolToken initialisation flag. */ williamr@2: enum TEmpty williamr@2: /** Initialise for an empty page pool flag. */ williamr@2: {EEmpty}; williamr@2: public: williamr@2: /** Default constructor. */ williamr@2: TStorePagePoolToken() {} williamr@2: williamr@2: /** Constructor that intialises the TStorePagePoolToken for an empty page pool. williamr@2: williamr@2: @param Intialises for an empty page pool */ williamr@2: inline TStorePagePoolToken(TEmpty); williamr@2: inline void Touch(); williamr@2: // williamr@2: inline TBool HasAvailable() const; williamr@2: inline TBool IsEmpty() const; williamr@2: // williamr@2: IMPORT_C void ExternalizeL(RWriteStream& aStream) const; williamr@2: IMPORT_C void InternalizeL(RReadStream& aStream); williamr@2: private: williamr@2: inline TStorePagePoolToken(TStreamId aHead,TPageRef anAvail); williamr@2: private: williamr@2: TStreamId iHead; williamr@2: TPageRef iAvail; williamr@2: private: williamr@2: friend class RStorePagePool; williamr@2: }; williamr@2: #if defined(__NO_CLASS_CONSTS__) williamr@2: #define KEmptyStorePagePoolToken TStorePagePoolToken(TStorePagePoolToken::EEmpty) williamr@2: #else williamr@2: /** Defines a TStorePagePoolToken object initialised for an empty page pool. */ williamr@2: const TStorePagePoolToken KEmptyStorePagePoolToken=TStorePagePoolToken::EEmpty; williamr@2: #endif williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Uses a store to implement the page pool interface MPagePool. williamr@2: williamr@2: Pages can be reclaimable (tracked by the page pool, so that they can be freed williamr@2: when required) or not (in which case they must be deleted explicitly): this williamr@2: is indicated by a flag of type TPageReclamation. Non-reclaimable pages each williamr@2: have their own stream in the store; reclaimable pages are bundled 15 to a williamr@2: stream. To track the reclaimable pages, the page pool has a separate token, williamr@2: type TStorePagePoolToken, that must be saved by the user of the pool. williamr@2: williamr@2: The store used must support CStreamStore::ExtendL(), CStreamStore::DeleteL() williamr@2: and allow streams to be re-written. CPermanentFileStore meets these conditions. williamr@2: williamr@2: A store page pool uses a cache to store pages in-memory and to cache frequently williamr@2: accessed pages. You should provide a cache object (CPageCache) to the pool williamr@2: for this purpose. williamr@2: williamr@2: @see CPageCache williamr@2: @see CPermanentFileStore williamr@2: @see CStreamStore williamr@2: @see TPageReclamation williamr@2: */ williamr@2: class RStorePagePool : public TCachePagePool williamr@2: { williamr@2: friend class StorePagePool; williamr@2: public: williamr@2: IMPORT_C RStorePagePool(); williamr@2: IMPORT_C RStorePagePool(CPageCache& aCache); williamr@2: IMPORT_C RStorePagePool(CStreamStore& aStore); williamr@2: IMPORT_C RStorePagePool(CStreamStore& aStore,const TStorePagePoolToken& aToken); williamr@2: IMPORT_C void Create(CStreamStore& aStore); williamr@2: IMPORT_C void Open(CStreamStore& aStore,const TStorePagePoolToken& aToken); williamr@2: IMPORT_C TStorePagePoolToken Token() const; williamr@2: IMPORT_C void Close(); williamr@2: inline void Release(); williamr@2: // williamr@2: inline TBool IsDirty() const; williamr@2: inline void MarkCurrent(); williamr@2: inline void MarkDirty(); williamr@2: // williamr@2: inline TBool HasAvailable() const; williamr@2: inline void Discard(); williamr@2: // williamr@2: inline TBool IsEmpty() const; williamr@2: IMPORT_C TBool ReclaimL(); williamr@2: IMPORT_C void ReclaimAllL(); williamr@2: protected: williamr@2: IMPORT_C TPageRef ExtendL(const TAny* aPage,TPageReclamation aReclamation); williamr@2: IMPORT_C void WriteL(TPageRef aRef,const TAny* aPage,TPageChange aChange); williamr@2: IMPORT_C void ReadL(TPageRef aRef,TAny* aPage); williamr@2: IMPORT_C void DoDeleteL(TPageRef aRef); williamr@2: private: williamr@2: inline void CacheDeleteL(TPageRef aRef); williamr@2: private: williamr@2: CStreamStore* iStore; williamr@2: TStreamId iHead; williamr@2: TPageRef iAvail; williamr@2: TBool iDirty; williamr@2: }; williamr@2: williamr@2: /** williamr@2: * @publishedAll williamr@2: * @released williamr@2: * Interface for incrementally reclaiming or compacting space in a stream store. williamr@2: The interface allows these actions to be performed in small steps, so that williamr@2: applications can remain responsive while doing these potentially long-running williamr@2: tasks. williamr@2: williamr@2: An instance of a class derived from this interface is returned by williamr@2: StreamStore::DoReclaimL() and DoCompactL(). Each step is carried out in williamr@2: response to a call of DoNextL() and the object is released on completion of williamr@2: the last step. williamr@2: williamr@2: Notes: williamr@2: williamr@2: One-step reclaim using CStreamStore::ReclaimL() is actually implemented in williamr@2: terms of the incremental collector. williamr@2: williamr@2: A CStreamStore implementation will only need to implement a collector class williamr@2: if it supports reclamation or compaction. williamr@2: */ williamr@2: class MIncrementalCollector williamr@2: { williamr@2: public: williamr@2: inline void Close(); williamr@2: inline void Release(); williamr@2: // williamr@2: inline void ResetL(TInt& aCount); williamr@2: inline void NextL(TInt& aStep,TInt& aTotal); williamr@2: inline void NextL(TPckgBuf& aStep,TRequestStatus& aStatus,TPckgBuf& aTotal); williamr@2: protected: williamr@2: /** Protected constructor. Protecting the constructor ensures that this williamr@2: abstract class cannot be instantiated. williamr@2: williamr@2: MIncrementalCollector(const MIncrementalCollector&); williamr@2: williamr@2: MIncrementalCollector& operator=(const MIncrementalCollector&); williamr@2: williamr@2: Private copy constructor and copy assignment to prevent */ williamr@2: MIncrementalCollector() {} williamr@2: private: williamr@2: /** Protected constructor. Protecting the constructor ensures that this williamr@2: abstract class cannot be instantiated. williamr@2: williamr@2: MIncrementalCollector(const MIncrementalCollector&); williamr@2: williamr@2: MIncrementalCollector& operator=(const MIncrementalCollector&); williamr@2: williamr@2: Private copy constructor and copy assignment to prevent */ williamr@2: MIncrementalCollector(const MIncrementalCollector&); williamr@2: MIncrementalCollector& operator=(const MIncrementalCollector&); williamr@2: // williamr@2: virtual IMPORT_C void DoRelease(); williamr@2: williamr@2: /** Implementation of the public ResetL() function. This signals that the williamr@2: client wants to start or retsart the operation from the beginning. A new williamr@2: progress count should be returned in aCount. williamr@2: williamr@2: @param aCount On return, contains a progress count for the williamr@2: reclamation/compaction process. */ williamr@2: virtual void DoResetL(TInt& aCount)=0; williamr@2: williamr@2: /** Implementation of the public synchronous NextL() function. The next williamr@2: step in the reclamation should be done, reporting progress in aStep and williamr@2: aTotal. williamr@2: williamr@2: @param aStep The progress value from either the last NextL() increment of williamr@2: from ResetL() if the reclamation/compaction was restarted. On return, williamr@2: should contain the new progress value, which can be used in subsequent williamr@2: calls to NextL(). This must be equal to, or less than, the previous williamr@2: value — a zero value must be used to indicate that the operation is williamr@2: complete. williamr@2: @param aTotal On return, should contain the total amount of free space in williamr@2: the store. */ williamr@2: virtual void DoNextL(TInt& aStep,TInt& aTotal)=0; williamr@2: virtual IMPORT_C void DoNextL(TPckgBuf& aStep,TRequestStatus& aStatus,TPckgBuf& aTotal); williamr@2: }; williamr@2: williamr@2: #include williamr@2: #endif