windows-nt/Source/XPSP1/NT/inetsrv/query/bigtable/strhash.hxx
2020-09-26 16:20:57 +08:00

262 lines
8.1 KiB
C++

//+-------------------------------------------------------------------------
//
// 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;
}