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.

305 lines
8.7 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: pershash.cxx
  7. //
  8. // Contents: Abstract class for persistent hash table
  9. //
  10. // History: 07-May-97 SitaramR Created from strings.cxx
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <mmstrm.hxx>
  16. #include <cistore.hxx>
  17. #include <propstor.hxx>
  18. #include <propiter.hxx>
  19. #include "pershash.hxx"
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Member: CPersHash::CPersHash
  23. //
  24. // Synopsis: Constructor
  25. //
  26. // Arguments: [PropStore] -- Property store
  27. //
  28. // History: 07-May-97 SitaramR Created
  29. //
  30. //----------------------------------------------------------------------------
  31. CPersHash::CPersHash(
  32. CPropStoreManager &PropStoreMgr,
  33. BOOL fAggressiveGrowth )
  34. : _PropStoreMgr ( PropStoreMgr ),
  35. _fIsOpen( FALSE ),
  36. _hTable( fAggressiveGrowth ),
  37. _pStreamHash(0),
  38. _fAbort(FALSE),
  39. _fFullInit(FALSE),
  40. _fIsReadOnly(FALSE)
  41. {
  42. }
  43. //+---------------------------------------------------------------------------
  44. //
  45. // Member: CPersHash::~CPersHash
  46. //
  47. // Synopsis: Destructor
  48. //
  49. // History: 07-May-97 SitaramR Created
  50. //
  51. //----------------------------------------------------------------------------
  52. CPersHash::~CPersHash()
  53. {
  54. delete _pStreamHash;
  55. }
  56. //+---------------------------------------------------------------------------
  57. //
  58. // Member: CPersHash::FastInit
  59. //
  60. // Synopsis: Opens persistent wid hash
  61. //
  62. // Arguments: [pStorage] -- CI storage
  63. // [version] -- Content index version
  64. // [fIsFileIdMap] -- TRUE if the fileidmap, false if the strings
  65. // table.
  66. //
  67. // Returns: TRUE if table was successfully opened
  68. //
  69. // History: 07-May-97 SitaramR Created
  70. // 23-Feb-98 KitmanH Initialized the value of
  71. // _fIsReadOnly with pStorage
  72. // 27-Feb-98 KitmanH If _fIsReadOnly, do part of long
  73. // init. i.e. init. hash table but
  74. // not mark dirty
  75. // 13-Mar-98 KitmanH new flag is added to determine
  76. // the type of hash stream to open
  77. // (fileidmap or strings) and open
  78. // the CMmStream with the new methods
  79. // QueryFileIdMap or QueryStringHash.
  80. //
  81. //----------------------------------------------------------------------------
  82. BOOL CPersHash::FastInit( CiStorage * pStorage, ULONG version, BOOL fIsFileIdMap )
  83. {
  84. _fIsReadOnly = pStorage->IsReadOnly();
  85. XPtr<PMmStream> xStrm;
  86. if ( fIsFileIdMap )
  87. xStrm.Set( pStorage->QueryFileIdMap() );
  88. else
  89. xStrm.Set( pStorage->QueryStringHash() );
  90. Win4Assert( 0 == _pStreamHash );
  91. _pStreamHash = new CDynStream( xStrm.GetPointer() );
  92. xStrm.Acquire();
  93. _pStreamHash->CheckVersion( *pStorage, version, _fIsReadOnly );
  94. _fIsOpen = TRUE;
  95. if (_fIsReadOnly)
  96. {
  97. ULONG htabSize = _pStreamHash->DataSize() / sizeof(WORKID);
  98. WORKID* table = (WORKID *) (_pStreamHash->Get() + sizeof(FILETIME));
  99. _hTable.Init( _pStreamHash->Count(), htabSize, table );
  100. _fFullInit = TRUE;
  101. }
  102. return TRUE;
  103. } //FastInit
  104. //+---------------------------------------------------------------------------
  105. //
  106. // Member: CPersHash::LongInit
  107. //
  108. // Synopsis: Initialization that may take a long time
  109. //
  110. // Arguments: [version] -- CI version
  111. // [fDirtyShutdown] -- Set to TRUE if the previous shutdown
  112. // was dirty.
  113. //
  114. // History: 07-May-97 SitaramR Created
  115. //
  116. //----------------------------------------------------------------------------
  117. void CPersHash::LongInit( ULONG version, BOOL fDirtyShutdown )
  118. {
  119. if ( fDirtyShutdown || _pStreamHash->Version() != version || _pStreamHash->IsDirty() )
  120. ReInit( version );
  121. _pStreamHash->MarkDirty();
  122. ULONG htabSize = _pStreamHash->DataSize() / sizeof(WORKID);
  123. WORKID* table = (WORKID *) (_pStreamHash->Get() + sizeof(FILETIME));
  124. _hTable.Init ( _pStreamHash->Count(), htabSize, table );
  125. _fFullInit = TRUE;
  126. } //LongInit
  127. //+---------------------------------------------------------------------------
  128. //
  129. // Member: CPersHash::Empty
  130. //
  131. // Synopsis: Method to empty out any of the initialized members. This is
  132. // called if corruption is detected and all resources must
  133. // be released.
  134. //
  135. // History: 07-May-97 SitaramR Created
  136. //
  137. //----------------------------------------------------------------------------
  138. void CPersHash::Empty()
  139. {
  140. delete _pStreamHash;
  141. _pStreamHash = 0;
  142. _fIsOpen = FALSE;
  143. _fFullInit = FALSE;
  144. } //Empty
  145. //+---------------------------------------------------------------------------
  146. //
  147. // Member: CPersHash::Shutdown
  148. //
  149. // Synopsis: Shutdown processing
  150. //
  151. // History: 07-May-97 SitaramR Created
  152. //
  153. //----------------------------------------------------------------------------
  154. void CPersHash::Shutdown()
  155. {
  156. _fAbort = TRUE;
  157. if ( _fIsOpen && _fFullInit )
  158. LokFlush();
  159. } //Shutdown
  160. //+---------------------------------------------------------------------------
  161. //
  162. // Member: CPersHash::ReInit
  163. //
  164. // Synopsis: Clears out hash table
  165. //
  166. // Arguments: [version] -- Content index version
  167. //
  168. // Returns: TRUE if table was successfully opened.
  169. //
  170. // History: 07-May-97 SitaramR Created.
  171. //
  172. //----------------------------------------------------------------------------
  173. BOOL CPersHash::ReInit( ULONG version )
  174. {
  175. ciDebugOut(( DEB_WARN, "Persistent hash file %s must be recreated\n",
  176. _hTable.IsAggressiveGrowth() ? "strings" : "fileid" ));
  177. if ( !_pStreamHash->isWritable() )
  178. return FALSE;
  179. // Re-create stream.
  180. _pStreamHash->SetVersion( version );
  181. ciDebugOut(( DEB_ITRACE, "propstore max workid: %d\n",
  182. _PropStoreMgr.MaxWorkId() ));
  183. // Re-hash the entries. HashAll will determine the size of the stream
  184. HashAll();
  185. LokFlush();
  186. return TRUE;
  187. } //ReInit
  188. //+---------------------------------------------------------------------------
  189. //
  190. // Member: CPersHash::LokFlush
  191. //
  192. // Synopsis: Flush stream
  193. //
  194. // History: 07-May-97 SitaramR Created
  195. // 03-Mar-98 KitmanH Don't do anything if _fIsReadOnly
  196. // is set.
  197. //
  198. //----------------------------------------------------------------------------
  199. void CPersHash::LokFlush ()
  200. {
  201. if ( !_fIsReadOnly )
  202. {
  203. _pStreamHash->SetCount( _hTable.Count() );
  204. _pStreamHash->Flush();
  205. }
  206. } //LokFlush
  207. //+-------------------------------------------------------------------------
  208. //
  209. // Member: CPersHash::GrowHashTable
  210. //
  211. // Synopsis: Grow the persistent hash and rehash existing entries
  212. //
  213. // History: 07-May-97 SitaramR Created
  214. //
  215. //--------------------------------------------------------------------------
  216. void CPersHash::GrowHashTable()
  217. {
  218. Win4Assert ( _hTable.IsFull() );
  219. ciDebugOut ((DEB_CAT, "Growing persistent hash table\n" ));
  220. //
  221. // Invalidate on-disk version
  222. //
  223. _pStreamHash->SetCount(0);
  224. _pStreamHash->Flush();
  225. ULONG newSize = _hTable.GrowSize();
  226. PStorage* pStore = 0;
  227. _pStreamHash->Grow( *pStore, newSize * sizeof WORKID + sizeof FILETIME );
  228. _pStreamHash->SetDataSize( newSize * sizeof WORKID );
  229. _hTable.ReInit( 0, newSize,
  230. (WORKID *) ( _pStreamHash->Get() + sizeof FILETIME ) );
  231. HashAll();
  232. LokFlush ();
  233. } //GrowHashTable
  234. //+-------------------------------------------------------------------------
  235. //
  236. // Member: CPersHash::GrowToSize
  237. //
  238. // Synopsis: Grow the persistent hash
  239. //
  240. // History: 05-March-98 dlee Created
  241. //
  242. //--------------------------------------------------------------------------
  243. void CPersHash::GrowToSize( unsigned cElements )
  244. {
  245. ciDebugOut ((DEB_CAT, "Growing persistent hash table\n" ));
  246. ULONG htabSize = _hTable.GrowSize( cElements );
  247. PStorage * pStore = 0;
  248. ULONG cbStream = htabSize * sizeof WORKID + sizeof FILETIME;
  249. _pStreamHash->Grow( *pStore, cbStream );
  250. _pStreamHash->Shrink( *pStore, cbStream );
  251. _pStreamHash->SetDataSize ( htabSize * sizeof WORKID );
  252. _hTable.ReInit( 0, htabSize,
  253. (WORKID *) ( _pStreamHash->Get() + sizeof FILETIME ) );
  254. } //GrowToSize