Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 481001

Summary: Eclipse Filesystem Refresh takes minutes to hours if many files are in same folder
Product: [Eclipse Project] Platform Reporter: Moritz Eysholdt <moritz.eysholdt>
Component: RuntimeAssignee: platform-runtime-inbox <platform-runtime-inbox>
Status: CLOSED DUPLICATE QA Contact:
Severity: normal    
Priority: P3 CC: sebastian.zarnekow, sptaszkiewicz
Version: 4.6   
Target Milestone: ---   
Hardware: PC   
OS: Mac OS X   
Whiteboard:

Description Moritz Eysholdt CLA 2015-10-29 10:18:11 EDT
steps to reproduce

1. Create a new Java Project
2. Create a class with the following main method:

----------------
public static void main(String[] args) {
	File dir = new File("./gen/");
	dir.mkdirs();
	for (int i = 1; i <= 10000; i++) {
		try {
			new File(dir, "file" + i + ".txt").createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
----------------

3. Run the main method.
4. In the Package Explorer, select the project, open the context menu, and click on "refresh". 
5. Observe that the "Refresh" job seems to stall at 0%. 

Analysis:
See blow for the JStack Stacktrace for where exactly "Refresh" is spending its time.

The problem is probably the code from
org.eclipse.core.internal.filesystem.local.unix.UnixFileNatives.fetchFileInfo(UnixFileNatives.java:108):

----------------
String[] names = file.getParentFile().list(new FilenameFilter() {
	@Override
	public boolean accept(File dir, String n) {
		return n.equalsIgnoreCase(lastName);
	}
});
----------------

For each file, the code iterates *again* over every file in the directory and checks if a file with the same name but different case exists. 

That's quadratic runtime complexity. No surprise this code never terminates for me when there are 10.000 files inside a folder. 

It would be great if eclipse would call file.list only *once* per directory. Furthermore, to avoid that matching file names with their case-variying counterparts it may be reasonable to first do a lookup in a map (to handle the scenarios where the case matches) and only do the linear search when the case doesn't match. Or put lower-cased names in a map. But I think str1.toLower().equals(str2.toLower()) == str1.equalsIgnoreCase(str2) is not true for all languages.

In case somebody is about to say that nobody would want to put 10.000 files into the same folder in their project because that's not human manageable. I totally agree. This large number of files are generated debug data. 

Oh, and if fixing this bug leads to a general speedup of the eclipse filesystem refresh, I can't emphasize enough how much I'd appreciate that.


java.lang.Thread.State: RUNNABLE
	at java.io.UnixFileSystem.list(Native Method)
	at java.io.File.list(File.java:1122)
	at java.io.File.list(File.java:1155)
	at org.eclipse.core.internal.filesystem.local.unix.UnixFileNatives.fetchFileInfo(UnixFileNatives.java:108)
	at org.eclipse.core.internal.filesystem.local.unix.UnixFileHandler.fetchFileInfo(UnixFileHandler.java:28)
	at org.eclipse.core.internal.filesystem.local.LocalFileNativesManager.fetchFileInfo(LocalFileNativesManager.java:85)
	at org.eclipse.core.internal.filesystem.local.LocalFile.fetchInfo(LocalFile.java:156)
	at org.eclipse.core.filesystem.provider.FileStore.fetchInfo(FileStore.java:284)
	at org.eclipse.core.filesystem.provider.FileStore.childInfos(FileStore.java:110)
	at org.eclipse.core.internal.localstore.UnifiedTree.getLocalList(UnifiedTree.java:346)
	at org.eclipse.core.internal.localstore.UnifiedTree.addChildren(UnifiedTree.java:138)
	at org.eclipse.core.internal.localstore.UnifiedTree.addNodeChildrenToQueue(UnifiedTree.java:244)
	at org.eclipse.core.internal.localstore.UnifiedTree.accept(UnifiedTree.java:110)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refreshResource(FileSystemResourceManager.java:957)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refresh(FileSystemResourceManager.java:941)
	at org.eclipse.core.internal.resources.Resource.refreshLocal(Resource.java:1593)
	at org.eclipse.ui.actions.RefreshAction.refreshResource(RefreshAction.java:284)
	at org.eclipse.ui.actions.RefreshAction$3.execute(RefreshAction.java:238)
	at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:108)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2241)
	at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:130)
	- locked <0x00000007401e5db0> (a org.eclipse.ui.actions.RefreshAction$3)
	at org.eclipse.jdt.ui.actions.RefreshAction$WrappedWorkbenchRefreshAction.run(RefreshAction.java:113)
	at org.eclipse.jdt.ui.actions.RefreshAction.performRefresh(RefreshAction.java:195)
	at org.eclipse.jdt.ui.actions.RefreshAction.access$0(RefreshAction.java:190)
	at org.eclipse.jdt.ui.actions.RefreshAction$1.run(RefreshAction.java:184)
	at org.eclipse.jdt.internal.core.BatchOperation.executeOperation(BatchOperation.java:39)
	at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:729)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2241)
	at org.eclipse.jdt.core.JavaCore.run(JavaCore.java:5409)
	at org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:106)
	at org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter$1.run(WorkbenchRunnableAdapter.java:122)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)


I'm using 
org.eclipse.core.filesystem_1.5.0.v20150421-0713.jar
Comment 1 Szymon Ptaszkiewicz CLA 2015-10-29 10:31:50 EDT
(In reply to Moritz Eysholdt from comment #0)
> I'm using org.eclipse.core.filesystem_1.5.0.v20150421-0713.jar

This does not correspond to the Version field where you chose 4.6. In 4.6 we have org.eclipse.core.filesystem at version 1.6.0. What is the exact version of your Eclipse?
Comment 2 Moritz Eysholdt CLA 2015-10-29 10:41:34 EDT
(In reply to Szymon Ptaszkiewicz from comment #1)
> (In reply to Moritz Eysholdt from comment #0)
> What is the exact version of your Eclipse?

feature org.eclipse.platform.feature.group has version 4.5.0.v20150603-2358

Is that the version you wanted to know?
Comment 4 Szymon Ptaszkiewicz CLA 2015-10-29 10:49:33 EDT
(In reply to Moritz Eysholdt from comment #3)
> It looks like the problem was introduced here:
> http://git.eclipse.org/c/platform/eclipse.platform.resources.git/commit/
> bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/
> local/unix/UnixFileNatives.java?id=f0785e1932f0d66008f6d54349f0bbdf341f9c0d
> 
> and it has been fixed here:
> http://git.eclipse.org/c/platform/eclipse.platform.resources.git/commit/
> bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/
> local/unix/UnixFileNatives.java?id=c80ef501e2eb5fe9f033f396852122128fe17f6c
> 
> see bug 470153
> 
> *** This bug has been marked as a duplicate of bug 470153 ***

That's exactly what I wanted to confirm :) Thanks!
Comment 5 Moritz Eysholdt CLA 2015-10-29 11:02:46 EDT
*much* better with 4.5.1. A refresh on a folder with 10k files causes no noticeable delay. Awesome! :-D