coordinatorscratchpad.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / internal / materialization / coordinatorscratchpad.cs / 1599186 / 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;
using System.Runtime.CompilerServices; 

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 readonly Type _elementType; 
        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; set; } 
 
        /// 
        /// 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; set; } 

        ///  
        /// 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; set; }

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

        ///  
        /// Gets or sets an Expression initializing the collection storing results from this coordinator.
        /// 
        internal Expression InitializeCollection { get; set; }
 
        /// 
        /// 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; set; } 

        /// 
        /// Gets or sets the depth of the current coordinator. A root collection has depth 0.
        ///  
        internal int Depth { get; set; }
 
        ///  
        /// 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. 
        /// 
        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] 
        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,
                                                            this.InitializeCollection,
                                                            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 : EntityExpressionVisitor 
        {
            // 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