windows-nt/Source/XPSP1/NT/inetsrv/query/cindex/fretest.hxx

263 lines
6.6 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 1998.
//
// File: FRETEST.HXX
//
// Contents: Fresh test object
//
// Classes: CFreshTest
//
// History: 01-Oct-91 BartoszM Created.
//
//----------------------------------------------------------------------------
#pragma once
#include <fretable.hxx>
class CWidArray;
class CDocList;
//+---------------------------------------------------------------------------
//
// Class: CFreshTest
//
// Purpose: Tests the freshness of the index id <-> work id association
//
// History: 16-May-91 BartoszM Created.
//
//----------------------------------------------------------------------------
class CFreshTest
{
public:
CFreshTest ( unsigned size );
CFreshTest ( CFreshTest& source, CWidArray& widTable );
CFreshTest ( CFreshTest& source, CIdxSubstitution& subst);
CFreshTest( CFreshTest& source );
unsigned Count() { return _freshTable.Count(); }
unsigned DeleteCount() { return _cDeletes; }
void DecrementDeleteCount( unsigned cDeletes )
{
_cDeletes -= cDeletes;
}
void Add ( WORKID wid, INDEXID iid )
{
_freshTable.Add ( wid, iid );
}
void AddReplace ( WORKID wid, INDEXID iid )
{
_freshTable.AddReplace ( wid, iid );
}
void AddReplaceDelete ( WORKID wid, INDEXID iidDeleted )
{
//
// NOTE: _cDeletes can be artificially high, if we get double-deletions
// but this doesn't really hurt, just possibly leads to an extra
// delete merge occasionally. So why waste the time filtering
// out the double-deletes?
//
INDEXID iidOld = _freshTable.AddReplace ( wid, iidDeleted );
if ( iidOld != iidDeleted1 && iidOld != iidDeleted2 )
_cDeletes++;
}
void ModificationsComplete() { _freshTable.ModificationsComplete(); }
enum IndexSource
{
Invalid,
Unknown,
Master,
Shadow
};
IndexSource IsCorrectIndex( INDEXID iid, WORKID wid );
BOOL InUse() { return _refCount != 0; }
void Reference() { _refCount++; }
ULONG Dereference() { return --_refCount; }
CFreshTable * GetFreshTable() { Reference(); return &_freshTable; }
void ReleaseFreshTable(CFreshTable *p) { if (p != 0) Dereference(); }
INDEXID Find ( WORKID wid );
#ifdef CIEXTMODE
void CiExtDump(void *ciExtSelf);
#endif
private:
ULONG RefCount() { return _refCount; } // for debugging only
void PatchEntry ( CFreshItem* pEntry, INDEXID iid );
ULONG _refCount;
CFreshTable _freshTable;
unsigned _cDeletes;
};
//+-------------------------------------------------------------------------
//
// Class: CFreshTestLock
//
// Synopsis: A lock smart pointer on a CFreshTest object.
// Note that the destructor only de-references the fresh test
// It does NOT destroy the fresh test.
//
// History: 94-Mar-31 DwightKr Created
//
//--------------------------------------------------------------------------
class CFreshTestLock
{
public:
inline CFreshTestLock( CFreshTest * );
inline CFreshTestLock();
inline ~CFreshTestLock();
inline CFreshTest * operator->() { return _pFreshTest; }
inline CFreshTest & operator*() { return *_pFreshTest; }
private:
CFreshTest * _pFreshTest;
};
//+-------------------------------------------------------------------------
//
// Class: SFreshTable
//
// Synopsis: A smart pointer to a CFreshTable object
//
// History: 94-Jan-19 DwightKr Created
//
//--------------------------------------------------------------------------
class SFreshTable
{
public:
inline SFreshTable( CFreshTest & );
inline ~SFreshTable();
inline CFreshTable * operator->() { return _pFreshTable; }
inline CFreshTable & operator*() { return *_pFreshTable; }
private:
CFreshTable * _pFreshTable;
CFreshTest & _freshTest;
};
//+---------------------------------------------------------------------------
//
// Member: CFreshTest::PatchEntry, private
//
// Synopsis: During recovery, if the wordlist
// has not been recreated yet, patch the entry
//
// Arguments: [fresh] -- fresh table
//
// History: 08-Oct-91 BartoszM Created.
//
// Notes: The assumption is that the operation is atomic.
// If there is a race to patch, the last query
// wins, but it doesn't really matter.
//
//----------------------------------------------------------------------------
inline void CFreshTest::PatchEntry ( CFreshItem* pEntry, INDEXID iid )
{
ciDebugOut (( DEB_ITRACE, "FreshTest: patching entry %ld\n", iid ));
pEntry->SetIndexId ( iid );
}
//+---------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline INDEXID CFreshTest::Find ( WORKID wid )
{
INDEXID iid = iidInvalid; // Assume it's in the master index
Reference();
CFreshItem *freshEntry = _freshTable.Find( wid );
if (0 != freshEntry)
{
iid = freshEntry->IndexId();
}
Dereference();
return iid;
}
//+---------------------------------------------------------------------------
//
// Member: CFreshTestLock::CFreshTestLock, public
//
// Synopsis: Constructor.
//
// Arguments: [frestTest] -- freshTest to encapsulate
//
// History: 94-Mar-31 DwightKr Created.
//
//----------------------------------------------------------------------------
CFreshTestLock::CFreshTestLock( CFreshTest * pFreshTest) : _pFreshTest(pFreshTest)
{
}
CFreshTestLock::CFreshTestLock()
: _pFreshTest( 0 )
{
}
CFreshTestLock::~CFreshTestLock()
{
if ( _pFreshTest )
_pFreshTest->Dereference();
}
//+---------------------------------------------------------------------------
//
// Member: SFreshTable::SFreshTable, public
//
// Synopsis: Constructor.
//
// Arguments: [frestTest] -- freshTest which owns the freshTable
//
// History: 94-Jan-19 DwightKr Created.
//
//----------------------------------------------------------------------------
SFreshTable::SFreshTable( CFreshTest & freshTest) : _freshTest(freshTest),
_pFreshTable(0)
{
_pFreshTable = _freshTest.GetFreshTable();
}
SFreshTable::~SFreshTable()
{
_freshTest.ReleaseFreshTable(_pFreshTable);
}