Description
Transpose
, Interleave
and SortedMerge
are three methods that have to deals with enumeration of a collection of IEnumerable
.
In this three methods, implementation have to ensure that all enumerators from the input enumerables are disposed when:
- The enumeration of the input collection of IEnumerable fail.
- The result sequence enumerator is disposed.
1. is assured by Acquire
in the three methods.
2. is assured by DisposableGroup
in SortedMerge
and by some try {} finaly {}
blocks in Transpose
and Interleave
(and those make Acquire
useless as discussed here #696 ).
Acquire
return an array, DisposableGroup
is based on an list.
For the three methods we can build cases where enumerators are heavily removed from the array/list (or, for Transpose
, tested as null).
Since remove for array/list (or repeatedly skip null elements) is O(N) in time, that lead to O(N²) time complexity.
This can be easily fixed with the use of a LinkedList
(and by removing null elements from it).
I propose a ToDisposableLinkedList()
method that 1. have the functionality of Acquire (on error, dispose already acquired elements) and provide a DisposableLinkedList
that 2. have the functionality of DisposableGroup<T>
(being disposable and dispose its content when disposed).
It will be used like that:
using var enumerators = source.Select(e => e.GetEnumerator()).ToDisposableLinkedList();
The using
here allow to remove the try {} finally {}
from here:
MoreLINQ/MoreLinq/Transpose.cs
Lines 92 to 96 in 9fc8486
and here:
MoreLINQ/MoreLinq/Interleave.cs
Lines 141 to 146 in 9fc8486
and improve the DisposableGroup/Acquire
combo from here:
MoreLINQ/MoreLinq/SortedMerge.cs
Line 101 in 9fc8486