public static IAsyncEnumerable <IReadOnlyCollection <IMessage> > GetMessagesAsync(ISocketMessageChannel channel, DiscordSocketClient discord, MessageCache messages, ulong?fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options) { if (dir == Direction.Around) { throw new NotImplementedException(); //TODO: Impl } IReadOnlyCollection <SocketMessage> cachedMessages = null; IAsyncEnumerable <IReadOnlyCollection <IMessage> > result = null; if (dir == Direction.After && fromMessageId == null) { return(AsyncEnumerable.Empty <IReadOnlyCollection <IMessage> >()); } if (dir == Direction.Before || mode == CacheMode.CacheOnly) { if (messages != null) //Cache enabled { cachedMessages = messages.GetMany(fromMessageId, dir, limit); } else { cachedMessages = ImmutableArray.Create <SocketMessage>(); } result = ImmutableArray.Create(cachedMessages).ToAsyncEnumerable <IReadOnlyCollection <IMessage> >(); } if (dir == Direction.Before) { limit -= cachedMessages.Count; if (mode == CacheMode.CacheOnly || limit <= 0) { return(result); } //Download remaining messages ulong?minId = cachedMessages.Count > 0 ? cachedMessages.Min(x => x.Id) : fromMessageId; var downloadedMessages = ChannelHelper.GetMessagesAsync(channel, discord, minId, dir, limit, options); return(result.Concat(downloadedMessages)); } else { if (mode == CacheMode.CacheOnly) { return(result); } //Dont use cache in this case return(ChannelHelper.GetMessagesAsync(channel, discord, fromMessageId, dir, limit, options)); } }
/// <summary> /// Merges multiple sequences into one. /// </summary> public static IAsyncEnumerable <T> Merge <T>(this IAsyncEnumerable <IAsyncEnumerable <T> > sources, int maxConcurrent = int.MaxValue) { if (sources is null) { throw new ArgumentNullException(nameof(sources)); } return(maxConcurrent switch { 1 => sources.Concat(), > 1 => new MergeIterator <T>(sources, maxConcurrent), _ => throw new ArgumentOutOfRangeException(nameof(maxConcurrent)), });
/// <summary> /// Produces the set union of two sequences by using the specified equality comparer. /// </summary> /// <typeparam name="T">The type of elements.</typeparam> /// <param name="first">The first sequence.</param> /// <param name="second">The second sequence.</param> /// <param name="comparer">The <see cref="IEqualityComparer{T}"/> to compare individual keys for equality.</param> /// <returns> /// An <see cref="IAsyncEnumerable{T}"/> that contains all elements from <paramref name="first"/> and /// <paramref name="second"/> but returns each item only once. /// </returns> public static IAsyncEnumerable <T> Union <T>(this IAsyncEnumerable <T> first, IAsyncEnumerable <T> second, IEqualityComparer <T> comparer) { if (first == null) { throw new ArgumentNullException("first"); } if (second == null) { throw new ArgumentNullException("second"); } return(first.Concat(second).Distinct(comparer)); }
public static IAsyncEnumerable <TSource> Union <TSource>(this IAsyncEnumerable <TSource> first, IAsyncEnumerable <TSource> second, IEqualityComparer <TSource> comparer) { if (first == null) { throw new ArgumentNullException(nameof(first)); } if (second == null) { throw new ArgumentNullException(nameof(second)); } if (comparer == null) { throw new ArgumentNullException(nameof(comparer)); } return(first.Concat(second) .Distinct(comparer)); }
public static IAsyncEnumerable <IReadOnlyCollection <IMessage> > GetMessagesAsync(ISocketMessageChannel channel, DiscordSocketClient discord, MessageCache messages, ulong?fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options) { if (dir == Direction.After && fromMessageId == null) { return(AsyncEnumerable.Empty <IReadOnlyCollection <IMessage> >()); } IReadOnlyCollection <SocketMessage> cachedMessages = GetCachedMessages(channel, discord, messages, fromMessageId, dir, limit); IAsyncEnumerable <IReadOnlyCollection <IMessage> > result = ImmutableArray.Create(cachedMessages).ToAsyncEnumerable <IReadOnlyCollection <IMessage> >(); if (dir == Direction.Before) { limit -= cachedMessages.Count; if (mode == CacheMode.CacheOnly || limit <= 0) { return(result); } //Download remaining messages ulong?minId = cachedMessages.Count > 0 ? cachedMessages.Min(x => x.Id) : fromMessageId; IAsyncEnumerable <IReadOnlyCollection <RestMessage> > downloadedMessages = ChannelHelper.GetMessagesAsync(channel, discord, minId, dir, limit, options); if (cachedMessages.Count != 0) { return(result.Concat(downloadedMessages)); } else { return(downloadedMessages); } } else if (dir == Direction.After) { limit -= cachedMessages.Count; if (mode == CacheMode.CacheOnly || limit <= 0) { return(result); } //Download remaining messages ulong maxId = cachedMessages.Count > 0 ? cachedMessages.Max(x => x.Id) : fromMessageId.Value; IAsyncEnumerable <IReadOnlyCollection <RestMessage> > downloadedMessages = ChannelHelper.GetMessagesAsync(channel, discord, maxId, dir, limit, options); if (cachedMessages.Count != 0) { return(result.Concat(downloadedMessages)); } else { return(downloadedMessages); } } else //Direction.Around { if (mode == CacheMode.CacheOnly || limit <= cachedMessages.Count) { return(result); } //Cache isn't useful here since Discord will send them anyways return(ChannelHelper.GetMessagesAsync(channel, discord, fromMessageId, dir, limit, options)); } }