/// <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); }
/// <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); }
/// <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 }
/// <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 }