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

Partial fix for 167551, use index on project import.

This commit is contained in:
Markus Schorn 2007-03-02 14:09:40 +00:00
parent a435c99411
commit 5d94f504c5
20 changed files with 922 additions and 192 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2007 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
@ -58,7 +58,7 @@ public class CModelListener implements IElementChangedListener {
final ICProject project = (ICProject)delta.getElement();
switch (delta.getKind()) {
case ICElementDelta.ADDED:
fManager.addProject(project, delta);
fManager.addProject(project.getProject());
break;
case ICElementDelta.CHANGED:
fManager.changeProject(project, delta);

View file

@ -0,0 +1,141 @@
/*******************************************************************************
* Copyright (c) 2007 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;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
public class Checksums {
private static final String KEY_ALGORITHM = "//algorithm//"; //$NON-NLS-1$
private static final String DEFAULT_ALGORITHM = "MD5"; //$NON-NLS-1$
/**
* Returns the default algorithm used to compute checksums.
* @throws NoSuchAlgorithmException
* @since 4.0
*/
public static MessageDigest getDefaultAlgorithm() throws NoSuchAlgorithmException {
return MessageDigest.getInstance(DEFAULT_ALGORITHM);
}
/**
* Retrieves the algorithm for computing checksums from the persisted map.
* @throws NoSuchAlgorithmException
* @since 4.0
*/
public static MessageDigest getAlgorithm(Map persistedMap) throws NoSuchAlgorithmException {
Object obj= persistedMap.get(KEY_ALGORITHM);
String alg= obj instanceof String ? (String) obj : DEFAULT_ALGORITHM;
return MessageDigest.getInstance(alg);
}
/**
* Stores the algorithm in a map.
* @since 4.0
*/
public static void putAlgorithm(Map mapToPersist, MessageDigest md) {
mapToPersist.put(KEY_ALGORITHM, md.getAlgorithm());
}
/**
* Computes the checksum for a given file.
*/
public static byte[] computeChecksum(MessageDigest md, File file) throws IOException {
md.reset();
FileInputStream fi= new FileInputStream(file);
try {
int read;
byte[] buf= new byte[1024*64];
while( (read= fi.read(buf)) >= 0) {
md.update(buf, 0, read);
}
return md.digest();
}
finally {
fi.close();
}
}
/**
* Retrieves a checksum for a file from the persisted map. May return <code>null</code>.
* @since 4.0
*/
public static byte[] getChecksum(Map persistedMap, IFile file) {
IPath prjRel= file.getProjectRelativePath();
Object checksum= persistedMap.get(prjRel.toString());
if (checksum instanceof byte[]) {
return (byte[]) checksum;
}
return null;
}
/**
* Stores a checksum in a map.
* @since 4.0
*/
public static void putChecksum(Map mapToPersist, IFile file, byte[] checksum) {
IPath prjRel= file.getProjectRelativePath();
mapToPersist.put(prjRel.toString(), checksum);
}
/**
* Creates a map to persist checksums for a project.
* @throws OperationCanceledException
* @since 4.0
*/
public static Map createChecksumMap(ITranslationUnit[] tus, MessageDigest md, IProgressMonitor pm)
throws OperationCanceledException {
Map result= new HashMap();
putAlgorithm(result, md);
pm.beginTask(Messages.Checksums_taskComputeChecksums, tus.length);
for (int i = 0; i < tus.length; i++) {
if (pm.isCanceled()) {
throw new OperationCanceledException();
}
ITranslationUnit tu = tus[i];
IResource res= tu.getResource();
if (res instanceof IFile) {
IFile file= (IFile) res;
IPath location= file.getLocation();
if (location != null) {
File f= location.toFile();
if (f.exists()) {
try {
byte[] checksum= computeChecksum(md, f);
putChecksum(result, file, checksum);
}
catch (IOException e) {
CCorePlugin.log(e);
}
}
}
}
pm.worked(1);
}
pm.done();
return result;
}
}

View file

@ -17,7 +17,6 @@ public class IndexerProgress {
public int fCompletedHeaders;
public int fCompletedSources;
public int fTimeEstimate;
public String fMonitorDetail;
public IndexerProgress() {
}
@ -26,7 +25,6 @@ public class IndexerProgress {
fTotalSourcesEstimate= info.fTotalSourcesEstimate;
fCompletedHeaders= info.fCompletedHeaders;
fCompletedSources= info.fCompletedSources;
fMonitorDetail= info.fMonitorDetail;
}

View file

@ -15,6 +15,7 @@ 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 Checksums_taskComputeChecksums;
public static String PDOMManager_ExistingFileCollides;
public static String PDOMManager_indexMonitorDetail;
public static String PDOMManager_JoinIndexerTask;

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
@ -25,6 +26,7 @@ import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.IPDOM;
@ -48,6 +50,7 @@ import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.ApplyVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
@ -110,15 +113,24 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
private IIndexLocationConverter locationConverter;
public PDOM(File dbPath, IIndexLocationConverter locationConverter) throws CoreException {
// Load up the database
loadDatabase(dbPath);
this.locationConverter = locationConverter;
}
private void loadDatabase(File dbPath) throws CoreException {
fPath= dbPath;
boolean exists= fPath.exists();
db = new Database(fPath);
if (db.getVersion() == VERSION) {
readLinkages();
if (exists) {
int version= db.getVersion();
if (version == VERSION) {
readLinkages();
}
}
else {
db.setVersion(VERSION);
}
this.locationConverter = locationConverter;
}
public IIndexLocationConverter getLocationConverter() {
@ -180,6 +192,21 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
return PDOMFile.findFile(this, getFileIndex(), location, locationConverter);
}
public List/*<IIndexFileLocation>*/ getAllFileLocations() throws CoreException {
final List locations = new ArrayList();
getFileIndex().accept(new IBTreeVisitor(){
public int compare(int record) throws CoreException {
return 0;
}
public boolean visit(int record) throws CoreException {
PDOMFile file = new PDOMFile(PDOM.this, record);
locations.add(file.getLocation());
return true;
}
});
return locations;
}
protected IIndexFragmentFile addFile(IIndexFileLocation location) throws CoreException {
IIndexFragmentFile file = getFile(location);
if (file == null) {
@ -208,6 +235,18 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
db.putInt(LINKAGES, 0);
fLinkageIDCache.clear();
}
void reloadFromFile(File file) throws CoreException {
File oldFile= fPath;
fLinkageIDCache.clear();
try {
db.close();
} catch (IOException e) {
CCorePlugin.log(e);
}
loadDatabase(file);
oldFile.delete();
}
public boolean isEmpty() throws CoreException {
return getFirstLinkageRecord() == 0;

View file

@ -0,0 +1,309 @@
/*******************************************************************************
* Copyright (c) 2007 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;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.cdt.internal.core.pdom.indexer.Messages;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.osgi.util.NLS;
public class PDOMImporter {
private static final String CHECKSUMS_NAME = "checksums.dat"; //$NON-NLS-1$
private static final String INDEX_NAME = "cdt-index.pdom"; //$NON-NLS-1$
private static final class FileAndChecksum {
public ITranslationUnit fFile;
public byte[] fChecksum;
public FileAndChecksum(ITranslationUnit tu, byte[] checksum) {
fFile= tu;
fChecksum= checksum;
}
}
private ICProject fProject;
private boolean fSuccess;
private ITranslationUnit[] fTranslationUnitsToUpdate= new ITranslationUnit[0];
private boolean fShowActivity;
public PDOMImporter(ICProject project) {
fProject= project;
fShowActivity= PDOMIndexerTask.checkDebugOption(IPDOMIndexerTask.TRACE_ACTIVITY, "true"); //$NON-NLS-1$
}
public void performImport(IProgressMonitor pm) {
if (fShowActivity) {
System.out.println("Indexer: PDOMImporter start"); //$NON-NLS-1$
}
IPath importLocation= getImportLocation();
fSuccess= importIndex(importLocation, pm);
if (fShowActivity) {
System.out.println("Indexer: PDOMImporter completed, ok=" + fSuccess); //$NON-NLS-1$
}
}
public boolean wasSuccessful() {
return fSuccess;
}
public ITranslationUnit[] getTranslationUnitsToUpdate() {
return fTranslationUnitsToUpdate;
}
private IPath getImportLocation() {
IProject project= fProject.getProject();
String locationString= IndexerPreferences.getIndexImportLocation(project);
// mstodo support variables
IPath location= new Path(locationString);
if (!location.isAbsolute()) {
location= project.getLocation().append(location);
}
return location;
}
private boolean importIndex(IPath importLocation, IProgressMonitor monitor) {
File importFile= importLocation.toFile();
if (!importFile.exists()) {
return false;
}
Exception ex= null;
try {
doImportIndex(importFile, monitor);
}
catch (InterruptedException e) {
throw new OperationCanceledException();
}
catch (ZipException e) {
ex= e;
}
catch (IOException e) {
ex= e;
}
catch (CoreException e) {
ex= e;
}
if (ex != null) {
CCorePlugin.log(ex);
return false;
}
return true;
}
private void doImportIndex(File importFile, IProgressMonitor monitor) throws CoreException, InterruptedException, IOException {
ZipFile zip= new ZipFile(importFile);
Map checksums= null;
try {
importIndex(zip, monitor);
checksums= getChecksums(zip);
}
finally {
try {
zip.close();
} catch (IOException e) {
CCorePlugin.log(e);
}
}
checkIndex(checksums, monitor);
}
private void importIndex(ZipFile zip, IProgressMonitor monitor) throws CoreException, IOException {
ZipEntry indexEntry= zip.getEntry(INDEX_NAME);
if (indexEntry == null) {
throw new CoreException(CCorePlugin.createStatus(
NLS.bind(Messages.PDOMImportTask_errorInvalidArchive, zip.getName())));
}
InputStream stream= zip.getInputStream(indexEntry);
CCoreInternals.getPDOMManager().importProjectPDOM(fProject, stream);
}
private Map getChecksums(ZipFile zip) {
ZipEntry indexEntry= zip.getEntry(CHECKSUMS_NAME);
if (indexEntry != null) {
try {
ObjectInputStream input= new ObjectInputStream(zip.getInputStream(indexEntry));
try {
Object obj= input.readObject();
if (obj instanceof Map) {
return (Map) obj;
}
}
finally {
input.close();
}
}
catch (Exception e) {
CCorePlugin.log(e);
}
}
return Collections.EMPTY_MAP;
}
private void checkIndex(Map checksums, IProgressMonitor monitor) throws CoreException, InterruptedException {
List filesToCheck= new ArrayList();
WritablePDOM pdom= (WritablePDOM) CCoreInternals.getPDOMManager().getPDOM(fProject);
pdom.acquireReadLock();
try {
if (pdom.versionMismatch()) {
throw new CoreException(CCorePlugin.createStatus(
NLS.bind(Messages.PDOMImportTask_errorInvalidPDOMVersion, fProject.getElementName())));
}
final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
List filesToDelete= pdom.getAllFileLocations();
for (Iterator i = filesToDelete.iterator(); i.hasNext();) {
checkMonitor(monitor);
byte[] checksum= null;
ITranslationUnit tu= null;
IIndexFileLocation ifl = (IIndexFileLocation) i.next();
String fullPathStr= ifl.getFullPath();
if (fullPathStr != null) {
Path fullPath= new Path(fullPathStr);
IFile file= root.getFile(fullPath);
boolean exists= file.exists();
if (!exists) {
try {
file.refreshLocal(0, new NullProgressMonitor());
exists= file.exists();
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
if (exists) {
tu= (ITranslationUnit) CoreModel.getDefault().create(file);
if (tu != null) {
checksum= Checksums.getChecksum(checksums, file);
}
}
}
if (checksum != null) {
filesToCheck.add(new FileAndChecksum(tu, checksum));
i.remove();
}
}
deleteFiles(pdom, 1, filesToDelete, filesToCheck, monitor);
try {
fTranslationUnitsToUpdate= checkFiles(checksums, filesToCheck, monitor);
}
catch (NoSuchAlgorithmException e) {
CCorePlugin.log(e);
}
}
finally {
pdom.releaseReadLock();
}
}
private void checkMonitor(IProgressMonitor monitor) {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
}
private void deleteFiles(WritablePDOM pdom, final int giveupReadlocks, List filesToDelete,
List updateTimestamps, IProgressMonitor monitor) throws InterruptedException, CoreException {
pdom.acquireWriteLock(giveupReadlocks);
try {
for (Iterator i = filesToDelete.iterator(); i.hasNext();) {
checkMonitor(monitor);
IndexFileLocation ifl = (IndexFileLocation) i.next();
IIndexFragmentFile file= pdom.getFile(ifl);
pdom.clearFile(file);
}
for (Iterator i = updateTimestamps.iterator(); i.hasNext();) {
checkMonitor(monitor);
FileAndChecksum fc = (FileAndChecksum) i.next();
IIndexFragmentFile file= pdom.getFile(IndexLocationFactory.getIFL(fc.fFile));
if (file != null) {
IResource r= fc.fFile.getResource();
if (r != null) {
file.setTimestamp(r.getLocalTimeStamp());
}
}
}
}
finally {
pdom.releaseWriteLock(giveupReadlocks);
}
}
private ITranslationUnit[] checkFiles(Map checksums, List filesToCheck, IProgressMonitor monitor) throws NoSuchAlgorithmException {
List result= new ArrayList();
MessageDigest md= Checksums.getAlgorithm(checksums);
for (Iterator i = filesToCheck.iterator(); i.hasNext();) {
checkMonitor(monitor);
FileAndChecksum cs= (FileAndChecksum) i.next();
ITranslationUnit tu= cs.fFile;
if (tu != null) {
IPath location= tu.getLocation();
if (location != null) {
try {
byte[] checksum= Checksums.computeChecksum(md, location.toFile());
if (!Arrays.equals(checksum, cs.fChecksum)) {
result.add(tu);
}
}
catch (IOException e) {
CCorePlugin.log(e);
}
}
}
}
return (ITranslationUnit[]) result.toArray(new ITranslationUnit[result.size()]);
}
}

View file

@ -14,9 +14,11 @@ package org.eclipse.cdt.internal.core.pdom;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
@ -27,17 +29,19 @@ import org.eclipse.core.runtime.jobs.Job;
public class PDOMIndexerJob extends Job {
private static final int PROGRESS_UPDATE_INTERVAL = 500;
private static final int TOTAL_MONITOR_WORK = 1000;
static volatile String sMonitorDetail= null;
private final PDOMManager pdomManager;
private IPDOMIndexerTask currentTask;
private boolean cancelledByManager= false;
private Object taskMutex = new Object();
private IProgressMonitor fMonitor;
private final boolean fShowActivity;
public PDOMIndexerJob(PDOMManager manager) {
super(CCorePlugin.getResourceString("pdom.indexer.name")); //$NON-NLS-1$
this.pdomManager = manager;
fShowActivity= PDOMIndexerTask.checkDebugOption(IPDOMIndexerTask.TRACE_ACTIVITY, "true"); //$NON-NLS-1$
setPriority(Job.LONG);
}
@ -47,15 +51,18 @@ public class PDOMIndexerJob extends Job {
monitor.beginTask(taskName, TOTAL_MONITOR_WORK);
Job monitorJob= startMonitorJob(monitor);
try {
IProgressMonitor npm= new NullProgressMonitor() {
public boolean isCanceled() {
return fMonitor.isCanceled();
}
public void setCanceled(boolean cancelled) {
fMonitor.setCanceled(cancelled);
}
public void subTask(String name) {
sMonitorDetail= name;
}
};
do {
IProgressMonitor npm= new NullProgressMonitor() {
public boolean isCanceled() {
return fMonitor.isCanceled();
}
public void setCanceled(boolean cancelled) {
fMonitor.setCanceled(cancelled);
}
};
synchronized(taskMutex) {
currentTask= null;
taskMutex.notify();
@ -71,7 +78,22 @@ public class PDOMIndexerJob extends Job {
}
if (currentTask != null) {
currentTask.run(npm);
try {
String name= null;
long time= 0;
if (fShowActivity) {
name= getClassName(currentTask);
time= -System.currentTimeMillis();
System.out.println("Indexer: start " + name); //$NON-NLS-1$
}
currentTask.run(npm);
if (fShowActivity) {
time += System.currentTimeMillis();
System.out.println("Indexer: completed " + name + "[" + time + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
catch (OperationCanceledException e) {
}
}
}
while (currentTask != null);
@ -100,6 +122,12 @@ public class PDOMIndexerJob extends Job {
monitor.done();
}
}
private String getClassName(Object obj) {
String name= obj.getClass().getName();
name= name.substring(name.lastIndexOf('.')+1);
return name;
}
private Job startMonitorJob(final IProgressMonitor targetMonitor) {
Job monitorJob= new Job(CCorePlugin.getResourceString("PDOMIndexerJob.updateMonitorJob")) { //$NON-NLS-1$
@ -136,4 +164,8 @@ public class PDOMIndexerJob extends Job {
}
}
}
public boolean belongsTo(Object family) {
return family == pdomManager;
}
}

View file

@ -16,6 +16,8 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.text.MessageFormat;
import java.util.HashMap;
@ -38,8 +40,8 @@ import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.internal.core.index.IndexChangeEvent;
@ -49,12 +51,14 @@ import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMImportTask;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMRebuildTask;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMResourceDeltaTask;
import org.eclipse.cdt.internal.core.pdom.indexer.nulli.PDOMNullIndexer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
@ -62,10 +66,12 @@ 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.OperationCanceledException;
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.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
@ -105,6 +111,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
private static final ISchedulingRule NOTIFICATION_SCHEDULING_RULE = new PerInstanceSchedulingRule();
private static final ISchedulingRule INDEXER_SCHEDULING_RULE = new PerInstanceSchedulingRule();
private static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0];
/**
* Protects indexerJob, currentTask and taskQueue.
@ -148,27 +155,11 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
final CoreModel model = CoreModel.getDefault();
model.addElementChangedListener(fCModelListener);
Job startup= new Job(Messages.PDOMManager_StartJob_name) {
protected IStatus run(IProgressMonitor monitor) {
ICProject[] projects;
try {
projects = model.getCModel().getCProjects();
for (int i = 0; i < projects.length; i++) {
ICProject project = projects[i];
if (project.getProject().isOpen()) {
addProject(project, null);
}
}
} catch (CoreException e) {
CCorePlugin.log(e);
return e.getStatus();
}
return Status.OK_STATUS;
}
};
startup.setSystem(true);
startup.setRule(INDEXER_SCHEDULING_RULE); // block indexer until init is done.
startup.schedule(1000);
IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (int i = 0; i < projects.length; i++) {
IProject project = projects[i];
addProject(project);
}
}
public IPDOM getPDOM(ICProject project) throws CoreException {
@ -182,7 +173,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
String dbName= rproject.getPersistentProperty(dbNameProperty);
File dbFile= null;
if (dbName != null) {
dbFile= CCorePlugin.getDefault().getStateLocation().append(dbName).toFile();
dbFile= fileFromDatabaseName(dbName);
ICProject currentCOwner= (ICProject) fFileToProject.get(dbFile);
if (currentCOwner != null) {
IProject currentOwner= currentCOwner.getProject();
@ -199,13 +190,12 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
if (pdom == null) {
if (dbName == null) {
dbName= getDefaultName(project);
rproject.setPersistentProperty(dbNameProperty, dbName);
dbFile= CCorePlugin.getDefault().getStateLocation().append(dbName).toFile();
dbName = createNewDatabaseName(project);
dbFile= fileFromDatabaseName(dbName);
storeDatabaseName(rproject, dbName);
}
pdom = new WritablePDOM(dbFile, new PDOMProjectIndexLocationConverter(rproject));
pdom.setProperty(IIndexFragment.PROPERTY_FRAGMENT_ID, "org.eclipse.cdt.internal.pdom["+rproject.getName()+"]"); //$NON-NLS-1$ //$NON-NLS-2$
pdom.addListener(this);
}
@ -215,8 +205,29 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
}
private String getDefaultName(ICProject project) {
return project.getElementName() + "." + System.currentTimeMillis() + ".pdom"; //$NON-NLS-1$//$NON-NLS-2$
private void storeDatabaseName(IProject rproject, String dbName)
throws CoreException {
rproject.setPersistentProperty(dbNameProperty, dbName);
}
private String createNewDatabaseName(ICProject project) {
String dbName;
long time= System.currentTimeMillis();
File file;
do {
dbName= getDefaultName(project, time++);
file= fileFromDatabaseName(dbName);
}
while (file.exists());
return dbName;
}
private File fileFromDatabaseName(String dbName) {
return CCorePlugin.getDefault().getStateLocation().append(dbName).toFile();
}
private String getDefaultName(ICProject project, long time) {
return project.getElementName() + "." + time + ".pdom"; //$NON-NLS-1$//$NON-NLS-2$
}
public String getDefaultIndexerId() {
@ -259,7 +270,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
Properties props= IndexerPreferences.getProperties(prj);
synchronized (fIndexerMutex) {
oldIndexer= getIndexer(cproject, false);
oldIndexer= getIndexer(cproject);
if (oldIndexer != null) {
if (oldIndexer.getID().equals(newid)) {
if (!oldIndexer.needsToRebuildForProperties(props)) {
@ -267,7 +278,9 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
return;
}
}
createIndexer(cproject, newid, props, true);
IPDOMIndexer indexer= createIndexer(cproject, newid, props);
registerIndexer(cproject, indexer);
enqueue(new PDOMRebuildTask(indexer));
}
}
@ -276,7 +289,14 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
}
private IPDOMIndexer getIndexer(ICProject project, boolean create) {
private void registerIndexer(ICProject project, IPDOMIndexer indexer) throws CoreException {
assert Thread.holdsLock(fIndexerMutex);
indexer.setProject(project);
registerPreferenceListener(project);
project.getProject().setSessionProperty(indexerProperty, indexer);
}
private IPDOMIndexer getIndexer(ICProject project) {
assert !Thread.holdsLock(fProjectToPDOM);
synchronized (fIndexerMutex) {
IProject prj = project.getProject();
@ -296,24 +316,66 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
return indexer;
}
if (create) {
try {
Properties props= IndexerPreferences.getProperties(prj);
return createIndexer(project, getIndexerId(project), props, false);
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
return null;
}
}
private IPDOMIndexer createIndexer(ICProject project, String indexerId, Properties props, boolean forceReindex) throws CoreException {
assert Thread.holdsLock(fIndexerMutex);
PDOM pdom= (PDOM) getPDOM(project);
boolean reindex= forceReindex || pdom.versionMismatch() || pdom.isEmpty();
private void createIndexer(ICProject project, IProgressMonitor pm) {
assert !Thread.holdsLock(fProjectToPDOM);
IProject prj= project.getProject();
try {
synchronized (fIndexerMutex) {
PDOM pdom= (PDOM) getPDOM(project);
Properties props= IndexerPreferences.getProperties(prj);
IPDOMIndexer indexer= createIndexer(project, getIndexerId(project), props);
boolean performImport= false;
boolean rebuild= false;
if (!IPDOMManager.ID_NO_INDEXER.equals(indexer.getID()) && pdom.isEmpty()) {
performImport= true;
}
else if (pdom.versionMismatch()) {
rebuild= true;
}
if (!performImport) {
registerIndexer(project, indexer);
if (rebuild) {
enqueue(new PDOMRebuildTask(indexer));
}
return;
}
}
// perform import
PDOMImporter importer= new PDOMImporter(project);
importer.performImport(pm);
synchronized (fIndexerMutex) {
Properties props= IndexerPreferences.getProperties(prj);
IPDOMIndexer indexer= createIndexer(project, getIndexerId(project), props);
registerIndexer(project, indexer);
IPDOMIndexerTask task= null;
if (!importer.wasSuccessful()) {
task= new PDOMRebuildTask(indexer);
}
else {
ITranslationUnit[] tus= importer.getTranslationUnitsToUpdate();
if (tus.length > 0) {
task= indexer.createTask(NO_TUS, tus, NO_TUS);
}
}
if (task != null) {
enqueue(task);
}
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
private IPDOMIndexer createIndexer(ICProject project, String indexerId, Properties props) throws CoreException {
IPDOMIndexer indexer = null;
// Look up in extension point
IExtension indexerExt = Platform.getExtensionRegistry().getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId);
@ -337,18 +399,6 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
if (indexer == null)
indexer = new PDOMNullIndexer();
indexer.setProject(project);
registerPreferenceListener(project);
project.getProject().setSessionProperty(indexerProperty, indexer);
if (reindex) {
if (forceReindex) {
enqueue(new PDOMRebuildTask(indexer));
}
else {
enqueue(new PDOMImportTask(indexer));
}
}
return indexer;
}
@ -410,8 +460,39 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
}
public void addProject(ICProject project, ICElementDelta delta) {
getIndexer(project, true); // if the indexer is new this triggers a rebuild
public void addProject(final IProject project) {
Job addProject= new Job(Messages.PDOMManager_StartJob_name) {
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("", 100); //$NON-NLS-1$
if (project.isOpen()) {
ICProject cproject= CoreModel.getDefault().create(project);
if (cproject != null) {
syncronizeProjectSettings(project, new SubProgressMonitor(monitor, 1));
if (getIndexer(cproject) == null) {
createIndexer(cproject, new SubProgressMonitor(monitor, 99));
}
}
}
return Status.OK_STATUS;
}
private void syncronizeProjectSettings(IProject project, IProgressMonitor monitor) {
try {
IFolder settings= project.getFolder(".settings"); //$NON-NLS-1$
settings.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} catch (CoreException e) {
CCorePlugin.log(e);
}
monitor.done();
}
public boolean belongsTo(Object family) {
return family == PDOMManager.this;
}
};
addProject.setRule(project);
addProject.setSystem(true);
addProject.schedule();
}
private void registerPreferenceListener(ICProject project) {
@ -433,7 +514,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
public void changeProject(ICProject project, ICElementDelta delta) throws CoreException {
IPDOMIndexer indexer = getIndexer(project, true);
IPDOMIndexer indexer = getIndexer(project);
if (indexer != null) {
PDOMResourceDeltaTask resourceDeltaTask = new PDOMResourceDeltaTask(indexer, delta);
if (!resourceDeltaTask.isEmpty()) {
@ -443,7 +524,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
public void removeProject(ICProject project) {
IPDOMIndexer indexer= getIndexer(project, false);
IPDOMIndexer indexer= getIndexer(project);
if (indexer != null) {
stopIndexer(indexer);
}
@ -452,7 +533,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
public void deleteProject(ICProject cproject, IResourceDelta delta) {
// Project is about to be deleted. Stop all indexing tasks for it
IPDOMIndexer indexer = getIndexer(cproject, false);
IPDOMIndexer indexer = getIndexer(cproject);
if (indexer != null) {
stopIndexer(indexer);
}
@ -505,7 +586,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
assert !Thread.holdsLock(fProjectToPDOM);
IPDOMIndexer indexer= null;
synchronized (fIndexerMutex) {
indexer= getIndexer(project, false);
indexer= getIndexer(project);
}
// don't attempt to hold lock on indexerMutex while cancelling
if (indexer != null) {
@ -513,8 +594,10 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
synchronized(fIndexerMutex) {
indexer= getIndexer(project, true);
enqueue(new PDOMRebuildTask(indexer));
indexer= getIndexer(project);
if (indexer != null) {
enqueue(new PDOMRebuildTask(indexer));
}
}
}
@ -607,7 +690,36 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
}
public boolean joinIndexer(int waitMaxMillis, IProgressMonitor monitor) {
public boolean joinIndexer(final int waitMaxMillis, final IProgressMonitor monitor) {
assert monitor != null;
Thread th= new Thread() {
public void run() {
try {
Thread.sleep(waitMaxMillis);
monitor.setCanceled(true);
}
catch (InterruptedException e) {
}
}
};
th.setDaemon(true);
th.start();
try {
try {
Job.getJobManager().join(this, monitor);
assert Job.getJobManager().find(this).length == 0;
return true;
} catch (OperationCanceledException e1) {
} catch (InterruptedException e1) {
}
return Job.getJobManager().find(this).length == 0;
}
finally {
th.interrupt();
}
}
public boolean joinIndexerOld(int waitMaxMillis, IProgressMonitor monitor) {
final int totalTicks = 1000;
monitor.beginTask(Messages.PDOMManager_JoinIndexerTask, totalTicks);
long limit= System.currentTimeMillis()+waitMaxMillis;
@ -669,7 +781,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
remainingSources+= info.getRemainingSources();
completedHeaders+= info.fCompletedHeaders;
completedSources+= info.fCompletedSources;
detail= info.fMonitorDetail;
detail= PDOMIndexerJob.sMonitorDetail;
totalEstimate+= info.getTimeEstimate();
}
}
@ -770,4 +882,41 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
throw new CoreException(CCorePlugin.createStatus(ie.getMessage()));
}
}
/**
* Resets the pdom for the project with the provided stream.
* @throws CoreException
* @throws OperationCanceledException in case the thread was interrupted
* @since 4.0
*/
public void importProjectPDOM(ICProject project, InputStream stream) throws CoreException, IOException {
// make a copy of the database
String newName= createNewDatabaseName(project);
File newFile= fileFromDatabaseName(newName);
OutputStream out= new FileOutputStream(newFile);
try {
byte[] buffer= new byte[2048];
int read;
while ((read= stream.read(buffer)) >= 0) {
out.write(buffer, 0, read);
}
}
finally {
out.close();
}
WritablePDOM pdom= (WritablePDOM) getPDOM(project);
try {
pdom.acquireWriteLock();
} catch (InterruptedException e) {
throw new OperationCanceledException();
}
try {
pdom.reloadFromFile(newFile);
storeDatabaseName(project.getProject(), newName);
}
finally {
pdom.releaseWriteLock();
}
}
}

View file

@ -9,7 +9,7 @@
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
package org.eclipse.cdt.internal.core.pdom;
import java.util.ArrayList;
import java.util.HashMap;
@ -17,7 +17,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
@ -29,20 +28,18 @@ import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerASTVisitor;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerStatistics;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
/**
* Abstract class to write information from AST
* @since 4.0
*/
abstract public class PDOMWriter {
private static final String TRUE = "true"; //$NON-NLS-1$
protected boolean fShowActivity;
protected boolean fShowProblems;
protected IndexerStatistics fStatistics;
@ -50,22 +47,17 @@ abstract public class PDOMWriter {
private IndexerProgress fInfo= new IndexerProgress();
public PDOMWriter() {
fShowActivity= checkDebugOption(IPDOMIndexerTask.TRACE_ACTIVITY, TRUE);
fShowProblems= checkDebugOption(IPDOMIndexerTask.TRACE_PROBLEMS, TRUE);
fStatistics= new IndexerStatistics();
}
/**
* Checks whether a given debug option is enabled. See {@link IPDOMIndexerTask}
* for valid values.
* @since 4.0
*/
protected boolean checkDebugOption(String option, String value) {
String trace= Platform.getDebugOption(option);
boolean internallyActivated= Boolean.getBoolean(option);
return internallyActivated || (trace != null && trace.equalsIgnoreCase(value));
public void setShowActivity(boolean val) {
fShowActivity= val;
}
public void setShowProblems(boolean val) {
fShowProblems= val;
}
/**
* Called to check whether a translation unit still needs to be updated.
* @see #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)
@ -301,14 +293,4 @@ abstract public class PDOMWriter {
fInfo.fTotalSourcesEstimate+= totalEstimate;
}
}
/**
* Updates the current monitor detail.
* @since 4.0
*/
protected void setMonitorDetail(String detail) {
synchronized(fInfo) {
fInfo.fMonitorDetail= detail;
}
}
}

View file

@ -36,12 +36,14 @@ import org.osgi.service.prefs.Preferences;
* @since 4.0
*/
public class IndexerPreferences {
private static final String DEFAULT_INDEX_IMPORT_LOCATION = ".settings/cdt-index.zip"; //$NON-NLS-1$
public static final String KEY_INDEXER_ID= "indexerId"; //$NON-NLS-1$
public static final String KEY_INDEX_ALL_FILES= "indexAllFiles"; //$NON-NLS-1$
private static final String QUALIFIER = CCorePlugin.PLUGIN_ID;
private static final String INDEXER_NODE = "indexer"; //$NON-NLS-1$
private static final String KEY_INDEXER_PREFS_SCOPE = "preferenceScope"; //$NON-NLS-1$
private static final String KEY_INDEX_IMPORT_LOCATION = "indexImportLocation"; //$NON-NLS-1$
public static final int SCOPE_INSTANCE = 0;
public static final int SCOPE_PROJECT_PRIVATE = 1;
@ -218,16 +220,24 @@ public class IndexerPreferences {
private static Preferences[] getInstancePreferencesArray() {
return new Preferences[] {
getInstancePreferences(),
new ConfigurationScope().getNode(QUALIFIER).node(INDEXER_NODE),
new DefaultScope().getNode(QUALIFIER).node(INDEXER_NODE)
getConfigurationPreferences(),
getDefaultPreferences()
};
}
private static Preferences getDefaultPreferences() {
return new DefaultScope().getNode(QUALIFIER).node(INDEXER_NODE);
}
private static Preferences getConfigurationPreferences() {
return new ConfigurationScope().getNode(QUALIFIER).node(INDEXER_NODE);
}
private static Preferences getInstancePreferences() {
return new InstanceScope().getNode(QUALIFIER).node(INDEXER_NODE);
}
private static Preferences getProjectPreferences(IProject project) {
public static Preferences getProjectPreferences(IProject project) {
return new ProjectScope(project).getNode(QUALIFIER).node(INDEXER_NODE);
}
@ -253,6 +263,7 @@ public class IndexerPreferences {
Preferences prefs= defaultPreferences.node(INDEXER_NODE);
prefs.put(KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER);
prefs.putBoolean(KEY_INDEX_ALL_FILES, false);
prefs.put(KEY_INDEX_IMPORT_LOCATION, DEFAULT_INDEX_IMPORT_LOCATION);
}
public static void addChangeListener(IProject prj, IPreferenceChangeListener pcl) {
@ -286,4 +297,22 @@ public class IndexerPreferences {
enode.removePreferenceChangeListener(pcl);
}
}
public static String getIndexImportLocation(IProject project) {
Preferences[] prefs= new Preferences[] {
getProjectPreferences(project),
getInstancePreferences(),
getConfigurationPreferences(),
getDefaultPreferences()
};
return Platform.getPreferencesService().get(KEY_INDEX_IMPORT_LOCATION, DEFAULT_INDEX_IMPORT_LOCATION, prefs);
}
public static void setIndexImportLocation(IProject project, String location) {
if (!location.equals(getIndexImportLocation(project))) {
getProjectPreferences(project).put(KEY_INDEX_IMPORT_LOCATION, location);
CCoreInternals.savePreferences(project);
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2007 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
@ -15,6 +15,8 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.pdom.indexer.messages"; //$NON-NLS-1$
public static String PDOMImportTask_errorInvalidArchive;
public static String PDOMImportTask_errorInvalidPDOMVersion;
public static String PDOMIndexerTask_collectingFilesTask;
public static String PDOMIndexerTask_errorWhileParsing;
public static String PDOMIndexerTask_parsingFileTask;

View file

@ -1,27 +0,0 @@
/*******************************************************************************
* Copyright (c) 2007 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 org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.core.runtime.IProgressMonitor;
public class PDOMImportTask extends PDOMRebuildTask {
public PDOMImportTask(IPDOMIndexer indexer) {
super(indexer);
}
public void run(IProgressMonitor monitor) {
// mstodo try to import pdom first.
super.run(monitor);
}
}

View file

@ -35,11 +35,13 @@ 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.pdom.IndexerProgress;
import org.eclipse.core.resources.IFile;
import org.eclipse.cdt.internal.core.pdom.PDOMWriter;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexerTask {
private static final Object NO_CONTEXT = new Object();
@ -48,9 +50,12 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
private IPDOMIndexer fIndexer;
protected Map/*<IIndexFileLocation, Object>*/ fContextMap = new HashMap/*<IIndexFileLocation, Object>*/();
private boolean fCheckTimestamps= false;
protected PDOMIndexerTask(IPDOMIndexer indexer) {
fIndexer= indexer;
setShowActivity(checkDebugOption(TRACE_ACTIVITY, TRUE));
setShowProblems(checkDebugOption(TRACE_PROBLEMS, TRUE));
}
final public IPDOMIndexer getIndexer() {
@ -65,6 +70,21 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
return super.getProgressInformation();
}
final public void setCheckTimestamps(boolean val) {
fCheckTimestamps= val;
}
/**
* Checks whether a given debug option is enabled. See {@link IPDOMIndexerTask}
* for valid values.
* @since 4.0
*/
public static boolean checkDebugOption(String option, String value) {
String trace= Platform.getDebugOption(option);
boolean internallyActivated= Boolean.getBoolean(option);
return internallyActivated || (trace != null && trace.equalsIgnoreCase(value));
}
/**
* Figurues out whether all files (sources without config, headers not included)
* should be parsed.
@ -97,7 +117,11 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
if (needToUpdate(getIndexFileLocation(tu))) {
final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu);
if (fCheckTimestamps && !isOutdated(tu, ifl, index)) {
updateInfo(0,0,-1);
}
else if (needToUpdate(ifl)) {
parseTU(tu, index, readlockCount, monitor);
}
}
@ -107,10 +131,15 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
IIndexFileLocation location = getIndexFileLocation(tu);
if (!needToUpdate(location)) {
IIndexFileLocation location = IndexLocationFactory.getIFL(tu);
if (fCheckTimestamps && !isOutdated(tu, location, index)) {
updateInfo(0,0,-1);
iter.remove();
} else {
}
else if (!needToUpdate(location)) {
iter.remove();
}
else {
ITranslationUnit context= findContext(index, location);
if (context != null) {
parseTU(context, index, readlockCount, monitor);
@ -124,7 +153,12 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
if (!needToUpdate(getIndexFileLocation(tu))) {
final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu);
if (fCheckTimestamps && !isOutdated(tu, ifl, index)) {
updateInfo(0,0,-1);
iter.remove();
}
else if (!needToUpdate(ifl)) {
iter.remove();
}
else {
@ -133,6 +167,21 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
}
}
}
private boolean isOutdated(ITranslationUnit tu, IIndexFileLocation ifl, IIndex index) throws CoreException {
boolean outofdate= true;
IResource res= tu.getResource();
if (res != null) {
IIndexFile indexFile= index.getFile(ifl);
if (indexFile != null) {
if (res.getLocalTimeStamp() == indexFile.getTimestamp()) {
outofdate= false;
}
}
}
return outofdate;
}
private void parseTU(ITranslationUnit tu, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws CoreException, InterruptedException {
IPath path= tu.getPath();
@ -140,7 +189,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
if (fShowActivity) {
System.out.println("Indexer: parsing " + path.toOSString()); //$NON-NLS-1$
}
setMonitorDetail(MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask,
pm.subTask(MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask,
new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()}));
long start= System.currentTimeMillis();
IASTTranslationUnit ast= createAST(tu, pm);
@ -218,7 +267,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
protected void removeTU(IWritableIndex index, ITranslationUnit tu, int readlocks) throws CoreException, InterruptedException {
index.acquireWriteLock(readlocks);
try {
IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(getIndexFileLocation(tu));
IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(IndexLocationFactory.getIFL(tu));
if (file != null)
index.clearFile(file);
} finally {
@ -226,13 +275,6 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
}
}
protected IIndexFileLocation getIndexFileLocation(ITranslationUnit tu) {
if(tu.getResource()!=null)
return IndexLocationFactory.getWorkspaceIFL((IFile)tu.getResource());
else
return IndexLocationFactory.getExternalIFL(tu.getLocation());
}
protected void traceEnd(long start) {
if (checkDebugOption(IPDOMIndexerTask.TRACE_STATISTICS, TRUE)) {
IndexerProgress info= getProgressInformation();

View file

@ -28,8 +28,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.osgi.util.NLS;
public class PDOMRebuildTask implements IPDOMIndexerTask {
private static final String TRUE= String.valueOf(true);
private static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0];
protected static final String TRUE= String.valueOf(true);
protected static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0];
private final IPDOMIndexer fIndexer;
private final IndexerProgress fProgress;
@ -37,13 +37,12 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
public PDOMRebuildTask(IPDOMIndexer indexer) {
fIndexer= indexer;
fProgress= createProgress(indexer.getProject().getElementName());
fProgress= createProgress();
}
private IndexerProgress createProgress(String prjName) {
private IndexerProgress createProgress() {
IndexerProgress progress= new IndexerProgress();
progress.fTimeEstimate= 1000;
progress.fMonitorDetail= NLS.bind(Messages.PDOMIndexerTask_collectingFilesTask, prjName);
return progress;
}
@ -52,6 +51,9 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
}
public void run(IProgressMonitor monitor) {
monitor.subTask(NLS.bind(Messages.PDOMIndexerTask_collectingFilesTask,
fIndexer.getProject().getElementName()));
ICProject project= fIndexer.getProject();
if (project.getProject().isOpen()) {
try {

View file

@ -15,9 +15,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
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.model.CoreModel;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
@ -36,6 +38,8 @@ public class PDOMResourceDeltaTask implements IPDOMIndexerTask {
final private IPDOMIndexerTask fDelegate;
final private IndexerProgress fProgress;
private IIndex fIndex;
public PDOMResourceDeltaTask(IPDOMIndexer indexer, ICElementDelta delta) throws CoreException {
fIndexer= indexer;
fProgress= new IndexerProgress();
@ -44,16 +48,31 @@ public class PDOMResourceDeltaTask implements IPDOMIndexerTask {
List a= new ArrayList();
List c= new ArrayList();
List r= new ArrayList();
processDelta(delta, a, c, r, new NullProgressMonitor());
if (!a.isEmpty() || !c.isEmpty() || !r.isEmpty()) {
ITranslationUnit[] aa= (ITranslationUnit[]) a.toArray(new ITranslationUnit[a.size()]);
ITranslationUnit[] ca= (ITranslationUnit[]) c.toArray(new ITranslationUnit[c.size()]);
ITranslationUnit[] ra= (ITranslationUnit[]) r.toArray(new ITranslationUnit[r.size()]);
fDelegate= indexer.createTask(aa, ca, ra);
}
else {
fIndex= CCorePlugin.getIndexManager().getIndex(indexer.getProject());
try {
fIndex.acquireReadLock();
} catch (InterruptedException e) {
fDelegate= null;
return;
}
try {
processDelta(delta, a, c, r, new NullProgressMonitor());
if (!a.isEmpty() || !c.isEmpty() || !r.isEmpty()) {
ITranslationUnit[] aa= (ITranslationUnit[]) a.toArray(new ITranslationUnit[a.size()]);
ITranslationUnit[] ca= (ITranslationUnit[]) c.toArray(new ITranslationUnit[c.size()]);
ITranslationUnit[] ra= (ITranslationUnit[]) r.toArray(new ITranslationUnit[r.size()]);
fDelegate= indexer.createTask(aa, ca, ra);
if (fDelegate instanceof PDOMIndexerTask) {
((PDOMIndexerTask) fDelegate).setCheckTimestamps(true);
}
}
else {
fDelegate= null;
}
}
finally {
fIndex.releaseReadLock();
}
}
else {

View file

@ -112,7 +112,7 @@ class PDOMFastIndexerTask extends PDOMIndexerTask {
private void registerTUsInReaderFactory(Collection files) throws CoreException {
for (Iterator iter = files.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
IIndexFileLocation location = getIndexFileLocation(tu);
IIndexFileLocation location = IndexLocationFactory.getIFL(tu);
FileInfo info= fCodeReaderFactory.createFileInfo(location);
info.setRequested(true);
}

View file

@ -113,7 +113,7 @@ class PDOMFullIndexerTask extends PDOMIndexerTask {
filePathsToParse= new HashMap/*<IIndexFileLocation, Object>*/();
for (Iterator iter = sources.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
filePathsToParse.put(getIndexFileLocation(tu), REQUIRED);
filePathsToParse.put(IndexLocationFactory.getIFL(tu), REQUIRED);
}
}

View file

@ -10,5 +10,7 @@
###############################################################################
PDOMIndexerTask_collectingFilesTask=Collecting files (project ''{0}'')
PDOMIndexerTask_tooManyIndexProblems=Too many problems while indexing project ''{0}'', stopping indexer.
PDOMImportTask_errorInvalidPDOMVersion=The version of the cdt-index to import for project {0} does not match
PDOMIndexerTask_parsingFileTask=parsing {0} ({1})
PDOMIndexerTask_errorWhileParsing=Error while parsing {0}.
PDOMImportTask_errorInvalidArchive=Invalid Archive: {0}

View file

@ -15,3 +15,4 @@ PDOMManager_StartJob_name=Initialize Indexing
PDOMManager_notifyTask_message=Notify Listeners
PDOMManager_indexMonitorDetail={0}/{1} sources, {2} headers
PDOMManager_ExistingFileCollides=A pdom already exists at location {0}
Checksums_taskComputeChecksums=Computing checksums

View file

@ -19,6 +19,7 @@ import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
@ -41,6 +42,7 @@ public class THInformationControl extends AbstractInformationControl implements
private THHierarchyModel fModel;
private THLabelProvider fHierarchyLabelProvider;
private TreeViewer fHierarchyTreeViewer;
private boolean fDisposed= false;
public THInformationControl(Shell parent, int shellStyle, int treeStyle) {
super(parent, shellStyle, treeStyle, ICEditorActionDefinitionIds.OPEN_QUICK_TYPE_HIERARCHY, true);
@ -127,20 +129,27 @@ public class THInformationControl extends AbstractInformationControl implements
return null;
}
public void widgetDisposed(DisposeEvent event) {
fDisposed= true;
super.widgetDisposed(event);
}
public void onEvent(int event) {
switch (event) {
case THHierarchyModel.END_OF_COMPUTATION:
if (fModel.hasTrivialHierarchy()) {
fHierarchyLabelProvider.setHideNonImplementers(false);
}
fHierarchyTreeViewer.refresh();
THNode selection= fModel.getSelectionInHierarchy();
if (selection != null) {
fHierarchyTreeViewer.setSelection(new StructuredSelection(selection));
fHierarchyTreeViewer.expandToLevel(selection, 1);
}
break;
}
if (!fDisposed) {
switch (event) {
case THHierarchyModel.END_OF_COMPUTATION:
if (fModel.hasTrivialHierarchy()) {
fHierarchyLabelProvider.setHideNonImplementers(false);
}
fHierarchyTreeViewer.refresh();
THNode selection= fModel.getSelectionInHierarchy();
if (selection != null) {
fHierarchyTreeViewer.setSelection(new StructuredSelection(selection));
fHierarchyTreeViewer.expandToLevel(selection, 1);
}
break;
}
}
}
public void setMessage(String msg) {