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.

341 lines
9.4 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: CHANGES.CXX
  7. //
  8. // Contents: Table of changes
  9. //
  10. // Classes: CChange CPartQueue
  11. //
  12. // History: 29-Mar-91 BartoszM Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <glbconst.hxx>
  18. #include "indxact.hxx"
  19. #include "changes.hxx"
  20. #define CI_PRIORITY_INVALID CI_PRIORITIES
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Member: CChange::CChange, public
  24. //
  25. // Arguments: [storage] -- physical storage
  26. //
  27. // History: 29-Mar-91 BartoszM Created
  28. //
  29. //----------------------------------------------------------------------------
  30. CChange::CChange (
  31. WORKID wid,
  32. PStorage& storage,
  33. CCiFrameworkParams & frmwrkParams ) :
  34. _frmwrkParams( frmwrkParams ),
  35. _queue( wid, storage, PStorage::ePrimChangeLog, frmwrkParams ),
  36. _secQueue( wid, storage, PStorage::eSecChangeLog, frmwrkParams )
  37. {
  38. Win4Assert( sizeof(FILETIME) == sizeof(LONGLONG) );
  39. GetSystemTimeAsFileTime( (FILETIME *) &_ftLast );
  40. }
  41. //+---------------------------------------------------------------------------
  42. //
  43. // Member: CChange::LokEmpty, public
  44. //
  45. // Synopsis: Initializes changes object so it looks new/empty
  46. //
  47. // Notes: ResMan LOCKED
  48. //
  49. // History: 15-Nov-94 DwightKr Created
  50. //
  51. //----------------------------------------------------------------------------
  52. void CChange::LokEmpty()
  53. {
  54. _queue.LokEmpty();
  55. _secQueue.LokEmpty();
  56. }
  57. //+---------------------------------------------------------------------------
  58. //
  59. // Member: CChange::LokCompact, public
  60. //
  61. // Synopsis: Frees memory not currently in use.
  62. //
  63. // Notes: ResMan LOCKED
  64. //
  65. // History: 19-May-92 BartoszM Created
  66. //
  67. //----------------------------------------------------------------------------
  68. void CChange::LokCompact()
  69. {
  70. }
  71. //+---------------------------------------------------------------------------
  72. //
  73. // Member: CChange::LokGetPendingUpdates
  74. //
  75. // Synopsis: Like QueryPendingUpdates, but doesn't remove documents from
  76. // queue, and doesn't require a transaction (no deserialization).
  77. //
  78. // Arguments: [aWid] -- Workids returned here.
  79. // [cWid] -- INPUT: Maximum number of entries to fetch.
  80. // OUTPUT: Number of entries fetched.
  81. //
  82. // Returns: TRUE if all change entries were processed.
  83. //
  84. // History: 15-Nov-94 KyleP Created
  85. //
  86. // Notes: ResMan LOCKED
  87. //
  88. //----------------------------------------------------------------------------
  89. BOOL CChange::LokGetPendingUpdates( WORKID * aWid, unsigned & cWid )
  90. {
  91. if ( _queue.IsEmpty() && _secQueue.IsEmpty() )
  92. {
  93. cWid = 0;
  94. return TRUE;
  95. }
  96. else
  97. {
  98. const unsigned cMax = cWid;
  99. unsigned cPrim = 0; // count of wids from primary
  100. unsigned cSec = 0; // count of wids from secondary
  101. BOOL fSuccess = TRUE;
  102. if ( !_queue.IsEmpty() )
  103. {
  104. cPrim = cMax;
  105. fSuccess = _queue.Get(aWid, cPrim);
  106. }
  107. if ( fSuccess && !_secQueue.IsEmpty() )
  108. {
  109. Win4Assert( cPrim <= cMax );
  110. cSec = cMax-cPrim;
  111. fSuccess = _secQueue.Get( aWid+cPrim, cSec );
  112. }
  113. Win4Assert( cPrim + cSec <= cMax );
  114. cWid = cPrim+cSec;
  115. return fSuccess;
  116. }
  117. }
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Member: CChange::LokQueryPendingUpdates
  121. //
  122. // Synopsis: Checks update queues, returns list of documents
  123. //
  124. // Arguments: [xact] -- transaction
  125. // [maxDocs] -- maximum # of updates acceptable
  126. // [docList] -- (returned) list of documents,
  127. // initially empty.
  128. //
  129. // Returns: An array of document descriptors (or NULL)
  130. //
  131. // History: 25-Sept-91 BartoszM Created
  132. //
  133. // Notes: ResMan LOCKED
  134. //
  135. //----------------------------------------------------------------------------
  136. void CChange::LokQueryPendingUpdates (
  137. CChangeTrans & xact,
  138. unsigned maxDocs,
  139. CDocList& docList )
  140. {
  141. ciDebugOut (( DEB_ITRACE, "Query Pending Updates\n" ));
  142. if ( !_queue.IsEmpty() )
  143. {
  144. _queue.Extract( xact, maxDocs, docList );
  145. }
  146. else
  147. {
  148. docList.LokSetCount(0);
  149. return;
  150. }
  151. }
  152. //+---------------------------------------------------------------------------
  153. //
  154. // Member: CChange::LokDone, public
  155. //
  156. // Synopsis: After creating a volatile index marks
  157. // entries in table done. Stores actual index id.
  158. //
  159. // Arguments: [xact] -- transaction
  160. // [iid] -- index id
  161. // [docList] -- array of document descriptors
  162. //
  163. // History: 26-Apr-91 BartoszM Created
  164. //
  165. // Notes: ResMan LOCKED
  166. //
  167. //----------------------------------------------------------------------------
  168. void CChange::LokDone ( CChangeTrans & xact, INDEXID iid, CDocList& docList )
  169. {
  170. ciDebugOut (( DEB_ITRACE, "Changes: Done\n" ));
  171. int cDoc = docList.Count();
  172. //
  173. // Look for PENDING or PREEMPTED documents, which must be reindexed.
  174. //
  175. for ( int i = 0; i < cDoc; i++ )
  176. {
  177. STATUS status = docList.Status(i);
  178. if ( status == PREEMPTED || status == PENDING )
  179. {
  180. _queue.Append( xact,
  181. docList.Wid(i),
  182. docList.Usn(i),
  183. docList.VolumeId(i),
  184. CI_UPDATE_OBJ,
  185. docList.Retries(i),
  186. docList.SecQRetries(i)
  187. );
  188. }
  189. }
  190. }
  191. //+---------------------------------------------------------------------------
  192. //
  193. // Member: CChange::LokRemoveIndexes, public
  194. //
  195. // Synopsis: Remove entries from the table after volatile indexes
  196. // have been merged away.
  197. //
  198. // Arguments: [cIndexes] -- count of index ids
  199. // [aIndexIds] -- array of index ids
  200. //
  201. // History: 26-Apr-91 BartoszM Created
  202. // 14-May-91 BartoszM Implemented
  203. //
  204. // Notes: ResMan LOCKED
  205. //
  206. //----------------------------------------------------------------------------
  207. void CChange::LokRemoveIndexes (
  208. CTransaction& xact,
  209. unsigned cIndexes,
  210. INDEXID aIndexIds[] )
  211. {
  212. ciDebugOut (( DEB_ITRACE, "Changes: Remove Indexes\n" ));
  213. }
  214. //+---------------------------------------------------------------------------
  215. //
  216. // Member: CChange::LokAddToSecQueue
  217. //
  218. // Synopsis: Adds the document to the secondary change queue.
  219. //
  220. // Arguments: [xact] -- Change transaction
  221. // [wid] -- Workid
  222. // [volumeId] -- Volume id
  223. // [cSecQRetries] -- Sec Q Retry Count
  224. //
  225. // History: 5-08-96 srikants Created
  226. //
  227. //----------------------------------------------------------------------------
  228. void CChange::LokAddToSecQueue( CChangeTrans & xact, WORKID wid, VOLUMEID volumeId, ULONG cSecQRetries )
  229. {
  230. USN usn = 0;
  231. ULONG action = CI_UPDATE_OBJ;
  232. ciDebugOut(( DEB_TRACE,
  233. "Refiling wid %d (0x%X) to secondary queue\n", wid, wid ));
  234. SCODE sc = _secQueue.Append( xact,
  235. wid,
  236. usn,
  237. volumeId,
  238. action,
  239. 1, // retries (reset for sharing viol)
  240. cSecQRetries
  241. );
  242. if ( S_OK != sc )
  243. {
  244. ciDebugOut(( DEB_ERROR, "LokAddToSecQueue returned 0x%X\n", sc ));
  245. }
  246. }
  247. //+---------------------------------------------------------------------------
  248. //
  249. // Member: CChange::LokRefileSecQueue
  250. //
  251. // Synopsis: Moves items from seconday queue to primary queue
  252. //
  253. // Arguments: [xact] - Change transaction
  254. //
  255. // History: 5-08-96 srikants Created
  256. //
  257. //----------------------------------------------------------------------------
  258. void CChange::LokRefileSecQueue( CChangeTrans & xact )
  259. {
  260. // convert the retry interval from minutes into 100s of nano seconds
  261. const LONGLONG eXferInterval =
  262. _frmwrkParams.GetFilterRetryInterval() * 60 * 1000 * 10000;
  263. LONGLONG ftNow;
  264. GetSystemTimeAsFileTime( (FILETIME *) &ftNow );
  265. LONGLONG llDelta = ftNow - _ftLast;
  266. if ( llDelta > 0 && !_secQueue.IsEmpty() )
  267. {
  268. if ( llDelta < eXferInterval )
  269. return;
  270. CDocList docList;
  271. while ( !_secQueue.IsEmpty() )
  272. {
  273. docList.LokClear();
  274. _secQueue.Extract( xact, CI_MAX_DOCS_IN_WORDLIST, docList );
  275. for ( unsigned i = 0; i < docList.Count(); i++ )
  276. {
  277. ciDebugOut(( DEB_TRACE,
  278. "Transferring wid %d (0x%X) from secondary to primary queue\n",
  279. docList.Wid(i),
  280. docList.Wid(i) ));
  281. _queue.Append ( xact,
  282. docList.Wid(i),
  283. docList.Usn(i),
  284. docList.VolumeId(i),
  285. CI_UPDATE_OBJ,
  286. docList.Retries(i),
  287. docList.SecQRetries(i) );
  288. }
  289. }
  290. _secQueue.LokEmpty();
  291. }
  292. _ftLast = ftNow;
  293. }