coordinator.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 / Common / internal / materialization / coordinator.cs / 1 / coordinator.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System.Collections.Generic;
using System.Diagnostics; 
using System.Linq;
using System.Text;
using System.Globalization;
 
namespace System.Data.Common.Internal.Materialization
{ 
 
    /// 
    /// A coordinator is responsible for tracking state and processing result in a root or nested query 
    /// result collection. The coordinator exists within a graph, and knows its Parent, (First)Child,
    /// and Next sibling. This allows the Shaper to use the coordinator as a simple state machine when
    /// consuming store reader results.
    ///  
    internal abstract class Coordinator
    { 
        #region state 

        ///  
        /// The factory used to generate this coordinator instance. Contains delegates used
        /// by the Shaper during result enumeration.
        /// 
        internal readonly CoordinatorFactory CoordinatorFactory; 

        ///  
        /// Parent coordinator (the coordinator producing rows containing this collection). 
        /// If this is the root, null.
        ///  
        internal readonly Coordinator Parent;

        /// 
        /// First coordinator for nested results below this collection. When reading a new row 
        /// for this coordinator, we walk down to the Child.
        /// 
        /// NOTE:: this cannot be readonly because we can't know both the parent and the child 
        /// at initialization time; we set the Child in the parent's constructor.
        ///  
        public Coordinator Child
        {
            get { return _child; }
            protected set { _child = value; } 
        }
        private Coordinator _child; 
 
        /// 
        /// Next coordinator at this depth. Once we're done consuming results for this reader, 
        /// we move on to this.Next.
        /// 
        internal readonly Coordinator Next;
 
        /// 
        /// Indicates whether data has been read for the collection being aggregated or yielded 
        /// by this coordinator. 
        /// 
        public bool IsEntered 
        {
            get { return _isEntered; }
            protected set { _isEntered = value; }
        } 
        private bool _isEntered;
 
        ///  
        /// Indicates whether this is the top level coordinator for a query.
        ///  
        internal bool IsRoot
        {
            get { return null == Parent; }
        } 

        #endregion 
 
        #region constructor
 
        protected Coordinator(CoordinatorFactory coordinatorFactory, Coordinator parent, Coordinator next)
        {
            this.CoordinatorFactory = coordinatorFactory;
            this.Parent = parent; 
            this.Next = next;
        } 
 
        #endregion
 
        #region "public" surface area

        /// 
        /// Registers this hierarchy of coordinators in the given shaper. 
        /// 
        internal void Initialize(Shaper shaper) 
        { 
            ResetCollection(shaper);
 
            // Add this coordinator to the appropriate state slot in the
            // shaper so that it is available to materialization delegates.
            shaper.State[this.CoordinatorFactory.StateSlot] = this;
 
            if (null != this.Child)
            { 
                this.Child.Initialize(shaper); 
            }
            if (null != this.Next) 
            {
                this.Next.Initialize(shaper);
            }
        } 

        ///  
        /// Determines the maximum depth of this subtree. 
        /// 
        internal int MaxDistanceToLeaf() 
        {
            int maxDistance = 0;
            Coordinator child = this.Child;
            while (null != child) 
            {
                maxDistance = Math.Max(maxDistance, child.MaxDistanceToLeaf() + 1); 
                child = child.Next; 
            }
            return maxDistance; 
        }

        /// 
        /// This method is called when the current collection is finished and it's time to move to the next collection. 
        /// Recursively initializes children and siblings as well.
        ///  
        internal abstract void ResetCollection(Shaper shaper); 

        ///  
        /// Precondition: the current row has data for the coordinator.
        /// Side-effects: updates keys currently stored in state and updates IsEntered if a new value is encountered.
        /// Determines whether the row contains the next element in this collection.
        ///  
        internal bool HasNextElement(Shaper shaper)
        { 
            // check if this row contains a new element for this coordinator 
            bool result = false;
 
            if (!this.IsEntered || !this.CoordinatorFactory.CheckKeys(shaper))
            {
                // remember initial keys values
                this.CoordinatorFactory.SetKeys(shaper); 
                this.IsEntered = true;
                result = true; 
            } 

            return result; 
        }

        /// 
        /// Precondition: the current row has data and contains a new element for the coordinator. 
        /// Reads the next element in this collection.
        ///  
        internal abstract void ReadNextElement(Shaper shaper); 

        #endregion 
    }

    /// 
    /// Typed  
    /// 
    internal class Coordinator : Coordinator 
    { 
        #region state
 
        internal readonly CoordinatorFactory TypedCoordinatorFactory;

        /// 
        /// Exposes the Current element that has been materialized (and is being populated) by this coordinator. 
        /// 
        internal T Current 
        { 
            get { return _current; }
        } 
        private T _current;

        /// 
        /// For ObjectResult, aggregates all elements for in the nested collection handled by this coordinator. 
        /// 
        private List _elements; 
 
        /// 
        /// Delegate called when the current nested collection has been consumed. This is necessary in Span 
        /// scenarios where an EntityCollection RelatedEnd is populated only when all related entities have
        /// been materialized.
        /// 
        private Action> _handleClose; 

        ///  
        /// For nested, object-layer coordinators we want to collect all the elements we find and handle them 
        /// when the root coordinator advances.  Otherwise we just want to return them as we find them.
        ///  
        private readonly bool IsUsingElementCollection;

        #endregion
 
        #region constructors
 
        internal Coordinator(CoordinatorFactory coordinator, Coordinator parent, Coordinator next) 
            : base(coordinator, parent, next)
        { 
            this.TypedCoordinatorFactory = coordinator;

            // generate all children
            Coordinator nextChild = null; 
            foreach (var nestedCoordinator in coordinator.NestedCoordinators.Reverse())
            { 
                // last child processed is first child... 
                this.Child = nestedCoordinator.CreateCoordinator(this, nextChild);
                nextChild = this.Child; 
            }

            this.IsUsingElementCollection = (!this.IsRoot && typeof(T) != typeof(RecordState));
        } 

        #endregion 
 
        #region "public" surface area
 
        internal override void ResetCollection(Shaper shaper)
        {
            // Check to see if anyone has registered for notification when the current coordinator
            // is reset. 
            if (null != _handleClose)
            { 
                _handleClose(shaper, _elements); 
                _handleClose = null;
            } 

            // Reset is entered for this collection.
            this.IsEntered = false;
 
            if (IsUsingElementCollection)
            { 
                _elements = new List(); 
            }
 
            if (null != this.Child)
            {
                this.Child.ResetCollection(shaper);
            } 
            if (null != this.Next)
            { 
                this.Next.ResetCollection(shaper); 
            }
        } 

        internal override void ReadNextElement(Shaper shaper)
        {
            T element; 
            try
            { 
                element = this.TypedCoordinatorFactory.Element(shaper); 
            }
            catch (Exception e) 
            {
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    // call a variation of the "Element" delegate with more detailed 
                    // error handling (to produce a better exception message)
                    element = this.TypedCoordinatorFactory.ElementWithErrorHandling(shaper); 
                } 

                // rethrow 
                throw;
            }
            if (IsUsingElementCollection)
            { 
                _elements.Add(element);
            } 
            else 
            {
                _current = element; 
            }
        }

        ///  
        /// Sets the delegate called when this collection is closed.
        ///  
        internal void RegisterCloseHandler(Action> closeHandler) 
        {
            Debug.Assert(null == _handleClose, "more than one handler for a collection close 'event'"); 
            _handleClose = closeHandler;
        }

        ///  
        /// Called when we're disposing the enumerator;
        ///  
        internal void SetCurrentToDefault() 
        {
            _current = default(T); 
        }

        #endregion
 
        #region runtime callable code
 
        // Code in this section is called from the delegates produced by the Translator.  It may 
        // not show up if you search using Find All References
 
        /// 
        /// Returns a handle to the element aggregator for this nested collection.
        /// 
        private IEnumerable GetElements() 
        {
            return _elements; 
        } 

        #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.Diagnostics; 
using System.Linq;
using System.Text;
using System.Globalization;
 
namespace System.Data.Common.Internal.Materialization
{ 
 
    /// 
    /// A coordinator is responsible for tracking state and processing result in a root or nested query 
    /// result collection. The coordinator exists within a graph, and knows its Parent, (First)Child,
    /// and Next sibling. This allows the Shaper to use the coordinator as a simple state machine when
    /// consuming store reader results.
    ///  
    internal abstract class Coordinator
    { 
        #region state 

        ///  
        /// The factory used to generate this coordinator instance. Contains delegates used
        /// by the Shaper during result enumeration.
        /// 
        internal readonly CoordinatorFactory CoordinatorFactory; 

        ///  
        /// Parent coordinator (the coordinator producing rows containing this collection). 
        /// If this is the root, null.
        ///  
        internal readonly Coordinator Parent;

        /// 
        /// First coordinator for nested results below this collection. When reading a new row 
        /// for this coordinator, we walk down to the Child.
        /// 
        /// NOTE:: this cannot be readonly because we can't know both the parent and the child 
        /// at initialization time; we set the Child in the parent's constructor.
        ///  
        public Coordinator Child
        {
            get { return _child; }
            protected set { _child = value; } 
        }
        private Coordinator _child; 
 
        /// 
        /// Next coordinator at this depth. Once we're done consuming results for this reader, 
        /// we move on to this.Next.
        /// 
        internal readonly Coordinator Next;
 
        /// 
        /// Indicates whether data has been read for the collection being aggregated or yielded 
        /// by this coordinator. 
        /// 
        public bool IsEntered 
        {
            get { return _isEntered; }
            protected set { _isEntered = value; }
        } 
        private bool _isEntered;
 
        ///  
        /// Indicates whether this is the top level coordinator for a query.
        ///  
        internal bool IsRoot
        {
            get { return null == Parent; }
        } 

        #endregion 
 
        #region constructor
 
        protected Coordinator(CoordinatorFactory coordinatorFactory, Coordinator parent, Coordinator next)
        {
            this.CoordinatorFactory = coordinatorFactory;
            this.Parent = parent; 
            this.Next = next;
        } 
 
        #endregion
 
        #region "public" surface area

        /// 
        /// Registers this hierarchy of coordinators in the given shaper. 
        /// 
        internal void Initialize(Shaper shaper) 
        { 
            ResetCollection(shaper);
 
            // Add this coordinator to the appropriate state slot in the
            // shaper so that it is available to materialization delegates.
            shaper.State[this.CoordinatorFactory.StateSlot] = this;
 
            if (null != this.Child)
            { 
                this.Child.Initialize(shaper); 
            }
            if (null != this.Next) 
            {
                this.Next.Initialize(shaper);
            }
        } 

        ///  
        /// Determines the maximum depth of this subtree. 
        /// 
        internal int MaxDistanceToLeaf() 
        {
            int maxDistance = 0;
            Coordinator child = this.Child;
            while (null != child) 
            {
                maxDistance = Math.Max(maxDistance, child.MaxDistanceToLeaf() + 1); 
                child = child.Next; 
            }
            return maxDistance; 
        }

        /// 
        /// This method is called when the current collection is finished and it's time to move to the next collection. 
        /// Recursively initializes children and siblings as well.
        ///  
        internal abstract void ResetCollection(Shaper shaper); 

        ///  
        /// Precondition: the current row has data for the coordinator.
        /// Side-effects: updates keys currently stored in state and updates IsEntered if a new value is encountered.
        /// Determines whether the row contains the next element in this collection.
        ///  
        internal bool HasNextElement(Shaper shaper)
        { 
            // check if this row contains a new element for this coordinator 
            bool result = false;
 
            if (!this.IsEntered || !this.CoordinatorFactory.CheckKeys(shaper))
            {
                // remember initial keys values
                this.CoordinatorFactory.SetKeys(shaper); 
                this.IsEntered = true;
                result = true; 
            } 

            return result; 
        }

        /// 
        /// Precondition: the current row has data and contains a new element for the coordinator. 
        /// Reads the next element in this collection.
        ///  
        internal abstract void ReadNextElement(Shaper shaper); 

        #endregion 
    }

    /// 
    /// Typed  
    /// 
    internal class Coordinator : Coordinator 
    { 
        #region state
 
        internal readonly CoordinatorFactory TypedCoordinatorFactory;

        /// 
        /// Exposes the Current element that has been materialized (and is being populated) by this coordinator. 
        /// 
        internal T Current 
        { 
            get { return _current; }
        } 
        private T _current;

        /// 
        /// For ObjectResult, aggregates all elements for in the nested collection handled by this coordinator. 
        /// 
        private List _elements; 
 
        /// 
        /// Delegate called when the current nested collection has been consumed. This is necessary in Span 
        /// scenarios where an EntityCollection RelatedEnd is populated only when all related entities have
        /// been materialized.
        /// 
        private Action> _handleClose; 

        ///  
        /// For nested, object-layer coordinators we want to collect all the elements we find and handle them 
        /// when the root coordinator advances.  Otherwise we just want to return them as we find them.
        ///  
        private readonly bool IsUsingElementCollection;

        #endregion
 
        #region constructors
 
        internal Coordinator(CoordinatorFactory coordinator, Coordinator parent, Coordinator next) 
            : base(coordinator, parent, next)
        { 
            this.TypedCoordinatorFactory = coordinator;

            // generate all children
            Coordinator nextChild = null; 
            foreach (var nestedCoordinator in coordinator.NestedCoordinators.Reverse())
            { 
                // last child processed is first child... 
                this.Child = nestedCoordinator.CreateCoordinator(this, nextChild);
                nextChild = this.Child; 
            }

            this.IsUsingElementCollection = (!this.IsRoot && typeof(T) != typeof(RecordState));
        } 

        #endregion 
 
        #region "public" surface area
 
        internal override void ResetCollection(Shaper shaper)
        {
            // Check to see if anyone has registered for notification when the current coordinator
            // is reset. 
            if (null != _handleClose)
            { 
                _handleClose(shaper, _elements); 
                _handleClose = null;
            } 

            // Reset is entered for this collection.
            this.IsEntered = false;
 
            if (IsUsingElementCollection)
            { 
                _elements = new List(); 
            }
 
            if (null != this.Child)
            {
                this.Child.ResetCollection(shaper);
            } 
            if (null != this.Next)
            { 
                this.Next.ResetCollection(shaper); 
            }
        } 

        internal override void ReadNextElement(Shaper shaper)
        {
            T element; 
            try
            { 
                element = this.TypedCoordinatorFactory.Element(shaper); 
            }
            catch (Exception e) 
            {
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    // call a variation of the "Element" delegate with more detailed 
                    // error handling (to produce a better exception message)
                    element = this.TypedCoordinatorFactory.ElementWithErrorHandling(shaper); 
                } 

                // rethrow 
                throw;
            }
            if (IsUsingElementCollection)
            { 
                _elements.Add(element);
            } 
            else 
            {
                _current = element; 
            }
        }

        ///  
        /// Sets the delegate called when this collection is closed.
        ///  
        internal void RegisterCloseHandler(Action> closeHandler) 
        {
            Debug.Assert(null == _handleClose, "more than one handler for a collection close 'event'"); 
            _handleClose = closeHandler;
        }

        ///  
        /// Called when we're disposing the enumerator;
        ///  
        internal void SetCurrentToDefault() 
        {
            _current = default(T); 
        }

        #endregion
 
        #region runtime callable code
 
        // Code in this section is called from the delegates produced by the Translator.  It may 
        // not show up if you search using Find All References
 
        /// 
        /// Returns a handle to the element aggregator for this nested collection.
        /// 
        private IEnumerable GetElements() 
        {
            return _elements; 
        } 

        #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