Skip to content

Commit

Permalink
Changed to use cached class index
Browse files Browse the repository at this point in the history
  • Loading branch information
mopemope committed Jun 22, 2017
1 parent 6db8ed9 commit e22b1bb
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 66 deletions.
3 changes: 1 addition & 2 deletions src/main/java/meghanada/junit/TestRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import meghanada.reflect.ClassIndex;
import meghanada.reflect.asm.CachedASMReflector;
import meghanada.store.ProjectDatabaseHelper;
import meghanada.utils.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.runner.JUnitCore;
Expand Down Expand Up @@ -59,7 +58,7 @@ public static void main(String... args) throws Exception {
private void cleanup() throws Exception {
ProjectDatabaseHelper.shutdown();
String p = System.getProperty(TEMP_PROJECT_SETTING_DIR);
FileUtils.deleteFiles(new File(p), true);
org.apache.commons.io.FileUtils.deleteDirectory(new File(p));
}

private List<Class<?>> getTestClass(String testName) throws ClassNotFoundException {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/meghanada/location/LocationSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ private Location searchLocationFromDecompileFile(
}
return null;
} finally {
FileUtils.deleteFiles(output, false);
org.apache.commons.io.FileUtils.deleteDirectory(output);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/meghanada/project/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ public void clearCache() throws IOException {
System.setProperty(PROJECT_ROOT_KEY, this.projectRootPath);
final File projectSettingDir = new File(Config.load().getProjectSettingDir());
log.info("clear cache {}", projectSettingDir);
FileUtils.deleteFiles(projectSettingDir, false);
org.apache.commons.io.FileUtils.deleteDirectory(projectSettingDir);
}

private Optional<Properties> readFormatPropertiesFromFile() {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/meghanada/reflect/ClassIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
public class ClassIndex implements CandidateUnit, Cloneable, Serializable, Storable {

public static final String ENTITY_TYPE = "ClassIndex";
public static final String FILE_ENTITY_TYPE = "ClassIndexFile";
private static final long serialVersionUID = 4833311903131990013L;

// fqcn
Expand All @@ -33,6 +34,7 @@ public class ClassIndex implements CandidateUnit, Cloneable, Serializable, Stora
private String filePath;
private MemberType memberType = MemberType.CLASS;
private EntityId entityID;
public transient boolean loaded;

public ClassIndex(
final String declaration, final List<String> typeParameters, final List<String> supers) {
Expand Down
56 changes: 37 additions & 19 deletions src/main/java/meghanada/reflect/asm/CachedASMReflector.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,32 +133,50 @@ public void createClassIndexes() {
.forEach(
wrapIOConsumer(
root -> {
// TODO is loaded ?
final ASMReflector reflector = ASMReflector.getInstance();
reflector
.getClasses(root)
.entrySet()
.parallelStream()
.forEach(entry -> addClassIndex(entry.getKey(), entry.getValue()));
String name = root.getName();
if (name.endsWith(".jar")
&& !name.endsWith("SNAPSHOT.jar")
&& ProjectDatabaseHelper.getLoadJar(root.getPath())) {
List<ClassIndex> indexes =
ProjectDatabaseHelper.getClassIndexes(root.getPath());

for (ClassIndex index : indexes) {
index.loaded = true;
String fqcn = index.getRawDeclaration();
this.globalClassIndex.put(fqcn, index);
}
} else {
final ASMReflector reflector = ASMReflector.getInstance();
reflector
.getClasses(root)
.entrySet()
.parallelStream()
.forEach(entry -> addClassIndex(entry.getKey(), entry.getValue()));
if (name.endsWith(".jar") && !name.endsWith("SNAPSHOT.jar")) {
ProjectDatabaseHelper.saveLoadJar(root.getPath());
}
}
}));

this.updateClassIndexFromDirectory();
this.saveAllClassIndexes();
}

private void saveAllClassIndexes() {
List<ClassIndex> jarIndexes =
globalClassIndex
.values()
.stream()
.filter(classIndex -> classIndex.getFilePath().endsWith(".jar"))
.collect(Collectors.toList());
List<ClassIndex> otherIndexes =
globalClassIndex
.values()
.stream()
.filter(classIndex -> !classIndex.getFilePath().endsWith(".jar"))
.collect(Collectors.toList());
List<ClassIndex> jarIndexes = new ArrayList<>();
List<ClassIndex> otherIndexes = new ArrayList<>();
globalClassIndex
.values()
.forEach(
index -> {
if (!index.getFilePath().endsWith(".jar")) {
otherIndexes.add(index);
} else {
if (!index.loaded) {
jarIndexes.add(index);
}
}
});

ProjectDatabaseHelper.saveClassIndexes(jarIndexes, false);
ProjectDatabaseHelper.saveClassIndexes(otherIndexes, true);
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/meghanada/store/ProjectDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import meghanada.Main;
import meghanada.config.Config;
import meghanada.project.Project;
import meghanada.utils.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand Down Expand Up @@ -89,7 +88,7 @@ private ProjectDatabase() {
}));
}

public static ProjectDatabase getInstance() {
public static synchronized ProjectDatabase getInstance() {
checkChangeProject();
if (projectDatabase != null) {
projectDatabase.open();
Expand Down Expand Up @@ -330,7 +329,7 @@ private void open() {
if (nonNull(files)) {
for (File file : files) {
if (file.isDirectory() && file.getName().startsWith(name) && !file.equals(base)) {
FileUtils.deleteFiles(file, true);
org.apache.commons.io.FileUtils.deleteDirectory(file);
}
}
}
Expand All @@ -339,7 +338,7 @@ private void open() {
this.environment = Environments.newInstance(base);
} catch (ExodusException ex) {
// try re-create
FileUtils.deleteFiles(base, true);
org.apache.commons.io.FileUtils.deleteDirectory(base);
this.environment = Environments.newInstance(base);
}
this.entityStore = PersistentEntityStores.newInstance(environment, STORE_NAME);
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/meghanada/store/ProjectDatabaseHelper.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package meghanada.store;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -46,6 +47,45 @@ public static void saveClassIndexes(Collection<ClassIndex> indexes, boolean allo
}
}

public static boolean getLoadJar(String filePath) {
ProjectDatabase database = ProjectDatabase.getInstance();
return database.computeInReadonly(
txn -> {
EntityIterable it = txn.find(ClassIndex.FILE_ENTITY_TYPE, "filePath", filePath);
return nonNull(it.getFirst());
});
}

public static void saveLoadJar(String filePath) {
ProjectDatabase database = ProjectDatabase.getInstance();
database.execute(
txn -> {
EntityIterable it = txn.find(ClassIndex.FILE_ENTITY_TYPE, "filePath", filePath);
if (nonNull(it.getFirst())) {
return false;
}
Entity entity = txn.newEntity(ClassIndex.FILE_ENTITY_TYPE);
entity.setProperty("filePath", filePath);
return true;
});
}

public static List<ClassIndex> getClassIndexes(String filePath) {
ProjectDatabase database = ProjectDatabase.getInstance();
return database.find(
ClassIndex.ENTITY_TYPE,
"filePath",
filePath,
entity -> {
try (InputStream in = entity.getBlob(ProjectDatabase.SERIALIZE_KEY)) {
return Serializer.readObject(in, ClassIndex.class);
} catch (Exception e) {
log.warn(e.getMessage());
return null;
}
});
}

public static File getClassFile(String fqcn) {
ProjectDatabase database = ProjectDatabase.getInstance();
Optional<String> res =
Expand Down
30 changes: 0 additions & 30 deletions src/main/java/meghanada/utils/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,36 +121,6 @@ public static Optional<File> collectFile(final File root, final String ext) thro
}
}

public static void deleteFiles(final File root, final boolean deleteRoot) throws IOException {
if (!root.exists()) {
return;
}
Files.walkFileTree(
root.toPath(),
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc)
throws IOException {
if (deleteRoot) {
Files.delete(dir);
} else {
if (!dir.toFile().equals(root)) {
Files.delete(dir);
}
}

return FileVisitResult.CONTINUE;
}
});
}

public static boolean filterFile(final File file) {
final Config config = Config.load();

Expand Down
5 changes: 3 additions & 2 deletions src/test/java/meghanada/GradleTestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ protected static File getTestOutput() {
public static void setupReflector() throws Exception {
setupProject();
CachedASMReflector cachedASMReflector = CachedASMReflector.getInstance();
cachedASMReflector.getGlobalClassIndex().clear();
addClasspath(cachedASMReflector);
final Stopwatch stopwatch = Stopwatch.createStarted();
cachedASMReflector.createClassIndexes();
Expand All @@ -136,11 +137,11 @@ public static void shutdown() throws IOException, InterruptedException {
ProjectDatabaseHelper.shutdown();
String p = System.getProperty(TEMP_PROJECT_SETTING_DIR);
File file = new File(p);
FileUtils.deleteFiles(file, true);
org.apache.commons.io.FileUtils.deleteDirectory(file);
assert !file.exists();
String tempPath = GradleProject.getTempPath();
if (nonNull(tempPath)) {
FileUtils.deleteFiles(new File(tempPath), true);
org.apache.commons.io.FileUtils.deleteDirectory(new File(tempPath));
}
log.info("deleted database {}", file);
}
Expand Down
5 changes: 2 additions & 3 deletions src/test/java/meghanada/project/gradle/GradleProjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import meghanada.project.Project;
import meghanada.reflect.asm.CachedASMReflector;
import meghanada.store.ProjectDatabaseHelper;
import meghanada.utils.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.AfterClass;
Expand All @@ -36,10 +35,10 @@ public static void shutdown() throws Exception {
ProjectDatabaseHelper.shutdown();
String p = System.getProperty(TEMP_PROJECT_SETTING_DIR);
File file = new File(p);
FileUtils.deleteFiles(file, true);
org.apache.commons.io.FileUtils.deleteDirectory(file);
String tempPath = GradleProject.getTempPath();
if (nonNull(tempPath)) {
FileUtils.deleteFiles(new File(tempPath), true);
org.apache.commons.io.FileUtils.deleteDirectory(new File(tempPath));
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/test/java/meghanada/store/ProjectDatabaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.util.List;
import meghanada.project.Project;
import meghanada.reflect.ClassIndex;
import meghanada.utils.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
Expand All @@ -31,8 +30,7 @@ public void setup() throws Exception {
tempDir.deleteOnExit();
final String path = tempDir.getCanonicalPath();
System.setProperty(TEMP_PROJECT_SETTING_DIR, path);
FileUtils.deleteFiles(new File(path), true);

org.apache.commons.io.FileUtils.deleteDirectory(new File(path));
String projectRoot = new File(".").getCanonicalPath();
System.setProperty(Project.PROJECT_ROOT_KEY, projectRoot);

Expand All @@ -45,7 +43,7 @@ public void tearDown() throws InterruptedException, IOException {
database.shutdown();
}
String p = System.getProperty(TEMP_PROJECT_SETTING_DIR);
FileUtils.deleteFiles(new File(p), true);
org.apache.commons.io.FileUtils.deleteDirectory(new File(p));
}

@Test
Expand Down

0 comments on commit e22b1bb

Please sign in to comment.