Author: sco...@google.com Date: Mon May 11 17:09:17 2009 New Revision: 5343
Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardGeneratedResource.java trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardPublicResource.java Log: Optimize Link production of output directory. This is done by added a method to EmittedArtifact that returns a byte[] directly, which can then be written out in one shot. The default implementation reads from the existing stream API, but the important implementation classes have a much better implementation. Review by: spoon Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java Mon May 11 17:09:17 2009 @@ -18,7 +18,10 @@ import com.google.gwt.core.ext.Linker; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; +import com.google.gwt.dev.util.Util; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; /** @@ -44,6 +47,20 @@ super(linker); assert partialPath != null; this.partialPath = partialPath; + } + + /** + * Provides access to the contents of the EmittedResource as a byte buffer. + */ + public byte[] getBytes(TreeLogger logger) throws UnableToCompleteException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + Util.copy(getContents(logger), baos); + } catch (IOException e) { + logger.log(TreeLogger.ERROR, "Unable to read stream", e); + throw new UnableToCompleteException(); + } + return baos.toByteArray(); } /** Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java Mon May 11 17:09:17 2009 @@ -46,6 +46,11 @@ } @Override + public byte[] getBytes(TreeLogger logger) throws UnableToCompleteException { + return diskCache.readByteArray(token); + } + + @Override public InputStream getContents(TreeLogger logger) throws UnableToCompleteException { return new ByteArrayInputStream(diskCache.readByteArray(token)); Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardGeneratedResource.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardGeneratedResource.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardGeneratedResource.java Mon May 11 17:09:17 2009 @@ -24,6 +24,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.RandomAccessFile; /** * The standard implementation of {...@link GeneratedResource}. @@ -35,6 +36,19 @@ String partialPath, File file) { super(StandardLinkerContext.class, generatorType, partialPath); this.file = file; + } + + @Override + public byte[] getBytes(TreeLogger logger) throws UnableToCompleteException { + try { + RandomAccessFile raf = new RandomAccessFile(file, "r"); + byte[] buf = new byte[(int) raf.length()]; + raf.readFully(buf); + return buf; + } catch (IOException e) { + logger.log(TreeLogger.ERROR, "Unable to read file", e); + throw new UnableToCompleteException(); + } } @Override Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java Mon May 11 17:09:17 2009 @@ -56,14 +56,17 @@ import java.io.File; import java.io.IOException; +import java.io.RandomAccessFile; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -110,6 +113,25 @@ } }; + /** + * A faster bulk version of {...@link File#mkdirs()} that takes advantage of + * cached state to avoid a lot of file system access. + */ + private static void mkdirs(File dir, Set<String> createdDirs) { + if (dir == null) { + return; + } + String path = dir.getPath(); + if (createdDirs.contains(path)) { + return; + } + if (!dir.exists()) { + mkdirs(dir.getParentFile(), createdDirs); + dir.mkdir(); + } + createdDirs.add(path); + } + private final ArtifactSet artifacts = new ArtifactSet(); private final SortedSet<ConfigurationProperty> configurationProperties; @@ -435,30 +457,47 @@ public void produceOutputDirectory(TreeLogger logger, ArtifactSet artifacts, File outputPath, File extraPath) throws UnableToCompleteException { + outputPath = outputPath.getAbsoluteFile(); + if (extraPath != null) { + extraPath = extraPath.getAbsoluteFile(); + } + logger = logger.branch(TreeLogger.TRACE, "Linking compilation into " + outputPath.getPath(), null); + Set<String> createdDirs = new HashSet<String>(); for (EmittedArtifact artifact : artifacts.find(EmittedArtifact.class)) { - TreeLogger artifactLogger = logger.branch(TreeLogger.DEBUG, - "Emitting resource " + artifact.getPartialPath(), null); + TreeLogger artifactLogger = logger.branch(TreeLogger.DEBUG, + "Emitting resource " + artifact.getPartialPath(), null); - File outFile; - if (artifact.isPrivate()) { - if (extraPath == null) { - continue; - } - outFile = new File(getExtraPathForLinker(extraPath, - artifact.getLinker()), artifact.getPartialPath()); - } else { - outFile = new File(outputPath, artifact.getPartialPath()); - } - - if (!outFile.exists() - || (outFile.lastModified() <= artifact.getLastModified())) { - Util.copy(artifactLogger, artifact.getContents(artifactLogger), outFile); - outFile.setLastModified(artifact.getLastModified()); - } - } + File outFile; + if (artifact.isPrivate()) { + if (extraPath == null) { + continue; + } + outFile = new File(getExtraPathForLinker(extraPath, + artifact.getLinker()), artifact.getPartialPath()); + } else { + outFile = new File(outputPath, artifact.getPartialPath()); + } + + if (!outFile.exists() + || (outFile.lastModified() <= artifact.getLastModified())) { + mkdirs(outFile.getParentFile(), createdDirs); + try { + RandomAccessFile raf = new RandomAccessFile(outFile, "rw"); + byte[] bytes = artifact.getBytes(artifactLogger); + raf.setLength(bytes.length); + raf.write(bytes); + raf.close(); + } catch (IOException e) { + logger.log(TreeLogger.ERROR, "Unable to create file '" + + outFile.getAbsolutePath() + "'", e); + throw new UnableToCompleteException(); + } + outFile.setLastModified(artifact.getLastModified()); + } + } for (StandardCompilationAnalysis soycFiles : artifacts.find(StandardCompilationAnalysis.class)) { TreeLogger artifactLogger = logger.branch(TreeLogger.DEBUG, "Emitting soyc resources.", null); Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardPublicResource.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardPublicResource.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardPublicResource.java Mon May 11 17:09:17 2009 @@ -47,6 +47,11 @@ } @Override + public byte[] getBytes(TreeLogger logger) throws UnableToCompleteException { + return data; + } + + @Override public InputStream getContents(TreeLogger logger) throws UnableToCompleteException { return new ByteArrayInputStream(data); --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---