Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MNG-8575] Replace a list with O(N²) performance by O(N) at least during iteration. #2092

Merged
merged 4 commits into from
Feb 11, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Path;
import java.util.AbstractList;
import java.util.AbstractSequentialList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
import java.util.stream.Stream;

Expand Down Expand Up @@ -146,9 +146,9 @@ public class MavenProject implements Cloneable {
private List<MavenProject> collectedProjects;

/**
* All sources of this project. The map includes main and test codes for all languages.
* All sources of this project, in the order they were added.
*/
private List<SourceRoot> sources = new CopyOnWriteArrayList<>();
private Set<SourceRoot> sources = new LinkedHashSet<>();

@Deprecated
private ArtifactRepository releaseArtifactRepository;
Expand Down Expand Up @@ -317,22 +317,16 @@ public DependencyManagement getDependencyManagement() {
// ----------------------------------------------------------------------

/**
* Adds the given source. If a source already exists for the given scope, language and directory,
* then this method either does nothing if all other properties are equal, or thrown
* {@linkplain IllegalArgumentException} otherwise.
* Adds the given source if not already present.
*
* @param source the source to add
* @throws IllegalArgumentException if a source exists for the given language, scope and directory
* but with different values for the other properties.
*
* @see #getSourceRoots()
*
* @since 4.0.0
*/
public void addSourceRoot(SourceRoot source) {
if (!sources.contains(source)) {
sources.add(source);
}
sources.add(source);
}

/**
Expand Down Expand Up @@ -738,56 +732,47 @@ public Build getBuild() {
*/
@Deprecated(since = "4.0.0")
public List<Resource> getResources() {
return new AbstractList<>() {
@Override
public Resource get(int index) {
return toResource(getEnabledSourceRoots(ProjectScope.MAIN, Language.RESOURCES)
.toList()
.get(index));
}

@Override
public int size() {
return (int) getEnabledSourceRoots(ProjectScope.MAIN, Language.RESOURCES)
.count();
}

@Override
public boolean add(Resource resource) {
addResource(resource);
return true;
}
};
return getResources(ProjectScope.MAIN);
}

/**
* @deprecated Replaced by {@code getEnabledSourceRoots(ProjectScope.TEST, Language.RESOURCES)}.
*/
@Deprecated(since = "4.0.0")
public List<Resource> getTestResources() {
return new AbstractList<>() {
return getResources(ProjectScope.TEST);
}

private List<Resource> getResources(final ProjectScope scope) {
return new AbstractSequentialList<>() {
private Stream<SourceRoot> sources() {
return getEnabledSourceRoots(scope, Language.RESOURCES);
}

@Override
public Resource get(int index) {
return toResource(getEnabledSourceRoots(ProjectScope.TEST, Language.RESOURCES)
.toList()
.get(index));
public ListIterator<Resource> listIterator(int index) {
return sources().map(MavenProject::toResource).toList().listIterator(index);
}

@Override
public int size() {
return (int) getEnabledSourceRoots(ProjectScope.TEST, Language.RESOURCES)
.count();
return Math.toIntExact(sources().count());
}

@Override
public boolean isEmpty() {
return sources().findAny().isEmpty();
}

@Override
public boolean add(Resource resource) {
addTestResource(resource);
addResource(scope, resource);
return true;
}
};
}

private Resource toResource(SourceRoot sourceRoot) {
private static Resource toResource(SourceRoot sourceRoot) {
return new Resource(org.apache.maven.api.model.Resource.newBuilder()
.directory(sourceRoot.directory().toString())
.includes(sourceRoot.includes().stream().map(Object::toString).toList())
Expand All @@ -796,20 +781,24 @@ private Resource toResource(SourceRoot sourceRoot) {
.build());
}

private void addResource(ProjectScope scope, Resource resource) {
addSourceRoot(new DefaultSourceRoot(getBaseDirectory(), scope, resource.getDelegate()));
}

/**
* @deprecated {@link Resource} is replaced by {@link SourceRoot}.
*/
@Deprecated(since = "4.0.0")
public void addResource(Resource resource) {
addSourceRoot(new DefaultSourceRoot(getBaseDirectory(), ProjectScope.MAIN, resource.getDelegate()));
addResource(ProjectScope.MAIN, resource);
}

/**
* @deprecated {@link Resource} is replaced by {@link SourceRoot}.
*/
@Deprecated(since = "4.0.0")
public void addTestResource(Resource testResource) {
addSourceRoot(new DefaultSourceRoot(getBaseDirectory(), ProjectScope.TEST, testResource.getDelegate()));
addResource(ProjectScope.TEST, testResource);
}

public void setLicenses(List<License> licenses) {
Expand Down Expand Up @@ -1337,7 +1326,7 @@ private void deepCopy(MavenProject project) {
// This property is not handled like others as we don't use public API.
// The whole implementation of this `deepCopy` method may need revision,
// but it would be the topic for a separated commit.
sources = new CopyOnWriteArrayList<>(project.sources);
sources = new LinkedHashSet<>(project.sources);

if (project.getModel() != null) {
setModel(project.getModel().clone());
Expand Down