Bug 172944 - [package explorer] refreshes whole project when single compilation unit saved
Summary: [package explorer] refreshes whole project when single compilation unit saved
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 3.3 M6   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2007-02-05 17:02 EST by Nick Edgar CLA
Modified: 2007-02-12 12:12 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Edgar CLA 2007-02-05 17:02:49 EST
3.3 M4

- had many projects loaded, with many errors due to missing prerequisites
- made an innocuous change to one file (adding a void foo() method)
- this led to various notifications, the end result of which was that the Package Explorer did a complete refresh of the containing project and a downstream project, which also caused a label update event for every visible element in these projects (I had expanded all packages, so there were a lot of these)
- this occurred despite the resource delta indicating that there were only changes to the affected file's content - all other changes were either to binary files or to markers

The stack for the refresh of one of the projects looks like:

Thread [Worker-51] (Suspended (entry into method postRefresh in PackageExplorerContentProvider))	
	PackageExplorerContentProvider.postRefresh(List, boolean) line: 650	
	PackageExplorerContentProvider.postRefresh(Object, int, Object) line: 634	
	PackageExplorerContentProvider.processResourceDeltas(IResourceDelta[], Object) line: 614	
	PackageExplorerContentProvider.processDelta(IJavaElementDelta) line: 457	
	PackageExplorerContentProvider.processAffectedChildren(IJavaElementDelta[]) line: 497	
	PackageExplorerContentProvider.handleAffectedChildren(IJavaElementDelta, IJavaElement) line: 492	
	PackageExplorerContentProvider.processDelta(IJavaElementDelta) line: 460	
	PackageExplorerContentProvider.elementChanged(ElementChangedEvent) line: 107	
	DeltaProcessor$3.run() line: 1531	
	SafeRunner.run(ISafeRunnable) line: 37	
	DeltaProcessor.notifyListeners(IJavaElementDelta, int, IElementChangedListener[], int[], int) line: 1521	
	DeltaProcessor.firePostChangeDelta(IJavaElementDelta, IElementChangedListener[], int[], int) line: 1356	
	DeltaProcessor.fire(IJavaElementDelta, int) line: 1335	
	DeltaProcessor.resourceChanged(IResourceChangeEvent) line: 1895	
	DeltaProcessingState.resourceChanged(IResourceChangeEvent) line: 369	
	NotificationManager$2.run() line: 282	
	SafeRunner.run(ISafeRunnable) line: 37	
	NotificationManager.notify(ResourceChangeListenerList$ListenerEntry[], IResourceChangeEvent, boolean) line: 276	
	NotificationManager.broadcastChanges(ElementTree, ResourceChangeEvent, boolean) line: 148	
	Workspace.broadcastPostChange() line: 257	
	Workspace.endOperation(ISchedulingRule, boolean, IProgressMonitor) line: 964	
	AutoBuildJob.doBuild(IProgressMonitor) line: 169	
	AutoBuildJob.run(IProgressMonitor) line: 222	
	Worker.run() line: 58	

Tracing backwards:
- In PackageExplorerContentProvider.processResourceDeltas(IResourceDelta[], Object), it fired the postRefresh because deltas.length > 1.  Here, the model element is the project, and the child deltas are for META-INF and plugin.xml.  The changes here are to markers only, so no structural changes to the viewer should be necessary.

- In DeltaProcessor.resourceChanged(IResourceChangeEvent), the optimization check isAffectedBy(delta) returned true because some binary files had been added.  All changes outside of bin were only to markers.  I'd expect isAffectedBy to ignore binary/derived files (I'm assuming the Java model is only computed from source files).
Comment 1 Nick Edgar CLA 2007-02-05 17:03:28 EST
For more context, see work item 15734.
Comment 2 Nick Edgar CLA 2007-02-05 17:26:10 EST
This case is likely to arise whenever the manifest checker needs to run, as it typically replaces any markers on the manifest.mf and plugin.xml files.
Comment 3 Nick Edgar CLA 2007-02-05 17:32:19 EST
Even though the isAffectedBy check will skip deltas with only marker changes, it will return true if there have been any content changes to sources, or added/removed files (whether binary or source), both of which are common cases.
Then, processResourceDelta will return a Java delta flagging changes to META-INF (and its children) and plugin.xml.

When this Java delta is seen by PackageExplorerContentProvider.processResourceDeltas, it will do a full refresh on the project because deltas.length > 1, even though there are only changes to markers under META-INF and on plugin.xml.
Comment 4 Nick Edgar CLA 2007-02-07 12:11:32 EST
Also: if the java delta describes a change to two projects, each with marker changes to their manifests, the code in PackageExplorerPart.handleAffectedChildren(IJavaElementDelta, IJavaElement) will cause a full refresh of the entire model.

I'm not sure if this code (and the case above) really cares about multiple changes to existing resources, or if it's just looking multiple additions/deletions.
If the latter, then maybe replacing:
  if (delta.getAffectedChildren().length > 1)
with:
  if (delta.getAddedChildren().length + delta.getRemovedChildren().length) > 1)
would improve things.
Comment 5 Markus Keller CLA 2007-02-07 16:52:51 EST
Thanks, we will look at this during M6. Note that Marker changes are relevant for the error ticks, so we cannot simply skip these. And we have to thoroughly test that changes don't break the rippling-up of error ticks.
Comment 6 Dani Megert CLA 2007-02-07 16:55:41 EST
>Note that Marker changes are relevant for the error ticks
Isn't that done by the decorator and not the content provider?
Comment 7 Martin Aeschlimann CLA 2007-02-12 12:12:43 EST
fixed > 20070212