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.

288 lines
8.4 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: PIDXTBL.CXX
  7. //
  8. // Contents: Partition Index Table
  9. //
  10. // Classes: PIndexTable
  11. //
  12. // History: 16-Feb-94 SrikantS Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <pidxtbl.hxx>
  18. #include <pstore.hxx>
  19. #include <rcstxact.hxx>
  20. #include <rcstrmit.hxx>
  21. #include "prtiflst.hxx"
  22. #define WORKID_CONTENTINDXROOT 0
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Function: CreateAndAddIt
  26. //
  27. // Synopsis: This methods creates a WID for the specified "it" and
  28. // adds an entry to the index table. The "iid" is formed
  29. // by using the partition id and the index type.
  30. //
  31. // Arguments: [it] -- Index Type to be created.
  32. // [partid] -- Partition Id for the it.
  33. //
  34. // History: 2-16-94 srikants Created
  35. //
  36. // Notes:
  37. //
  38. //----------------------------------------------------------------------------
  39. WORKID PIndexTable::CreateAndAddIt( IndexType it, PARTITIONID partid )
  40. {
  41. WORKID wid;
  42. if ( itFreshLog == it )
  43. {
  44. wid = GetStorage().GetNewObjectIdForFreshLog();
  45. }
  46. else
  47. {
  48. //
  49. // In Kernel, OFS does not use the iid but in FAT that is used
  50. // as the wid of the object. So, generating a unique wid for
  51. // each "it" is by using the parition id and the it.
  52. //
  53. CIndexId iid(it, partid);
  54. wid = GetStorage().CreateObjectId( iid, PStorage::eRcovHdr );
  55. }
  56. AddObject( partid, it, wid );
  57. return wid;
  58. }
  59. //+---------------------------------------------------------------------------
  60. //----------------------------------------------------------------------------
  61. CPartInfo *
  62. PIndexTable::CreateOrGet( SPartInfoList & pList, PARTITIONID partId )
  63. {
  64. CPartInfo * pPartInfo = pList->GetPartInfo( partId );
  65. if ( !pPartInfo ) {
  66. pPartInfo = new CPartInfo( partId );
  67. pList->Append( pPartInfo );
  68. }
  69. return(pPartInfo);
  70. }
  71. //+---------------------------------------------------------------------------
  72. //
  73. // Function: QueryBootStrapInfo
  74. //
  75. // Synopsis: This method acts as the bootstrap procedure by reading the
  76. // index table from disk and creating/initializing the
  77. // "special" index types like the changelog, freshlog, etc.
  78. //
  79. // It also handles creating the "first" partition entry if
  80. // none exists.
  81. //
  82. // History: 2-16-94 srikants Created
  83. //
  84. // Notes: It is upto the caller of the function to destroy the
  85. // CPartInfoList that is created here.
  86. //
  87. //----------------------------------------------------------------------------
  88. CPartInfoList * PIndexTable::QueryBootStrapInfo()
  89. {
  90. WORKID widFreshLog = widInvalid;
  91. WORKID widPhraseLat = widInvalid;
  92. CPartInfoList * pPartInfoList = new CPartInfoList;
  93. SPartInfoList pList( pPartInfoList );
  94. BOOL fCreatePart = TRUE;
  95. {
  96. //
  97. // Iterate over the index table and form the PartInfoList.
  98. //
  99. SIndexTabIter pIdxIter(QueryIterator());
  100. if ( pIdxIter->Begin() )
  101. {
  102. CIndexRecord record;
  103. while ( pIdxIter->NextRecord ( record ) )
  104. {
  105. PARTITIONID partId = CIndexId( record.Iid()).PartId();
  106. if ( partidInvalid == partId )
  107. {
  108. //
  109. // The deleted index ids (iidDeleted1 and iidDeleted2)
  110. // both have 0xffff as their partid which is also the
  111. // partid invalid. We must treat it as a special case.
  112. //
  113. if ( itDeleted == record.Type() )
  114. {
  115. Win4Assert( iidInvalid == _iidDeleted &&
  116. "You have to reformat" );
  117. _iidDeleted = record.Iid();
  118. }
  119. continue;
  120. }
  121. //
  122. // Check if the partition is valid or not.
  123. //
  124. CPartInfo * pPartInfo = NULL;
  125. if ( partId != partidKeyList &&
  126. partId != partidFresh1 &&
  127. partId != partidFresh2 )
  128. {
  129. pPartInfo = CreateOrGet( pList, partId );
  130. Win4Assert( pPartInfo );
  131. fCreatePart = FALSE;
  132. }
  133. else if ( partidKeyList == partId )
  134. {
  135. continue;
  136. }
  137. switch( record.Type() ) {
  138. case itPartition:
  139. break;
  140. case itChangeLog:
  141. pPartInfo->SetChangeLogObjectId(record.ObjectId());
  142. break;
  143. case itMaster:
  144. pPartInfo->SetCurrMasterIndex(record.ObjectId());
  145. break;
  146. case itNewMaster:
  147. pPartInfo->SetNewMasterIndex(record.ObjectId());
  148. break;
  149. case itMMLog:
  150. pPartInfo->SetMMergeLog(record.ObjectId());
  151. break;
  152. case itFreshLog:
  153. widFreshLog = record.ObjectId();
  154. Win4Assert( widInvalid != widFreshLog );
  155. break;
  156. case itPhraseLat:
  157. widPhraseLat = record.ObjectId();
  158. Win4Assert( widInvalid != widPhraseLat );
  159. break;
  160. } // of switch
  161. } // of while
  162. } // of if
  163. } // This block necessary to destroy the pIdxIter
  164. if ( fCreatePart )
  165. {
  166. AddPartition( partidDefault );
  167. CPartInfo * pPartInfo = new CPartInfo( partidDefault );
  168. pList->Append( pPartInfo );
  169. }
  170. //
  171. // We now have to create any objects that are not created yet.
  172. //
  173. BOOL fNewFreshLog = FALSE;
  174. if ( widInvalid == widFreshLog )
  175. {
  176. fNewFreshLog = TRUE;
  177. widFreshLog = CreateAndAddIt( itFreshLog, partidDefault );
  178. }
  179. BOOL fNewPhraseLat = FALSE;
  180. if ( widInvalid == widPhraseLat )
  181. {
  182. fNewPhraseLat = TRUE;
  183. widPhraseLat = CreateAndAddIt( itPhraseLat, partidDefault );
  184. }
  185. if ( _iidDeleted == iidInvalid )
  186. {
  187. SetDeletedIndex( iidDeleted1 );
  188. }
  189. Win4Assert( widInvalid != widFreshLog );
  190. Win4Assert( widInvalid != widPhraseLat );
  191. GetStorage().InitRcovObj( widFreshLog, FALSE ); // other two strms also.
  192. GetStorage().InitRcovObj( widPhraseLat, TRUE ); // atomic strm only
  193. GetStorage().SetSpecialItObjectId( itFreshLog, widFreshLog );
  194. GetStorage().SetSpecialItObjectId( itPhraseLat, widPhraseLat );
  195. if ( fNewFreshLog )
  196. {
  197. //
  198. // Inside kernel, we are guaranteed that a new object has no data in
  199. // it. In user space, we may be using an object that was not deleted
  200. // before due to a failure.
  201. //
  202. PRcovStorageObj * pObj = GetStorage().QueryFreshLog(widFreshLog);
  203. XPtr<PRcovStorageObj> xObj(pObj);
  204. xObj->InitHeader(GetStorage().GetStorageVersion());
  205. }
  206. // phrase lattice is not used now
  207. //
  208. // For each partition, create/initialize the persistent objects
  209. // that exist on a per-partition basis. eg. ChangeLog.
  210. //
  211. for ( CForPartInfoIter it(*pList); !pList->AtEnd(it); pList->Advance(it) )
  212. {
  213. CPartInfo * pPartInfo = it.GetPartInfo();
  214. Win4Assert( pPartInfo );
  215. BOOL fNewChangeLog = FALSE;
  216. if ( widInvalid == pPartInfo->GetChangeLogObjectId() )
  217. {
  218. pPartInfo->SetChangeLogObjectId(
  219. CreateAndAddIt( itChangeLog, pPartInfo->GetPartId() ));
  220. fNewChangeLog = TRUE;
  221. }
  222. Win4Assert( widInvalid != pPartInfo->GetChangeLogObjectId() );
  223. GetStorage().InitRcovObj( pPartInfo->GetChangeLogObjectId(), FALSE );
  224. if ( fNewChangeLog )
  225. {
  226. PRcovStorageObj * pObj =
  227. GetStorage().QueryChangeLog( pPartInfo->GetChangeLogObjectId(),
  228. PStorage::ePrimChangeLog );
  229. XPtr<PRcovStorageObj> xObj(pObj);
  230. xObj->InitHeader(GetStorage().GetStorageVersion());
  231. }
  232. }
  233. return pList.Acquire();
  234. }