Example #1
0
        ///<summary>
        /// Create a range facet attribute.
        ///</summary>
        ///<param name="name">the name of the facet attribute.</param>
        ///<param name="facets">The facets in this attribute.</param>
        ///<param name="descriptions">Descriptions mapped from locales for the attribute.</param>
        ///<param name="defaultLocale">The default locale for descriptions.</param>
        public RangeFacetAttribute(String name, IEnumerable <IFacet> facets, Dictionary <string, string> descriptions, string defaultLocale) :
            base(name, facets, descriptions, defaultLocale)
        {
            int count = 0;

            foreach (IFacet f in facets)
            {
                _ordinals[f.Key] = count++;
            }
            _rc = new RangeComparer(_ordinals);
        }
Example #2
0
    ///<summary>Enumerates the tree nodes whose aggregate from left to right is within the given range.</summary>
    public IEnumerable <Tuple <TKey, TVal, TAggregate> > Range(RangeComparer <Tuple <TKey, TVal, TAggregate> > range = null)
    {
        if (_root.IsNilLeaf)
        {
            yield break;
        }
        range = range ?? (e => 0);

        // recursive enumeration rewritten to use an explicit stack
        // (to avoid iterator methods using yield must do work for each recursive level for each item, due to how they are implemented)
        var callStack = new Stack <Tuple <LeafwardNode, bool, TAggregate> >();

        callStack.Push(Tuple.Create(_root, true, default(TAggregate)));
        while (callStack.Count > 0)
        {
            var item           = callStack.Pop();
            var node           = item.Item1;
            var exploreVsYield = item.Item2;
            var leftOverhead   = item.Item3;
            if (node.IsNilLeaf)
            {
                continue;
            }

            var leftOverheadForRightChild = _aggregator(leftOverhead, node.Data.Key, node.Data.Val, node.Left.Aggregate);
            var cur = Tuple.Create(node.Data.Key, node.Data.Val, leftOverheadForRightChild);
            if (exploreVsYield)
            {
                var c = range(cur);
                // schedule recurse right when current node is below range maximum
                if (c <= 0)
                {
                    callStack.Push(Tuple.Create(node.Right, true, leftOverheadForRightChild));
                }
                // schedule yield self when current node is in range
                if (c == 0)
                {
                    callStack.Push(Tuple.Create(node, false, leftOverhead));
                }
                // schedule recurse left when current node is below range minimum
                if (c >= 0)
                {
                    callStack.Push(Tuple.Create(node.Left, true, leftOverhead));
                }
            }
            else
            {
                yield return(cur);
            }
        }
    }
Example #3
0
        private IEnumerable <int> IndexOfOverlap(SelectionRangeWithItems rangeWithItems)
        {
            if (rangeWithItems.IsEmpty)
            {
                yield break;
            }

            var targetRange = rangeWithItems.Range;
            var comparer    = new RangeComparer(targetRange);

            var index = this.FindIndex(comparer);

            if (index < 0)
            {
                yield break;
            }

            while (index > 0)
            {
                if (comparer.Compare(m_sortedRanges[index - 1]) != 0)
                {
                    break;
                }

                index--;
            }

            for (int i = index; i < m_sortedRanges.Count; i++)
            {
                var wrapper = m_sortedRanges[i];
                if (comparer.Compare(wrapper) != 0)
                {
                    break;
                }

                var currentRangeWithItems = wrapper.Value;
                var overlap = targetRange.Intersect(currentRangeWithItems.Range);

                if (!overlap.IsEmpty && (rangeWithItems.IsItemsEqual(overlap, currentRangeWithItems)))
                {
                    yield return(wrapper.Index);
                }
            }
        }
Example #4
0
            public int Compare(SelectionRangeWithItemsWrapper item)
            {
                if (item == m_target)
                {
                    return(0);
                }

                var xr = m_target.Value.Range;
                var yr = item.Value.Range;

                int xs, xe, ys, ye;

                ItemComparer.GetBounds(xr, out xs, out xe);
                ItemComparer.GetBounds(yr, out ys, out ye);

                if (xs < ys)
                {
                    Debug.Assert(RangeComparer.Compare(xr, item) <= 0);
                    return(-1);
                }
                else if (xs > ys)
                {
                    Debug.Assert(RangeComparer.Compare(xr, item) >= 0);
                    return(1);
                }

                Debug.Assert(RangeComparer.Compare(xr, item) == 0);

                if (xe < ye)
                {
                    return(-1);
                }
                else if (xe > ye)
                {
                    return(1);
                }

                Debug.Assert(xr == yr);

                return(m_target.Index - item.Index);
            }
Example #5
0
 public int Compare(SelectionRangeWithItemsWrapper item)
 {
     return(RangeComparer.Compare(m_target, item));
 }
Example #6
0
        public void OffsetIndex(int startIndex, int offset)
        {
            if (m_sortedRanges.Count == 0)
            {
                return;
            }

            // Used to offset index after an add or remove from the data source of the grid.
            var offsetRange = new SelectionRange(startIndex, startIndex + System.Math.Abs(offset) - 1);
            var comparer    = new RangeComparer(offsetRange);

            // Find the first range that is greater or that overlaps the target range.
            var index = this.FindIndex(comparer);

            if (index < 0)
            {
                index = ~index;
            }
            else
            {
                while (index > 0)
                {
                    if (comparer.Compare(m_sortedRanges[index - 1]) != 0)
                    {
                        break;
                    }

                    index--;
                }
            }

            var matches = m_sortedRanges.Skip(index).OrderByDescending(item => item.Index).ToList();

            // Adjust the range of all ranges greater or that overlaps the target range.
            foreach (var currentRangeWithItemsWrapper in matches)
            {
                Debug.Assert(comparer.Compare(currentRangeWithItemsWrapper) <= 0);

                var currentRangeIndex     = currentRangeWithItemsWrapper.Index;
                var currentRangeWithItems = currentRangeWithItemsWrapper.Value;
                var currentRange          = currentRangeWithItems.Range;
                var currentRangeItems     = currentRangeWithItems.Items;

                Debug.Assert(!(offsetRange > currentRange));

                var currentRangeIntersection = currentRange.Intersect(offsetRange);

                // The range overlaps.
                if (!currentRangeIntersection.IsEmpty)
                {
                    // Should only happen when adding since when we remove data from the source, we remove the
                    // the range from the list.
                    Debug.Assert(offset > 0);

                    SelectionRange topRange;
                    SelectionRange bottomRange;

                    if (currentRange.StartIndex > currentRange.EndIndex)
                    {
                        if (currentRangeIntersection.EndIndex == currentRange.EndIndex)
                        {
                            this[currentRangeIndex] = new SelectionRangeWithItems(
                                new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset),
                                currentRangeItems);
                            continue;
                        }
                        else
                        {
                            topRange    = new SelectionRange(currentRange.StartIndex + offset, startIndex + offset);
                            bottomRange = new SelectionRange(startIndex - 1, currentRange.EndIndex);
                        }
                    }
                    else
                    {
                        if (currentRangeIntersection.StartIndex == currentRange.StartIndex)
                        {
                            this[currentRangeIndex] = new SelectionRangeWithItems(
                                new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset),
                                currentRangeItems);
                            continue;
                        }
                        else
                        {
                            topRange    = new SelectionRange(currentRange.StartIndex, startIndex - 1);
                            bottomRange = new SelectionRange(startIndex + offset, currentRange.EndIndex + offset);
                        }
                    }

                    object[] topItems    = null;
                    object[] bottomItems = null;

                    if (currentRangeItems != null)
                    {
                        topItems = new object[topRange.Length];
                        Array.Copy(currentRangeItems, 0, topItems, 0, topItems.Length);

                        bottomItems = new object[bottomRange.Length];
                        Array.Copy(currentRangeItems, topItems.Length, bottomItems, 0, bottomItems.Length);
                    }

                    this[currentRangeIndex] = new SelectionRangeWithItems(topRange, topItems);
                    this.Insert(currentRangeIndex + 1, new SelectionRangeWithItems(bottomRange, bottomItems), true);
                }
                // The range is greater.
                else
                {
                    this[currentRangeIndex] = new SelectionRangeWithItems(
                        new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset),
                        currentRangeItems);
                }
            }
        }