From ee628f9a749c8a4684cb80e610cb6b61eca51b36 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 13 May 2009 16:05:51 +0000 Subject: [PATCH] Index based code reader factory needs to respect the fallback factory, bug 275600. --- .../internal/core/model/TranslationUnit.java | 14 +- .../cdt/core/parser/ICodeReaderCache.java | 19 +++ .../core/dom/parser/EmptyCodeReaderCache.java | 14 +- .../index/IndexBasedCodeReaderFactory.java | 18 ++- .../indexer/StandaloneFastIndexerTask.java | 4 +- .../core/indexer/StandaloneFullIndexer.java | 10 +- .../indexer/StandaloneFullIndexerTask.java | 4 +- ...tandaloneIndexerFallbackReaderFactory.java | 15 +- .../core/parser/CodeReaderCacheEntry.java | 42 +++++ .../core/parser/CodeReaderLRUCache.java | 90 +++++++++++ .../core/parser/InternalParserUtil.java | 27 +++- .../core/pdom/AbstractIndexerTask.java | 6 +- .../pdom/indexer/PDOMFastIndexerTask.java | 4 +- .../pdom/indexer/PDOMFullIndexerTask.java | 4 +- .../cdt/core/parser/CodeReaderCache.java | 145 +++--------------- .../eclipse/cdt/core/parser/ParserUtil.java | 4 +- .../core/dom/AbstractCodeReaderFactory.java | 9 +- .../core/dom/NullCodeReaderFactory.java | 14 +- .../PartialWorkingCopyCodeReaderFactory.java | 12 +- .../core/dom/SavedCodeReaderFactory.java | 12 +- 20 files changed, 295 insertions(+), 172 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderCacheEntry.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderLRUCache.java diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index 92d0fefe7e9..4cc093cd25e 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; @@ -66,6 +65,7 @@ import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory; @@ -826,7 +826,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { ILanguage language= configureWith.getLanguage(); fLanguageOfContext= language; if (language != null) { - ICodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); + AbstractCodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); int options= 0; if ((style & AST_SKIP_FUNCTION_BODIES) != 0) { options |= ILanguage.OPTION_SKIP_FUNCTION_BODIES; @@ -852,11 +852,11 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return null; } - private ICodeReaderFactory getCodeReaderFactory(int style, IIndex index, int linkageID) { + private AbstractCodeReaderFactory getCodeReaderFactory(int style, IIndex index, int linkageID) { final ICProject cprj= getCProject(); final ProjectIndexerInputAdapter pathResolver = new ProjectIndexerInputAdapter(cprj); final ProjectIndexerIncludeResolutionHeuristics heuristics = new ProjectIndexerIncludeResolutionHeuristics(cprj.getProject(), pathResolver); - ICodeReaderFactory codeReaderFactory; + AbstractCodeReaderFactory codeReaderFactory; if ((style & AST_SKIP_NONINDEXED_HEADERS) != 0) { codeReaderFactory= NullCodeReaderFactory.getInstance(); } else { @@ -935,7 +935,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { ILanguage language= configureWith.getLanguage(); fLanguageOfContext= language; if (language != null) { - ICodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); + AbstractCodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); return language.getCompletionNode(reader, scanInfo, crf, index, ParserUtil.getParserLogService(), offset); } return null; @@ -952,9 +952,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit { IResource res= getResource(); try { if (res instanceof IFile) - return InternalParserUtil.createWorkspaceFileReader(location.toOSString(), (IFile) res); + return InternalParserUtil.createWorkspaceFileReader(location.toOSString(), (IFile) res, null); else - return InternalParserUtil.createExternalFileReader(location.toOSString()); + return InternalParserUtil.createExternalFileReader(location.toOSString(), null); } catch (CoreException e) { CCorePlugin.log(e); } catch (IOException e) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java index 01578e13d6c..3d2821109d5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java @@ -10,6 +10,11 @@ *******************************************************************************/ package org.eclipse.cdt.core.parser; +import java.io.IOException; + +import org.eclipse.cdt.core.index.IIndexFileLocation; +import org.eclipse.core.runtime.CoreException; + /** * This is the interface to a cache for CodeReaders. * @@ -31,6 +36,20 @@ public interface ICodeReaderCache { */ public CodeReader get(String key); + /** + * Retrieves the CodeReader corresponding to the key specified that represents the + * path for that CodeReader. If no CodeReader is found in the cache then a new CodeReader + * is created for the ifl and then returned. + * + * @param key the path corresponding to the CodeReader, generally: + * fileToParse.getLocation().toOSString() + * @return the CodeReader corresponding to the path specified by the key + * @throws IOException + * @throws CoreException + * @since 5.1 + */ + public CodeReader get(String key, IIndexFileLocation ifl) throws CoreException, IOException; + /** * Used to remove the CodeReader corresponding to the path specified by key from the cache. * diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/EmptyCodeReaderCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/EmptyCodeReaderCache.java index 7b37a81aa3a..9a5056503e4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/EmptyCodeReaderCache.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/EmptyCodeReaderCache.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 IBM Corporation 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 @@ -12,17 +12,18 @@ package org.eclipse.cdt.internal.core.dom.parser; import java.io.IOException; +import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ICodeReaderCache; +import org.eclipse.cdt.internal.core.parser.InternalParserUtil; +import org.eclipse.core.runtime.CoreException; /** * This is an empty implementation of the ICodeReaderCache interface. It is used to implement a * cache for the interface that isn't actually a cache, but rather always creates new CodeReaders - * everytime a CodeReader is retrieved. + * every time a CodeReader is retrieved. * * This cache is not optimized to be run from within Eclipse (i.e. it ignores IResources). - * - * @author dsteffle */ public class EmptyCodeReaderCache implements ICodeReaderCache { @@ -37,6 +38,10 @@ public class EmptyCodeReaderCache implements ICodeReaderCache { return null; } + public CodeReader get(String key, IIndexFileLocation ifl) throws CoreException, IOException { + return InternalParserUtil.createCodeReader(ifl, null); + } + /** * Returns null. */ @@ -55,5 +60,4 @@ public class EmptyCodeReaderCache implements ICodeReaderCache { // nothing to do } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java index 39c6a804ee3..95560742ef7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; @@ -55,19 +54,19 @@ public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory private int fLinkage; private Set fIncludedFiles= new HashSet(); /** The fall-back code reader factory used in case a header file is not indexed */ - private final ICodeReaderFactory fFallBackFactory; + private final AbstractCodeReaderFactory fFallBackFactory; private final ASTFilePathResolver fPathResolver; private final AbstractIndexerTask fRelatedIndexerTask; private boolean fSupportFillGapFromContextToHeader= false; public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics, - ASTFilePathResolver pathResolver, int linkage, ICodeReaderFactory fallbackFactory) { + ASTFilePathResolver pathResolver, int linkage, AbstractCodeReaderFactory fallbackFactory) { this(index, heuristics, pathResolver, linkage, fallbackFactory, null); } public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics, ASTFilePathResolver pathResolver, int linkage, - ICodeReaderFactory fallbackFactory, AbstractIndexerTask relatedIndexerTask) { + AbstractCodeReaderFactory fallbackFactory, AbstractIndexerTask relatedIndexerTask) { super(heuristics); fIndex= index; fFallBackFactory= fallbackFactory; @@ -103,6 +102,15 @@ public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory return ParserUtil.createReader(path, null); } + @Override + public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) throws CoreException, IOException { + if (fFallBackFactory != null) { + return fFallBackFactory.createCodeReaderForInclusion(ifl, astPath); + } + return InternalParserUtil.createCodeReader(ifl, null); + } + + @Deprecated public CodeReader createCodeReaderForInclusion(String path) { if (fFallBackFactory != null) { return fFallBackFactory.createCodeReaderForInclusion(path); @@ -157,7 +165,7 @@ public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory } try { - CodeReader codeReader= InternalParserUtil.createCodeReader(ifl); + CodeReader codeReader= createCodeReaderForInclusion(ifl, path); if (codeReader != null) { IncludeFileContent ifc= new IncludeFileContent(codeReader); ifc.setIsSource(fPathResolver.isSource(path)); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java index 6114a471cd4..a781b12d72f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java @@ -15,7 +15,7 @@ package org.eclipse.cdt.internal.core.indexer; import java.util.List; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; /** @@ -36,7 +36,7 @@ public class StandaloneFastIndexerTask extends StandaloneIndexerTask { } @Override - protected ICodeReaderFactory createReaderFactory() { + protected AbstractCodeReaderFactory createReaderFactory() { return new StandaloneIndexerFallbackReaderFactory(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java index 1e41f09a8ca..4d64b6e974c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java @@ -17,10 +17,10 @@ import java.io.File; import java.util.List; import java.util.Map; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.WritableCIndex; import org.eclipse.cdt.internal.core.pdom.WritablePDOM; @@ -42,7 +42,7 @@ import org.eclipse.core.runtime.CoreException; */ public class StandaloneFullIndexer extends StandaloneIndexer{ - private ICodeReaderFactory fCodeReaderFactory; + private AbstractCodeReaderFactory fCodeReaderFactory; /** * Create a full indexer. @@ -59,7 +59,7 @@ public class StandaloneFullIndexer extends StandaloneIndexer{ */ @Deprecated public StandaloneFullIndexer(File writableIndexFile, IIndexLocationConverter converter, Map linkageFactoryMappings, - IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log, ICodeReaderFactory codeReaderFactory) throws CoreException { + IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log, AbstractCodeReaderFactory codeReaderFactory) throws CoreException { super(new WritableCIndex(new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings),new IIndexFragment[0]), false, mapper, log, scanner); fCodeReaderFactory = codeReaderFactory; @@ -78,7 +78,7 @@ public class StandaloneFullIndexer extends StandaloneIndexer{ * @throws CoreException */ public StandaloneFullIndexer(File writableIndexFile, IIndexLocationConverter converter, Map linkageFactoryMappings, - IStandaloneScannerInfoProvider scannerProvider, ILanguageMapper mapper, IParserLogService log, ICodeReaderFactory codeReaderFactory) throws CoreException { + IStandaloneScannerInfoProvider scannerProvider, ILanguageMapper mapper, IParserLogService log, AbstractCodeReaderFactory codeReaderFactory) throws CoreException { super(new WritableCIndex(new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings),new IIndexFragment[0]), false, mapper, log, scannerProvider); fCodeReaderFactory = codeReaderFactory; @@ -89,7 +89,7 @@ public class StandaloneFullIndexer extends StandaloneIndexer{ * Returns the factory that provides CodeReaders for files included * by the source code being parsed. */ - public ICodeReaderFactory getCodeReaderFactory() { + public AbstractCodeReaderFactory getCodeReaderFactory() { return fCodeReaderFactory; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java index de3d76a3d4c..dc65728eaa1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java @@ -15,7 +15,7 @@ package org.eclipse.cdt.internal.core.indexer; import java.util.List; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; /** @@ -37,7 +37,7 @@ public class StandaloneFullIndexerTask extends StandaloneIndexerTask { } @Override - protected ICodeReaderFactory createReaderFactory() { + protected AbstractCodeReaderFactory createReaderFactory() { return ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java index 3a75a85e7b8..9182e9aa806 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java @@ -14,9 +14,11 @@ package org.eclipse.cdt.internal.core.indexer; import java.io.File; import java.io.IOException; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ICodeReaderCache; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; +import org.eclipse.core.runtime.CoreException; /** * A factory for CodeReaders construction. @@ -30,7 +32,11 @@ import org.eclipse.cdt.core.parser.ICodeReaderCache; * * @since 4.0 */ -public class StandaloneIndexerFallbackReaderFactory implements ICodeReaderFactory { +public class StandaloneIndexerFallbackReaderFactory extends AbstractCodeReaderFactory { + + public StandaloneIndexerFallbackReaderFactory() { + super(null); + } public CodeReader createCodeReaderForInclusion(String path) { try { @@ -59,4 +65,9 @@ public class StandaloneIndexerFallbackReaderFactory implements ICodeReaderFactor public int getUniqueIdentifier() { return 0; } + + @Override + public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) throws CoreException, IOException { + return createCodeReaderForInclusion(astPath); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderCacheEntry.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderCacheEntry.java new file mode 100644 index 00000000000..077008a7438 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderCacheEntry.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2005, 2009 IBM Corporation 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: + * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.parser; + +import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.internal.core.util.ILRUCacheable; + +/** + * This is a wrapper for entries to put into the OverflowingLRUCache (required to determine the + * size of entries relative to the CodeReader's file size). + * + * Although the size of the CodeReaderCache is specified in terms of MB, the actual granularity of + * the cache is KB. + */ +class CodeReaderCacheEntry implements ILRUCacheable { + + private static final double CHAR_TO_KB_FACTOR = 1024; + CodeReader reader = null; + int size = 0; // used to specify the size of the CodeReader in terms of KB + + public CodeReaderCacheEntry(CodeReader value) { + this.reader = value; + size = (int)Math.ceil(reader.buffer.length / CHAR_TO_KB_FACTOR); // get the size of the file in terms of KB + } + + public int getCacheFootprint() { + return size; + } + + public CodeReader getCodeReader() { + return reader; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderLRUCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderLRUCache.java new file mode 100644 index 00000000000..75059d908c5 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CodeReaderLRUCache.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2005, 2009 IBM Corporation 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: + * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.parser; + +import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.internal.core.util.OverflowingLRUCache; + +/** + * This class is a wrapper/implementor class for OverflowingLRUCache. + * + * It uses CodeReaderCacheEntry (which implements ILRUCacheable) to specify that the size of + * the cache should be relative to the size of the entries and not the number of entries. + */ +public class CodeReaderLRUCache extends OverflowingLRUCache { + + + /** + * Creates a new CodeReaderLRUCache with a specified initial maximum size. + * @param size the maximum size of the cache in terms of MB + */ + public CodeReaderLRUCache(int size) { + super(); // need to initialize the LRUCache with super() so that the size of the hashtable isn't relative to the size in MB + this.setSpaceLimit(size); + } + + // must be overloaded, required to remove entries from the cache + @Override + protected boolean close(LRUCacheEntry entry) { + Object obj = remove(entry._fKey); + + if (obj != null) + return true; + + return false; + } + + @Override + protected OverflowingLRUCache newInstance(int size, int overflow) { + return null; + } + + /** + * Removes an entry from the cache and returns the entry that was removed if found. + * Otherwise null is returned. + */ + @Override + public CodeReader remove(String key) { + Object removed = removeKey(key); + + if (removed instanceof CodeReaderCacheEntry) + return ((CodeReaderCacheEntry)removed).getCodeReader(); + + return null; + } + + /** + * Puts a CodeReader into the cache by wrapping it with a CodeReaderCacheEntry first. + * This way the proper size of the element in the cache can be determined + * via the CodeReaderCacheEntry. + */ + public CodeReader put(String key, CodeReader value) { + CodeReaderCacheEntry entry = new CodeReaderCacheEntry(value); + CodeReaderCacheEntry ret = put(key, entry); + if (ret != null) + return ret.getCodeReader(); + + return null; + } + + /** + * Retrieves a CodeReader from the cache corresponding to the path specified by the key. + */ + public CodeReader get(String key) { + CodeReaderCacheEntry obj = peek(key); + if (obj != null) + return obj.getCodeReader(); + + return null; + } + +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java index ae43f2bab34..d6e30fa5dd7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java @@ -44,15 +44,22 @@ public class InternalParserUtil extends ParserFactory { /** * Creates a code reader for an external location, normalizing path to - * canonical path. + * canonical path. The cache is consulted after the path has been normalized. */ - public static CodeReader createExternalFileReader(String externalLocation) throws IOException { + public static CodeReader createExternalFileReader(String externalLocation, CodeReaderLRUCache cache) throws IOException { File includeFile = new File(externalLocation); if (includeFile.isFile()) { //use the canonical path so that in case of non-case-sensitive OSs //the CodeReader always has the same name as the file on disk with //no differences in case. - return new CodeReader(includeFile.getCanonicalPath()); + final String path = includeFile.getCanonicalPath(); + if (cache != null) { + CodeReader result= cache.get(path); + if (result != null) + return result; + } + + return new CodeReader(path); } return null; } @@ -61,8 +68,14 @@ public class InternalParserUtil extends ParserFactory { * Creates a code reader for an external location, normalizing path to * canonical path. */ - public static CodeReader createWorkspaceFileReader(String path, IFile file) throws CoreException, IOException{ + public static CodeReader createWorkspaceFileReader(String path, IFile file, CodeReaderLRUCache cache) throws CoreException, IOException{ path = normalizePath(path, file); + if (cache != null) { + CodeReader result= cache.get(path); + if (result != null) + return result; + } + InputStream in; try { in= file.getContents(true); @@ -86,13 +99,13 @@ public class InternalParserUtil extends ParserFactory { } } - public static CodeReader createCodeReader(IIndexFileLocation ifl) throws CoreException, IOException { + public static CodeReader createCodeReader(IIndexFileLocation ifl, CodeReaderLRUCache cache) throws CoreException, IOException { String fullPath= ifl.getFullPath(); if (fullPath != null) { IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath)); if (res instanceof IFile) - return createWorkspaceFileReader(ifl.getURI().getPath(), (IFile) res); + return createWorkspaceFileReader(ifl.getURI().getPath(), (IFile) res, cache); } - return createExternalFileReader(ifl.getURI().getPath()); + return createExternalFileReader(ifl.getURI().getPath(), cache); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java index e37ae3b79bd..57c55268749 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java @@ -22,7 +22,6 @@ import java.util.Map; import java.util.Map.Entry; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree; @@ -42,6 +41,7 @@ import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ScannerInfo; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IWritableIndex; @@ -174,7 +174,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { protected IWritableIndex fIndex; private ITodoTaskUpdater fTodoTaskUpdater; private final boolean fIsFastIndexer; - private ICodeReaderFactory fCodeReaderFactory; + private AbstractCodeReaderFactory fCodeReaderFactory; public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove, IndexerInputAdapter resolver, boolean fastIndexer) { super(resolver); @@ -208,7 +208,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { protected abstract IWritableIndex createIndex(); protected abstract IIncludeFileResolutionHeuristics createIncludeHeuristics(); - protected abstract ICodeReaderFactory createReaderFactory(); + protected abstract AbstractCodeReaderFactory createReaderFactory(); protected abstract AbstractLanguage[] getLanguages(String fileName); protected ITodoTaskUpdater createTodoTaskUpdater() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java index 96f45ae1cf6..c42f91a6d75 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java @@ -12,8 +12,8 @@ package org.eclipse.cdt.internal.core.pdom.indexer; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; /** @@ -26,7 +26,7 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { } @Override - protected ICodeReaderFactory createReaderFactory() { + protected AbstractCodeReaderFactory createReaderFactory() { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java index fedce096a73..4b424a4fff5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java @@ -12,8 +12,8 @@ package org.eclipse.cdt.internal.core.pdom.indexer; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; @@ -28,7 +28,7 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { } @Override - protected ICodeReaderFactory createReaderFactory() { + protected AbstractCodeReaderFactory createReaderFactory() { return SavedCodeReaderFactory.createInstance(createIncludeHeuristics()); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/CodeReaderCache.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/CodeReaderCache.java index 47dd7dfd92a..6455cab0df3 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/CodeReaderCache.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/CodeReaderCache.java @@ -16,9 +16,9 @@ import java.io.File; import java.io.IOException; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.index.IIndexFileLocation; +import org.eclipse.cdt.internal.core.parser.CodeReaderLRUCache; import org.eclipse.cdt.internal.core.parser.InternalParserUtil; -import org.eclipse.cdt.internal.core.util.ILRUCacheable; -import org.eclipse.cdt.internal.core.util.OverflowingLRUCache; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; @@ -159,18 +159,9 @@ public class CodeReaderCache implements ICodeReaderCache { IResource file = ParserUtil.getResourceForFilename(key); if (file instanceof IFile) { key= InternalParserUtil.normalizePath(key, (IFile) file); - result= cache.get(key); - if (result != null) - return result; - - result= InternalParserUtil.createWorkspaceFileReader(key, (IFile) file); + result= InternalParserUtil.createWorkspaceFileReader(key, (IFile) file, cache); } - key= jfile.getCanonicalPath(); - result= cache.get(key); - if (result != null) - return result; - - result= InternalParserUtil.createExternalFileReader(key); + result= InternalParserUtil.createExternalFileReader(key, cache); if (cache.getSpaceLimit() > 0) put(result); @@ -182,6 +173,26 @@ public class CodeReaderCache implements ICodeReaderCache { return null; } + /** + * @throws IOException + * @throws CoreException + * @since 5.1 + */ + public CodeReader get(String key, IIndexFileLocation ifl) throws CoreException, IOException { + CodeReader result = null; + if (cache.getSpaceLimit() > 0) + result= cache.get(key); + + if (result != null) + return result; + + result= InternalParserUtil.createCodeReader(ifl, cache); + if (cache.getSpaceLimit() > 0) + put(result); + + return result; + } + /** * Put a CodeReader into the Cache. * @param key @@ -206,114 +217,6 @@ public class CodeReaderCache implements ICodeReaderCache { } - /** - * This is a wrapper for entries to put into the OverflowingLRUCache (required to determine the - * size of entries relative to the CodeReader's file size). - * - * Although the size of the CodeReaderCache is specified in terms of MB, the actual granularity of - * the cache is KB. - * - * @author dsteffle - * - */ - private class CodeReaderCacheEntry implements ILRUCacheable { - - private static final double CHAR_TO_KB_FACTOR = 1024; - CodeReader reader = null; - int size = 0; // used to specify the size of the CodeReader in terms of KB - - public CodeReaderCacheEntry(CodeReader value) { - this.reader = value; - size = (int)Math.ceil(reader.buffer.length / CHAR_TO_KB_FACTOR); // get the size of the file in terms of KB - } - - public int getCacheFootprint() { - return size; - } - - public CodeReader getCodeReader() { - return reader; - } - } - - /** - * This class is a wrapper/implementor class for OverflowingLRUCache. - * - * It uses CodeReaderCacheEntry (which implements ILRUCacheable) to specify that the size of - * the cache should be relative to the size of the entries and not the number of entries. - * - * @author dsteffle - * - */ - private class CodeReaderLRUCache extends OverflowingLRUCache { - - - /** - * Creates a new CodeReaderLRUCache with a specified initial maximum size. - * @param size the maximum size of the cache in terms of MB - */ - public CodeReaderLRUCache(int size) { - super(); // need to initialize the LRUCache with super() so that the size of the hashtable isn't relative to the size in MB - this.setSpaceLimit(size); - } - - // must be overloaded, required to remove entries from the cache - @Override - protected boolean close(LRUCacheEntry entry) { - Object obj = remove(entry._fKey); - - if (obj != null) - return true; - - return false; - } - - @Override - protected OverflowingLRUCache newInstance(int size, int overflow) { - return null; - } - - /** - * Removes an entry from the cache and returns the entry that was removed if found. - * Otherwise null is returned. - */ - @Override - public CodeReader remove(String key) { - Object removed = removeKey(key); - - if (removed instanceof CodeReaderCacheEntry) - return ((CodeReaderCacheEntry)removed).getCodeReader(); - - return null; - } - - /** - * Puts a CodeReader into the cache by wrapping it with a CodeReaderCacheEntry first. - * This way the proper size of the element in the cache can be determined - * via the CodeReaderCacheEntry. - */ - public CodeReader put(String key, CodeReader value) { - CodeReaderCacheEntry entry = new CodeReaderCacheEntry(value); - CodeReaderCacheEntry ret = put(key, entry); - if (ret != null) - return ret.getCodeReader(); - - return null; - } - - /** - * Retrieves a CodeReader from the cache corresponding to the path specified by the key. - */ - public CodeReader get(String key) { - CodeReaderCacheEntry obj = peek(key); - if (obj != null) - return obj.getCodeReader(); - - return null; - } - - } - /** * Removes the CodeReader from the cache corresponding to the path specified by the key and * returns the CodeReader that was removed. If no CodeReader is removed then null is returned. diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java index 5334c625da9..659d570a352 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java @@ -74,9 +74,9 @@ public class ParserUtil if (buffer != null) return new CodeReader(InternalParserUtil.normalizePath(path, (IFile) file), buffer); } - return InternalParserUtil.createWorkspaceFileReader(path, (IFile) file); + return InternalParserUtil.createWorkspaceFileReader(path, (IFile) file, null); } - return InternalParserUtil.createExternalFileReader(path); + return InternalParserUtil.createExternalFileReader(path, null); } catch (CoreException ce) { } catch (IOException e) { } catch (IllegalStateException e) { diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/AbstractCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/AbstractCodeReaderFactory.java index 147601dba14..8ebb45bfc3f 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/AbstractCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/AbstractCodeReaderFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2009 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 @@ -10,7 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom; +import java.io.IOException; + import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.core.index.IIndexFileLocation; +import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; /** @@ -31,4 +36,6 @@ public abstract class AbstractCodeReaderFactory implements ICodeReaderFactory, I } return null; } + + public abstract CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) throws CoreException, IOException; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/NullCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/NullCodeReaderFactory.java index 96378b05096..47453aafb2b 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/NullCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/NullCodeReaderFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2009 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 @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom; -import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ICodeReaderCache; @@ -22,9 +22,9 @@ import org.eclipse.cdt.core.parser.ICodeReaderCache; public class NullCodeReaderFactory extends AbstractCodeReaderFactory { private static final char[] EMPTY_CHARS = new char[0]; - private static final ICodeReaderFactory INSTANCE= new NullCodeReaderFactory(); + private static final NullCodeReaderFactory INSTANCE= new NullCodeReaderFactory(); - public static ICodeReaderFactory getInstance() { + public static NullCodeReaderFactory getInstance() { return INSTANCE; } @@ -39,6 +39,12 @@ public class NullCodeReaderFactory extends AbstractCodeReaderFactory { return new CodeReader(path, EMPTY_CHARS); } + + @Override + public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) { + return new CodeReader(astPath, EMPTY_CHARS); + } + /* * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForTranslationUnit(java.lang.String) */ diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java index ed9215de07c..289c4265758 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation 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 @@ -10,10 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom; +import java.io.IOException; import java.util.Arrays; import java.util.Iterator; import org.eclipse.cdt.core.dom.CDOM; +import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopyProvider; @@ -21,6 +23,7 @@ import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.internal.core.parser.EmptyIterator; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon @@ -71,6 +74,13 @@ public class PartialWorkingCopyCodeReaderFactory extends AbstractCodeReaderFacto return cache.get( path ); } + + @Override + public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) + throws CoreException, IOException { + return cache.get(astPath, ifl); + } + protected Iterator createWorkingCopyIterator() { if( provider == null ) return EmptyIterator.empty(); return Arrays.asList( provider.getWorkingCopies() ).iterator(); diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java index db318bf8085..fa82038dca9 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation 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 @@ -10,12 +10,16 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom; +import java.io.IOException; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.CDOM; +import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReaderCache; import org.eclipse.cdt.core.parser.ICodeReaderCache; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Preferences; /** @@ -90,6 +94,12 @@ public class SavedCodeReaderFactory extends AbstractCodeReaderFactory { return cache.get(path); } + @Override + public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) + throws CoreException, IOException { + return cache.get(astPath, ifl); + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String) */