--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/ustor/US_STD.H Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,691 @@
+// 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:
+//
+
+#include "U32STD.H"
+#include "D32REC.H"
+#include "D32STOR.H"
+#include <s32buf.h>
+#include <s32crypt.h>
+#include <s32btree.h>
+#include <s32ucmp.h>
+#include <e32hal.h>
+#include <e32math.h>
+
+// classes defined
+class TDbStoreIndexStats;
+class CDbStoreIndexDef;
+class TRecordSize;
+class CDbStoreDef;
+class RClusterMap;
+class TClusterLinkCache;
+struct TClusterDes;
+class CCluster;
+class CClusterCache;
+class CDbStoreRecords;
+class CDbStoreBlobs;
+class CDbStoreIndex;
+class CDbStoreTable;
+class RDbStoreReadStream;
+class RDbStoreWriteStream;
+class MDbStreamFilter;
+class CDbStoreCompression;
+
+/**
+@internalComponent
+*/
+enum TStorePanic
+ {
+ EDbUnimplemented,
+ EDbNoStore,
+ EDbCannotSeek,
+ EDbNotFixedFieldType,
+ EDbWrongType
+ };
+
+/**
+@internalComponent
+*/
+GLREF_C void Panic(TStorePanic aPanic);
+
+/**
+@internalComponent
+*/
+GLREF_D const TDbDriver KBuiltinDriver;
+
+/**
+@internalComponent
+*/
+const TUid KDbmsStoreDatabase={268435561};
+
+/**
+@internalComponent
+*/
+const TInt KDbStoreMaxRecordLength=0x200A; // v5.10 32 nullable longtext columns
+const TInt KClusterLimit=0x1000;
+const TInt KMaxClustering=16;
+const TInt KBlobRefSize=sizeof(TDbBlobId)+sizeof(TInt32);
+const TInt KMinInlineLimit=16;
+const TInt KMaxIndexKeySize=248;
+
+/**
+@internalComponent
+*/
+class TDbStoreIndexStats
+ {
+public:
+ /**
+ @internalComponent
+ */
+ class TBound
+ {
+ public:
+ inline void Set(TReal64 aBound);
+ void Set(const TInt64& aBound);
+ void Set(const TText8* aPtr,TInt aLen,const TTextOps& aConv);
+ void Set(const TText16* aPtr,TInt aLen,const TTextOps& aConv);
+ void Set(const TDbLookupKey::SColumn& aBound,const TTextOps& aConv);
+ public:
+ TReal64 iValue;
+ };
+ enum TType {EContinuous,EDiscrete};
+public:
+ inline TDbStoreIndexStats();
+//
+ void InternalizeL(RReadStream& aStream);
+ void ExternalizeL(RWriteStream& aStream) const;
+//
+ inline void Reset(TInt aCardinality=0);
+ inline void Inc();
+ inline void Dec();
+ inline void Refresh(TType aType);
+//
+ inline TBool IsValid() const;
+ inline TBool NeedsRefresh() const;
+ inline TInt Cardinality() const;
+ TInt Span(TUint aInclusion,const TDbLookupKey* aLower,const TDbLookupKey* aUpper,const TTextOps& aConv) const;
+private:
+ inline void Touch();
+ TInt ReverseSpan(TUint aInclusion,const TDbLookupKey* aLower,const TDbLookupKey* aUpper,const TTextOps& aConv) const;
+private:
+ enum {ERefreshFactor=3};
+ enum {EInvalid=-1,ERefresh=0};
+ enum {ERefreshShift=2+ERefreshFactor,EFlagsMask=(1<<ERefreshShift)-1};
+ enum {EFlgDiscrete=0x1,EFlgClustering=0x2};
+private:
+ TInt iCardinality;
+ TInt iRefresh;
+ TUint iFlags;
+public:
+ TBound iLower;
+ TBound iUpper;
+ };
+
+/**
+@internalComponent
+*/
+class CDbStoreIndexDef : public CDbTableIndexDef
+ {
+public:
+ static CDbStoreIndexDef* NewLC(const TDesC& aName,const CDbKey& aKey,const HDbColumnSet& aColumns);
+ static CDbStoreIndexDef* NewL(RReadStream& aStream);
+ void ExternalizeL(RWriteStream& aStream) const;
+ inline void SetTokenId(TStreamId anId);
+ inline TStreamId TokenId() const;
+//
+ static TInt KeySize(const TDbKeyCol& aKeyCol,const TDbColumnDef& aColumn);
+ static void CheckSizeL(const CDbKey& aKey,const HDbColumnSet& aColSet);
+private:
+ CDbStoreIndexDef();
+ static CDbStoreIndexDef* NewLC(const TDesC& aName);
+private:
+ TStreamId iTokenId;
+public:
+ __MUTABLE TDbStoreIndexStats iStats; // cache the statistics here
+ };
+
+/**
+@internalComponent
+*/
+class TRecordSize
+ {
+public:
+ TBool Set(const HDbColumnSet& aColumns);
+ inline TInt Clustering() const;
+ inline TInt InlineLimit() const;
+//
+ static void CheckSizeL(const HDbColumnSet& aColumns);
+ static TInt InlineLimit(const HDbColumnSet& aColumns);
+//
+ static inline TInt FixedFieldSize(TDbColType aType);
+private:
+ TInt iClustering;
+ TInt iInlineLimit;
+private:
+ static TUint8 const FieldSizes[];
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreDef) : public CDbTableDef
+ {
+public:
+ static CDbStoreDef* NewLC(const TDesC& aName,const CDbColSet& aColSet);
+ static CDbStoreDef* NewL(RReadStream& aStream);
+ void ExternalizeL(RWriteStream& aStream) const;
+ inline void SetTokenId(TStreamId anId);
+ inline TStreamId TokenId() const;
+ inline TInt Clustering() const;
+ inline TInt InlineLimit() const;
+ void Changed();
+private:
+ void AlteredColumnSetL(HDbColumnSet& aSet,const CDbColSet& aChange,const CDbColSet& aAdd);
+protected:
+ CDbStoreDef();
+private:
+ static CDbStoreDef* NewLC(const TDesC& aName,TInt aColumnCount);
+private:
+ TStreamId iTokenId;
+ TRecordSize iInfo;
+ };
+
+/**
+@internalComponent
+*/
+typedef TUint32 TClusterId;
+
+/**
+@internalComponent
+*/
+const TClusterId KNullClusterId=0;
+
+/**
+@internalComponent
+*/
+inline TClusterId ClusterId(TDbRecordId aRecordId);
+inline TInt RecordIndex(TDbRecordId aRecordId);
+inline TDbRecordId RecordId(TClusterId aId,TInt aIndex);
+inline TClusterId ClusterId(TStreamId aStreamId);
+
+/**
+@internalComponent
+*/
+class RClusterMap
+ {
+private:
+ enum {EGranularity=8};
+ class TIdPair
+ {
+ public:
+ TClusterId iId;
+ TClusterId iPreviousId;
+ };
+public:
+ enum {ESeparation=16};
+public:
+ inline RClusterMap();
+ inline void Close();
+//
+ void ResetL(TClusterId aHeadCluster);
+ inline void BindL(TClusterId aPrevious,TClusterId aCluster);
+ void DropL(TClusterId aCluster,TClusterId aNext);
+ TBool At(TClusterId aCluster,TClusterId& aPrevious);
+ inline TClusterId LastBound() const;
+ inline void Complete(TClusterId aLastCluster);
+ inline TBool IsComplete() const;
+private:
+ void AddL(TClusterId aCluster);
+ void InsertL(TClusterId aCluster,TClusterId aPrevious);
+ TIdPair* At(TClusterId aCluster);
+private:
+ TIdPair* iMap;
+ TInt iEntries;
+ TInt iAlloc;
+ TClusterId iLastBound;
+ TClusterId iLastMapped;
+ TInt iSkipped;
+ TBool iComplete;
+ };
+
+/**
+@internalComponent
+*/
+class TClusterLinkCache
+ {
+public:
+ inline void Invalidate();
+ inline void Reset(TClusterId aBaseId);
+ inline void Bind(TClusterId aPrevious,TClusterId aCluster,RClusterMap& aMap);
+ void Add(const TClusterId* aFirst,const TClusterId* aLast);
+ void Drop(TClusterId aCluster,TClusterId aNext);
+ TBool Has(TClusterId aCluster) const;
+ TBool At(TClusterId aCluster,TClusterId& aPrevious) const;
+private:
+ void Add(TClusterId aCluster,RClusterMap& aMap);
+private:
+ TClusterId iMap[RClusterMap::ESeparation+1];
+ TClusterId* iEnd;
+ };
+
+/**
+@internalComponent
+*/
+struct TClusterDes
+ {
+public:
+ void InternalizeL(RReadStream& aStream);
+ void ExternalizeL(RWriteStream& aStream) const;
+public:
+ TClusterId iNext;
+ TUint32 iMembership;
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CCluster) : public CBase
+ {
+ friend class CClusterCache;
+private:
+ enum {EGranularity=0x200};
+ enum {EExpandBuffer=0x40};
+public:
+ /**
+ @internalComponent
+ */
+ NONSHARABLE_CLASS(MAlter)
+ {
+ public:
+ virtual TInt RecordExpansion(const TUint8* aRec,TInt aLength);
+ virtual TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength) =0;
+ };
+public:
+ static CCluster* NewL(CDbStoreDatabase& aDatabase);
+ ~CCluster();
+//
+ void FlushL();
+ void Discard();
+//
+ void Create(TClusterId aClusterId);
+ void ReadL(TClusterId aCluster);
+ void Relink(TClusterId aNextClusterId);
+ void AlterL(MAlter& anAlterer);
+//
+ TPtrC8 RecordL(TInt aIndex);
+ TUint8* UpdateL(TInt aIndex,TInt aNewSize);
+ TBool DeleteL(TInt aIndex);
+ inline TBool IsFull() const;
+//
+ inline TClusterId Id() const;
+ inline const TClusterDes& Des() const;
+private:
+ CCluster(CDbStoreDatabase& aDatabase);
+//
+ TInt SetSizeL(TInt aSize);
+ void AdjustMap(TUint8** aMapEntry,TInt aAdjust);
+ void SetRecordL(TInt aIndex,TInt aNewSize);
+ void AdjustL(TUint8** aMapEntry,TInt aAdjust,TUint8* aData);
+private:
+ TDblQueLink iLink;
+ CDbStoreDatabase& iDatabase;
+ TInt iSize;
+ TClusterId iCluster;
+ TClusterDes iDes;
+ TBool iModified;
+ TUint8* iMap[KMaxClustering+1];
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CClusterCache) : public CBase
+ {
+ #ifndef MAX_CLUSTER_CACHE_SIZE
+ #define MAX_CLUSTER_CACHE_SIZE 8
+ #else
+ #if MAX_CLUSTER_CACHE_SIZE < 4
+ #error "MAX_CLUSTER_CACHE_SIZE macro value can't be less than 4"
+ #endif
+ #endif
+ enum {EMaxClusters=MAX_CLUSTER_CACHE_SIZE};
+public:
+ static CClusterCache* NewL(CDbStoreDatabase& aDatabase);
+ ~CClusterCache();
+//
+ void FlushL();
+ void Discard();
+//
+ CCluster* Cluster(TClusterId aCluster);
+ CCluster& ClusterL(TClusterId aCluster);
+ CCluster& ClusterL();
+//
+ inline CDbStoreDatabase& Database();
+ inline CStreamStore& Store();
+private:
+ inline CClusterCache(CDbStoreDatabase& aDatabase);
+//
+ void Apply(void (*aFunc)(CCluster*));
+ CCluster& AddClusterL();
+ CCluster& NewClusterL();
+ CCluster& Touch(CCluster& aCluster);
+private:
+ CDbStoreDatabase& iDatabase;
+ TClusterId iCachePlus1;
+ TClusterId iCachePlus2;
+ TUint8 iFollowOnHits;
+ TUint8 iClusters;
+ TDblQue<CCluster> iCache;
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreRecords) : public CDbRecordSpace
+ {
+public:
+ class TIteratorC;
+ class CIter;
+public:
+ static TStreamId CreateL(CClusterCache& aCache);
+ static CDbStoreRecords* NewL(CClusterCache& aCache,const CDbStoreDef& aDef);
+//
+ static TInt CardinalityL(CStreamStore& aStore,const CDbStoreDef& aDef);
+//
+ TBool GotoL(TDbPosition aPosition,TIteratorC& anIterator);
+ TBool GotoL(TDbRecordId aRecordId,TIteratorC& anIterator);
+ TBool DeletedL(TDbPosition aPosition,TIteratorC& anIterator);
+//
+ inline TClusterId Head() const;
+ inline TInt Count() const;
+ TInt DiscardL(TClusterId& aCluster);
+ TClusterId AlterL(TClusterId aCluster,CCluster::MAlter& anAlterer);
+ void DestroyL();
+// providing for CDbRecordSpace
+ TBool ExistsL(TDbRecordId aRecordId);
+ TPtrC8 ReadL(TDbRecordId aRecordId) const;
+ TUint8* DoReplaceL(TDbRecordId aRecordId,TInt aRecordSize);
+ TUint AutoIncrementL();
+ TUint8* DoNewL(TInt aRecordSize);
+ TDbRecordId AppendL();
+ void DoEraseL(TDbRecordId aRecordId);
+ CDbRecordIter* IteratorL();
+ TBool RestoreL();
+ void SynchL();
+private:
+ CDbStoreRecords(CClusterCache& aCache);
+ ~CDbStoreRecords();
+//
+ TUint8* UpdateRecordL(TDbRecordId aRecordId,TInt aNewSize);
+ void DesL(TClusterDes& aDes,TClusterId aCluster);
+ void CompleteMapL();
+ TClusterId NextClusterL(TClusterDes& aDes,TClusterId aCluster);
+ TClusterId PreviousClusterL(TClusterDes& aDes,TClusterId aCluster);
+ TBool LocateL(TClusterId aCluster);
+private:
+ class TToken
+ {
+ public:
+ void InternalizeL(RReadStream& aStream);
+ void ExternalizeL(RWriteStream& aStream) const;
+ public:
+ TClusterId iHead;
+ TDbRecordId iNext;
+ TInt iCount;
+ TUint iAutoIncrement;
+ };
+private:
+ CClusterCache& iCache;
+ TStreamId iTokenId;
+ TToken iToken;
+ TInt iClustering;
+ TClusterLinkCache iLinks;
+ RClusterMap iMap;
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreBlobs) : public CDbBlobSpace
+ {
+public:
+ CDbStoreBlobs(CDbStoreDatabase& aDatabase,TInt aInlineLimit);
+//
+ MStreamBuf* DoCreateL(TDbBlobId &aBlobId,TDbColType aType);
+ MStreamBuf* ReadL(TDbBlobId aBlobId,TDbColType aType) const;
+ void DoDeleteL(TDbBlobId aBlobId);
+private:
+ CDbStoreDatabase& iDatabase;
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreIndex) : public CDbRecordIndex
+ {
+public:
+ class HKey;
+ class HDupKey;
+ class CIter;
+ class CDiscarder;
+ class CRecover;
+ class CRepair;
+public:
+ static CDbStoreIndex* NewL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef,const CDbTableDef& aTable);
+ ~CDbStoreIndex();
+//
+ static TStreamId CreateL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef);
+ static TBool IsDamagedL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef);
+//
+ inline HKey& Key() const;
+ inline const TBtree& Tree() const;
+ inline TInt Count() const;
+ void RepairL();
+ void DiscardL();
+ void DestroyL();
+private:
+ CDbStoreIndex(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef);
+//
+ void RefreshStatsL();
+// CDbTableIndex framework
+ TFind FindL(TDbRecordId aRecordId,const RDbTableRow& aRow);
+ TBool DoInsertL(TDbRecordId aRecordId,const RDbTableRow& aRow);
+ void DoDeleteL(TDbRecordId aRecordId,const RDbTableRow& aRow);
+ CDbRecordIter* IteratorL(TUint aInclusion,const TDbLookupKey* aLowerBound,const TDbLookupKey* aUpperBound);
+ TBool RestoreL();
+ void AboutToModifyL();
+ void SynchL();
+private:
+ CDbStoreDatabase& iDatabase;
+ TStreamId iTokenId;
+ TBtree iTree;
+ HKey* iKey;
+ TBtreeInlineLeafOrg iLeafOrg;
+ TBtreeInlineIndexOrg iIndexOrg;
+ TDbStoreIndexStats& iStats;
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreIndex::CDiscarder) : public CDbTableDatabase::CStepper
+ {
+public:
+ CDiscarder();
+ ~CDiscarder();
+ TInt Open(CDbStoreIndex* anIndex);
+private:
+ TInt StepL(TInt aStep);
+private:
+ CDbStoreIndex* iIndex;
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreTable) : public CDbTable
+ {
+public:
+ class CDiscarder;
+ class CAlter;
+ class CCompressor;
+ friend class CDiscarder;
+ friend class CAlter;
+ friend class CCompressor;
+public:
+ CDbStoreTable(CDbStoreDatabase& aDatabase,const CDbTableDef& aDef);
+private:
+ inline const CDbStoreDef& Def() const;
+ inline CDbStoreDatabase& Database();
+ inline CDbStoreRecords& StoreRecordsL();
+//
+ TInt RowSize(const TUint8* aRec,TInt aLength);
+ const TUint8* CopyToRowL(TDbCell* aCell,TInt aSize,const TUint8* aRec);
+ TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength,TInt aInlineLimit);
+// providing for CDbTable framework
+ TInt IndexSpanL(const CDbTableIndexDef& aIndex,TUint aInclusion,const TDbLookupKey* aLowerBound,const TDbLookupKey* aUpperBound);
+ CDbRecordSpace* RecordSpaceL();
+ CDbBlobSpace* BlobSpaceL();
+ CDbRecordIndex* RecordIndexL(const CDbTableIndexDef& anIndex);
+ void CopyToRowL(RDbRow& aRow,const TDesC8& aRecord);
+ TInt RecordLength(const RDbRow& aRow);
+ TInt OptimizedRowLength(const RDbRow& aRow);
+ void CopyFromRow(TUint8* aRecord,const RDbRow& aRow);
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreTable::CDiscarder) : public CDbTableDatabase::CStepper, public CCluster::MAlter
+ {
+private:
+ enum {EDiscardClusters=32,EBlobDiscardClusters=2};
+public:
+ CDiscarder();
+ ~CDiscarder();
+ TInt OpenL(CDbStoreTable* aTable);
+private:
+ TInt StepL(TInt aStep);
+ TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength);
+private:
+ CDbStoreTable* iTable;
+ CDbStoreRecords* iRecords;
+ TClusterId iCluster;
+ RDbRow iRow;
+ };
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreTable::CAlter) : public CDbTableDatabase::CStepper, public CCluster::MAlter
+ {
+public:
+ CAlter();
+ ~CAlter();
+ void OpenL(CDbStoreTable* aTable,const HDbColumnSet& aNewSet);
+private:
+ TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength);
+ TInt RecordExpansion(const TUint8* aRec,TInt aLength);
+ TInt StepL(TInt aStep);
+private:
+ TInt iExpansion;
+ TInt iInlineLimit;
+ CDbStoreTable* iTable;
+ CDbStoreRecords* iRecords;
+ TClusterId iCluster;
+ TInt iStep;
+ };
+
+/**
+@internalComponent
+*/
+class RDbStoreReadStream : public RStoreReadStream
+ {
+public:
+ enum TType {EMixed,EBinary,EText};
+public:
+ inline RDbStoreReadStream(CDbStoreDatabase& aDatabase)
+ :iDatabase(aDatabase)
+ {}
+ void FilterL(TType aType,TUint32 aInit);
+private:
+ CDbStoreDatabase& iDatabase;
+ };
+
+/**
+@internalComponent
+*/
+class RDbStoreWriteStream : public RStoreWriteStream
+ {
+public:
+ enum TType {EMixed,EBinary,EText};
+public:
+ inline RDbStoreWriteStream(CDbStoreDatabase& aDatabase)
+ :iDatabase(aDatabase)
+ {}
+ void FilterL(TType aType,TUint32 aInit);
+private:
+ CDbStoreDatabase& iDatabase;
+ };
+
+/**
+@internalComponent
+*/
+class MDbStreamFilter
+ {
+public:
+ virtual MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreReadStream::TType aType) =0;
+ virtual MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreWriteStream::TType aType) =0;
+ };
+
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(CDbStoreCompression) : public CBase, public MDbStreamFilter
+ {
+public:
+ /**
+ @internalComponent
+ */
+ class TEncoding
+ {
+ public:
+ enum {ELiterals=256,ELengths=28,ESpecials=1,EDistances=44};
+ enum {ELitLens=ELiterals+ELengths+ESpecials};
+ enum {EEos=ELiterals+ELengths};
+ public:
+ TUint32 iLitLen[ELitLens];
+ TUint32 iDistance[EDistances];
+ };
+public:
+ static CDbStoreCompression* NewL();
+//
+ void EncodeL();
+ inline void Inflate();
+ void ExternalizeL(RWriteStream& aStream) const;
+ void InternalizeL(RReadStream& aStream);
+// for MDbStreamFilter
+ MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreReadStream::TType aType);
+ MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreWriteStream::TType aType);
+private:
+ inline CDbStoreCompression();
+private:
+ enum TState {EAnalysis,EEncoding,EDecoding,EInflating};
+private:
+ TState iState;
+ TEncoding iEncoding[3];
+ };
+
+#include "US_STD.INL"