2025-04-27 07:49:33 -04:00

1407 lines
26 KiB
C++

// (C) 1999 Microsoft Corporation
#ifndef __DNF_TREE_H
#define __DNF_TREE_H
class WmiOrNode : public WmiTreeNode
{
private:
protected:
public:
WmiOrNode (
WmiTreeNode *a_Left = NULL ,
WmiTreeNode *a_Right = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiTreeNode ( NULL , a_Left , a_Right , a_Parent ) {}
~WmiOrNode () ;
WmiTreeNode *Copy () ;
void Print () ;
} ;
class WmiAndNode : public WmiTreeNode
{
private:
protected:
public:
WmiAndNode (
WmiTreeNode *a_Left = NULL ,
WmiTreeNode *a_Right = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiTreeNode ( NULL , a_Left , a_Right , a_Parent ) {}
~WmiAndNode () ;
WmiTreeNode *Copy () ;
void Print () ;
} ;
class WmiNotNode : public WmiTreeNode
{
private:
protected:
public:
WmiNotNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiTreeNode ( NULL , a_Node , NULL , a_Parent ) {}
~WmiNotNode () ;
WmiTreeNode *Copy () ;
void Print () ;
} ;
class WmiRangeNode ;
class WmiOperatorNode : public WmiTreeNode
{
private:
protected:
public:
WmiOperatorNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiTreeNode ( NULL , a_Node , NULL , a_Parent ) {}
~WmiOperatorNode () {} ;
virtual WmiRangeNode *GetRange () = 0 ;
} ;
class WmiOperatorEqualNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorEqualNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorEqualNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () ;
void Print () ;
} ;
class WmiOperatorNotEqualNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorNotEqualNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorNotEqualNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () { return NULL ; }
void Print () ;
} ;
class WmiOperatorEqualOrGreaterNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorEqualOrGreaterNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorEqualOrGreaterNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () ;
void Print () ;
} ;
class WmiOperatorEqualOrLessNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorEqualOrLessNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorEqualOrLessNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () ;
void Print () ;
} ;
class WmiOperatorGreaterNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorGreaterNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorGreaterNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () ;
void Print () ;
} ;
class WmiOperatorLessNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorLessNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorLessNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () ;
void Print () ;
} ;
class WmiOperatorLikeNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorLikeNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorLikeNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () ;
void Print () ;
} ;
class WmiOperatorNotLikeNode : public WmiOperatorNode
{
private:
protected:
public:
WmiOperatorNotLikeNode (
WmiTreeNode *a_Node = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiOperatorNode ( a_Node , a_Parent ) {}
~WmiOperatorNotLikeNode () ;
WmiTreeNode *Copy () ;
WmiRangeNode *GetRange () ;
void Print () ;
} ;
class WmiValueNode : public WmiTreeNode
{
public:
enum WmiValueFunction
{
Function_None = SQL_LEVEL_1_TOKEN :: IFUNC_NONE ,
Function_Upper = SQL_LEVEL_1_TOKEN :: IFUNC_UPPER ,
Function_Lower = SQL_LEVEL_1_TOKEN :: IFUNC_LOWER
} ;
private:
protected:
BSTR m_PropertyName ;
ULONG m_Index ;
WmiValueFunction m_PropertyFunction ;
WmiValueFunction m_ConstantFunction ;
public:
WmiValueNode (
BSTR a_PropertyName ,
WmiValueFunction a_PropertyFunction ,
WmiValueFunction a_ConstantFunction ,
ULONG a_Index ,
WmiTreeNode *a_Parent = NULL
) : WmiTreeNode ( NULL , NULL , NULL , a_Parent ) ,
m_PropertyFunction ( a_PropertyFunction ) ,
m_ConstantFunction ( a_ConstantFunction ) ,
m_Index ( a_Index )
{
if ( a_PropertyName )
{
m_PropertyName = SysAllocString ( a_PropertyName ) ;
if ( m_PropertyName == NULL )
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
}
else
{
m_PropertyName = NULL ;
}
}
~WmiValueNode ()
{
if ( m_PropertyName )
SysFreeString ( m_PropertyName ) ;
}
BSTR GetPropertyName ()
{
return m_PropertyName ;
}
ULONG GetIndex () { return m_Index ; }
WmiValueNode :: WmiValueFunction GetPropertyFunction ()
{
return m_PropertyFunction ;
}
WmiValueNode :: WmiValueFunction GetConstantFunction ()
{
return m_ConstantFunction ;
}
LONG ComparePropertyName ( WmiValueNode &a_ValueNode )
{
if ( m_Index < a_ValueNode.m_Index )
{
return -1 ;
}
else if ( m_Index > a_ValueNode.m_Index )
{
return 1 ;
}
else
{
return _wcsicmp ( m_PropertyName , a_ValueNode.m_PropertyName ) ;
}
}
} ;
class WmiSignedIntegerNode : public WmiValueNode
{
private:
protected:
LONG m_Integer ;
public:
WmiSignedIntegerNode (
BSTR a_PropertyName ,
LONG a_Integer ,
ULONG a_Index ,
WmiTreeNode *a_Parent = NULL
) : WmiValueNode (
a_PropertyName ,
Function_None ,
Function_None ,
a_Index ,
a_Parent
) , m_Integer ( a_Integer )
{
}
WmiTreeNode *Copy () ;
BOOL LexicographicallyBefore ( LONG &a_Integer )
{
if ( m_Integer == 0x80000000 )
return FALSE ;
else
{
a_Integer = m_Integer - 1 ;
return TRUE ;
}
}
BOOL LexicographicallyAfter ( LONG &a_Integer )
{
if ( m_Integer == 0x7FFFFFFF )
return FALSE ;
else
{
a_Integer = m_Integer + 1 ;
return TRUE ;
}
}
LONG GetValue ()
{
return m_Integer ;
}
void Print () ;
} ;
class WmiUnsignedIntegerNode : public WmiValueNode
{
private:
protected:
ULONG m_Integer ;
public:
WmiUnsignedIntegerNode (
BSTR a_PropertyName ,
ULONG a_Integer ,
ULONG a_Index ,
WmiTreeNode *a_Parent = NULL
) : WmiValueNode (
a_PropertyName ,
Function_None ,
Function_None ,
a_Index ,
a_Parent
) , m_Integer ( a_Integer )
{
}
WmiTreeNode *Copy () ;
BOOL LexicographicallyBefore ( ULONG &a_Integer )
{
if ( m_Integer == 0 )
return FALSE ;
else
{
a_Integer = m_Integer - 1 ;
return TRUE ;
}
}
BOOL LexicographicallyAfter ( ULONG &a_Integer )
{
if ( m_Integer == 0xFFFFFFFF )
return FALSE ;
else
{
a_Integer = m_Integer + 1 ;
return TRUE ;
}
}
ULONG GetValue ()
{
return m_Integer ;
}
void Print () ;
} ;
class WmiStringNode : public WmiValueNode
{
private:
protected:
BSTR m_String ;
public:
WmiStringNode (
BSTR a_PropertyName ,
BSTR a_String ,
WmiValueNode :: WmiValueFunction a_PropertyFunction ,
WmiValueNode :: WmiValueFunction a_ConstantFunction ,
ULONG a_Index ,
WmiTreeNode *a_Parent = NULL
) : WmiValueNode (
a_PropertyName ,
a_PropertyFunction ,
Function_None ,
a_Index ,
a_Parent
)
{
if ( a_String )
{
if ( a_ConstantFunction == Function_Upper )
{
ULONG t_StringLength = wcslen ( a_String ) ;
wchar_t *t_String = new wchar_t [ t_StringLength + 1 ] ;
for ( ULONG t_Index = 0 ; t_Index < t_StringLength ; t_Index ++ )
{
t_String [ t_Index ] = tolower ( a_String [ t_Index ] ) ;
}
m_String = SysAllocString ( t_String ) ;
delete [] t_String ;
}
else if ( a_ConstantFunction == Function_Upper )
{
ULONG t_StringLength = wcslen ( a_String ) ;
wchar_t *t_String = new wchar_t [ t_StringLength + 1 ] ;
for ( ULONG t_Index = 0 ; t_Index < t_StringLength ; t_Index ++ )
{
t_String [ t_Index ] = toupper ( a_String [ t_Index ] ) ;
}
m_String = SysAllocString ( t_String ) ;
delete [] t_String ;
}
else
{
m_String = SysAllocString ( a_String ) ;
}
if ( m_String == NULL )
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
}
else
m_String = NULL ;
}
~WmiStringNode ()
{
if ( m_String )
SysFreeString ( m_String ) ;
} ;
WmiTreeNode *Copy () ;
BOOL LexicographicallyBefore ( BSTR &a_String )
{
if ( wcscmp ( L"" , m_String ) == 0 )
return FALSE ;
else
{
ULONG t_StringLen = wcslen ( m_String ) ;
wchar_t *t_String = NULL ;
if ( m_String [ t_StringLen - 1 ] == 0x01 )
{
t_String = new wchar_t [ t_StringLen ] ;
wcsncpy ( t_String , m_String , t_StringLen - 1 ) ;
t_String [ t_StringLen ] = 0 ;
}
else
{
t_String = new wchar_t [ t_StringLen + 1 ] ;
wcscpy ( t_String , m_String ) ;
t_String [ t_StringLen - 1 ] = t_String [ t_StringLen - 1 ] - 1 ;
}
a_String = SysAllocString ( t_String ) ;
delete [] t_String ;
return TRUE ;
}
}
BOOL LexicographicallyAfter ( BSTR &a_String )
{
ULONG t_StringLen = wcslen ( m_String ) ;
wchar_t *t_String = new wchar_t [ t_StringLen + 2 ] ;
wcscpy ( t_String , m_String ) ;
t_String [ t_StringLen ] = 0x01 ;
t_String [ t_StringLen ] = 0x00 ;
a_String = SysAllocString ( t_String ) ;
delete [] t_String ;
return TRUE ;
}
BSTR GetValue ()
{
return m_String ;
}
void Print () ;
} ;
class WmiNullNode : public WmiValueNode
{
private:
protected:
public:
WmiNullNode (
BSTR a_PropertyName ,
ULONG a_Index ,
WmiTreeNode *a_Parent = NULL
) : WmiValueNode (
a_PropertyName ,
Function_None ,
Function_None ,
a_Index ,
a_Parent
)
{
}
WmiTreeNode *Copy () ;
void Print () ;
} ;
class WmiRangeNode : public WmiTreeNode
{
private:
protected:
BSTR m_PropertyName ;
ULONG m_Index ;
BOOL m_InfiniteLowerBound ;
BOOL m_InfiniteUpperBound ;
BOOL m_LowerBoundClosed;
BOOL m_UpperBoundClosed;
public:
WmiRangeNode (
BSTR a_PropertyName ,
ULONG a_Index ,
BOOL a_InfiniteLowerBound ,
BOOL a_InfiniteUpperBound ,
BOOL a_LowerBoundClosed ,
BOOL a_UpperBoundClosed ,
WmiTreeNode *a_NextNode = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiTreeNode ( NULL , NULL , a_NextNode , a_Parent ),
m_InfiniteLowerBound ( a_InfiniteLowerBound ) ,
m_InfiniteUpperBound ( a_InfiniteUpperBound ) ,
m_LowerBoundClosed ( a_LowerBoundClosed ) ,
m_UpperBoundClosed ( a_UpperBoundClosed ) ,
m_Index ( a_Index )
{
if ( a_PropertyName )
m_PropertyName = SysAllocString ( a_PropertyName ) ;
else
m_PropertyName = NULL ;
} ;
~WmiRangeNode ()
{
if ( m_PropertyName )
SysFreeString ( m_PropertyName ) ;
} ;
BSTR GetPropertyName ()
{
return m_PropertyName ;
}
ULONG GetIndex () { return m_Index ; }
LONG ComparePropertyName ( WmiRangeNode &a_RangeNode )
{
if ( m_Index < a_RangeNode.m_Index )
{
return -1 ;
}
else if ( m_Index > a_RangeNode.m_Index )
{
return 1 ;
}
else
{
return _wcsicmp ( m_PropertyName , a_RangeNode.m_PropertyName ) ;
}
}
BOOL InfiniteLowerBound () { return m_InfiniteLowerBound ; }
BOOL InfiniteUpperBound () { return m_InfiniteUpperBound ; }
BOOL ClosedLowerBound () { return m_LowerBoundClosed ; }
BOOL ClosedUpperBound () { return m_UpperBoundClosed ; }
} ;
class WmiUnsignedIntegerRangeNode : public WmiRangeNode
{
private:
protected:
ULONG m_LowerBound ;
ULONG m_UpperBound ;
public:
WmiUnsignedIntegerRangeNode (
BSTR a_PropertyName ,
ULONG a_Index ,
BOOL a_InfiniteLowerBound ,
BOOL a_InfiniteUpperBound ,
BOOL a_LowerBoundClosed ,
BOOL a_UpperBoundClosed ,
ULONG a_LowerBound ,
ULONG a_UpperBound ,
WmiTreeNode *a_NextNode = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiRangeNode (
a_PropertyName ,
a_Index ,
a_InfiniteLowerBound ,
a_InfiniteUpperBound ,
a_LowerBoundClosed ,
a_UpperBoundClosed ,
a_NextNode ,
a_Parent
) ,
m_LowerBound ( a_LowerBound ) ,
m_UpperBound ( a_UpperBound )
{
}
WmiTreeNode *Copy () ;
ULONG LowerBound () { return m_LowerBound ; }
ULONG UpperBound () { return m_UpperBound ; }
void Print () ;
BOOL GetIntersectingRange (
WmiUnsignedIntegerRangeNode &a_Range ,
WmiUnsignedIntegerRangeNode *&a_Intersection
) ;
BOOL GetOverlappingRange (
WmiUnsignedIntegerRangeNode &a_Range ,
WmiUnsignedIntegerRangeNode *&a_Intersection
) ;
BOOL GetNonIntersectingRange (
WmiUnsignedIntegerRangeNode &a_Range ,
WmiUnsignedIntegerRangeNode *&a_Before ,
WmiUnsignedIntegerRangeNode *&a_Intersection ,
WmiUnsignedIntegerRangeNode *&a_After
) ;
} ;
class WmiSignedIntegerRangeNode : public WmiRangeNode
{
private:
protected:
LONG m_LowerBound ;
LONG m_UpperBound ;
public:
WmiSignedIntegerRangeNode (
BSTR a_PropertyName ,
ULONG a_Index ,
BOOL a_InfiniteLowerBound ,
BOOL a_InfiniteUpperBound ,
BOOL a_LowerBoundClosed ,
BOOL a_UpperBoundClosed ,
LONG a_LowerBound ,
LONG a_UpperBound ,
WmiTreeNode *a_NextNode = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiRangeNode (
a_PropertyName ,
a_Index ,
a_InfiniteLowerBound ,
a_InfiniteUpperBound ,
a_LowerBoundClosed ,
a_UpperBoundClosed ,
a_NextNode ,
a_Parent
) ,
m_LowerBound ( a_LowerBound ) ,
m_UpperBound ( a_UpperBound )
{
}
WmiTreeNode *Copy () ;
LONG LowerBound () { return m_LowerBound ; }
LONG UpperBound () { return m_UpperBound ; }
void Print () ;
BOOL GetIntersectingRange (
WmiSignedIntegerRangeNode &a_Range ,
WmiSignedIntegerRangeNode *&a_Intersection
) ;
BOOL GetOverlappingRange (
WmiSignedIntegerRangeNode &a_Range ,
WmiSignedIntegerRangeNode *&a_Intersection
) ;
BOOL GetNonIntersectingRange (
WmiSignedIntegerRangeNode &a_Range ,
WmiSignedIntegerRangeNode *&a_Before ,
WmiSignedIntegerRangeNode *&a_Intersection ,
WmiSignedIntegerRangeNode *&a_After
) ;
} ;
class WmiStringRangeNode : public WmiRangeNode
{
private:
protected:
BSTR m_LowerBound ;
BSTR m_UpperBound ;
public:
WmiStringRangeNode (
BSTR a_PropertyName ,
ULONG a_Index ,
BOOL a_InfiniteLowerBound ,
BOOL a_InfiniteUpperBound ,
BOOL a_LowerBoundClosed ,
BOOL a_UpperBoundClosed ,
BSTR a_LowerBound ,
BSTR a_UpperBound ,
WmiTreeNode *a_NextNode = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiRangeNode (
a_PropertyName ,
a_Index ,
a_InfiniteLowerBound ,
a_InfiniteUpperBound ,
a_LowerBoundClosed ,
a_UpperBoundClosed ,
a_NextNode ,
a_Parent
)
{
if ( a_LowerBound )
m_LowerBound = SysAllocString ( a_LowerBound ) ;
else
m_LowerBound = NULL ;
if ( a_UpperBound )
m_UpperBound = SysAllocString ( a_UpperBound ) ;
else
m_UpperBound = NULL ;
}
~WmiStringRangeNode ()
{
if ( m_LowerBound )
SysFreeString ( m_LowerBound ) ;
if ( m_UpperBound )
SysFreeString ( m_UpperBound ) ;
} ;
WmiTreeNode *Copy () ;
BSTR LowerBound () { return m_LowerBound ; }
BSTR UpperBound () { return m_UpperBound ; }
void Print () ;
BOOL GetIntersectingRange (
WmiStringRangeNode &a_Range ,
WmiStringRangeNode *&a_Intersection
) ;
BOOL GetOverlappingRange (
WmiStringRangeNode &a_Range ,
WmiStringRangeNode *&a_Intersection
) ;
BOOL GetNonIntersectingRange (
WmiStringRangeNode &a_Range ,
WmiStringRangeNode *&a_Before ,
WmiStringRangeNode *&a_Intersection ,
WmiStringRangeNode *&a_After
) ;
} ;
class WmiNullRangeNode : public WmiRangeNode
{
private:
protected:
public:
WmiNullRangeNode (
BSTR a_PropertyName ,
ULONG a_Index ,
WmiTreeNode *a_NextNode = NULL ,
WmiTreeNode *a_Parent = NULL
) : WmiRangeNode (
a_PropertyName ,
a_Index ,
TRUE ,
TRUE ,
FALSE ,
FALSE ,
a_NextNode ,
a_Parent
)
{
}
~WmiNullRangeNode ()
{
} ;
WmiTreeNode *Copy () ;
void Print () ;
} ;
class Conjunctions
{
private:
protected:
/*
* Range values for the set of properties in a disjunction.
* Array index is ordered in property order.
*/
ULONG m_RangeContainerCount ;
WmiRangeNode **m_RangeContainer ;
public:
Conjunctions (
ULONG a_RangeContainerCount
) : m_RangeContainerCount ( a_RangeContainerCount )
{
m_RangeContainer = new WmiRangeNode * [ a_RangeContainerCount ] ;
for ( ULONG t_Index = 0 ; t_Index < m_RangeContainerCount ; t_Index ++ )
{
m_RangeContainer [ t_Index ] = NULL ;
}
}
~Conjunctions ()
{
for ( ULONG t_Index = 0 ; t_Index < m_RangeContainerCount ; t_Index ++ )
{
delete m_RangeContainer [ t_Index ] ;
}
delete [] m_RangeContainer ;
} ;
ULONG GetRangeCount ()
{
return m_RangeContainerCount ;
}
WmiRangeNode *GetRange ( ULONG a_Index )
{
if ( m_RangeContainerCount > a_Index )
{
return m_RangeContainer [ a_Index ] ;
}
else
return NULL ;
}
void SetRange ( ULONG a_Index , WmiRangeNode *a_Range )
{
if ( m_RangeContainerCount > a_Index )
{
if ( m_RangeContainer [ a_Index ] )
delete m_RangeContainer [ a_Index ] ;
m_RangeContainer [ a_Index ] = a_Range ;
}
}
} ;
class Disjunctions
{
private:
protected:
/*
* Range values for the set of properties in a disjunction.
* Array index is ordered in property order.
*/
ULONG m_ConjunctionCount ;
ULONG m_DisjunctionCount ;
Conjunctions **m_Disjunction ;
public:
Disjunctions (
ULONG a_DisjunctionCount ,
ULONG a_ConjunctionCount
) : m_DisjunctionCount ( a_DisjunctionCount ) ,
m_ConjunctionCount ( a_ConjunctionCount )
{
m_Disjunction = new Conjunctions * [ m_DisjunctionCount ] ;
for ( ULONG t_Index = 0 ; t_Index < m_DisjunctionCount ; t_Index ++ )
{
Conjunctions *t_Disjunction = new Conjunctions ( a_ConjunctionCount ) ;
m_Disjunction [ t_Index ] = t_Disjunction ;
}
}
~Disjunctions ()
{
for ( ULONG t_Index = 0 ; t_Index < m_DisjunctionCount ; t_Index ++ )
{
Conjunctions *t_Disjunction = m_Disjunction [ t_Index ] ;
delete t_Disjunction ;
}
delete [] m_Disjunction ;
} ;
ULONG GetDisjunctionCount ()
{
return m_DisjunctionCount ;
}
ULONG GetConjunctionCount ()
{
return m_ConjunctionCount ;
}
Conjunctions *GetDisjunction ( ULONG a_Index )
{
if ( m_DisjunctionCount > a_Index )
{
return m_Disjunction [ a_Index ] ;
}
else
return NULL ;
}
} ;
class PartitionSet
{
private:
protected:
/*
* Null for top level
*/
ULONG m_KeyIndex ;
WmiRangeNode *m_Range ;
/*
* Number of non overlapping partitions, zero when all keys have been partitioned
*/
ULONG m_NumberOfNonOverlappingPartitions ;
PartitionSet **m_NonOverlappingPartitions ;
public:
PartitionSet () : m_Range ( NULL ) ,
m_KeyIndex ( 0 ) ,
m_NumberOfNonOverlappingPartitions ( 0 ) ,
m_NonOverlappingPartitions ( NULL )
{
}
virtual ~PartitionSet ()
{
delete m_Range ;
for ( ULONG t_Index = 0 ; t_Index < m_NumberOfNonOverlappingPartitions ; t_Index ++ )
{
delete m_NonOverlappingPartitions [ t_Index ] ;
}
delete [] m_NonOverlappingPartitions ;
}
ULONG GetKeyIndex () { return m_KeyIndex ; }
void SetKeyIndex ( ULONG a_KeyIndex ) { m_KeyIndex = a_KeyIndex ; }
BOOL Root () { return m_Range == NULL ; }
BOOL Leaf () { return m_NonOverlappingPartitions == NULL ; }
void SetRange ( WmiRangeNode *a_Range ) { m_Range = a_Range ; }
WmiRangeNode *GetRange () { return m_Range ; }
void CreatePartitions ( ULONG a_Count )
{
m_NumberOfNonOverlappingPartitions = a_Count ;
m_NonOverlappingPartitions = new PartitionSet * [ a_Count ] ;
for ( ULONG t_Index = 0 ; t_Index < a_Count ; t_Index ++ )
{
m_NonOverlappingPartitions [ t_Index ] = NULL ;
}
}
void SetPartition ( ULONG a_Index , PartitionSet *a_Partition )
{
if ( a_Index < m_NumberOfNonOverlappingPartitions )
m_NonOverlappingPartitions [ a_Index ] = a_Partition ;
}
ULONG GetPartitionCount () { return m_NumberOfNonOverlappingPartitions ; }
PartitionSet *GetPartition ( ULONG a_Index )
{
if ( a_Index < m_NumberOfNonOverlappingPartitions )
return m_NonOverlappingPartitions [ a_Index ] ;
else
return NULL ;
}
} ;
class QueryPreprocessor
{
public:
enum QuadState {
State_True ,
State_False ,
State_ReEvaluate ,
State_Undefined ,
State_Error
} ;
private:
protected:
BOOL EvaluateNotEqualExpression ( WmiTreeNode *&a_Node ) ;
BOOL EvaluateNotExpression ( WmiTreeNode *&a_Node ) ;
BOOL EvaluateAndExpression ( WmiTreeNode *&a_Node ) ;
BOOL EvaluateOrExpression ( WmiTreeNode *&a_Node ) ;
BOOL RecursiveEvaluate (
SQL_LEVEL_1_RPN_EXPRESSION &a_Expression ,
WmiTreeNode *a_Parent ,
WmiTreeNode **a_Node ,
int &a_Index
) ;
void TransformAndOrExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_AndChild ,
WmiTreeNode *a_OrChild
) ;
void TransformNotNotExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotAndExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorEqualExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorNotEqualExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorEqualOrGreaterExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorEqualOrLessExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorGreaterExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorLessExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorLikeExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOperatorNotLikeExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotOrExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformNotEqualExpression (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
BOOL RecursiveDisjunctiveNormalForm ( WmiTreeNode *&a_Node ) ;
void TransformAndTrueEvaluation (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
void TransformOrFalseEvaluation (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Child
) ;
QuadState RecursiveRemoveInvariants ( WmiTreeNode *&a_Root ) ;
BOOL RecursiveInsertNode ( WmiTreeNode *&a_Root , WmiTreeNode *&a_Node ) ;
BOOL InsertNode ( WmiTreeNode *&a_Root , WmiTreeNode *&a_Node ) ;
BOOL RecursiveSortConditionals ( WmiTreeNode *&a_Root , WmiTreeNode *&a_NewRoot ) ;
BOOL SortConditionals ( WmiTreeNode *&a_Root ) ;
BOOL RecursiveSort ( WmiTreeNode *&a_Root ) ;
void TransformOperatorToRange (
WmiTreeNode *&a_Node
) ;
BOOL RecursiveConvertToRanges ( WmiTreeNode *&a_Root ) ;
void TransformIntersectingRange (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Compare ,
WmiTreeNode *a_Intersection
) ;
void TransformNonIntersectingRange (
WmiTreeNode *&a_Node ,
WmiTreeNode *a_Compare
) ;
QuadState RecursiveRemoveNonOverlappingRanges ( WmiTreeNode *&a_Root , WmiTreeNode *&a_Compare ) ;
void CountDisjunctions ( WmiTreeNode *a_Root , ULONG &a_Count ) ;
void CreateDisjunctions (
WmiTreeNode *a_Node ,
Disjunctions *a_Disjunctions ,
ULONG a_PropertiesToPartitionCount ,
BSTR *a_PropertiesToPartition ,
ULONG &a_DisjunctionIndex
) ;
BOOL RecursivePartitionSet (
Disjunctions *a_Disjunctions ,
PartitionSet *&a_Partition ,
ULONG a_DisjunctionSetToTestCount ,
ULONG *a_DisjunctionSetToTest ,
ULONG a_KeyIndex
) ;
protected:
/*
* Given a property name and it's value convert to it's correct type.
* e.g. if the CIMType of a_PropertyName is uint32 then create an WmiUnsignedIntegerNode
* return NULL if error.
*/
virtual WmiTreeNode *AllocTypeNode (
BSTR a_PropertyName ,
VARIANT &a_Variant ,
WmiValueNode :: WmiValueFunction a_PropertyFunction ,
WmiValueNode :: WmiValueFunction a_ConstantFunction ,
WmiTreeNode *a_Parent
) = 0 ;
virtual QuadState InvariantEvaluate (
WmiTreeNode *a_Operator ,
WmiTreeNode *a_Operand
) { return State_Undefined ; }
virtual WmiRangeNode *AllocInfiniteRangeNode (
BSTR a_PropertyName
) = 0 ;
virtual void GetPropertiesToPartition ( ULONG &a_Count , BSTR *&a_Container ) = 0 ;
protected:
BOOL Evaluate ( SQL_LEVEL_1_RPN_EXPRESSION &a_Expression , WmiTreeNode **a_Root ) ;
void DisjunctiveNormalForm ( WmiTreeNode *&a_Root ) ;
QuadState RemoveInvariants ( WmiTreeNode *&a_Root ) ;
BOOL Sort ( WmiTreeNode *&a_Root ) ;
BOOL ConvertToRanges ( WmiTreeNode *&a_Root ) ;
QuadState RemoveNonOverlappingRanges ( WmiTreeNode *&a_Root ) ;
BOOL CreateDisjunctionContainer ( WmiTreeNode *a_Root , Disjunctions *&a_Disjunctions ) ;
BOOL CreatePartitionSet ( Disjunctions *a_Disjunctions , PartitionSet *&a_Partition ) ;
void PrintTree ( WmiTreeNode *a_Root ) ;
public:
QuadState Preprocess ( SQL_LEVEL_1_RPN_EXPRESSION &a_Expression , PartitionSet *&a_Partition ) ;
virtual ~QueryPreprocessor() {}
} ;
#endif