Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 315162 - Proposal for startup performance improvement
Summary: Proposal for startup performance improvement
Status: CLOSED FIXED
Alias: None
Product: Virgo
Classification: RT
Component: unknown (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Steve Powell CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-01 01:07 EDT by Nikolai Tankov CLA
Modified: 2010-09-28 03:57 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nikolai Tankov CLA 2010-06-01 01:07:22 EDT
Hi , 
 
Startup is too slow on Windows and I experimented with following changes in ...kernel.install.artifact.internal.StandardArtifactStorage 
The changes are in 2 methods : 

    private void stashContent() {
        if (this.baseStagingPathReference.exists()) {
            this.pastStagingPathReference.delete(true);            

            //move from base to past recursively
            //this.baseStagingPathReference.copy(this.pastStagingPathReference, true);
            //this.baseStagingPathReference.delete(true);
            move(pastStagingPathReference.toFile(), baseStagingPathReference.toFile());
        }
    } 

    private void unstashContent() {
        if (this.pastStagingPathReference.exists()) {
            this.baseStagingPathReference.delete(true);            

            //move from past to base recursively
            //this.pastStagingPathReference.copy(this.baseStagingPathReference, true);
            //this.pastStagingPathReference.delete(true);
            move(baseStagingPathReference.toFile(), pastStagingPathReference.toFile());
        }
    }

And one additional method was added :

      public static void move(File target, File source) {
            if (source.exists()) {
                  if (source.isFile()) {
                        source.renameTo(target);
                  } else {
                        String[] files = source.list();
                        if (files != null) {
                              for (String name : files) {
                                    File sourceFile = new File(source, name);
                                    File targetFile = new File(target, name);
                                    sourceFile.renameTo(targetFile);
                              }                             
                        }
                        source.delete();
                  }
            }
      }

With this simple change I was able to achieve 5-8% improvement on my machine. Probably same optimization is also applicable in other classes but I did not checked.  

Best regards, 
  Nikolai.
Comment 1 Steve Powell CLA 2010-06-01 07:41:28 EDT
(In reply to comment #0)
Thanks Nikolai,

This is a really useful patch suggestion.  I notice that the code applies quite well to single-level directories, and for the un/stashContent() methods explicitly.

I would like to make the 'move' function available more generally, and so I want to generalise your patch to a method called 'moveTo' on org.eclipse.virgo.util.io.PathReference. 

In order to understand it better I have a few questions:

- can you explain why you don't rename directories directly? does this fail on Windows? It should work fine on Unix.

- when rename of a directory is required the immediate children are renamed first (but the top-level directory is not renamed) and the source directory is then deleted (it is presumably empty). What happens if the children are directories?

I also want to make a few suggestions of my own:

- it would be better if the result of the File.renameTo() methods was not ignored.  If any of the renames fail (this might be a hard failure if the rename crosses filesystems) the resulting mess could be considerable.

- if there are pre-conditions on the use of the method StandardArtifactStorage#move(File, File) they should be documented in the comments of the method. 

This patch suggestion is really important to us and this will turn out to be a very valuable contribution to the code base.

I have a proposed change to PathReference (and to the un/stashContent() methods to call it) which I will post here when it is finalised.

Steve Powell
Comment 2 Steve Powell CLA 2010-07-12 05:24:37 EDT
The git commits on util:
    Fri May 21 2010 17:43:00 60ecdfbc05 (Added moveTo() operation to PathReference (plus tests).)
    Wed Jun 09 2010 16:41:44 d92ba88c69 (Added explicit test for moveTo to check that fast move works.)
    Wed Jun 09 2010 20:19:54 530c29e26a (Add test for coverage of moveTo() method on PathReference.)

added the moveTo() method on class PathReference; which is used extensively in kernel code for file manipulation.

The git commit on kernel:
    Tue Jun 15 2010 12:46:30 8dda7f9a06 (Exploit PathReference.moveTo() in kernel deployer for performance.)

modified StandardArtifactStorage and DeployerRecoveryLog to use moveTo().

These changes made it into 2.1.0.M01.

The performance improvements were not re-measured, and although expected to be modest, combined with other improvements to startup we should see benefit from this change.
Comment 3 Steve Powell CLA 2010-08-06 04:13:19 EDT
Done