//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1993. // // File: ColCompr.hxx // // Contents: Column compressor definitions // // Classes: CCompressedCol // CCompressedColHash // XCompressFreeVariant // // History: 22 Mar 1994 Alanw Created // //-------------------------------------------------------------------------- #pragma once #ifdef DISPLAY_INCLUDES #pragma message( "#include <" __FILE__ ">..." ) #endif #include class CPathStore; //+------------------------------------------------------------------------- // // Class: CCompressedCol // // Purpose: An encapsulation of a compressed column // // Interface: // // Notes: // //-------------------------------------------------------------------------- class CCompressedCol { public: enum CompType { FixedHash=1, // fixed data width hash table VarHash, // variable data width hash table PathCompr, // file path name compression StringVecCompr, // string vector compression }; CCompressedCol( VARTYPE vtData, unsigned cbKey, CompType ComprType ) : DataType( vtData ), _cbKeyWidth( cbKey ), _CompressionType( ComprType ) { } CCompressedCol( ) : DataType( VT_NULL ), _cbKeyWidth( sizeof ULONG ), _CompressionType( (CompType) 0 ) { } virtual ~CCompressedCol( ) { } virtual void AddData(PROPVARIANT const * const pvarnt, ULONG * pKey, GetValueResult& reIndicator) = 0; virtual GetValueResult GetData(PROPVARIANT * pvarnt, VARTYPE PreferredType, ULONG key = 0, PROPID prop = 0) = 0; virtual void FreeVariant(PROPVARIANT * pvarnt) = 0; virtual ULONG MemUsed(void) = 0; VARTYPE DataType; virtual CPathStore * GetPathStore() { return 0; } virtual BOOL FindData(PROPVARIANT const * const pvarnt, ULONG & rKey ) { Win4Assert(!"FindData should not be called!"); return FALSE; } protected: unsigned _cbKeyWidth; // width in row data (0 if compressed and no // key needed CompType _CompressionType; }; //+------------------------------------------------------------------------- // // Class: CCompressedColHash // // Purpose: A compressed column which uses a hash table for // redundant value elimination. // // Interface: CCompressedCol // // Notes: The hash table code is generic and intended for // any fixed sized data. A hash table may be parameterized // for any particular data type by supplying the data // item width, an initial hash table size and optionally // a hash function. Items in the hash table are uniquely // identified by their offset in the data area. // // Entries are only added to the table, never removed. // This reduces storage requirements since reference // counts do not need to be stored. // //-------------------------------------------------------------------------- typedef ULONG HASHKEY; const HASHKEY MAX_HASHKEY = 0xFFFFFFFF; class CCompressedColHash: public CCompressedCol { public: typedef ULONG (* PFNHASH) (BYTE *, USHORT); static ULONG DefaultHash(BYTE *pbData, USHORT cbData); CCompressedColHash( VARTYPE vtData, USHORT cbDataWidth, PFNHASH pfnHashFunction = DefaultHash); ~CCompressedColHash(); void AddData(PROPVARIANT const * const pvarnt, ULONG * pKey, GetValueResult& reIndicator); GetValueResult GetData(PROPVARIANT * pvarnt, VARTYPE PreferredType, ULONG key = 0, PROPID prop = 0); void FreeVariant(PROPVARIANT * pvarnt); ULONG MemUsed(void) { // return (_pAlloc->MemUsed()); return _cbData; } protected: VOID _AddData(BYTE *pbData, USHORT cbDataSize, ULONG* pKey); VOID _Rehash(HASHKEY iKey, BYTE *pbData); VOID _GrowHashTable( void ); HASHKEY* _IndexHashkey( HASHKEY iKey ); ULONG _GetHashIndex( BYTE *pbData, USHORT cbData ) { ULONG ulHash = _pfnHash( pbData, cbData ); return ulHash%_cHashEntries; } void _ClearAll(); HASHKEY* _pHashTable; // pointer to hash table PBYTE _pDataItems; // pointer to data items HASHKEY _cDataItems; // number of entries in pDataItems const USHORT _cbDataWidth; // width of each data item private: USHORT _NextHashSize( HASHKEY cItems, USHORT cHash ); PFNHASH _pfnHash; // hash function USHORT _cHashEntries; // size of hash table USHORT _maxChain; // maximum hash chain length USHORT _fGrowthInProgress; // TRUE if _GrowHashTable active // CLEANCODE - the class should be changed to use CFixedAllocator ULONG _cbData; // size of allocation for compressed data PVOID _pData; // pointer to compression data ULONG _ulMemCounter; // Memory allocation counter // // Serialization. // CMutexSem _mtxSerialize; // Serialize Table access }; //+------------------------------------------------------------------------- // // Method: CCompressedColHash::_IndexHashkey, protected inline // // Synopsis: Index a hash key and return a pointer to the hash // chain. The data will be found at the return value // plus sizeof (HASHKEY) // // Arguments: [iKey] - lookup key value // // Returns: HASHKEY*, pointer to the indexed item // // Notes: // //-------------------------------------------------------------------------- inline HASHKEY* CCompressedColHash::_IndexHashkey( HASHKEY iKey ) { Win4Assert(iKey > 0 && iKey <= _cDataItems); return (HASHKEY *) ((BYTE *)_pDataItems + (iKey - 1) * (sizeof (HASHKEY) + _cbDataWidth)); } ULONG GuidHash(BYTE *pbData, USHORT cbData); //+------------------------------------------------------------------------- // // Class: XCompressFreeVariant // // Purpose: Safe pointer for variants created by compressors // // Interface: // // Notes: This class assures that variant structures are properly freed // in case of exception unwinds. // //-------------------------------------------------------------------------- class XCompressFreeVariant { CCompressedCol * _pCompr; PROPVARIANT * _pVarnt; public: XCompressFreeVariant() : _pCompr( 0 ), _pVarnt( 0 ) { END_CONSTRUCTION( XCompressFreeVariant ); } ~XCompressFreeVariant( ) { if (_pCompr) _pCompr->FreeVariant(_pVarnt); } void Set( CCompressedCol * pCompr, PROPVARIANT * pVarnt ) { _pCompr = pCompr; _pVarnt = pVarnt; } };