public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken) { var searchToken = continuationToken as FeedSearchContinuationToken; if (searchToken == null) { throw new InvalidOperationException("Invalid token"); } IEnumerable <IPackageSearchMetadata> packagesWithUpdates = await GetPackagesWithUpdatesAsync(searchToken.SearchString, searchToken.SearchFilter, cancellationToken); IPackageSearchMetadata[] items = packagesWithUpdates .Skip(searchToken.StartIndex) .ToArray(); SearchResult <IPackageSearchMetadata> result = SearchResult.FromItems(items); LoadingStatus loadingStatus = items.Length == 0 ? LoadingStatus.NoItemsFound : LoadingStatus.NoMoreItems; result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { ["Update"] = loadingStatus }; return(result); }
public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken) { var searchToken = continuationToken as FeedSearchContinuationToken; if (searchToken == null) { throw new InvalidOperationException("Invalid token"); } var packagesWithUpdates = (_cachedUpdates?.IncludePrerelease == searchToken.SearchFilter.IncludePrerelease) ? GetPackagesFromCache(searchToken.SearchString) : await GetPackagesWithUpdatesAsync(searchToken.SearchString, searchToken.SearchFilter, cancellationToken); var items = packagesWithUpdates .Skip(searchToken.StartIndex) .ToArray(); var result = SearchResult.FromItems(items); var loadingStatus = items.Length == 0 ? LoadingStatus.NoItemsFound : LoadingStatus.NoMoreItems; result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { ["Update"] = loadingStatus }; return(result); }
public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken) { var searchToken = continuationToken as FeedSearchContinuationToken; if (searchToken == null) { throw new InvalidOperationException("Invalid token"); } var packagesNeedingConsolidation = _installedPackages .GroupById() .Where(g => g.Count() > 1) .Select(g => new PackageIdentity(g.Key, g.Max())) .ToArray(); var packages = packagesNeedingConsolidation .Where(p => p.Id.IndexOf(searchToken.SearchString, StringComparison.OrdinalIgnoreCase) != -1) .OrderBy(p => p.Id) .Skip(searchToken.StartIndex) .Take(PageSize + 1) .ToArray(); var hasMoreItems = packages.Length > PageSize; if (hasMoreItems) { packages = packages.Take(packages.Length - 1).ToArray(); } var items = await TaskCombinators.ThrottledAsync( packages, (p, t) => _metadataProvider.GetPackageMetadataAsync(p, searchToken.SearchFilter.IncludePrerelease, t), cancellationToken); var result = SearchResult.FromItems(items.ToArray()); var loadingStatus = hasMoreItems ? LoadingStatus.Ready : packages.Length == 0 ? LoadingStatus.NoItemsFound : LoadingStatus.NoMoreItems; result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { { "Consolidate", loadingStatus } }; if (hasMoreItems) { result.NextToken = new FeedSearchContinuationToken { SearchString = searchToken.SearchString, SearchFilter = searchToken.SearchFilter, StartIndex = searchToken.StartIndex + packages.Length }; } return(result); }
public static async Task <SearchResult <IPackageSearchMetadata> > SearchAsync( this SourceRepository sourceRepository, ContinuationToken continuationToken, int pageSize, CancellationToken cancellationToken) { var stopWatch = Stopwatch.StartNew(); var searchToken = continuationToken as FeedSearchContinuationToken; if (searchToken == null) { throw new InvalidOperationException("Invalid token"); } var searchResource = await sourceRepository.GetResourceAsync <PackageSearchResource>(cancellationToken); var searchResults = await searchResource?.SearchAsync( searchToken.SearchString, searchToken.SearchFilter, searchToken.StartIndex, pageSize + 1, Common.NullLogger.Instance, cancellationToken); var items = searchResults?.ToArray() ?? new IPackageSearchMetadata[] { }; var hasMoreItems = items.Length > pageSize; if (hasMoreItems) { items = items.Take(items.Length - 1).ToArray(); } var result = SearchResult.FromItems(items); var loadingStatus = hasMoreItems ? LoadingStatus.Ready : items.Length == 0 ? LoadingStatus.NoItemsFound : LoadingStatus.NoMoreItems; result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { { sourceRepository.PackageSource.Name, loadingStatus } }; if (hasMoreItems) { result.NextToken = new FeedSearchContinuationToken { SearchString = searchToken.SearchString, SearchFilter = searchToken.SearchFilter, StartIndex = searchToken.StartIndex + items.Length }; } stopWatch.Stop(); result.Duration = stopWatch.Elapsed; return(result); }
public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken) { var searchToken = continuationToken as FeedSearchContinuationToken; if (searchToken == null) { throw new InvalidOperationException("Invalid token"); } var packages = _installedPackages .GetLatest() .Where(p => p.Id.IndexOf(searchToken.SearchString, StringComparison.OrdinalIgnoreCase) != -1) .OrderBy(p => p.Id) .Skip(searchToken.StartIndex) .Take(PageSize + 1) .ToArray(); var hasMoreItems = packages.Length > PageSize; if (hasMoreItems) { packages = packages.Take(packages.Length - 1).ToArray(); } var items = await TaskCombinators.ThrottledAsync( packages, (p, t) => GetPackageMetadataAsync(p, searchToken.SearchFilter.IncludePrerelease, t), cancellationToken); // The packages were originally sorted which is important because we Skip and Take based on that sort // however the asynchronous execution has randomly reordered the set. So we need to resort. var result = SearchResult.FromItems(items.OrderBy(p => p.Identity.Id).ToArray()); var loadingStatus = hasMoreItems ? LoadingStatus.Ready : packages.Length == 0 ? LoadingStatus.NoItemsFound : LoadingStatus.NoMoreItems; result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { { "Installed", loadingStatus } }; if (hasMoreItems) { result.NextToken = new FeedSearchContinuationToken { SearchString = searchToken.SearchString, SearchFilter = searchToken.SearchFilter, StartIndex = searchToken.StartIndex + packages.Length }; } return(result); }
internal static SearchResult <IPackageSearchMetadata> CreateResult(IPackageSearchMetadata[] items) { SearchResult <IPackageSearchMetadata> result = SearchResult.FromItems(items); var loadingStatus = result.Any() ? LoadingStatus.NoMoreItems : LoadingStatus.NoItemsFound; // No pagination on installed-based feeds result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { { "Installed", loadingStatus } }; return(result); }
private async Task <SearchResult <IPackageSearchMetadata> > AggregateSearchResultsAsync( string searchText, IEnumerable <SearchResult <IPackageSearchMetadata> > results, TelemetryState telemetryState) { SearchResult <IPackageSearchMetadata> result; var nonEmptyResults = results.Where(r => r.Any()).ToArray(); if (nonEmptyResults.Length == 0) { result = SearchResult.Empty <IPackageSearchMetadata>(); } else if (nonEmptyResults.Length == 1) { result = SearchResult.FromItems(nonEmptyResults[0].Items); } else { var items = nonEmptyResults.Select(r => r.Items).ToArray(); var indexer = new RelevanceSearchResultsIndexer(); var aggregator = new SearchResultsAggregator(indexer, new PackageSearchMetadataSplicer()); var aggregatedItems = await aggregator.AggregateAsync( searchText, items); result = SearchResult.FromItems(aggregatedItems.ToArray()); // set correct count of unmerged items result.RawItemsCount = items.Aggregate(0, (r, next) => r + next.Count); } result.SourceSearchStatus = results .SelectMany(r => r.SourceSearchStatus) .ToDictionary(kv => kv.Key, kv => kv.Value); var cursors = results .Where(r => r.NextToken != null) .ToDictionary(r => r.SourceSearchStatus.Single().Key, r => r.NextToken); if (cursors.Keys.Any()) { result.NextToken = new AggregatedContinuationToken { TelemetryState = telemetryState, SearchString = searchText, SourceSearchCursors = cursors }; } return(result); }