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.

233 lines
7.4 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1992.
  5. //
  6. // File: FRESHLOG.CXX
  7. //
  8. // Contents: Fresh persistent log & snapshot
  9. //
  10. // Classes: CPersFresh, CPersStream, SPersStream, CPersFreshTrans
  11. //
  12. // History: 93-Nov-15 DwightKr Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <pstore.hxx>
  18. #include <dynstrm.hxx>
  19. #include <freshlog.hxx>
  20. #include "fresh.hxx"
  21. #include "partlst.hxx"
  22. #include "partn.hxx"
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Member: CPersFresh::LokEmpty, public
  26. //
  27. // Synopsis: Empties the fresh log
  28. //
  29. // History: 94-Nov-15 DwightKr Created.
  30. //
  31. //----------------------------------------------------------------------------
  32. void CPersFresh::LokEmpty()
  33. {
  34. WORKID oidFreshLog = _storage.GetSpecialItObjectId( itFreshLog );
  35. PRcovStorageObj *pPersFreshLog = _storage.QueryFreshLog( oidFreshLog );
  36. SRcovStorageObj PersFreshLog( pPersFreshLog );
  37. CRcovStrmWriteTrans xact( &PersFreshLog );
  38. PersFreshLog->GetHeader().SetCount(PersFreshLog->GetHeader().GetBackup(), 0);
  39. xact.Empty();
  40. xact.Commit();
  41. }
  42. //+---------------------------------------------------------------------------
  43. //
  44. // Member: CPersFresh::LoadFreshTest, private
  45. //
  46. // Synopsis: Load the persistent log into the freshTable.
  47. //
  48. // Arguments: [freshTable] -- freshTable to load from the persistent log
  49. //
  50. // History: 93-Nov-18 DwightKr Created.
  51. //
  52. //----------------------------------------------------------------------------
  53. void CPersFresh::LoadFreshTest(CFreshTable & freshTable)
  54. {
  55. ciDebugOut (( DEB_ITRACE, "Loading persistent log into freshTable.\n" ));
  56. WORKID widFreshLog = _storage.GetSpecialItObjectId( itFreshLog );
  57. PRcovStorageObj *pPersFreshLog = _storage.QueryFreshLog( widFreshLog );
  58. SRcovStorageObj PersFreshLog( pPersFreshLog );
  59. CRcovStrmReadTrans xact( *pPersFreshLog );
  60. CRcovStrmReadIter iter( xact, sizeof(CPersRec) );
  61. while ( !iter.AtEnd() )
  62. {
  63. CPersRec PersRec(0,0);
  64. iter.GetRec( &PersRec );
  65. #if CIDBG==1
  66. CIndexId iid( PersRec.GetIndexID() );
  67. Win4Assert( iid.IsPersistent() );
  68. BOOL fDeleted = iidDeleted1 == PersRec.GetIndexID() ||
  69. iidDeleted2 == PersRec.GetIndexID() ;
  70. if ( !fDeleted )
  71. {
  72. //
  73. // If it is not a deleted index, the index MUST be valid.
  74. //
  75. CPartition * partn = _partList.LokGetPartition( iid.PartId() );
  76. Win4Assert( partn->LokIsPersIndexValid( iid ) );
  77. }
  78. #endif // CIDBG==1
  79. freshTable.AddReplace( PersRec.GetWorkID(), PersRec.GetIndexID() );
  80. }
  81. freshTable.ModificationsComplete();
  82. }
  83. //+---------------------------------------------------------------------------
  84. //
  85. // Member: CPersFresh::GetPersRecCount
  86. //
  87. // Synopsis: Returns the count of the number of entries in the
  88. // freshlog.
  89. //
  90. // Returns: Number fresh entries.
  91. //
  92. // History: 3-21-97 srikants Created
  93. //
  94. //----------------------------------------------------------------------------
  95. ULONG CPersFresh::GetPersRecCount()
  96. {
  97. WORKID widFreshLog = _storage.GetSpecialItObjectId( itFreshLog );
  98. PRcovStorageObj *pPersFreshLog = _storage.QueryFreshLog( widFreshLog );
  99. SRcovStorageObj PersFreshLog( pPersFreshLog );
  100. CRcovStorageHdr & hdr = pPersFreshLog->GetHeader();
  101. return hdr.GetCount( hdr.GetPrimary() );
  102. }
  103. //+---------------------------------------------------------------------------
  104. //
  105. // Member: CPersFresh::LokCompactLog, public
  106. //
  107. // Synopsis: Compacts the freshTable into a persistent stream
  108. //
  109. // Arguments: [PersFreshLog] -- persistant log to write data to
  110. // [iter] -- iterator to walk though freshTable table
  111. // [subst] -- index substitution object
  112. //
  113. // History: 93-Dec-03 DwightKr Created.
  114. // 94-Sep-07 SrikantS Corrected the bug by which entries
  115. // in the pers fresh test were lost
  116. // if a doc. is in wordlist.
  117. //
  118. // Notes: When we write the freshtest to disk, we must be careful not
  119. // to lose entries that already exist in the current persistent
  120. // log but have subsequently ended up in a wordlist. For example,
  121. // let (wid 20, iid 001) be an entry in the pers fresh test. If
  122. // the wid now got re-filtered and is in a wordlist iid 1001, we
  123. // must write (wid 20, iid 001) into the new persistent fresh
  124. // test. O/W, we will end up with no entry for wid 20 in the
  125. // fresh test upon a restart and cause "duplicate wid" problem
  126. // where by a wid will be present in a master index as well as
  127. // as a shadow index.
  128. //
  129. //----------------------------------------------------------------------------
  130. void CPersFresh::LokCompactLog( SRcovStorageObj & PersFreshLog,
  131. CFreshTableIter & freshIter,
  132. CIdxSubstitution& subst)
  133. {
  134. //
  135. // Create an in-memory copy the persistent fresh test. This will be
  136. // used to know the last persistent mapping for a document which
  137. // has subsequently been filtered and is in a wordlist.
  138. // 100 is the count guess for the # of entries.
  139. //
  140. XPtr<CFreshTest> xFreTestPersist( new CFreshTest( 100 ) );
  141. //
  142. // Load the entries from the persistent fresh log in the fresh hash.
  143. //
  144. LoadFreshTest( * xFreTestPersist->GetFreshTable() );
  145. //
  146. // Replace old index id's in this copy of persistent fresh test
  147. //
  148. XPtr<CFreshTest> xFreTestPersistUpdated(
  149. new CFreshTest( xFreTestPersist.GetReference(),
  150. subst ) );
  151. //
  152. // Create a brand new fresh log and append entries to it.
  153. //
  154. CRcovStrmAppendTrans xact( &PersFreshLog );
  155. //
  156. // It should be an empty object.
  157. //
  158. Win4Assert( PersFreshLog->GetHeader().GetCount(
  159. PersFreshLog->GetHeader().GetBackup() ) == 0 );
  160. CRcovStrmAppendIter appendIter( xact, sizeof(CPersRec) );
  161. //
  162. // freshIter points to the first entry in the freshTable. If the
  163. // freshTable is empty, then we don't need to process anything more
  164. // here, as we have an empty stream, which reflects an empty freshTable.
  165. //
  166. for ( ; !freshIter.AtEnd(); freshIter.Advance() )
  167. {
  168. INDEXID iidCurr = freshIter->IndexId();
  169. Win4Assert( iidInvalid != iidCurr );
  170. CIndexId IndexID( iidCurr );
  171. WORKID wid = freshIter->WorkId();
  172. //
  173. // If there is a wordlist which contains the information for this
  174. // wid, then we should use any persistent association found in the
  175. // persistent fresh test for this wid.
  176. //
  177. if ( !IndexID.IsPersistent() )
  178. {
  179. iidCurr = xFreTestPersistUpdated->Find( wid );
  180. }
  181. if ( iidInvalid != iidCurr )
  182. {
  183. #if CIDBG==1
  184. CIndexId iidVerify( iidCurr );
  185. Win4Assert( iidVerify.IsPersistent() );
  186. #endif // CIDBG
  187. CPersRec PersRec( wid, iidCurr );
  188. appendIter.AppendRec( &PersRec );
  189. }
  190. }
  191. xact.Commit();
  192. }