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.

873 lines
25 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: IDXTAB.CXX
  7. //
  8. // Contents: Index Manager
  9. //
  10. // Classes: CIndexTable
  11. //
  12. // History: 22-Mar-91 BartoszM Created.
  13. // 12-Feb-92 AmyA Hacked all methods for FAT.
  14. // 01-Jul-93 BartoszM Rewrote to use memory mapped file
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <pch.cxx>
  18. #pragma hdrstop
  19. #include <cistore.hxx>
  20. #include <idxtab.hxx>
  21. #include <eventlog.hxx>
  22. #include <imprsnat.hxx>
  23. //+---------------------------------------------------------------------------
  24. //----------------------------------------------------------------------------
  25. CWriteIndexFile::CWriteIndexFile ( PRcovStorageObj & rcovObj ) :
  26. _rcovObj(rcovObj),
  27. _xact(rcovObj),
  28. _iter(_xact, sizeof(CIndexRecord)),
  29. _xactPtr(0)
  30. {
  31. }
  32. //+---------------------------------------------------------------------------
  33. //----------------------------------------------------------------------------
  34. void CWriteIndexFile::BackUp()
  35. {
  36. ciAssert(_xactPtr > 0);
  37. _xactPtr--;
  38. _iter.Seek( _xactPtr );
  39. }
  40. //+---------------------------------------------------------------------------
  41. //----------------------------------------------------------------------------
  42. BOOL CWriteIndexFile::ReadRecord ( CIndexRecord * pRecord )
  43. {
  44. ULONG ulRecCnt = _rcovObj.GetHeader().GetCount(_rcovObj.GetHeader().GetBackup());
  45. if (_xactPtr >= ulRecCnt)
  46. return(FALSE);
  47. _iter.GetRec( pRecord );
  48. _xactPtr++;
  49. return(TRUE);
  50. }
  51. //+---------------------------------------------------------------------------
  52. //----------------------------------------------------------------------------
  53. void CWriteIndexFile::WriteRecord ( CIndexRecord* pRecord )
  54. {
  55. _iter.SetRec( pRecord );
  56. _xactPtr++;
  57. ULONG ulRecCnt = _rcovObj.GetHeader().GetCount(_rcovObj.GetHeader().GetBackup());
  58. if (ulRecCnt < _xactPtr)
  59. _rcovObj.GetHeader().SetCount(_rcovObj.GetHeader().GetBackup(), _xactPtr);
  60. }
  61. //+---------------------------------------------------------------------------
  62. //
  63. // Member: CWriteIndexFile::IncrMMergeSeqNum
  64. //
  65. // Synopsis: Increments the master merge sequence number in the header.
  66. //
  67. // History: 3-21-97 srikants Created
  68. //
  69. //----------------------------------------------------------------------------
  70. void CWriteIndexFile::IncrMMergeSeqNum()
  71. {
  72. CRcovStorageHdr & storageHdr = _rcovObj.GetHeader();
  73. CRcovUserHdr usrHdr;
  74. CIndexTableUsrHdr * pIdxUsrHdr = (CIndexTableUsrHdr *) &usrHdr;
  75. storageHdr.GetUserHdr( storageHdr.GetPrimary(), usrHdr );
  76. ciDebugOut(( DEB_ITRACE, "Current MMerge Seq Num = %d \n",
  77. pIdxUsrHdr->GetMMergeSeqNum() ));
  78. pIdxUsrHdr->IncrMMergeSeqNum();
  79. ciDebugOut(( DEB_ITRACE, "New MMerge Seq Num = %d \n",
  80. pIdxUsrHdr->GetMMergeSeqNum() ));
  81. storageHdr.SetUserHdr( storageHdr.GetBackup(), usrHdr );
  82. }
  83. //+---------------------------------------------------------------------------
  84. //----------------------------------------------------------------------------
  85. CReadIndexFile::CReadIndexFile ( PRcovStorageObj & rcovObj ) :
  86. _rcovObj(rcovObj),
  87. _xact(rcovObj),
  88. _iter(_xact, sizeof(CIndexRecord)),
  89. _xactPtr(0)
  90. {
  91. }
  92. //+---------------------------------------------------------------------------
  93. //----------------------------------------------------------------------------
  94. void CReadIndexFile::BackUp()
  95. {
  96. ciAssert(_xactPtr > 0);
  97. _xactPtr--;
  98. _iter.Seek( _xactPtr );
  99. }
  100. //+---------------------------------------------------------------------------
  101. //----------------------------------------------------------------------------
  102. BOOL CReadIndexFile::ReadRecord ( CIndexRecord * pRecord )
  103. {
  104. ULONG ulRecCnt = _rcovObj.GetHeader().GetCount(_rcovObj.GetHeader().GetPrimary());
  105. if (_xactPtr >= ulRecCnt)
  106. return(FALSE);
  107. _iter.GetRec( pRecord );
  108. _xactPtr++;
  109. return(TRUE);
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CAddReplaceIndexRecord::CAddReplaceIndexRecord, public
  114. //
  115. // Synopsis: Rewinds the file pointer indFile, then reads in IndexRecords until
  116. // either a record with INDEXID iid is found or EOF is reached.
  117. //
  118. // Notes: Whether or not a record with INDEXID iid is found can be
  119. // determined by calling Found().
  120. //
  121. // History: 16-Mar-92 AmyA Created.
  122. //
  123. //----------------------------------------------------------------------------
  124. CAddReplaceIndexRecord::CAddReplaceIndexRecord ( CWriteIndexFile & indFile,
  125. INDEXID iid )
  126. : _indFile( indFile )
  127. {
  128. _indFile.Rewind();
  129. do
  130. {
  131. _found = _indFile.ReadRecord ( this );
  132. } while (_found && Iid() != iid);
  133. }
  134. //+---------------------------------------------------------------------------
  135. //
  136. // Member: CAddReplaceIndexRecord::Write()
  137. //
  138. // Synopsis: Writes the information from CIndexRecord out to the file--
  139. // either replacing the record that was found in the constructor
  140. // (if there was one found) or appending to the end of the file
  141. // indicated by _indFile.
  142. //
  143. // History: 28-Feb-95 DwightKr Created.
  144. //
  145. //----------------------------------------------------------------------------
  146. inline void CAddReplaceIndexRecord::WriteRecord()
  147. {
  148. if ( Found() )
  149. {
  150. _indFile.BackUp();
  151. }
  152. _indFile.WriteRecord( this );
  153. }
  154. //+---------------------------------------------------------------------------
  155. //
  156. // Member: CIndexTable::CIndexTable, public
  157. //
  158. // Synopsis: Constructor.
  159. //
  160. // History: 28-Mar-91 BartoszM Created.
  161. //
  162. //----------------------------------------------------------------------------
  163. CIndexTable::CIndexTable ( CiStorage& storage, CTransaction& xact )
  164. : _storage(storage), _pRcovObj(0)
  165. {
  166. _pRcovObj = _storage.QueryIdxTableObject();
  167. Win4Assert( 0 != _pRcovObj );
  168. }
  169. //+---------------------------------------------------------------------------
  170. //
  171. // Member: CIndexTable::~CIndexTable, public
  172. //
  173. // Synopsis: Destructor.
  174. //
  175. // History: 28-May-92 BartoszM Created.
  176. //
  177. //----------------------------------------------------------------------------
  178. CIndexTable::~CIndexTable ()
  179. {
  180. delete _pRcovObj;
  181. }
  182. //+---------------------------------------------------------------------------
  183. //
  184. // Member: CIndexTableIter::CIndexTableIter
  185. //
  186. // Synopsis: Constructor.
  187. //
  188. // History: 28-May-92 BartoszM Created.
  189. //
  190. //----------------------------------------------------------------------------
  191. CIndexTabIter::CIndexTabIter ( CIndexTable& idxTable )
  192. : _idxTable(idxTable),
  193. _indFile( idxTable.GetIndexTableObj() )
  194. {
  195. }
  196. //+---------------------------------------------------------------------------
  197. //
  198. // Member: CIndexTabIter::Begin, public
  199. //
  200. // Synopsis: Position cursor at the beginning of table
  201. //
  202. // History: 28-Mar-91 BartoszM Created.
  203. //
  204. //----------------------------------------------------------------------------
  205. BOOL CIndexTabIter::Begin ()
  206. {
  207. CNextIndexRecord rec(_indFile);
  208. if (!rec.Found())
  209. return FALSE;
  210. _indFile.Rewind();
  211. return TRUE;
  212. }
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Member: CIndexTabIter::NextRecord, public
  216. //
  217. // Synopsis: Called during startup. Reads next record
  218. //
  219. // Arguments: [indexRecord] -- record to be filled
  220. //
  221. // History: 28-Mar-91 BartoszM Created.
  222. //
  223. //----------------------------------------------------------------------------
  224. BOOL CIndexTabIter::NextRecord ( CIndexRecord& indexRecord )
  225. {
  226. CNextIndexRecord rec(_indFile);
  227. if (!rec.Found())
  228. return(FALSE);
  229. if ( rec.VersionStamp() < _idxTable._storage.GetStorageVersion() )
  230. {
  231. Win4Assert ( !"Corrupt index table" );
  232. PStorage & storage = GetStorage();
  233. storage.ReportCorruptComponent ( L"IndexTable1" );
  234. THROW( CException ( STATUS_INTERNAL_DB_CORRUPTION ));
  235. }
  236. else if ( rec.VersionStamp() > _idxTable._storage.GetStorageVersion() )
  237. {
  238. ciAssert ( !"Unknown index format: upgrade index software" );
  239. PStorage & storage = GetStorage();
  240. storage.ReportCorruptComponent ( L"IndexTable2" );
  241. THROW( CException ( STATUS_INTERNAL_DB_CORRUPTION ));
  242. }
  243. indexRecord._objectId = rec.ObjectId();
  244. indexRecord._iid = rec.Iid();
  245. indexRecord._type = rec.Type();
  246. indexRecord._maxWorkId = rec.MaxWorkId();
  247. return TRUE;
  248. }
  249. //+---------------------------------------------------------------------------
  250. //
  251. // Member: CIndexTabIter::~CIndexTabIter, public
  252. //
  253. // Synopsis: Iteration finished
  254. //
  255. // History: 28-Mar-91 BartoszM Created.
  256. //
  257. //----------------------------------------------------------------------------
  258. CIndexTabIter::~CIndexTabIter()
  259. {
  260. }
  261. //+---------------------------------------------------------------------------
  262. //
  263. // Member: CIndexTable::SwapIndexes, public
  264. //
  265. // Synopsis: Replaces old indexes with a new one after merge
  266. //
  267. // Arguments: [pIndexNew] -- new index
  268. // [cIndexOld] -- count of old indexes to be removed
  269. // [aIidOld] -- array of old index id's
  270. //
  271. // Notes: ResMan LOCKED
  272. //
  273. // History: 02-May-91 BartoszM Created.
  274. //
  275. //----------------------------------------------------------------------------
  276. void CIndexTable::SwapIndexes ( CShadowMergeSwapInfo & info )
  277. {
  278. CIndexRecord & record = info._recNewIndex;
  279. ciDebugOut (( DEB_ITRACE, "IndexManager: Adding index %lx, maxWid %ld\n",
  280. record.Iid(), record.MaxWorkId() ));
  281. CWriteIndexFile indFile( GetIndexTableObj() );
  282. // Mark old indexes deleted
  283. for ( unsigned i = 0; i < info._cIndexOld; i++ )
  284. {
  285. CIndexId idFull = info._aIidOld[i];
  286. if ( idFull.IsPersistent())
  287. {
  288. CAddReplaceIndexRecord rec(indFile, info._aIidOld[i]);
  289. if (!rec.Found())
  290. {
  291. //
  292. // We have a persistent index which was not found in the
  293. // index list. This must be an index corruption.
  294. //
  295. ciDebugOut(( DEB_ERROR, "Can't find index 0x%lx\n",
  296. info._aIidOld[i] ));
  297. Win4Assert( !"Corrupt index table" );
  298. _storage.ReportCorruptComponent( L"IndexTable3" );
  299. THROW( CException ( CI_CORRUPT_DATABASE ));
  300. }
  301. rec.SetType(itZombie); // And one more....
  302. rec.WriteRecord();
  303. }
  304. }
  305. //
  306. // Add record for the new index.
  307. //
  308. if ( widInvalid != record.ObjectId() )
  309. AddRecord ( indFile,
  310. record.Iid(),
  311. record.Type(),
  312. record.MaxWorkId(),
  313. record.ObjectId() );
  314. //
  315. // Replace the old fresh test entry with the new fresh test entry.
  316. //
  317. DeleteObject( indFile, partidDefault, itFreshLog, info._widOldFreshLog );
  318. AddRecord( indFile, CIndexId( 0, partidDefault ), itFreshLog,
  319. 0, info._widNewFreshLog );
  320. indFile.Commit();
  321. }
  322. //+---------------------------------------------------------------------------
  323. //
  324. // Function: SwapIndexes
  325. //
  326. // Synopsis: This method marks the old indexes as "zombie" in the index
  327. // table, deletes the MMLog, MMFreshLog and NewMasterIndex
  328. // entries. It then adds an entry making the NewMaster the
  329. // current master.
  330. //
  331. // This is done as a single TRANSACTION - either the entire
  332. // step succeeds or the previous state is retained.
  333. //
  334. // Effects: All the indexes that participated in the master merge will
  335. // be deleted from the index list and the new master will be
  336. // made the only master index.
  337. //
  338. // Arguments: [partid] -- Partition Id where the master merge just
  339. // completed.
  340. // [cIndexOld] -- Count of the indexes in aIidOld.
  341. // [aIidOld] -- Array of index ids to be marked zombie.
  342. // [recNewMaster] -- CIndexRecord for the new master index.
  343. // [widMMLog] -- WorkId of the MMLog object.
  344. //
  345. // History: 4-04-94 srikants Created
  346. //
  347. // Notes:
  348. //
  349. //----------------------------------------------------------------------------
  350. void CIndexTable::SwapIndexes ( CMasterMergeSwapInfo & info )
  351. {
  352. CIndexRecord & recNewMaster = info._recNewIndex;
  353. CIndexRecord & recNewKeyList = info._recNewKeyList;
  354. ciDebugOut (( DEB_ITRACE, "Master Merge Completed\n"));
  355. CWriteIndexFile indFile( GetIndexTableObj() );
  356. //
  357. // Mark old indexes as "Zombie".
  358. //
  359. for ( unsigned i = 0; i < info._cIndexOld; i++ )
  360. {
  361. CIndexId idFull = info._aIidOld[i];
  362. Win4Assert( idFull.IsPersistent() );
  363. Win4Assert( idFull.PartId() == info._partid );
  364. CAddReplaceIndexRecord rec(indFile, info._aIidOld[i]);
  365. if (!rec.Found())
  366. {
  367. //
  368. // We have a persistent index which was not found in the
  369. // index list. This must be an index corruption.
  370. //
  371. ciDebugOut(( DEB_ERROR, "Can't find index 0x%lx\n",
  372. info._aIidOld[i] ));
  373. Win4Assert( !"Corrupt index table" );
  374. _storage.ReportCorruptComponent( L"IndexTable4" );
  375. THROW( CException ( CI_CORRUPT_DATABASE ));
  376. }
  377. rec.SetType(itZombie); // And one more....
  378. rec.WriteRecord();
  379. }
  380. //
  381. // Delete the MMLog entry.
  382. //
  383. DeleteObject( indFile, info._partid, itMMLog, info._widMMLog );
  384. //
  385. // Delete the itMMKeyList entry.
  386. //
  387. DeleteObject( indFile, partidKeyList, itMMKeyList,
  388. recNewKeyList.ObjectId() );
  389. //
  390. // Delete the old itKeyList entry and add an entry for the new
  391. // key list.
  392. //
  393. {
  394. //
  395. // DeleteRecord assumes that the record is found. When we create
  396. // the key list for the first time, it may not be present.
  397. //
  398. CAddReplaceIndexRecord rec( indFile, info._iidOldKeyList );
  399. if ( rec.Found() )
  400. {
  401. rec.SetIid( CIndexId(iidInvalid,partidInvalid) );
  402. rec.WriteRecord();
  403. }
  404. }
  405. AddRecord( indFile, recNewKeyList.Iid(),
  406. recNewKeyList.Type(),
  407. recNewKeyList.MaxWorkId(),
  408. recNewKeyList.ObjectId()
  409. );
  410. //
  411. // Delete the entry for the new master index and make it the
  412. // current master index.
  413. //
  414. DeleteRecord( indFile, recNewMaster.Iid() );
  415. AddRecord (
  416. indFile,
  417. recNewMaster.Iid(),
  418. itMaster, // Note the change from itNewMaster to itMaster
  419. recNewMaster.MaxWorkId(),
  420. recNewMaster.ObjectId());
  421. //
  422. // Replace the old fresh test entry with the new fresh test entry.
  423. //
  424. DeleteObject( indFile, partidDefault, itFreshLog, info._widOldFreshLog );
  425. AddRecord( indFile, CIndexId( 0, partidDefault ), itFreshLog, 0,
  426. info._widNewFreshLog );
  427. //
  428. // Increment the master merge sequence number.
  429. //
  430. indFile.IncrMMergeSeqNum();
  431. indFile.Commit();
  432. }
  433. PIndexTabIter* CIndexTable::QueryIterator()
  434. {
  435. return new CIndexTabIter ( *this );
  436. }
  437. PStorage& CIndexTable::GetStorage()
  438. {
  439. return(_storage);
  440. }
  441. //+---------------------------------------------------------------------------
  442. //
  443. // Member: CIndexTable::RemoveIndex, public
  444. //
  445. // Synopsis: Removes index from table
  446. //
  447. // Arguments: [iid] -- index id
  448. //
  449. // Notes: ResMan LOCKED
  450. //
  451. // History: 02-May-91 BartoszM Created.
  452. //
  453. //----------------------------------------------------------------------------
  454. #pragma optimize( "", off )
  455. void CIndexTable::RemoveIndex ( INDEXID iid )
  456. {
  457. CImpersonateSystem impersonate;
  458. CWriteIndexFile indFile( GetIndexTableObj() );
  459. DeleteRecord( indFile, iid );
  460. indFile.Commit();
  461. }
  462. #pragma optimize( "", on )
  463. //+---------------------------------------------------------------------------
  464. //
  465. // Function: AddObject
  466. //
  467. // Synopsis: Appends a record for the specified object to the
  468. // index table.
  469. //
  470. // Arguments: [partid] -- Id of the partition to which the object
  471. // belongs.
  472. // [it] -- Index type of the object.
  473. // [wid] -- WorkId of the object.
  474. //
  475. // History: 2-18-94 srikants Created
  476. //
  477. //----------------------------------------------------------------------------
  478. void CIndexTable::AddObject( PARTITIONID partid, IndexType it, WORKID wid )
  479. {
  480. CWriteIndexFile indFile( GetIndexTableObj() );
  481. AddRecord ( indFile, CIndexId ( 0, partid ), it, 0, wid );
  482. indFile.Commit();
  483. }
  484. //+---------------------------------------------------------------------------
  485. //
  486. // Function: AddMMergeObjects
  487. //
  488. // Synopsis: This method adds records for the NewMaster Index,
  489. // and MasterMerge Log to the index table.
  490. //
  491. // Arguments: [partid] -- Partition id of the partition in which
  492. // master merge is being done.
  493. // [recNewMaster] -- The index record for the new master index.
  494. // [widMMLog] -- WorkId of the MasterMerge Log.
  495. // [deletedIndex] -- Index id for the current index
  496. //
  497. // History: 4-04-94 srikants Created
  498. //
  499. // Notes: The recNewMaster must be fully initialized with the correct
  500. // indexType, WorkId and MaxWorkId.
  501. //
  502. //----------------------------------------------------------------------------
  503. void CIndexTable::AddMMergeObjects( PARTITIONID partid,
  504. CIndexRecord & recNewMaster,
  505. WORKID widMMLog,
  506. WORKID widMMKeyList,
  507. INDEXID iidDelOld,
  508. INDEXID iidDelNew )
  509. {
  510. CWriteIndexFile indFile( GetIndexTableObj() );
  511. Win4Assert( recNewMaster.Type() == itNewMaster );
  512. Win4Assert( iidDeleted1 == iidDelOld && iidDeleted2 == iidDelNew ||
  513. iidDeleted2 == iidDelOld && iidDeleted1 == iidDelNew );
  514. #if CIDBG == 1
  515. CIndexId iid( recNewMaster.Iid() );
  516. Win4Assert( iid.PartId() == partid );
  517. #endif // CIDBG == 1
  518. AddRecord( indFile, recNewMaster.Iid(), itNewMaster,
  519. recNewMaster.MaxWorkId(), recNewMaster.ObjectId() );
  520. AddRecord( indFile, CIndexId( 0, partid ), itMMLog, 0,widMMLog );
  521. AddRecord( indFile, CIndexId( 0, partidKeyList ), itMMKeyList, 0, widMMKeyList );
  522. DeleteRecord( indFile, iidDelOld );
  523. AddRecord( indFile, iidDelNew, itDeleted, 0, 0 );
  524. indFile.Commit();
  525. }
  526. inline BOOL IsMatched( const CIndexRecord & rec,
  527. INDEXID iid, IndexType it, WORKID wid )
  528. {
  529. return rec.Type() == (ULONG) it && rec.Iid() == iid && rec.ObjectId() == wid ;
  530. }
  531. //+---------------------------------------------------------------------------
  532. //
  533. // Function: DeleteObject
  534. //
  535. // Synopsis: Deletes the record for the specified object by marking
  536. // it as "iidInvalid". The record will be deleted only
  537. // if there is an exact match with the partid, it and wid.
  538. //
  539. // Arguments: [partid] -- Partition Id.
  540. // [it] -- Index type of the object.
  541. // [wid] -- Work Id to match on.
  542. //
  543. // History: 2-18-94 srikants Created
  544. //
  545. // Notes:
  546. //
  547. //----------------------------------------------------------------------------
  548. void CIndexTable::DeleteObject( PARTITIONID partid, IndexType it, WORKID wid )
  549. {
  550. CWriteIndexFile indFile( GetIndexTableObj() );
  551. DeleteObject( indFile, partid, it, wid );
  552. indFile.Commit();
  553. }
  554. void CIndexTable::DeleteObject( CWriteIndexFile & indFile,
  555. PARTITIONID partid, IndexType it, WORKID wid )
  556. {
  557. CIndexRecord rec;
  558. BOOL found;
  559. indFile.Rewind();
  560. do
  561. {
  562. found = indFile.ReadRecord ( &rec );
  563. }
  564. while ( found && !IsMatched( rec, CIndexId(0, partid), it, wid) );
  565. if ( found ) {
  566. indFile.BackUp();
  567. rec._iid = (INDEXID) CIndexId(iidInvalid, partidInvalid);
  568. rec._objectId = widInvalid;
  569. indFile.WriteRecord( &rec );
  570. }
  571. }
  572. //+---------------------------------------------------------------------------
  573. //
  574. // Member: CIndexTable::AddRecord, private
  575. //
  576. // Synopsis: Adds new record to table
  577. //
  578. // Arguments: [iid] -- index id
  579. // [type] -- type of record
  580. // [maxWorkId] -- max work id in the index
  581. // [objectId] -- id of the index object
  582. //
  583. // Notes: ResMan LOCKED
  584. //
  585. // History: 02-May-91 BartoszM Created.
  586. //
  587. //----------------------------------------------------------------------------
  588. void CIndexTable::AddRecord( CWriteIndexFile & indFile,
  589. INDEXID iid,
  590. ULONG type,
  591. WORKID maxWorkId,
  592. WORKID objectId )
  593. {
  594. ciDebugOut (( DEB_ITRACE, "Indexes: AddRecord %lx, %ld %s\n",
  595. iid, maxWorkId, (type == itMaster)? "master": "not-master" ));
  596. CAddReplaceIndexRecord rec(indFile, CIndexId(iidInvalid,partidInvalid) );
  597. rec.SetIid(iid);
  598. rec.SetType(type);
  599. rec.SetWid(maxWorkId);
  600. rec.SetObjectId ( objectId );
  601. rec.WriteRecord();
  602. }
  603. //+---------------------------------------------------------------------------
  604. //
  605. // Member: CIndexTable::AddIndex, public
  606. //
  607. // Synopsis: Adds new index to table
  608. //
  609. // Arguments: [iid] -- index id
  610. // [type] -- type of record
  611. // [maxWorkId] -- max work id in the index
  612. // [objectId] -- id of the index object
  613. //
  614. // Notes: ResMan LOCKED
  615. //
  616. // History: 14-Jul-94 DwightKr Created.
  617. //
  618. //----------------------------------------------------------------------------
  619. void CIndexTable::AddIndex( INDEXID iid,
  620. IndexType type,
  621. WORKID maxWorkId,
  622. WORKID objectId )
  623. {
  624. CWriteIndexFile indFile( GetIndexTableObj() );
  625. AddRecord( indFile, iid, type, maxWorkId, objectId );
  626. indFile.Commit();
  627. }
  628. //+---------------------------------------------------------------------------
  629. //
  630. // Member: CIndexTable::LokEmpty, public
  631. //
  632. // Synopsis: Deleted everything from the index table
  633. //
  634. // Notes: ResMan LOCKED
  635. //
  636. // History: 16-Aug-94 DwightKr Created
  637. //
  638. //----------------------------------------------------------------------------
  639. void CIndexTable::LokEmpty()
  640. {
  641. PRcovStorageObj & rcovObj = GetIndexTableObj();
  642. CRcovStrmWriteTrans xact( rcovObj );
  643. rcovObj.GetHeader().SetCount( rcovObj.GetHeader().GetBackup(), 0 );
  644. xact.Empty();
  645. xact.Seek(0);
  646. xact.Commit();
  647. }
  648. //+---------------------------------------------------------------------------
  649. //
  650. // Member: CIndexTable::LokMakeBackupCopy
  651. //
  652. // Synopsis: Makes a backup copy of the index table.
  653. //
  654. // Arguments: [storage] - Storage to use for creation of the
  655. // destination index table.
  656. // [fFullSave] - Set to TRUE if a full save is being performed.
  657. // [progressTracker] - Progress tracker.
  658. //
  659. // History: 3-18-97 srikants Created
  660. //
  661. //----------------------------------------------------------------------------
  662. void CIndexTable::LokMakeBackupCopy( PStorage & storage,
  663. BOOL fFullSave,
  664. PSaveProgressTracker & progressTracker )
  665. {
  666. //
  667. // Create a new index table object using the storage provided.
  668. //
  669. PRcovStorageObj * pDstObj = storage.QueryIdxTableObject();
  670. XPtr<PRcovStorageObj> xDstObj( pDstObj );
  671. PRcovStorageObj & srcObj = GetIndexTableObj();
  672. //
  673. // Copy the contents of source to destination.
  674. //
  675. CCopyRcovObject copier( *pDstObj, srcObj );
  676. NTSTATUS status = copier.DoIt();
  677. if ( STATUS_SUCCESS != status )
  678. {
  679. THROW(CException(status) );
  680. }
  681. //
  682. // Set the Full/Partial Save bit appropriately.
  683. //
  684. CRcovStrmAppendTrans xact( *pDstObj );
  685. CRcovStorageHdr & storageHdr = pDstObj->GetHeader();
  686. CRcovUserHdr usrHdr;
  687. CIndexTableUsrHdr * pIdxUsrHdr = (CIndexTableUsrHdr *) &usrHdr;
  688. storageHdr.GetUserHdr( storageHdr.GetBackup(), usrHdr );
  689. if ( fFullSave )
  690. pIdxUsrHdr->SetFullSave();
  691. else pIdxUsrHdr->ClearFullSave();
  692. storageHdr.SetUserHdr( storageHdr.GetBackup(), usrHdr );
  693. xact.Commit();
  694. }
  695. //+---------------------------------------------------------------------------
  696. //
  697. // Member: CIndexTable::GetUserHdrInfo
  698. //
  699. // Synopsis: Retrieves the information in the user header.
  700. //
  701. // Arguments: [mMergeSeqNum] - Master Merge sequence number.
  702. // [fFullSave] - Set to TRUE if a full save was performed.
  703. //
  704. // History: 3-21-97 srikants Created
  705. //
  706. //----------------------------------------------------------------------------
  707. void CIndexTable::GetUserHdrInfo( unsigned & mMergeSeqNum, BOOL & fFullSave )
  708. {
  709. PRcovStorageObj & obj = GetIndexTableObj();
  710. CRcovUserHdr usrHdr;
  711. CIndexTableUsrHdr * pIdxUsrHdr = (CIndexTableUsrHdr *) &usrHdr;
  712. CRcovStorageHdr & storageHdr = obj.GetHeader();
  713. storageHdr.GetUserHdr( storageHdr.GetPrimary(), usrHdr );
  714. ciDebugOut(( DEB_ERROR, "Current MMerge Seq Num = %d \n",
  715. pIdxUsrHdr->GetMMergeSeqNum() ));
  716. mMergeSeqNum = pIdxUsrHdr->GetMMergeSeqNum();
  717. fFullSave = pIdxUsrHdr->IsFullSave();
  718. }