QueryProcessor.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / QueryProcessor.cs / 1 / QueryProcessor.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System.Diagnostics;
    using System.ServiceModel.Channels; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Xml; 
    using System.Xml.XPath;
    using System.ServiceModel.Diagnostics;

    internal class ProcessingContext 
    {
        internal ProcessingContext next; // for chaining together in free lists 
        int nodeCount; 
        QueryProcessor processor;
        EvalStack sequenceStack; 
        EvalStack valueStack;

        internal ProcessingContext(QueryProcessor processor)
        { 
            this.processor = processor;
            this.valueStack = new EvalStack(2, 4); 
            this.sequenceStack = new EvalStack(1, 2); 
            this.nodeCount = -1;
        } 

        internal ProcessingContext()
            : this(null)
        { 
        }
#if NO 
        internal int FrameCount 
        {
            get 
            {
                return this.valueStack.FrameCount;
            }
        } 

        internal int FramePtr 
        { 
            get
            { 
                return this.valueStack.FramePtr;
            }
        }
#endif 
        internal StackFrame this[int frameIndex]
        { 
            get 
            {
                return this.valueStack[frameIndex]; 
            }
        }

        internal int IterationCount 
        {
            get 
            { 
                if (-1 == this.nodeCount)
                { 
                    this.nodeCount = this.sequenceStack.CalculateNodecount();
                    if (this.nodeCount == 0 && !this.sequenceStack.InUse)
                    {
                        this.nodeCount = 1; 
                    }
                } 
 
                return this.nodeCount;
            } 
        }

        internal int NodeCount
        { 
            get
            { 
                return this.nodeCount; 
            }
            set 
            {
                this.nodeCount = value;
            }
        } 

        internal ProcessingContext Next 
        { 
            get
            { 
                return this.next;
            }
            set
            { 
                this.next = value;
            } 
        } 

        internal QueryProcessor Processor 
        {
            get
            {
                return this.processor; 
            }
            set 
            { 
                this.processor = value;
            } 
        }

        internal StackFrame SecondArg
        { 
            get
            { 
                return this.valueStack.SecondArg; 
            }
        } 

        internal Value[] Sequences
        {
            get 
            {
                return this.sequenceStack.Buffer; 
            } 
        }
 
        internal bool SequenceStackInUse
        {
            get
            { 
                return this.sequenceStack.InUse;
            } 
        } 

        internal bool StacksInUse 
        {
            get
            {
                return (this.valueStack.frames.Count > 0 || this.sequenceStack.frames.Count > 0); 
            }
        } 
 
        internal StackFrame TopArg
        { 
            get
            {
                return this.valueStack.TopArg;
            } 
        }
 
        internal StackFrame TopSequenceArg 
        {
            get 
            {
                return this.sequenceStack.TopArg;
            }
        } 

        internal Value[] Values 
        { 
            get
            { 
                return this.valueStack.Buffer;
            }
        }
 
        internal ProcessingContext Clone()
        { 
            return this.processor.CloneContext(this); 
        }
 
        internal void ClearContext()
        {
            this.sequenceStack.Clear();
            this.valueStack.Clear(); 
            this.nodeCount = -1;
        } 
 
        internal void CopyFrom(ProcessingContext context)
        { 
            DiagnosticUtility.DebugAssert(null != context, "");

            this.processor = context.processor;
            if (context.sequenceStack.frames.Count > 0) 
            {
                this.sequenceStack.CopyFrom(ref context.sequenceStack); 
            } 
            else
            { 
                this.sequenceStack.Clear();
            }
            if (context.valueStack.frames.Count > 0)
            { 
                this.valueStack.CopyFrom(ref context.valueStack);
            } 
            else 
            {
                this.valueStack.Clear(); 
            }
            this.nodeCount = context.nodeCount;
        }
 
        internal NodeSequence CreateSequence()
        { 
            NodeSequence sequence = this.processor.PopSequence(); 
            if (null == sequence)
            { 
                sequence = new NodeSequence();
            }
            sequence.OwnerContext = this;
            sequence.refCount++; 

            return sequence; 
        } 

        internal bool LoadVariable(int var) 
        {
            return this.Processor.LoadVariable(this, var);
        }
 
        internal void EvalCodeBlock(Opcode block)
        { 
            this.processor.Eval(block, this); 
        }
 
        internal bool PeekBoolean(int index)
        {
            return this.valueStack.PeekBoolean(index);
        } 

        internal double PeekDouble(int index) 
        { 
            return this.valueStack.PeekDouble(index);
        } 
#if NO
        internal int PeekInteger(int index)
        {
            return (int) this.valueStack.PeekInteger(index); 
        }
#endif 
        internal NodeSequence PeekSequence(int index) 
        {
            return this.valueStack.PeekSequence(index); 
        }

        internal string PeekString(int index)
        { 
            return this.valueStack.PeekString(index);
        } 
 
        internal void PopFrame()
        { 
            this.valueStack.PopFrame(this);
        }

        internal void PopSequenceFrame() 
        {
            this.sequenceStack.PopFrame(this); 
            this.nodeCount = -1; 
        }
 
        internal void PopContextSequenceFrame()
        {
            PopSequenceFrame();
            if (!this.sequenceStack.InUse) 
                this.sequenceStack.contextOnTopOfStack = false;
        } 
 
        internal void Push(bool boolVal)
        { 
            this.valueStack.Push(boolVal);
        }

        internal void Push(bool boolVal, int addCount) 
        {
            this.valueStack.Push(boolVal, addCount); 
        } 

#if NO 
        internal void Push(double doubleVal)
        {
            this.valueStack.Push(doubleVal);
        } 
#endif
        internal void Push(double doubleVal, int addCount) 
        { 
            this.valueStack.Push(doubleVal, addCount);
        } 

        internal void Push(NodeSequence sequence)
        {
            this.valueStack.Push(sequence); 
        }
 
        internal void Push(NodeSequence sequence, int addCount) 
        {
            this.valueStack.Push(sequence, addCount); 
        }

        internal void Push(string stringVal)
        { 
            this.valueStack.Push(stringVal);
        } 
 
        internal void Push(string stringVal, int addCount)
        { 
            this.valueStack.Push(stringVal, addCount);
        }

        internal void PushFrame() 
        {
            this.valueStack.PushFrame(); 
        } 

        internal void PopSequenceFrameToValueStack() 
        {
            this.sequenceStack.PopSequenceFrameTo(ref this.valueStack);
            this.nodeCount = -1;
        } 

        internal void PushSequence(NodeSequence seq) 
        { 
            this.sequenceStack.Push(seq);
            this.nodeCount = -1; 
        }

        internal void PushSequenceFrame()
        { 
            this.sequenceStack.PushFrame();
            this.nodeCount = -1; 
        } 

        internal void PushContextSequenceFrame() 
        {
            if (!this.sequenceStack.InUse)
                this.sequenceStack.contextOnTopOfStack = true;
            PushSequenceFrame(); 
        }
 
        internal void PushSequenceFrameFromValueStack() 
        {
            this.valueStack.PopSequenceFrameTo(ref this.sequenceStack); 
            this.nodeCount = -1;
        }

        internal void ReleaseSequence(NodeSequence sequence) 
        {
            DiagnosticUtility.DebugAssert(null != sequence, ""); 
            if (this == sequence.OwnerContext) 
            {
                sequence.refCount--; 
                DiagnosticUtility.DebugAssert(sequence.refCount >= 0, "");
                if (0 == sequence.refCount)
                {
                    this.processor.ReleaseSequenceToPool(sequence); 
                }
            } 
        } 

        internal void Release() 
        {
            this.processor.ReleaseContext(this);
        }
 
        internal void ReplaceSequenceAt(int index, NodeSequence sequence)
        { 
            this.sequenceStack.ReplaceAt(index, sequence); 
            this.nodeCount = -1;
        } 

        internal void SaveVariable(int var, int count)
        {
            this.Processor.SaveVariable(this, var, count); 
        }
 
        internal void SetValue(ProcessingContext context, int index, bool val) 
        {
            this.valueStack.SetValue(this, index, val); 
        }

        internal void SetValue(ProcessingContext context, int index, double val)
        { 
            this.valueStack.SetValue(this, index, val);
        } 
 
        internal void SetValue(ProcessingContext context, int index, string val)
        { 
            this.valueStack.SetValue(this, index, val);
        }

        internal void SetValue(ProcessingContext context, int index, NodeSequence val) 
        {
            this.valueStack.SetValue(this, index, val); 
        } 

        internal void TransferSequenceSize() 
        {
            this.sequenceStack.TransferSequenceSizeTo(ref this.valueStack);
        }
 
        internal void TransferSequencePositions()
        { 
            this.sequenceStack.TransferPositionsTo(ref this.valueStack); 
        }
 
        #region IQueryBufferPool Members
#if NO
        public virtual void Reset()
        { 
            this.valueStack.Clear();
            this.valueStack.Trim(); 
            this.sequenceStack.Clear(); 
            this.sequenceStack.Trim();
        } 

        public virtual void Trim()
        {
            this.valueStack.Trim(); 
            this.sequenceStack.Trim();
        } 
#endif 
        #endregion
    } 

    internal enum QueryProcessingFlags : byte
    {
        None        = 0x00, 
        Match       = 0x01,
        Message     = 0x02, 
        //Select      = 0x04, 
    }
 
    internal class QueryProcessor : ProcessingContext
    {
        SeekableXPathNavigator contextNode; // original context node off which everything started
        ProcessingContext contextPool; 
        INodeCounter counter;
        QueryProcessingFlags flags; 
        QueryMatcher matcher; 
        Message message;
        bool matchMessageBody; 
        bool result; // for singleton queries...
        QueryBranchResultSet resultPool;
        Collection resultList;
        ICollection resultSet; // for inverse queries that produce multiple matches 
        NodeSequence sequencePool;
        //string selectResults; 
        SubExprVariable[] subExprVars; 
        string messageAction;
        //string messageAddress; 
        //string messageVia;
        string messageId;
        string messageSoapUri;
        string messageTo; 

        internal QueryProcessor(QueryMatcher matcher) 
            : base() 
        {
            this.Processor = this; 
            this.matcher = matcher;
            this.flags = QueryProcessingFlags.Match;

            // PERF, [....], see if we can just let these to their default init 
            this.messageAction = null;
            //this.messageAddress = null; 
            //this.messageVia = null; 
            this.messageId = null;
            this.messageSoapUri = null; 
            this.messageTo = null;

            if(matcher.SubExprVarCount > 0)
            { 
                this.subExprVars = new SubExprVariable[matcher.SubExprVarCount];
            } 
        } 

 
        internal string Action
        {
            get
            { 
                return this.messageAction;
            } 
            set 
            {
                this.messageAction = value; 
            }
        }
#if NO
        internal string Address 
        {
            get 
            { 
                return this.messageAddress;
            } 
            set
            {
                this.messageAddress = value;
            } 
        }
#endif 
        // IMPORTANT: Either ContextNode.get or CounterMarker.get MUST be called before this.counter 
        //            can be considered valid.
        internal SeekableXPathNavigator ContextNode 
        {
            get
            {
                if (null == this.contextNode) 
                {
                    if (null != this.message) 
                    { 
                        this.contextNode = this.matcher.CreateMessageNavigator(this.message, this.matchMessageBody);
                    } 
                    else
                    {
#pragma warning suppress 56503 // [....], property is more readable for this
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new QueryProcessingException(QueryProcessingError.Unexpected)); 
                    }
                    this.counter = this.contextNode as INodeCounter; 
                    if (null == this.counter) 
                    {
                        this.counter = DummyNodeCounter.Dummy; 
                    }
                }
                return this.contextNode;
            } 
            set
            { 
                this.contextNode = value; 
                this.counter = value as INodeCounter;
            } 
        }

        internal Message ContextMessage
        { 
            get
            { 
                return this.message; 
            }
            set 
            {
                this.message = value;
                if (null != value)
                { 
                    this.flags |= QueryProcessingFlags.Message;
                } 
                else 
                {
                    this.flags &= ~QueryProcessingFlags.Message; 
                }
            }
        }
 
        // IMPORTANT: Either ContextNode.get or CounterMarker.get MUST be called before this.counter
        //            can be considered valid. 
        internal int CounterMarker 
        {
            get 
            {
                if (this.counter == null)
                {
                    this.counter = this.ContextNode as INodeCounter; 
                    if (this.counter == null)
                        this.counter = DummyNodeCounter.Dummy; 
                } 
                return this.counter.CounterMarker;
            } 
            set
            {
                this.counter.CounterMarker = value;
            } 
        }
 
#if NO 
        internal QueryProcessingFlags Flags
        { 
            get
            {
                return this.flags;
            } 
        }
 
        internal bool HasContextNode 
        {
            get 
            {
                return (null != this.contextNode);
            }
        } 
#endif
 
#if FILTER_SELECT 
        internal bool IsMatch
        { 
            get
            {
                return (0 != (this.flags & QueryProcessingFlags.Match));
            } 
            set
            { 
                if (value) 
                {
                    this.flags |= QueryProcessingFlags.Match; 
                    this.IsSelect = false;
                }
                else
                { 
                    this.flags &= ~QueryProcessingFlags.Match;
                    this.resultSet = null; 
                } 
            }
        } 

        internal bool IsSelect
        {
            get 
            {
                return (0 != (this.flags & QueryProcessingFlags.Select)); 
            } 
            set
            { 
                if (value)
                {
                    this.flags |= QueryProcessingFlags.Select;
                    this.IsMatch = false; 
                }
                else 
                { 
                    this.flags &= ~QueryProcessingFlags.Select;
                } 
            }
        }
#endif
 
        internal bool MatchBody
        { 
#if NO 
            get
            { 
                return this.matchMessageBody;
            }
#endif
            set 
            {
                this.matchMessageBody = value; 
            } 
        }
 
        internal string MessageId
        {
            get
            { 
                return this.messageId;
            } 
            set 
            {
                this.messageId = value; 
            }
        }

        internal bool Result 
        {
            get 
            { 
                return this.result;
            } 
            set
            {
                this.result = value;
            } 
        }
 
        internal Collection ResultList 
        {
            get 
            {
                return this.resultList;
            }
        } 

        internal ICollection ResultSet 
        { 
            get
            { 
                return this.resultSet;
            }
            set
            { 
                this.resultSet = value;
            } 
        } 

#if FILTER_SELECT 
        internal string SelectResults
        {
            get
            { 
                return this.selectResults;
            } 
            set 
            {
                this.selectResults = value; 
            }
        }
#endif
 
        internal string SoapUri
        { 
            get 
            {
                return this.messageSoapUri; 
            }
            set
            {
                this.messageSoapUri = value; 
            }
        } 
 
        internal string ToHeader
        { 
            get
            {
                return this.messageTo;
            } 
            set
            { 
                this.messageTo = value; 
            }
        } 
#if NO
        internal string Via
        {
            get 
            {
                return this.messageVia; 
            } 
            set
            { 
                this.messageVia = value;
            }
        }
#endif 
        internal void ClearProcessor()
        { 
            base.ClearContext(); 

            this.flags = QueryProcessingFlags.Match; 

            this.messageAction = null;
            //this.messageAddress = null;
            //this.messageVia = null; 
            this.messageId = null;
            this.messageSoapUri = null; 
            this.messageTo = null; 

            int exprCount = this.matcher.SubExprVarCount; 
            if (exprCount == 0)
            {
                // No vars. Recycle entire subexpression cache
                this.subExprVars = null; 
                return;
            } 
 
            SubExprVariable[] vars = this.subExprVars; // save locally for speed
            if (vars == null) 
            {
                // Allocate space for sub-expressions
                this.subExprVars = new SubExprVariable[exprCount];
                return; 
            }
 
            int varCount = vars.Length; 
            // The # of subexpressions changed since this processor was last used.
            if (varCount != exprCount) 
            {
                this.subExprVars = new SubExprVariable[exprCount];
                return;
            } 

            if (varCount == 1) 
            { 
                NodeSequence seq = vars[0].seq;
                if (seq != null) 
                {
                    this.ReleaseSequenceToPool(seq);
                }
                return; 
            }
 
            // We can reuse the sub-expression cache 
            // Clear out the sub-expression results from an earlier run, and return sequences to pool
            for (int i = 0; i < varCount; ++i) 
            {
                NodeSequence seq = vars[i].seq;
                if (seq != null && seq.refCount > 0)
                { 
                    this.ReleaseSequenceToPool(seq);
                } 
            } 
            Array.Clear(vars, 0, vars.Length);
        } 

        internal ProcessingContext CloneContext(ProcessingContext srcContext)
        {
            ProcessingContext context = this.PopContext(); 
            if (null == context)
            { 
                context = new ProcessingContext(); 
            }
            context.CopyFrom(srcContext); 

            return context;
        }
 
        internal QueryBranchResultSet CreateResultSet()
        { 
            QueryBranchResultSet resultSet = this.PopResultSet(); 
            if (null == resultSet)
            { 
                resultSet = new QueryBranchResultSet();
            }
            else
            { 
                resultSet.Clear();
            } 
            return resultSet; 
        }
 
        internal int ElapsedCount(int marker)
        {
            return this.counter.ElapsedCount(marker);
        } 

        internal void EnsureFilterCollection() 
        { 
            if (null == this.resultSet)
            { 
                if (null == this.resultList)
                {
                    this.resultList = new Collection();
                } 
                else
                { 
                    this.resultList.Clear(); 
                }
                this.resultSet = this.resultList; 
            }
        }

        internal void Eval(Opcode block) 
        {
            Opcode op = block; 
            try 
            {
                // Walk over and evaulate the entire trace 
                while (null != op)
                {
                    op = op.Eval(this);
                } 
            }
            catch(XPathNavigatorException e) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(op));
            } 
            catch(NavigatorInvalidBodyAccessException e)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(op));
            } 
        }
 
        internal void Eval(Opcode block, ProcessingContext context) 
        {
            Opcode op = block; 
            try
            {
                // Walk over and evaulate the entire trace
                while (null != op) 
                {
                    op = op.Eval(context); 
                } 
            }
            catch(XPathNavigatorException e) 
            {
                throw TraceUtility.ThrowHelperError(e.Process(op), this.message);
            }
            catch(NavigatorInvalidBodyAccessException e) 
            {
                throw TraceUtility.ThrowHelperError(e.Process(op), this.message); 
            } 
        }
 
        //
        // Set up the query processor to match messages
        //
        internal void Eval(Opcode block, Message message, bool matchBody) 
        {
            this.result = false; 
            this.ContextNode = null; 
            this.ContextMessage = message;
            this.MatchBody = matchBody; 
            this.Eval(block);
            this.message = null;
            this.contextNode = null;
        } 

        internal void Eval(Opcode block, SeekableXPathNavigator navigator) 
        { 
            this.result = false;
            this.ContextNode = navigator; 
            this.ContextMessage = null;
            this.Eval(block);
        }
 
        internal bool LoadVariable(ProcessingContext context, int var)
        { 
            if(this.subExprVars[var].seq == null) 
            {
                return false; 
            }

            int iter = context.IterationCount;
            this.counter.IncreaseBy(iter * this.subExprVars[var].count); 

            NodeSequence seq = this.subExprVars[var].seq; 
            context.PushSequenceFrame(); 
            for(int i = 0; i < iter; ++i)
            { 
                seq.refCount++;
                context.PushSequence(seq);
            }
 
            return true;
        } 
 
        internal ProcessingContext PopContext()
        { 
            ProcessingContext context = this.contextPool;
            if (null != context)
            {
                this.contextPool = context.Next; 
                context.Next = null;
            } 
            return context; 
        }
 
        internal NodeSequence PopSequence()
        {
            NodeSequence sequence = this.sequencePool;
            if (null != sequence) 
            {
                this.sequencePool = sequence.Next; 
                sequence.Next = null; 
            }
            return sequence; 
        }

        internal QueryBranchResultSet PopResultSet()
        { 
            QueryBranchResultSet resultSet = this.resultPool;
            if (null != resultSet) 
            { 
                this.resultPool = resultSet.Next;
                resultSet.Next = null; 
            }
            return resultSet;
        }
 
        internal void PushContext(ProcessingContext context)
        { 
            DiagnosticUtility.DebugAssert(null != context, ""); 

            context.Next = this.contextPool; 
            this.contextPool = context;
        }

        internal void PushResultSet(QueryBranchResultSet resultSet) 
        {
            DiagnosticUtility.DebugAssert(null != resultSet, ""); 
 
            resultSet.Next = this.resultPool;
            this.resultPool = resultSet; 
        }

        internal void ReleaseContext(ProcessingContext context)
        { 
            DiagnosticUtility.DebugAssert(null != context, "");
            this.PushContext(context); 
        } 

        internal void ReleaseResults(QueryBranchResultSet resultSet) 
        {
            DiagnosticUtility.DebugAssert(null != resultSet, "");
            this.PushResultSet(resultSet);
        } 

        internal void ReleaseSequenceToPool(NodeSequence sequence) 
        { 
            if (NodeSequence.Empty != sequence)
            { 
                sequence.Reset(this.sequencePool);
                this.sequencePool = sequence;
            }
        } 

        internal void SaveVariable(ProcessingContext context, int var, int count) 
        { 
            NodeSequence seq = context.Sequences[context.TopSequenceArg.basePtr].Sequence;
            if (seq == null) 
                seq = CreateSequence();
            seq.OwnerContext = null;
            this.subExprVars[var].seq = seq;
            this.subExprVars[var].count = count; 
        }
 
        #region IQueryBufferPool Members 
#if NO
        public override void Reset() 
        {
            base.Release();
            // Trim local pools by releasing all references
            while (null != this.PopResultSet()); 
            this.resultPool = null;
            while (null != this.PopSequence()); 
            this.sequencePool = null; 
            while (null != this.PopContext());
            this.contextPool = null; 
        }

        public override void Trim()
        { 
            // Trim stacks
            base.Trim(); 
            // Trim local pools individually 
            QueryBranchResultSet result = this.resultPool;
            while (null != result) 
            {
                result.Trim();
                result = result.Next;
            } 
            NodeSequence sequence = this.sequencePool;
            while (null != sequencePool) 
            { 
                sequencePool.Trim();
                sequence = sequence.Next; 
            }
            ProcessingContext context = this.contextPool;
            while (null != context)
            { 
                context.Trim();
                context = context.Next; 
            } 
        }
#endif 
        #endregion

        struct SubExprVariable
        { 
            internal NodeSequence seq;
            internal int count; 
        } 
    }
 

#if NO
    internal struct QueryStatistics
    { 
        int backupCapacity;
 
        int nodeCapacity; 

        int seqStackCapacity; 

        int seqFrameCapacity;

        int valFrameCapacity; 

        int valStackCapacity; 
 
        internal QueryStatistics()
        { 
            this.backupCapacity = 8;
            this.nodeCapacity = 8;
            this.seqFrameCapacity = 2;
            this.seqStackCapacity = 4; 
            this.valFrameCapacity = 2;
            this.valStackCapacity = 4; 
        } 

        internal int BackupCapacity 
        {
            get
            {
                return this.backupCapacity; 
            }
        } 
 
        internal int NodeCapacity
        { 
            get
            {
                return this.nodeCapacity;
            } 
        }
 
        internal int SeqFrameCapacity 
        {
            get 
            {
                return this.seqFrameCapacity;
            }
        } 

        internal int SeqStackCapacity 
        { 
            get
            { 
                return this.seqStackCapacity;
            }
        }
 
        internal int ValFrameCapacity
        { 
            get 
            {
                return this.valFrameCapacity; 
            }
        }

        internal int ValStackCapacity 
        {
            get 
            { 
                return this.valStackCapacity;
            } 
        }
    }
#endif
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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