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.

415 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1998.
  5. //
  6. // File: changlog.hxx
  7. //
  8. // Contents: Persistent Change Log manager and related classes.
  9. //
  10. // Classes: CDocNotification, CDocChunk, CChunkList, CChangeLog
  11. //
  12. // History: 5-26-94 srikants ReWrite Change Log implementation.
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <glbconst.hxx>
  17. #include <rcstxact.hxx>
  18. #include <eventlog.hxx>
  19. #include <doclist.hxx>
  20. #include <usninfo.hxx>
  21. class CResManager;
  22. class CNotificationTransaction;
  23. const unsigned cDocInChunk = 16;
  24. //+---------------------------------------------------------------------------
  25. //
  26. // Class: CDocNotification
  27. //
  28. // Purpose: Notification
  29. //
  30. // History: 11-Aug-93 BartoszM Created.
  31. // 08-Feb-94 DwightKr Added retries
  32. // 24-Feb-97 SitaramR Push filtering
  33. //
  34. //----------------------------------------------------------------------------
  35. #include <pshpack2.h>
  36. class CDocNotification
  37. {
  38. public:
  39. CDocNotification() { _wid = widInvalid; }
  40. void Set ( WORKID wid,
  41. USN usn,
  42. VOLUMEID volumeId,
  43. ULONG action,
  44. ULONG retries,
  45. ULONG secQRetries )
  46. {
  47. _wid = wid;
  48. _usn = usn;
  49. _volumeId = volumeId;
  50. Win4Assert( action <= 0xffff );
  51. Win4Assert( retries <= 0xffff );
  52. Win4Assert( secQRetries <= 0xffff );
  53. _action = (USHORT) action;
  54. _retries = (USHORT) retries;
  55. _secQRetries = (USHORT) secQRetries;
  56. }
  57. WORKID Wid() const { return _wid; }
  58. USN Usn() const { return _usn; }
  59. VOLUMEID VolumeId() const { return _volumeId; }
  60. ULONG Action() const { return _action; }
  61. ULONG Retries() const { return _retries; }
  62. ULONG SecQRetries() const { return _secQRetries; }
  63. BOOL IsDeletion () const { return (_action & CI_DELETE_OBJ) != 0; }
  64. #ifdef CIEXTMODE
  65. void CiExtDump(void *ciExtSelf);
  66. #endif
  67. private:
  68. USN _usn;
  69. WORKID _wid;
  70. VOLUMEID _volumeId;
  71. USHORT _action;
  72. USHORT _retries;
  73. USHORT _secQRetries;
  74. };
  75. #include <poppack.h>
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Class: CDocChunk
  79. //
  80. // Purpose: Array of document notifications
  81. //
  82. // History: 11-Aug-93 BartoszM Created.
  83. //
  84. //----------------------------------------------------------------------------
  85. class CDocChunk
  86. {
  87. public:
  88. CDocChunk () : _pNext(0)
  89. {
  90. Win4Assert (sizeof(_aNotify) == (sizeof(CDocNotification) * cDocInChunk));
  91. }
  92. CDocChunk* GetNext() const { return _pNext; }
  93. void SetNext ( CDocChunk* pNext ) { _pNext = pNext; }
  94. CDocNotification* GetDoc( unsigned offset )
  95. {
  96. Win4Assert( offset < cDocInChunk );
  97. return( &_aNotify[offset] );
  98. }
  99. CDocNotification* GetArray() { return &_aNotify[0]; }
  100. unsigned Size() { return cDocInChunk; }
  101. void UpdateMaxUsn( CCountedDynArray<CUsnFlushInfo> & aUsnFlushInfo );
  102. #ifdef CIEXTMODE
  103. void CiExtDump(void *ciExtSelf);
  104. #endif
  105. private:
  106. CDocChunk* _pNext;
  107. CDocNotification _aNotify[cDocInChunk];
  108. };
  109. //+---------------------------------------------------------------------------
  110. //
  111. // Class: CChunkList
  112. //
  113. // Purpose: A singly linked list of CDocChunks.
  114. //
  115. // History: 5-26-94 srikants Created
  116. //
  117. // Notes:
  118. //
  119. //----------------------------------------------------------------------------
  120. class CChunkList
  121. {
  122. public:
  123. CChunkList() : _pHead(0), _pTail(0), _count(0)
  124. {
  125. }
  126. ~CChunkList()
  127. {
  128. DestroyUpto();
  129. }
  130. CDocChunk * GetFirst() { return _pHead; }
  131. CDocChunk * GetLast() { return _pTail; }
  132. BOOL IsEmpty() const { return 0 == _pHead; }
  133. ULONG Count( ) const { return _count; }
  134. void Append( CDocChunk * pChunk );
  135. CDocChunk * Pop();
  136. void DestroyUpto( CDocChunk * pChunk = 0 );
  137. CDocChunk * Acquire()
  138. {
  139. CDocChunk * pTemp = _pHead;
  140. _pHead = _pTail = 0;
  141. _count = 0;
  142. return(pTemp);
  143. }
  144. void TruncateFrom( CDocChunk * pChunk );
  145. void AcquireAndAppend( CChunkList & chunkList );
  146. #ifdef CIEXTMODE
  147. void CiExtDump(void *ciExtSelf);
  148. #endif
  149. private:
  150. CDocChunk * _pHead; // Head of the linked list.
  151. CDocChunk * _pTail; // Tail of the linked list.
  152. ULONG _count; // number of chunks in the list.
  153. };
  154. //+---------------------------------------------------------------------------
  155. //
  156. // Function: Append
  157. //
  158. // Synopsis: Appends the specified chunk to the list.
  159. //
  160. // Arguments: [pChunk] -- Chunk to append.
  161. //
  162. // History: 5-26-94 srikants Created
  163. //
  164. //----------------------------------------------------------------------------
  165. inline void CChunkList::Append( CDocChunk * pChunk )
  166. {
  167. Win4Assert( 0 != pChunk );
  168. pChunk->SetNext(0);
  169. if ( 0 != _pHead )
  170. {
  171. Win4Assert( 0 != _pTail );
  172. _pTail->SetNext( pChunk );
  173. }
  174. else
  175. {
  176. Win4Assert( 0 == _pTail );
  177. _pHead = pChunk;
  178. }
  179. _pTail = pChunk;
  180. _count++;
  181. }
  182. //+---------------------------------------------------------------------------
  183. //
  184. // Function: Pop
  185. //
  186. // Synopsis: Removes and returns the first element in the list.
  187. //
  188. // History: 5-26-94 srikants Created
  189. //
  190. //----------------------------------------------------------------------------
  191. inline CDocChunk * CChunkList::Pop()
  192. {
  193. CDocChunk * pChunk = 0;
  194. if ( 0 != _pHead )
  195. {
  196. pChunk = _pHead;
  197. _pHead = _pHead->GetNext();
  198. if ( 0 == _pHead )
  199. {
  200. Win4Assert( 1 == _count );
  201. Win4Assert( pChunk == _pTail );
  202. _pTail = 0;
  203. }
  204. pChunk->SetNext(0);
  205. Win4Assert( _count > 0 );
  206. _count--;
  207. }
  208. else
  209. {
  210. Win4Assert( 0 == _pTail );
  211. }
  212. return(pChunk);
  213. }
  214. //+---------------------------------------------------------------------------
  215. //
  216. // Function: DestroyUpto
  217. //
  218. // Synopsis: Destroys all the elements in the list and frees them.
  219. //
  220. // History: 5-26-94 srikants Created
  221. //
  222. //----------------------------------------------------------------------------
  223. inline void CChunkList::DestroyUpto( CDocChunk * pChunk )
  224. {
  225. while ( _pHead != pChunk )
  226. {
  227. CDocChunk * pDelete = Pop();
  228. delete pDelete;
  229. }
  230. }
  231. //+---------------------------------------------------------------------------
  232. //
  233. // Function: TruncateFrom
  234. //
  235. // Synopsis: Removes all the elements in the queue from the specified node
  236. // to the end of the list. It has been assumed that the specified
  237. // node is part of the list.
  238. //
  239. // Arguments: [pChunk] -- The first chunk to be deleted from the list.
  240. //
  241. // History: 5-26-94 srikants Created
  242. //
  243. //----------------------------------------------------------------------------
  244. inline void CChunkList::TruncateFrom( CDocChunk * pChunk )
  245. {
  246. Win4Assert( 0 != pChunk );
  247. CDocChunk * pDelete = pChunk->GetNext();
  248. while ( 0 != pDelete )
  249. {
  250. CDocChunk * pNext = pDelete->GetNext();
  251. delete pDelete;
  252. Win4Assert( _count > 0 );
  253. _count--;
  254. pDelete = pNext;
  255. }
  256. Win4Assert( _count > 0 );
  257. _pTail = pChunk;
  258. pChunk->SetNext(0);
  259. }
  260. class CFreshTest;
  261. class PStorage;
  262. //+---------------------------------------------------------------------------
  263. //
  264. // Class: CChangeLog
  265. //
  266. // Purpose: Persistent change list manager. This class is capable of
  267. // doing operations on the persistent change log, eg.
  268. // serializing, de-serializing, and compacting.
  269. //
  270. // History: 5-26-94 srikants Created
  271. // 2-24-97 SitaramR Push filtering
  272. //
  273. //----------------------------------------------------------------------------
  274. const LONGLONG eSigChangeLog = 0x474f4c474e414843i64; // "CHANGLOG"
  275. class CChangeLog
  276. {
  277. public:
  278. CChangeLog( WORKID widChangeLog, PStorage & storage,
  279. PStorage::EChangeLogType type );
  280. ~CChangeLog();
  281. void LokEmpty();
  282. BOOL IsEmpty() const { return 0 == _cChunksAvail; }
  283. BOOL IsPrimary() const { return PStorage::ePrimChangeLog == _type; }
  284. BOOL IsSecondary() const { return PStorage::eSecChangeLog == _type; }
  285. ULONG AvailChunkCount() const { return _cChunksAvail; }
  286. ULONG DeSerialize( CChunkList & deserializedList,
  287. ULONG cChunksToRead );
  288. ULONG Serialize( CChunkList & listToSerialize,
  289. CCountedDynArray<CUsnFlushInfo> & aUsnFlushInfo );
  290. ULONG LokDeleteWIDsInPersistentIndexes( ULONG cFilteredChunks,
  291. CFreshTest & freshTestLatest,
  292. CFreshTest & freshTestAtMerge,
  293. CDocList & docList,
  294. CNotificationTransaction & notifTrans );
  295. void LokDisableUpdates();
  296. void LokEnableUpdates( BOOL fFirstTimeUpdatesAreEnabled );
  297. BOOL AreUpdatesEnabled() { return _fUpdatesEnabled; }
  298. void SkipChunk()
  299. {
  300. Win4Assert( _cChunksAvail > 0 );
  301. Win4Assert( _oChunkToRead + _cChunksAvail == _cChunksTotal );
  302. _oChunkToRead++;
  303. _cChunksAvail--;
  304. }
  305. void SetResMan( CResManager * pResManager, BOOL fPushFiltering );
  306. BOOL FPushFiltering() { return _fPushFiltering; }
  307. #ifdef CIEXTMODE
  308. void CiExtDump(void *ciExtSelf);
  309. #endif
  310. private:
  311. void InitSize();
  312. void LokVerifyConsistency();
  313. BOOL IsWidInDocList( WORKID wid, CDocList& docList );
  314. const LONGLONG _sigChangeLog;
  315. CResManager * _pResManager; // Resman
  316. WORKID _widChangeLog; // WorkId of the changelog.
  317. PStorage & _storage; // Persistent storage object.
  318. PStorage::EChangeLogType _type; // Type of change log
  319. BOOL _fUpdatesEnabled; // Flag indicating whether updates
  320. // are allowed or not.
  321. BOOL _fPushFiltering; // Using push model of filtering ?
  322. SRcovStorageObj _PersDocQueue; // The persistent doc queue.
  323. ULONG _oChunkToRead; // Offset of the next chunk to
  324. // read from the log.
  325. ULONG _cChunksAvail; // Number of chunks available in
  326. // the change log for reading.
  327. ULONG _cChunksTotal; // Total number of chunks.
  328. // (For debugging).
  329. };