QueryIntervalOp.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 / QueryIntervalOp.cs / 1 / QueryIntervalOp.cs

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

    // Based on the Paper: The IBS Tree: A Datastructure for finding all intervals that overlap a point.
    // by Eric Hanson & Moez Chaabouni, Nov, 1994
 
    internal enum IntervalOp : byte
    { 
        LessThan, 
        LessThanEquals
    } 

    internal class Interval
    {
        QueryBranch branch; 
        double lowerBound;
        IntervalOp lowerOp; 
        double upperBound; 
        IntervalOp upperOp;
 
        // Converts expressions of the form:
        // x < 5 => -infinity <= x and x < 5
        // x <= 5 => -infinity <= x and x <= 5
        // x > 5 => 5 < x <= infinity 
        // x >= 5 => 5 <= x <= infinity
        // 
        // The variable is always to the left 
        internal Interval(double literal, RelationOperator op)
        { 
            this.lowerBound = double.MinValue;
            this.upperBound = double.MaxValue;
            this.lowerOp = IntervalOp.LessThanEquals;
            this.upperOp = IntervalOp.LessThanEquals; 

            DiagnosticUtility.DebugAssert(RelationOperator.Eq != op && RelationOperator.Ne != op, ""); 
            switch (op) 
            {
                case RelationOperator.Lt: 
                    this.upperBound = literal;
                    this.upperOp = IntervalOp.LessThan;
                    break;
                case RelationOperator.Le: 
                    this.upperBound = literal;
                    break; 
                case RelationOperator.Gt: 
                    this.lowerBound = literal;
                    this.lowerOp = IntervalOp.LessThan; 
                    break;
                case RelationOperator.Ge:
                    this.lowerBound = literal;
                    break; 
            }
        } 
 
#if NO
        internal Interval(double lowerBound, IntervalOp lowerOp, double upperBound, IntervalOp upperOp) 
        {
            DiagnosticUtility.DebugAssert(lowerBound <= upperBound, "");

            this.lowerBound = lowerBound; 
            this.upperBound = upperBound;
            if (this.lowerBound == this.upperBound) 
            { 
                this.lowerOp = IntervalOp.LessThanEquals;
                this.upperOp = IntervalOp.LessThanEquals; 
            }
            else
            {
                this.lowerOp = lowerOp; 
                this.upperOp = upperOp;
            } 
        } 
#endif
        internal QueryBranch Branch 
        {
            get
            {
                return this.branch; 
            }
            set 
            { 
                this.branch = value;
            } 
        }

        internal double LowerBound
        { 
            get
            { 
                return this.lowerBound; 
            }
        } 

        internal IntervalOp LowerOp
        {
            get 
            {
                return this.lowerOp; 
            } 
        }
 
        internal double UpperBound
        {
            get
            { 
                return this.upperBound;
            } 
        } 

        internal IntervalOp UpperOp 
        {
            get
            {
                return this.upperOp; 
            }
        } 
 
#if NO
        internal bool Equals(Interval interval) 
        {
            DiagnosticUtility.DebugAssert(null != interval, "");
            return this.Equals(interval.lowerBound, interval.lowerOp, interval.upperBound, interval.upperOp);
        } 
#endif
        internal bool Equals(double lowerBound, IntervalOp lowerOp, double upperBound, IntervalOp upperOp) 
        { 
            return (this.lowerBound == lowerBound && this.lowerOp == lowerOp && this.upperBound == upperBound && this.upperOp == upperOp);
        } 

        internal bool HasMatchingEndPoint(double endpoint)
        {
            return (this.lowerBound == endpoint || this.upperBound == endpoint); 
        }
    } 
 
    /// 
    /// IntervalCollection 
    /// All Contains/Find operations are currently linear, since they are required only during
    /// Inserts/Removes from the Interval Tree, which is not anticipated to be performance critical.
    /// 
    internal class IntervalCollection : ArrayList 
    {
        internal IntervalCollection() 
            : base(1) 
        {
        } 

        internal bool HasIntervals
        {
            get 
            {
                return (this.Count > 0); 
            } 
        }
 
        internal new Interval this[int index]
        {
            get
            { 
                return (Interval) base[index];
            } 
        } 

        internal int Add(Interval interval) 
        {
            DiagnosticUtility.DebugAssert(null != interval, "");
            this.Capacity = this.Count + 1;
            return base.Add(interval); 
        }
 
        internal int AddUnique(Interval interval) 
        {
            DiagnosticUtility.DebugAssert(null != interval, ""); 
            int index = this.IndexOf(interval);
            if (-1 == index)
            {
                return this.Add(interval); 
            }
            return index; 
        } 

        internal IntervalCollection GetIntervalsWithEndPoint(double endPoint) 
        {
            IntervalCollection matches = new IntervalCollection();

            int count = this.Count; 
            for (int i = 0; i < count; ++i)
            { 
                Interval interval = this[i]; 
                if (interval.HasMatchingEndPoint(endPoint))
                { 
                    matches.Add(interval);
                }
            }
 
            return matches;
        } 
 
        internal int IndexOf(Interval interval)
        { 
            DiagnosticUtility.DebugAssert(null != interval, "");
            return base.IndexOf(interval);
        }
 
        internal int IndexOf(double endPoint)
        { 
            int count = this.Count; 
            for (int i = 0; i < count; ++i)
            { 
                Interval interval = this[i];
                if (interval.HasMatchingEndPoint(endPoint))
                {
                    return i; 
                }
            } 
 
            return -1;
        } 

        internal int IndexOf(double lowerBound, IntervalOp lowerOp, double upperBound, IntervalOp upperOp)
        {
            int count = this.Count; 
            for (int i = 0; i < count; ++i)
            { 
                if (this[i].Equals(lowerBound, lowerOp, upperBound, upperOp)) 
                {
                    return i; 
                }
            }
            return -1;
        } 

        internal void Remove(Interval interval) 
        { 
            DiagnosticUtility.DebugAssert(null != interval, "");
            base.Remove(interval); 
            this.TrimToSize();
        }

        internal void Trim() 
        {
            this.TrimToSize(); 
        } 
    }
 
    internal class IntervalBoundary
    {
        IntervalCollection eqSlot;
        IntervalCollection gtSlot; 
        IntervalBoundary left;
        IntervalCollection ltSlot; 
        IntervalBoundary parent; 
        IntervalBoundary right;
        double val; 

        internal IntervalBoundary(double val, IntervalBoundary parent)
        {
            this.val = val; 
            this.parent = parent;
        } 
 
        internal IntervalCollection EqSlot
        { 
            get
            {
                return this.eqSlot;
            } 
        }
 
        internal IntervalCollection GtSlot 
        {
            get 
            {
                return this.gtSlot;
            }
        } 

        internal IntervalBoundary Left 
        { 
            get
            { 
                return this.left;
            }
            set
            { 
                this.left = value;
            } 
        } 

        internal IntervalCollection LtSlot 
        {
            get
            {
                return this.ltSlot; 
            }
        } 
 
        internal IntervalBoundary Parent
        { 
            get
            {
                return this.parent;
            } 
            set
            { 
                this.parent = value; 
            }
        } 

        internal IntervalBoundary Right
        {
            get 
            {
                return this.right; 
            } 
            set
            { 
                this.right = value;
            }
        }
 
        internal double Value
        { 
            get 
            {
                return this.val; 
            }
            set
            {
                this.val = value; 
            }
        } 
 
        internal void AddToEqSlot(Interval interval)
        { 
            DiagnosticUtility.DebugAssert(null != interval, "");
            this.AddToSlot(ref this.eqSlot, interval);
        }
 
        internal void AddToGtSlot(Interval interval)
        { 
            DiagnosticUtility.DebugAssert(null != interval, ""); 
            this.AddToSlot(ref this.gtSlot, interval);
        } 

        internal void AddToLtSlot(Interval interval)
        {
            DiagnosticUtility.DebugAssert(null != interval, ""); 
            this.AddToSlot(ref this.ltSlot, interval);
        } 
 
        void AddToSlot(ref IntervalCollection slot, Interval interval)
        { 
            if (null == slot)
            {
                slot = new IntervalCollection();
            } 
            slot.AddUnique(interval);
        } 
 
        internal IntervalBoundary EnsureLeft(double val)
        { 
            if (null == this.left)
            {
                this.left = new IntervalBoundary(val,this);
            } 

            return this.left; 
        } 

        internal IntervalBoundary EnsureRight(double val) 
        {
            if (null == this.right)
            {
                this.right = new IntervalBoundary(val, this); 
            }
 
            return this.right; 
        }
#if NO 
        internal Interval GetInterval(double lowerBound, IntervalOp lowerOp, double upperBound, IntervalOp upperOp)
        {
            Interval interval;
            if ( 
                null != (interval = this.GetIntervalFromSlot(this.eqSlot, lowerBound, lowerOp, upperBound, upperOp))
                || null != (interval = this.GetIntervalFromSlot(this.ltSlot, lowerBound, lowerOp, upperBound, upperOp)) 
                || null != (interval = this.GetIntervalFromSlot(this.gtSlot, lowerBound, lowerOp, upperBound, upperOp)) 
                )
            { 
                return interval;
            }

            return null; 
        }
 
        internal Interval GetIntervalByData(object data) 
        {
            Interval interval; 
            if (
                null != (interval = this.GetIntervalFromSlot(this.eqSlot, data))
                || null != (interval = this.GetIntervalFromSlot(this.ltSlot, data))
                || null != (interval = this.GetIntervalFromSlot(this.gtSlot, data)) 
                )
            { 
                return interval; 
            }
 
            return null;
        }

        Interval GetIntervalFromSlot(IntervalCollection slot, object data) 
        {
            int index; 
            if (null != slot && -1 != (index = slot.IndexOf(data))) 
            {
                return slot[index]; 
            }
            return null;
        }
 
        Interval GetIntervalFromSlot(IntervalCollection slot, double lowerBound, IntervalOp lowerOp, double upperBound, IntervalOp upperOp)
        { 
            int index; 
            if (null != slot && -1 != (index = slot.IndexOf(lowerBound, lowerOp, upperBound, upperOp)))
            { 
                return slot[index];
            }
            return null;
        } 
#endif
        internal void RemoveFromEqSlot(Interval interval) 
        { 
            DiagnosticUtility.DebugAssert(null != interval, "");
            this.RemoveFromSlot(ref this.eqSlot, interval); 
        }

        internal void RemoveFromGtSlot(Interval interval)
        { 
            DiagnosticUtility.DebugAssert(null != interval, "");
            this.RemoveFromSlot(ref this.gtSlot, interval); 
        } 

        internal void RemoveFromLtSlot(Interval interval) 
        {
            DiagnosticUtility.DebugAssert(null != interval, "");
            this.RemoveFromSlot(ref this.ltSlot, interval);
        } 

        void RemoveFromSlot(ref IntervalCollection slot, Interval interval) 
        { 
            if (null != slot)
            { 
                slot.Remove(interval);
                if (!slot.HasIntervals)
                {
                    slot = null; 
                }
            } 
        } 

        internal void Trim() 
        {
            if(this.eqSlot != null)
            {
                this.eqSlot.Trim(); 
            }
 
            if(this.gtSlot != null) 
            {
                this.gtSlot.Trim(); 
            }

            if(this.ltSlot != null)
            { 
                this.ltSlot.Trim();
            } 
 
            if(this.left != null)
            { 
                this.left.Trim();
            }

            if(this.right != null) 
            {
                this.right.Trim(); 
            } 
        }
    } 

    internal struct IntervalTreeTraverser
    {
        IntervalBoundary currentNode; 
        IntervalBoundary nextNode;
        IntervalCollection slot; 
        double val; 

        internal IntervalTreeTraverser(double val, IntervalBoundary root) 
        {
            DiagnosticUtility.DebugAssert(null != root, "");
            this.currentNode = null;
            this.slot = null; 
            this.nextNode = root;
            this.val = val; 
        } 

        internal IntervalCollection Slot 
        {
            get
            {
                return this.slot; 
            }
        } 
 
        internal bool MoveNext()
        { 
            while (null != this.nextNode)
            {
                this.currentNode = this.nextNode;
                double currentVal = this.currentNode.Value; 
                if (val < currentVal)
                { 
                    this.slot = this.currentNode.LtSlot; 
                    this.nextNode = this.currentNode.Left;
                } 
                else if (val > currentVal)
                {
                    this.slot = this.currentNode.GtSlot;
                    this.nextNode = this.currentNode.Right; 
                }
                else 
                { 
                    this.slot = this.currentNode.EqSlot;
                    this.nextNode = null; 
                }
                if (null != this.slot)
                {
                    return true; 
                }
            } 
 
            return false;
        } 
    }

    internal class IntervalTree
    { 
        IntervalCollection intervals;
        IntervalBoundary root; 
 
        internal IntervalTree()
        { 
        }

        internal int Count
        { 
            get
            { 
                return (null != this.intervals) ? this.intervals.Count : 0; 
            }
        } 

        internal IntervalCollection Intervals
        {
            get 
            {
                if (null == this.intervals) 
                { 
                    return new IntervalCollection();
                } 
                return this.intervals;
            }
        }
 
#if NO
        internal bool IsEmpty 
        { 
            get
            { 
                return (this.root == null);
            }
        }
#endif 
        internal IntervalBoundary Root
        { 
            get 
            {
                return this.root; 
            }
        }

        internal void Add(Interval interval) 
        {
            DiagnosticUtility.DebugAssert(null != interval, ""); 
 
            this.AddIntervalToTree(interval);
            this.EnsureIntervals(); 
            this.intervals.Add(interval);
        }

        void AddIntervalToTree(Interval interval) 
        {
            this.EditLeft(interval, true); 
            this.EditRight(interval, true); 
        }
 
#if NO
        internal bool Contains(double lowerBound, IntervalOp lowerOp, double upperBound, IntervalOp upperOp)
        {
            if (null != this.intervals) 
            {
                return (this.intervals.IndexOf(lowerBound, lowerOp, upperBound, upperOp) >= 0); 
            } 

            return false; 
        }
#endif
        void EditLeft(Interval interval, bool add)
        { 
            if (add)
            { 
                this.EnsureRoot(interval.LowerBound); 
            }
 
            IntervalBoundary root = this.root;
            IntervalBoundary leftAncestor = null;

            while (true) 
            {
                double rootVal = root.Value; 
 
                if (rootVal < interval.LowerBound)
                { 
                    // root is outside the interval range because it is < the lower bound
                    root = add ? root.EnsureRight(interval.LowerBound) : root.Right;
                    continue;
                } 

                // rootVal is >= to interval.lowerBound 
                // 
                // All values in thee subtree at 'root' are < leftAncestor.Value
                // All values to the left of this node cannot be in the interval because they are < the interval's 
                // lower bound.
                // Values to the right of this node lie in range (root.Value to leftAncestor.Value)
                // Thus, the entire right subtree of root will be inside the range if the interval.upperBound
                // is >= leftAncestor.Value 
                if (null != leftAncestor && leftAncestor.Value <= interval.UpperBound)
                { 
                    if (add) 
                    {
                        root.AddToGtSlot(interval); 
                    }
                    else
                    {
                        root.RemoveFromGtSlot(interval); 
                    }
                } 
 
                if (rootVal > interval.LowerBound)
                { // This node itself lies in the range if it is also < the upper bound 
                    if (rootVal < interval.UpperBound)
                    {
                        if (add)
                        { 
                            root.AddToEqSlot(interval);
                        } 
                        else 
                        {
                            root.RemoveFromEqSlot(interval); 
                        }
                    }
                    leftAncestor = root;
                    root = add ? root.EnsureLeft(interval.LowerBound) : root.Left; 
                    continue;
                } 
 
                // lowerBound == rootVal. We're done.
                if (IntervalOp.LessThanEquals == interval.LowerOp) 
                {
                    // If the range is inclusive of the lower bound (>=), then since this node == lowerBound,
                    // it must be in the range.
                    if (add) 
                    {
                        root.AddToEqSlot(interval); 
                    } 
                    else
                    { 
                        root.RemoveFromEqSlot(interval);
                    }
                }
                break; 
            }
        } 
 
        void EditRight(Interval interval, bool add)
        { 
            if (add)
            {
                this.EnsureRoot(interval.UpperBound);
            } 

            IntervalBoundary root = this.root; 
            IntervalBoundary rightAncestor = null; 

            while (true) 
            {
                double rootVal = root.Value;

                if (rootVal > interval.UpperBound) 
                {
                    // root is outside the interval range because it is > the upper bound 
                    root = add ? root.EnsureLeft(interval.UpperBound) : root.Left; 
                    continue;
                } 

                // rootVal is <= to interval.UpperBound
                //
                // All values in the subtree at 'root' are > leftAncestor.Value 
                // All values to the right of this node cannot be in the interval because they are > the interval's
                // upper bound. 
                // Values to the left of this node lie in range (rightAncestor.Value to root.Value) 
                // Thus, the entire left subtree of root will be inside the range if the interval.lowerBound
                // is <= rightAncestor.Value 
                if (null != rightAncestor && rightAncestor.Value >= interval.LowerBound)
                {
                    if (add)
                    { 
                        root.AddToLtSlot(interval);
                    } 
                    else 
                    {
                        root.RemoveFromLtSlot(interval); 
                    }
                }

                if (rootVal < interval.UpperBound) 
                {
                    // This node itself lies in the range if it is also > the lower bound 
                    if (rootVal > interval.LowerBound) 
                    {
                        if (add) 
                        {
                            root.AddToEqSlot(interval);
                        }
                        else 
                        {
                            root.RemoveFromEqSlot(interval); 
                        } 
                    }
                    rightAncestor = root; 
                    root = add ? root.EnsureRight(interval.UpperBound) : root.Right;
                    continue;
                }
 
                // upperBound == rootVal. We're done.
                // If upperBound == lowerBound, we already inserted this when doing AddLeft 
                if (IntervalOp.LessThanEquals == interval.UpperOp) 
                {
                    // If the range is inclusive of the upper bound, then since this node == upperBound, 
                    // it must be in the range.
                    if (add)
                    {
                        root.AddToEqSlot(interval); 
                    }
                    else 
                    { 
                        root.RemoveFromEqSlot(interval);
                    } 
                }
                break;
            }
        } 

        void EnsureIntervals() 
        { 
            if (null == this.intervals)
            { 
                this.intervals = new IntervalCollection();
            }
        }
 
        void EnsureRoot(double val)
        { 
            if (null == this.root) 
            {
                this.root = new IntervalBoundary(val, null); 
            }
        }

        internal IntervalBoundary FindBoundaryNode(double val) 
        {
            return this.FindBoundaryNode(root, val); 
        } 

        internal IntervalBoundary FindBoundaryNode(IntervalBoundary root, double val) 
        {
            IntervalBoundary boundary = null;
            if (null != root)
            { 
                if (root.Value == val)
                { 
                    boundary = root; 
                }
                else 
                {
                    if (null == (boundary = this.FindBoundaryNode(root.Left, val)))
                    {
                        boundary = this.FindBoundaryNode(root.Right, val); 
                    }
                } 
            } 
            return boundary;
        } 

        internal Interval FindInterval(Interval interval)
        {
            return this.FindInterval(interval.LowerBound, interval.LowerOp, interval.UpperBound, interval.UpperOp); 
        }
 
        internal Interval FindInterval(double lowerBound, IntervalOp lowerOp, double upperBound, IntervalOp upperOp) 
        {
            if (null != this.intervals) 
            {
                int index;
                if (-1 != (index = this.intervals.IndexOf(lowerBound, lowerOp, upperBound, upperOp)))
                { 
                    return this.intervals[index];
                } 
            } 
            return null;
        } 

        /// 
        /// An interval has been removed. Prune the tree appropriately
        ///  
        /// interval that was removed
        void PruneTree(Interval intervalRemoved) 
        { 
            // Delete endpoints if no other intervals have them
            int index; 
            if (-1 == (index = this.intervals.IndexOf(intervalRemoved.LowerBound)))
            {
                this.RemoveBoundary(this.FindBoundaryNode(intervalRemoved.LowerBound));
            } 
            if (intervalRemoved.LowerBound != intervalRemoved.UpperBound && -1 == (index = this.intervals.IndexOf(intervalRemoved.UpperBound)))
            { 
                this.RemoveBoundary(this.FindBoundaryNode(intervalRemoved.UpperBound)); 
            }
        } 

        internal void Remove(Interval interval)
        {
            DiagnosticUtility.DebugAssert(null != interval, ""); 
            DiagnosticUtility.DebugAssert(null != this.intervals, "");
 
            // First, delete all occurences of interval in the tree. Note: we do a reference equals 
            this.RemoveIntervalFromTree(interval);
            // Remove interval from interval collection 
            this.intervals.Remove(interval);
            // It may be possible to prune the tree.. this will do the necessary, if required
            this.PruneTree(interval);
        } 

        void RemoveBoundary(IntervalBoundary boundary) 
        { 
            IntervalCollection replacementIntervals = null;
            int replacementCount = 0; 

            if (null != boundary.Left && null != boundary.Right)
            {
                // Neither left/right are null. Typical binary tree node removal - replace the removed node 
                // with the symmetric order predecessor
                IntervalBoundary replacement = boundary.Left; 
                while (null != replacement.Right) 
                {
                    replacement = replacement.Right; 
                }
                // Find all intervals with endpoint y in the tree
                replacementIntervals = this.intervals.GetIntervalsWithEndPoint(replacement.Value);
 
                // Remove the intervals from the tree
                replacementCount = replacementIntervals.Count; 
                for (int i = 0; i < replacementCount; ++i) 
                {
                    this.RemoveIntervalFromTree(replacementIntervals[i]); 
                }

                double val = boundary.Value;
                boundary.Value = replacement.Value; 
                replacement.Value = val;
                boundary = replacement; 
            } 

            if (null != boundary.Left) 
            {
                this.Replace(boundary, boundary.Left);
            }
            else 
            {
                this.Replace(boundary, boundary.Right); 
            } 

            // Discard the node 
            boundary.Parent = null;
            boundary.Left = null;
            boundary.Right = null;
 
            // Reinstall Intervals
            for (int i = 0; i < replacementCount; ++i) 
            { 
                this.AddIntervalToTree(replacementIntervals[i]);
            } 
        }

        void RemoveIntervalFromTree(Interval interval)
        { 
            this.EditLeft(interval, false);
            this.EditRight(interval, false); 
        } 

        void Replace(IntervalBoundary replace, IntervalBoundary with) 
        {
            IntervalBoundary parent = replace.Parent;
            if (null != parent)
            { 
                if (replace == parent.Left)
                { 
                    parent.Left = with; 
                }
                else if (replace == parent.Right) 
                {
                    parent.Right = with;
                }
            } 
            else
            { 
                // Replacing root 
                this.root = with;
            } 
            if (null != with)
            {
                with.Parent = parent;
            } 
        }
 
        internal void Trim() 
        {
            this.intervals.Trim(); 
            this.root.Trim();
        }
    }
 
    internal class NumberRelationOpcode : LiteralRelationOpcode
    { 
        double literal; 
        RelationOperator op;
 
        internal NumberRelationOpcode(double literal, RelationOperator op)
            : this(OpcodeID.NumberRelation, literal, op)
        {
        } 

        protected NumberRelationOpcode(OpcodeID id, double literal, RelationOperator op) 
            : base(id) 
        {
            this.literal = literal; 
            this.op = op;
        }
#if NO
        internal override ValueDataType DataType 
        {
            get 
            { 
                return ValueDataType.Double;
            } 
        }
#endif

        internal override object Literal 
        {
            get 
            { 
                return this.literal;
            } 
        }
#if NO
        internal RelationOperator Op
        { 
            get
            { 
                return this.op; 
            }
        } 
#endif
        internal override bool Equals(Opcode opcode)
        {
            if (base.Equals (opcode)) 
            {
                NumberRelationOpcode numOp = (NumberRelationOpcode) opcode; 
                return (numOp.op == this.op && numOp.literal == this.literal); 
            }
 
            return false;
        }

        internal override Opcode Eval(ProcessingContext context) 
        {
            Value[] values = context.Values; 
            StackFrame arg = context.TopArg; 

            for (int i = arg.basePtr; i <= arg.endPtr; ++i) 
            {
                values[i].Update(context, values[i].CompareTo(this.literal, op));
            }
            return this.next; 
        }
 
        internal Interval ToInterval() 
        {
            return new Interval(this.literal, this.op); 
        }
    }

    internal class NumberIntervalOpcode : NumberRelationOpcode 
    {
        Interval interval; 
 
        internal NumberIntervalOpcode(double literal, RelationOperator op)
            : base(OpcodeID.NumberInterval, literal, op) 
        {
        }

        internal override object Literal 
        {
            get 
            { 
                if (null == this.interval)
                { 
                    this.interval = this.ToInterval();
                }

                return this.interval; 
            }
        } 
 
        internal override void Add(Opcode op)
        { 
            NumberIntervalOpcode intervalOp = op as NumberIntervalOpcode;
            if (null == intervalOp)
            {
                base.Add(op); 
                return;
            } 
 
            DiagnosticUtility.DebugAssert(null != this.prev, "");
 
            NumberIntervalBranchOpcode branch = new NumberIntervalBranchOpcode();
            this.prev.Replace(this, branch);
            branch.Add(this);
            branch.Add(intervalOp); 
        }
    } 
 
    internal class IntervalBranchIndex : QueryBranchIndex
    { 
        IntervalTree intervalTree;

        internal IntervalBranchIndex()
        { 
            this.intervalTree = new IntervalTree();
        } 
 
        internal override int Count
        { 
            get
            {
                return this.intervalTree.Count;
            } 
        }
 
        internal override QueryBranch this[object key] 
        {
            get 
            {
                Interval interval = this.intervalTree.FindInterval((Interval) key);
                if (null != interval)
                { 
                    return interval.Branch;
                } 
                return null; 
            }
            set 
            {
                Interval interval = (Interval) key;
                interval.Branch = value;
                this.intervalTree.Add(interval); 
            }
        } 
 
        internal override void CollectXPathFilters(ICollection filters)
        { 
            for(int i = 0; i < this.intervalTree.Intervals.Count; ++i)
            {
                this.intervalTree.Intervals[i].Branch.Branch.CollectXPathFilters(filters);
            } 
        }
 
#if NO 

        internal override IEnumerator GetEnumerator() 
        {
            return this.intervalTree.Intervals.GetEnumerator();
        }
 
#endif
 
        void Match(int valIndex, double point, QueryBranchResultSet results) 
        {
            IntervalTreeTraverser traverser = new IntervalTreeTraverser(point, this.intervalTree.Root); 
            while (traverser.MoveNext())
            {
                IntervalCollection matches = traverser.Slot;
                for (int i = 0, count = matches.Count; i < count; ++i) 
                {
                    QueryBranch branch = matches[i].Branch; 
                    if (null != branch) 
                    {
                        results.Add(branch, valIndex); 
                    }
                }
            }
        } 

        internal override void Match(int valIndex, ref Value val, QueryBranchResultSet results) 
        { 
            if (ValueDataType.Sequence == val.Type)
            { 
                NodeSequence sequence = val.Sequence;
                for (int i = 0; i < sequence.Count; ++i)
                {
                    this.Match(valIndex, sequence.Items[i].NumberValue(), results); 
                }
            } 
            else 
            {
                this.Match(valIndex, val.ToDouble(), results); 
            }
        }

        internal override void Remove(object key) 
        {
            this.intervalTree.Remove((Interval) key); 
        } 

        internal override void Trim() 
        {
            this.intervalTree.Trim();
        }
    } 

    internal class NumberIntervalBranchOpcode : QueryConditionalBranchOpcode 
    { 
        internal NumberIntervalBranchOpcode()
            : base(OpcodeID.NumberIntervalBranch, new IntervalBranchIndex()) 
        {
        }

        internal override LiteralRelationOpcode ValidateOpcode(Opcode opcode) 
        {
            NumberIntervalOpcode numOp = opcode as NumberIntervalOpcode; 
            if (null != numOp) 
            {
                return numOp; 
            }

            return null;
        } 

    } 
} 

// 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