From 789f315fce4deea1097b1752ce547f44fc398194 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Sun, 18 Mar 2012 17:56:28 -0700 Subject: [PATCH] Added file size to the condition used for determining if the file has changed since it was indexed. Timestamps on Unix have 1-sec granularity and comparison based on them alone may produce false negatives. --- .../core/index/IIndexFragmentFile.java | 10 ++++++++-- .../StandaloneIndexerInputAdapter.java | 6 ++++++ .../core/pdom/AbstractIndexerTask.java | 9 ++++----- .../core/pdom/IndexerInputAdapter.java | 17 ++++++++++------ .../eclipse/cdt/internal/core/pdom/PDOM.java | 10 +++++++--- .../cdt/internal/core/pdom/PDOMWriter.java | 6 +++++- .../internal/core/pdom/db/IBTreeVisitor.java | 8 +++----- .../cdt/internal/core/pdom/dom/PDOMFile.java | 20 ++++++++++++------- .../indexer/ProjectIndexerInputAdapter.java | 18 +++++++++++++++++ 9 files changed, 75 insertions(+), 29 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java index a8c922b561b..f6ca6b05ca2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java @@ -34,10 +34,16 @@ public interface IIndexFragmentFile extends IIndexFile { void setContentsHash(long hash) throws CoreException; /** - * Sets the hash-code of the file encoding. + * Returns the hash-code computed by combining the file size and the file encoding. + * @return hashcode a hash-code or 0 if it is unknown. + */ + int getSizeAndEncodingHashcode() throws CoreException; + + /** + * Sets the hash-code computed by combining the file size and the file encoding. * @param hashcode a hash-code or 0 if it is unknown. */ - void setEncodingHashcode(int hashcode) throws CoreException; + void setSizeAndEncodingHashcode(int hashcode) throws CoreException; /** * Sets the flag that determines whether the file is a header with #pragma once statement diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java index ae9953e5acb..bd018868a36 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java @@ -8,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * IBM Corporation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.indexer; @@ -55,6 +56,11 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter { return new File(URIUtil.toPath(location.getURI()).toOSString()).lastModified(); } + @Override + public long getFileSize(IIndexFileLocation location) { + return new File(URIUtil.toPath(location.getURI()).toOSString()).length(); + } + @Override public String getEncoding(IIndexFileLocation ifl) { String encoding= getFileEncoding(getASTPath(ifl)); 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 d99c50908ee..9c30c079929 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 @@ -71,12 +71,11 @@ import org.eclipse.osgi.util.NLS; * @since 5.0 */ public abstract class AbstractIndexerTask extends PDOMWriter { - public static enum UnusedHeaderStrategy { - skip, useC, useCPP, useDefaultLanguage, useBoth - } + public static enum UnusedHeaderStrategy { skip, useC, useCPP, useDefaultLanguage, useBoth } private static final int MAX_ERRORS = 500; - private static enum UpdateKind {REQUIRED_SOURCE, REQUIRED_HEADER, ONE_LINKAGE_HEADER, OTHER_HEADER} + private static enum UpdateKind { REQUIRED_SOURCE, REQUIRED_HEADER, ONE_LINKAGE_HEADER, OTHER_HEADER } + private static class LinkageTask { final int fLinkageID; private final Map fLocationTasks; @@ -687,7 +686,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { Object tu, IIndexFragmentFile file) throws CoreException { if (checkTimestamps) { if (fResolver.getLastModified(ifl) != file.getTimestamp() || - fResolver.getEncoding(ifl).hashCode() != file.getEncodingHashcode()) { + computeFileSizeAndEncodingHashcode(ifl) != file.getSizeAndEncodingHashcode()) { if (checkFileContentsHash && computeFileContentsHash(tu) == file.getContentsHash()) { return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java index 66f3158c4cf..d49d6c13d81 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom; @@ -22,7 +23,6 @@ import org.eclipse.cdt.core.parser.IScannerInfo; * @since 5.0 */ public abstract class IndexerInputAdapter extends ASTFilePathResolver { - /** * Returns an object representing an input file for the given index location, * or null, if it does not exist. @@ -34,6 +34,16 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver { */ public abstract long getLastModified(IIndexFileLocation location); + /** + * Returns the size of the file in bytes, or 0 if the file does not exist. + */ + public abstract long getFileSize(IIndexFileLocation ifl); + + /** + * Returns the encoding for the file. + */ + public abstract String getEncoding(IIndexFileLocation ifl); + /** * Create an index location for the given input file. */ @@ -82,9 +92,4 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver { * Returns a code reader for the given input file. */ public abstract FileContent getCodeReader(Object tu); - - /** - * Returns the encoding for the file. - */ - public abstract String getEncoding(IIndexFileLocation ifl); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 3ea6248527f..e507340e261 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -213,10 +213,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 120.1 - Specializations of using declarations, bug 357293. * 121.0 - Multiple variants of included header file, bug 197989. * 122.0 - Compacting strings + * 123.0 - Combined file size and encoding hash code. */ - private static final int MIN_SUPPORTED_VERSION= version(122, 0); - private static final int MAX_SUPPORTED_VERSION= version(122, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(122, 0); + private static final int MIN_SUPPORTED_VERSION= version(123, 0); + private static final int MAX_SUPPORTED_VERSION= version(123, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(123, 0); private static int version(int major, int minor) { return (major << 16) + minor; @@ -232,12 +233,15 @@ public class PDOM extends PlatformObject implements IPDOM { public static boolean isSupportedVersion(int vers) { return vers >= MIN_SUPPORTED_VERSION && vers <= MAX_SUPPORTED_VERSION; } + public static int getMinSupportedVersion() { return MIN_SUPPORTED_VERSION; } + public static int getMaxSupportedVersion() { return MAX_SUPPORTED_VERSION; } + public static String versionString(int version) { final int major= version >> 16; final int minor= version & 0xffff; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java index 7bf753147d3..ed854f09862 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java @@ -560,7 +560,7 @@ abstract public class PDOMWriter { index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock); } file.setTimestamp(fResolver.getLastModified(location)); - file.setEncodingHashcode(fResolver.getEncoding(location).hashCode()); + file.setSizeAndEncodingHashcode(computeFileSizeAndEncodingHashcode(location)); file.setContentsHash(astFile.fContentsHash); file = index.commitUncommittedFile(); } finally { @@ -569,6 +569,10 @@ abstract public class PDOMWriter { return file; } + protected int computeFileSizeAndEncodingHashcode(IIndexFileLocation location) { + return ((int) fResolver.getFileSize(location)) + 31 * fResolver.getEncoding(location).hashCode(); + } + private boolean isContextFor(IIndexFragmentFile oldFile, IASTPreprocessorIncludeStatement stmt) throws CoreException { IIndexFile target= stmt.getImportedIndexFile(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeVisitor.java index cb3461b0ea6..e22c1895174 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeVisitor.java @@ -6,8 +6,8 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.db; @@ -19,7 +19,6 @@ import org.eclipse.core.runtime.CoreException; * The visitor visits all records where compare returns 0. */ public interface IBTreeVisitor { - /** * Compare the record against an internally held key. The comparison must be * compatible with the one used for the btree. @@ -37,6 +36,5 @@ public interface IBTreeVisitor { * @return true to continue the visit, false to abort it. * @throws CoreException */ - public abstract boolean visit(long record) throws CoreException; - + public abstract boolean visit(long record) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java index a896f2a3f58..a8692a2927c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java @@ -74,8 +74,8 @@ public class PDOMFile implements IIndexFragmentFile { private static final int FLAGS= LINKAGE_ID + 3; // size 1 private static final int TIME_STAMP = FLAGS + 1; // long private static final int CONTENT_HASH= TIME_STAMP + 8; // long - private static final int ENCODING_HASH= CONTENT_HASH + 8; - private static final int LAST_USING_DIRECTIVE= ENCODING_HASH + 4; + private static final int SIZE_AND_ENCODING_HASH= CONTENT_HASH + 8; + private static final int LAST_USING_DIRECTIVE= SIZE_AND_ENCODING_HASH + 4; private static final int FIRST_MACRO_REFERENCE= LAST_USING_DIRECTIVE + Database.PTR_SIZE; private static final int SIGNIFICANT_MACROS= FIRST_MACRO_REFERENCE + Database.PTR_SIZE; private static final int RECORD_SIZE= SIGNIFICANT_MACROS + Database.PTR_SIZE; // 8*PTR_SIZE + 3+1+8+8+4 = 56 @@ -205,7 +205,7 @@ public class PDOMFile implements IIndexFragmentFile { } setTimestamp(sourceFile.getTimestamp()); - setEncodingHashcode(sourceFile.getEncodingHashcode()); + setSizeAndEncodingHashcode(sourceFile.getSizeAndEncodingHashcode()); setContentsHash(sourceFile.getContentsHash()); // Transfer the flags. @@ -327,15 +327,21 @@ public class PDOMFile implements IIndexFragmentFile { } @Override - public int getEncodingHashcode() throws CoreException { + public int getSizeAndEncodingHashcode() throws CoreException { Database db = fLinkage.getDB(); - return db.getInt(record + ENCODING_HASH); + return db.getInt(record + SIZE_AND_ENCODING_HASH); } @Override - public void setEncodingHashcode(int hashcode) throws CoreException { + @Deprecated + public int getEncodingHashcode() throws CoreException { + return 0; + } + + @Override + public void setSizeAndEncodingHashcode(int hashcode) throws CoreException { Database db= fLinkage.getDB(); - db.putInt(record + ENCODING_HASH, hashcode); + db.putInt(record + SIZE_AND_ENCODING_HASH, hashcode); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java index 4777cf181fb..bfb8c6cba4c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java @@ -178,6 +178,24 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter { return 0; } + @Override + public long getFileSize(IIndexFileLocation ifl) { + String fullPath= ifl.getFullPath(); + IPath location= null; + if (fullPath != null) { + IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath)); + if (res != null) { + location = res.getLocation(); + } + } else { + location= IndexLocationFactory.getAbsolutePath(ifl); + } + if (location != null) { + return location.toFile().length(); + } + return 0; + } + @Override public String getEncoding(IIndexFileLocation ifl) { String fullPath= ifl.getFullPath();