Community
Participate
Working Groups
To reproduce, create a Java project and generate some text files in it. E.g. with (adjust path to folder accordingly): public class GenerateFiles { public static void main(String[] args) { Path folder = Paths.get("/tmp/cr150896_ws/Test/folder"); int n = 5_000; String baseContent = "replacement here"; for (int i = 0; i < n; ++i) { System.out.println("Writing file " + i); String content = baseContent + " n" + i; String fileName = "file" + i + ".txt"; Path file = folder.resolve(fileName); try { Files.write(file, content.getBytes()); } catch (IOException e) { System.err.println("Failed to write file: " + fileName); e.printStackTrace(); } } } } Refresh the folder, use Search, use Replace... and try to replace e.g. "some text" with "replacement". The UI then freezes for upward of 10 minutes (on a HP Z640 workstation and local disk), with a stack trace similar to e.g.: "main" #1 prio=6 os_prio=0 cpu=347370.93ms elapsed=843.04s tid=0x00007ffff0017000 nid=0x186b5 runnable [0x00007ffff7fc8000] java.lang.Thread.State: RUNNABLE at java.lang.StringBuffer.<init>(java.base@11.0.11/StringBuffer.java:152) at sun.text.normalizer.ReplaceableString.<init>(java.base@11.0.11/ReplaceableString.java:59) at sun.text.normalizer.ReplaceableUCharacterIterator.<init>(java.base@11.0.11/ReplaceableUCharacterIterator.java:62) at sun.text.normalizer.UCharacterIterator.getInstance(java.base@11.0.11/UCharacterIterator.java:79) at sun.text.normalizer.NormalizerBase.setText(java.base@11.0.11/NormalizerBase.java:709) at java.text.CollationElementIterator.setText(java.base@11.0.11/CollationElementIterator.java:511) at java.text.RuleBasedCollator.compare(java.base@11.0.11/RuleBasedCollator.java:390) - locked <0x0000000604edc4d0> (a java.text.RuleBasedCollator) at java.text.Collator.compare(java.base@11.0.11/Collator.java:305) at org.eclipse.search.internal.ui.text.FileSearchPage$DecoratorIgnoringViewerSorter.compare(FileSearchPage.java:114) at org.eclipse.jface.viewers.ViewerComparator.lambda$0(ViewerComparator.java:206) at org.eclipse.jface.viewers.ViewerComparator$$Lambda$556/0x0000000840781040.compare(Unknown Source) at java.util.TimSort.mergeHi(java.base@11.0.11/TimSort.java:841) at java.util.TimSort.mergeAt(java.base@11.0.11/TimSort.java:520) at java.util.TimSort.mergeForceCollapse(java.base@11.0.11/TimSort.java:461) at java.util.TimSort.sort(java.base@11.0.11/TimSort.java:254) at java.util.Arrays.sort(java.base@11.0.11/Arrays.java:1441) at org.eclipse.jface.viewers.ViewerComparator.sort(ViewerComparator.java:206) at org.eclipse.jface.viewers.AbstractTreeViewer.getSortedChildren(AbstractTreeViewer.java:649) at org.eclipse.jface.viewers.AbstractTreeViewer.updateChildren(AbstractTreeViewer.java:2673) at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefreshStruct(AbstractTreeViewer.java:1960) at org.eclipse.jface.viewers.TreeViewer.internalRefreshStruct(TreeViewer.java:677) at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1936) at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1893) at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1879) at org.eclipse.jface.viewers.StructuredViewer.lambda$2(StructuredViewer.java:1461) at org.eclipse.jface.viewers.StructuredViewer$$Lambda$538/0x00000008406f8c40.run(Unknown Source) at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1400) at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:363) at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1361) at org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1461) at org.eclipse.jface.viewers.ColumnViewer.refresh(ColumnViewer.java:526) at org.eclipse.search.internal.ui.text.FileTreeContentProvider.remove(FileTreeContentProvider.java:145) at org.eclipse.search.internal.ui.text.FileTreeContentProvider.remove(FileTreeContentProvider.java:152) at org.eclipse.search.internal.ui.text.FileTreeContentProvider.remove(FileTreeContentProvider.java:152) at org.eclipse.search.internal.ui.text.FileTreeContentProvider.elementsChanged(FileTreeContentProvider.java:216) - locked <0x0000000619c12558> (a org.eclipse.search.internal.ui.text.FileTreeContentProvider) at org.eclipse.search.internal.ui.text.FileSearchPage.elementsChanged(FileSearchPage.java:322) at org.eclipse.search.ui.text.AbstractTextSearchViewPage.runBatchedUpdates(AbstractTextSearchViewPage.java:1240) - locked <0x0000000619c0bc80> (a org.eclipse.search.internal.ui.text.FileSearchPage) at org.eclipse.search.ui.text.AbstractTextSearchViewPage$UpdateUIJob.runInUIThread(AbstractTextSearchViewPage.java:151) at org.eclipse.ui.progress.UIJob.lambda$0(UIJob.java:95) at org.eclipse.ui.progress.UIJob$$Lambda$665/0x0000000840822c40.run(Unknown Source) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:185) - locked <0x00000006049c3a10> (a org.eclipse.swt.widgets.RunnableLock) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5110) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4596) at org.eclipse.jface.operation.ModalContext$ModalContextThread.block(ModalContext.java:166) at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:368) at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.run(RefactoringWizardDialog2.java:324) at org.eclipse.ltk.ui.refactoring.RefactoringWizard.internalPerformFinish(RefactoringWizard.java:636) at org.eclipse.ltk.ui.refactoring.UserInputWizardPage.performFinish(UserInputWizardPage.java:148) at org.eclipse.search.internal.ui.text.ReplaceConfigurationPage.performFinish(ReplaceConfigurationPage.java:186) at org.eclipse.ltk.ui.refactoring.RefactoringWizard.performFinish(RefactoringWizard.java:710) at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.okPressed(RefactoringWizardDialog2.java:450) at org.eclipse.jface.dialogs.Dialog.buttonPressed(Dialog.java:468) at org.eclipse.jface.dialogs.Dialog.lambda$0(Dialog.java:619) at org.eclipse.jface.dialogs.Dialog$$Lambda$206/0x00000008402e7440.accept(Unknown Source) at org.eclipse.swt.events.SelectionListener$1.widgetSelected(SelectionListener.java:84) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:252) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5893) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1439) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:5135) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4593) at org.eclipse.jface.window.Window.runEventLoop(Window.java:823) at org.eclipse.jface.window.Window.open(Window.java:799) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.lambda$0(RefactoringWizardOpenOperation.java:190) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$$Lambda$1396/0x0000000840ebf440.run(Unknown Source) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:209) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:126) at org.eclipse.search.internal.ui.text.ReplaceAction.run(ReplaceAction.java:65) at org.eclipse.search.internal.ui.text.TextSearchPage.lambda$0(TextSearchPage.java:302) at org.eclipse.search.internal.ui.text.TextSearchPage$$Lambda$1393/0x0000000840ebe440.run(Unknown Source) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:185) - locked <0x00000006089a7668> (a org.eclipse.swt.widgets.RunnableLock) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5110) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4596) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1158) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1047) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644) at org.eclipse.ui.internal.Workbench$$Lambda$236/0x000000084033cc40.run(Unknown Source) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@11.0.11/Native Method) at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@11.0.11/NativeMethodAccessorImpl.java:62) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.11/DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(java.base@11.0.11/Method.java:566) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:654) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591) at org.eclipse.equinox.launcher.Main.run(Main.java:1462) at org.eclipse.equinox.launcher.Main.main(Main.java:1435) Likely the Search results view is not batching the remove operation, or some other expensive operation.
Patch: https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/183701 Briefly checked, that reduces wait time to < 1 second. Have not tested other use cases.
I've tested various "Search" use cases now and I see no functional changes, only performance improvement for most cases. I've tried selecting different expanded nodes in same / multiple files and either remove one/some of them from Search results, or deleting related / not related files with search matches - in all cases the behavior with the patch seem to be identical - right elements are removed, tree is properly updated, remaining selected elements are still selected etc.
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/183747
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/183748
Generating 100 000 matches, the Search view struggles with even populating its tree; regardless of how replacing behaves, the UI is frozen for 10+ minutes: "main" #1 prio=6 os_prio=0 cpu=43454.15ms elapsed=108.45s tid=0x00007ffff0017800 nid=0xa312 runnable [0x00007ffff7fca000] java.lang.Thread.State: RUNNABLE at org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_append(Native Method) at org.eclipse.swt.widgets.Tree.createItem(Tree.java:992) at org.eclipse.swt.widgets.TreeItem.<init>(TreeItem.java:168) at org.eclipse.swt.widgets.TreeItem.<init>(TreeItem.java:128) at org.eclipse.jface.viewers.TreeViewer.createNewRowPart(TreeViewer.java:769) at org.eclipse.jface.viewers.TreeViewer.newItem(TreeViewer.java:276) at org.eclipse.jface.viewers.AbstractTreeViewer.updatePlus(AbstractTreeViewer.java:2920) at org.eclipse.jface.viewers.TreeViewer.updatePlus(TreeViewer.java:794) at org.eclipse.jface.viewers.AbstractTreeViewer.createTreeItem(AbstractTreeViewer.java:854) at org.eclipse.jface.viewers.AbstractTreeViewer.createChildren(AbstractTreeViewer.java:831) at org.eclipse.jface.viewers.TreeViewer.createChildren(TreeViewer.java:604) at org.eclipse.jface.viewers.AbstractTreeViewer.createChildren(AbstractTreeViewer.java:779) at org.eclipse.jface.viewers.AbstractTreeViewer.setExpandedState(AbstractTreeViewer.java:2526) at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.getChildren(TreeViewerNavigator.java:140) at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.getFirstChildWithMatches(TreeViewerNavigator.java:129) at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.getFirstChildWithMatches(TreeViewerNavigator.java:136) at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.getNextItemForward(TreeViewerNavigator.java:106) at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.navigateNext(TreeViewerNavigator.java:41) at org.eclipse.search.ui.text.AbstractTextSearchViewPage.navigateNext(AbstractTextSearchViewPage.java:989) at org.eclipse.search.ui.text.AbstractTextSearchViewPage$UpdateUIJob.runInUIThread(AbstractTextSearchViewPage.java:162) at org.eclipse.ui.progress.UIJob.lambda$0(UIJob.java:95) at org.eclipse.ui.progress.UIJob$$Lambda$715/0x00000008409b2040.run(Unknown Source) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:185) - locked <0x00000000dc4851b8> (a org.eclipse.swt.widgets.RunnableLock) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5115) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4601) at org.eclipse.jface.operation.ModalContext$ModalContextThread.block(ModalContext.java:166) at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:368) at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:468) at org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog.run(ProgressMonitorJobsDialog.java:228) at org.eclipse.ui.internal.progress.ProgressManager.lambda$26(ProgressManager.java:821) at org.eclipse.ui.internal.progress.ProgressManager$$Lambda$832/0x0000000840b65840.run(Unknown Source) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:854) at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:830) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.checkInitialConditions(RefactoringWizardOpenOperation.java:222) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.lambda$0(RefactoringWizardOpenOperation.java:173) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$$Lambda$831/0x0000000840b67040.run(Unknown Source) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:209) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:126) at org.eclipse.search.internal.ui.text.ReplaceAction.run(ReplaceAction.java:65) at org.eclipse.search.internal.ui.text.TextSearchPage.lambda$0(TextSearchPage.java:302) at org.eclipse.search.internal.ui.text.TextSearchPage$$Lambda$1156/0x0000000840defc40.run(Unknown Source) Replacing itself then also freezes the UI for minutes (despite all suggested changes so far): "main" #1 prio=6 os_prio=0 cpu=948236.07ms elapsed=1018.00s tid=0x00007ffff0017800 nid=0xa312 runnable [0x00007ffff7fca000] java.lang.Thread.State: RUNNABLE at org.eclipse.swt.internal.gtk.GTK.gtk_tree_store_set(Native Method) at org.eclipse.swt.widgets.TreeItem.setBackground(TreeItem.java:1191) at org.eclipse.jface.viewers.TreeViewerRow.setBackground(TreeViewerRow.java:96) at org.eclipse.jface.viewers.ViewerCell.setBackground(ViewerCell.java:134) at org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.update(DelegatingStyledCellLabelProvider.java:127) at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.update(DecoratingStyledCellLabelProvider.java:134) at org.eclipse.jface.viewers.ViewerColumn.refresh(ViewerColumn.java:144) at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:959) at org.eclipse.jface.viewers.AbstractTreeViewer$UpdateItemSafeRunnable.run(AbstractTreeViewer.java:126) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.JFaceUtil$$Lambda$102/0x00000008401d8040.run(Unknown Source) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:174) at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:1037) at org.eclipse.jface.viewers.StructuredViewer$UpdateItemSafeRunnable.run(StructuredViewer.java:427) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.JFaceUtil$$Lambda$102/0x00000008401d8040.run(Unknown Source) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:174) at org.eclipse.jface.viewers.StructuredViewer.updateItem(StructuredViewer.java:2111) at org.eclipse.jface.viewers.StructuredViewer.internalUpdate(StructuredViewer.java:2094) at org.eclipse.jface.viewers.StructuredViewer.update(StructuredViewer.java:2035) at org.eclipse.jface.viewers.ColumnViewer.update(ColumnViewer.java:545) at org.eclipse.jface.viewers.StructuredViewer.update(StructuredViewer.java:1979) at org.eclipse.jface.viewers.StructuredViewer.handleLabelProviderChanged(StructuredViewer.java:1158) at org.eclipse.jface.viewers.ContentViewer$1.labelProviderChanged(ContentViewer.java:95) at org.eclipse.jface.viewers.BaseLabelProvider$1.run(BaseLabelProvider.java:75) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.JFaceUtil$$Lambda$102/0x00000008401d8040.run(Unknown Source) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:174) at org.eclipse.jface.viewers.BaseLabelProvider.fireLabelProviderChanged(BaseLabelProvider.java:72) at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider$$Lambda$460/0x000000084067bc40.labelProviderChanged(Unknown Source) at org.eclipse.ui.internal.decorators.DecoratorManager$1.run(DecoratorManager.java:347) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.decorators.DecoratorManager.fireListener(DecoratorManager.java:344) at org.eclipse.ui.internal.decorators.DecorationScheduler$3.runInUIThread(DecorationScheduler.java:551) at org.eclipse.ui.progress.UIJob.lambda$0(UIJob.java:95) at org.eclipse.ui.progress.UIJob$$Lambda$715/0x00000008409b2040.run(Unknown Source) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:185) - locked <0x00000000de800118> (a org.eclipse.swt.widgets.RunnableLock) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5115) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4601) at org.eclipse.jface.operation.ModalContext$ModalContextThread.block(ModalContext.java:166) at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:368) at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:468) at org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog.run(ProgressMonitorJobsDialog.java:228) at org.eclipse.ui.internal.progress.ProgressManager.lambda$26(ProgressManager.java:821) at org.eclipse.ui.internal.progress.ProgressManager$$Lambda$832/0x0000000840b65840.run(Unknown Source) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:854) at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:830) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.checkInitialConditions(RefactoringWizardOpenOperation.java:222) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.lambda$0(RefactoringWizardOpenOperation.java:173) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$$Lambda$831/0x0000000840b67040.run(Unknown Source) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:209) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:126) at org.eclipse.search.internal.ui.text.ReplaceAction.run(ReplaceAction.java:65) at org.eclipse.search.internal.ui.text.TextSearchPage.lambda$0(TextSearchPage.java:302) at org.eclipse.search.internal.ui.text.TextSearchPage$$Lambda$1156/0x0000000840defc40.run(Unknown Source) The main problem here should be that we are filling a GTK+ tree with "too many" elements. I believe a virtual tree/table should be used for this amount of data. Either that or we limit the number of elements shown in the tree. Or we group them in a way that doesn't hang in GTK+ code (e.g. add a root node for every 1k matches, if above 1k matches). I think the limit might be the easiest option, if it doesn't hinder replacing all matches. I.e. the user should not be told "this operation will replace only the first N matches". A limit might not be easy to add at all (I've not checked how dependent the replacement code is on the UI elements), just likely easier than the other options. A virtual tree/table is probably the cleanest option, but I don't know if we have the time to make a change like that (in particular, whether we can validate that all use cases work).
(In reply to Simeon Andreev from comment #5) > Generating 100 000 matches, the Search view struggles with even populating > its tree; regardless of how replacing behaves, the UI is frozen for 10+ > minutes: As discussed, please create another bug for that, and attach there your example that causes this hang. I don't see it with 10000 files and 10 matches each, I assume it depends on how the matches are placed. > The main problem here should be that we are filling a GTK+ tree with "too > many" elements. I believe a virtual tree/table should be used for this > amount of data. Either that or we limit the number of elements shown in the > tree. Or we group them in a way that doesn't hang in GTK+ code (e.g. add a > root node for every 1k matches, if above 1k matches). > > I think the limit might be the easiest option, if it doesn't hinder > replacing all matches. I.e. the user should not be told "this operation will > replace only the first N matches". A limit might not be easy to add at all > (I've not checked how dependent the replacement code is on the UI elements), > just likely easier than the other options. > > A virtual tree/table is probably the cleanest option, but I don't know if we > have the time to make a change like that (in particular, whether we can > validate that all use cases work). That's why it should go to a different bug or even two/more. One for JFace/Search regarding the performance of tree creation etc, another one for search limit. The issue we've originally observed here was the UI hang on performing replace with 25.000 matches, and that should be fixed by linked gerrits.
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/183701 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.text.git/commit/?id=2690d12a9b397f7a0b0587ffda56f2f72de874f1
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/183747 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.text.git/commit/?id=9917c2fa5a80e5111cfd50e07f1c0dda24ffbcbe
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/183748 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.text.git/commit/?id=697ed6cd9c6828a9ea5c03d70d5eda2b14120f68
Verified with I20210806-1800