windows-nt/Source/XPSP1/NT/inetsrv/query/cindex/changes.cxx
2020-09-26 16:20:57 +08:00

342 lines
9.4 KiB
C++

//+---------------------------------------------------------------------------
//
// 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 <pch.cxx>
#pragma hdrstop
#include <glbconst.hxx>
#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;
}