mirror of https://github.com/apache/maven.git
[MNG-8016] Simplify ModelCache (#1377)
The `ModelCache` is now bloated and can be simplified a lot. --- https://issues.apache.org/jira/browse/MNG-8016
This commit is contained in:
parent
0d046da6f1
commit
7f70467aa3
|
@ -118,14 +118,8 @@ under the License.
|
|||
<exclude>org.apache.maven.model.building.DefaultModelProcessor#setModelLocator(org.apache.maven.model.locator.ModelLocator):METHOD_REMOVED</exclude>
|
||||
<exclude>org.apache.maven.model.building.DefaultModelProcessor#setModelReader(org.apache.maven.model.io.ModelReader):METHOD_REMOVED</exclude>
|
||||
<exclude>org.apache.maven.model.building.DefaultModelProcessor#DefaultModelProcessor():CONSTRUCTOR_REMOVED</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#get(org.apache.maven.building.Source,java.lang.String):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#get(org.apache.maven.building.Source,org.apache.maven.model.building.ModelCacheTag):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#get(java.lang.String,java.lang.String,java.lang.String,org.apache.maven.model.building.ModelCacheTag):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#put(org.apache.maven.building.Source,java.lang.String,java.lang.Object):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#put(org.apache.maven.building.Source,org.apache.maven.model.building.ModelCacheTag,java.lang.Object):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#put(java.lang.String,java.lang.String,java.lang.String,org.apache.maven.model.building.ModelCacheTag,java.lang.Object):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#computeIfAbsent(java.lang.String,java.lang.String,java.lang.String,org.apache.maven.model.building.ModelCacheTag,java.util.function.Supplier):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#computeIfAbsent(org.apache.maven.building.Source,org.apache.maven.model.building.ModelCacheTag,java.util.function.Supplier):METHOD_NEW_DEFAULT</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#get(java.lang.String,java.lang.String,java.lang.String,java.lang.String):METHOD_REMOVED</exclude>
|
||||
<exclude>org.apache.maven.model.building.ModelCache#put(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Object):METHOD_REMOVED</exclude>
|
||||
<exclude>org.apache.maven.model.composition.DependencyManagementImporter#importManagement(org.apache.maven.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>
|
||||
<exclude>org.apache.maven.model.composition.DefaultDependencyManagementImporter#importManagement(org.apache.maven.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>
|
||||
<exclude>org.apache.maven.model.inheritance.DefaultInheritanceAssembler</exclude>
|
||||
|
|
|
@ -1870,11 +1870,11 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
String version,
|
||||
ModelCacheTag<T> tag,
|
||||
Callable<T> supplier) {
|
||||
return doWithCache(cache, supplier, s -> cache.computeIfAbsent(groupId, artifactId, version, tag, s));
|
||||
return doWithCache(cache, supplier, s -> cache.computeIfAbsent(groupId, artifactId, version, tag.getName(), s));
|
||||
}
|
||||
|
||||
private static <T> T cache(ModelCache cache, Source source, ModelCacheTag<T> tag, Callable<T> supplier) {
|
||||
return doWithCache(cache, supplier, s -> cache.computeIfAbsent(source, tag, s));
|
||||
return doWithCache(cache, supplier, s -> cache.computeIfAbsent(source, tag.getName(), s));
|
||||
}
|
||||
|
||||
private static <T> T doWithCache(
|
||||
|
|
|
@ -26,122 +26,13 @@ import org.apache.maven.building.Source;
|
|||
* Caches auxiliary data used during model building like already processed raw/effective models. The data in the cache
|
||||
* is meant for exclusive consumption by the model builder and is opaque to the cache implementation. The cache key is
|
||||
* formed by a combination of group id, artifact id, version and tag. The first three components generally refer to the
|
||||
* identify of a model. The tag allows for further classification of the associated data on the sole discretion of the
|
||||
* identity of a model. The tag allows for further classification of the associated data on the sole discretion of the
|
||||
* model builder.
|
||||
*
|
||||
*/
|
||||
public interface ModelCache {
|
||||
/**
|
||||
* Puts the specified data into the cache.
|
||||
*
|
||||
* @param path The path of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @param data The data to store in the cache, must not be {@code null}.
|
||||
* @since 4.0.0
|
||||
*/
|
||||
default void put(Source path, String tag, Object data) {
|
||||
// only useful for ReactorModelCache
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified data from the cache.
|
||||
*
|
||||
* @param path The path of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @return The requested data or {@code null} if none was present in the cache.
|
||||
* @since 4.0.0
|
||||
*/
|
||||
default Object get(Source path, String tag) {
|
||||
// only useful for ReactorModelCache
|
||||
return null;
|
||||
}
|
||||
<T> T computeIfAbsent(String groupId, String artifactId, String version, String tag, Supplier<Supplier<T>> data);
|
||||
|
||||
/**
|
||||
* Puts the specified data into the cache.
|
||||
*
|
||||
* @param groupId The group id of the cache record, must not be {@code null}.
|
||||
* @param artifactId The artifact id of the cache record, must not be {@code null}.
|
||||
* @param version The version of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @param data The data to store in the cache, must not be {@code null}.
|
||||
*/
|
||||
void put(String groupId, String artifactId, String version, String tag, Object data);
|
||||
|
||||
/**
|
||||
* Gets the specified data from the cache.
|
||||
*
|
||||
* @param groupId The group id of the cache record, must not be {@code null}.
|
||||
* @param artifactId The artifact id of the cache record, must not be {@code null}.
|
||||
* @param version The version of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @return The requested data or {@code null} if none was present in the cache.
|
||||
*/
|
||||
Object get(String groupId, String artifactId, String version, String tag);
|
||||
|
||||
/**
|
||||
* Puts the specified data into the cache.
|
||||
*
|
||||
* @param path The path of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @param data The data to store in the cache, must not be {@code null}.
|
||||
* @since 4.0.0
|
||||
*/
|
||||
default <T> void put(Source path, ModelCacheTag<T> tag, T data) {
|
||||
put(path, tag.getName(), tag.intoCache(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified data from the cache.
|
||||
*
|
||||
* @param path The path of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @return The requested data or {@code null} if none was present in the cache.
|
||||
* @since 4.0.0
|
||||
*/
|
||||
default <T> T get(Source path, ModelCacheTag<T> tag) {
|
||||
Object obj = get(path, tag.getName());
|
||||
return (obj != null) ? tag.fromCache(tag.getType().cast(obj)) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the specified data into the cache.
|
||||
*
|
||||
* @param groupId The group id of the cache record, must not be {@code null}.
|
||||
* @param artifactId The artifact id of the cache record, must not be {@code null}.
|
||||
* @param version The version of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @param data The data to store in the cache, must not be {@code null}.
|
||||
*/
|
||||
default <T> void put(String groupId, String artifactId, String version, ModelCacheTag<T> tag, T data) {
|
||||
put(groupId, artifactId, version, tag.getName(), tag.intoCache(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified data from the cache.
|
||||
*
|
||||
* @param groupId The group id of the cache record, must not be {@code null}.
|
||||
* @param artifactId The artifact id of the cache record, must not be {@code null}.
|
||||
* @param version The version of the cache record, must not be {@code null}.
|
||||
* @param tag The tag of the cache record, must not be {@code null}.
|
||||
* @return The requested data or {@code null} if none was present in the cache.
|
||||
*/
|
||||
default <T> T get(String groupId, String artifactId, String version, ModelCacheTag<T> tag) {
|
||||
Object obj = get(groupId, artifactId, version, tag.getName());
|
||||
return (obj != null) ? tag.fromCache(tag.getType().cast(obj)) : null;
|
||||
}
|
||||
|
||||
default <T> T computeIfAbsent(
|
||||
String groupId, String artifactId, String version, ModelCacheTag<T> tag, Supplier<Supplier<T>> data) {
|
||||
Object obj = computeIfAbsent(groupId, artifactId, version, tag.getName(), (Supplier) data);
|
||||
return (obj != null) ? tag.fromCache(tag.getType().cast(obj)) : null;
|
||||
}
|
||||
|
||||
default <T> T computeIfAbsent(Source path, ModelCacheTag<T> tag, Supplier<Supplier<T>> data) {
|
||||
Object obj = computeIfAbsent(path, tag.getName(), (Supplier) data);
|
||||
return (obj != null) ? tag.fromCache(tag.getType().cast(obj)) : null;
|
||||
}
|
||||
|
||||
Object computeIfAbsent(String groupId, String artifactId, String version, String tag, Supplier<Supplier<?>> data);
|
||||
|
||||
Object computeIfAbsent(Source path, String tag, Supplier<Supplier<?>> data);
|
||||
<T> T computeIfAbsent(Source path, String tag, Supplier<Supplier<T>> data);
|
||||
}
|
||||
|
|
|
@ -43,24 +43,6 @@ interface ModelCacheTag<T> {
|
|||
*/
|
||||
Class<T> getType();
|
||||
|
||||
/**
|
||||
* Creates a copy of the data suitable for storage in the cache. The original data to store can be mutated after the
|
||||
* cache is populated but the state of the cache must not change so we need to make a copy.
|
||||
*
|
||||
* @param data The data to store in the cache, must not be {@code null}.
|
||||
* @return The data being stored in the cache, never {@code null}.
|
||||
*/
|
||||
T intoCache(T data);
|
||||
|
||||
/**
|
||||
* Creates a copy of the data suitable for retrieval from the cache. The retrieved data can be mutated after the
|
||||
* cache is queried but the state of the cache must not change so we need to make a copy.
|
||||
*
|
||||
* @param data The data to retrieve from the cache, must not be {@code null}.
|
||||
* @return The data being retrieved from the cache, never {@code null}.
|
||||
*/
|
||||
T fromCache(T data);
|
||||
|
||||
/**
|
||||
* The tag used for the raw model without profile activation
|
||||
*/
|
||||
|
@ -75,16 +57,6 @@ interface ModelCacheTag<T> {
|
|||
public Class<ModelData> getType() {
|
||||
return ModelData.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelData intoCache(ModelData data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelData fromCache(ModelData data) {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -101,16 +73,6 @@ interface ModelCacheTag<T> {
|
|||
public Class<DependencyManagement> getType() {
|
||||
return DependencyManagement.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DependencyManagement intoCache(DependencyManagement data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DependencyManagement fromCache(DependencyManagement data) {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -127,15 +89,5 @@ interface ModelCacheTag<T> {
|
|||
public Class<Model> getType() {
|
||||
return Model.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model intoCache(Model data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model fromCache(Model data) {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,79 +18,57 @@
|
|||
*/
|
||||
package org.apache.maven.repository.internal;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.maven.building.Source;
|
||||
import org.apache.maven.model.building.ModelCache;
|
||||
import org.eclipse.aether.RepositoryCache;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* A model builder cache backed by the repository system cache.
|
||||
*
|
||||
*/
|
||||
public class DefaultModelCache implements ModelCache {
|
||||
|
||||
private static final String KEY = DefaultModelCache.class.getName();
|
||||
|
||||
private final Map<Object, Supplier<?>> cache;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ModelCache newInstance(RepositorySystemSession session) {
|
||||
Map<Object, Supplier<?>> cache;
|
||||
if (session.getCache() == null) {
|
||||
ConcurrentHashMap<Object, Supplier<?>> cache;
|
||||
RepositoryCache repositoryCache = session.getCache();
|
||||
if (repositoryCache == null) {
|
||||
cache = new ConcurrentHashMap<>();
|
||||
} else {
|
||||
cache = (Map) session.getCache().get(session, KEY);
|
||||
if (cache == null) {
|
||||
cache = new ConcurrentHashMap<>();
|
||||
session.getCache().put(session, KEY, cache);
|
||||
}
|
||||
cache = (ConcurrentHashMap<Object, Supplier<?>>)
|
||||
repositoryCache.computeIfAbsent(session, KEY, ConcurrentHashMap::new);
|
||||
}
|
||||
return new DefaultModelCache(cache);
|
||||
}
|
||||
|
||||
private DefaultModelCache(Map<Object, Supplier<?>> cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
private final ConcurrentMap<Object, Supplier<?>> cache;
|
||||
|
||||
public Object get(Source path, String tag) {
|
||||
return get(new SourceCacheKey(path, tag));
|
||||
}
|
||||
|
||||
public void put(Source path, String tag, Object data) {
|
||||
put(new SourceCacheKey(path, tag), data);
|
||||
private DefaultModelCache(ConcurrentMap<Object, Supplier<?>> cache) {
|
||||
this.cache = requireNonNull(cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String groupId, String artifactId, String version, String tag) {
|
||||
return get(new GavCacheKey(groupId, artifactId, version, tag));
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public <T> T computeIfAbsent(
|
||||
String groupId, String artifactId, String version, String tag, Supplier<Supplier<T>> data) {
|
||||
Object obj = computeIfAbsent(new GavCacheKey(groupId, artifactId, version, tag), (Supplier) data);
|
||||
return (T) obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String groupId, String artifactId, String version, String tag, Object data) {
|
||||
put(new GavCacheKey(groupId, artifactId, version, tag), data);
|
||||
}
|
||||
|
||||
protected Object get(Object key) {
|
||||
Supplier<?> s = cache.get(key);
|
||||
return s != null ? s.get() : null;
|
||||
}
|
||||
|
||||
protected void put(Object key, Object data) {
|
||||
cache.put(key, () -> data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object computeIfAbsent(
|
||||
String groupId, String artifactId, String version, String tag, Supplier<Supplier<?>> data) {
|
||||
return computeIfAbsent(new GavCacheKey(groupId, artifactId, version, tag), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object computeIfAbsent(Source path, String tag, Supplier<Supplier<?>> data) {
|
||||
return computeIfAbsent(new SourceCacheKey(path, tag), data);
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public <T> T computeIfAbsent(Source path, String tag, Supplier<Supplier<T>> data) {
|
||||
Object obj = computeIfAbsent(new SourceCacheKey(path, tag), (Supplier) data);
|
||||
return (T) obj;
|
||||
}
|
||||
|
||||
protected Object computeIfAbsent(Object key, Supplier<Supplier<?>> data) {
|
||||
|
|
Loading…
Reference in New Issue