コード例 #1
0
        /// <summary>
        ///     Creates a new <see cref="IAsyncReadOnlyCollection{T}" /> that contains the sorted elements of the
        ///     <see cref="IAsyncEnumerable{T}" />.
        /// </summary>
        /// <param name="source">
        ///     The <see cref="IAsyncEnumerable{T}" /> to sort.
        /// </param>
        /// <param name="comparison">
        ///     The comparison to use while sorting.
        /// </param>
        /// <typeparam name="T">
        ///     The type of the items.
        /// </typeparam>
        /// <returns>
        ///     The sorted <see cref="IAsyncReadOnlyCollection{T}" />.
        /// </returns>
        public async Task <IAsyncReadOnlyCollection <T> > SortAsync <T>(IAsyncEnumerable <T> source, Comparison <T> comparison)
        {
            var chunks = new List <IAsyncReadOnlyCollection <T> >();

            if (source.Policy != this)
            {
                source = await this.MaterializeAsync(source).ConfigureAwait(false);
            }

            await source.Batch(this.MaximumChunkSize).ForEachAsync(
                async batch =>
            {
                var builder = await this.CreateBuilder <T>().AddAsync(await this.memPolicy.SortAsync(batch, comparison).ConfigureAwait(false));

                chunks.Add(await builder.BuildAsync().ConfigureAwait(false));
            });

            var result = this.CreateBuilder <T>();

            var enumerators = chunks.Select(c => c.GetAsyncEnumerator()).ToList();

            foreach (var enumerator in enumerators.ToArray())
            {
                if (!enumerator.MoveNext() && !(await enumerator.NextBatchAsync().ConfigureAwait(false) && enumerator.MoveNext()))
                {
                    enumerator.Dispose();
                    enumerators.Remove(enumerator);
                }
            }

            enumerators.Sort((a, b) => comparison(a.Current, b.Current));

            while (true)
            {
                await result.AddAsync(TemporaryFilePolicy.TakeItems(enumerators, comparison)).ConfigureAwait(false);

                if (!(await enumerators[0].NextBatchAsync().ConfigureAwait(false) && enumerators[0].MoveNext()))
                {
                    enumerators[0].Dispose();
                    enumerators.RemoveAt(0);

                    if (enumerators.Count == 0)
                    {
                        break;
                    }
                }
                else
                {
                    TemporaryFilePolicy.SortEnumerators(enumerators, comparison);
                }
            }

            foreach (var chunk in chunks)
            {
                chunk.Dispose();
            }

            return(await result.BuildAsync().ConfigureAwait(false));
        }
コード例 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Collection{T}"/> class.
 /// </summary>
 /// <param name="policy">
 /// The policy.
 /// </param>
 /// <param name="fileId">
 /// The file id.
 /// </param>
 /// <param name="count">
 /// The count.
 /// </param>
 /// <param name="transform">
 /// The transform.
 /// </param>
 /// <param name="context">
 /// The context.
 /// </param>
 public Collection(TemporaryFilePolicy policy, int fileId, long count, ITransform <T> transform, IDisposable context)
 {
     this.policy    = policy;
     this.fileId    = fileId;
     this.Count     = count;
     this.transform = transform;
     this.context   = context;
 }
コード例 #3
0
        /// <summary>
        /// Takes sorted items from the enumerators while it can be done synchronously.
        /// </summary>
        /// <param name="enumerators">
        /// The enumerators.
        /// </param>
        /// <param name="comparison">
        /// The comparison.
        /// </param>
        /// <typeparam name="T">
        /// The type of the items.
        /// </typeparam>
        /// <returns>
        /// The items that were taken synchronously.
        /// </returns>
        private static IEnumerable <T> TakeItems <T>([NotNull] List <IAsyncEnumerator <T> > enumerators, Comparison <T> comparison)
        {
            while (true)
            {
                yield return(enumerators[0].Current);

                if (!enumerators[0].MoveNext())
                {
                    yield break;
                }

                TemporaryFilePolicy.SortEnumerators(enumerators, comparison);
            }
        }
コード例 #4
0
            public async Task <IAsyncReadOnlyCollection <T> > BuildAsync()
            {
                if (this.policy == null)
                {
                    throw new InvalidOperationException("A builder can only be used once; collection was already built.");
                }

                if (this.addTask != null)
                {
                    await this.addTask;
                }

                await this.file.FlushAsync();

                this.file.Dispose();
                this.file = null;

                var result = new Collection <T>(this.policy, this.fileId, this.count, this.transform, this.context);

                this.policy = null;

                return(result);
            }
コード例 #5
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="Builder{T}" /> class.
 /// </summary>
 /// <param name="policy">
 ///     The policy.
 /// </param>
 public Builder(TemporaryFilePolicy policy)
 {
     this.policy = policy;
 }