Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] disable background type cache

This patch adds an option to the Work In Progress preferences page. If you uncheck "Cache types in background" the AllTypesCache will no longer search for types in the background. The search will begin when you initiate the Open Type action. The type cache is still maintained so subsequent Open Type actions should be quicker.

Note this patch does not address the parsing/indexing issue. Another patch will be forthcoming which should reduce the excessive parsing now being done.

-Chris
Index: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java,v
retrieving revision 1.2
diff -u -r1.2 OpenTypeAction.java
--- browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java	7 Apr 2004 00:32:13 -0000	1.2
+++ browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java	21 Apr 2004 15:49:43 -0000
@@ -127,7 +127,7 @@
 	}
 	
 	protected Shell getShell() {
-		return CUIPlugin.getDefault().getActiveWorkbenchShell();
+		return CUIPlugin.getActiveWorkbenchShell();
 	}
 
 	/**
Index: src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java,v
retrieving revision 1.2
diff -u -r1.2 WorkInProgressPreferencePage.java
--- src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java	13 Apr 2004 03:52:51 -0000	1.2
+++ src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java	21 Apr 2004 15:49:56 -0000
@@ -9,6 +9,7 @@
 import java.util.ArrayList;
 
 import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.browser.AllTypesCache;
 import org.eclipse.cdt.internal.core.search.indexing.SourceIndexer;
 import org.eclipse.cdt.internal.ui.search.CSearchPage;
 import org.eclipse.cdt.ui.CUIPlugin;
@@ -45,6 +46,7 @@
 	private Combo fExternLinks;
 	private Button fExternEnabled;
 	private Button fIProblemMarkers;
+	private Button fBackgroundTypeCacheEnabled;
 	
 	protected OverlayPreferenceStore fOverlayStore;
 	private Text fTextControl;
@@ -59,6 +61,7 @@
 		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CSearchPage.EXTERNALMATCH_ENABLED));
 		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, CSearchPage.EXTERNALMATCH_VISIBLE));
 		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, SourceIndexer.CDT_INDEXER_TIMEOUT));
+		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE));
 		
         OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
 		overlayKeys.toArray(keys);
@@ -120,7 +123,22 @@
 		indexerTimeoutGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 		indexerTimeoutGroup.setText("Indexer Timeout"); //$NON-NLS-1$
 		
-		fTextControl = (Text) addTextField( indexerTimeoutGroup, "Time out (ms)","TimeOut",6,0,true);
+		fTextControl = (Text) addTextField( indexerTimeoutGroup, "Time out (ms)","TimeOut",6,0,true); //$NON-NLS-1$ //$NON-NLS-2$
+		
+		Group backgroundTypeCacheGroup= new Group(result, SWT.NONE);
+		backgroundTypeCacheGroup.setLayout(new GridLayout());
+		backgroundTypeCacheGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		backgroundTypeCacheGroup.setText("Open Type"); //$NON-NLS-1$
+
+		fBackgroundTypeCacheEnabled = createCheckButton(backgroundTypeCacheGroup, "Cache types in background"); //$NON-NLS-1$
+		fBackgroundTypeCacheEnabled.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+			public void widgetSelected(SelectionEvent e) {
+				Button button = (Button) e.widget;
+				fOverlayStore.setValue(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE, button.getSelection());
+			}
+		});
 		
 		initialize(); 
 		
@@ -137,7 +155,7 @@
 		
 		fTextControl.setText(fOverlayStore.getString(SourceIndexer.CDT_INDEXER_TIMEOUT));
 		
-
+		fBackgroundTypeCacheEnabled.setSelection(fOverlayStore.getBoolean(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE));
 	}
 	
 	/* (non-Javadoc)
@@ -199,6 +217,9 @@
 //		Store IProblem Marker value in CCorePlugin Preferences 
 		Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
 		prefs.setValue(SourceIndexer.CDT_INDEXER_TIMEOUT,fOverlayStore.getString(SourceIndexer.CDT_INDEXER_TIMEOUT));
+
+		prefs.setValue(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE, fOverlayStore.getString(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE));
+
 		CCorePlugin.getDefault().savePluginPreferences();
 		
 		return true;
@@ -210,7 +231,8 @@
 	public static void initDefaults(IPreferenceStore store) {
 		store.setDefault(CSearchPage.EXTERNALMATCH_ENABLED, false);
 		store.setDefault(CSearchPage.EXTERNALMATCH_VISIBLE, 0);
-		store.setDefault(SourceIndexer.CDT_INDEXER_TIMEOUT, "20000");
+		store.setDefault(SourceIndexer.CDT_INDEXER_TIMEOUT, "20000"); //$NON-NLS-1$
+		store.setDefault(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE, true);
 	}
 	
 	/*
Index: browser/ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/ChangeLog,v
retrieving revision 1.1
diff -u -r1.1 ChangeLog
--- browser/ChangeLog	7 Apr 2004 00:32:00 -0000	1.1
+++ browser/ChangeLog	21 Apr 2004 15:51:03 -0000
@@ -1,2 +1,7 @@
 2004-04-06 Chris Wiebe
 	initial placement of non-ui code into org.eclipse.cdt.core.browser
+
+2004-04-20 Chris Wiebe
+	refactored TypeCacheDeltaListener into standalone class
+	added option in Work In Progress prefs page to disable background cache
+	
\ No newline at end of file
Index: browser/org/eclipse/cdt/core/browser/AllTypesCache.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java,v
retrieving revision 1.1
diff -u -r1.1 AllTypesCache.java
--- browser/org/eclipse/cdt/core/browser/AllTypesCache.java	7 Apr 2004 00:32:00 -0000	1.1
+++ browser/org/eclipse/cdt/core/browser/AllTypesCache.java	21 Apr 2004 15:51:06 -0000
@@ -11,23 +11,23 @@
 package org.eclipse.cdt.core.browser;
 
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
-import java.util.Set;
 
+import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ElementChangedEvent;
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.core.model.ICElementDelta;
-import org.eclipse.cdt.core.model.IElementChangedListener;
 import org.eclipse.cdt.core.model.IWorkingCopy;
 import org.eclipse.cdt.core.search.ICSearchScope;
 import org.eclipse.cdt.core.search.SearchEngine;
 import org.eclipse.cdt.internal.core.browser.cache.TypeCache;
+import org.eclipse.cdt.internal.core.browser.cache.TypeCacheDeltaListener;
 import org.eclipse.cdt.internal.core.browser.cache.TypeCacherJob;
 import org.eclipse.cdt.internal.core.browser.util.ArrayUtil;
-import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobManager;
 import org.eclipse.core.runtime.jobs.Job;
 
 /**
@@ -47,6 +47,11 @@
 	private static TypeCache fgCache;
 	private static TypeCacherJob fgJob;
 	private static TypeCacheDeltaListener fgDeltaListener;
+	private static IPropertyChangeListener fgPropertyChangeListener;
+	private static boolean fBackgroundJobEnabled;
+
+	/** Preference key for enabling background cache */
+    public final static String ENABLE_BACKGROUND_TYPE_CACHE = "enableBackgroundTypeCache"; //$NON-NLS-1$
 	
 	/**
 	 * Defines a simple interface in order to provide
@@ -63,18 +68,50 @@
 	 * @param provider A working copy provider.
 	 */
 	public static void initialize(IWorkingCopyProvider provider) {
+
+		// load prefs
+		Preferences prefs= CCorePlugin.getDefault().getPluginPreferences();
+		if (prefs.contains(ENABLE_BACKGROUND_TYPE_CACHE)) {
+			fBackgroundJobEnabled= prefs.getBoolean(ENABLE_BACKGROUND_TYPE_CACHE);
+		} else {
+			prefs.setDefault(ENABLE_BACKGROUND_TYPE_CACHE, true);
+			prefs.setValue(ENABLE_BACKGROUND_TYPE_CACHE, true);
+			CCorePlugin.getDefault().savePluginPreferences();
+			fBackgroundJobEnabled= true;
+		}
+
 		fgCache= new TypeCache();
 		fgJob= new TypeCacherJob(fgCache, provider);
-		fgDeltaListener= new TypeCacheDeltaListener(fgCache, fgJob);
-		
+		fgDeltaListener= new TypeCacheDeltaListener(fgCache, fBackgroundJobEnabled, fgJob);
+
+		fgPropertyChangeListener= new IPropertyChangeListener() {
+			public void propertyChange(PropertyChangeEvent event) {
+				String property= event.getProperty();		
+				if (property.equals(ENABLE_BACKGROUND_TYPE_CACHE)) {
+					String value= (String)event.getNewValue();
+					fBackgroundJobEnabled= Boolean.valueOf(value).booleanValue();
+					fgDeltaListener.setBackgroundJobEnabled(fBackgroundJobEnabled);
+					if (!fBackgroundJobEnabled) {
+						// terminate all background jobs
+						IJobManager jobMgr = Platform.getJobManager();
+						jobMgr.cancel(TypeCacherJob.FAMILY);
+					}
+				}
+			}
+		};
+		// add property change listener
+		prefs.addPropertyChangeListener(fgPropertyChangeListener);
+
 		// add delta listener
 		CoreModel.getDefault().addElementChangedListener(fgDeltaListener);
 
-		// schedule job to run after INITIAL_DELAY
-		if (fgJob.getState() != Job.RUNNING) {
-			fgJob.setSearchPaths(null);
-			fgJob.setPriority(Job.BUILD);
-			fgJob.schedule(INITIAL_DELAY);
+		if (fBackgroundJobEnabled) {
+			// schedule job to run after INITIAL_DELAY
+			if (fgJob.getState() != Job.RUNNING) {
+				fgJob.setSearchPaths(null);
+				fgJob.setPriority(Job.BUILD);
+				fgJob.schedule(INITIAL_DELAY);
+			}
 		}
 	}
 	
@@ -140,156 +177,4 @@
 			}
 		}
 	}
-	
-	/**
-	 * Listener for changes to CModel.
-	 * @see org.eclipse.cdt.core.model.IElementChangedListener
-	 * @since 3.0
-	 */
-	private static class TypeCacheDeltaListener implements IElementChangedListener {
-		
-		private TypeCache fTypeCache;
-		private TypeCacherJob fTypeCacherJob;
-		private Set fPaths= new HashSet(5);
-		private Set fPrefixes= new HashSet(5);
-		private boolean fFlushAll= false;
-		
-		public TypeCacheDeltaListener(TypeCache cache, TypeCacherJob job) {
-			fTypeCache= cache;
-			fTypeCacherJob= job;
-		}
-		
-		/*
-		 * @see IElementChangedListener#elementChanged
-		 */
-		public void elementChanged(ElementChangedEvent event) {
-			fPaths.clear();
-			fPrefixes.clear();
-			fFlushAll= false;
-
-			boolean needsFlushing= processDelta(event.getDelta());
-			if (needsFlushing) {
-				// cancel background job
-				if (fTypeCacherJob.getState() == Job.RUNNING) {
-					// wait for job to finish?
-					try {
-						fTypeCacherJob.cancel();
-						fTypeCacherJob.join();
-					} catch (InterruptedException ex) {
-					}
-				}
-				
-				if (fFlushAll) {
-					// flush the entire cache
-					fTypeCacherJob.setSearchPaths(null);
-					fTypeCache.flushAll();
-				} else {
-					// flush affected files from cache
-					Set searchPaths= new HashSet(10);
-					getPrefixMatches(fPrefixes, searchPaths);
-					searchPaths.addAll(fPaths);
-					fTypeCacherJob.setSearchPaths(searchPaths);
-					fTypeCache.flush(searchPaths);
-				}
-
-				// restart the background job
-				fTypeCacherJob.setPriority(Job.BUILD);
-				fTypeCacherJob.schedule();
-			}
-		}
-		
-		/*
-		 * returns true if the cache needs to be flushed
-		 */
-		private boolean processDelta(ICElementDelta delta) {
-			ICElement elem= delta.getElement();
-			int pathEntryChanged= ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE |
-									ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE | ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
-			boolean isAddedOrRemoved= (delta.getKind() != ICElementDelta.CHANGED)
-			 || ((delta.getFlags() & pathEntryChanged) != 0);
-			
-			switch (elem.getElementType()) {
-				case ICElement.C_MODEL:
-				{
-					if (isAddedOrRemoved) {
-						// CModel has changed
-						// flush the entire cache
-						fFlushAll= true;
-						return true;
-					}
-					return processDeltaChildren(delta);
-				}
-				
-				case ICElement.C_PROJECT:
-				case ICElement.C_CCONTAINER:
-				{
-					if (isAddedOrRemoved) {
-						// project or folder has changed
-						// flush all files with matching prefix
-						IPath path= elem.getPath();
-						if (path != null)
-							fPrefixes.add(path);
-						return true;
-					}
-					return processDeltaChildren(delta);
-				}
-				
-				case ICElement.C_NAMESPACE:
-				case ICElement.C_TEMPLATE_CLASS:
-				case ICElement.C_CLASS:
-				case ICElement.C_STRUCT:
-				case ICElement.C_UNION:
-				case ICElement.C_ENUMERATION:
-				case ICElement.C_TYPEDEF:
-				case ICElement.C_INCLUDE:
-				case ICElement.C_UNIT:
-				{
-					if (isAddedOrRemoved) {
-						// CElement has changed
-						// flush file from cache
-						IPath path= elem.getPath();
-						if (path != null)
-							fPaths.add(path);
-						return true;
-					}
-					return processDeltaChildren(delta);
-				}
-					
-				default:
-					// fields, methods, imports ect
-					return false;
-			}	
-		}
-
-		private boolean processDeltaChildren(ICElementDelta delta) {
-			ICElementDelta[] children= delta.getAffectedChildren();
-			for (int i= 0; i < children.length; i++) {
-				if (processDelta(children[i])) {
-					return true;
-				}
-			}
-			return false;
-		}
-		
-		private boolean getPrefixMatches(Set prefixes, Set results) {
-			Set pathSet= fTypeCache.getAllFiles();
-			if (pathSet.isEmpty() || prefixes == null || prefixes.isEmpty())
-				return false;
-
-			for (Iterator pathIter= pathSet.iterator(); pathIter.hasNext(); ) {
-				IPath path= (IPath) pathIter.next();
-
-				// find paths which match prefix
-				for (Iterator prefixIter= prefixes.iterator(); prefixIter.hasNext(); ) {
-					IPath prefix= (IPath) prefixIter.next();
-					if (prefix.isPrefixOf(path)) {
-						results.add(path);
-						break;
-					}
-				}
-			}
-
-			return !results.isEmpty();
-		}
-	}	
 }
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java,v
retrieving revision 1.1
diff -u -r1.1 TypeCacherJob.java
--- browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java	7 Apr 2004 00:32:00 -0000	1.1
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java	21 Apr 2004 15:51:06 -0000
@@ -61,12 +61,12 @@
 	 * @see IJobManager#join(Object, IProgressMonitor)
 	 * @since 3.0
 	 */
-	private static final Object FAMILY= new Object();
+	public static final Object FAMILY= new Object();
 
-	private DelegatedProgressMonitor fProgressMonitor;
 	private Set fSearchPaths= new HashSet(50);
 	private TypeCache fTypeCache;
 	private IWorkingCopyProvider fWorkingCopyProvider;
+	private DelegatedProgressMonitor fProgressMonitor= new DelegatedProgressMonitor();
 
 	public TypeCacherJob(TypeCache cache, IWorkingCopyProvider provider) {
 		super(TypeCacheMessages.getString("TypeCacherJob.jobName")); //$NON-NLS-1$
@@ -94,7 +94,11 @@
 	 * @see org.eclipse.core.runtime.jobs.Job#run(IProgressMonitor)
 	 */
 	public IStatus run(IProgressMonitor monitor) {
-		fProgressMonitor= new DelegatedProgressMonitor(monitor);
+		if (monitor.isCanceled())
+			return Status.CANCEL_STATUS;
+
+		fProgressMonitor.init();
+		fProgressMonitor.addDelegate(monitor);
 		
 		try {
 			search(fProgressMonitor);
@@ -104,7 +108,8 @@
 		} catch (OperationCanceledException ex) {
 			return Status.CANCEL_STATUS;
 		} finally {
-			fProgressMonitor= null;
+			fProgressMonitor.removeAllDelegates();
+			fProgressMonitor.init();
 		}
 
 		return Status.OK_STATUS;
@@ -120,8 +125,7 @@
 	 * @see Job#join
 	 */
 	public void join(IProgressMonitor monitor) throws InterruptedException {
-		if (fProgressMonitor != null)
-			fProgressMonitor.addDelegate(monitor);
+		fProgressMonitor.addDelegate(monitor);
 		super.join();
 	}
 	
Index: browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java,v
retrieving revision 1.1
diff -u -r1.1 DelegatedProgressMonitor.java
--- browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java	7 Apr 2004 00:32:00 -0000	1.1
+++ browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java	21 Apr 2004 15:51:06 -0000
@@ -28,24 +28,38 @@
 	private final ArrayList fDelegateList = new ArrayList(INITIAL_DELEGATE_COUNT);
 	private String fTaskName;
 	private String fSubTask;
-	private int fTotalWork = IProgressMonitor.UNKNOWN;
+	private int fTotalWork;
 	private double fWorked;
-	private boolean fIsBlocked = false;
-	private boolean fIsCanceled = false;
+	private boolean fIsBlocked;
+	private boolean fIsCanceled;
 	
 	/**
 	 * Creates a new delegated monitor.
 	 */
 	public DelegatedProgressMonitor() {
+		init();
 	}
 	
 	/**
 	 * Creates a new delegated monitor, and adds a delegate.
 	 */
 	public DelegatedProgressMonitor(IProgressMonitor delegate) {
+		init();
 		addDelegate(delegate);
 	}
 	
+	/**
+	 * Resets delegated monitor to initial state.
+	 */
+	public synchronized void init() {
+		fTaskName= null;
+		fSubTask= null;
+		fTotalWork= IProgressMonitor.UNKNOWN;
+		fWorked= 0.0f;
+		fIsBlocked= false;
+		fIsCanceled= false;
+	}
+	
 	/*
 	 * @see IProgressMonitor#beginTask
 	 */
@@ -196,6 +210,13 @@
 		if (index != -1) {
 			fDelegateList.remove(index);
 		}
+	}
+
+	/**
+	 * Removes all delegates.
+	 */
+	public synchronized void removeAllDelegates() {
+		fDelegateList.clear();
 	}
 
 	/**
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheDeltaListener.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheDeltaListener.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheDeltaListener.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheDeltaListener.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,179 @@
+/*
+ * Created on Apr 20, 2004
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.cdt.core.model.ElementChangedEvent;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICElementDelta;
+import org.eclipse.cdt.core.model.IElementChangedListener;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.jobs.Job;
+
+
+/**
+ * Listener for changes to CModel.
+ * @see org.eclipse.cdt.core.model.IElementChangedListener
+ * @since 3.0
+ */
+public class TypeCacheDeltaListener implements IElementChangedListener {
+	
+	private TypeCache fTypeCache;
+	private TypeCacherJob fTypeCacherJob;
+	private Set fPaths= new HashSet(5);
+	private Set fPrefixes= new HashSet(5);
+	private boolean fFlushAll= false;
+	private boolean fCreateBackgroundJob= true;
+	
+	public TypeCacheDeltaListener(TypeCache cache, boolean createBackgroundJob, TypeCacherJob job) {
+		fTypeCache= cache;
+		fTypeCacherJob= job;
+		fCreateBackgroundJob= createBackgroundJob;
+	}
+	
+	public void setBackgroundJobEnabled(boolean enabled) {
+		fCreateBackgroundJob= enabled;
+	}
+	
+	/*
+	 * @see IElementChangedListener#elementChanged
+	 */
+	public void elementChanged(ElementChangedEvent event) {
+		fPaths.clear();
+		fPrefixes.clear();
+		fFlushAll= false;
+
+		boolean needsFlushing= processDelta(event.getDelta());
+		if (needsFlushing) {
+			// cancel background job
+			if (fTypeCacherJob.getState() == Job.RUNNING) {
+				// wait for job to finish?
+				try {
+					fTypeCacherJob.cancel();
+					fTypeCacherJob.join();
+				} catch (InterruptedException ex) {
+				}
+			}
+			
+			if (fFlushAll) {
+				// flush the entire cache
+				fTypeCacherJob.setSearchPaths(null);
+				fTypeCache.flushAll();
+			} else {
+				// flush affected files from cache
+				Set searchPaths= new HashSet(10);
+				getPrefixMatches(fPrefixes, searchPaths);
+				searchPaths.addAll(fPaths);
+				fTypeCacherJob.setSearchPaths(searchPaths);
+				fTypeCache.flush(searchPaths);
+			}
+
+			// restart the background job
+			if (fCreateBackgroundJob) {
+				fTypeCacherJob.setPriority(Job.BUILD);
+				fTypeCacherJob.schedule();
+			}
+		}
+	}
+	
+	/*
+	 * returns true if the cache needs to be flushed
+	 */
+	private boolean processDelta(ICElementDelta delta) {
+		ICElement elem= delta.getElement();
+		int pathEntryChanged= ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE |
+								ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE | ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
+		boolean isAddedOrRemoved= (delta.getKind() != ICElementDelta.CHANGED)
+		 || ((delta.getFlags() & pathEntryChanged) != 0);
+		
+		switch (elem.getElementType()) {
+			case ICElement.C_MODEL:
+			{
+				if (isAddedOrRemoved) {
+					// CModel has changed
+					// flush the entire cache
+					fFlushAll= true;
+					return true;
+				}
+				return processDeltaChildren(delta);
+			}
+			
+			case ICElement.C_PROJECT:
+			case ICElement.C_CCONTAINER:
+			{
+				if (isAddedOrRemoved) {
+					// project or folder has changed
+					// flush all files with matching prefix
+					IPath path= elem.getPath();
+					if (path != null)
+						fPrefixes.add(path);
+					return true;
+				}
+				return processDeltaChildren(delta);
+			}
+			
+			case ICElement.C_NAMESPACE:
+			case ICElement.C_TEMPLATE_CLASS:
+			case ICElement.C_CLASS:
+			case ICElement.C_STRUCT:
+			case ICElement.C_UNION:
+			case ICElement.C_ENUMERATION:
+			case ICElement.C_TYPEDEF:
+			case ICElement.C_INCLUDE:
+			case ICElement.C_UNIT:
+			{
+				if (isAddedOrRemoved) {
+					// CElement has changed
+					// flush file from cache
+					IPath path= elem.getPath();
+					if (path != null)
+						fPaths.add(path);
+					return true;
+				}
+				return processDeltaChildren(delta);
+			}
+				
+			default:
+				// fields, methods, imports ect
+				return false;
+		}	
+	}
+
+	private boolean processDeltaChildren(ICElementDelta delta) {
+		ICElementDelta[] children= delta.getAffectedChildren();
+		for (int i= 0; i < children.length; i++) {
+			if (processDelta(children[i])) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private boolean getPrefixMatches(Set prefixes, Set results) {
+		Set pathSet= fTypeCache.getAllFiles();
+		if (pathSet.isEmpty() || prefixes == null || prefixes.isEmpty())
+			return false;
+
+		for (Iterator pathIter= pathSet.iterator(); pathIter.hasNext(); ) {
+			IPath path= (IPath) pathIter.next();
+
+			// find paths which match prefix
+			for (Iterator prefixIter= prefixes.iterator(); prefixIter.hasNext(); ) {
+				IPath prefix= (IPath) prefixIter.next();
+				if (prefix.isPrefixOf(path)) {
+					results.add(path);
+					break;
+				}
+			}
+		}
+
+		return !results.isEmpty();
+	}
+}

Back to the top