diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/IPyPiClient.cs b/src/Microsoft.ComponentDetection.Detectors/pip/IPyPiClient.cs index 862b557f..2ec5e83f 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/IPyPiClient.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/IPyPiClient.cs @@ -201,7 +201,7 @@ public class PyPiClient : IPyPiClient { try { - var parsedVersion = new PythonVersion(release.Key); + var parsedVersion = PythonVersion.Create(release.Key); if (release.Value != null && release.Value.Count > 0 && parsedVersion.Valid && parsedVersion.IsReleasedPackage && PythonVersionUtilities.VersionValidForSpec(release.Key, spec.DependencySpecifiers)) diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersion.cs b/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersion.cs index 71a65e64..5dd7026f 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersion.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersion.cs @@ -14,9 +14,11 @@ public class PythonVersion : IComparable private static readonly Dictionary PreReleaseMapping = new Dictionary { { "a", 0 }, { "alpha", 0 }, { "b", 1 }, { "beta", 1 }, { "c", 2 }, { "rc", 2 }, { "pre", 2 }, { "preview", 2 } }; + private static readonly Dictionary Cache = new(); + private readonly Match match; - public PythonVersion(string version) + private PythonVersion(string version) { var toOperate = version; if (version.EndsWith(".*")) @@ -105,6 +107,23 @@ public class PythonVersion : IComparable public static bool operator <=(PythonVersion operand1, PythonVersion operand2) => operand1.CompareTo(operand2) <= 0; + public static PythonVersion Create(string version) + { + if (version == null) + { + throw new ArgumentNullException(nameof(version)); + } + + if (Cache.TryGetValue(version, out var cachedVersion)) + { + return cachedVersion; + } + + var pythonVersion = new PythonVersion(version); + Cache.Add(version, pythonVersion); + return pythonVersion; + } + public int CompareTo(PythonVersion other) { if (other == null || !other.Valid) diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionComparer.cs b/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionComparer.cs index d7224589..4cd34e5a 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionComparer.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionComparer.cs @@ -5,8 +5,8 @@ public class PythonVersionComparer : IComparer { public int Compare(string x, string y) { - var xVer = new PythonVersion(x); - var yVer = new PythonVersion(y); + var xVer = PythonVersion.Create(x); + var yVer = PythonVersion.Create(y); return xVer.CompareTo(yVer); } diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionUtilities.cs b/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionUtilities.cs index eaf2662c..95ac93e6 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionUtilities.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionUtilities.cs @@ -95,8 +95,8 @@ public static class PythonVersionUtilities var op = spec[..i]; - var targetVer = new PythonVersion(version); - var specVer = new PythonVersion(spec[i..]); + var targetVer = PythonVersion.Create(version); + var specVer = PythonVersion.Create(spec[i..]); if (!targetVer.Valid) { diff --git a/test/Microsoft.ComponentDetection.Detectors.Tests/PythonVersionTests.cs b/test/Microsoft.ComponentDetection.Detectors.Tests/PythonVersionTests.cs index ea4aa3f6..e8f094ed 100644 --- a/test/Microsoft.ComponentDetection.Detectors.Tests/PythonVersionTests.cs +++ b/test/Microsoft.ComponentDetection.Detectors.Tests/PythonVersionTests.cs @@ -14,7 +14,7 @@ public class PythonVersionTests [TestMethod] public void TestBasicVersionConstruction() { - var pythonVersion = new PythonVersion("4!3.2.1.1rc2.post99.dev2"); + var pythonVersion = PythonVersion.Create("4!3.2.1.1rc2.post99.dev2"); Assert.AreEqual(4, pythonVersion.Epoch); Assert.AreEqual("3.2.1.1", pythonVersion.Release); @@ -27,7 +27,7 @@ public class PythonVersionTests [TestMethod] public void TestDefaultDevVersionConstruction() { - var pythonVersion = new PythonVersion("4!3.2.1.1rc2.post90.dev"); + var pythonVersion = PythonVersion.Create("4!3.2.1.1rc2.post90.dev"); Assert.AreEqual(4, pythonVersion.Epoch); Assert.AreEqual("3.2.1.1", pythonVersion.Release); @@ -69,7 +69,7 @@ public class PythonVersionTests "2.10.0.dev1", "v2.10.0.dev2", "v2.10.0", - }.Select(x => new { Raw = x, Version = new PythonVersion(x) }).ToList(); + }.Select(x => new { Raw = x, Version = PythonVersion.Create(x) }).ToList(); for (var i = 1; i < versionItems.Count; i++) {