Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
8.1 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: StrHash.hxx
  7. //
  8. // Contents: String column compressor definitions
  9. //
  10. // Classes: CCompressedColHashString
  11. // CStringBuffer
  12. //
  13. // History: 03 Mar 1995 Alanw Created
  14. //
  15. //--------------------------------------------------------------------------
  16. #pragma once
  17. #include <tblalloc.hxx>
  18. #include "colcompr.hxx"
  19. const DWORD stridInvalid = 0xffffffff;
  20. //+-------------------------------------------------------------------------
  21. //
  22. // Class: CStringBuffer
  23. //
  24. // Purpose: A smart string buffer used for the GetData methods
  25. // of CCompressedColHashString and CCompressedColPath.
  26. //
  27. // Interface:
  28. //
  29. // Notes:
  30. //
  31. // History: 03 Mar 1995 Alanw Created
  32. //
  33. //--------------------------------------------------------------------------
  34. class CStringBuffer
  35. {
  36. public:
  37. CStringBuffer() :
  38. _cchPathBuffer(0),
  39. _pwchPathBuffer(0),
  40. _fPathBufferInUse(FALSE) {
  41. }
  42. ~CStringBuffer() {
  43. delete [] _pwchPathBuffer;
  44. }
  45. BOOL InUse() { return _fPathBufferInUse; }
  46. PWSTR Alloc( unsigned cchString );
  47. BOOL FreeConditionally( PWSTR pwszBuf )
  48. {
  49. if (_fPathBufferInUse && pwszBuf == _pwchPathBuffer) {
  50. _fPathBufferInUse = FALSE;
  51. return TRUE;
  52. }
  53. return FALSE;
  54. }
  55. private:
  56. //
  57. // Full path buffer used by GetData. At most one GetData can be
  58. // outstanding at any one time.
  59. //
  60. unsigned _cchPathBuffer; // size of _pwchPathBuffer
  61. PWSTR _pwchPathBuffer; // temp. buffer for path
  62. BOOL _fPathBufferInUse; // TRUE if _pwchPathBuffer in use
  63. };
  64. //+-------------------------------------------------------------------------
  65. //
  66. // Method: CStringBuffer::Alloc, public inline
  67. //
  68. // Synopsis: Return a pointer to a buffer large enough to
  69. // accomodate an the requested number of characters.
  70. //
  71. // Arguments: [cchPath] - number of characters needed, including
  72. // null terminator
  73. //
  74. // Returns: PWSTR - pointer to buffer
  75. //
  76. // Notes: At most one active GetData can ask for the path
  77. // at a time. GetData can be a performance hot spot,
  78. // so we don't want to do an allocation every time.
  79. //
  80. //--------------------------------------------------------------------------
  81. inline PWSTR CStringBuffer::Alloc( unsigned cchPath )
  82. {
  83. Win4Assert( _fPathBufferInUse == FALSE );
  84. if (cchPath > _cchPathBuffer)
  85. {
  86. delete [] _pwchPathBuffer;
  87. _pwchPathBuffer = new WCHAR[ cchPath ];
  88. _cchPathBuffer = cchPath;
  89. }
  90. _fPathBufferInUse = TRUE;
  91. return _pwchPathBuffer;
  92. }
  93. //+-------------------------------------------------------------------------
  94. //
  95. // Class: CCompressedColHashString
  96. //
  97. // Purpose: A compressed column which uses a hash table for
  98. // redundant value elimination. Specific to storing
  99. // string (VT_LPWSTR and VT_LPSTR) values.
  100. //
  101. // Interface: CCompressedCol
  102. //
  103. // Notes: To save storage space, strings are compressed to
  104. // ANSI strings whenever possible (only the ASCII
  105. // subset is tested for compression). Also, at most
  106. // MAX_HASHKEY distinct strings will be stored.
  107. //
  108. // Entries are only added to the table, never removed.
  109. // This reduces storage requirements since reference
  110. // counts do not need to be stored.
  111. //
  112. // History: 03 May 1994 Alanw Created
  113. //
  114. //--------------------------------------------------------------------------
  115. class CCompressedColHashString: public CCompressedCol
  116. {
  117. friend class CCompressedColPath; // needs access to _pAlloc, _AddData
  118. // and _GetStringBuffer.
  119. friend class CStringStore;
  120. struct HashEntry
  121. {
  122. HASHKEY ulHashChain; // hash chain (must be first!)
  123. TBL_OFF ulStringKey; // key to string value in variable data
  124. USHORT usSizeFmt; // size and format(ascii/wchar) of the string
  125. };
  126. public:
  127. CCompressedColHashString( BOOL fOptimizeAscii = TRUE ):
  128. CCompressedCol(
  129. VT_LPWSTR, // vtData,
  130. sizeof (HASHKEY), // cbKey,
  131. VarHash // ComprType
  132. ),
  133. _cHashEntries( 0 ),
  134. _cDataItems( 0 ),
  135. _pAlloc( NULL ),
  136. _fOptimizeAscii( fOptimizeAscii ),
  137. _cbDataWidth( sizeof (HashEntry) ),
  138. _Buf1(),
  139. _Buf2() { }
  140. ~CCompressedColHashString() {
  141. delete _pAlloc;
  142. }
  143. ULONG HashString( BYTE *pbData,
  144. USHORT cbData,
  145. VARTYPE vtType,
  146. BOOL fNullTerminated );
  147. ULONG HashWSTR( WCHAR const * pwszStr, USHORT nChar );
  148. ULONG HashSTR ( CHAR const * pszStr, USHORT nChar );
  149. void AddData(PROPVARIANT const * const pvarnt,
  150. ULONG * pKey,
  151. GetValueResult& reIndicator);
  152. void AddData( const WCHAR * pwszStr,
  153. ULONG & key,
  154. GetValueResult& reIndicator );
  155. void AddCountedWStr( const WCHAR * pwszStr,
  156. ULONG cwcStr,
  157. ULONG & key,
  158. GetValueResult& reIndicator );
  159. ULONG FindCountedWStr( const WCHAR * pwszStr,
  160. ULONG cwcStr );
  161. GetValueResult GetData( ULONG key, WCHAR * pwszStr, ULONG & cwcStr);
  162. GetValueResult GetData( PROPVARIANT * pvarnt,
  163. VARTYPE PreferredType,
  164. ULONG key = 0,
  165. PROPID prop = 0);
  166. const WCHAR * GetCountedWStr( ULONG key , ULONG & cwcStr );
  167. void FreeVariant(PROPVARIANT * pvarnt);
  168. ULONG MemUsed(void) {
  169. return _pAlloc ? _pAlloc->MemUsed() : 0;
  170. }
  171. USHORT DataLength(ULONG key);
  172. private:
  173. PWSTR _GetStringBuffer( unsigned cchPath );
  174. VOID _AddData( BYTE *pbData, USHORT cbDataSize,
  175. VARTYPE vt, ULONG* pKey,
  176. BOOL fNullTerminated );
  177. ULONG _FindData( BYTE * pbData,
  178. USHORT cbDataSize,
  179. VARTYPE vt,
  180. BOOL fNullTerminated );
  181. VOID _GrowHashTable( void );
  182. HashEntry* _IndexHashkey( HASHKEY iKey );
  183. USHORT _cHashEntries; // size of hash table
  184. const USHORT _cbDataWidth; // width of each data item
  185. ULONG _cDataItems; // number of entries in pDataItems
  186. CFixedVarAllocator *_pAlloc; // Data allocator
  187. BOOL _fOptimizeAscii;
  188. //
  189. // Name buffers used by GetData. There are two because sorted
  190. // insertion operations in the table can require two buffers.
  191. //
  192. CStringBuffer _Buf1;
  193. CStringBuffer _Buf2;
  194. };
  195. //+-------------------------------------------------------------------------
  196. //
  197. // Method: CCompressedColHashString::_IndexHashkey, private inline
  198. //
  199. // Synopsis: Index a hash key and return a pointer to the corresponding
  200. // data entry.
  201. //
  202. // Arguments: [iKey] - lookup key value
  203. //
  204. // Returns: HashEntry*, pointer to the indexed item
  205. //
  206. // Notes:
  207. //
  208. //--------------------------------------------------------------------------
  209. inline
  210. CCompressedColHashString::HashEntry* CCompressedColHashString::_IndexHashkey(
  211. HASHKEY iKey
  212. ) {
  213. Win4Assert(iKey > 0 && iKey <= _cDataItems);
  214. return ((HashEntry*) _pAlloc->FirstRow()) + iKey - 1;
  215. }