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.

802 lines
23 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: PARTLST.CXX
  7. //
  8. // Contents: Partition list
  9. //
  10. // Classes: CPartList
  11. //
  12. // History: 28-Mar-91 BartoszM Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <pstore.hxx>
  18. #include <cifailte.hxx>
  19. #include <eventlog.hxx>
  20. #include "partn.hxx"
  21. #include "partlst.hxx"
  22. #include "ci.hxx"
  23. #include "index.hxx"
  24. #include "idxids.hxx"
  25. #include "mindex.hxx"
  26. #include "resman.hxx"
  27. //+---------------------------------------------------------------------------
  28. //
  29. // Member: CPartList::CPartList
  30. //
  31. // Synopsis: Constructor.
  32. //
  33. // Effects: Opens Partitions Table and creates partitions
  34. //
  35. // Arguments: [storage] -- physical storage
  36. // [ciparent] -- parent content index object
  37. //
  38. // History: 28-Mar-91 BartoszM Created.
  39. //
  40. // Notes: _partArray is a dynamic array of pointers to partitions
  41. // indexed by partition ID. Null pointers correspond
  42. // to nonexisting (deleted) partitions.
  43. //
  44. // Index ID's for a given partition are packed in the table.
  45. // SHORT_IDX_ID's are of byte size, 255 of them can be
  46. // packed into a binary table field. The partition
  47. // will expand them into full index id's by oring
  48. // in the partition ID.
  49. //
  50. //----------------------------------------------------------------------------
  51. CPartList::CPartList( PStorage& storage,
  52. PIndexTable & idxTab,
  53. XPtr<CKeyList> & sKeyList,
  54. CTransaction& xact,
  55. CCiFrameworkParams & frmwrkParams
  56. ) : _sigPartList(eSigPartList),
  57. _frmwrkParams( frmwrkParams ),
  58. _idxTab(idxTab),
  59. _partInfoList(_idxTab.QueryBootStrapInfo()),
  60. _partArray ( _partInfoList->Count()+1 )
  61. {
  62. CIndex * pIndex = 0;
  63. CIidStack stkZombie(1);
  64. Win4Assert( !_partInfoList->IsEmpty() );
  65. //
  66. // Create the Partition Array from the PartInfoList.
  67. //
  68. CPartInfo * pPartInfo;
  69. while ( NULL != (pPartInfo = _partInfoList->GetFirst()) )
  70. {
  71. PARTITIONID partId = pPartInfo->GetPartId();
  72. Win4Assert( !IsValid(partId) );
  73. CPartition * pPart = new
  74. CPartition( pPartInfo->GetChangeLogObjectId(),
  75. partId,
  76. storage,
  77. frmwrkParams );
  78. _partArray.Add( pPart, partId );
  79. //
  80. // Set the wids of the objects that are part of a master
  81. // merge in this partition. If there is no master merge,
  82. // the wids will be appropriately set to widInvalid.
  83. //
  84. pPart->SetMMergeObjectIds( pPartInfo->GetMMergeLog(),
  85. pPartInfo->GetNewMasterIndex(),
  86. pPartInfo->GetCurrMasterIndex() );
  87. _partInfoList->RemoveFirst();
  88. delete pPartInfo;
  89. }
  90. Win4Assert( _partInfoList->IsEmpty() );
  91. CIndexIdList iidsInUse(16);
  92. CKeyList * pKeyList = 0;
  93. {
  94. SIndexTabIter pIdxIter(_idxTab.QueryIterator());
  95. if ( pIdxIter->Begin() )
  96. {
  97. CIndexRecord record;
  98. while ( pIdxIter->NextRecord ( record ) )
  99. {
  100. #ifdef CI_FAILTEST
  101. NTSTATUS status = CI_CORRUPT_DATABASE ;
  102. ciFAILTEST( status );
  103. #endif // CI_FAILTEST
  104. pIndex = RestoreIndex ( record, iidsInUse, stkZombie );
  105. if ( pIndex )
  106. {
  107. PARTITIONID partid = CIndexId ( record.Iid() ).PartId();
  108. if (partid == partidKeyList)
  109. {
  110. pKeyList = (CKeyList *) pIndex;
  111. sKeyList.Set( pKeyList );
  112. }
  113. else
  114. {
  115. _partArray.Get(partid)->RegisterId(pIndex->GetId());
  116. _partArray.Get(partid)->AddIndex ( pIndex );
  117. }
  118. }
  119. }
  120. }
  121. if (pKeyList == 0)
  122. {
  123. #ifdef CI_FAILTEST
  124. NTSTATUS status = CI_CORRUPT_DATABASE ;
  125. ciFAILTEST( status );
  126. #endif // CI_FAILTEST
  127. pKeyList = new CKeyList();
  128. sKeyList.Set(pKeyList);
  129. }
  130. } // This block needed to destroy the pIdxIter
  131. //
  132. // If there are any zombie indexes, they must be deleted now.
  133. //
  134. if ( stkZombie.Count() != 0 )
  135. {
  136. ciDebugOut (( DEB_WARN, "%d zombies\n", stkZombie.Count() ));
  137. do
  138. {
  139. CIndexDesc * pDesc = stkZombie.Pop();
  140. ciDebugOut (( DEB_WARN, "Removing zombie, iid = %x, objid = %x\n",
  141. pDesc->Iid(), pDesc->ObjectId() ));
  142. #ifdef CI_FAILTEST
  143. NTSTATUS status = CI_CORRUPT_DATABASE ;
  144. ciFAILTEST( status );
  145. #endif // CI_FAILTEST
  146. _idxTab.RemoveIndex ( pDesc->Iid() );
  147. if ( !storage.RemoveObject( pDesc->ObjectId() ) )
  148. {
  149. Win4Assert( !"delete of index failed" );
  150. ciDebugOut(( DEB_ERROR, "Delete of index, objid %08x failed\n",
  151. pDesc->ObjectId() ));
  152. }
  153. delete pDesc;
  154. }
  155. while ( stkZombie.Count() != 0);
  156. }
  157. //
  158. // Delete any unreferenced indexes.
  159. //
  160. storage.DeleteUnUsedPersIndexes( iidsInUse );
  161. //
  162. // Acquire and return the key list to resman.
  163. //
  164. Win4Assert( !sKeyList.IsNull() );
  165. }
  166. //+---------------------------------------------------------------------------
  167. //
  168. // Function: RestoreMMergeState
  169. //
  170. // Synopsis: Restores the state in memory for a stopped master merge.
  171. //
  172. // History: 7-07-94 srikants Moved from the constructor and added
  173. // more robustness checks.
  174. // 9-28-94 srikants Transfer of mastermerge indsnap fix.
  175. //
  176. // Notes: This can throw exceptions if the new index cannot be
  177. // constructed for some reason.
  178. //
  179. //----------------------------------------------------------------------------
  180. void CPartList::RestoreMMergeState( CResManager & resman, PStorage & storage )
  181. {
  182. for (PARTITIONID partid=0; partid<_partArray.Size(); partid++)
  183. {
  184. CPartition * pPart = _partArray.Get(partid);
  185. if ( (0 != pPart) && (pPart->InMasterMerge()) )
  186. {
  187. WORKID widNewMaster;
  188. WORKID widMasterLog;
  189. WORKID widCurrentMaster;
  190. pPart->GetMMergeObjectIds( widMasterLog, widNewMaster, widCurrentMaster);
  191. CPersIndex * pCurrentMasterIndex = pPart->GetCurrentMasterIndex();
  192. if ( widInvalid != widCurrentMaster && 0 == pCurrentMasterIndex )
  193. {
  194. //
  195. // MMState indicates that there is a master index but
  196. // we don't have one now - it must be a corruption.
  197. //
  198. Win4Assert( !"Corrupt catalog" );
  199. storage.ReportCorruptComponent( L"PartitionList1" );
  200. THROW( CException( CI_CORRUPT_DATABASE ) );
  201. }
  202. PRcovStorageObj *pPersMMergeLog = _idxTab.GetStorage().QueryMMergeLog(widMasterLog);
  203. SRcovStorageObj PersMMergeLog( pPersMMergeLog );
  204. XPtr<CMMergeLog> xMMergeLog( new CMMergeLog( *pPersMMergeLog ) );
  205. CMasterMergeIndex * pIndex = 0;
  206. //
  207. // Create a snapshot of the merge indexes to be given to the
  208. // master merge index.
  209. //
  210. CIndexSnapshot * pIndSnap = new CIndexSnapshot( resman );
  211. SIndexSnapshot sIndSnap( pIndSnap );
  212. pIndSnap->LokRestart( *pPart, *pPersMMergeLog );
  213. #ifdef CI_FAILTEST
  214. NTSTATUS status = CI_CORRUPT_DATABASE ;
  215. ciFAILTEST( status );
  216. #endif // CI_FAILTEST
  217. pIndex = new CMasterMergeIndex( _idxTab.GetStorage(),
  218. widNewMaster,
  219. pPart->GetNewMasterIid(),
  220. xMMergeLog->GetIndexWidMax(),
  221. pCurrentMasterIndex,
  222. widMasterLog,
  223. xMMergeLog.GetPointer() );
  224. //
  225. // ===================================================
  226. //
  227. // Beginning of no-failure region.
  228. pIndex->SetMMergeIndSnap( sIndSnap.Acquire() );
  229. pPart->RegisterId( pIndex->GetId() );
  230. pPart->AddIndex ( pIndex );
  231. //
  232. // If there is a pCurrentMasterIndex, then the pNewMasterIndex
  233. // encapsulates it and it should be invisible to the rest of CI.
  234. // Hence remove it from the index list within the partition.
  235. //
  236. if ( pCurrentMasterIndex )
  237. {
  238. pPart->LokRemoveIndex( pCurrentMasterIndex->GetId() );
  239. pPart->SetOldMasterIndex( pCurrentMasterIndex );
  240. }
  241. //
  242. // ===================================================
  243. //
  244. // End of no-failure region.
  245. }
  246. }
  247. }
  248. extern BOOL IsLowResources( SCODE sc );
  249. //+---------------------------------------------------------------------------
  250. //
  251. // Member: CPartList::RestoreIndex
  252. //
  253. // Synopsis: Restores the index
  254. //
  255. // Arguments: [rec] -
  256. // [iidsInUse] -
  257. // [stkZombie] -
  258. //
  259. // History: 07-Jan-99 klam Created header
  260. // Rethrow if low on disk space
  261. //
  262. //----------------------------------------------------------------------------
  263. CIndex* CPartList::RestoreIndex ( CIndexRecord & rec,
  264. CIndexIdList & iidsInUse,
  265. CIidStack & stkZombie)
  266. {
  267. PARTITIONID partid = CIndexId ( rec.Iid() ).PartId();
  268. //for keylist needs, should this be turned into CIndex * pIndex?
  269. CPersIndex * pIndex = 0;
  270. CIndexDesc * pdesc;
  271. CPartition * pPart = 0;
  272. TRY
  273. {
  274. switch ( rec.Type() )
  275. {
  276. case itNewMaster:
  277. pPart = _partArray.Get(partid);
  278. pPart->SetNewMasterIid( rec.Iid() );
  279. iidsInUse.Add( rec.Iid(), iidsInUse.Count() );
  280. break;
  281. case itMaster:
  282. case itShadow:
  283. {
  284. ciDebugOut (( DEB_ITRACE, "\tRestore %s %x, max wid %d\n",
  285. rec.Type() == itMaster ? "MASTER" : "SHADOW",
  286. rec.Iid(), rec.MaxWorkId() ));
  287. iidsInUse.Add( rec.Iid(), iidsInUse.Count() );
  288. CDiskIndex::EDiskIndexType idxType = rec.Type() == itMaster ?
  289. CDiskIndex::eMaster : CDiskIndex::eShadow;
  290. pIndex = new CPersIndex (
  291. _idxTab.GetStorage(),
  292. rec.ObjectId(),
  293. rec.Iid(),
  294. rec.MaxWorkId(),
  295. idxType,
  296. PStorage::eOpenForRead,
  297. TRUE);
  298. }
  299. break;
  300. case itZombie:
  301. ciDebugOut((DEB_ITRACE,
  302. "Removing zombie index %lx from physical storage\n",
  303. rec.Iid()));
  304. pIndex = 0;
  305. pdesc = new CIndexDesc( rec );
  306. stkZombie.Push( pdesc );
  307. break;
  308. case itPartition:
  309. break;
  310. case itDeleted:
  311. ciDebugOut (( DEB_ITRACE, "Deleted index %lx\n", rec.Iid() ));
  312. break;
  313. case itKeyList:
  314. ciDebugOut (( DEB_ITRACE, "\tRestore keylist %x, max key %d, KeyList\n",
  315. rec.Iid(), rec.MaxWorkId() ));
  316. #ifdef KEYLIST_ENABLED
  317. pIndex = (CPersIndex *) new CKeyList ( _idxTab.GetStorage(),
  318. rec.ObjectId(),
  319. rec.Iid(),
  320. rec.MaxWorkId() );
  321. #else
  322. pIndex = (CPersIndex *) new CKeyList( rec.MaxWorkId(),
  323. rec.Iid() );
  324. #endif // KEYLIST_ENABLED
  325. break;
  326. case itMMKeyList:
  327. ciDebugOut(( DEB_ITRACE,
  328. "MM KeyList Wid 0x%X\n", rec.ObjectId() ));
  329. _idxTab.GetStorage().SetSpecialItObjectId( itMMKeyList, rec.ObjectId() );
  330. break;
  331. }
  332. }
  333. CATCH( CException, e )
  334. {
  335. delete pIndex;
  336. pIndex = 0;
  337. SCODE sc = e.GetErrorCode();
  338. if ( IsDiskLowError( sc ) || IsLowResources( sc ) )
  339. {
  340. ciDebugOut (( DEB_WARN, "CPartlist::RestoreIndex - Out of resources!" ));
  341. RETHROW ();
  342. }
  343. else
  344. {
  345. ciDebugOut(( DEB_WARN, "Fatal error %x opening index. "
  346. "Zombifying iid=0x%x, objid=0x%x, type=0x%x\n",
  347. sc,
  348. rec.Iid(), rec.ObjectId(), rec.Type() ));
  349. Win4Assert( !"Corrupt catalog" );
  350. THROW( CException( CI_CORRUPT_DATABASE ) );
  351. }
  352. }
  353. END_CATCH;
  354. return pIndex;
  355. } //RestoreIndex
  356. //+---------------------------------------------------------------------------
  357. //
  358. // Member: CPartList::LokGetPartition, public
  359. //
  360. // Synopsis: Converts partition id into partition object
  361. //
  362. // History: 07-Oct-91 BartoszM Created.
  363. //
  364. //----------------------------------------------------------------------------
  365. CPartition* CPartList::LokGetPartition ( PARTITIONID partid )
  366. {
  367. if ( partid >= _partArray.Size() )
  368. THROW ( CException ( CI_INVALID_PARTITION ));
  369. return _partArray.Get( partid );
  370. }
  371. //+---------------------------------------------------------------------------
  372. //
  373. // Member: CPartList::LokSwapIndexes, public
  374. //
  375. // Synopsis: Adds new persistent index to the table
  376. // and removes old ones
  377. //
  378. // Arguments: [indexNew] -- new index
  379. // [cIidOld] -- count of old indexes
  380. // [aIidOld] -- array of old index id's
  381. //
  382. // History: 02-May-91 BartoszM Created.
  383. // 07-Apr-94 DwightKr Added code for master index
  384. //
  385. // Notes: ResMan LOCKED
  386. //
  387. //----------------------------------------------------------------------------
  388. void CPartList::LokSwapIndexes (
  389. CMergeTrans& xact,
  390. PARTITIONID partid,
  391. CDiskIndex * indexNew,
  392. CShadowMergeSwapInfo & info
  393. )
  394. {
  395. ciDebugOut (( DEB_ITRACE, "CPartList::LokSwapIndexes\n" ));
  396. CPartition* pPart = LokGetPartition ( partid );
  397. if ( 0 == indexNew )
  398. info._recNewIndex._objectId = widInvalid;
  399. else
  400. {
  401. pPart->Swap ( xact, indexNew, info._cIndexOld, info._aIidOld );
  402. indexNew->FillRecord( info._recNewIndex );
  403. Win4Assert( ! indexNew->IsMaster() );
  404. #ifdef CI_FAILTEST
  405. NTSTATUS status = CI_CORRUPT_DATABASE ;
  406. ciFAILTEST( status );
  407. #endif // CI_FAILTEST
  408. }
  409. _idxTab.SwapIndexes (info);
  410. }
  411. void CPartList::LokSwapIndexes (
  412. CMergeTrans& xact,
  413. PARTITIONID partid,
  414. CDiskIndex * indexNew,
  415. CMasterMergeSwapInfo & info,
  416. CKeyList const * pOldKeyList,
  417. CKeyList const * pNewKeyList )
  418. {
  419. ciDebugOut (( DEB_ITRACE, "CPartList::LokSwapIndexes\n" ));
  420. CPartition* pPart = LokGetPartition ( partid );
  421. indexNew->FillRecord( info._recNewIndex );
  422. info._iidOldKeyList = pOldKeyList->GetId();
  423. pNewKeyList->FillRecord( info._recNewKeyList );
  424. Win4Assert( indexNew->IsMaster() );
  425. WORKID widCurrentMaster;
  426. WORKID widNewMaster;
  427. pPart->GetMMergeObjectIds( info._widMMLog, widNewMaster, widCurrentMaster );
  428. #ifdef CI_FAILTEST
  429. NTSTATUS status = CI_CORRUPT_DATABASE ;
  430. ciFAILTEST( status );
  431. #endif // CI_FAILTEST
  432. _idxTab.SwapIndexes ( info );
  433. //
  434. // At this stage there are no traces of the master merge in persistent
  435. // storage. The entry for the master merge log has been deleted from
  436. // the index list. We have to clean up the in-memory data structures
  437. // to reflect this.
  438. //
  439. pPart->Swap ( xact, indexNew, info._cIndexOld, info._aIidOld );
  440. pPart->SetMMergeObjectIds( widInvalid, widInvalid, widNewMaster );
  441. pPart->SetOldMasterIndex(0);
  442. pPart->SetNewMasterIid(CIndexId( iidInvalid, partidInvalid ) );
  443. //
  444. // RemoveMMLog cannot throw.
  445. //
  446. _idxTab.GetStorage().RemoveMMLog( info._widMMLog );
  447. }
  448. #ifdef KEYLIST_ENABLED
  449. //+-------------------------------------------------------------------------
  450. //
  451. // Method: CPartList::LokRemoveKeyList
  452. //
  453. // Synopsis: Persistently remove keylist
  454. //
  455. // Arguments: [pKeyList] -- Keylist to remove
  456. //
  457. // History: 17-Feb-1994 KyleP Created
  458. //
  459. //--------------------------------------------------------------------------
  460. void CPartList::LokRemoveKeyList ( CKeyList const * pKeyList )
  461. {
  462. if ( pKeyList->IsPersistent() )
  463. {
  464. #ifdef CI_FAILTEST
  465. NTSTATUS status = CI_CORRUPT_DATABASE ;
  466. ciFAILTEST( status );
  467. #endif // CI_FAILTEST
  468. CIndexId iid = pKeyList->GetId();
  469. _idxTab.RemoveIndex ( iid );
  470. }
  471. }
  472. #endif // KEYLIST_ENABLED
  473. //+---------------------------------------------------------------------------
  474. //
  475. // Member: CPartList::LokRemoveIndex, public
  476. //
  477. // Synopsis: Removes index from list
  478. //
  479. // Arguments: [iid] -- index id
  480. //
  481. // History: 02-May-91 BartoszM Created.
  482. //
  483. // Notes: ResMan LOCKED
  484. //
  485. //----------------------------------------------------------------------------
  486. void CPartList::LokRemoveIndex ( CIndexId iid )
  487. {
  488. CPartition* pPart = LokGetPartition ( iid.PartId() );
  489. ciAssert ( pPart != 0 );
  490. pPart->FreeIndexId ( iid );
  491. #ifdef CI_FAILTEST
  492. NTSTATUS status = CI_CORRUPT_DATABASE ;
  493. ciFAILTEST( status );
  494. #endif // CI_FAILTEST
  495. if ( iid.IsPersistent() )
  496. _idxTab.RemoveIndex ( iid );
  497. }
  498. //+---------------------------------------------------------------------------
  499. //
  500. // Member: CPartList::LokWlCount, public
  501. //
  502. // Synopsis: Counts the existing word lists
  503. //
  504. // Returns: number of word lists
  505. //
  506. // History: 11-May-93 AmyA Created.
  507. //
  508. // Notes: ResMan LOCKED
  509. //
  510. //----------------------------------------------------------------------------
  511. unsigned CPartList::LokWlCount ()
  512. {
  513. CPartIter iter;
  514. unsigned count = 0;
  515. for ( iter.LokInit(*this); !iter.LokAtEnd(); iter.LokAdvance(*this))
  516. count += iter.LokGet()->WordListCount();
  517. return count;
  518. }
  519. //+---------------------------------------------------------------------------
  520. //
  521. // Member: CPartList::LokIndexCount, public
  522. //
  523. // Synopsis: Counts the existing persistent indexs
  524. //
  525. // Returns: number of indexs
  526. //
  527. // History: 14-Apr-93 t-joshh Created.
  528. //
  529. // Notes: ResMan LOCKED
  530. //
  531. //----------------------------------------------------------------------------
  532. unsigned CPartList::LokIndexCount ()
  533. {
  534. CPartIter iter;
  535. unsigned count = 0;
  536. for ( iter.LokInit(*this); !iter.LokAtEnd(); iter.LokAdvance(*this))
  537. count += iter.LokGet()->LokIndexCount();
  538. return count;
  539. }
  540. //+---------------------------------------------------------------------------
  541. //
  542. // Member: CPartList::LokIndexSize, public
  543. //
  544. // Synopsis: Counts the total size occupied by the persistent indexs
  545. //
  546. // Returns: size of index
  547. //
  548. // History: 14-Apr-93 t-joshh Created.
  549. //
  550. // Notes: ResMan LOCKED
  551. //
  552. //----------------------------------------------------------------------------
  553. unsigned CPartList::LokIndexSize ()
  554. {
  555. CPartIter iter;
  556. unsigned count = 0;
  557. for ( iter.LokInit(*this); !iter.LokAtEnd(); iter.LokAdvance(*this))
  558. count += iter.LokGet()->LokIndexSize();
  559. return count;
  560. }
  561. //+---------------------------------------------------------------------------
  562. //
  563. // Function: LokAddIt, public
  564. //
  565. // Synopsis: Adds the wid to the index list
  566. //
  567. // Arguments: [objectId] -- object ID to add to partition table
  568. // [it] -- Index type of the object to be added
  569. // [partid] -- Partition id in which to add.
  570. //
  571. // History: Nov-16-94 DwightKr Created
  572. //
  573. // Notes: It is assumed that only one of each "it" will be added
  574. // but no check is made to that effect.
  575. //
  576. //----------------------------------------------------------------------------
  577. void CPartList::LokAddIt( WORKID objectId, IndexType it, PARTITIONID partid )
  578. {
  579. _idxTab.AddObject( partid, it, objectId );
  580. }
  581. //+---------------------------------------------------------------------------
  582. //
  583. // Function: GetChangeLogObjectId, public
  584. //
  585. // Synopsis: Returns the change log wid for the partition specified
  586. //
  587. // Arguments: [partid] -- Partition id to return change log wid
  588. //
  589. // History: 16-Aug-94 DwightKr Created
  590. //
  591. //----------------------------------------------------------------------------
  592. WORKID CPartList::GetChangeLogObjectId( PARTITIONID partid )
  593. {
  594. WORKID widChangeLog = widInvalid;
  595. CPartInfo *pPartInfo = _partInfoList->GetPartInfo( partid );
  596. if ( pPartInfo )
  597. widChangeLog = pPartInfo->GetChangeLogObjectId();
  598. return widChangeLog;
  599. }
  600. //+---------------------------------------------------------------------------
  601. //----------------------------------------------------------------------------
  602. void CPartIter::LokInit(CPartList& partList)
  603. {
  604. _curPartId = 0;
  605. _pPart = 0;
  606. LokAdvance(partList);
  607. }
  608. //+---------------------------------------------------------------------------
  609. //
  610. // Member: CPartIter::LokAdvance, public
  611. //
  612. // Synopsis: Returns pointer to next partition
  613. //
  614. // History: 23-Jul-91 BartoszM Created.
  615. //
  616. //----------------------------------------------------------------------------
  617. void CPartIter::LokAdvance ( CPartList& partList)
  618. {
  619. ciAssert ( _curPartId != partidInvalid );
  620. while ( _curPartId <= partList.MaxPartid()
  621. && !partList.IsValid (_curPartId) )
  622. {
  623. _curPartId++;
  624. }
  625. if ( !partList.IsValid (_curPartId ) )
  626. {
  627. _curPartId = partidInvalid;
  628. _pPart = 0;
  629. }
  630. else
  631. {
  632. _pPart = partList.LokGetPartition ( _curPartId );
  633. ciAssert ( _pPart );
  634. _curPartId++;
  635. }
  636. }
  637. //+---------------------------------------------------------------------------
  638. //
  639. // Member: CPartIdIter::LokInit, public
  640. //
  641. // Synopsis: Partition iterator
  642. //
  643. // History: 23-Jul-91 BartoszM Created.
  644. //
  645. //----------------------------------------------------------------------------
  646. void CPartIdIter::LokInit ( CPartList& partList )
  647. {
  648. _curPartId = 0;
  649. LokAdvance(partList);
  650. }
  651. //+---------------------------------------------------------------------------
  652. //
  653. // Member: CPartIdIter::LokAdvance, public
  654. //
  655. // Synopsis: Advances to next partition id
  656. //
  657. // History: 23-Jul-91 BartoszM Created.
  658. //
  659. //----------------------------------------------------------------------------
  660. void CPartIdIter::LokAdvance( CPartList& partList )
  661. {
  662. ciAssert ( _curPartId != partidInvalid );
  663. while ( _curPartId <= partList.MaxPartid()
  664. && !partList.IsValid (_curPartId) )
  665. {
  666. _curPartId++;
  667. }
  668. if ( !partList.IsValid (_curPartId ) )
  669. {
  670. _curPartId = partidInvalid;
  671. }
  672. }