1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 319330 - The indexing queue should give preference to the recently changed files

This commit is contained in:
Sergey Prigogin 2010-11-27 02:08:28 +00:00
parent 8dc35f6030
commit 0bdbe7ce95
9 changed files with 247 additions and 101 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2009 QNX Software Systems * Copyright (c) 2005, 2010 QNX Software Systems
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors: * Contributors:
* Doug Schaefer (QNX Software Systems) - initial API and implementation * Doug Schaefer (QNX Software Systems) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom; package org.eclipse.cdt.core.dom;
@ -42,4 +43,15 @@ public interface IPDOMIndexerTask {
* @noreference This method is not intended to be referenced by clients. * @noreference This method is not intended to be referenced by clients.
*/ */
public IndexerProgress getProgressInformation(); public IndexerProgress getProgressInformation();
/**
* Takes files from another task and adds them to this task in front of all not yet processed
* files. The urgent work my be rejected if this task is not capable of accepting it, or if
* the amount of urgent work is too large compared to the work already assigned to this task.
* @param task the task to add the work from.
* @return {@code true} if the work was accepted, {@code false} if it was rejected.
* @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=319330"
* @since 5.3
*/
public boolean acceptUrgentTask(IPDOMIndexerTask task);
} }

View file

@ -129,8 +129,7 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
} catch (NeedToParseException e) { } catch (NeedToParseException e) {
} }
} }
} } catch (CoreException e) {
catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
@ -224,8 +223,7 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
fIncludedFiles.add(file.getLocation()); fIncludedFiles.add(file.getLocation());
} }
return new InternalFileContent(GAP, macros, directives, new ArrayList<IIndexFile>(filesIncluded)); return new InternalFileContent(GAP, macros, directives, new ArrayList<IIndexFile>(filesIncluded));
} } catch (CoreException e) {
catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
return null; return null;
@ -249,7 +247,6 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
private boolean collectFileContentForGap(IIndexFile from, IIndexFileLocation to, private boolean collectFileContentForGap(IIndexFile from, IIndexFileLocation to,
Set<IIndexFile> filesIncluded, List<IIndexMacro> macros, Set<IIndexFile> filesIncluded, List<IIndexMacro> macros,
List<ICPPUsingDirective> directives) throws CoreException { List<ICPPUsingDirective> directives) throws CoreException {
final IIndexFileLocation ifl= from.getLocation(); final IIndexFileLocation ifl= from.getLocation();
if (ifl.equals(to)) { if (ifl.equals(to)) {
return true; return true;

View file

@ -6,8 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* IBM Corporation * IBM Corporation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom; package org.eclipse.cdt.internal.core.pdom;
@ -15,6 +16,7 @@ import java.lang.reflect.InvocationTargetException;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -24,6 +26,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -92,13 +95,17 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
public static class IndexFileContent { public static class IndexFileContent {
private IIndexFile fIndexFile= null; private IIndexFile fIndexFile;
private boolean fRequestUpdate= false; private boolean fRequestUpdate;
private boolean fRequestIsCounted= true; private boolean fRequestIsCounted= true;
private boolean fIsUpdated= false; private boolean fIsUpdated;
private Object[] fPreprocessingDirectives; private Object[] fPreprocessingDirectives;
private ICPPUsingDirective[] fDirectives; private ICPPUsingDirective[] fDirectives;
public IndexFileContent() {
fRequestIsCounted = true;
}
public Object[] getPreprocessingDirectives() throws CoreException { public Object[] getPreprocessingDirectives() throws CoreException {
if (fPreprocessingDirectives == null) { if (fPreprocessingDirectives == null) {
if (fIndexFile == null) if (fIndexFile == null)
@ -131,7 +138,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
public static Object[] merge(IIndexInclude[] includes, IIndexMacro[] macros) throws CoreException { public static Object[] merge(IIndexInclude[] includes, IIndexMacro[] macros) throws CoreException {
Object[] merged= new Object[includes.length+macros.length]; Object[] merged= new Object[includes.length + macros.length];
int i= 0; int i= 0;
int m= 0; int m= 0;
int ioffset= getOffset(includes, i); int ioffset= getOffset(includes, i);
@ -162,8 +169,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
} }
protected enum MessageKind {parsingFileTask, errorWhileParsing, tooManyIndexProblems} protected enum MessageKind { parsingFileTask, errorWhileParsing, tooManyIndexProblems }
private int fUpdateFlags= IIndexManager.UPDATE_ALL; private int fUpdateFlags= IIndexManager.UPDATE_ALL;
private UnusedHeaderStrategy fIndexHeadersWithoutContext= UnusedHeaderStrategy.useDefaultLanguage; private UnusedHeaderStrategy fIndexHeadersWithoutContext= UnusedHeaderStrategy.useDefaultLanguage;
@ -182,13 +189,21 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
private long fFileSizeLimit= 0; private long fFileSizeLimit= 0;
private InternalFileContentProvider fCodeReaderFactory; private InternalFileContentProvider fCodeReaderFactory;
private int fSwallowOutOfMemoryError= 5; private int fSwallowOutOfMemoryError= 5;
/**
* A queue of urgent indexing tasks that contribute additional files to this task.
* The files from the urgent tasks are indexed before all not yet processed files.
*/
private final LinkedList<AbstractIndexerTask> fUrgentTasks;
boolean fTaskCompleted;
public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove, IndexerInputAdapter resolver, boolean fastIndexer) { public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove,
IndexerInputAdapter resolver, boolean fastIndexer) {
super(resolver); super(resolver);
fIsFastIndexer= fastIndexer; fIsFastIndexer= fastIndexer;
fFilesToUpdate= filesToUpdate; fFilesToUpdate= filesToUpdate;
fFilesToRemove.addAll(Arrays.asList(filesToRemove)); Collections.addAll(fFilesToRemove, filesToRemove);
updateRequestedFiles(fFilesToUpdate.length + fFilesToRemove.size()); updateRequestedFiles(fFilesToUpdate.length + fFilesToRemove.size());
fUrgentTasks = new LinkedList<AbstractIndexerTask>();
} }
public final void setIndexHeadersWithoutContext(UnusedHeaderStrategy mode) { public final void setIndexHeadersWithoutContext(UnusedHeaderStrategy mode) {
@ -314,54 +329,126 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
public final void runTask(IProgressMonitor monitor) throws InterruptedException { public final void runTask(IProgressMonitor monitor) throws InterruptedException {
if (!fIndexFilesWithoutConfiguration) {
fIndexHeadersWithoutContext= UnusedHeaderStrategy.skip;
}
fIndex= createIndex();
if (fIndex == null) {
return;
}
fTodoTaskUpdater= createTodoTaskUpdater();
fASTOptions= ILanguage.OPTION_NO_IMAGE_LOCATIONS
| ILanguage.OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS;
if (getSkipReferences() == SKIP_ALL_REFERENCES) {
fASTOptions |= ILanguage.OPTION_SKIP_FUNCTION_BODIES;
}
fIndex.resetCacheCounters();
fIndex.acquireReadLock();
try { try {
try { if (!fIndexFilesWithoutConfiguration) {
// split into sources and headers, remove excluded sources. fIndexHeadersWithoutContext= UnusedHeaderStrategy.skip;
final HashMap<Integer, List<Object>> files= new HashMap<Integer, List<Object>>(); }
final ArrayList<IIndexFragmentFile> ifilesToRemove= new ArrayList<IIndexFragmentFile>();
extractFiles(files, ifilesToRemove, monitor); fIndex= createIndex();
if (fIndex == null) {
setResume(true); return;
}
// remove files from index fTodoTaskUpdater= createTodoTaskUpdater();
removeFilesInIndex(fFilesToRemove, ifilesToRemove, monitor);
fASTOptions= ILanguage.OPTION_NO_IMAGE_LOCATIONS
parseFilesUpFront(monitor); | ILanguage.OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS;
for (int linkageID : getLinkagesToParse()) { if (getSkipReferences() == SKIP_ALL_REFERENCES) {
parseLinkage(linkageID, files, monitor); fASTOptions |= ILanguage.OPTION_SKIP_FUNCTION_BODIES;
} }
if (!monitor.isCanceled()) {
setResume(false); fIndex.resetCacheCounters();
} fIndex.acquireReadLock();
} finally {
fIndex.flush(); try {
try {
// Split into sources and headers, remove excluded sources.
HashMap<Integer, List<Object>> files= new HashMap<Integer, List<Object>>();
final ArrayList<IIndexFragmentFile> indexFilesToRemove= new ArrayList<IIndexFragmentFile>();
extractFiles(files, indexFilesToRemove, monitor);
setResume(true);
// Remove files from index
removeFilesInIndex(fFilesToRemove, indexFilesToRemove, monitor);
parseFilesUpFront(monitor);
HashMap<Integer, List<Object>> moreFiles= null;
while (true) {
for (int linkageID : getLinkagesToParse()) {
parseLinkage(linkageID, files, monitor);
if (hasUrgentTasks())
break;
}
synchronized (this) {
if (fUrgentTasks.isEmpty()) {
if (moreFiles == null) {
// No urgent tasks and no more files to parse. We are done.
fTaskCompleted = true;
break;
} else {
files = moreFiles;
moreFiles = null;
}
}
}
AbstractIndexerTask urgentTask;
while ((urgentTask = getUrgentTask()) != null) {
// Move the lists of not yet parsed files from 'files' to 'moreFiles'.
if (moreFiles == null) {
moreFiles = files;
} else {
for (Map.Entry<Integer, List<Object>> entry : files.entrySet()) {
List<Object> list= moreFiles.get(entry.getKey());
if (list == null) {
moreFiles.put(entry.getKey(), entry.getValue());
} else {
list.addAll(0, entry.getValue());
}
}
}
// Extract files from the urgent task.
files = new HashMap<Integer, List<Object>>();
fFilesToUpdate = urgentTask.fFilesToUpdate;
fForceNumberFiles = urgentTask.fForceNumberFiles;
fFilesToRemove = urgentTask.fFilesToRemove;
extractFiles(files, indexFilesToRemove, monitor);
removeFilesInIndex(fFilesToRemove, indexFilesToRemove, monitor);
}
}
if (!monitor.isCanceled()) {
setResume(false);
}
} finally {
fIndex.flush();
}
} catch (CoreException e) {
logException(e);
} finally {
fIndex.releaseReadLock();
} }
} catch (CoreException e) {
logException(e);
} finally { } finally {
fIndex.releaseReadLock(); synchronized (this) {
fTaskCompleted = true;
}
} }
} }
/**
* @see IPDOMIndexerTask#acceptUrgentTask(IPDOMIndexerTask)
*/
public synchronized boolean acceptUrgentTask(IPDOMIndexerTask urgentTask) {
if (!(urgentTask instanceof AbstractIndexerTask)) {
return false;
}
AbstractIndexerTask task = (AbstractIndexerTask) urgentTask;
if (!task.fFilesUpFront.isEmpty() ||
task.fIsFastIndexer != fIsFastIndexer ||
task.fIndexFilesWithoutConfiguration != fIndexFilesWithoutConfiguration ||
(fIndexFilesWithoutConfiguration && task.fIndexHeadersWithoutContext != fIndexHeadersWithoutContext) ||
fTaskCompleted) {
// Reject the urgent work since this task is not capable of doing it, or it's too late.
return false;
}
if (task.fFilesToUpdate.length >
(fFilesToUpdate != null ? fFilesToUpdate.length : getProgressInformation().fRequestedFilesCount)) {
// Reject the urgent work since it's too heavy for this task.
return false;
}
fUrgentTasks.add(task);
return true;
}
private void setResume(boolean value) throws InterruptedException, CoreException { private void setResume(boolean value) throws InterruptedException, CoreException {
fIndex.acquireWriteLock(1); fIndex.acquireWriteLock(1);
try { try {
@ -371,7 +458,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} }
private void extractFiles(Map<Integer, List<Object>> files, List<IIndexFragmentFile> iFilesToRemove, private void extractFiles(HashMap<Integer, List<Object>> files, List<IIndexFragmentFile> iFilesToRemove,
IProgressMonitor monitor) throws CoreException { IProgressMonitor monitor) throws CoreException {
final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0; final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0;
final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0; final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0;
@ -444,8 +531,10 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} }
} }
updateRequestedFiles(count - fFilesToUpdate.length); synchronized (this) {
fFilesToUpdate= null; updateRequestedFiles(count - fFilesToUpdate.length);
fFilesToUpdate= null;
}
} }
private boolean isModified(boolean checkTimestamps, boolean checkFileContentsHash, IIndexFileLocation ifl, private boolean isModified(boolean checkTimestamps, boolean checkFileContentsHash, IIndexFileLocation ifl,
@ -470,6 +559,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
info.fIndexFile= ifile; info.fIndexFile= ifile;
info.fRequestUpdate= true; info.fRequestUpdate= true;
info.fIsUpdated= false;
} }
private void setIndexed(int linkageID, IIndexFileLocation ifl) { private void setIndexed(int linkageID, IIndexFileLocation ifl) {
@ -520,7 +610,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} }
private void store(Object tu, int linkageID, boolean isSourceUnit, Map<Integer, List<Object>> files) { private void store(Object tu, int linkageID, boolean isSourceUnit, HashMap<Integer, List<Object>> files) {
Integer key = getFileListKey(linkageID, isSourceUnit); Integer key = getFileListKey(linkageID, isSourceUnit);
List<Object> list= files.get(key); List<Object> list= files.get(key);
if (list == null) { if (list == null) {
@ -535,12 +625,12 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
return key; return key;
} }
private void removeFilesInIndex(List<Object> filesToRemove, List<IIndexFragmentFile> ifilesToRemove, private void removeFilesInIndex(List<Object> filesToRemove, List<IIndexFragmentFile> indexFilesToRemove,
IProgressMonitor monitor) throws InterruptedException, CoreException { IProgressMonitor monitor) throws InterruptedException, CoreException {
if (!filesToRemove.isEmpty() || !ifilesToRemove.isEmpty()) { if (!filesToRemove.isEmpty() || !indexFilesToRemove.isEmpty()) {
fIndex.acquireWriteLock(1); fIndex.acquireWriteLock(1);
try { try {
for (Object tu : fFilesToRemove) { for (Object tu : filesToRemove) {
if (monitor.isCanceled()) { if (monitor.isCanceled()) {
return; return;
} }
@ -553,7 +643,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
updateRequestedFiles(-1); updateRequestedFiles(-1);
} }
for (IIndexFragmentFile ifile : ifilesToRemove) { for (IIndexFragmentFile ifile : indexFilesToRemove) {
if (monitor.isCanceled()) { if (monitor.isCanceled()) {
return; return;
} }
@ -564,7 +654,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
fIndex.releaseWriteLock(1); fIndex.releaseWriteLock(1);
} }
} }
fFilesToRemove.clear(); filesToRemove.clear();
} }
private void parseFilesUpFront(IProgressMonitor monitor) throws CoreException { private void parseFilesUpFront(IProgressMonitor monitor) throws CoreException {
@ -630,35 +720,38 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
private void parseLinkage(int linkageID, Map<Integer, List<Object>> fileListMap, IProgressMonitor monitor) private void parseLinkage(int linkageID, Map<Integer, List<Object>> fileListMap, IProgressMonitor monitor)
throws CoreException, InterruptedException { throws CoreException, InterruptedException {
// sources // Sources
List<Object> files= fileListMap.get(getFileListKey(linkageID, true)); List<Object> files= fileListMap.get(getFileListKey(linkageID, true));
if (files != null) { if (files != null) {
for (Object tu : files) { for (Iterator<Object> iter = files.iterator(); iter.hasNext();) {
if (monitor.isCanceled()) Object tu = iter.next();
if (monitor.isCanceled() || hasUrgentTasks())
return; return;
final IIndexFileLocation ifl = fResolver.resolveFile(tu); final IIndexFileLocation ifl = fResolver.resolveFile(tu);
if (ifl == null) if (ifl != null) {
continue; final IndexFileContent info= getFileInfo(linkageID, ifl);
final IndexFileContent info= getFileInfo(linkageID, ifl); if (info != null && info.fRequestUpdate && !info.fIsUpdated) {
if (info != null && info.fRequestUpdate && !info.fIsUpdated) { info.fRequestIsCounted= false;
info.fRequestIsCounted= false; final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, tu);
final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, tu); parseFile(tu, linkageID, ifl, scannerInfo, false, monitor);
parseFile(tu, linkageID, ifl, scannerInfo, false, monitor); if (info.fIsUpdated) {
if (info.fIsUpdated) { updateFileCount(1, 0, 0); // a source file was parsed
updateFileCount(1, 0, 0); // a source file was parsed }
} }
} }
iter.remove();
} }
files.clear();
} }
// headers with context // Headers with context
HashMap<IIndexFragmentFile, Object> contextMap= new HashMap<IIndexFragmentFile, Object>(); HashMap<IIndexFragmentFile, Object> contextMap= new HashMap<IIndexFragmentFile, Object>();
files= fileListMap.get(getFileListKey(linkageID, false)); files= fileListMap.get(getFileListKey(linkageID, false));
if (files != null) { if (files != null) {
for (Iterator<Object> iter = files.iterator(); iter.hasNext();) { for (Iterator<Object> iter = files.iterator(); iter.hasNext();) {
if (monitor.isCanceled()) if (monitor.isCanceled() || hasUrgentTasks())
return; return;
final Object header= iter.next(); final Object header= iter.next();
final IIndexFileLocation ifl = fResolver.resolveFile(header); final IIndexFileLocation ifl = fResolver.resolveFile(header);
final IndexFileContent info= getFileInfo(linkageID, ifl); final IndexFileContent info= getFileInfo(linkageID, ifl);
@ -676,16 +769,17 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} }
} else { } else {
// file was already parsed. // The file has been parsed already.
iter.remove(); iter.remove();
} }
} }
// headers without context // Headers without context
contextMap= null; contextMap= null;
for (Iterator<Object> iter = files.iterator(); iter.hasNext();) { for (Iterator<Object> iter = files.iterator(); iter.hasNext();) {
if (monitor.isCanceled()) if (monitor.isCanceled() || hasUrgentTasks())
return; return;
final Object header= iter.next(); final Object header= iter.next();
final IIndexFileLocation ifl = fResolver.resolveFile(header); final IIndexFileLocation ifl = fResolver.resolveFile(header);
final IndexFileContent info= getFileInfo(linkageID, ifl); final IndexFileContent info= getFileInfo(linkageID, ifl);
@ -695,13 +789,25 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
parseFile(header, linkageID, ifl, scannerInfo, false, monitor); parseFile(header, linkageID, ifl, scannerInfo, false, monitor);
if (info.fIsUpdated) { if (info.fIsUpdated) {
updateFileCount(0, 1, 1); // a header was parsed without context updateFileCount(0, 1, 1); // a header was parsed without context
iter.remove();
} }
} }
iter.remove();
} }
} }
} }
private synchronized boolean hasUrgentTasks() {
return !fUrgentTasks.isEmpty();
}
/**
* Retrieves the first urgent task from the queue of urgent tasks.
* @return An urgent task, or {@code null} if there are no urgent tasks.
*/
private synchronized AbstractIndexerTask getUrgentTask() {
return fUrgentTasks.poll();
}
private static final Object NO_CONTEXT= new Object(); private static final Object NO_CONTEXT= new Object();
private Object findContext(int linkageID, IIndexFragmentFile ifile, HashMap<IIndexFragmentFile, Object> contextMap) { private Object findContext(int linkageID, IIndexFragmentFile ifile, HashMap<IIndexFragmentFile, Object> contextMap) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -23,13 +23,12 @@ import org.eclipse.core.runtime.content.IContentTypeManager.ContentTypeChangeEve
/** /**
* Task to notify the CModel manager of changes to the content types. * Task to notify the CModel manager of changes to the content types.
*
*/ */
public class NotifyCModelManagerTask implements IPDOMIndexerTask { public class NotifyCModelManagerTask implements IPDOMIndexerTask {
private final IProject fProject; private final IProject fProject;
public NotifyCModelManagerTask(IProject prj) { public NotifyCModelManagerTask(IProject project) {
fProject= prj; fProject= project;
} }
public IPDOMIndexer getIndexer() { public IPDOMIndexer getIndexer() {
@ -51,4 +50,8 @@ public class NotifyCModelManagerTask implements IPDOMIndexerTask {
}); });
} }
} }
public boolean acceptUrgentTask(IPDOMIndexerTask task) {
return false;
}
} }

View file

@ -664,8 +664,14 @@ public class PDOMManager implements IWritableIndexManager, IListener {
getReferencingProjects(indexer.getProject().getProject(), referencing); getReferencingProjects(indexer.getProject().getProject(), referencing);
} }
synchronized (fTaskQueue) { synchronized (fTaskQueue) {
if (fCurrentTask != null && fCurrentTask.acceptUrgentTask(subjob)) {
return;
}
int i= 0; int i= 0;
for (IPDOMIndexerTask task : fTaskQueue) { for (IPDOMIndexerTask task : fTaskQueue) {
if (task.acceptUrgentTask(subjob)) {
return;
}
final IPDOMIndexer ti = task.getIndexer(); final IPDOMIndexer ti = task.getIndexer();
if (ti != null && referencing.contains(ti.getProject().getProject())) { if (ti != null && referencing.contains(ti.getProject().getProject())) {
fTaskQueue.add(i, subjob); fTaskQueue.add(i, subjob);

View file

@ -170,7 +170,8 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
if (ct != null) { if (ct != null) {
ILanguage l = LanguageManager.getInstance().getLanguage(ct); ILanguage l = LanguageManager.getInstance().getLanguage(ct);
if (l instanceof AbstractLanguage) { if (l instanceof AbstractLanguage) {
if (filename.indexOf('.') >= 0 && ct.getId().equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) && l.getLinkageID() == ILinkage.CPP_LINKAGE_ID) { if (filename.indexOf('.') >= 0 && ct.getId().equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) &&
l.getLinkageID() == ILinkage.CPP_LINKAGE_ID) {
ILanguage l2= LanguageManager.getInstance().getLanguageForContentTypeID(CCorePlugin.CONTENT_TYPE_CHEADER); ILanguage l2= LanguageManager.getInstance().getLanguageForContentTypeID(CCorePlugin.CONTENT_TYPE_CHEADER);
if (l2 instanceof AbstractLanguage) { if (l2 instanceof AbstractLanguage) {
return new AbstractLanguage[] {(AbstractLanguage) l, (AbstractLanguage) l2}; return new AbstractLanguage[] {(AbstractLanguage) l, (AbstractLanguage) l2};
@ -371,4 +372,14 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
public void setWriteInfoToLog() { public void setWriteInfoToLog() {
fWriteInfoToLog= true; fWriteInfoToLog= true;
} }
@Override
public synchronized boolean acceptUrgentTask(IPDOMIndexerTask urgentTask) {
final IPDOMIndexer ti = urgentTask.getIndexer();
if (fIndexer == null || ti == null ||
fIndexer.getProject().getProject() != ti.getProject().getProject()) {
return false;
}
return super.acceptUrgentTask(urgentTask);
}
} }

View file

@ -1,12 +1,13 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2009 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer; package org.eclipse.cdt.internal.core.pdom.indexer;
@ -94,8 +95,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
if (wf instanceof WritablePDOM) { if (wf instanceof WritablePDOM) {
PDOMManager.writeProjectPDOMProperties((WritablePDOM) wf, project.getProject()); PDOMManager.writeProjectPDOMProperties((WritablePDOM) wf, project.getProject());
} }
} } finally {
finally {
index.releaseWriteLock(0); index.releaseWriteLock(0);
} }
} }
@ -124,4 +124,8 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
public synchronized IndexerProgress getProgressInformation() { public synchronized IndexerProgress getProgressInformation() {
return fDelegate != null ? fDelegate.getProgressInformation() : fProgress; return fDelegate != null ? fDelegate.getProgressInformation() : fProgress;
} }
public synchronized boolean acceptUrgentTask(IPDOMIndexerTask task) {
return fDelegate != null && fDelegate.acceptUrgentTask(task);
}
} }

View file

@ -6,8 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ * Sergey Prigogin (Google)
******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer; package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.ArrayList; import java.util.ArrayList;
@ -92,8 +93,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
boolean haveProject= false; boolean haveProject= false;
if (fFilesAndFolders == null) { if (fFilesAndFolders == null) {
project.accept(collector); project.accept(collector);
} } else {
else {
for (ICElement elem : fFilesAndFolders) { for (ICElement elem : fFilesAndFolders) {
if (elem.getElementType() == ICElement.C_PROJECT) { if (elem.getElementType() == ICElement.C_PROJECT) {
haveProject= true; haveProject= true;
@ -147,6 +147,10 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
return fDelegate != null ? fDelegate.getProgressInformation() : fProgress; return fDelegate != null ? fDelegate.getProgressInformation() : fProgress;
} }
public synchronized boolean acceptUrgentTask(IPDOMIndexerTask task) {
return fDelegate != null && fDelegate.acceptUrgentTask(task);
}
public void setTranslationUnitSelection(List<ICElement> filesAndFolders) { public void setTranslationUnitSelection(List<ICElement> filesAndFolders) {
fFilesAndFolders= new ArrayList<ICElement>(filesAndFolders.size()); fFilesAndFolders= new ArrayList<ICElement>(filesAndFolders.size());
fFilesAndFolders.addAll(filesAndFolders); fFilesAndFolders.addAll(filesAndFolders);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2009 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -23,7 +23,6 @@ import org.eclipse.core.runtime.IProgressMonitor;
* In this situation the pdom itself does not generate a notification. * In this situation the pdom itself does not generate a notification.
*/ */
public class TriggerNotificationTask implements IPDOMIndexerTask { public class TriggerNotificationTask implements IPDOMIndexerTask {
private WritablePDOM fPDOM; private WritablePDOM fPDOM;
private PDOMManager fManager; private PDOMManager fManager;
@ -45,4 +44,8 @@ public class TriggerNotificationTask implements IPDOMIndexerTask {
event.setReloaded(); event.setReloaded();
fManager.handleChange(fPDOM, event); fManager.handleChange(fPDOM, event);
} }
public boolean acceptUrgentTask(IPDOMIndexerTask task) {
return false;
}
} }