internal override int BinarySearch(TreeSpan span, T item, IComparer <T> comparer)
                {
                    Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                    Debug.Assert(comparer != null, $"Assertion failed: {nameof(comparer)} != null");

                    return(~0);
                }
Exemple #2
0
            internal override int FindLastIndex(TreeSpan span, Predicate <T> match)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                Debug.Assert(match != null, $"Assertion failed: {nameof(match)} != null");

                return(Array.FindLastIndex(_data, span.EndInclusive, span.Count, match));
            }
Exemple #3
0
            internal override int BinarySearch(TreeSpan span, T item, IComparer <T> comparer)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                Debug.Assert(comparer != null, $"Assertion failed: {nameof(comparer)} != null");

                return(Array.BinarySearch(_data, span.Start, span.Count, item, comparer));
            }
                internal override int FindLastIndex(TreeSpan span, Predicate <T> match)
                {
                    Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                    Debug.Assert(match != null, $"Assertion failed: {nameof(match)} != null");

                    return(-1);
                }
Exemple #5
0
            internal override void Sort(TreeSpan span, IComparer <T> comparer)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                Debug.Assert(comparer != null, $"Assertion failed: {nameof(comparer)} != null");

                Array.Sort(_data, span.Start, span.Count, comparer);
            }
Exemple #6
0
            internal override int BinarySearch(TreeSpan span, T item, IComparer <T> comparer)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                Debug.Assert(comparer != null, $"Assertion failed: {nameof(comparer)} != null");

                // Since accessing FirstLeaf is O(1), at each index level we are only looking for the correct child page
                int firstPage = FindLowerBound(_offsets, _nodeCount, span.Start);
                int lastPage  = FindLowerBound(_offsets, _nodeCount, span.EndInclusive);

                int lowPage  = firstPage;
                int highPage = lastPage;

                while (lowPage < highPage)
                {
                    // Avoid choosing page == lowPage because we won't have enough information to make progress
                    int page = lowPage + ((highPage - lowPage + 1) >> 1);
                    Debug.Assert(page > firstPage, $"Assertion failed: {nameof(page)} > {nameof(firstPage)}");

                    T value = _nodes[page].FirstLeaf[0];

                    int c;
                    try
                    {
                        c = comparer.Compare(value, item);
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Failed to compare two elements in the list.", e);
                    }

                    if (c == 0)
                    {
                        // Binary search allows any index once found
                        return(_offsets[page]);
                    }

                    if (c < 0)
                    {
                        lowPage = page;
                    }
                    else
                    {
                        highPage = page - 1;
                    }
                }

                Debug.Assert(lowPage >= 0 && lowPage < _nodeCount, $"Assertion failed: {nameof(lowPage)} >= 0 && {nameof(lowPage)} < {nameof(_nodeCount)}");

                int result = _nodes[lowPage].BinarySearch(MapSpanDownToChild(span, lowPage), item, comparer);

                if (result < 0)
                {
                    return(~(~result + _offsets[lowPage]));
                }
                else
                {
                    return(result + _offsets[lowPage]);
                }
            }
 internal Enumerator(TreeList <T> list, TreeSpan span)
 {
     _list      = list;
     _span      = span;
     _version   = list._version;
     _index     = -1;
     _leafNode  = null;
     _leafIndex = -1;
     _current   = default !;
Exemple #8
0
            private TreeSpan MapSpanDownToChild(TreeSpan span, int childIndex)
            {
                Debug.Assert(childIndex >= 0 && childIndex < _nodeCount, $"Assertion failed: {nameof(childIndex)} >= 0 && {nameof(childIndex)} < {nameof(_nodeCount)}");

                // Offset the input span
                TreeSpan mappedFullSpan = span.Offset(-_offsets[childIndex]);

                // Return the intersection
                return(TreeSpan.Intersect(mappedFullSpan, _nodes[childIndex].Span));
            }
            internal void Reverse(TreeSpan span)
            {
                int firstIndex = span.Start;
                int lastIndex  = firstIndex + span.Count - 1;

                while (lastIndex > firstIndex)
                {
                    T temp = this[firstIndex];
                    this[firstIndex] = this[lastIndex];
                    this[lastIndex]  = temp;
                    firstIndex++;
                    lastIndex--;
                }
            }
Exemple #10
0
            internal override int BinarySearch(TreeSpan span, T item, IComparer <T> comparer)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                Debug.Assert(comparer != null, $"Assertion failed: {nameof(comparer)} != null");

                // Since accessing FirstLeaf is O(1), at each index level we are only looking for the correct child page
                int firstPage = FindLowerBound(_offsets, _nodeCount, span.Start);
                int lastPage  = FindLowerBound(_offsets, _nodeCount, span.EndInclusive);

                int lowPage  = firstPage;
                int highPage = lastPage;

                while (lowPage < highPage)
                {
                    // Avoid choosing page == lowPage because we won't have enough information to make progress
                    int page = lowPage + ((highPage - lowPage + 1) >> 1);
                    Debug.Assert(page > firstPage, $"Assertion failed: {nameof(page)} > {nameof(firstPage)}");

                    T value = _nodes[page].FirstLeaf ![0];
Exemple #11
0
            internal override int LastIndexOf(T item, TreeSpan span)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");

                for (int i = FindLowerBound(_offsets, _nodeCount, span.EndInclusive); i >= 0; i--)
                {
                    TreeSpan mappedSpan = MapSpanDownToChild(span, i);
                    if (mappedSpan.IsEmpty)
                    {
                        return(-1);
                    }

                    int foundIndex = _nodes[i].LastIndexOf(item, mappedSpan);
                    if (foundIndex >= 0)
                    {
                        return(_offsets[i] + foundIndex);
                    }
                }

                return(-1);
            }
Exemple #12
0
            internal override int FindLastIndex(TreeSpan span, Predicate <T> match)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                Debug.Assert(match != null, $"Assertion failed: {nameof(match)} != null");

                for (int i = FindLowerBound(_offsets, _nodeCount, span.EndInclusive); i >= 0; i--)
                {
                    TreeSpan mappedSpan = MapSpanDownToChild(span, i);
                    if (mappedSpan.IsEmpty)
                    {
                        return(-1);
                    }

                    int foundIndex = _nodes[i].FindLastIndex(mappedSpan, match);
                    if (foundIndex >= 0)
                    {
                        return(_offsets[i] + foundIndex);
                    }
                }

                return(-1);
            }
Exemple #13
0
            internal override void Sort(TreeSpan span, IComparer <T> comparer)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");
                Debug.Assert(comparer != null, $"Assertion failed: {nameof(comparer)} != null");

                int firstPage = FindLowerBound(_offsets, _nodeCount, span.Start);
                int lastPage  = firstPage;

                for (int i = firstPage; i < _nodeCount; i++)
                {
                    TreeSpan mappedSpan = MapSpanDownToChild(span, i);
                    if (mappedSpan.IsEmpty)
                    {
                        break;
                    }

                    lastPage = i;
                    _nodes[i].Sort(mappedSpan, comparer);
                }

                if (firstPage != lastPage)
                {
                    // Need to merge the results
                    int pageCount = lastPage - firstPage + 1;
                    for (int mergeSegmentSize = 1; mergeSegmentSize < pageCount; mergeSegmentSize *= 2)
                    {
                        for (int firstSegment = firstPage; firstSegment < lastPage; firstSegment += mergeSegmentSize * 2)
                        {
                            int secondSegment = firstSegment + mergeSegmentSize;
                            if (secondSegment > lastPage)
                            {
                                break;
                            }

                            TreeSpan firstSpan  = GetSegmentSpan(span, firstSegment, mergeSegmentSize);
                            TreeSpan secondSpan = GetSegmentSpan(span, secondSegment, mergeSegmentSize);
                            MergeSegments(firstSpan, secondSpan);
                        }
                    }
                }

                // Local functions
                TreeSpan GetSegmentSpan(TreeSpan bounds, int firstPageOfSegment, int segmentPageCount)
                {
                    int lastPageOfSegment = Math.Min(_nodeCount - 1, firstPageOfSegment + segmentPageCount - 1);
                    int startIndex        = _offsets[firstPageOfSegment];
                    int endIndexExclusive = _offsets[lastPageOfSegment] + _nodes[lastPageOfSegment].Count;

                    return(TreeSpan.Intersect(bounds, TreeSpan.FromBounds(startIndex, endIndexExclusive)));
                }

                void MergeSegments(TreeSpan first, TreeSpan second)
                {
                    Debug.Assert(first.IsSubspanOf(Span), $"Assertion failed: {nameof(first)}.IsSubspanOf({nameof(Span)})");
                    Debug.Assert(second.IsSubspanOf(Span), $"Assertion failed: {nameof(second)}.IsSubspanOf({nameof(Span)})");
                    Debug.Assert(first.EndExclusive == second.Start, $"Assertion failed: first.EndExclusive == second.Start");

                    // Stop immediately if already ordered
                    if (comparer.Compare(this[first.EndInclusive], this[second.Start]) <= 0)
                    {
                        return;
                    }

                    int i = first.Start;
                    int j = second.Start;

                    while (true)
                    {
                        if (i == first.EndExclusive)
                        {
                            break;
                        }

                        Debug.Assert(j < second.EndExclusive, $"Assertion failed: j < second.EndExclusive");

                        int c = comparer.Compare(this[i], this[j]);
                        if (c == 0)
                        {
                            i++;
                        }
                        else if (c < 0)
                        {
                            i++;
                        }
                        else
                        {
                            T temp = this[i];
                            this[i] = this[j];
                            this[j] = temp;
                            i++;
                            while (i < first.EndExclusive && j < second.EndExclusive - 1 && comparer.Compare(temp, this[j + 1]) > 0)
                            {
                                j++;
                                T temp2 = this[i];
                                this[i] = this[j];
                                this[j] = temp2;
                                i++;
                            }

                            if (j > 1 && j + 1 < second.EndExclusive)
                            {
                                MergeSegments(TreeSpan.FromBounds(second.Start, j + 1), TreeSpan.FromBounds(j + 1, second.EndExclusive));
                            }

                            j = second.Start;
                        }
                    }
                }
            }
 internal abstract int LastIndexOf(T item, TreeSpan span);
Exemple #15
0
            internal override int LastIndexOf(T item, TreeSpan span)
            {
                Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");

                return(Array.LastIndexOf(_data, item, span.EndInclusive, span.Count));
            }
 internal abstract void Sort(TreeSpan span, IComparer <T> comparer);
 internal abstract int FindLastIndex(TreeSpan span, Predicate <T> match);
 internal abstract int BinarySearch(TreeSpan span, T item, IComparer <T> comparer);
                internal override int IndexOf(T item, TreeSpan span)
                {
                    Debug.Assert(span.IsSubspanOf(Span), $"Assertion failed: {nameof(span)}.IsSubspanOf({nameof(Span)})");

                    return(-1);
                }
 internal override int LastIndexOf(T item, TreeSpan span)
 {
     throw ExceptionUtilities.Unreachable;
 }