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
-~----------~----~----~----~------~----~------~--~---

Reply via email to