Esempio n. 1
0
        public SortedDictionary <string, long> Compare(
            DownloadData oldData,
            DownloadData newData)
        {
            if (newData.Count == 0)
            {
                throw new InvalidOperationException("The new data should not be empty.");
            }

            var stopwatch = Stopwatch.StartNew();

            // We use a very simplistic algorithm here. Find the union of both ID sets and compare each download count.
            var uniqueIds = new HashSet <string>(
                oldData.Keys.Concat(newData.Keys),
                StringComparer.OrdinalIgnoreCase);

            _logger.LogInformation(
                "There are {OldCount} IDs in the old data, {NewCount} IDs in the new data, and {TotalCount} IDs in total.",
                oldData.Count,
                newData.Count,
                uniqueIds.Count);

            var result        = new SortedDictionary <string, long>(StringComparer.OrdinalIgnoreCase);
            var decreaseCount = 0;

            foreach (var id in uniqueIds)
            {
                // Detect download count decreases and emit a metric. This is not necessarily wrong because there have
                // been times that we manually delete spoofed download counts.
                DetectDownloadCountDecreases(oldData, newData, id, ref decreaseCount);

                var oldCount = oldData.GetDownloadCount(id);
                var newCount = newData.GetDownloadCount(id);
                if (oldCount != newCount)
                {
                    result.Add(id, newCount);
                }
            }

            _logger.LogInformation("There are {Count} package IDs with download count changes.", result.Count);
            _logger.LogInformation("There are {Count} package versions with download count decreases.", decreaseCount);

            if (decreaseCount > _options.Value.MaxDownloadCountDecreases)
            {
                throw new InvalidOperationException("Too many download count decreases are occurring.");
            }

            stopwatch.Stop();
            _telemetryService.TrackDownloadSetComparison(oldData.Count, newData.Count, result.Count, stopwatch.Elapsed);

            return(result);
        }