diff --git a/pom.xml b/pom.xml index 1f50b8ef5..41f2aa6a1 100644 --- a/pom.xml +++ b/pom.xml @@ -237,6 +237,11 @@ commons-lang3 3.12.0 + + org.apache.commons + commons-collections4 + 4.4 + org.apache.maven.plugin-testing maven-plugin-testing-harness diff --git a/versions-common/pom.xml b/versions-common/pom.xml index 6983325c1..2a0cbfe89 100644 --- a/versions-common/pom.xml +++ b/versions-common/pom.xml @@ -60,7 +60,10 @@ org.apache.commons commons-lang3 - + + org.apache.commons + commons-collections4 + org.apache.maven.plugin-testing maven-plugin-testing-harness diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java b/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java index 0b8695680..fe5a5f019 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java @@ -29,7 +29,9 @@ import java.util.Map; import java.util.Properties; import java.util.Stack; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.apache.commons.collections4.map.LRUMap; /** * Generic implementation of version comparison. @@ -39,7 +41,9 @@ * Note: The implementation of the maven core should be used. */ public class ComparableVersion implements Comparable { - private static final Map CACHE = new ConcurrentHashMap<>(); + private static final int MAX_CACHE_SIZE = 0x200; + private static final Map CACHE = new LRUMap<>(MAX_CACHE_SIZE); + private static final ReentrantReadWriteLock CACHE_LOCK = new ReentrantReadWriteLock(); private String value; @@ -291,7 +295,21 @@ public String toString() { * Get a ComparableVersion representing the version in a string. */ public static ComparableVersion of(String version) { - return CACHE.computeIfAbsent(version, ComparableVersion::new); + try { + CACHE_LOCK.readLock().lock(); + ComparableVersion result = CACHE.get(version); + if (result != null) { + return result; + } + } finally { + CACHE_LOCK.readLock().unlock(); + } + try { + CACHE_LOCK.writeLock().lock(); + return CACHE.computeIfAbsent(version, ComparableVersion::new); + } finally { + CACHE_LOCK.writeLock().unlock(); + } } /**