VarRefManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / VarRefManager.cs / 1 / VarRefManager.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Globalization;
using System.Diagnostics;
using System.Data.Query.InternalTrees;
 
namespace System.Data.Query.PlanCompiler
{ 
    ///  
    /// This is a halper module for 
    /// The VarRefManager keeps track of the child-parent relationships in order to be able 
    /// to decide whether a given var is referenced by children on right-side relatives of a given node.
    /// It is used in JoinElimination when deciding whether it is possible to eliminate the child table participating
    /// in a left-outer join when there is a 1 - 0..1 FK relationship.
    ///  
    internal class VarRefManager
    { 
        #region Internal State 
        private Dictionary m_nodeToParentMap;   //child-parent mapping
        private Dictionary m_nodeToSiblingNumber;   //the index of the given node among its siblings, i.e. 0 for a first child 
        Command m_command;
        #endregion

        #region Constructor 
        /// 
        /// Constructs a new VarRefManager given a command. 
        ///  
        /// 
        internal VarRefManager(Command command) 
        {
            m_nodeToParentMap = new Dictionary();
            m_nodeToSiblingNumber = new Dictionary();
            m_command = command; 
        }
        #endregion 
 
        #region Public Methods
 
        /// 
        /// Tracks the information that the given node is a parent of its children (one level only)
        /// 
        ///  
        internal void AddChildren(Node parent)
        { 
            for(int i=0; i< parent.Children.Count; i++) 
            {
                //We do not use add on purpose, we may be updating a child's parent after join elimination in a subtree 
                m_nodeToParentMap[parent.Children[i]] = parent;
                m_nodeToSiblingNumber[parent.Children[i]] = i;
            }
        } 

        ///  
        /// Determines whether any var from a given list of keys is referenced by any of defining node's right relatives, 
        /// with the exception of the relatives brunching at the given targetJoinNode.
        ///  
        /// A list of vars to check for
        /// The node considered to be the defining node
        /// The relatives branching at this node are skipped
        /// False, only it can determine that not a single var from a given list of keys is referenced by any 
        /// of defining node's right relatives, with the exception of the relatives brunching at the given targetJoinNode. 
        internal bool HasKeyReferences(VarVec keys, Node definingNode, Node targetJoinNode) 
        { 
            Node currentChild = definingNode;
            Node parent; 
            bool continueUp = true;

            while (continueUp & m_nodeToParentMap.TryGetValue(currentChild, out parent))
            { 
                if (parent != targetJoinNode)
                { 
                    // Check the parent 
                    if (HasVarReferencesShallow(parent, keys, m_nodeToSiblingNumber[currentChild], out continueUp))
                    { 
                        return true;
                    }

                    //Check all the siblings to the right 
                    for (int i = m_nodeToSiblingNumber[currentChild] + 1; i < parent.Children.Count; i++)
                    { 
                        if (parent.Children[i].GetNodeInfo(m_command).ExternalReferences.Overlaps(keys)) 
                        {
                            return true; 
                        }
                    }
                }
                currentChild = parent; 
            }
            return false; 
        } 

        #endregion 

        #region Private Methods
        /// 
        /// Checks whether the given node has references to any of the vars in the given VarVec. 
        /// It only checks the given node, not its children.
        ///  
        /// The node to check 
        /// The list of vars to check for
        /// The index of the node's subree from which this var is coming. 
        /// This is used for SetOp-s, to be able to locate the appropriate var map that will give the
        /// vars corresponding to the given once
        /// If the OpType of the node's Op is such that it 'hides' the input, i.e.
        /// the decision of whether the given vars are referenced can be made on this level, it returns true, 
        /// false otherwise
        /// True if the given node has references to any of the vars in the given VarVec, false otherwise 
        private static bool HasVarReferencesShallow(Node node, VarVec vars, int childIndex, out bool continueUp) 
        {
            switch (node.Op.OpType) 
            {
                case OpType.ConstrainedSort:
                case OpType.Sort:
                    continueUp = true; 
                    return HasVarReferences(((SortBaseOp)node.Op).Keys, vars);
 
                case OpType.Distinct: 
                    continueUp = false;
                    return HasVarReferences(((DistinctOp)node.Op).Keys, vars); 

                case OpType.Except:
                case OpType.Intersect:
                case OpType.UnionAll: 
                    continueUp = false;
                    return HasVarReferences((SetOp)node.Op, vars, childIndex); 
 
                case OpType.GroupBy:
                    continueUp = false; 
                    return HasVarReferences(((GroupByOp)node.Op).Keys, vars);

                case OpType.PhysicalProject:
                    continueUp = false; 
                    return HasVarReferences(((PhysicalProjectOp)node.Op).Outputs, vars);
 
                case OpType.Project: 
                    continueUp = false;
                    return HasVarReferences(((ProjectOp)node.Op).Outputs, vars); 

                default:
                    continueUp = true;
                    return false; 
            }
        } 
 
        /// 
        /// Does the gvien VarList overlap with the given VarVec 
        /// 
        /// 
        /// 
        ///  
        private static bool HasVarReferences(VarList listToCheck, VarVec vars)
        { 
            foreach (Var var in vars) 
            {
                if (listToCheck.Contains(var)) 
                {
                    return true;
                }
            } 
            return false;
        } 
 
        /// 
        /// Do the two given varVecs overlap 
        /// 
        /// 
        /// 
        ///  
        private static bool HasVarReferences(VarVec listToCheck, VarVec vars)
        { 
            return listToCheck.Overlaps(vars); 
        }
 
        /// 
        /// Does the given list of sort keys contain a key with a var that is the given VarVec
        /// 
        ///  
        /// 
        ///  
        private static bool HasVarReferences(List listToCheck, VarVec vars) 
        {
            foreach (InternalTrees.SortKey key in listToCheck) 
            {
                if (vars.IsSet(key.Var))
                {
                    return true; 
                }
            } 
            return false; 
        }
 
        /// 
        /// Does the list of outputs of the given SetOp contain a var
        /// from the given VarVec defined by the SetOp's child with the given index
        ///  
        /// 
        ///  
        ///  
        /// 
        private static bool HasVarReferences(SetOp op, VarVec vars, int index) 
        {
            foreach (Var var in op.VarMap[index].Values)
            {
                if (vars.IsSet(var)) 
                {
                    return true; 
                } 
            }
            return false; 
        }
        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Globalization;
using System.Diagnostics;
using System.Data.Query.InternalTrees;
 
namespace System.Data.Query.PlanCompiler
{ 
    ///  
    /// This is a halper module for 
    /// The VarRefManager keeps track of the child-parent relationships in order to be able 
    /// to decide whether a given var is referenced by children on right-side relatives of a given node.
    /// It is used in JoinElimination when deciding whether it is possible to eliminate the child table participating
    /// in a left-outer join when there is a 1 - 0..1 FK relationship.
    ///  
    internal class VarRefManager
    { 
        #region Internal State 
        private Dictionary m_nodeToParentMap;   //child-parent mapping
        private Dictionary m_nodeToSiblingNumber;   //the index of the given node among its siblings, i.e. 0 for a first child 
        Command m_command;
        #endregion

        #region Constructor 
        /// 
        /// Constructs a new VarRefManager given a command. 
        ///  
        /// 
        internal VarRefManager(Command command) 
        {
            m_nodeToParentMap = new Dictionary();
            m_nodeToSiblingNumber = new Dictionary();
            m_command = command; 
        }
        #endregion 
 
        #region Public Methods
 
        /// 
        /// Tracks the information that the given node is a parent of its children (one level only)
        /// 
        ///  
        internal void AddChildren(Node parent)
        { 
            for(int i=0; i< parent.Children.Count; i++) 
            {
                //We do not use add on purpose, we may be updating a child's parent after join elimination in a subtree 
                m_nodeToParentMap[parent.Children[i]] = parent;
                m_nodeToSiblingNumber[parent.Children[i]] = i;
            }
        } 

        ///  
        /// Determines whether any var from a given list of keys is referenced by any of defining node's right relatives, 
        /// with the exception of the relatives brunching at the given targetJoinNode.
        ///  
        /// A list of vars to check for
        /// The node considered to be the defining node
        /// The relatives branching at this node are skipped
        /// False, only it can determine that not a single var from a given list of keys is referenced by any 
        /// of defining node's right relatives, with the exception of the relatives brunching at the given targetJoinNode. 
        internal bool HasKeyReferences(VarVec keys, Node definingNode, Node targetJoinNode) 
        { 
            Node currentChild = definingNode;
            Node parent; 
            bool continueUp = true;

            while (continueUp & m_nodeToParentMap.TryGetValue(currentChild, out parent))
            { 
                if (parent != targetJoinNode)
                { 
                    // Check the parent 
                    if (HasVarReferencesShallow(parent, keys, m_nodeToSiblingNumber[currentChild], out continueUp))
                    { 
                        return true;
                    }

                    //Check all the siblings to the right 
                    for (int i = m_nodeToSiblingNumber[currentChild] + 1; i < parent.Children.Count; i++)
                    { 
                        if (parent.Children[i].GetNodeInfo(m_command).ExternalReferences.Overlaps(keys)) 
                        {
                            return true; 
                        }
                    }
                }
                currentChild = parent; 
            }
            return false; 
        } 

        #endregion 

        #region Private Methods
        /// 
        /// Checks whether the given node has references to any of the vars in the given VarVec. 
        /// It only checks the given node, not its children.
        ///  
        /// The node to check 
        /// The list of vars to check for
        /// The index of the node's subree from which this var is coming. 
        /// This is used for SetOp-s, to be able to locate the appropriate var map that will give the
        /// vars corresponding to the given once
        /// If the OpType of the node's Op is such that it 'hides' the input, i.e.
        /// the decision of whether the given vars are referenced can be made on this level, it returns true, 
        /// false otherwise
        /// True if the given node has references to any of the vars in the given VarVec, false otherwise 
        private static bool HasVarReferencesShallow(Node node, VarVec vars, int childIndex, out bool continueUp) 
        {
            switch (node.Op.OpType) 
            {
                case OpType.ConstrainedSort:
                case OpType.Sort:
                    continueUp = true; 
                    return HasVarReferences(((SortBaseOp)node.Op).Keys, vars);
 
                case OpType.Distinct: 
                    continueUp = false;
                    return HasVarReferences(((DistinctOp)node.Op).Keys, vars); 

                case OpType.Except:
                case OpType.Intersect:
                case OpType.UnionAll: 
                    continueUp = false;
                    return HasVarReferences((SetOp)node.Op, vars, childIndex); 
 
                case OpType.GroupBy:
                    continueUp = false; 
                    return HasVarReferences(((GroupByOp)node.Op).Keys, vars);

                case OpType.PhysicalProject:
                    continueUp = false; 
                    return HasVarReferences(((PhysicalProjectOp)node.Op).Outputs, vars);
 
                case OpType.Project: 
                    continueUp = false;
                    return HasVarReferences(((ProjectOp)node.Op).Outputs, vars); 

                default:
                    continueUp = true;
                    return false; 
            }
        } 
 
        /// 
        /// Does the gvien VarList overlap with the given VarVec 
        /// 
        /// 
        /// 
        ///  
        private static bool HasVarReferences(VarList listToCheck, VarVec vars)
        { 
            foreach (Var var in vars) 
            {
                if (listToCheck.Contains(var)) 
                {
                    return true;
                }
            } 
            return false;
        } 
 
        /// 
        /// Do the two given varVecs overlap 
        /// 
        /// 
        /// 
        ///  
        private static bool HasVarReferences(VarVec listToCheck, VarVec vars)
        { 
            return listToCheck.Overlaps(vars); 
        }
 
        /// 
        /// Does the given list of sort keys contain a key with a var that is the given VarVec
        /// 
        ///  
        /// 
        ///  
        private static bool HasVarReferences(List listToCheck, VarVec vars) 
        {
            foreach (InternalTrees.SortKey key in listToCheck) 
            {
                if (vars.IsSet(key.Var))
                {
                    return true; 
                }
            } 
            return false; 
        }
 
        /// 
        /// Does the list of outputs of the given SetOp contain a var
        /// from the given VarVec defined by the SetOp's child with the given index
        ///  
        /// 
        ///  
        ///  
        /// 
        private static bool HasVarReferences(SetOp op, VarVec vars, int index) 
        {
            foreach (Var var in op.VarMap[index].Values)
            {
                if (vars.IsSet(var)) 
                {
                    return true; 
                } 
            }
            return false; 
        }
        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK