Improve performance of source file copier

This commit is contained in:
Alexey Andreev 2017-06-01 16:14:07 +03:00
parent 36f2932caa
commit 89eb87e8ca
5 changed files with 87 additions and 34 deletions

View File

@ -20,10 +20,6 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
/**
*
* @author Alexey Andreev
*/
public class DirectorySourceFileProvider implements SourceFileProvider { public class DirectorySourceFileProvider implements SourceFileProvider {
private File baseDirectory; private File baseDirectory;
@ -40,8 +36,26 @@ public class DirectorySourceFileProvider implements SourceFileProvider {
} }
@Override @Override
public InputStream openSourceFile(String fullPath) throws IOException { public SourceFileInfo getSourceFile(String fullPath) throws IOException {
File file = new File(baseDirectory, fullPath); File file = new File(baseDirectory, fullPath);
return file.exists() ? new FileInputStream(file) : null; return file.exists() ? new DirectorySourceFile(file) : null;
}
static class DirectorySourceFile implements SourceFileInfo {
private File file;
DirectorySourceFile(File file) {
this.file = file;
}
@Override
public long lastModified() {
return file.lastModified();
}
@Override
public InputStream open() throws IOException {
return new FileInputStream(file);
}
} }
} }

View File

@ -24,10 +24,6 @@ import java.util.Set;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
/**
*
* @author Alexey Andreev
*/
public class JarSourceFileProvider implements SourceFileProvider { public class JarSourceFileProvider implements SourceFileProvider {
private File file; private File file;
private ZipFile zipFile; private ZipFile zipFile;
@ -58,11 +54,31 @@ public class JarSourceFileProvider implements SourceFileProvider {
} }
@Override @Override
public InputStream openSourceFile(String fullPath) throws IOException { public SourceFileInfo getSourceFile(String fullPath) throws IOException {
if (zipFile == null || !sourceFiles.contains(fullPath)) { if (zipFile == null || !sourceFiles.contains(fullPath)) {
return null; return null;
} }
ZipEntry entry = zipFile.getEntry(fullPath); ZipEntry entry = zipFile.getEntry(fullPath);
return entry != null ? zipFile.getInputStream(entry) : null; return entry != null ? new JarSourceFile(zipFile, entry) : null;
}
static class JarSourceFile implements SourceFileInfo {
private ZipFile file;
private ZipEntry entry;
JarSourceFile(ZipFile file, ZipEntry entry) {
this.file = file;
this.entry = entry;
}
@Override
public long lastModified() {
return entry.getTime();
}
@Override
public InputStream open() throws IOException {
return file.getInputStream(entry);
}
} }
} }

View File

@ -0,0 +1,25 @@
/*
* Copyright 2017 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.tooling.sources;
import java.io.IOException;
import java.io.InputStream;
public interface SourceFileInfo {
long lastModified();
InputStream open() throws IOException;
}

View File

@ -16,16 +16,11 @@
package org.teavm.tooling.sources; package org.teavm.tooling.sources;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
/**
*
* @author Alexey Andreev
*/
public interface SourceFileProvider { public interface SourceFileProvider {
void open() throws IOException; void open() throws IOException;
void close() throws IOException; void close() throws IOException;
InputStream openSourceFile(String fullPath) throws IOException; SourceFileInfo getSourceFile(String fullPath) throws IOException;
} }

View File

@ -26,10 +26,6 @@ import org.teavm.model.MethodReader;
import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.EmptyTeaVMToolLog;
import org.teavm.tooling.TeaVMToolLog; import org.teavm.tooling.TeaVMToolLog;
/**
*
* @author Alexey Andreev
*/
public class SourceFilesCopier { public class SourceFilesCopier {
private TeaVMToolLog log = new EmptyTeaVMToolLog(); private TeaVMToolLog log = new EmptyTeaVMToolLog();
private List<SourceFileProvider> sourceFileProviders; private List<SourceFileProvider> sourceFileProviders;
@ -66,15 +62,22 @@ public class SourceFilesCopier {
} }
targetDirectory.mkdirs(); targetDirectory.mkdirs();
for (String fileName : sourceFiles) { for (String fileName : sourceFiles) {
try (InputStream input = findSourceFile(fileName)) { try {
if (input != null) { SourceFileInfo sourceFile = findSourceFile(fileName);
File outputFile = new File(targetDirectory, fileName); File outputFile = new File(targetDirectory, fileName);
outputFile.getParentFile().mkdirs(); if (outputFile.exists() && outputFile.lastModified() > sourceFile.lastModified()
try (OutputStream output = new FileOutputStream(outputFile)) { && sourceFile.lastModified() > 0) {
IOUtils.copy(input, output); continue;
}
try (InputStream input = sourceFile.open()) {
if (input != null) {
outputFile.getParentFile().mkdirs();
try (OutputStream output = new FileOutputStream(outputFile)) {
IOUtils.copy(input, output);
}
} else {
log.info("Missing source file: " + fileName);
} }
} else {
log.info("Missing source file: " + fileName);
} }
} catch (IOException e) { } catch (IOException e) {
log.warning("Could not copy source file " + fileName, e); log.warning("Could not copy source file " + fileName, e);
@ -89,11 +92,11 @@ public class SourceFilesCopier {
} }
} }
private InputStream findSourceFile(String fileName) throws IOException { private SourceFileInfo findSourceFile(String fileName) throws IOException {
for (SourceFileProvider provider : sourceFileProviders) { for (SourceFileProvider provider : sourceFileProviders) {
InputStream input = provider.openSourceFile(fileName); SourceFileInfo sourceFile = provider.getSourceFile(fileName);
if (input != null) { if (sourceFile != null) {
return input; return sourceFile;
} }
} }
return null; return null;