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

Moved an improved cache for include paths into the ASTFilePathResolver, where it can be reused with EFS, bug 225302.

This commit is contained in:
Markus Schorn 2008-04-07 13:36:24 +00:00
parent 3d6501658c
commit ac29604de3
8 changed files with 167 additions and 202 deletions

View file

@ -35,19 +35,17 @@ import org.eclipse.cdt.core.parser.ICodeReaderCache;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.internal.core.parser.scanner.IIndexBasedCodeReaderFactory; import org.eclipse.cdt.internal.core.parser.scanner.IIndexBasedCodeReaderFactory;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent; import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileResolutionCache;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind; import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind;
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver; import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask; import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.FileContent; import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.FileContent;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
/** /**
* Code reader factory, that fakes code readers for header files already stored in the * Code reader factory, that fakes code readers for header files already stored in the
* index. * index.
*/ */
public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory, IAdaptable { public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory {
private static final class NeedToParseException extends Exception {} private static final class NeedToParseException extends Exception {}
private final IIndex fIndex; private final IIndex fIndex;
@ -57,7 +55,6 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
private final ICodeReaderFactory fFallBackFactory; private final ICodeReaderFactory fFallBackFactory;
private final ASTFilePathResolver fPathResolver; private final ASTFilePathResolver fPathResolver;
private final AbstractIndexerTask fRelatedIndexerTask; private final AbstractIndexerTask fRelatedIndexerTask;
private final IncludeFileResolutionCache fIncludeFileResolutionCache;
public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage, public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage,
ICodeReaderFactory fallbackFactory) { ICodeReaderFactory fallbackFactory) {
@ -71,13 +68,12 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
fPathResolver= pathResolver; fPathResolver= pathResolver;
fRelatedIndexerTask= relatedIndexerTask; fRelatedIndexerTask= relatedIndexerTask;
fLinkage= linkage; fLinkage= linkage;
fIncludeFileResolutionCache= new IncludeFileResolutionCache(1024);
} }
public int getUniqueIdentifier() { public int getUniqueIdentifier() {
return 0; return 0;
} }
public CodeReader createCodeReaderForTranslationUnit(String path) { public CodeReader createCodeReaderForTranslationUnit(String path) {
if (fFallBackFactory != null) { if (fFallBackFactory != null) {
return fFallBackFactory.createCodeReaderForTranslationUnit(path); return fFallBackFactory.createCodeReaderForTranslationUnit(path);
@ -92,6 +88,10 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
return ParserUtil.createReader(path, null); return ParserUtil.createReader(path, null);
} }
public boolean getInclusionExists(String path) {
return fPathResolver.doesIncludeFileExist(path);
}
public IncludeFileContent getContentForInclusion(String path) { public IncludeFileContent getContentForInclusion(String path) {
IIndexFileLocation ifl= fPathResolver.resolveIncludeFile(path); IIndexFileLocation ifl= fPathResolver.resolveIncludeFile(path);
if (ifl == null) { if (ifl == null) {
@ -183,12 +183,4 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
public void setLinkage(int linkageID) { public void setLinkage(int linkageID) {
fLinkage= linkageID; fLinkage= linkageID;
} }
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
if (adapter.isInstance(fIncludeFileResolutionCache)) {
return fIncludeFileResolutionCache;
}
return null;
}
} }

View file

@ -30,7 +30,7 @@ import org.eclipse.core.runtime.Path;
* @since 5.0 * @since 5.0
*/ */
public class StandaloneIndexerInputAdapter extends IndexerInputAdapter { public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
private HashMap fIflCache= new HashMap(); private HashMap<String, IIndexFileLocation> fIflCache= new HashMap<String, IIndexFileLocation>();
private final StandaloneIndexer fIndexer; private final StandaloneIndexer fIndexer;
@ -38,28 +38,34 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
fIndexer= indexer; fIndexer= indexer;
} }
@Override
public IScannerInfo getBuildConfiguration(int linkageID, Object tu) { public IScannerInfo getBuildConfiguration(int linkageID, Object tu) {
return fIndexer.getScannerInfo(); return fIndexer.getScannerInfo();
} }
@Override
public long getLastModified(IIndexFileLocation location) { public long getLastModified(IIndexFileLocation location) {
return new File(location.getFullPath()).lastModified(); return new File(location.getFullPath()).lastModified();
} }
@Override
public boolean isSourceUnit(Object tu) { public boolean isSourceUnit(Object tu) {
return isValidSourceUnitName((String) tu); return isValidSourceUnitName((String) tu);
} }
@Override
public IIndexFileLocation resolveFile(Object tu) { public IIndexFileLocation resolveFile(Object tu) {
return resolveASTPath((String) tu); return resolveASTPath((String) tu);
} }
@Override
public String getASTPath(IIndexFileLocation ifl) { public String getASTPath(IIndexFileLocation ifl) {
return ifl.getFullPath(); return ifl.getFullPath();
} }
@Override
public IIndexFileLocation resolveASTPath(String astPath) { public IIndexFileLocation resolveASTPath(String astPath) {
IIndexFileLocation result= (IIndexFileLocation) fIflCache.get(astPath); IIndexFileLocation result= fIflCache.get(astPath);
if (result == null) { if (result == null) {
try { try {
astPath = new File(astPath).getCanonicalPath(); astPath = new File(astPath).getCanonicalPath();
@ -73,13 +79,17 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
return result; return result;
} }
@Override
public boolean doesIncludeFileExist(String includePath) {
return new File(includePath).exists();
}
@Override
public IIndexFileLocation resolveIncludeFile(String includePath) { public IIndexFileLocation resolveIncludeFile(String includePath) {
IIndexFileLocation result= (IIndexFileLocation) fIflCache.get(includePath); IIndexFileLocation result= fIflCache.get(includePath);
if (result == null) { if (result == null) {
File file= new File(includePath); File file= new File(includePath);
if (!file.exists()) {
return null;
}
try { try {
includePath = file.getCanonicalPath(); includePath = file.getCanonicalPath();
} catch (IOException e) { } catch (IOException e) {
@ -92,14 +102,17 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
return result; return result;
} }
@Override
public boolean isFileBuildConfigured(Object tu) { public boolean isFileBuildConfigured(Object tu) {
return isValidSourceUnitName((String) tu); return isValidSourceUnitName((String) tu);
} }
@Override
public boolean canBePartOfSDK(IIndexFileLocation ifl) { public boolean canBePartOfSDK(IIndexFileLocation ifl) {
return false; return false;
} }
@Override
public CodeReader getCodeReader(Object tu) { public CodeReader getCodeReader(Object tu) {
try { try {
return new CodeReader((String) tu); return new CodeReader((String) tu);
@ -108,10 +121,12 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
return null; return null;
} }
@Override
public Object getInputFile(IIndexFileLocation location) { public Object getInputFile(IIndexFileLocation location) {
return location.getFullPath(); return location.getFullPath();
} }
@Override
public AbstractLanguage[] getLanguages(Object tu) { public AbstractLanguage[] getLanguages(Object tu) {
ILanguage language = fIndexer.getLanguageMapper().getLanguage((String) tu); ILanguage language = fIndexer.getLanguageMapper().getLanguage((String) tu);
if (language instanceof AbstractLanguage) { if (language instanceof AbstractLanguage) {

View file

@ -45,8 +45,6 @@ import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
import org.eclipse.cdt.core.parser.util.CharArrayMap; import org.eclipse.cdt.core.parser.util.CharArrayMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileResolutionCache.ISPKey;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileResolutionCache.LookupKey;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions; import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
import org.eclipse.cdt.internal.core.parser.scanner.MacroDefinitionParser.InvalidMacroDefinitionException; import org.eclipse.cdt.internal.core.parser.scanner.MacroDefinitionParser.InvalidMacroDefinitionException;
import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IAdaptable;
@ -93,15 +91,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() { final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() {
public IncludeFileContent checkFile(String path, String fileName) { public IncludeFileContent checkFile(String path, String fileName) {
return createReader(path, fileName); String finalPath = ScannerUtility.createReconciledPath(path, fileName);
return fCodeReaderFactory.getContentForInclusion(finalPath);
} }
}; };
final private IIncludeFileTester<String> createPathTester= new IIncludeFileTester<String>() { final private IIncludeFileTester<String> createPathTester= new IIncludeFileTester<String>() {
public String checkFile(String path, String fileName) { public String checkFile(String path, String fileName) {
path= ScannerUtility.createReconciledPath(path, fileName); String finalPath= ScannerUtility.createReconciledPath(path, fileName);
if (new File(path).exists()) { if (fCodeReaderFactory.getInclusionExists(finalPath)) {
return path; return finalPath;
} }
return null; return null;
} }
@ -121,9 +120,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final private String[] fIncludePaths; final private String[] fIncludePaths;
final private String[] fQuoteIncludePaths; final private String[] fQuoteIncludePaths;
private String[][] fPreIncludedFiles= null; private String[][] fPreIncludedFiles= null;
private final IncludeFileResolutionCache fIncludeResolutionCache;
private final ISPKey fIncludePathKey;
private final ISPKey fQuoteIncludePathKey;
private int fContentAssistLimit= -1; private int fContentAssistLimit= -1;
private boolean fHandledCompletion= false; private boolean fHandledCompletion= false;
@ -162,10 +158,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fMacroExpander= new MacroExpander(this, fMacroDictionary, fLocationMap, fLexOptions); fMacroExpander= new MacroExpander(this, fMacroDictionary, fLocationMap, fLexOptions);
fCodeReaderFactory= wrapReaderFactory(readerFactory); fCodeReaderFactory= wrapReaderFactory(readerFactory);
fIncludeResolutionCache= getIncludeResolutionCache(readerFactory);
fIncludePathKey= fIncludeResolutionCache.getKey(fIncludePaths);
fQuoteIncludePathKey= fIncludeResolutionCache.getKey(fQuoteIncludePaths);
setupMacroDictionary(configuration, info, language); setupMacroDictionary(configuration, info, language);
final String filePath= new String(reader.filename); final String filePath= new String(reader.filename);
@ -179,16 +171,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} }
} }
private IncludeFileResolutionCache getIncludeResolutionCache(ICodeReaderFactory readerFactory) {
if (readerFactory instanceof IAdaptable) {
IncludeFileResolutionCache cache= (IncludeFileResolutionCache) ((IAdaptable) readerFactory).getAdapter(IncludeFileResolutionCache.class);
if (cache != null) {
return cache;
}
}
return new IncludeFileResolutionCache(1024);
}
private IIndexBasedCodeReaderFactory wrapReaderFactory(final ICodeReaderFactory readerFactory) { private IIndexBasedCodeReaderFactory wrapReaderFactory(final ICodeReaderFactory readerFactory) {
if (readerFactory instanceof IIndexBasedCodeReaderFactory) { if (readerFactory instanceof IIndexBasedCodeReaderFactory) {
return (IIndexBasedCodeReaderFactory) readerFactory; return (IIndexBasedCodeReaderFactory) readerFactory;
@ -216,6 +198,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
public int getUniqueIdentifier() { public int getUniqueIdentifier() {
return readerFactory.getUniqueIdentifier(); return readerFactory.getUniqueIdentifier();
} }
public boolean getInclusionExists(String path) {
return readerFactory.createCodeReaderForInclusion(path) != null;
}
}; };
} }
@ -759,46 +744,18 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
// if we're not include_next, then we are looking for the first occurrence of // if we're not include_next, then we are looking for the first occurrence of
// the file, otherwise, we ignore all the paths before the current directory // the file, otherwise, we ignore all the paths before the current directory
String[] isp; final String[] isp= quoteInclude ? fQuoteIncludePaths : fIncludePaths;
ISPKey ispKey;
if (quoteInclude) {
isp= fQuoteIncludePaths;
ispKey= fQuoteIncludePathKey;
}
else {
isp= fIncludePaths;
ispKey= fIncludePathKey;
}
if (isp != null ) { if (isp != null ) {
if (includeNext && currentDirectory != null) { int i=0;
final int startpos = findIncludePos(isp, currentDirectory) + 1; if (includeNext && currentDirectory != null) {
for (int i= startpos; i < isp.length; ++i) { i= findIncludePos(isp, currentDirectory) + 1;
reader= tester.checkFile(isp[i], filename); }
if (reader != null) { for (; i < isp.length; ++i) {
return reader; reader= tester.checkFile(isp[i], filename);
} if (reader != null) {
} return reader;
return null; }
}
final LookupKey lookupKey= fIncludeResolutionCache.getKey(ispKey, filename.toCharArray());
Integer offset= fIncludeResolutionCache.getCachedPathOffset(lookupKey);
if (offset != null) {
if (offset < 0) {
return null;
}
return tester.checkFile(isp[offset], filename);
} }
for (int i= 0; i < isp.length; ++i) {
reader = tester.checkFile(isp[i], filename);
if (reader != null) {
fIncludeResolutionCache.putCachedPathOffset(lookupKey, i);
return reader;
}
}
fIncludeResolutionCache.putCachedPathOffset(lookupKey, -1);
} }
return null; return null;
} }
@ -848,13 +805,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
public void handleProblem(int id, char[] arg, int offset, int endOffset) { public void handleProblem(int id, char[] arg, int offset, int endOffset) {
fLocationMap.encounterProblem(id, arg, offset, endOffset); fLocationMap.encounterProblem(id, arg, offset, endOffset);
} }
private IncludeFileContent createReader(String path, String fileName){
String finalPath = ScannerUtility.createReconciledPath(path, fileName);
return fCodeReaderFactory.getContentForInclusion(finalPath);
}
/** /**
* Assumes that the pound token has not yet been consumed * Assumes that the pound token has not yet been consumed
* @param ppdCtx * @param ppdCtx

View file

@ -30,4 +30,10 @@ public interface IIndexBasedCodeReaderFactory extends ICodeReaderFactory {
* @see IncludeFileContent * @see IncludeFileContent
*/ */
public IncludeFileContent getContentForInclusion(String fileLocation); public IncludeFileContent getContentForInclusion(String fileLocation);
/**
* Check whether the specified inclusion exists.
* @since 5.0
*/
boolean getInclusionExists(String finalPath);
} }

View file

@ -1,107 +0,0 @@
/*******************************************************************************
* Copyright (c) 2008 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.parser.scanner;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.cdt.internal.core.parser.util.WeakHashSet;
/**
* A limited LRU cache for looking up files in an include search path.
* @since 5.0
*/
public final class IncludeFileResolutionCache {
public static class ISPKey {
private String[] fISP;
private int fHashCode;
private ISPKey(String[] isp) {
fISP= isp;
fHashCode= Arrays.hashCode(isp);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
return obj != null && Arrays.equals(fISP, ((ISPKey) obj).fISP);
}
@Override
public int hashCode() {
return fHashCode;
}
}
public static class LookupKey {
private ISPKey fCanonicISP;
private char[] fName;
private int fHashCode;
private LookupKey(ISPKey ispKey, char[] include) {
fCanonicISP= ispKey;
fName= include;
fHashCode= Arrays.hashCode(include) * 31 + ispKey.hashCode();
}
@Override
public int hashCode() {
return fHashCode;
}
@Override
public boolean equals(Object obj) {
LookupKey other= (LookupKey) obj;
if (fCanonicISP != other.fCanonicISP)
return false;
if (!Arrays.equals(fName, other.fName))
return false;
return true;
}
}
private WeakHashSet<ISPKey> fCanonicISPs;
private LinkedHashMap<LookupKey, Integer> fCache;
/**
* Creates a cache for include file resolution using up to the given amount of memory
* @param maxSizeKBytes the maximum size of the cache in kilobytes
*/
public IncludeFileResolutionCache(final int maxSizeKBytes) {
final int size= maxSizeKBytes*1024/72; // HashEntry 32 bytes, Key 16 bytes, Name 16 bytes, Integer 8 bytes
fCache= new LinkedHashMap<LookupKey, Integer>(size, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<LookupKey, Integer> eldest) {
return size() > size;
}
};
fCanonicISPs= new WeakHashSet<ISPKey>();
}
public ISPKey getKey(String[] isp) {
return fCanonicISPs.add(new ISPKey(isp));
}
public LookupKey getKey(ISPKey ispKey, char[] filename) {
return new LookupKey(ispKey, filename);
}
public Integer getCachedPathOffset(LookupKey key) {
return fCache.get(key);
}
public void putCachedPathOffset(LookupKey key, int offset) {
fCache.put(key, offset);
}
}

View file

@ -25,12 +25,17 @@ public abstract class ASTFilePathResolver {
public abstract IIndexFileLocation resolveASTPath(String astFilePath); public abstract IIndexFileLocation resolveASTPath(String astFilePath);
/** /**
* Resolve a path for an inclusion as computed by the preprocessor. Check for existance * Resolve a path for an inclusion as computed by the preprocessor. Check for existence
* and return <code>null</code> if the file does not exist. * and return <code>null</code> if the file does not exist.
* @return an index file location or <code>null</code> if the file does not exist. * @return an index file location or <code>null</code> if the file does not exist.
*/ */
public abstract IIndexFileLocation resolveIncludeFile(String includePath); public abstract IIndexFileLocation resolveIncludeFile(String includePath);
/**
* Check for existence of an inclusion as computed by the preprocessor.
*/
public abstract boolean doesIncludeFileExist(String includePath);
/** /**
* Convert an index file location to the path as it will be stored in the AST. * Convert an index file location to the path as it will be stored in the AST.
*/ */

View file

@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2008 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.io.File;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* A cache for checking whether a file exists. The cache shall be used for a limited amount of time, only (e.g. one
* indexer task). It uses as much memory as it needs. To protect against OutOfMemory situations, a soft reference is
* used.
* @since 5.0
*/
public final class FileExistsCache {
private static final String[] EMPTY_STRING_ARRAY= {};
private static final boolean CASE_INSENSITIVE = new File("a").equals(new File("A")); //$NON-NLS-1$ //$NON-NLS-2$
private static boolean BYPASS_CACHE= Boolean.getBoolean("CDT_INDEXER_BYPASS_FILE_EXISTS_CACHE"); //$NON-NLS-1$
private Reference<Map<String,String[]>> fCache= null;
public FileExistsCache() {
fCache= new SoftReference<Map<String,String[]>>(new HashMap<String, String[]>()); // before running out of memory the entire map will be thrown away.
}
public boolean exists(String path) {
File file= new File(path);
if (BYPASS_CACHE) {
return file.exists();
}
String parent= file.getParent();
String name= file.getName();
if (CASE_INSENSITIVE)
name= name.toUpperCase();
String[] avail= getExistsCache().get(parent);
if (avail == null) {
avail= new File(parent).list();
if (avail == null || avail.length == 0) {
avail= EMPTY_STRING_ARRAY;
}
else {
if (CASE_INSENSITIVE) {
for (int i = 0; i < avail.length; i++) {
avail[i]= avail[i].toUpperCase();
}
}
Arrays.sort(avail);
}
getExistsCache().put(parent, avail);
}
return Arrays.binarySearch(avail, name) >= 0;
}
private Map<String, String[]> getExistsCache() {
Map<String, String[]> cache= fCache.get();
if (cache == null) {
cache= new HashMap<String, String[]>();
fCache= new SoftReference<Map<String, String[]>>(cache); // before running out of memory the entire map will be thrown away.
}
return cache;
}
}

View file

@ -42,7 +42,8 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
private final static boolean CASE_SENSITIVE_FILES= !new File("a").equals(new File("A")); //$NON-NLS-1$//$NON-NLS-2$ private final static boolean CASE_SENSITIVE_FILES= !new File("a").equals(new File("A")); //$NON-NLS-1$//$NON-NLS-2$
private final ICProject fCProject; private final ICProject fCProject;
private HashMap<String, IIndexFileLocation> fIflCache; private final HashMap<String, IIndexFileLocation> fIflCache;
private final FileExistsCache fExistsCache;
public ProjectIndexerInputAdapter(ICProject cproject) { public ProjectIndexerInputAdapter(ICProject cproject) {
this(cproject, true); this(cproject, true);
@ -50,9 +51,17 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
public ProjectIndexerInputAdapter(ICProject cproject, boolean useCache) { public ProjectIndexerInputAdapter(ICProject cproject, boolean useCache) {
fCProject= cproject; fCProject= cproject;
fIflCache= useCache ? new HashMap<String, IIndexFileLocation>() : null; if (useCache) {
fIflCache= new HashMap<String, IIndexFileLocation>();
fExistsCache= new FileExistsCache();
}
else {
fIflCache= null;
fExistsCache= null;
}
} }
@Override
public IIndexFileLocation resolveASTPath(String astPath) { public IIndexFileLocation resolveASTPath(String astPath) {
if (fIflCache == null) { if (fIflCache == null) {
return doResolveASTPath(astPath); return doResolveASTPath(astPath);
@ -69,19 +78,20 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
return IndexLocationFactory.getIFLExpensive(fCProject, astPath); return IndexLocationFactory.getIFLExpensive(fCProject, astPath);
} }
@Override
public IIndexFileLocation resolveIncludeFile(String includePath) { public IIndexFileLocation resolveIncludeFile(String includePath) {
if (fIflCache == null) { if (fIflCache == null) {
return doResolveASTPath(includePath); return doResolveASTPath(includePath);
} }
if (!fExistsCache.exists(includePath)) {
return null;
}
IIndexFileLocation result= fIflCache.get(includePath); IIndexFileLocation result= fIflCache.get(includePath);
if (result == null) { if (result == null) {
File location= new File(includePath);
if (!location.exists()) {
return null;
}
result = doResolveASTPath(includePath); result = doResolveASTPath(includePath);
if (result.getFullPath() == null && !CASE_SENSITIVE_FILES) { if (result.getFullPath() == null && !CASE_SENSITIVE_FILES) {
try { try {
File location= new File(includePath);
String canonicalPath= location.getCanonicalPath(); String canonicalPath= location.getCanonicalPath();
if (!includePath.equals(canonicalPath)) { if (!includePath.equals(canonicalPath)) {
result= IndexLocationFactory.getExternalIFL(canonicalPath); result= IndexLocationFactory.getExternalIFL(canonicalPath);
@ -96,7 +106,16 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
} }
return result; return result;
} }
@Override
public boolean doesIncludeFileExist(String includePath) {
if (fExistsCache != null) {
return fExistsCache.exists(includePath);
}
return new File(includePath).exists();
}
@Override
public String getASTPath(IIndexFileLocation ifl) { public String getASTPath(IIndexFileLocation ifl) {
IPath path= IndexLocationFactory.getAbsolutePath(ifl); IPath path= IndexLocationFactory.getAbsolutePath(ifl);
if (path != null) { if (path != null) {
@ -105,6 +124,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
return ifl.getURI().getPath(); return ifl.getURI().getPath();
} }
@Override
public IScannerInfo getBuildConfiguration(int linkageID, Object tu) { public IScannerInfo getBuildConfiguration(int linkageID, Object tu) {
IScannerInfo info= ((ITranslationUnit) tu).getScannerInfo(true); IScannerInfo info= ((ITranslationUnit) tu).getScannerInfo(true);
if (info == null) { if (info == null) {
@ -113,6 +133,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
return info; return info;
} }
@Override
public long getLastModified(IIndexFileLocation ifl) { public long getLastModified(IIndexFileLocation ifl) {
String fullPath= ifl.getFullPath(); String fullPath= ifl.getFullPath();
if (fullPath != null) { if (fullPath != null) {
@ -130,6 +151,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
} }
@Override
public AbstractLanguage[] getLanguages(Object tuo) { public AbstractLanguage[] getLanguages(Object tuo) {
ITranslationUnit tu= (ITranslationUnit) tuo; ITranslationUnit tu= (ITranslationUnit) tuo;
try { try {
@ -144,25 +166,30 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
return new AbstractLanguage[0]; return new AbstractLanguage[0];
} }
@Override
public boolean isFileBuildConfigured(Object tuo) { public boolean isFileBuildConfigured(Object tuo) {
ITranslationUnit tu= (ITranslationUnit) tuo; ITranslationUnit tu= (ITranslationUnit) tuo;
return !CoreModel.isScannerInformationEmpty(tu.getResource()); return !CoreModel.isScannerInformationEmpty(tu.getResource());
} }
@Override
public boolean isSourceUnit(Object tuo) { public boolean isSourceUnit(Object tuo) {
ITranslationUnit tu= (ITranslationUnit) tuo; ITranslationUnit tu= (ITranslationUnit) tuo;
return tu.isSourceUnit(); return tu.isSourceUnit();
} }
@Override
public IIndexFileLocation resolveFile(Object tuo) { public IIndexFileLocation resolveFile(Object tuo) {
ITranslationUnit tu= (ITranslationUnit) tuo; ITranslationUnit tu= (ITranslationUnit) tuo;
return IndexLocationFactory.getIFL(tu); return IndexLocationFactory.getIFL(tu);
} }
@Override
public boolean canBePartOfSDK(IIndexFileLocation ifl) { public boolean canBePartOfSDK(IIndexFileLocation ifl) {
return ifl.getFullPath() == null; return ifl.getFullPath() == null;
} }
@Override
public Object getInputFile(IIndexFileLocation location) { public Object getInputFile(IIndexFileLocation location) {
try { try {
return CoreModelUtil.findTranslationUnitForLocation(location, fCProject); return CoreModelUtil.findTranslationUnitForLocation(location, fCProject);
@ -172,6 +199,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
return null; return null;
} }
@Override
public CodeReader getCodeReader(Object tuo) { public CodeReader getCodeReader(Object tuo) {
ITranslationUnit tu= (ITranslationUnit) tuo; ITranslationUnit tu= (ITranslationUnit) tuo;
return tu.getCodeReader(); return tu.getCodeReader();