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

Optimization to building OPAL Class Hierarchies #490

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -18,18 +18,16 @@

package eu.fasten.analyzer.javacgopal.data;

import com.google.common.collect.Lists;
import eu.fasten.analyzer.javacgopal.data.analysis.OPALClassHierarchy;
import eu.fasten.analyzer.javacgopal.data.analysis.OPALMethod;
import eu.fasten.analyzer.javacgopal.data.analysis.OPALType;
import eu.fasten.core.data.Constants;
import eu.fasten.core.data.JavaGraph;
import eu.fasten.core.data.PartialJavaCallGraph;
import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import eu.fasten.core.data.opal.MavenArtifactDownloader;
import eu.fasten.core.data.opal.MavenCoordinate;
import eu.fasten.core.data.opal.exceptions.OPALException;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.text.StringEscapeUtils;
import org.opalj.br.Annotation;
Expand All @@ -45,20 +43,20 @@
import org.opalj.value.ValueInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

import eu.fasten.analyzer.javacgopal.data.analysis.OPALClassHierarchy;
import eu.fasten.analyzer.javacgopal.data.analysis.OPALMethod;
import eu.fasten.analyzer.javacgopal.data.analysis.OPALType;
import eu.fasten.core.data.Constants;
import eu.fasten.core.data.JavaGraph;
import eu.fasten.core.data.opal.MavenArtifactDownloader;
import eu.fasten.core.data.opal.MavenCoordinate;
import eu.fasten.core.data.opal.exceptions.OPALException;
import scala.Function1;
import scala.collection.JavaConverters;

import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Call graphs that are not still fully resolved. i.e. isolated call graphs which within-artifact
* calls (edges) are known as internal calls and Cross-artifact calls are known as external calls.
Expand All @@ -85,7 +83,7 @@ public OPALPartialCallGraph construct(OPALCallGraph ocg, CallPreservationStrateg
createGraphWithExternalCHA(ocg, cha, callSiteOnly);

pcg.nodeCount = cha.getNodeCount();
pcg.classHierarchy = cha.asURIHierarchy(ocg.project.classHierarchy());
pcg.classHierarchy = cha.asURIHierarchyParallel(ocg.project.classHierarchy());
} catch (Exception e) {
if (e.getStackTrace().length > 0) {
var stackTrace = e.getStackTrace()[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@

package eu.fasten.analyzer.javacgopal.data.analysis;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import eu.fasten.analyzer.javacgopal.data.CallPreservationStrategy;
import eu.fasten.core.data.FastenURI;
import eu.fasten.core.data.JavaGraph;
import eu.fasten.core.data.JavaScope;
import eu.fasten.core.data.JavaType;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import org.opalj.br.ClassHierarchy;
import org.opalj.br.DeclaredMethod;
import org.opalj.br.Method;
Expand All @@ -38,17 +34,21 @@
import org.opalj.tac.Stmt;
import org.opalj.tac.UVar;
import org.opalj.value.ValueInformation;

import eu.fasten.analyzer.javacgopal.data.CallPreservationStrategy;
import eu.fasten.core.data.FastenURI;
import eu.fasten.core.data.JavaGraph;
import eu.fasten.core.data.JavaScope;
import eu.fasten.core.data.JavaType;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import scala.Tuple2;
import scala.collection.Iterator;
import scala.collection.JavaConverters;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
* Class hierarchy class containing two types of CHA - internal and external CHA
* and also keeping track of node count.
Expand Down Expand Up @@ -111,6 +111,34 @@ public EnumMap<JavaScope, Map<String, JavaType>> asURIHierarchy(ClassHierarchy p
JavaScope.resolvedTypes, new HashMap<>()));
}

/**
* An optimized version of `asURIHierarchy`.
* Converts all of the members of the classHierarchy to {@link FastenURI}.
*
* @param projectHierarchy OPAL class hierarchy
* @return A {@link Map} of {@link FastenURI} and {@link JavaType}
*/
public EnumMap<JavaScope, Map<String, JavaType>> asURIHierarchyParallel(ClassHierarchy projectHierarchy) {

final Map<String, JavaType> internalResult = new ConcurrentHashMap<>();
final Map<String, JavaType> externalResult = new ConcurrentHashMap<>();
final var internals = this.getInternalCHA();

internals.keySet().stream().parallel().forEach(aClass -> {
final var klass = OPALType.getType(internals.get(aClass), aClass);
internalResult.put(klass.getLeft(), klass.getRight());
});

final var externals = this.getExternalCHA();
externals.keySet().stream().parallel().forEach(aClass -> {
externalResult
.putAll(OPALType.getType(projectHierarchy, externals.get(aClass), aClass));
});

return new EnumMap<>(Map.of(JavaScope.internalTypes, internalResult, JavaScope.externalTypes, externalResult,
JavaScope.resolvedTypes, new HashMap<>()));
}

/**
* Adds a method to the external CHA if the method doesn't already exist.
* Otherwise returns and ID of the existing method.
Expand Down