Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eclipse becomes unresponsive when trying to refresh a viewer with more than 30000 elements on one level #818

Closed
raghucssit opened this issue Jun 12, 2023 · 33 comments · Fixed by #810
Assignees
Labels
bug Something isn't working performance
Milestone

Comments

@raghucssit
Copy link
Contributor

Description:
When we have a large number of files inside a folder in an eclipse workspace refreshing the folder makes the UI freeze.
Large number may depend on machine configuration. As per my test if we have ~30000 files generated on the disk and if we try to refresh the folder under project eclipse freezes. It takes more than 30 seconds to populate tree items in the Package Explorer.

The reason behind this is viewer takes all the time to create Items.

Solution proposed: We will limit the number of Items created and add an Expandable Node. This Expandable Node on click populate next block of Limited elements with another Expandable Node. This way we can keep the Package Explorer responsive.

The goal is to minimize the effort client need to use this solution. So client can implement ILimitBasedContentProvider with the existing content provider and tell us the number items to show in the viewer. WrapperContentProvider is an example and can be used to wrap existing Content Provider.

Below is the screenshot how does it look if we have items limit = 10 and number of files on the file system is 30000.
partition-based-pe2

@iloveeclipse iloveeclipse added bug Something isn't working performance labels Jun 12, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jun 12, 2023
A new interface is introduced which can be implemented with content
provider. User can return number of items to display with this
interface. A wrapper content provider is also implemented. Also there
are snippet example for Tree and Table viewer.
@iloveeclipse iloveeclipse changed the title Eclipse becomes unresponsive when trying to refresh a folder whichcontains more than 30000 files in Package Explorer Eclipse becomes unresponsive when trying to refresh a viewer with more than 30000 elements on one level Jun 12, 2023
@iloveeclipse
Copy link
Member

Note: the main goal here is to provide a small extension to viewers / content providers API that would allow every existing viewer implementation (Package / Project Explorer, JUnit, Search view etc) that can have a huge number of elements to deal with that huge number of elements without freezing UI and without lot of internal code rework.

As the end result we (Advantest) plan to provide patches for all affected SDK views that we are aware of and where we saw freezes.

raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jun 13, 2023
A new interface is introduced which can be implemented with content
provider. User can return number of items to display with this
interface. A wrapper content provider is also implemented. Also there
are snippet example for Tree and Table viewer.
iloveeclipse pushed a commit to raghucssit/eclipse.jdt.ui that referenced this issue Jun 27, 2023
iloveeclipse pushed a commit to raghucssit/eclipse.platform.ui that referenced this issue Jun 27, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 12, 2023
raghucssit added a commit to raghucssit/eclipse.jdt.ui that referenced this issue Jul 12, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 13, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 13, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 13, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 13, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 14, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 17, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 17, 2023
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 17, 2023
A new API has been introduced in ColumnViewer#setItemsLimit(int
newLimit). This will limit the number of items rendered by the viewer
per parent with a node called IExpandableNode which will then render
next block of limited items on selection.

This API is introduced to solve UI freeze caused by Viewer when it tries
to render large number of items at a given level. This is backward
compatible provided clients LabelProvider and ContentProvider safe for
receiving IExpandableNode.

A new preference is introduced to configure viewer limit on any clients
viewer provided they will configure their viewer using
WorkbenchViewerSetupsetupViewer(ColumnViewer viewer). Currently
ProjectExplorer, ContentOutline, MarkersView and SearchResultsView has
been configured to show limited items. Current default for limited items
is 10000

Fixes eclipse-platform#818
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 17, 2023
A new API has been introduced ColumnViewer#setItemsLimit(int
newLimit). This will limit the number of items rendered by the viewer
per parent with a node called IExpandableNode which will then render
next block of limited items on selection.

This API is introduced to solve UI freeze caused by Viewer when it tries
to render large number of items at a given level. This is backward
compatible provided clients LabelProvider and ContentProvider safe for
receiving IExpandableNode.

A new preference is introduced to configure viewer limit on any clients
viewer provided they will configure their viewer using
WorkbenchViewerSetupsetupViewer(ColumnViewer viewer). Currently
ProjectExplorer, ContentOutline, MarkersView and SearchResultsView has
been configured to show limited items. Current default for limited items
is 10000

Fixes eclipse-platform#818
iloveeclipse pushed a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 20, 2023
A new API has been introduced ColumnViewer#setItemsLimit(int
newLimit). This will limit the number of items rendered by the viewer
per parent with a node called IExpandableNode which will then render
next block of limited items on selection.

This API is introduced to solve UI freeze caused by Viewer when it tries
to render large number of items at a given level. This is backward
compatible provided clients LabelProvider and ContentProvider safe for
receiving IExpandableNode.

A new preference is introduced to configure viewer limit on any clients
viewer provided they will configure their viewer using
WorkbenchViewerSetupsetupViewer(ColumnViewer viewer). Currently
ProjectExplorer, ContentOutline, MarkersView and SearchResultsView has
been configured to show limited items. Current default for limited items
is 10000

Fixes eclipse-platform#818
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 20, 2023
A new API has been introduced ColumnViewer#setItemsLimit(int
newLimit). This will limit the number of items rendered by the viewer
per parent with a node called IExpandableNode which will then render
next block of limited items on selection.

This API is introduced to solve UI freeze caused by Viewer when it tries
to render large number of items at a given level. This is backward
compatible provided clients LabelProvider and ContentProvider safe for
receiving IExpandableNode.

A new preference is introduced to configure viewer limit on any clients
viewer provided they will configure their viewer using
WorkbenchViewerSetupsetupViewer(ColumnViewer viewer). Currently
ProjectExplorer, ContentOutline, MarkersView and SearchResultsView has
been configured to show limited items. Current default for limited items
is 10000

Fixes eclipse-platform#818
iloveeclipse pushed a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 20, 2023
New org.eclipse.jface.viewers.ColumnViewer#setItemsLimit(int) API has
been introduced. This API will limit the number of direct children
rendered per parent by the viewers by introducing an intermediate
IExpandableNode element which will then render a subset of original
children and show more elements on demand (user click).

This API is introduced to solve UI freezes caused by viewers when they
try to render large number of items at a given level. The changes made
for the new API should not affect any existing clients, because new
behavior has to be explicitly enabled by using new
ColumnViewer.setItemsLimit(int) API.

For the clients using this new API the change should be mostly backwards
compatible. Clients might need to adopt label provider and viewer code
to make them safe for receiving IExpandableNode from viewer.

Note: clients that extended (not allowed to be extended) TreeViewer
should make sure that isExpandable() returns "false" for
IExpandableNode.

A new workbench preference is introduced to provide a default viewer
limit suitable for most of the clients. Current default value for this
limit is 10000. Clients that adopt new API can use this preference to
configure their viewer by using new
WorkbenchViewerSetup.setupViewer(ColumnViewer) API.

Project Explorer, Outline, Markers, Problems and Search views has
been adopted to the new API and use the new preference to show limited
number of items. Package Explorer adoption for JDT follows in a
separated commit.

Fixes eclipse-platform#818
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 20, 2023
New org.eclipse.jface.viewers.ColumnViewer#setItemsLimit(int) API has
been introduced. This API will limit the number of direct children
rendered per parent by the viewers by introducing an intermediate
IExpandableNode element which will then render a subset of original
children and show more elements on demand (user click).

This API is introduced to solve UI freezes caused by viewers when they
try to render large number of items at a given level. The changes made
for the new API should not affect any existing clients, because new
behavior has to be explicitly enabled by using new
ColumnViewer.setItemsLimit(int) API.

For the clients using this new API the change should be mostly backwards
compatible. Clients might need to adopt label provider and viewer code
to make them safe for receiving IExpandableNode from viewer.

Note: clients that extended (not allowed to be extended) TreeViewer
should make sure that isExpandable() returns "false" for
IExpandableNode.

A new workbench preference is introduced to provide a default viewer
limit suitable for most of the clients. Current default value for this
limit is 10000. Clients that adopt new API can use this preference to
configure their viewer by using new
WorkbenchViewerSetup.setupViewer(ColumnViewer) API.

Project Explorer, Outline, Markers, Problems and Search views has
been adopted to the new API and use the new preference to show limited
number of items. Package Explorer adoption for JDT follows in a
separated commit.

Fixes eclipse-platform#818
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 21, 2023
New org.eclipse.jface.viewers.ColumnViewer#setItemsLimit(int) API has
been introduced. This API will limit the number of direct children
rendered per parent by the viewers by introducing an intermediate
IExpandableNode element which will then render a subset of original
children and show more elements on demand (user click).

This API is introduced to solve UI freezes caused by viewers when they
try to render large number of items at a given level. The changes made
for the new API should not affect any existing clients, because new
behavior has to be explicitly enabled by using new
ColumnViewer.setItemsLimit(int) API.

For the clients using this new API the change should be mostly backwards
compatible. Clients might need to adopt label provider and viewer code
to make them safe for receiving IExpandableNode from viewer.

Note: clients that extended (not allowed to be extended) TreeViewer
should make sure that isExpandable() returns "false" for
IExpandableNode.

A new workbench preference is introduced to provide a default viewer
limit suitable for most of the clients. Current default value for this
limit is 10000. Clients that adopt new API can use this preference to
configure their viewer by using new
WorkbenchViewerSetup.setupViewer(ColumnViewer) API.

Project Explorer, Outline, Markers, Problems and Search views has
been adopted to the new API and use the new preference to show limited
number of items. Package Explorer adoption for JDT follows in a
separated commit.

Fixes eclipse-platform#818
iloveeclipse added a commit to raghucssit/eclipse.platform.ui that referenced this issue Jul 21, 2023
- reduced new API methods
- fixed javadoc
- renamed getVisibleLimitBasedChildren to getChildrenWithLimitApplied
- improved getChildrenWithLimitApplied implementation

Fixes eclipse-platform#818
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Aug 1, 2023
New org.eclipse.jface.viewers.ColumnViewer#setItemsLimit(int) API has
been introduced. This API will limit the number of direct children
rendered per parent by the viewers by introducing an intermediate
IExpandableNode element which will then render a subset of original
children and show more elements on demand (user click).

This API is introduced to solve UI freezes caused by viewers when they
try to render large number of items at a given level. The changes made
for the new API should not affect any existing clients, because new
behavior has to be explicitly enabled by using new
ColumnViewer.setItemsLimit(int) API.

For the clients using this new API the change should be mostly backwards
compatible. Clients might need to adopt label provider and viewer code
to make them safe for receiving IExpandableNode from viewer.

Note: clients that extended (not allowed to be extended) TreeViewer
should make sure that isExpandable() returns "false" for
IExpandableNode.

A new workbench preference is introduced to provide a default viewer
limit suitable for most of the clients. Current default value for this
limit is 10000. Clients that adopt new API can use this preference to
configure their viewer by using new
WorkbenchViewerSetup.setupViewer(ColumnViewer) API.

Project Explorer, Outline, Markers, Problems and Search views has
been adopted to the new API and use the new preference to show limited
number of items. Package Explorer adoption for JDT follows in a
separated commit.

Fixes eclipse-platform#818
raghucssit pushed a commit to raghucssit/eclipse.platform.ui that referenced this issue Aug 1, 2023
- reduced new API methods
- fixed javadoc
- renamed getVisibleLimitBasedChildren to getChildrenWithLimitApplied
- improved getChildrenWithLimitApplied implementation

Fixes eclipse-platform#818
@iloveeclipse
Copy link
Member

Sure, we can set the preference to zero to disable the feature for M3 nd mark API as provisional.
@raghucssit : please prepare PR.

@raghucssit
Copy link
Contributor Author

Sure, we can set the preference to zero to disable the feature for M3 nd mark API as provisional. @raghucssit : please prepare PR.

ok. i will work on it.

raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Aug 16, 2023
As we have observed some issues with limit. We will revert until we fix
the issues.

See eclipse-platform#818
iloveeclipse pushed a commit that referenced this issue Aug 16, 2023
As we have observed some issues with limit. We will revert until we fix
the issues.

See #818
@iloveeclipse
Copy link
Member

Update: so far all known bugs were fixed and by default feature will be not enabled in M3 (preference need to be manually changed by used to enable the feature).

We (Advantest) will continue working on enabling this feature in 4.29 and on implementing reported enhancement requests. Everyone is welcome to help of course :-)

@Phillipus
Copy link
Contributor

Phillipus commented Aug 16, 2023

Thank-you everyone involved for your work and for listening to the community. :-)

raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Aug 22, 2023
It will calculate the location of expandable node, once it enters
visible area of Viewer expand it.

see eclipse-platform#818
fedejeanne pushed a commit to fedejeanne/eclipse.jdt.ui that referenced this issue Aug 23, 2023
Adopt Package Explorer, Outline view contribution and editor breadcrumb
for Java editor to use new JFace API that allows viewers display huge
number of elements without freezing UI.

See eclipse-platform/eclipse.platform.ui#818
and eclipse-platform/eclipse.platform.ui#810.

Fixes eclipse-jdt#631
fedejeanne pushed a commit to fedejeanne/eclipse.jdt.ui that referenced this issue Aug 23, 2023
Adopt Package Explorer, Outline view contribution and editor breadcrumb
for Java editor to use new JFace API that allows viewers display huge
number of elements without freezing UI.

See eclipse-platform/eclipse.platform.ui#818
and eclipse-platform/eclipse.platform.ui#810.

Fixes eclipse-jdt#631
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Aug 23, 2023
It will calculate the location of expandable node, once it enters
visible area of Viewer expand it.

see eclipse-platform#818
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Aug 24, 2023
It will calculate the location of expandable node, once it enters
visible area of Viewer expand it.
Install resize listener for control when limit is set and remove limit
is reset.Do the same thing for Vertical Scroll bar control.

see eclipse-platform#818
raghucssit added a commit to raghucssit/eclipse.platform.ui that referenced this issue Aug 24, 2023
It will calculate the location of expandable node, once it enters
visible area of Viewer expand it.
Install resize listener for control when limit is set and remove limit
is reset.Do the same thing for Vertical Scroll bar control.
Honor the entire drag event as one selection at the end of the drag.

see eclipse-platform#818
@vogella
Copy link
Contributor

vogella commented Sep 26, 2023

Could you also add it to the N&N of 4.29 / 4.30 and describe how to enable it in the preferences? Otherwise it is impossible for users to find out of this new feature.

@vogella
Copy link
Contributor

vogella commented Nov 7, 2023

Ping for N&N entry. Without this entry it is almost for other projects to leverage this improvement in their viewers.

@vogella
Copy link
Contributor

vogella commented Nov 9, 2023

If I create a new project with 30 000 and open it in the project explorer it still freezes for a very long time.
@iloveeclipse you said it is already implemented in project explorer but as @raghucssit never responded to the request to document this feature in the N&N I don't see how to activate it.

Here is my test handler to generate example project.

package com.vogella.resources.handlers;

import java.io.ByteArrayInputStream;
import java.util.Random;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.ui.IWorkbenchPage;

public class CreateLargeProjectHandler {
	private final Random random = new Random();

	private static final String CHARSFORCREATION = "abcdefghijklmnopqrstuvwxyz";

	@Execute
	public void execute(IWorkbenchPage page) {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRoot root = workspace.getRoot();
		IProject project = root.getProject("performancetest");
		try {
			project.create(new NullProgressMonitor());
			project.open(null);
			for (int i = 0; i < 1; i++) {
				IFolder folder = project.getFolder("test" + i);
				folder.create(true, true, null);
				for (int j = 0; j < 30000; j++) {
					IFile file = folder.getFile(createString(10));
					file.create(new ByteArrayInputStream(createBytes(5000)), IResource.NONE, null);
					IFileStore fileStore = EFS.getLocalFileSystem().getStore(file.getFullPath());
					if (!fileStore.fetchInfo().isDirectory()) {
//						try {
//							IDE.openEditorOnFileStore(page, fileStore);
//						} catch (PartInitException e) {
//							/* some code */
//						}
					}
				}
			}
		} catch (CoreException e) {
			// nothing to do
		}
	}

	private byte[] createBytes(int length) {
		byte[] bytes = new byte[length];
		random.nextBytes(bytes);
		return bytes;
	}

	private String createString(int length) {
		StringBuilder buf = new StringBuilder(length);
		// fill the string with random characters up to the desired length
		for (int i = 0; i < length; i++) {
			buf.append(CHARSFORCREATION.charAt(random.nextInt(CHARSFORCREATION.length())));
		}
		return buf.toString();
	}

}

@iloveeclipse
Copy link
Member

If I create a new project with 30 000 and open it in the project explorer it still freezes for a very long time.

See #1425, the feature was disabled by default.

@iloveeclipse
Copy link
Member

N&N for 4.31 were added via eclipse-platform/www.eclipse.org-eclipse#104 .
With that and #1425 we are done for the main part of the ticket.
Whatever enhancement requests or bugs can be found, should go to dedicated tickets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working performance
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants