From 0e0711482bc62554f8fdcb43c2759bcfaecde8ed Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Mon, 9 Mar 2015 19:22:55 +0100 Subject: [PATCH] If resolver runs into conflict then use then boost the package - fixes #684 --- RELEASE_NOTES.md | 3 +++ src/Paket.Core/PackageResolver.fs | 22 +++++++++++++++++++--- src/Paket.Core/Requirements.fs | 30 +++++++++++++++++------------- src/Paket/Paket.fsproj | 4 ++-- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 51d847a962..973bd630da 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,6 @@ +#### 0.31.13 - 09.03.2015 +* PERFORMANCE: If resolver runs into conflict then use then boost the package - https://github.com/fsprojects/Paket/pull/684 + #### 0.31.12 - 09.03.2015 * COSMETICS: Better tracing when resolver runs into conflict - https://github.com/fsprojects/Paket/pull/684 diff --git a/src/Paket.Core/PackageResolver.fs b/src/Paket.Core/PackageResolver.fs index 6f2aa2bd55..e638a1e816 100644 --- a/src/Paket.Core/PackageResolver.fs +++ b/src/Paket.Core/PackageResolver.fs @@ -149,6 +149,7 @@ let Resolve(getVersionsF, getPackageDetailsF, globalFrameworkRestrictions, rootD tracefn "Resolving packages:" let exploredPackages = Dictionary() let allVersions = Dictionary() + let conflictHistory = Dictionary() let getExploredPackage(packageCount,sources,packageName:PackageName,version,settings:InstallSettings) = let normalizedPackageName = NormalizedPackageName packageName @@ -203,7 +204,18 @@ let Resolve(getVersionsF, getPackageDetailsF, globalFrameworkRestrictions, rootD else ResolvedPackages.Conflict(closed,stillOpen) else - let dependency = Seq.head stillOpen + let dependency = + let currentMin = ref (Seq.head stillOpen) + let currentBoost = ref 0 + for d in stillOpen do + let boost = + match conflictHistory.TryGetValue(NormalizedPackageName d.Name) with + | true,c -> -c + | _ -> 0 + if PackageRequirement.Compare(d,!currentMin,boost,!currentBoost) = -1 then + currentMin := d + currentBoost := boost + !currentMin let allVersions = ref [] let compatibleVersions = ref [] @@ -236,11 +248,15 @@ let Resolve(getVersionsF, getPackageDetailsF, globalFrameworkRestrictions, rootD failwithf "Could not find compatible versions for top level dependency:%s %A%s Available versions:%s - %s%s Try to relax the dependency or allow prereleases." Environment.NewLine (dependency.ToString()) Environment.NewLine Environment.NewLine versionText Environment.NewLine else - tracefn " Could not find compatible versions for:%s %A%sConflicts with:" Environment.NewLine (dependency.ToString()) Environment.NewLine + match conflictHistory.TryGetValue(NormalizedPackageName dependency.Name) with + | true,count -> conflictHistory.[NormalizedPackageName dependency.Name] <- count + 1 + | _ -> conflictHistory.Add(NormalizedPackageName dependency.Name, 1) + tracefn " Could not find compatible versions for:%s %A%s Conflicts with:" Environment.NewLine (dependency.ToString()) Environment.NewLine + closed |> Seq.filter (fun d -> d.Name = dependency.Name) |> fun xs -> String.Join(Environment.NewLine + " ",xs) - |> tracefn "%s" + |> tracefn " %s" let sortedVersions = diff --git a/src/Paket.Core/Requirements.fs b/src/Paket.Core/Requirements.fs index 7481c26e0c..b35fb8eb43 100644 --- a/src/Paket.Core/Requirements.fs +++ b/src/Paket.Core/Requirements.fs @@ -202,21 +202,25 @@ type PackageRequirement = member this.IncludingPrereleases() = { this with VersionRequirement = VersionRequirement(this.VersionRequirement.Range,PreReleaseStatus.All) } + + static member Compare(x,y,boostX,boostY) = + if x = y then 0 else + let c1 = + compare + (not x.VersionRequirement.Range.IsGlobalOverride,x.Parent) + (not y.VersionRequirement.Range.IsGlobalOverride,x.Parent) + if c1 <> 0 then c1 else + let c2 = -1 * compare x.ResolverStrategy y.ResolverStrategy + if c2 <> 0 then c2 else + let cBoost = compare boostX boostY + if cBoost <> 0 then cBoost else + let c3 = -1 * compare x.VersionRequirement y.VersionRequirement + if c3 <> 0 then c3 else + compare x.Name y.Name interface System.IComparable with member this.CompareTo that = match that with - | :? PackageRequirement as that -> - if this = that then 0 else - let c1 = - compare - (not this.VersionRequirement.Range.IsGlobalOverride,this.Parent) - (not that.VersionRequirement.Range.IsGlobalOverride,this.Parent) - if c1 <> 0 then c1 else - let c2 = -1 * compare this.ResolverStrategy that.ResolverStrategy - if c2 <> 0 then c2 else - let c3 = -1 * compare this.VersionRequirement that.VersionRequirement - if c3 <> 0 then c3 else - compare this.Name that.Name - + | :? PackageRequirement as that -> + PackageRequirement.Compare(this,that,0,0) | _ -> invalidArg "that" "cannot compare value of different types" \ No newline at end of file diff --git a/src/Paket/Paket.fsproj b/src/Paket/Paket.fsproj index 120ca50e96..aea8d58514 100644 --- a/src/Paket/Paket.fsproj +++ b/src/Paket/Paket.fsproj @@ -27,10 +27,10 @@ 3 - update + outdated Project paket.exe - c:\code\PacketTest + c:\code\Paket09x pdbonly