persistentstorage/dbms/ustor/US_STD.H
changeset 0 08ec8eefde2f
--- /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"