logic: greatly improved Java indexing performance

* about 120% faster now
* also fixed minor synchronization issues
This commit is contained in:
malte_langkabel
2017-08-17 13:28:00 +02:00
parent cbbcc98832
commit 70997adc9c
6 changed files with 94 additions and 29 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,25 +3,25 @@ package com.sourcetrail;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.String;
import java.util.HashMap;
import java.util.Map;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseProblemException;
import com.github.javaparser.Position;
import com.github.javaparser.Problem;
import com.github.javaparser.Range;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.symbolsolver.javaparser.Navigator;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import com.sourcetrail.typesolver.SynchronizedJavaParserTypeSolver;
public class JavaIndexer
{
private static Map<String, TypeSolver> typeSolvers = new HashMap<>();
@@ -37,36 +37,40 @@ public class JavaIndexer
CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
combinedTypeSolver.add(new ReflectionTypeSolver());
for (String path: classPath.split("\\;"))
synchronized (typeSolvers)
{
if (typeSolvers.containsKey(path))
for (String path: classPath.split("\\;"))
{
combinedTypeSolver.add(typeSolvers.get(path));
}
else
{
TypeSolver typeSolver = null;
if (path.endsWith(".jar"))
if (typeSolvers.containsKey(path))
{
try
{
typeSolver = new JarTypeSolver(path);
}
catch (IOException e)
{
System.out.println("unable to add jar file: " + path);
}
combinedTypeSolver.add(typeSolvers.get(path));
}
else if (!path.isEmpty())
else
{
typeSolver = new JavaParserTypeSolver(new File(path));
}
if (typeSolver != null)
{
typeSolvers.put(path, typeSolver);
combinedTypeSolver.add(typeSolver);
TypeSolver typeSolver = null;
if (path.endsWith(".jar"))
{
try
{
typeSolver = new JarTypeSolver(path);
}
catch (IOException e)
{
System.out.println("unable to add jar file: " + path);
}
}
else if (!path.isEmpty())
{
typeSolver = new SynchronizedJavaParserTypeSolver(new File(path));
}
if (typeSolver != null)
{
typeSolvers.put(path, typeSolver);
combinedTypeSolver.add(typeSolver);
}
}
}
}
@@ -0,0 +1,53 @@
package com.sourcetrail.typesolver;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
public class SynchronizedJavaParserTypeSolver extends JavaParserTypeSolver
{
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private Map<String, SymbolReference<ReferenceTypeDeclaration>> solvedTypes = new HashMap<>();
public SynchronizedJavaParserTypeSolver(File srcDir)
{
super(srcDir);
}
@Override
public SymbolReference<ReferenceTypeDeclaration> tryToSolveType(String name)
{
SymbolReference<ReferenceTypeDeclaration> solvedType = SymbolReference.unsolved(ReferenceTypeDeclaration.class);
{
lock.readLock().lock();
if (solvedTypes.containsKey(name))
{
solvedType = solvedTypes.get(name);
}
lock.readLock().unlock();
}
if (!solvedType.isSolved())
{
solvedType = super.tryToSolveType(name);
if (solvedType.isSolved())
{
lock.writeLock().lock();
if (!solvedTypes.containsKey(name))
{
solvedTypes.put(name, solvedType);
}
lock.writeLock().unlock();
}
}
return solvedType;
}
}