coordinatorscratchpad.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / internal / materialization / coordinatorscratchpad.cs / 2 / coordinatorscratchpad.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System.Collections.Generic;
using System.Data.Query.InternalTrees; 
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
 
namespace System.Data.Common.Internal.Materialization
{ 
    ///  
    /// Used in the Translator to aggregate information about a (nested) reader
    /// coordinator. After the translator visits the columnMaps, it will compile 
    /// the coordinator(s) which produces an immutable CoordinatorFactory that
    /// can be shared amongst many query instances.
    /// 
    internal class CoordinatorScratchpad 
    {
        #region private state 
 
        private Type _elementType;
        private int _stateSlotNumber; 
        private int _depth;
        private Expression _element;
        private Expression _hasData;
        private Expression _setKeys; 
        private Expression _checkKeys;
        private CoordinatorScratchpad _parent; 
        private readonly List _nestedCoordinatorScratchpads; 
        /// 
        /// Map from original expressions to expressions with detailed error handling. 
        /// 
        private readonly Dictionary _expressionWithErrorHandlingMap;
        /// 
        /// Expressions that should be precompiled (i.e. reduced to constants in 
        /// compiled delegates.
        ///  
        private readonly HashSet _inlineDelegates; 

        #endregion 

        #region constructor

        internal CoordinatorScratchpad(Type elementType) 
        {
            _elementType = elementType; 
            _nestedCoordinatorScratchpads = new List(); 
            _expressionWithErrorHandlingMap = new Dictionary();
            _inlineDelegates = new HashSet(); 
        }

        #endregion
 
        #region "public" surface area
 
        ///  
        /// For nested collections, returns the parent coordinator.
        ///  
        internal CoordinatorScratchpad Parent
        {
            get { return _parent; }
        } 

        ///  
        /// Gets or sets an Expression setting key values (these keys are used 
        /// to determine when a collection has entered a new chapter) from the
        /// underlying store data reader. 
        /// 
        internal Expression SetKeys
        {
            get { return _setKeys; } 
            set { _setKeys = value; }
        } 
 
        /// 
        /// Gets or sets an Expression returning 'true' when the key values for 
        /// the current nested result (see SetKeys) are equal to the current key
        /// values on the underlying data reader.
        /// 
        internal Expression CheckKeys 
        {
            get { return _checkKeys; } 
            set { _checkKeys = value; } 
        }
 
        /// 
        /// Gets or sets an expression returning 'true' if the current row in
        /// the underlying data reader contains an element of the collection.
        ///  
        internal Expression HasData
        { 
            get { return _hasData; } 
            set { _hasData = value; }
        } 

        /// 
        /// Gets or sets an Expression yielding an element of the current collection
        /// given values in the underlying data reader. 
        /// 
        internal Expression Element 
        { 
            get { return _element; }
            set { _element = value; } 
        }

        /// 
        /// Indicates which Shaper.State slot is home for this collection's coordinator. 
        /// Used by Parent to pull out nested collection aggregators/streamers.
        ///  
        internal int StateSlotNumber 
        {
            get { return _stateSlotNumber; } 
            set { _stateSlotNumber = value; }
        }

        ///  
        /// Gets or sets the depth of the current coordinator. A root collection has depth 0.
        ///  
        internal int Depth 
        {
            get { return _depth; } 
            set { _depth = value; }
        }

        ///  
        /// List of all record types that we can return at this level in the query.
        ///  
        private List _recordStateScratchpads; 

        ///  
        /// Allows sub-expressions to register an 'interest' in exceptions thrown when reading elements
        /// for this coordinator. When an exception is thrown, we rerun the delegate using the slower
        /// but more error-friendly versions of expressions (e.g. reader.GetValue + type check instead
        /// of reader.GetInt32()) 
        /// 
        /// The lean and mean raw version of the expression 
        /// The slower version of the same expression with better 
        /// error handling
        internal void AddExpressionWithErrorHandling(Expression expression, Expression expressionWithErrorHandling) 
        {
            _expressionWithErrorHandlingMap[expression] = expressionWithErrorHandling;
        }
 
        /// 
        /// Registers a lambda expression for pre-compilation (i.e. reduction to a constant expression) 
        /// within materialization expression. Otherwise, the expression will be compiled every time 
        /// the enclosing delegate is invoked.
        ///  
        /// Lambda expression to register.
        internal void AddInlineDelegate(LambdaExpression expression)
        {
            _inlineDelegates.Add(expression); 
        }
 
        ///  
        /// Registers a coordinator for a nested collection contained in elements of this collection.
        ///  
        internal void AddNestedCoordinator(CoordinatorScratchpad nested)
        {
            Debug.Assert(nested.Depth == this.Depth + 1, "can only nest depth + 1");
            nested._parent = this; 
            _nestedCoordinatorScratchpads.Add(nested);
        } 
 
        /// 
        /// Use the information stored on the scratchpad to compile an immutable factory used 
        /// to construct the coordinators used at runtime when materializing results.
        /// 
        internal CoordinatorFactory Compile()
        { 
            RecordStateFactory[] recordStateFactories;
            if (null != _recordStateScratchpads) 
            { 
                recordStateFactories = new RecordStateFactory[_recordStateScratchpads.Count];
                for (int i = 0; i < recordStateFactories.Length; i++) 
                {
                    recordStateFactories[i] = _recordStateScratchpads[i].Compile();
                }
            } 
            else
            { 
                recordStateFactories = new RecordStateFactory[0]; 
            }
 
            CoordinatorFactory[] nestedCoordinators = new CoordinatorFactory[_nestedCoordinatorScratchpads.Count];
            for (int i = 0; i < nestedCoordinators.Length; i++)
            {
                nestedCoordinators[i] = _nestedCoordinatorScratchpads[i].Compile(); 
            }
 
            // compile inline delegates 
            ReplacementExpressionVisitor replacementVisitor = new ReplacementExpressionVisitor(null, this._inlineDelegates);
            Expression element = replacementVisitor.Visit(this.Element); 

            // substitute expressions that have error handlers into a new expression (used
            // when a more detailed exception message is needed)
            replacementVisitor = new ReplacementExpressionVisitor(this._expressionWithErrorHandlingMap, this._inlineDelegates); 
            Expression elementWithErrorHandling = replacementVisitor.Visit(this.Element);
 
            CoordinatorFactory result = (CoordinatorFactory)Activator.CreateInstance(typeof(CoordinatorFactory<>).MakeGenericType(_elementType), new object[] { 
                                                            this.Depth,
                                                            this.StateSlotNumber, 
                                                            this.HasData,
                                                            this.SetKeys,
                                                            this.CheckKeys,
                                                            nestedCoordinators, 
                                                            element,
                                                            elementWithErrorHandling, 
                                                            recordStateFactories 
                                                            });
            return result; 
        }

        /// 
        /// Allocates a new RecordStateScratchpad and adds it to the list of the ones we're 
        /// responsible for; will create the list if it hasn't alread been created.
        ///  
        internal RecordStateScratchpad CreateRecordStateScratchpad() 
        {
            RecordStateScratchpad recordStateScratchpad = new RecordStateScratchpad(); 

            if (null == _recordStateScratchpads)
            {
                _recordStateScratchpads = new List(); 
            }
            _recordStateScratchpads.Add(recordStateScratchpad); 
            return recordStateScratchpad; 
        }
        #endregion 

        #region Nested types

        ///  
        /// Visitor supporting (non-recursive) replacement of LINQ sub-expressions and
        /// compilation of inline delegates. 
        ///  
        private class ReplacementExpressionVisitor : ExpressionVisitor
        { 
            // Map from original expressions to replacement expressions.
            private readonly Dictionary _replacementDictionary;
            private readonly HashSet _inlineDelegates;
 
            internal ReplacementExpressionVisitor(Dictionary replacementDictionary,
                HashSet inlineDelegates) 
            { 
                this._replacementDictionary = replacementDictionary;
                this._inlineDelegates = inlineDelegates; 
            }

            internal override Expression Visit(Expression expression)
            { 
                if (null == expression)
                { 
                    return expression; 
                }
 
                Expression result;

                // check to see if a substitution has been provided for this expression
                Expression replacement; 
                if (null != this._replacementDictionary && this._replacementDictionary.TryGetValue(expression, out replacement))
                { 
                    // once a substitution is found, we stop walking the sub-expression and 
                    // return immediately (since recursive replacement is not needed or wanted)
                    result = replacement; 
                }
                else
                {
                    // check if we need to precompile an inline delegate 
                    bool preCompile = false;
                    LambdaExpression lambda = null; 
 
                    if (expression.NodeType == ExpressionType.Lambda &&
                        null != _inlineDelegates) 
                    {
                        lambda = (LambdaExpression)expression;
                        preCompile = _inlineDelegates.Contains(lambda);
                    } 

                    if (preCompile) 
                    { 
                        // do replacement in the body of the lambda expression
                        Expression body = Visit(lambda.Body); 

                        // compile to a delegate
                        result = Expression.Constant(Translator.Compile(body.Type, body));
                    } 
                    else
                    { 
                        result = base.Visit(expression); 
                    }
                } 

                return result;
            }
        } 
        #endregion
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System.Collections.Generic;
using System.Data.Query.InternalTrees; 
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
 
namespace System.Data.Common.Internal.Materialization
{ 
    ///  
    /// Used in the Translator to aggregate information about a (nested) reader
    /// coordinator. After the translator visits the columnMaps, it will compile 
    /// the coordinator(s) which produces an immutable CoordinatorFactory that
    /// can be shared amongst many query instances.
    /// 
    internal class CoordinatorScratchpad 
    {
        #region private state 
 
        private Type _elementType;
        private int _stateSlotNumber; 
        private int _depth;
        private Expression _element;
        private Expression _hasData;
        private Expression _setKeys; 
        private Expression _checkKeys;
        private CoordinatorScratchpad _parent; 
        private readonly List _nestedCoordinatorScratchpads; 
        /// 
        /// Map from original expressions to expressions with detailed error handling. 
        /// 
        private readonly Dictionary _expressionWithErrorHandlingMap;
        /// 
        /// Expressions that should be precompiled (i.e. reduced to constants in 
        /// compiled delegates.
        ///  
        private readonly HashSet _inlineDelegates; 

        #endregion 

        #region constructor

        internal CoordinatorScratchpad(Type elementType) 
        {
            _elementType = elementType; 
            _nestedCoordinatorScratchpads = new List(); 
            _expressionWithErrorHandlingMap = new Dictionary();
            _inlineDelegates = new HashSet(); 
        }

        #endregion
 
        #region "public" surface area
 
        ///  
        /// For nested collections, returns the parent coordinator.
        ///  
        internal CoordinatorScratchpad Parent
        {
            get { return _parent; }
        } 

        ///  
        /// Gets or sets an Expression setting key values (these keys are used 
        /// to determine when a collection has entered a new chapter) from the
        /// underlying store data reader. 
        /// 
        internal Expression SetKeys
        {
            get { return _setKeys; } 
            set { _setKeys = value; }
        } 
 
        /// 
        /// Gets or sets an Expression returning 'true' when the key values for 
        /// the current nested result (see SetKeys) are equal to the current key
        /// values on the underlying data reader.
        /// 
        internal Expression CheckKeys 
        {
            get { return _checkKeys; } 
            set { _checkKeys = value; } 
        }
 
        /// 
        /// Gets or sets an expression returning 'true' if the current row in
        /// the underlying data reader contains an element of the collection.
        ///  
        internal Expression HasData
        { 
            get { return _hasData; } 
            set { _hasData = value; }
        } 

        /// 
        /// Gets or sets an Expression yielding an element of the current collection
        /// given values in the underlying data reader. 
        /// 
        internal Expression Element 
        { 
            get { return _element; }
            set { _element = value; } 
        }

        /// 
        /// Indicates which Shaper.State slot is home for this collection's coordinator. 
        /// Used by Parent to pull out nested collection aggregators/streamers.
        ///  
        internal int StateSlotNumber 
        {
            get { return _stateSlotNumber; } 
            set { _stateSlotNumber = value; }
        }

        ///  
        /// Gets or sets the depth of the current coordinator. A root collection has depth 0.
        ///  
        internal int Depth 
        {
            get { return _depth; } 
            set { _depth = value; }
        }

        ///  
        /// List of all record types that we can return at this level in the query.
        ///  
        private List _recordStateScratchpads; 

        ///  
        /// Allows sub-expressions to register an 'interest' in exceptions thrown when reading elements
        /// for this coordinator. When an exception is thrown, we rerun the delegate using the slower
        /// but more error-friendly versions of expressions (e.g. reader.GetValue + type check instead
        /// of reader.GetInt32()) 
        /// 
        /// The lean and mean raw version of the expression 
        /// The slower version of the same expression with better 
        /// error handling
        internal void AddExpressionWithErrorHandling(Expression expression, Expression expressionWithErrorHandling) 
        {
            _expressionWithErrorHandlingMap[expression] = expressionWithErrorHandling;
        }
 
        /// 
        /// Registers a lambda expression for pre-compilation (i.e. reduction to a constant expression) 
        /// within materialization expression. Otherwise, the expression will be compiled every time 
        /// the enclosing delegate is invoked.
        ///  
        /// Lambda expression to register.
        internal void AddInlineDelegate(LambdaExpression expression)
        {
            _inlineDelegates.Add(expression); 
        }
 
        ///  
        /// Registers a coordinator for a nested collection contained in elements of this collection.
        ///  
        internal void AddNestedCoordinator(CoordinatorScratchpad nested)
        {
            Debug.Assert(nested.Depth == this.Depth + 1, "can only nest depth + 1");
            nested._parent = this; 
            _nestedCoordinatorScratchpads.Add(nested);
        } 
 
        /// 
        /// Use the information stored on the scratchpad to compile an immutable factory used 
        /// to construct the coordinators used at runtime when materializing results.
        /// 
        internal CoordinatorFactory Compile()
        { 
            RecordStateFactory[] recordStateFactories;
            if (null != _recordStateScratchpads) 
            { 
                recordStateFactories = new RecordStateFactory[_recordStateScratchpads.Count];
                for (int i = 0; i < recordStateFactories.Length; i++) 
                {
                    recordStateFactories[i] = _recordStateScratchpads[i].Compile();
                }
            } 
            else
            { 
                recordStateFactories = new RecordStateFactory[0]; 
            }
 
            CoordinatorFactory[] nestedCoordinators = new CoordinatorFactory[_nestedCoordinatorScratchpads.Count];
            for (int i = 0; i < nestedCoordinators.Length; i++)
            {
                nestedCoordinators[i] = _nestedCoordinatorScratchpads[i].Compile(); 
            }
 
            // compile inline delegates 
            ReplacementExpressionVisitor replacementVisitor = new ReplacementExpressionVisitor(null, this._inlineDelegates);
            Expression element = replacementVisitor.Visit(this.Element); 

            // substitute expressions that have error handlers into a new expression (used
            // when a more detailed exception message is needed)
            replacementVisitor = new ReplacementExpressionVisitor(this._expressionWithErrorHandlingMap, this._inlineDelegates); 
            Expression elementWithErrorHandling = replacementVisitor.Visit(this.Element);
 
            CoordinatorFactory result = (CoordinatorFactory)Activator.CreateInstance(typeof(CoordinatorFactory<>).MakeGenericType(_elementType), new object[] { 
                                                            this.Depth,
                                                            this.StateSlotNumber, 
                                                            this.HasData,
                                                            this.SetKeys,
                                                            this.CheckKeys,
                                                            nestedCoordinators, 
                                                            element,
                                                            elementWithErrorHandling, 
                                                            recordStateFactories 
                                                            });
            return result; 
        }

        /// 
        /// Allocates a new RecordStateScratchpad and adds it to the list of the ones we're 
        /// responsible for; will create the list if it hasn't alread been created.
        ///  
        internal RecordStateScratchpad CreateRecordStateScratchpad() 
        {
            RecordStateScratchpad recordStateScratchpad = new RecordStateScratchpad(); 

            if (null == _recordStateScratchpads)
            {
                _recordStateScratchpads = new List(); 
            }
            _recordStateScratchpads.Add(recordStateScratchpad); 
            return recordStateScratchpad; 
        }
        #endregion 

        #region Nested types

        ///  
        /// Visitor supporting (non-recursive) replacement of LINQ sub-expressions and
        /// compilation of inline delegates. 
        ///  
        private class ReplacementExpressionVisitor : ExpressionVisitor
        { 
            // Map from original expressions to replacement expressions.
            private readonly Dictionary _replacementDictionary;
            private readonly HashSet _inlineDelegates;
 
            internal ReplacementExpressionVisitor(Dictionary replacementDictionary,
                HashSet inlineDelegates) 
            { 
                this._replacementDictionary = replacementDictionary;
                this._inlineDelegates = inlineDelegates; 
            }

            internal override Expression Visit(Expression expression)
            { 
                if (null == expression)
                { 
                    return expression; 
                }
 
                Expression result;

                // check to see if a substitution has been provided for this expression
                Expression replacement; 
                if (null != this._replacementDictionary && this._replacementDictionary.TryGetValue(expression, out replacement))
                { 
                    // once a substitution is found, we stop walking the sub-expression and 
                    // return immediately (since recursive replacement is not needed or wanted)
                    result = replacement; 
                }
                else
                {
                    // check if we need to precompile an inline delegate 
                    bool preCompile = false;
                    LambdaExpression lambda = null; 
 
                    if (expression.NodeType == ExpressionType.Lambda &&
                        null != _inlineDelegates) 
                    {
                        lambda = (LambdaExpression)expression;
                        preCompile = _inlineDelegates.Contains(lambda);
                    } 

                    if (preCompile) 
                    { 
                        // do replacement in the body of the lambda expression
                        Expression body = Visit(lambda.Body); 

                        // compile to a delegate
                        result = Expression.Constant(Translator.Compile(body.Type, body));
                    } 
                    else
                    { 
                        result = base.Visit(expression); 
                    }
                } 

                return result;
            }
        } 
        #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