//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1991 - 2000. // // File: CHANGES.CXX // // Contents: Table of changes // // Classes: CChange CPartQueue // // History: 29-Mar-91 BartoszM Created // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include "indxact.hxx" #include "changes.hxx" #define CI_PRIORITY_INVALID CI_PRIORITIES //+--------------------------------------------------------------------------- // // Member: CChange::CChange, public // // Arguments: [storage] -- physical storage // // History: 29-Mar-91 BartoszM Created // //---------------------------------------------------------------------------- CChange::CChange ( WORKID wid, PStorage& storage, CCiFrameworkParams & frmwrkParams ) : _frmwrkParams( frmwrkParams ), _queue( wid, storage, PStorage::ePrimChangeLog, frmwrkParams ), _secQueue( wid, storage, PStorage::eSecChangeLog, frmwrkParams ) { Win4Assert( sizeof(FILETIME) == sizeof(LONGLONG) ); GetSystemTimeAsFileTime( (FILETIME *) &_ftLast ); } //+--------------------------------------------------------------------------- // // Member: CChange::LokEmpty, public // // Synopsis: Initializes changes object so it looks new/empty // // Notes: ResMan LOCKED // // History: 15-Nov-94 DwightKr Created // //---------------------------------------------------------------------------- void CChange::LokEmpty() { _queue.LokEmpty(); _secQueue.LokEmpty(); } //+--------------------------------------------------------------------------- // // Member: CChange::LokCompact, public // // Synopsis: Frees memory not currently in use. // // Notes: ResMan LOCKED // // History: 19-May-92 BartoszM Created // //---------------------------------------------------------------------------- void CChange::LokCompact() { } //+--------------------------------------------------------------------------- // // Member: CChange::LokGetPendingUpdates // // Synopsis: Like QueryPendingUpdates, but doesn't remove documents from // queue, and doesn't require a transaction (no deserialization). // // Arguments: [aWid] -- Workids returned here. // [cWid] -- INPUT: Maximum number of entries to fetch. // OUTPUT: Number of entries fetched. // // Returns: TRUE if all change entries were processed. // // History: 15-Nov-94 KyleP Created // // Notes: ResMan LOCKED // //---------------------------------------------------------------------------- BOOL CChange::LokGetPendingUpdates( WORKID * aWid, unsigned & cWid ) { if ( _queue.IsEmpty() && _secQueue.IsEmpty() ) { cWid = 0; return TRUE; } else { const unsigned cMax = cWid; unsigned cPrim = 0; // count of wids from primary unsigned cSec = 0; // count of wids from secondary BOOL fSuccess = TRUE; if ( !_queue.IsEmpty() ) { cPrim = cMax; fSuccess = _queue.Get(aWid, cPrim); } if ( fSuccess && !_secQueue.IsEmpty() ) { Win4Assert( cPrim <= cMax ); cSec = cMax-cPrim; fSuccess = _secQueue.Get( aWid+cPrim, cSec ); } Win4Assert( cPrim + cSec <= cMax ); cWid = cPrim+cSec; return fSuccess; } } //+--------------------------------------------------------------------------- // // Member: CChange::LokQueryPendingUpdates // // Synopsis: Checks update queues, returns list of documents // // Arguments: [xact] -- transaction // [maxDocs] -- maximum # of updates acceptable // [docList] -- (returned) list of documents, // initially empty. // // Returns: An array of document descriptors (or NULL) // // History: 25-Sept-91 BartoszM Created // // Notes: ResMan LOCKED // //---------------------------------------------------------------------------- void CChange::LokQueryPendingUpdates ( CChangeTrans & xact, unsigned maxDocs, CDocList& docList ) { ciDebugOut (( DEB_ITRACE, "Query Pending Updates\n" )); if ( !_queue.IsEmpty() ) { _queue.Extract( xact, maxDocs, docList ); } else { docList.LokSetCount(0); return; } } //+--------------------------------------------------------------------------- // // Member: CChange::LokDone, public // // Synopsis: After creating a volatile index marks // entries in table done. Stores actual index id. // // Arguments: [xact] -- transaction // [iid] -- index id // [docList] -- array of document descriptors // // History: 26-Apr-91 BartoszM Created // // Notes: ResMan LOCKED // //---------------------------------------------------------------------------- void CChange::LokDone ( CChangeTrans & xact, INDEXID iid, CDocList& docList ) { ciDebugOut (( DEB_ITRACE, "Changes: Done\n" )); int cDoc = docList.Count(); // // Look for PENDING or PREEMPTED documents, which must be reindexed. // for ( int i = 0; i < cDoc; i++ ) { STATUS status = docList.Status(i); if ( status == PREEMPTED || status == PENDING ) { _queue.Append( xact, docList.Wid(i), docList.Usn(i), docList.VolumeId(i), CI_UPDATE_OBJ, docList.Retries(i), docList.SecQRetries(i) ); } } } //+--------------------------------------------------------------------------- // // Member: CChange::LokRemoveIndexes, public // // Synopsis: Remove entries from the table after volatile indexes // have been merged away. // // Arguments: [cIndexes] -- count of index ids // [aIndexIds] -- array of index ids // // History: 26-Apr-91 BartoszM Created // 14-May-91 BartoszM Implemented // // Notes: ResMan LOCKED // //---------------------------------------------------------------------------- void CChange::LokRemoveIndexes ( CTransaction& xact, unsigned cIndexes, INDEXID aIndexIds[] ) { ciDebugOut (( DEB_ITRACE, "Changes: Remove Indexes\n" )); } //+--------------------------------------------------------------------------- // // Member: CChange::LokAddToSecQueue // // Synopsis: Adds the document to the secondary change queue. // // Arguments: [xact] -- Change transaction // [wid] -- Workid // [volumeId] -- Volume id // [cSecQRetries] -- Sec Q Retry Count // // History: 5-08-96 srikants Created // //---------------------------------------------------------------------------- void CChange::LokAddToSecQueue( CChangeTrans & xact, WORKID wid, VOLUMEID volumeId, ULONG cSecQRetries ) { USN usn = 0; ULONG action = CI_UPDATE_OBJ; ciDebugOut(( DEB_TRACE, "Refiling wid %d (0x%X) to secondary queue\n", wid, wid )); SCODE sc = _secQueue.Append( xact, wid, usn, volumeId, action, 1, // retries (reset for sharing viol) cSecQRetries ); if ( S_OK != sc ) { ciDebugOut(( DEB_ERROR, "LokAddToSecQueue returned 0x%X\n", sc )); } } //+--------------------------------------------------------------------------- // // Member: CChange::LokRefileSecQueue // // Synopsis: Moves items from seconday queue to primary queue // // Arguments: [xact] - Change transaction // // History: 5-08-96 srikants Created // //---------------------------------------------------------------------------- void CChange::LokRefileSecQueue( CChangeTrans & xact ) { // convert the retry interval from minutes into 100s of nano seconds const LONGLONG eXferInterval = _frmwrkParams.GetFilterRetryInterval() * 60 * 1000 * 10000; LONGLONG ftNow; GetSystemTimeAsFileTime( (FILETIME *) &ftNow ); LONGLONG llDelta = ftNow - _ftLast; if ( llDelta > 0 && !_secQueue.IsEmpty() ) { if ( llDelta < eXferInterval ) return; CDocList docList; while ( !_secQueue.IsEmpty() ) { docList.LokClear(); _secQueue.Extract( xact, CI_MAX_DOCS_IN_WORDLIST, docList ); for ( unsigned i = 0; i < docList.Count(); i++ ) { ciDebugOut(( DEB_TRACE, "Transferring wid %d (0x%X) from secondary to primary queue\n", docList.Wid(i), docList.Wid(i) )); _queue.Append ( xact, docList.Wid(i), docList.Usn(i), docList.VolumeId(i), CI_UPDATE_OBJ, docList.Retries(i), docList.SecQRetries(i) ); } } _secQueue.LokEmpty(); } _ftLast = ftNow; }