Esempio n. 1
0
        /// <summary>
        /// Removes all the elements that match the conditions defined by the specified predicate.
        /// </summary>
        /// <param name="match">The <see cref="System.Predicate{T}"/> delegate that defines the conditions of the elements to remove.</param>
        /// <returns>
        /// The number of elements removed from the <see cref="Partition{T}"/>.
        /// </returns>
        public long RemoveAll(Predicate <T> match)
        {
            long RemovedCount = 0;

            int SegmentCount = SegmentTable.Count;
            int SegmentIndex = 0;

            while (SegmentIndex < SegmentCount)
            {
                ISegment <T> Segment = SegmentTable[SegmentIndex];

                RemovedCount += Segment.RemoveAll(match);

                if (Segment.Count == 0)
                {
                    SegmentTable.RemoveAt(SegmentIndex);
                    SegmentTable.Add(Segment);
                    SegmentCount--;
                }
                else
                {
                    SegmentIndex++;
                }
            }

            Count -= RemovedCount;
            RebuildCache();

#if DEBUG
            AssertInvariant();
#endif

            return(RemovedCount);
        }
Esempio n. 2
0
        /// <summary>
        /// Removes the first occurrence of a specific object from the <see cref="Partition{T}"/>.
        /// </summary>
        /// <param name="item">The object to remove from the <see cref="Partition{T}"/>. The value can be null for reference types.</param>
        /// <returns>
        /// true if <paramref name="item"/> is successfully removed; otherwise, false. This method also returns false if <paramref name="item"/> was not found in the <see cref="Partition{T}"/>.
        /// </returns>
        public bool Remove(T item)
        {
            bool Result = false;

            foreach (ISegment <T> Segment in SegmentTable)
            {
                if (Segment.Remove(item))
                {
                    Result = true;
                    Count--;

                    if (Segment.Count == 0)
                    {
                        SegmentTable.Remove(Segment);
                        SegmentTable.Add(Segment);
                    }

                    break;
                }
            }

            RebuildCache();

#if DEBUG
            AssertInvariant();
#endif

            return(Result);
        }
Esempio n. 3
0
        /// <summary>
        /// Removes a range of elements from the <see cref="Partition{T}"/>.
        /// </summary>
        /// <param name="segmentIndex">The segment index of the position of the first element to remove.</param>
        /// <param name="elementIndex">The element index of the position of the first element to remove.</param>
        /// <param name="cacheIndex">The cache index of the position of the first element to remove.</param>
        /// <param name="count">The number of elements to remove.</param>
        public void RemoveRange(int segmentIndex, int elementIndex, int cacheIndex, long count)
        {
            Debug.Assert(IsValidPosition(segmentIndex, elementIndex, true));
            Debug.Assert(cacheIndex >= 0);

            long RemainingCount = count;

            while (RemainingCount > 0)
            {
                Debug.Assert(segmentIndex >= 0 && segmentIndex < SegmentTable.Count);
                Debug.Assert(elementIndex >= 0 && elementIndex < SegmentTable[segmentIndex].Count);

                int Removable = SegmentTable[segmentIndex].Count - elementIndex;
                if (Removable > RemainingCount)
                {
                    Removable = (int)RemainingCount;
                }

                SegmentTable[segmentIndex].RemoveRange(elementIndex, Removable);

                if (SegmentTable[segmentIndex].Count > 0)
                {
                    segmentIndex++;
                }
                else
                {
                    ISegment <T> Segment = SegmentTable[segmentIndex];
                    SegmentTable.RemoveAt(segmentIndex);
                    SegmentTable.Add(Segment);
                }

                RemainingCount -= Removable;
                elementIndex    = 0;
            }

            Debug.Assert(RemainingCount == 0);

            Count -= count;

            RebuildCacheFrom(cacheIndex);

#if DEBUG
            AssertInvariant();
#endif
        }
Esempio n. 4
0
        /// <summary>
        /// Increases the <see cref="Partition{T}"/>.Capacity by the given amount.
        /// </summary>
        /// <param name="extended">The number of elements added to the <see cref="Partition{T}"/>.Capacity.</param>
        public void ExtendCapacity(long extended)
        {
            Debug.Assert(extended >= 0);

            long RemainingCapacity = extended;

            // We first extend the capacity of the last segment in the partition.
            if (SegmentTable[SegmentTable.Count - 1].Capacity < MaxSegmentCapacity)
            {
                int Extendable = SegmentTable[SegmentTable.Count - 1].Extendable;
                if (Extendable > RemainingCapacity)
                {
                    Extendable = (int)RemainingCapacity;
                }

                int effectiveExtended;
                SegmentTable[SegmentTable.Count - 1].Extend(Extendable, out effectiveExtended);
                RemainingCapacity -= effectiveExtended;
            }

            Debug.Assert(RemainingCapacity >= 0);

            // Then we add as many empty segments as necessary to increase the partition capacity.
            while (RemainingCapacity > MaxSegmentCapacity)
            {
                SegmentTable.Add(CreateMaxCapacitySegment());
                RemainingCapacity -= MaxSegmentCapacity;
            }

            Debug.Assert(RemainingCapacity >= 0 && RemainingCapacity <= MaxSegmentCapacity);

            if (RemainingCapacity > 0)
            {
                SegmentTable.Add(CreateSegment((int)RemainingCapacity));
            }

            Capacity += extended;

            RebuildCache();

#if DEBUG
            AssertInvariant();
#endif
        }