From 6eef40d050d4b4c0bdf982c82de3e02e46f620dd Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 16 Oct 2006 18:23:13 +0000 Subject: [PATCH] Fix for 149572, notifications for index. --- .../tests/ast2/AST2FileBasePluginTest.java | 2 + .../tests/ast2/DOMFileBasePluginTest.java | 6 +- .../pdom/tests/IndexListenerTest.java | 107 +++++++ .../cdt/internal/pdom/tests/PDOMTestBase.java | 25 +- .../cdt/internal/pdom/tests/PDOMTests.java | 2 +- .../testplugin/util/TestSourceReader.java | 19 +- .../cdt/core/dom/IPDOMIndexerTask.java | 2 + .../eclipse/cdt/core/dom/IPDOMManager.java | 3 + .../cdt/core/index/IIndexChangeEvent.java | 33 ++ .../cdt/core/index/IIndexChangeListener.java | 44 +++ .../eclipse/cdt/core/index/IIndexManager.java | 35 +++ .../cdt/core/index/IIndexerStateEvent.java | 33 ++ .../cdt/core/index/IIndexerStateListener.java | 42 +++ .../cdt/internal/core/index/CIndex.java | 6 + .../internal/core/index/IIndexFragment.java | 2 +- .../internal/core/index/IndexChangeEvent.java | 36 +++ .../core/index/IndexerStateEvent.java | 38 +++ .../cdt/internal/core/pdom/Messages.java | 5 + .../internal/core/pdom/PDOMIndexerJob.java | 34 +- .../cdt/internal/core/pdom/PDOMManager.java | 295 +++++++++++++++--- .../core/pdom/indexer/PDOMIndexerTask.java | 128 ++++++++ .../indexer/fast/PDOMFastHandleDelta.java | 93 +----- .../pdom/indexer/fast/PDOMFastIndexer.java | 6 +- .../pdom/indexer/fast/PDOMFastIndexerJob.java | 31 +- .../pdom/indexer/fast/PDOMFastReindex.java | 60 ++-- .../indexer/full/PDOMFullHandleDelta.java | 101 ++---- .../pdom/indexer/full/PDOMFullIndexerJob.java | 16 +- .../pdom/indexer/full/PDOMFullReindex.java | 93 +++--- .../pdom/indexer/nulli/PDOMNullIndexer.java | 4 + .../internal/core/pdom/messages.properties | 5 + 30 files changed, 944 insertions(+), 362 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IndexListenerTest.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeListener.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateListener.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexerStateEvent.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2FileBasePluginTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2FileBasePluginTest.java index ef28ff3083e..29b5d447b3b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2FileBasePluginTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2FileBasePluginTest.java @@ -20,6 +20,7 @@ import java.io.InputStream; import junit.framework.TestCase; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.FileManager; @@ -61,6 +62,7 @@ public class AST2FileBasePluginTest extends TestCase { className = aClassName; numProjects++; } + CCorePlugin.getPDOMManager().setIndexerId(cPrj, IPDOMManager.ID_NO_INDEXER); } catch ( CoreException e ) { /*boo*/ } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMFileBasePluginTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMFileBasePluginTest.java index e11f4536a7a..abf0affcef0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMFileBasePluginTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMFileBasePluginTest.java @@ -20,6 +20,7 @@ import java.io.InputStream; import junit.framework.TestCase; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.FileManager; @@ -44,7 +45,7 @@ public class DOMFileBasePluginTest extends TestCase { static Class className; static ICProject cPrj; - private void initialize(Class aClassName){ + private void initialize(Class aClassName) { if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){ //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); monitor = new NullProgressMonitor(); @@ -61,12 +62,15 @@ public class DOMFileBasePluginTest extends TestCase { className = aClassName; numProjects++; } + // disable indexer + CCorePlugin.getPDOMManager().setIndexerId(cPrj, IPDOMManager.ID_NO_INDEXER); } catch ( CoreException e ) { /*boo*/ } if (project == null) throw new NullPointerException("Unable to create project"); //$NON-NLS-1$ + //Create file manager fileManager = new FileManager(); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IndexListenerTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IndexListenerTest.java new file mode 100644 index 00000000000..4c32595b702 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IndexListenerTest.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.pdom.tests; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Test; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IIndexChangeEvent; +import org.eclipse.cdt.core.index.IIndexChangeListener; +import org.eclipse.cdt.core.index.IIndexManager; +import org.eclipse.cdt.core.index.IIndexerStateEvent; +import org.eclipse.cdt.core.index.IIndexerStateListener; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.cdt.core.testplugin.util.TestSourceReader; +import org.eclipse.core.runtime.NullProgressMonitor; + +public class IndexListenerTest extends BaseTestCase { + protected IIndex fIndex; + private ICProject fProject1; + private ICProject fProject2; + + public static Test suite() { + return suite(IndexListenerTest.class); + } + + protected void setUp() throws Exception { + fProject1 = CProjectHelper.createCCProject("testIndexListener1", null); + fProject2 = CProjectHelper.createCCProject("testIndexListener2", null); + CCorePlugin.getPDOMManager().setIndexerId(fProject1, IPDOMManager.ID_FAST_INDEXER); + CCorePlugin.getPDOMManager().setIndexerId(fProject2, IPDOMManager.ID_FAST_INDEXER); + assertTrue(CCorePlugin.getIndexManager().joinIndexer(2000, new NullProgressMonitor())); + } + + protected void tearDown() throws Exception { + CProjectHelper.delete(fProject1); + CProjectHelper.delete(fProject2); + } + + public void testIdleListener() throws Exception { + final int[] state= new int[] {0, 0, 0}; + IIndexManager im= CCorePlugin.getIndexManager(); + + im.addIndexerStateListener(new IIndexerStateListener() { + public void indexChanged(IIndexerStateEvent event) { + if (event.indexerIsIdle()) { + state[0]++; + state[2]= 0; + } + else { + state[1]++; + state[2]= 1; + } + } + }); + + TestSourceReader.createFile(fProject1.getProject(), "test.cpp", "int a;"); + Thread.sleep(200); + assertTrue(im.joinIndexer(2000, new NullProgressMonitor())); + Thread.sleep(200); + assertEquals(1, state[0]); + assertEquals(1, state[1]); + assertEquals(0, state[2]); + } + + public void testChangeListener() throws Exception { + final List projects= new ArrayList(); + IIndexManager im= CCorePlugin.getIndexManager(); + + im.addIndexChangeListener(new IIndexChangeListener() { + public void indexChanged(IIndexChangeEvent event) { + projects.add(event.getAffectedProject()); + } + }); + + TestSourceReader.createFile(fProject1.getProject(), "test.cpp", "int a;"); + Thread.sleep(200); + assertEquals(1, projects.size()); + assertTrue(projects.contains(fProject1)); + projects.clear(); + + + TestSourceReader.createFile(fProject1.getProject(), "test.cpp", "int a;"); + TestSourceReader.createFile(fProject2.getProject(), "test.cpp", "int b;"); + Thread.sleep(200); + assertEquals(2, projects.size()); + assertTrue(projects.contains(fProject1)); + assertTrue(projects.contains(fProject2)); + projects.clear(); + + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java index 9ca11004251..9df15461114 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java @@ -20,8 +20,6 @@ import java.util.regex.Pattern; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IName; -import org.eclipse.cdt.core.dom.IPDOMIndexer; -import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; @@ -90,28 +88,7 @@ public class PDOMTestBase extends BaseTestCase { CCorePlugin.getPDOMManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER); // wait until the indexer is done - final boolean[] indexerDone = new boolean[1]; - CCorePlugin.getPDOMManager().enqueue(new IPDOMIndexerTask() { - public IPDOMIndexer getIndexer() { - return null; - } - public void run(IProgressMonitor monitor) { - synchronized(indexerDone) { - indexerDone[0] = true; - indexerDone.notify(); - } - } - }); - - try { - // Join indexer job - synchronized(indexerDone) { - while(!indexerDone[0]) - indexerDone.wait(); - } - } catch(InterruptedException ie) { - throw new RuntimeException(ie); - } + assertTrue(CCorePlugin.getIndexManager().joinIndexer(5000, new NullProgressMonitor())); cprojects[0] = cproject; } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTests.java index 2e92984aa02..b7537f97eb4 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTests.java @@ -20,7 +20,7 @@ import junit.framework.TestSuite; public class PDOMTests extends TestSuite { public static Test suite() { - TestSuite suite = new TestSuite(); + TestSuite suite = new PDOMTests(); suite.addTest(EnumerationTests.suite()); suite.addTest(ClassTests.suite()); diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java index 29f61eca16d..3de7cc69bb7 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java @@ -109,10 +109,11 @@ public class TestSourceReader { * @param filePath the path relative to the container to create the file at * @param contents the content for the file * @return a file object. + * @throws CoreException * @throws Exception * @since 4.0 */ - public static IFile createFile(IContainer container, IPath filePath, String contents) throws Exception { + public static IFile createFile(IContainer container, IPath filePath, String contents) throws CoreException { //Obtain file handle IFile file = container.getFile(filePath); @@ -126,4 +127,20 @@ public class TestSourceReader { } return file; } + + /** + * Creates a file with content at the given path inside the given container. + * If the file exists its content is replaced. + * @param container a container to create the file in + * @param filePath the path relative to the container to create the file at + * @param contents the content for the file + * @return + * @return a file object. + * @throws Exception + * @throws Exception + * @since 4.0 + */ + public static IFile createFile(IContainer container, String filePath, String contents) throws CoreException { + return createFile(container, new Path(filePath), contents); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java index 9950a3a06dc..20800d3e864 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java @@ -30,5 +30,7 @@ public interface IPDOMIndexerTask { public void run(IProgressMonitor monitor); public IPDOMIndexer getIndexer(); + + public int getFilesToIndexCount(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java index 347daa37e9e..dd7c06f8781 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java @@ -25,6 +25,9 @@ public interface IPDOMManager { public static final String ID_FULL_INDEXER= "org.eclipse.cdt.core.domsourceindexer"; //$NON-NLS-1$ // Getting the PDOM + /** + * mstodo deprecate: use CCorePlugin.getIndexManager().getIndex(...). + */ public IPDOM getPDOM(ICProject project) throws CoreException; // Get the indexer for a given project diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java new file mode 100644 index 00000000000..2819ffe2ee9 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.index; + +import org.eclipse.cdt.core.model.ICProject; + +/** + * IndexChangeEvents descrive changes to the index. + *

+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the CDT team. + *

+ * + * @since 4.0 + */ +public interface IIndexChangeEvent { + + /** + * Returns the project for which the index has changed. + */ + public ICProject getAffectedProject(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeListener.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeListener.java new file mode 100644 index 00000000000..8e3e2ec8939 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeListener.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.index; + + +/** + * An index change listener is notified of changes to the index. These changes + * arise from the indexer working in the background. + *

+ * Clients may implement this interface. + *

+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the CDT team. + *

+ * + * @since 4.0 + */ +public interface IIndexChangeListener { + + /** + * Notifies this listener that some part of the index has changed. + *

+ * The supplied event provides the details. This event object is valid only for + * the duration of the invocation of this method. + *

+ *

+ * Note: This method is called by CDT; it is not intended + * to be called directly by clients. + * + * @param event the index change event + */ + public void indexChanged(IIndexChangeEvent event); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java index 1b9558a0e2a..a32feab0a5e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.core.index; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; /** * Starting point for working with the index. The manager can be obtained via @@ -34,6 +35,7 @@ public interface IIndexManager { public final static int ADD_DEPENDENCIES = 0x1; public final static int ADD_DEPENDENT = 0x2; + public final static int FOREVER= -1; /** * Returns the index for the given project. * @param project the project to get the index for @@ -67,4 +69,37 @@ public interface IIndexManager { * @throws CoreException */ IIndex getIndex(ICProject[] projects, int options) throws CoreException; + + /** + * Registers a listener that will be notified whenever the indexer go idle. + * @param listener the listener to register. + */ + void addIndexChangeListener(IIndexChangeListener listener); + + /** + * Removes a previously registered index change listener. + * @param listener the listener to unregister. + */ + void removeIndexChangeListener(IIndexChangeListener listener); + + /** + * Registers a listener that will be notified whenever the indexer changes its state. + * @param listener the listener to register. + */ + void addIndexerStateListener(IIndexerStateListener listener); + + /** + * Removes a previously registered indexer state listener. + * @param listener the listener to unregister. + */ + void removeIndexerStateListener(IIndexerStateListener listener); + + /** + * Joins the indexer and reports progress. + * @param waitMaxMillis time limit in millis after which the method returns with false, + * or {@link #FOREVER}. + * @param monitor a monitor to report progress. + * @return true, if the indexer went idle in the given time. + */ + boolean joinIndexer(int waitMaxMillis, IProgressMonitor monitor); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java new file mode 100644 index 00000000000..9543dab11e8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.index; + + +/** + * IndexChangeEvents descrive changes to the state of the indexer. + *

+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the CDT team. + *

+ * + * @since 4.0 + */ +public interface IIndexerStateEvent { + + /** + * Tests whether the indexer has more work to do. + * @since 4.0 + */ + boolean indexerIsIdle(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateListener.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateListener.java new file mode 100644 index 00000000000..285924a0df9 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateListener.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.index; + + +/** + * An indexer state listener is notified of changes to the state of the indexer. + *

+ * Clients may implement this interface. + *

+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the CDT team. + *

+ * @since 4.0 + */ +public interface IIndexerStateListener { + + /** + * Notifies this listener that the state of the indexer has changed. + *

+ * The supplied event provides the details. This event object is valid only for + * the duration of the invocation of this method. + *

+ *

+ * Note: This method is called by CDT; it is not intended + * to be called directly by clients. + * + * @param event the indexer state event + */ + public void indexChanged(IIndexerStateEvent event); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java index 5924c8ef5c7..68555d146d8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java @@ -50,6 +50,12 @@ public class CIndex implements IIndex { this(fragments, fragments.length); } + public IIndexFragment[] getPrimaryFragments() { + IIndexFragment[] result= new IIndexFragment[fPrimaryFragmentCount]; + System.arraycopy(fFragments, 0, result, 0, fPrimaryFragmentCount); + return result; + } + public IIndexBinding findBinding(ICElement element) throws CoreException { // mstodo ICElement to IBinding return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java index 4cd52eb95f0..c640996346f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java @@ -47,7 +47,7 @@ public interface IIndexFragment { * @see IIndex#FIND_ALL_OCCURENCES */ final int FIND_ALL_OCCURENCES = IIndex.FIND_ALL_OCCURENCES; - + /** * Returns the file for the given location. May return null, if no such file exists. * This method may only return files that are actually managed by this fragement. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java new file mode 100644 index 00000000000..e508e463e5b --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.index; + +import org.eclipse.cdt.core.index.IIndexChangeEvent; +import org.eclipse.cdt.core.model.ICProject; + +public class IndexChangeEvent implements IIndexChangeEvent { + + private ICProject fAffectedProject; + + public IndexChangeEvent(ICProject projectChanged) { + fAffectedProject= projectChanged; + } + + public IndexChangeEvent() { + fAffectedProject= null; + } + + public ICProject getAffectedProject() { + return fAffectedProject; + } + + public void setAffectedProject(ICProject project) { + fAffectedProject= project; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexerStateEvent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexerStateEvent.java new file mode 100644 index 00000000000..62b5a78801a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexerStateEvent.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.index; + +import org.eclipse.cdt.core.index.IIndexerStateEvent; + +public class IndexerStateEvent implements IIndexerStateEvent { + + public static final int STATE_IDLE= 0; + public static final int STATE_BUSY= 1; + + private int fState; + + public IndexerStateEvent() { + this(STATE_IDLE); + } + + public IndexerStateEvent(int state) { + fState= state; + } + + public void setState(int state) { + fState= state; + } + + public boolean indexerIsIdle() { + return fState == STATE_IDLE; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java index 46fa8d8d52d..d1efb45b7af 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java @@ -15,6 +15,11 @@ import org.eclipse.osgi.util.NLS; public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.pdom.messages"; //$NON-NLS-1$ + public static String PDOMManager_errorNoSuchIndex; + public static String PDOMManager_FilesToIndexSubtask; + public static String PDOMManager_JoinIndexerTask; + public static String PDOMManager_notifyJob_label; + public static String PDOMManager_notifyTask_message; public static String WritablePDOM_error_unknownLinkage; static { // initialize resource bundle diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java index 72cbbef716d..0890713cd9f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java @@ -51,24 +51,30 @@ public class PDOMIndexerJob extends Job { while (!pdomManager.finishIndexerJob()) { IPDOMIndexerTask nextTask= pdomManager.getNextTask(); synchronized (taskMutex) { - if (!cancelledByManager) { - currentTask= nextTask; // write to currentTask needs protection - } + currentTask= nextTask; // write to currentTask needs protection } - if (currentTask != null) { // read on currentTask is ok (no write in other thread) + + try { currentTask.run(monitor); - synchronized (taskMutex) { - currentTask= null; // write to currentTask needs protection - if (cancelledByManager) { - // TODO chance for confusion here is user cancels - // while project is getting deletes. - monitor.setCanceled(false); - cancelledByManager = false; - taskMutex.notify(); - } + } + catch (Exception e) { + CCorePlugin.log(e); + } + boolean cancelledByUser= false; + synchronized (taskMutex) { + currentTask= null; // write to currentTask needs protection + if (cancelledByManager) { + // TODO chance for confusion here is user cancels + // while project is getting deletes. + monitor.setCanceled(false); + cancelledByManager = false; + taskMutex.notify(); + } + else { + cancelledByUser= monitor.isCanceled(); } } - if (monitor.isCanceled()) { + if (cancelledByUser) { pdomManager.cancelledByUser(); return Status.CANCEL_STATUS; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index 9fd39e0b18a..dccf41f9fc4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -29,7 +29,8 @@ import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.index.IIndex; -import org.eclipse.cdt.core.index.IIndexManager; +import org.eclipse.cdt.core.index.IIndexChangeListener; +import org.eclipse.cdt.core.index.IIndexerStateListener; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ElementChangedEvent; import org.eclipse.cdt.core.model.ICElement; @@ -42,7 +43,10 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IWritableIndex; import org.eclipse.cdt.internal.core.index.IWritableIndexFragment; import org.eclipse.cdt.internal.core.index.IWritableIndexManager; +import org.eclipse.cdt.internal.core.index.IndexChangeEvent; +import org.eclipse.cdt.internal.core.index.IndexerStateEvent; import org.eclipse.cdt.internal.core.index.WritableCIndex; +import org.eclipse.cdt.internal.core.pdom.PDOM.IListener; import org.eclipse.cdt.internal.core.pdom.indexer.nulli.PDOMNullIndexer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; @@ -51,10 +55,14 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IPreferencesService; @@ -69,34 +77,77 @@ import org.osgi.service.prefs.BackingStoreException; * * @author Doug Schaefer */ -public class PDOMManager implements IPDOMManager, IWritableIndexManager, IElementChangedListener { +public class PDOMManager implements IPDOMManager, IWritableIndexManager, IElementChangedListener, IListener { - private static final QualifiedName indexerProperty - = new QualifiedName(CCorePlugin.PLUGIN_ID, "pdomIndexer"); //$NON-NLS-1$ - private static final QualifiedName dbNameProperty - = new QualifiedName(CCorePlugin.PLUGIN_ID, "pdomName"); //$NON-NLS-1$ - private static final QualifiedName pdomProperty - = new QualifiedName(CCorePlugin.PLUGIN_ID, "pdom"); //$NON-NLS-1$ + private static final QualifiedName indexerProperty= new QualifiedName(CCorePlugin.PLUGIN_ID, "pdomIndexer"); //$NON-NLS-1$ + private static final QualifiedName dbNameProperty= new QualifiedName(CCorePlugin.PLUGIN_ID, "pdomName"); //$NON-NLS-1$ + private static final QualifiedName pdomProperty= new QualifiedName(CCorePlugin.PLUGIN_ID, "pdom"); //$NON-NLS-1$ + + private static final String INDEXER_ID_KEY = "indexerId"; //$NON-NLS-1$ + private static final ISchedulingRule NOTIFICATION_SCHEDULING_RULE = new ISchedulingRule(){ + public boolean contains(ISchedulingRule rule) { + return rule == this; + } + public boolean isConflicting(ISchedulingRule rule) { + return rule == this; + } + }; + + private PDOMIndexerJob indexerJob; + private IPDOMIndexerTask currentTask; + private LinkedList taskQueue = new LinkedList(); + private Object taskQueueMutex = new Object(); + private Object fWakeupOnIdle= new Object(); + + private Map fPDOMs= new HashMap(); + private ListenerList fChangeListeners= new ListenerList(); + private ListenerList fStateListeners= new ListenerList(); + + private IndexChangeEvent fIndexChangeEvent= new IndexChangeEvent(); + private IndexerStateEvent fIndexerStateEvent= new IndexerStateEvent(); + public synchronized IPDOM getPDOM(ICProject project) throws CoreException { IProject rproject = project.getProject(); WritablePDOM pdom = (WritablePDOM)rproject.getSessionProperty(pdomProperty); - if (pdom == null) { - String dbName = rproject.getPersistentProperty(dbNameProperty); - if (dbName == null) { - dbName = project.getElementName() + "." //$NON-NLS-1$ - + System.currentTimeMillis() + ".pdom"; //$NON-NLS-1$ + if (pdom != null) { + ICProject oldProject= (ICProject) fPDOMs.get(pdom); + if (project.equals(oldProject)) { + return pdom; + } + + if (oldProject != null && oldProject.getProject().exists()) { + // project was copied + String dbName= getDefaultName(project); rproject.setPersistentProperty(dbNameProperty, dbName); } - IPath dbPath = CCorePlugin.getDefault().getStateLocation().append(dbName); - pdom = new WritablePDOM(dbPath); - rproject.setSessionProperty(pdomProperty, pdom); - if (pdom.versionMismatch()) - getIndexer(project).reindex(); + else { + // project was renamed + fPDOMs.put(pdom, project); + return pdom; + } + } + + String dbName= rproject.getPersistentProperty(dbNameProperty); + if (dbName == null) { + dbName = getDefaultName(project); + rproject.setPersistentProperty(dbNameProperty, dbName); + } + IPath dbPath = CCorePlugin.getDefault().getStateLocation().append(dbName); + pdom = new WritablePDOM(dbPath); + pdom.addListener(this); + rproject.setSessionProperty(pdomProperty, pdom); + fPDOMs.put(pdom, project); + if (pdom.versionMismatch()) { + getIndexer(project).reindex(); } return pdom; } + private String getDefaultName(ICProject project) { + return project.getElementName() + "." + System.currentTimeMillis() + ".pdom"; //$NON-NLS-1$//$NON-NLS-2$ + } + public IPDOMIndexer getIndexer(ICProject project) { try { IProject rproject = project.getProject(); @@ -240,7 +291,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IElemen if (pdoms.isEmpty()) { throw new CoreException(CCorePlugin.createStatus( - MessageFormat.format("Cannot obtain index for project ''{0}''", new Object[]{project.getElementName()}))); + MessageFormat.format(Messages.PDOMManager_errorNoSuchIndex, new Object[]{project.getElementName()}))); } return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.size()]), new IIndexFragment[0]); @@ -300,8 +351,6 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IElemen return this; } - private static final String INDEXER_ID_KEY = "indexerId"; //$NON-NLS-1$ - public String getDefaultIndexerId() { IPreferencesService prefService = Platform.getPreferencesService(); return prefService.getString(CCorePlugin.PLUGIN_ID, INDEXER_ID_KEY, @@ -420,56 +469,83 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IElemen return indexer; } - // Indexer manager - private PDOMIndexerJob indexerJob; - private LinkedList indexerJobQueue = new LinkedList(); - private Object indexerJobMutex = new Object(); - public void enqueue(IPDOMIndexerTask subjob) { - synchronized (indexerJobMutex) { - indexerJobQueue.addLast(subjob); + boolean notifyBusy= false; + synchronized (taskQueueMutex) { + taskQueue.addLast(subjob); if (indexerJob == null) { indexerJob = new PDOMIndexerJob(this); indexerJob.schedule(); + notifyBusy= true; } } + if (notifyBusy) { + notifyState(IndexerStateEvent.STATE_BUSY); + } } - IPDOMIndexerTask getNextTask() { - synchronized (indexerJobMutex) { - return indexerJobQueue.isEmpty() - ? null - : (IPDOMIndexerTask)indexerJobQueue.removeFirst(); + IPDOMIndexerTask getNextTask() { + synchronized (taskQueueMutex) { + currentTask= taskQueue.isEmpty() ? null : (IPDOMIndexerTask)taskQueue.removeFirst(); + return currentTask; } } void cancelledByUser() { - synchronized (indexerJobMutex) { - indexerJobQueue.clear(); + synchronized (taskQueueMutex) { + taskQueue.clear(); + currentTask= null; + indexerJob= null; } + notifyState(IndexerStateEvent.STATE_IDLE); } boolean finishIndexerJob() { - synchronized (indexerJobMutex) { - if (indexerJobQueue.isEmpty()) { + boolean idle= false; + synchronized (taskQueueMutex) { + currentTask= null; + if (taskQueue.isEmpty()) { indexerJob = null; - return true; - } else - // No way, there's more work to do - return false; - } + idle= true; + } + } + if (idle) { + notifyState(IndexerStateEvent.STATE_IDLE); + } + return idle; } public void deleting(ICProject project) { // Project is about to be deleted. Stop all indexing tasks for it IPDOMIndexer indexer = getIndexer(project); - synchronized (indexerJobMutex) { + synchronized (taskQueueMutex) { if (indexerJob != null) { indexerJob.cancelJobs(indexer); } } } + private boolean isIndexerIdle() { + synchronized (taskQueueMutex) { + return currentTask == null && taskQueue.isEmpty(); + } + } + + private int getFilesToIndexCount() { + int count= 0; + synchronized (taskQueueMutex) { + if (currentTask != null) { + count= currentTask.getFilesToIndexCount(); + } + for (Iterator iter = taskQueue.iterator(); iter.hasNext();) { + IPDOMIndexerTask task= (IPDOMIndexerTask) iter.next(); + count+= task.getFilesToIndexCount(); + } + } + return count; + } + + /** * Startup the PDOM. This mainly sets us up to handle model * change events. @@ -478,4 +554,137 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IElemen CoreModel.getDefault().addElementChangedListener(this); } + public void addIndexChangeListener(IIndexChangeListener listener) { + fChangeListeners.add(listener); + } + + public void removeIndexChangeListener(IIndexChangeListener listener) { + fChangeListeners.remove(listener); + } + + public void addIndexerStateListener(IIndexerStateListener listener) { + fStateListeners.add(listener); + } + + public void removeIndexerStateListener(IIndexerStateListener listener) { + fStateListeners.remove(listener); + } + + private void notifyState(final int state) { + if (state == IndexerStateEvent.STATE_IDLE) { + assert !Thread.holdsLock(taskQueueMutex); + synchronized(fWakeupOnIdle) { + fWakeupOnIdle.notifyAll(); + } + } + + if (fStateListeners.isEmpty()) { + return; + } + Job notify= new Job(Messages.PDOMManager_notifyJob_label) { + protected IStatus run(IProgressMonitor monitor) { + fIndexerStateEvent.setState(state); + Object[] listeners= fStateListeners.getListeners(); + monitor.beginTask(Messages.PDOMManager_notifyTask_message, listeners.length); + for (int i = 0; i < listeners.length; i++) { + final IIndexerStateListener listener = (IIndexerStateListener) listeners[i]; + SafeRunner.run(new ISafeRunnable(){ + public void handleException(Throwable exception) { + CCorePlugin.log(exception); + } + public void run() throws Exception { + listener.indexChanged(fIndexerStateEvent); + } + }); + monitor.worked(1); + } + return Status.OK_STATUS; + } + }; + notify.setRule(NOTIFICATION_SCHEDULING_RULE); + notify.setSystem(true); + notify.schedule(); + } + + public void handleChange(PDOM pdom) { + if (fChangeListeners.isEmpty()) { + return; + } + + ICProject project; + synchronized (this) { + project = (ICProject) fPDOMs.get(pdom); + } + + if (project != null) { + final ICProject finalProject= project; + Job notify= new Job(Messages.PDOMManager_notifyJob_label) { + protected IStatus run(IProgressMonitor monitor) { + fIndexChangeEvent.setAffectedProject(finalProject); + Object[] listeners= fChangeListeners.getListeners(); + monitor.beginTask(Messages.PDOMManager_notifyTask_message, listeners.length); + for (int i = 0; i < listeners.length; i++) { + final IIndexChangeListener listener = (IIndexChangeListener) listeners[i]; + SafeRunner.run(new ISafeRunnable(){ + public void handleException(Throwable exception) { + CCorePlugin.log(exception); + } + public void run() throws Exception { + listener.indexChanged(fIndexChangeEvent); + } + }); + monitor.worked(1); + } + return Status.OK_STATUS; + } + }; + notify.setRule(NOTIFICATION_SCHEDULING_RULE); + notify.setSystem(true); + notify.schedule(); + } + } + + public boolean joinIndexer(int waitMaxMillis, IProgressMonitor monitor) { + monitor.beginTask(Messages.PDOMManager_JoinIndexerTask, IProgressMonitor.UNKNOWN); + long limit= System.currentTimeMillis()+waitMaxMillis; + try { + while (true) { + if (monitor.isCanceled()) { + return false; + } + boolean wouldFail= false; + int wait= 1000; + if (waitMaxMillis >= 0) { + int rest= (int) (limit - System.currentTimeMillis()); + if (rest < wait) { + if (rest <= 0) { + wouldFail= true; + } + + wait= rest; + } + } + + assert !Thread.holdsLock(taskQueueMutex); + synchronized(fWakeupOnIdle) { + if (isIndexerIdle()) { + return true; + } + if (wouldFail) { + return false; + } + + monitor.subTask(MessageFormat.format(Messages.PDOMManager_FilesToIndexSubtask, new Object[] {new Integer(getFilesToIndexCount())})); + try { + fWakeupOnIdle.wait(wait); + } catch (InterruptedException e) { + return false; + } + } + } + } + finally { + monitor.done(); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java new file mode 100644 index 00000000000..f8e126ef234 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.pdom.indexer; + +import java.util.Collection; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMIndexerTask; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ICElementVisitor; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; +import org.eclipse.cdt.internal.core.index.IWritableIndex; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +public abstract class PDOMIndexerTask implements IPDOMIndexerTask { + + protected static final int MAX_ERRORS = 10; + protected int fErrorCount; + + protected void processDelta(ICElementDelta delta, Collection added, Collection changed, Collection removed) throws CoreException { + int flags = delta.getFlags(); + + if ((flags & ICElementDelta.F_CHILDREN) != 0) { + ICElementDelta[] children = delta.getAffectedChildren(); + for (int i = 0; i < children.length; ++i) { + processDelta(children[i], added, changed, removed); + } + } + + ICElement element = delta.getElement(); + switch (element.getElementType()) { + case ICElement.C_UNIT: + ITranslationUnit tu = (ITranslationUnit)element; + switch (delta.getKind()) { + case ICElementDelta.CHANGED: + if ((flags & ICElementDelta.F_CONTENT) != 0) + changed.add(tu); + break; + case ICElementDelta.ADDED: + if (!tu.isWorkingCopy()) + added.add(tu); + break; + case ICElementDelta.REMOVED: + if (!tu.isWorkingCopy()) + removed.add(tu); + break; + } + break; + } + } + + protected void collectSources(ICProject project, final Collection sources, final Collection headers) throws CoreException { + project.accept(new ICElementVisitor() { + public boolean visit(ICElement element) throws CoreException { + switch (element.getElementType()) { + case ICElement.C_UNIT: + ITranslationUnit tu = (ITranslationUnit)element; + if (tu.isSourceUnit()) { + sources.add(tu); + } + else if (tu.isHeaderUnit()) { + headers.add(tu); + } + return false; + case ICElement.C_CCONTAINER: + case ICElement.C_PROJECT: + return true; + } + return false; + } + }); + } + + protected void removeTU(IWritableIndex index, ITranslationUnit tu) throws CoreException, InterruptedException { + index.acquireWriteLock(0); + try { + IPath path = ((IFile)tu.getResource()).getLocation(); + IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(path); + if (file != null) + index.clearFile(file); + } finally { + index.releaseWriteLock(0); + } + } + + protected void changeTU(ITranslationUnit tu) throws CoreException, InterruptedException { + try { + doChangeTU(tu); + } + catch (CoreException e) { + if (++fErrorCount <= MAX_ERRORS) { + CCorePlugin.log(e); + } + else { + throw e; + } + } + } + + abstract protected void doChangeTU(ITranslationUnit tu) throws CoreException, InterruptedException; + + protected void clearIndex(IWritableIndex index) throws InterruptedException, CoreException { + // reset error count + fErrorCount= 0; + // First clear the pdom + index.acquireWriteLock(0); + try { + index.clear(); + } + finally { + index.releaseWriteLock(0); + } + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastHandleDelta.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastHandleDelta.java index 10def35fede..0dc709d103f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastHandleDelta.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastHandleDelta.java @@ -17,68 +17,46 @@ import java.util.Iterator; import java.util.List; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.index.IIndexFile; -import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; -import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; class PDOMFastHandleDelta extends PDOMFastIndexerJob { - private final ICElementDelta delta; - - private List added = new ArrayList(); private List changed = new ArrayList(); private List removed = new ArrayList(); + private volatile int fFilesToIndex= 0; public PDOMFastHandleDelta(PDOMFastIndexer indexer, ICElementDelta delta) throws CoreException { super(indexer); - this.delta = delta; + processDelta(delta, changed, changed, removed); + fFilesToIndex= changed.size() + removed.size(); } public void run(IProgressMonitor monitor) { try { long start = System.currentTimeMillis(); - - processDelta(delta); - Iterator i = changed.iterator(); while (i.hasNext()) { + if (monitor.isCanceled()) + return; ITranslationUnit tu = (ITranslationUnit)i.next(); - try { - changeTU(tu); - } catch (Throwable e) { - CCorePlugin.log(e); - if (++errorCount > MAX_ERRORS) - return; - } + changeTU(tu); + fFilesToIndex--; } - - i = added.iterator(); - while (i.hasNext()) { - ITranslationUnit tu = (ITranslationUnit)i.next(); - try { - addTU(tu); - } catch (Throwable e) { - CCorePlugin.log(e); - if (++errorCount > MAX_ERRORS) - return; - } - } - + i = removed.iterator(); while (i.hasNext()) { + if (monitor.isCanceled()) + return; ITranslationUnit tu = (ITranslationUnit)i.next(); - removeTU(tu); + removeTU(index, tu); + fFilesToIndex--; } - String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID - + "/debug/pdomtimings"); //$NON-NLS-1$ + String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID + "/debug/pdomtimings"); //$NON-NLS-1$ if (showTimings != null && showTimings.equalsIgnoreCase("true")) //$NON-NLS-1$ System.out.println("PDOM Fast Delta Time: " + (System.currentTimeMillis() - start)); //$NON-NLS-1$ @@ -87,49 +65,8 @@ class PDOMFastHandleDelta extends PDOMFastIndexerJob { } catch (InterruptedException e) { } } - - protected void processDelta(ICElementDelta delta) throws CoreException { - int flags = delta.getFlags(); - - if ((flags & ICElementDelta.F_CHILDREN) != 0) { - ICElementDelta[] children = delta.getAffectedChildren(); - for (int i = 0; i < children.length; ++i) { - processDelta(children[i]); - } - } - - ICElement element = delta.getElement(); - switch (element.getElementType()) { - case ICElement.C_UNIT: - ITranslationUnit tu = (ITranslationUnit)element; - switch (delta.getKind()) { - case ICElementDelta.CHANGED: - if ((flags & ICElementDelta.F_CONTENT) != 0) - changed.add(tu); - break; - case ICElementDelta.ADDED: - if (!tu.isWorkingCopy()) - added.add(tu); - break; - case ICElementDelta.REMOVED: - if (!tu.isWorkingCopy()) - removed.add(tu); - break; - } - break; - } - } - protected void removeTU(ITranslationUnit tu) throws CoreException, InterruptedException { - index.acquireWriteLock(0); - try { - IPath path = ((IFile)tu.getResource()).getLocation(); - IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(path); - if (file != null) - index.clearFile(file); - } finally { - index.releaseWriteLock(0); - } + public int getFilesToIndexCount() { + return fFilesToIndex; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexer.java index 5a44eb297ea..b13a8f49453 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexer.java @@ -43,8 +43,10 @@ public class PDOMFastIndexer implements IPDOMIndexer { } public void handleDelta(ICElementDelta delta) throws CoreException { - CCorePlugin.getPDOMManager().enqueue( - new PDOMFastHandleDelta(this, delta)); + PDOMFastHandleDelta fhd= new PDOMFastHandleDelta(this, delta); + if (fhd.getFilesToIndexCount() > 0) { + CCorePlugin.getPDOMManager().enqueue(fhd); + } } public void reindex() throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java index 76b3ee4ec7a..d586067658f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java @@ -23,11 +23,13 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IWritableIndex; import org.eclipse.cdt.internal.core.index.IWritableIndexManager; import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory; +import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -35,16 +37,12 @@ import org.eclipse.core.runtime.IPath; * @author Doug Schaefer * */ -public abstract class PDOMFastIndexerJob implements IPDOMIndexerTask { +abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexerTask { protected final PDOMFastIndexer indexer; protected final IWritableIndex index; protected final IndexBasedCodeReaderFactory codeReaderFactory; - // Error counter. If we too many errors we bail - protected int errorCount; - protected final int MAX_ERRORS = 10; - public PDOMFastIndexerJob(PDOMFastIndexer indexer) throws CoreException { this.indexer = indexer; this.index= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(indexer.getProject()); @@ -55,31 +53,26 @@ public abstract class PDOMFastIndexerJob implements IPDOMIndexerTask { return indexer; } - protected void addTU(ITranslationUnit tu) throws InterruptedException, CoreException { - // we can do the same as for changing a tu - changeTU(tu); - } - - protected void changeTU(ITranslationUnit tu) throws CoreException, InterruptedException { + protected void doChangeTU(ITranslationUnit tu) throws CoreException, InterruptedException { + IPath path = tu.getLocation(); + if (path == null) { + return; + } ILanguage language = tu.getLanguage(); if (language == null) return; // skip if no scanner info IScannerInfo scanner= tu.getScannerInfo(false); - if (scanner == null) { - return; - } - - IPath path = tu.getLocation(); - if (path == null) { + CodeReader codeReader = tu.getCodeReader(); + if (scanner == null || codeReader == null) { return; } index.acquireReadLock(); try { // get the AST in a "Fast" way - IASTTranslationUnit ast= language.getASTTranslationUnit(tu.getCodeReader(), scanner, codeReaderFactory, index); + IASTTranslationUnit ast= language.getASTTranslationUnit(codeReader, scanner, codeReaderFactory, index); index.acquireWriteLock(1); try { @@ -148,7 +141,7 @@ public abstract class PDOMFastIndexerJob implements IPDOMIndexerTask { return PROCESS_CONTINUE; } catch (Throwable e) { CCorePlugin.log(e); - return ++errorCount > MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE; + return ++fErrorCount > MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE; } } }); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastReindex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastReindex.java index 29a73915df7..596e6181fb0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastReindex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastReindex.java @@ -12,64 +12,44 @@ package org.eclipse.cdt.internal.core.pdom.indexer.fast; +import java.util.ArrayList; +import java.util.Iterator; + import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.model.ICContainer; -import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; /** * @author Doug Schaefer * */ -public class PDOMFastReindex extends PDOMFastIndexerJob { +class PDOMFastReindex extends PDOMFastIndexerJob { + private volatile int fFilesToIndex= 0; + private ArrayList fTUs= new ArrayList(); + public PDOMFastReindex(PDOMFastIndexer indexer) throws CoreException { super(indexer); + collectSources(indexer.getProject(), fTUs, fTUs); + fFilesToIndex= fTUs.size()+1; } - - private void addSources(ICContainer container, IProgressMonitor monitor) throws CoreException { - ITranslationUnit[] tus = container.getTranslationUnits(); - for (int i = 0; i < tus.length; ++i) { - if (monitor.isCanceled()) - throw new CoreException(Status.CANCEL_STATUS); - ITranslationUnit tu = tus[i]; - if (tu.isSourceUnit()) { - try { - addTU(tu); - } catch (Throwable e) { - CCorePlugin.log(e); - if (++errorCount > MAX_ERRORS) - throw new CoreException(Status.CANCEL_STATUS); - } - } - } - ICContainer[] childContainers = container.getCContainers(); - for (int i = 0; i < childContainers.length; ++i) - addSources(childContainers[i], monitor); - } - public void run(final IProgressMonitor monitor) { try { long start = System.currentTimeMillis(); - // First clear the pdom - index.acquireWriteLock(0); - try { - index.clear(); - } - finally { - index.releaseWriteLock(0); - } - - ISourceRoot[] roots = indexer.getProject().getAllSourceRoots(); - for (int i = 0; i < roots.length; ++i) - addSources(roots[i], monitor); + clearIndex(index); + fFilesToIndex--; + for (Iterator iter = fTUs.iterator(); iter.hasNext();) { + ITranslationUnit tu = (ITranslationUnit) iter.next(); + changeTU(tu); + fFilesToIndex--; + } + + assert fFilesToIndex == 0; String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID + "/debug/pdomtimings"); //$NON-NLS-1$ if (showTimings != null && showTimings.equalsIgnoreCase("true")) //$NON-NLS-1$ @@ -82,4 +62,8 @@ public class PDOMFastReindex extends PDOMFastIndexerJob { } } + public int getFilesToIndexCount() { + return fFilesToIndex; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java index 60e4f1d95b6..80c1a10ec30 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java @@ -23,10 +23,8 @@ import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; @@ -40,41 +38,41 @@ import org.eclipse.core.runtime.Platform; * @author Doug Schaefer * */ -public class PDOMFullHandleDelta extends PDOMFullIndexerJob { +class PDOMFullHandleDelta extends PDOMFullIndexerJob { - private final ICElementDelta delta; - // Map of filename, TU of files that need to be parsed. - private Map changed = new HashMap(); + private Map changedMap = new HashMap(); + private List changed = new ArrayList(); private List added = new ArrayList(); private List removed = new ArrayList(); + private volatile int fFilesToIndex= 0; public PDOMFullHandleDelta(PDOMFullIndexer indexer, ICElementDelta delta) throws CoreException { super(indexer); - this.delta = delta; + processDelta(delta, added, changed, removed); } public void run(IProgressMonitor monitor) { try { long start = System.currentTimeMillis(); - - processDelta(delta); - + int count = changed.size() + added.size() + removed.size(); + for (Iterator iter = changed.iterator(); iter.hasNext();) { + ITranslationUnit tu = (ITranslationUnit) iter.next(); + processTranslationUnit(tu); + fFilesToIndex--; + } + changed.clear(); + if (count > 0) { - Iterator i = changed.values().iterator(); + Iterator i = changedMap.values().iterator(); while (i.hasNext()) { if (monitor.isCanceled()) return; ITranslationUnit tu = (ITranslationUnit)i.next(); - try { - changeTU(tu); - } catch (Throwable e) { - CCorePlugin.log(e); - if (++errorCount > MAX_ERRORS) - return; - } + changeTU(tu); + fFilesToIndex--; } i = added.iterator(); @@ -82,13 +80,8 @@ public class PDOMFullHandleDelta extends PDOMFullIndexerJob { if (monitor.isCanceled()) return; ITranslationUnit tu = (ITranslationUnit)i.next(); - try { - addTU(tu); - } catch (Throwable e) { - CCorePlugin.log(e); - if (++errorCount > MAX_ERRORS) - return; - } + changeTU(tu); + fFilesToIndex--; } i = removed.iterator(); @@ -96,7 +89,8 @@ public class PDOMFullHandleDelta extends PDOMFullIndexerJob { if (monitor.isCanceled()) return; ITranslationUnit tu = (ITranslationUnit)i.next(); - removeTU(tu); + removeTU(index, tu); + fFilesToIndex--; } String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID @@ -110,37 +104,6 @@ public class PDOMFullHandleDelta extends PDOMFullIndexerJob { } } - protected void processDelta(ICElementDelta delta) throws CoreException { - int flags = delta.getFlags(); - - if ((flags & ICElementDelta.F_CHILDREN) != 0) { - ICElementDelta[] children = delta.getAffectedChildren(); - for (int i = 0; i < children.length; ++i) { - processDelta(children[i]); - } - } - - ICElement element = delta.getElement(); - switch (element.getElementType()) { - case ICElement.C_UNIT: - ITranslationUnit tu = (ITranslationUnit)element; - switch (delta.getKind()) { - case ICElementDelta.CHANGED: - if ((flags & ICElementDelta.F_CONTENT) != 0) - processTranslationUnit(tu); - break; - case ICElementDelta.ADDED: - if (!tu.isWorkingCopy()) - added.add(tu); - break; - case ICElementDelta.REMOVED: - if (!tu.isWorkingCopy()) - removed.add(tu); - break; - } - break; - } - } protected void processTranslationUnit(ITranslationUnit tu) throws CoreException { IPath path = tu.getUnderlyingResource().getLocation(); @@ -155,13 +118,14 @@ public class PDOMFullHandleDelta extends PDOMFullIndexerJob { for (int i = 0; i < includedBy.length; ++i) { String incfilename = includedBy[i].getIncludedByLocation(); if (CoreModel.isValidSourceUnitName(project, incfilename)) { - if (changed.get(incfilename) == null) { + if (changedMap.get(incfilename) == null) { IFile[] rfiles = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(incfilename)); for (int j = 0; j < rfiles.length; ++j) { if (rfiles[j].getProject().equals(project)) { ITranslationUnit inctu = (ITranslationUnit)CoreModel.getDefault().create(rfiles[j]); - changed.put(incfilename, inctu); + changedMap.put(incfilename, inctu); found = true; + fFilesToIndex++; } } } @@ -169,20 +133,13 @@ public class PDOMFullHandleDelta extends PDOMFullIndexerJob { } } } - if (!found) - changed.put(path.toOSString(), tu); - } - - protected void removeTU(ITranslationUnit tu) throws CoreException, InterruptedException { - index.acquireWriteLock(0); - try { - IPath path = ((IFile)tu.getResource()).getLocation(); - IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(path); - if (file != null) - index.clearFile(file); - } finally { - index.releaseWriteLock(0); + if (!found) { + changedMap.put(path.toOSString(), tu); + fFilesToIndex++; } } + public int getFilesToIndexCount() { + return fFilesToIndex; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java index d7c5b1b3d01..0ab128bdaff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java @@ -25,6 +25,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IWritableIndex; import org.eclipse.cdt.internal.core.index.IWritableIndexManager; +import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -33,15 +34,11 @@ import org.eclipse.core.runtime.Path; * @author Doug Schaefer * */ -public abstract class PDOMFullIndexerJob implements IPDOMIndexerTask { +abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexerTask { protected final PDOMFullIndexer indexer; protected final IWritableIndex index; - - // Error count, bail when it gets too high - protected int errorCount; - protected final int MAX_ERRORS = 10; - + public PDOMFullIndexerJob(PDOMFullIndexer indexer) throws CoreException { this.indexer = indexer; this.index = ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(indexer.getProject()); @@ -51,11 +48,8 @@ public abstract class PDOMFullIndexerJob implements IPDOMIndexerTask { return indexer; } - protected void addTU(ITranslationUnit tu) throws InterruptedException, CoreException { - changeTU(tu); - } - protected void changeTU(ITranslationUnit tu) throws CoreException, InterruptedException { + protected void doChangeTU(ITranslationUnit tu) throws CoreException, InterruptedException { IPath path = tu.getLocation(); if (path == null) { return; @@ -134,7 +128,7 @@ public abstract class PDOMFullIndexerJob implements IPDOMIndexerTask { return PROCESS_CONTINUE; } catch (Throwable e) { CCorePlugin.log(e); - return ++errorCount > MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE; + return ++fErrorCount > MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE; } } }); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java index 6ac21f924a6..91f2ca7d205 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java @@ -12,9 +12,10 @@ package org.eclipse.cdt.internal.core.pdom.indexer.full; +import java.util.ArrayList; +import java.util.Iterator; + import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.ICElementVisitor; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -26,10 +27,16 @@ import org.eclipse.core.runtime.Status; * @author Doug Schaefer * */ -public class PDOMFullReindex extends PDOMFullIndexerJob { +class PDOMFullReindex extends PDOMFullIndexerJob { + + private volatile int fFilesToIndex= 0; + private ArrayList fTUs= new ArrayList(); + private ArrayList fHeaders= new ArrayList(); public PDOMFullReindex(PDOMFullIndexer indexer) throws CoreException { super(indexer); + collectSources(indexer.getProject(), fTUs, fHeaders); + fFilesToIndex= fTUs.size()+fHeaders.size() + 1; } public void run(final IProgressMonitor monitor) { @@ -37,65 +44,32 @@ public class PDOMFullReindex extends PDOMFullIndexerJob { long start = System.currentTimeMillis(); // First clear out the PDOM - index.clear(); + clearIndex(index); + fFilesToIndex--; - // First index all the source files (i.e. not headers) - indexer.getProject().accept(new ICElementVisitor() { - public boolean visit(ICElement element) throws CoreException { - if (monitor.isCanceled()) - throw new CoreException(Status.CANCEL_STATUS); - switch (element.getElementType()) { - case ICElement.C_UNIT: - ITranslationUnit tu = (ITranslationUnit)element; - if (tu.isSourceUnit()) { - try { - addTU(tu); - } catch (Throwable e) { - CCorePlugin.log(e); - if (++errorCount > MAX_ERRORS) - throw new CoreException(Status.CANCEL_STATUS); - } - } - return false; - case ICElement.C_CCONTAINER: - case ICElement.C_PROJECT: - return true; - } - return false; - } - }); + for (Iterator iter = fTUs.iterator(); iter.hasNext();) { + ITranslationUnit tu = (ITranslationUnit) iter.next(); + if (monitor.isCanceled()) + return; + changeTU(tu); + fFilesToIndex--; + } - // Now add in the header files but only if they aren't already indexed - indexer.getProject().accept(new ICElementVisitor() { - public boolean visit(ICElement element) throws CoreException { - if (monitor.isCanceled()) - throw new CoreException(Status.CANCEL_STATUS); - switch (element.getElementType()) { - case ICElement.C_UNIT: - ITranslationUnit tu = (ITranslationUnit)element; - if (tu.isHeaderUnit()) { - IPath fileLocation = tu.getLocation(); - if ( fileLocation != null ) { - if (index.getFile(fileLocation) == null) { - try { - addTU(tu); - } catch (InterruptedException e) { - CCorePlugin.log(e); - if (++errorCount > MAX_ERRORS) - throw new CoreException(Status.CANCEL_STATUS); - } - } - } - } - return false; - case ICElement.C_CCONTAINER: - case ICElement.C_PROJECT: - return true; + for (Iterator iter = fHeaders.iterator(); iter.hasNext();) { + ITranslationUnit tu = (ITranslationUnit) iter.next(); + if (monitor.isCanceled()) + return; + + IPath fileLocation = tu.getLocation(); + if ( fileLocation != null ) { + if (index.getFile(fileLocation) == null) { + changeTU(tu); } - return false; + fFilesToIndex--; } - }); + } + assert fFilesToIndex==0; String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID + "/debug/pdomtimings"); //$NON-NLS-1$ if (showTimings != null && showTimings.equalsIgnoreCase("true")) //$NON-NLS-1$ @@ -104,7 +78,12 @@ public class PDOMFullReindex extends PDOMFullIndexerJob { } catch (CoreException e) { if (e.getStatus() != Status.CANCEL_STATUS) CCorePlugin.log(e); + } catch (InterruptedException e) { } } + public int getFilesToIndexCount() { + return fFilesToIndex; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/nulli/PDOMNullIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/nulli/PDOMNullIndexer.java index 769dec91088..1b24aa009f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/nulli/PDOMNullIndexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/nulli/PDOMNullIndexer.java @@ -67,6 +67,10 @@ public class PDOMNullIndexer implements IPDOMIndexer { CCorePlugin.log(e); } } + + public int getFilesToIndexCount() { + return 1; + } } public void reindex() throws CoreException { CCorePlugin.getPDOMManager().enqueue(new PDOMNullReindex()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties index 54995ed29ce..b5f98c807fa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties @@ -1 +1,6 @@ WritablePDOM_error_unknownLinkage=AST specifies unknown linkage ''{0}'' +PDOMManager_errorNoSuchIndex=Cannot obtain index for project ''{0}'' +PDOMManager_notifyJob_label=Notify Index Change Listeners +PDOMManager_JoinIndexerTask=Join Indexer +PDOMManager_notifyTask_message=Notify Listeners +PDOMManager_FilesToIndexSubtask={0} files to index