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.
 
 
 
 
 
 

306 lines
7.8 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2000.
//
// File: Strategy.hxx
//
// Contents: Encapsulates strategy for choosing indexes
//
// History: 03-Nov-94 KyleP Created.
//
//----------------------------------------------------------------------------
#pragma once
class CRange
{
public:
inline CRange( PROPID pid );
void SetPid( PROPID pid ) { _pid = pid; }
void SetLowerBound( CStorageVariant const & var )
{
_varLower = var;
if ( !_varLower.IsValid() )
THROW( CException( E_OUTOFMEMORY ) );
}
void SetUpperBound( CStorageVariant const & var )
{
_varUpper = var;
if ( !_varUpper.IsValid() )
THROW( CException( E_OUTOFMEMORY ) );
}
PROPID Pid() const { return _pid; }
CStorageVariant const & LowerBound() const { return _varLower; }
CStorageVariant const & UpperBound() const { return _varUpper; }
BOOL IsValid() { return _fValid; }
void MarkInvalid() { _fValid = FALSE; }
private:
BOOL _fValid;
PROPID _pid;
CStorageVariant _varLower;
CStorageVariant _varUpper;
};
inline CRange::CRange( PROPID pid )
: _fValid( TRUE ),
_pid( pid )
{
}
//+---------------------------------------------------------------------------
//
// Class: CIndexStrategy
//
// Purpose: Helper class for choosing index strategy. Tracks bounds of
// properties used in restrictions.
//
// History: 18-Sep-95 KyleP Added header.
//
//----------------------------------------------------------------------------
class CIndexStrategy
{
public:
CIndexStrategy();
~CIndexStrategy();
//
// Information input
//
void SetBounds( PROPID pid,
CStorageVariant const & varLower,
CStorageVariant const & varUpper );
void SetLowerBound( PROPID pid, CStorageVariant const & varLower );
void SetUpperBound( PROPID pid, CStorageVariant const & varUpper );
inline void SetLowerBound( PROPID pid, CStorageVariant const & varLower, BOOL fSecondBound );
inline void SetUpperBound( PROPID pid, CStorageVariant const & varUpper, BOOL fSecondBound );
void SetUnknownBounds( PROPID pid = pidInvalid );
void SetContentHelper( CRestriction * pcrst );
inline BOOL SetOrMode();
inline BOOL SetAndMode();
inline void DoneWithBoolean();
//
// Information output
//
CStorageVariant const & LowerBound( PROPID pid ) const;
CStorageVariant const & UpperBound( PROPID pid ) const;
CRestriction * QueryContentRestriction( BOOL fPropertyOnly = FALSE );
BOOL CanUse( PROPID pid, BOOL fAscending ) const;
BOOL GetUsnRange( USN & usnMin, USN & usnMax ) const;
private:
unsigned FindPid( PROPID pid );
enum
{
NoMode,
AndMode,
OrMode,
InvalidMode
} _BooleanMode;
unsigned _cNodes;
unsigned _depth; // Depth below OR (started with AND) or below AND (started with OR)
unsigned _cBounds;
CDynArray<CRange> _aBounds;
CDynStack<CRestriction> _stkContentHelpers;
unsigned _iRangeUsn; // Index of USN range. 0xFFFFFFFF if invalid
};
unsigned const InvalidUsnRange = 0xFFFFFFFF;
//+---------------------------------------------------------------------------
//
// Member: CIndexStrategy::SetOrMode
//
// Synopsis: Indicates an OR node is being processed.
//
// History: 10-Oct-95 KyleP Created.
//
// Notes: The depth is incremented only if a mode switch (AND --> OR)
// occurred. We can handle OR with OR below, and AND with AND
// below.
//
//----------------------------------------------------------------------------
inline BOOL CIndexStrategy::SetOrMode()
{
switch( _BooleanMode )
{
case NoMode:
Win4Assert( 0 == _depth );
break;
case AndMode:
break;
case OrMode:
return FALSE;
default:
Win4Assert( !"Invalid mode" );
}
_BooleanMode = OrMode;
_depth++;
return TRUE;
}
//+---------------------------------------------------------------------------
//
// Member: CIndexStrategy::SetAndMode
//
// Synopsis: Indicates an AND node is being processed.
//
// History: 10-Oct-95 KyleP Created.
//
// Notes: The depth is incremented only if a mode switch (OR --> AND)
// occurred. We can handle OR with OR below, and AND with AND
// below.
//
//----------------------------------------------------------------------------
inline BOOL CIndexStrategy::SetAndMode()
{
switch( _BooleanMode )
{
case NoMode:
Win4Assert( 0 == _depth );
break;
case OrMode:
break;
case AndMode:
return FALSE;
default:
Win4Assert( !"Invalid mode" );
}
_BooleanMode = AndMode;
_depth++;
return TRUE;
}
//+---------------------------------------------------------------------------
//
// Member: CIndexStrategy::DoneWithBoolean
//
// Synopsis: Indicates end of processing for a boolean node.
//
// History: 10-Oct-95 KyleP Created.
//
// Notes: The depth is only decremented if we're tracking depth, which
// happens when we've switched boolean modes.
//
//----------------------------------------------------------------------------
inline void CIndexStrategy::DoneWithBoolean()
{
switch( _depth )
{
case 0:
Win4Assert( !"See CNodeXpr::SelectIndexing. This is not possible" );
return;
case 1:
break;
default:
switch( _BooleanMode )
{
case AndMode:
_BooleanMode = OrMode;
break;
case OrMode:
_BooleanMode = AndMode;
break;
default:
Win4Assert( !"Unrecognized mode");
break;
}
break;
}
_depth --;
}
//+---------------------------------------------------------------------------
//
// Member: CIndexStrategy::SetLowerBound
//
// Synopsis: Set lower bound.
//
// Effects: Same as the other form of SetLowerBound, except this doesn't
// count as the one allowed Set* for a single node. Used for
// bookkeeping.
//
// Arguments: [pid] -- Property Id
// [varLower] -- Lower bound
// [fSecondBound] -- TRUE if this is the second of a pair.
//
// History: 10-Oct-95 KyleP Created.
//
//----------------------------------------------------------------------------
inline void CIndexStrategy::SetLowerBound( PROPID pid,
CStorageVariant const & varLower,
BOOL fSecondBound )
{
SetLowerBound( pid, varLower );
if ( fSecondBound )
_cNodes--;
}
//+---------------------------------------------------------------------------
//
// Member: CIndexStrategy::SetUpperBound
//
// Synopsis: Set upper bound.
//
// Effects: Same as the other form of SetUpperBound, except this doesn't
// count as the one allowed Set* for a single node. Used for
// bookkeeping.
//
// Arguments: [pid] -- Property Id
// [varUpper] -- Upper bound
// [fSecondBound] -- TRUE if this is the second of a pair.
//
// History: 10-Oct-95 KyleP Created.
//
//----------------------------------------------------------------------------
inline void CIndexStrategy::SetUpperBound( PROPID pid,
CStorageVariant const & varUpper,
BOOL fSecondBound )
{
SetUpperBound( pid, varUpper );
if ( fSecondBound )
_cNodes--;
}