|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: StrHash.hxx
//
// Contents: String column compressor definitions
//
// Classes: CCompressedColHashString
// CStringBuffer
//
// History: 03 Mar 1995 Alanw Created
//
//--------------------------------------------------------------------------
#pragma once
#include <tblalloc.hxx>
#include "colcompr.hxx"
const DWORD stridInvalid = 0xffffffff;
//+-------------------------------------------------------------------------
//
// Class: CStringBuffer
//
// Purpose: A smart string buffer used for the GetData methods
// of CCompressedColHashString and CCompressedColPath.
//
// Interface:
//
// Notes:
//
// History: 03 Mar 1995 Alanw Created
//
//--------------------------------------------------------------------------
class CStringBuffer { public: CStringBuffer() : _cchPathBuffer(0), _pwchPathBuffer(0), _fPathBufferInUse(FALSE) { }
~CStringBuffer() { delete [] _pwchPathBuffer; }
BOOL InUse() { return _fPathBufferInUse; }
PWSTR Alloc( unsigned cchString );
BOOL FreeConditionally( PWSTR pwszBuf ) { if (_fPathBufferInUse && pwszBuf == _pwchPathBuffer) { _fPathBufferInUse = FALSE; return TRUE; } return FALSE; }
private: //
// Full path buffer used by GetData. At most one GetData can be
// outstanding at any one time.
//
unsigned _cchPathBuffer; // size of _pwchPathBuffer
PWSTR _pwchPathBuffer; // temp. buffer for path
BOOL _fPathBufferInUse; // TRUE if _pwchPathBuffer in use
};
//+-------------------------------------------------------------------------
//
// Method: CStringBuffer::Alloc, public inline
//
// Synopsis: Return a pointer to a buffer large enough to
// accomodate an the requested number of characters.
//
// Arguments: [cchPath] - number of characters needed, including
// null terminator
//
// Returns: PWSTR - pointer to buffer
//
// Notes: At most one active GetData can ask for the path
// at a time. GetData can be a performance hot spot,
// so we don't want to do an allocation every time.
//
//--------------------------------------------------------------------------
inline PWSTR CStringBuffer::Alloc( unsigned cchPath ) { Win4Assert( _fPathBufferInUse == FALSE ); if (cchPath > _cchPathBuffer) { delete [] _pwchPathBuffer; _pwchPathBuffer = new WCHAR[ cchPath ]; _cchPathBuffer = cchPath; } _fPathBufferInUse = TRUE; return _pwchPathBuffer; }
//+-------------------------------------------------------------------------
//
// Class: CCompressedColHashString
//
// Purpose: A compressed column which uses a hash table for
// redundant value elimination. Specific to storing
// string (VT_LPWSTR and VT_LPSTR) values.
//
// Interface: CCompressedCol
//
// Notes: To save storage space, strings are compressed to
// ANSI strings whenever possible (only the ASCII
// subset is tested for compression). Also, at most
// MAX_HASHKEY distinct strings will be stored.
//
// Entries are only added to the table, never removed.
// This reduces storage requirements since reference
// counts do not need to be stored.
//
// History: 03 May 1994 Alanw Created
//
//--------------------------------------------------------------------------
class CCompressedColHashString: public CCompressedCol { friend class CCompressedColPath; // needs access to _pAlloc, _AddData
// and _GetStringBuffer.
friend class CStringStore;
struct HashEntry { HASHKEY ulHashChain; // hash chain (must be first!)
TBL_OFF ulStringKey; // key to string value in variable data
USHORT usSizeFmt; // size and format(ascii/wchar) of the string
};
public: CCompressedColHashString( BOOL fOptimizeAscii = TRUE ): CCompressedCol( VT_LPWSTR, // vtData,
sizeof (HASHKEY), // cbKey,
VarHash // ComprType
), _cHashEntries( 0 ), _cDataItems( 0 ), _pAlloc( NULL ), _fOptimizeAscii( fOptimizeAscii ), _cbDataWidth( sizeof (HashEntry) ), _Buf1(), _Buf2() { }
~CCompressedColHashString() { delete _pAlloc; }
ULONG HashString( BYTE *pbData, USHORT cbData, VARTYPE vtType, BOOL fNullTerminated );
ULONG HashWSTR( WCHAR const * pwszStr, USHORT nChar ); ULONG HashSTR ( CHAR const * pszStr, USHORT nChar );
void AddData(PROPVARIANT const * const pvarnt, ULONG * pKey, GetValueResult& reIndicator);
void AddData( const WCHAR * pwszStr, ULONG & key, GetValueResult& reIndicator );
void AddCountedWStr( const WCHAR * pwszStr, ULONG cwcStr, ULONG & key, GetValueResult& reIndicator );
ULONG FindCountedWStr( const WCHAR * pwszStr, ULONG cwcStr );
GetValueResult GetData( ULONG key, WCHAR * pwszStr, ULONG & cwcStr); GetValueResult GetData( PROPVARIANT * pvarnt, VARTYPE PreferredType, ULONG key = 0, PROPID prop = 0);
const WCHAR * GetCountedWStr( ULONG key , ULONG & cwcStr );
void FreeVariant(PROPVARIANT * pvarnt);
ULONG MemUsed(void) { return _pAlloc ? _pAlloc->MemUsed() : 0; }
USHORT DataLength(ULONG key);
private:
PWSTR _GetStringBuffer( unsigned cchPath );
VOID _AddData( BYTE *pbData, USHORT cbDataSize, VARTYPE vt, ULONG* pKey, BOOL fNullTerminated );
ULONG _FindData( BYTE * pbData, USHORT cbDataSize, VARTYPE vt, BOOL fNullTerminated );
VOID _GrowHashTable( void );
HashEntry* _IndexHashkey( HASHKEY iKey );
USHORT _cHashEntries; // size of hash table
const USHORT _cbDataWidth; // width of each data item
ULONG _cDataItems; // number of entries in pDataItems
CFixedVarAllocator *_pAlloc; // Data allocator
BOOL _fOptimizeAscii;
//
// Name buffers used by GetData. There are two because sorted
// insertion operations in the table can require two buffers.
//
CStringBuffer _Buf1; CStringBuffer _Buf2; };
//+-------------------------------------------------------------------------
//
// Method: CCompressedColHashString::_IndexHashkey, private inline
//
// Synopsis: Index a hash key and return a pointer to the corresponding
// data entry.
//
// Arguments: [iKey] - lookup key value
//
// Returns: HashEntry*, pointer to the indexed item
//
// Notes:
//
//--------------------------------------------------------------------------
inline CCompressedColHashString::HashEntry* CCompressedColHashString::_IndexHashkey( HASHKEY iKey ) { Win4Assert(iKey > 0 && iKey <= _cDataItems); return ((HashEntry*) _pAlloc->FirstRow()) + iKey - 1; }
|