Exemple #1
0
        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);
        }
Exemple #7
0
        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);
        }