| File: Resolution\GatherCache.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.PackageManagement\NuGet.PackageManagement.csproj (NuGet.PackageManagement) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #nullable disable using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using NuGet.Frameworks; using NuGet.Packaging.Core; using NuGet.Protocol.Core.Types; using NuGet.Shared; namespace NuGet.PackageManagement { /// <summary> /// GatherCache contains cached results from DependencyInfoResource providers /// This class is for internal use or testing only. /// </summary> public class GatherCache { // These are typically the primary targets or installed packages which perform the lookup on only a single version. private readonly ConcurrentDictionary<GatherSingleCacheKey, SourcePackageDependencyInfo> _singleVersion = new ConcurrentDictionary<GatherSingleCacheKey, SourcePackageDependencyInfo>(); // This contains the full list of package versions for the package id private readonly ConcurrentDictionary<GatherAllCacheKey, List<SourcePackageDependencyInfo>> _allPackageVersions = new ConcurrentDictionary<GatherAllCacheKey, List<SourcePackageDependencyInfo>>(); /// <summary> /// Add a single package /// </summary> public void AddPackageFromSingleVersionLookup( Configuration.PackageSource source, PackageIdentity identity, NuGetFramework framework, SourcePackageDependencyInfo package) { var key = new GatherSingleCacheKey(identity, source, framework); _singleVersion.TryAdd(key, package); } /// <summary> /// Add the full list of versions for a package /// </summary> public void AddAllPackagesForId( Configuration.PackageSource source, string packageId, NuGetFramework framework, List<SourcePackageDependencyInfo> packages) { var key = new GatherAllCacheKey(packageId, source, framework); _allPackageVersions.TryAdd(key, packages); } /// <summary> /// Retrieve an exact version of a package /// </summary> public GatherCacheResult GetPackage( Configuration.PackageSource source, PackageIdentity package, NuGetFramework framework) { var key = new GatherSingleCacheKey(package, source, framework); var hasEntry = false; SourcePackageDependencyInfo result; hasEntry = _singleVersion.TryGetValue(key, out result); if (!hasEntry) { // Try finding the packages from cached all packages results var allPackagesResult = GetPackages(source, package.Id, framework); if (allPackagesResult.HasEntry) { hasEntry = true; // Find the exact package version in the list. The result may be null // if that version does not exist. result = allPackagesResult.Packages .FirstOrDefault(p => package.Equals(p)); } } var packages = new List<SourcePackageDependencyInfo>(1); if (result != null) { packages.Add(result); } return new GatherCacheResult(hasEntry, packages); } /// <summary> /// Retrieve all versions of a package id /// </summary> public GatherCacheResult GetPackages( Configuration.PackageSource source, string packageId, NuGetFramework framework) { var key = new GatherAllCacheKey(packageId, source, framework); List<SourcePackageDependencyInfo> result; var hasEntry = _allPackageVersions.TryGetValue(key, out result); return new GatherCacheResult(hasEntry, result); } /// <summary> /// Cache key for a package id and version /// </summary> private class GatherSingleCacheKey : IEquatable<GatherSingleCacheKey> { public GatherSingleCacheKey( PackageIdentity package, Configuration.PackageSource source, NuGetFramework framework) { Package = package; Source = source; Framework = framework; } public NuGetFramework Framework { get; } public PackageIdentity Package { get; } public Configuration.PackageSource Source { get; } public bool Equals(GatherSingleCacheKey other) { if (other == null) { return false; } if (Object.ReferenceEquals(this, other)) { return true; } return Package.Equals(other.Package) && Source.Equals(other.Source) && Framework.Equals(other.Framework); } public override bool Equals(object obj) { return Equals(obj as GatherSingleCacheKey); } public override int GetHashCode() { var combiner = new HashCodeCombiner(); combiner.AddObject(Package); combiner.AddObject(Source); combiner.AddObject(Framework); return combiner.CombinedHash; } } /// <summary> /// Cache key for a package id and all versions /// </summary> private class GatherAllCacheKey : IEquatable<GatherAllCacheKey> { public GatherAllCacheKey( string packageId, Configuration.PackageSource source, NuGetFramework framework) { PackageId = packageId; Source = source; Framework = framework; } public NuGetFramework Framework { get; set; } public string PackageId { get; set; } public Configuration.PackageSource Source { get; set; } public bool Equals(GatherAllCacheKey other) { if (other == null) { return false; } if (Object.ReferenceEquals(this, other)) { return true; } return string.Equals(PackageId, other.PackageId, StringComparison.OrdinalIgnoreCase) && Source.Equals(other.Source) && Framework.Equals(other.Framework); } public override bool Equals(object obj) { return Equals(obj as GatherAllCacheKey); } public override int GetHashCode() { var combiner = new HashCodeCombiner(); combiner.AddObject(PackageId.ToUpperInvariant()); combiner.AddObject(Source); combiner.AddObject(Framework); return combiner.CombinedHash; } } } }