1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fix for 149572, notifications for index.

This commit is contained in:
Markus Schorn 2006-10-16 18:23:13 +00:00
parent 31cb030bae
commit 6eef40d050
30 changed files with 944 additions and 362 deletions

View file

@ -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*/
}

View file

@ -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();
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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());

View file

@ -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);
}
}

View file

@ -30,5 +30,7 @@ public interface IPDOMIndexerTask {
public void run(IProgressMonitor monitor);
public IPDOMIndexer getIndexer();
public int getFilesToIndexCount();
}

View file

@ -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

View file

@ -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.
* <p>
* <strong>EXPERIMENTAL</strong>. 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.
* </p>
*
* @since 4.0
*/
public interface IIndexChangeEvent {
/**
* Returns the project for which the index has changed.
*/
public ICProject getAffectedProject();
}

View file

@ -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.
* <p>
* Clients may implement this interface.
* <p>
* <strong>EXPERIMENTAL</strong>. 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.
* </p>
*
* @since 4.0
*/
public interface IIndexChangeListener {
/**
* Notifies this listener that some part of the index has changed.
* <p>
* The supplied event provides the details. This event object is valid only for
* the duration of the invocation of this method.
* </p>
* <p>
* 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);
}

View file

@ -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 <code>false</code>,
* or {@link #FOREVER}.
* @param monitor a monitor to report progress.
* @return <code>true</code>, if the indexer went idle in the given time.
*/
boolean joinIndexer(int waitMaxMillis, IProgressMonitor monitor);
}

View file

@ -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.
* <p>
* <strong>EXPERIMENTAL</strong>. 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.
* </p>
*
* @since 4.0
*/
public interface IIndexerStateEvent {
/**
* Tests whether the indexer has more work to do.
* @since 4.0
*/
boolean indexerIsIdle();
}

View file

@ -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.
* <p>
* Clients may implement this interface.
* <p>
* <strong>EXPERIMENTAL</strong>. 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.
* </p>
* @since 4.0
*/
public interface IIndexerStateListener {
/**
* Notifies this listener that the state of the indexer has changed.
* <p>
* The supplied event provides the details. This event object is valid only for
* the duration of the invocation of this method.
* </p>
* <p>
* 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);
}

View file

@ -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;

View file

@ -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 <code>null</code>, if no such file exists.
* This method may only return files that are actually managed by this fragement.

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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();
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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 {

View file

@ -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;
}
}
});

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}
});

View file

@ -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;
}
}

View file

@ -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());

View file

@ -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