diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
index eb1aec237a2..526777f16cc 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
@@ -8,6 +8,7 @@
* Contributors:
* Andrew Ferguson (Symbian) - initial API and implementation
* Markus Schorn (Wind River Systems)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
@@ -123,6 +124,11 @@ public class EmptyIndexFragment implements IIndexFragment {
}
public void releaseReadLock() {}
+
+ public boolean hasWaitingReaders() {
+ return false;
+ }
+
public void resetCacheCounters() {}
public IIndexFragmentFileSet createFileSet() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java
index 03047bd8f8e..6fe8024593c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java
@@ -9,6 +9,7 @@
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
* Bryan Wilkinson (QNX)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.index;
@@ -91,6 +92,12 @@ public interface IIndex {
*/
public void releaseReadLock();
+ /**
+ * @return true
if there are threads waiting for read locks.
+ * @since 5.2
+ */
+ public boolean hasWaitingReaders();
+
/**
* Returns a timestamp of when the index was last written to. This can
* be used to figure out whether information read from the index is
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
index c3c0844d523..0df4c0555df 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
@@ -10,6 +10,7 @@
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian)
* Anton Leherbauer (Wind River Systems)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
@@ -355,6 +356,15 @@ public class CIndex implements IIndex {
return fReadLock;
}
+ public boolean hasWaitingReaders() {
+ for (int i= 0; i < fFragments.length; i++) {
+ if (fFragments[i].hasWaitingReaders()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public long getLastWriteAccess() {
long result= 0;
for (int i = 0; i < fFragments.length; i++) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
index 5d9ffa85dbf..3197f68f2a5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
@@ -9,6 +9,7 @@
* Markus Schorn - initial API and implementation
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
@@ -85,6 +86,10 @@ final public class EmptyCIndex implements IIndex {
public void releaseReadLock() {
}
+ public boolean hasWaitingReaders() {
+ return false;
+ }
+
public long getLastWriteAccess() {
return 0;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
index 50d35af6e28..ff5755f07f9 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
@@ -9,6 +9,7 @@
* Markus Schorn - initial API and implementation
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
@@ -190,6 +191,11 @@ public interface IIndexFragment {
*/
void releaseReadLock();
+ /**
+ * @return true
if there are threads waiting for read locks.
+ */
+ public boolean hasWaitingReaders();
+
/**
* Returns the timestamp of the last modification to the index.
*/
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java
index 21169115848..b125d44838e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java
@@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
@@ -21,6 +22,7 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
+import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
import org.eclipse.core.runtime.CoreException;
/**
@@ -65,7 +67,28 @@ public interface IWritableIndex extends IIndex {
/**
* Creates a file object for the given location or returns an existing one.
*/
- IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
+ IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException;
+
+ /**
+ * Creates a uncommitted file object for the given location.
+ */
+ IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException;
+
+ /**
+ * Makes an uncommitted file that was created earlier by calling
+ * {@link #addUncommittedFile(int, IIndexFileLocation)} method visible in the index.
+ *
+ * @return The file that was updated.
+ * @throws CoreException
+ */
+ IIndexFragmentFile commitUncommittedFile() throws CoreException;
+
+ /**
+ * Removes an uncommitted file if there is one. Used to recover from a failed index update.
+ *
+ * @throws CoreException
+ */
+ void clearUncommittedFile() throws CoreException;
/**
* Adds content to the given file.
@@ -73,7 +96,7 @@ public interface IWritableIndex extends IIndex {
void setFileContent(IIndexFragmentFile sourceFile,
int linkageID, IncludeInformation[] includes,
IASTPreprocessorStatement[] macros, IASTName[][] names,
- ASTFilePathResolver resolver) throws CoreException;
+ ASTFilePathResolver resolver, YieldableIndexLock lock) throws CoreException, InterruptedException;
/**
* Clears the entire index.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java
index 137d950c63a..aec945d2c91 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java
@@ -8,7 +8,8 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
- *******************************************************************************/
+ * Sergey Prigogin (Google)
+******************************************************************************/
package org.eclipse.cdt.internal.core.index;
@@ -19,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
+import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
import org.eclipse.core.runtime.CoreException;
/**
@@ -41,18 +43,43 @@ public interface IWritableIndexFragment extends IIndexFragment {
/**
* Creates a file object for the given location and linkage or returns an existing one.
- * @param fileLocation an IIndexFileLocation representing the location of the file
- * @return the existing IIndexFragmentFile for this location, or a newly created one
+ * @param fileLocation an IIndexFileLocation representing the location of the file.
+ * @return the existing IIndexFragmentFile for this location, or a newly created one.
* @throws CoreException
*/
IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
/**
- * Adds an include to the given file.
+ * Creates a file object for the given location and linkage. The created file object is not added to
+ * the file index.
+ * @param fileLocation an IIndexFileLocation representing the location of the file.
+ * @return a newly created IIndexFragmentFile.
+ * @throws CoreException
*/
- void addFileContent(IIndexFragmentFile sourceFile,
- IncludeInformation[] includes,
- IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver) throws CoreException;
+ IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
+
+ /**
+ * Makes an uncommitted file that was created earlier by calling
+ * {@link #addUncommittedFile(int, IIndexFileLocation)} method visible in the index.
+ *
+ * @return The file that was updated.
+ * @throws CoreException
+ */
+ IIndexFragmentFile commitUncommittedFile() throws CoreException;
+
+ /**
+ * Removes an uncommitted file if there is one. Used to recover from a failed index update.
+ *
+ * @throws CoreException
+ */
+ void clearUncommittedFile() throws CoreException;
+
+ /**
+ * Adds includes, macros and names to the given file.
+ */
+ void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes,
+ IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver,
+ YieldableIndexLock lock) throws CoreException, InterruptedException;
/**
* Acquires a write lock, while giving up a certain amount of read locks.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java
index 1cca94dbdd6..ad7d877db3f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java
@@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
@@ -19,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
+import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
import org.eclipse.core.runtime.CoreException;
public class WritableCIndex extends CIndex implements IWritableIndex {
@@ -50,17 +52,29 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
return fWritableFragment.getFiles(location);
}
- public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException {
- return fWritableFragment.addFile(linkageID, fileLocation);
+ public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
+ return fWritableFragment.addFile(linkageID, location);
+ }
+
+ public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException {
+ return fWritableFragment.addUncommittedFile(linkageID, location);
+ }
+
+ public IIndexFragmentFile commitUncommittedFile() throws CoreException {
+ return fWritableFragment.commitUncommittedFile();
+ }
+
+ public void clearUncommittedFile() throws CoreException {
+ fWritableFragment.clearUncommittedFile();
}
private boolean isWritableFragment(IIndexFragment frag) {
return frag == fWritableFragment;
}
- public void setFileContent(IIndexFragmentFile file, int linkageID,
- IncludeInformation[] includes,
- IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver) throws CoreException {
+ public void setFileContent(IIndexFragmentFile file, int linkageID, IncludeInformation[] includes,
+ IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver,
+ YieldableIndexLock lock) throws CoreException, InterruptedException {
IIndexFragment indexFragment = file.getIndexFragment();
if (!isWritableFragment(indexFragment)) {
assert false : "Attempt to update file of read-only fragment"; //$NON-NLS-1$
@@ -70,7 +84,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
ii.fTargetFile= addFile(linkageID, ii.fLocation);
}
}
- ((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names, resolver);
+ ((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names, resolver, lock);
}
}
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 e7ca8c7fc85..56652441d7a 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
@@ -6,11 +6,12 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Doug Schaefer (QNX) - Initial API and implementation
- * Markus Schorn (Wind River Systems)
- * IBM Corporation
- * Andrew Ferguson (Symbian)
- * Anton Leherbauer (Wind River Systems)
+ * Doug Schaefer (QNX) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ * IBM Corporation
+ * Andrew Ferguson (Symbian)
+ * Anton Leherbauer (Wind River Systems)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
@@ -96,6 +97,7 @@ import org.eclipse.core.runtime.Status;
public class PDOM extends PlatformObject implements IPDOM {
private static final int BLOCKED_WRITE_LOCK_OUTPUT_INTERVAL = 30000;
private static final int LONG_WRITE_LOCK_REPORT_THRESHOLD = 1000;
+ private static final int LONG_READ_LOCK_WAIT_REPORT_THRESHOLD = 1000;
static boolean sDEBUG_LOCKS= false; // initialized in the PDOMManager, because IBM needs PDOM independent of runtime plugin.
/**
@@ -341,7 +343,7 @@ public class PDOM extends PlatformObject implements IPDOM {
}
}
- private PDOMLinkage createLinkage(int linkageID) throws CoreException {
+ protected PDOMLinkage createLinkage(int linkageID) throws CoreException {
PDOMLinkage pdomLinkage= fLinkageIDCache.get(linkageID);
if (pdomLinkage == null) {
final String linkageName= Linkage.getLinkageName(linkageID);
@@ -766,6 +768,7 @@ public class PDOM extends PlatformObject implements IPDOM {
private long timeWriteLockAcquired;
public void acquireReadLock() throws InterruptedException {
+ long t = sDEBUG_LOCKS ? System.nanoTime() : 0;
synchronized (mutex) {
++waitingReaders;
try {
@@ -776,14 +779,17 @@ public class PDOM extends PlatformObject implements IPDOM {
}
++lockCount;
db.setLocked(true);
-
+
if (sDEBUG_LOCKS) {
+ t = (System.nanoTime() - t) / 1000000;
+ if (t >= LONG_READ_LOCK_WAIT_REPORT_THRESHOLD) {
+ System.out.println("Acquired index read lock after " + t + " ms wait."); //$NON-NLS-1$//$NON-NLS-2$
+ }
incReadLock(fLockDebugging);
}
}
}
-
public void releaseReadLock() {
boolean clearCache= false;
synchronized (mutex) {
@@ -884,6 +890,12 @@ public class PDOM extends PlatformObject implements IPDOM {
fireChange(event);
}
+ public boolean hasWaitingReaders() {
+ synchronized (mutex) {
+ return waitingReaders > 0;
+ }
+ }
+
public long getLastWriteAccess() {
return lastWriteAccess;
}
@@ -957,17 +969,23 @@ public class PDOM extends PlatformObject implements IPDOM {
PDOMName name;
if ((options & FIND_DECLARATIONS) != 0) {
for (name= pdomBinding.getFirstDeclaration(); name != null; name= name.getNextInBinding()) {
- names.add(name);
+ if (isCommitted(name)) {
+ names.add(name);
+ }
}
}
if ((options & FIND_DEFINITIONS) != 0) {
for (name = pdomBinding.getFirstDefinition(); name != null; name= name.getNextInBinding()) {
- names.add(name);
+ if (isCommitted(name)) {
+ names.add(name);
+ }
}
}
if ((options & FIND_REFERENCES) != 0) {
for (name = pdomBinding.getFirstReference(); name != null; name= name.getNextInBinding()) {
- names.add(name);
+ if (isCommitted(name)) {
+ names.add(name);
+ }
}
}
}
@@ -977,24 +995,40 @@ public class PDOM extends PlatformObject implements IPDOM {
if ((options & FIND_DEFINITIONS) != 0) {
for (PDOMMacro macro= container.getFirstDefinition(); macro != null; macro= macro.getNextInContainer()) {
final IIndexFragmentName name = macro.getDefinition();
- if (name != null) {
+ if (name != null && isCommitted(macro)) {
names.add(name);
}
}
}
if ((options & FIND_REFERENCES) != 0) {
for (PDOMMacroReferenceName name = container.getFirstReference(); name != null; name= name.getNextInContainer()) {
- names.add(name);
+ if (isCommitted(name)) {
+ names.add(name);
+ }
}
}
}
+ protected boolean isCommitted(PDOMName name) throws CoreException {
+ return true;
+ }
+
+ protected boolean isCommitted(PDOMMacro name) throws CoreException {
+ return true;
+ }
+
+ protected boolean isCommitted(PDOMMacroReferenceName name) throws CoreException {
+ return true;
+ }
+
public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) throws CoreException {
PDOMFile pdomFile= adaptFile(file);
if (pdomFile != null) {
List result = new ArrayList();
for (PDOMInclude i= pdomFile.getFirstIncludedBy(); i != null; i= i.getNextInIncludedBy()) {
- result.add(i);
+ if (i.getIncludedBy().getTimestamp() > 0) {
+ result.add(i);
+ }
}
return result.toArray(new PDOMInclude[result.size()]);
}
@@ -1197,6 +1231,10 @@ public class PDOM extends PlatformObject implements IPDOM {
public String createKeyForCache(long record, char[] name) {
return new StringBuilder(name.length + 2).append((char) (record >> 16)).append((char) record).append(name).toString();
}
+
+ public boolean hasLastingDefinition(PDOMBinding binding) throws CoreException {
+ return binding.hasDefinition();
+ }
private PDOMBinding[] getCrossLanguageBindings(IBinding binding) throws CoreException {
switch(binding.getLinkage().getLinkageID()) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
index e1cabeb4403..e61693ef1bc 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
@@ -187,6 +188,10 @@ public class PDOMProxy implements IPDOM {
}
}
+ public boolean hasWaitingReaders() {
+ return fDelegate != null && fDelegate.hasWaitingReaders();
+ }
+
public synchronized void resetCacheCounters() {
if (fDelegate != null)
fDelegate.resetCacheCounters();
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 24f3e024944..e5abcf63fb6 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
@@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* IBM Corporation
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
@@ -46,6 +47,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
@@ -68,6 +70,9 @@ import org.eclipse.osgi.util.NLS;
* @since 4.0
*/
abstract public class PDOMWriter {
+ // TODO(sprigogin): Remove SEMI_TRANSACTIONAL_UPDATES and ALLOW_LOCK_YIELDING constants and simplify the code.
+ public static boolean SEMI_TRANSACTIONAL_UPDATES = true;
+ public static boolean ALLOW_LOCK_YIELDING = true;
public static int SKIP_ALL_REFERENCES= -1;
public static int SKIP_TYPE_REFERENCES= 1;
public static int SKIP_MACRO_REFERENCES= 2;
@@ -200,11 +205,11 @@ abstract public class PDOMWriter {
if (fShowActivity) {
trace("Indexer: adding " + ifl.getURI()); //$NON-NLS-1$
}
- index.acquireWriteLock(readlockCount);
- long start= System.currentTimeMillis();
Throwable th= null;
+ YieldableIndexLock lock = new YieldableIndexLock(index, readlockCount, flushIndex);
+ lock.acquire();
try {
- storeFileInIndex(index, ifl, symbolMap, linkageID, configHash, contextIncludes);
+ storeFileInIndex(index, ifl, symbolMap, linkageID, configHash, contextIncludes, lock);
} catch (RuntimeException e) {
th= e;
} catch (PDOMNotImplementedError e) {
@@ -214,7 +219,7 @@ abstract public class PDOMWriter {
} catch (AssertionError e) {
th= e;
} finally {
- index.releaseWriteLock(readlockCount, flushIndex);
+ lock.release();
}
if (th != null) {
stati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
@@ -223,7 +228,7 @@ abstract public class PDOMWriter {
if (i < ifls.length - 1) {
updateFileCount(0, 0, 1); // update header count
}
- fStatistics.fAddToIndexTime += System.currentTimeMillis() - start;
+ fStatistics.fAddToIndexTime += lock.getCumulativeLockTime();
}
}
}
@@ -448,40 +453,70 @@ abstract public class PDOMWriter {
private IIndexFragmentFile storeFileInIndex(IWritableIndex index, IIndexFileLocation location,
Map symbolMap, int linkageID, int configHash,
- Set contextIncludes) throws CoreException {
+ Set contextIncludes, YieldableIndexLock lock)
+ throws CoreException, InterruptedException {
Set clearedContexts= Collections.emptySet();
- IIndexFragmentFile file= index.getWritableFile(linkageID, location);
- if (file != null) {
- clearedContexts= new HashSet();
- index.clearFile(file, clearedContexts);
+ IIndexFragmentFile file;
+ long timestamp = fResolver.getLastModified(location);
+ if (SEMI_TRANSACTIONAL_UPDATES) {
+ // In fine grained locking mode we create a temporary PDOMFile with zero timestamp,
+ // add names to it, then replace contents of the old file from the temporary one, then
+ // delete the temporary file. The write lock on the index is periodically yielded while
+ // adding names to the temporary file, if the process takes long time.
+ IIndexFragmentFile oldFile = index.getWritableFile(linkageID, location);
+ if (oldFile != null) {
+ IIndexInclude[] includedBy = index.findIncludedBy(oldFile);
+ if (includedBy.length > 0) {
+ clearedContexts= new HashSet();
+ for (IIndexInclude include : includedBy) {
+ clearedContexts.add(include.getIncludedByLocation());
+ }
+ }
+ }
+ file= index.addUncommittedFile(linkageID, location);
} else {
- file= index.addFile(linkageID, location);
+ file= index.getWritableFile(linkageID, location);
+ if (file != null) {
+ clearedContexts= new HashSet();
+ index.clearFile(file, clearedContexts);
+ } else {
+ file= index.addFile(linkageID, location);
+ }
+ file.setTimestamp(timestamp);
}
- file.setTimestamp(fResolver.getLastModified(location));
- file.setScannerConfigurationHashcode(configHash);
- Symbols lists= symbolMap.get(location);
- if (lists != null) {
- IASTPreprocessorStatement[] macros= lists.fMacros.toArray(new IASTPreprocessorStatement[lists.fMacros.size()]);
- IASTName[][] names= lists.fNames.toArray(new IASTName[lists.fNames.size()][]);
- for (IASTName[] name2 : names) {
- final IASTName name= name2[0];
- if (name != null) {
- ASTInternal.setFullyResolved(name.getBinding(), true);
+ try {
+ file.setScannerConfigurationHashcode(configHash);
+ Symbols lists= symbolMap.get(location);
+ if (lists != null) {
+ IASTPreprocessorStatement[] macros= lists.fMacros.toArray(new IASTPreprocessorStatement[lists.fMacros.size()]);
+ IASTName[][] names= lists.fNames.toArray(new IASTName[lists.fNames.size()][]);
+ for (IASTName[] name2 : names) {
+ final IASTName name= name2[0];
+ if (name != null) {
+ ASTInternal.setFullyResolved(name.getBinding(), true);
+ }
}
- }
-
- IncludeInformation[] includeInfos= new IncludeInformation[lists.fIncludes.size()];
- for (int i= 0; i < lists.fIncludes.size(); i++) {
- final IASTPreprocessorIncludeStatement include = lists.fIncludes.get(i);
- final IncludeInformation info= includeInfos[i]= new IncludeInformation();
- info.fStatement= include;
- if (include.isResolved()) {
- info.fLocation= fResolver.resolveASTPath(include.getPath());
- info.fIsContext= include.isActive() &&
- (contextIncludes.contains(include) || clearedContexts.contains(info.fLocation));
+
+ IncludeInformation[] includeInfos= new IncludeInformation[lists.fIncludes.size()];
+ for (int i= 0; i < lists.fIncludes.size(); i++) {
+ final IASTPreprocessorIncludeStatement include = lists.fIncludes.get(i);
+ final IncludeInformation info= includeInfos[i]= new IncludeInformation();
+ info.fStatement= include;
+ if (include.isResolved()) {
+ info.fLocation= fResolver.resolveASTPath(include.getPath());
+ info.fIsContext= include.isActive() &&
+ (contextIncludes.contains(include) || clearedContexts.contains(info.fLocation));
+ }
}
+ index.setFileContent(file, linkageID, includeInfos, macros, names, fResolver,
+ SEMI_TRANSACTIONAL_UPDATES && ALLOW_LOCK_YIELDING ? lock : null);
}
- index.setFileContent(file, linkageID, includeInfos, macros, names, fResolver);
+ if (SEMI_TRANSACTIONAL_UPDATES) {
+ file.setTimestamp(timestamp);
+ file = index.commitUncommittedFile();
+ }
+ } finally {
+ index.clearUncommittedFile();
}
return file;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
index 9d8fc7199e8..216bfa9cf79 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
@@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
@@ -25,17 +26,26 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
+import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacroReferenceName;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.core.runtime.CoreException;
public class WritablePDOM extends PDOM implements IWritableIndexFragment {
private boolean fClearedBecauseOfVersionMismatch= false;
private boolean fCreatedFromScratch= false;
private ASTFilePathResolver fPathResolver;
+ private PDOMFile fileBeingUpdated;
+ private PDOMFile uncommittedFile;
+ private IIndexFileLocation uncommittedLocation;
public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter,
Map linkageFactoryMappings) throws CoreException {
@@ -53,11 +63,57 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
@Override
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
+ if (uncommittedLocation != null && uncommittedLocation.equals(location)) {
+ return uncommittedFile;
+ }
return super.addFile(linkageID, location);
}
+ public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException {
+ uncommittedLocation = location;
+ fileBeingUpdated = getFile(linkageID, uncommittedLocation);
+ PDOMLinkage linkage= createLinkage(linkageID);
+ uncommittedFile = new PDOMFile(linkage, location, linkageID);
+ return uncommittedFile;
+ }
+
+ public IIndexFragmentFile commitUncommittedFile() throws CoreException {
+ if (uncommittedFile == null)
+ return null;
+ IIndexFragmentFile file;
+ if (fileBeingUpdated == null) {
+ // New file.
+ BTree fileIndex = getFileIndex();
+ fileIndex.insert(uncommittedFile.getRecord());
+ file = uncommittedFile;
+ } else {
+ // Existing file.
+ fileBeingUpdated.replaceContentsFrom(uncommittedFile);
+ file = fileBeingUpdated;
+ fileBeingUpdated = null;
+ }
+ fEvent.fFilesWritten.add(uncommittedLocation);
+ uncommittedFile = null;
+ uncommittedLocation = null;
+ return file;
+ }
+
+ public void clearUncommittedFile() throws CoreException {
+ if (uncommittedFile != null) {
+ try {
+ uncommittedFile.clear(null);
+ uncommittedFile.delete();
+ } finally {
+ uncommittedFile = null;
+ uncommittedLocation = null;
+ fileBeingUpdated = null;
+ }
+ }
+ }
+
public void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes,
- IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver) throws CoreException {
+ IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver,
+ YieldableIndexLock lock) throws CoreException, InterruptedException {
assert sourceFile.getIndexFragment() == this;
PDOMFile pdomFile = (PDOMFile) sourceFile;
@@ -66,14 +122,16 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
final ASTFilePathResolver origResolver= fPathResolver;
fPathResolver= pathResolver;
try {
- pdomFile.addNames(names);
+ pdomFile.addNames(names, lock);
} finally {
fPathResolver= origResolver;
}
final IIndexFileLocation location = pdomFile.getLocation();
- fEvent.fClearedFiles.remove(location);
- fEvent.fFilesWritten.add(location);
+ if (location != null) {
+ fEvent.fClearedFiles.remove(location);
+ fEvent.fFilesWritten.add(location);
+ }
}
public void clearFile(IIndexFragmentFile file, Collection contextsRemoved)
@@ -171,11 +229,47 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public PDOMFile getFileForASTPath(int linkageID, String astPath) throws CoreException {
if (fPathResolver != null && astPath != null) {
- return getFile(linkageID, fPathResolver.resolveASTPath(astPath));
+ IIndexFileLocation location = fPathResolver.resolveASTPath(astPath);
+ if (location.equals(uncommittedLocation))
+ return fileBeingUpdated != null ? fileBeingUpdated : uncommittedFile;
+ return getFile(linkageID, location);
}
return null;
}
+ @Override
+ public boolean hasLastingDefinition(PDOMBinding binding) throws CoreException {
+ if (fileBeingUpdated == null) {
+ return binding.hasDefinition();
+ }
+ // Definitions in fileBeingUpdated will soon go away, so look for a definition elsewhere.
+ for (PDOMName name = binding.getFirstDefinition(); name != null; name = name.getNextInBinding()) {
+ if (!fileBeingUpdated.getPDOM().equals(name.getPDOM()) ||
+ fileBeingUpdated.getRecord() != name.getFileRecord()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean isCommitted(PDOMName name) throws CoreException {
+ return uncommittedFile == null || !uncommittedFile.getPDOM().equals(name.getPDOM()) ||
+ uncommittedFile.getRecord() != name.getFileRecord();
+ }
+
+ @Override
+ protected boolean isCommitted(PDOMMacro name) throws CoreException {
+ return uncommittedFile == null || !uncommittedFile.getPDOM().equals(name.getPDOM()) ||
+ uncommittedFile.getRecord() != name.getFileRecord();
+ }
+
+ @Override
+ protected boolean isCommitted(PDOMMacroReferenceName name) throws CoreException {
+ return uncommittedFile == null || !uncommittedFile.getPDOM().equals(name.getPDOM()) ||
+ uncommittedFile.getRecord() != name.getFileRecord();
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.index.IWritableIndexFragment#getDatabaseSizeBytes()
*/
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/YieldableIndexLock.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/YieldableIndexLock.java
new file mode 100644
index 00000000000..8e110800675
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/YieldableIndexLock.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Google, 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:
+ * Sergey Prigogin (Google) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.pdom;
+
+import org.eclipse.cdt.internal.core.index.IWritableIndex;
+
+/**
+ * Write lock on the index that can be yielded temporarily to unblock threads that need
+ * read access to the index.
+ * @since 5.2
+ */
+public class YieldableIndexLock {
+ private final IWritableIndex index;
+ private final int readlockCount;
+ private final boolean flushIndex;
+ private long lastLockTime;
+ private long cumulativeLockTime;
+
+ public YieldableIndexLock(IWritableIndex index, int readlockCount, boolean flushIndex) {
+ this.index = index;
+ this.readlockCount = readlockCount;
+ this.flushIndex = flushIndex;
+ }
+
+ /**
+ * Acquires the lock.
+ *
+ * @throws InterruptedException
+ */
+ public void acquire() throws InterruptedException {
+ index.acquireWriteLock(readlockCount);
+ lastLockTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Releases the lock.
+ */
+ public void release() {
+ if (lastLockTime != 0) {
+ index.releaseWriteLock(readlockCount, flushIndex);
+ cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
+ lastLockTime = 0;
+ }
+ }
+
+ /**
+ * Yields the lock temporarily if it was held for YIELD_INTERVAL or more, and somebody is waiting
+ * for a read lock.
+ * @throws InterruptedException
+ */
+ public void yield() throws InterruptedException {
+ if (index.hasWaitingReaders()) {
+ index.releaseWriteLock(readlockCount, false);
+ cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
+ lastLockTime = 0;
+ acquire();
+ }
+ }
+
+ /**
+ * @return Total time the lock was held in milliseconds.
+ */
+ public long getCumulativeLockTime() {
+ return cumulativeLockTime;
+ }
+}
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 fa688906957..ad1fce180b3 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
@@ -9,6 +9,7 @@
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@@ -30,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
+import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
@@ -42,6 +44,7 @@ import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
@@ -115,6 +118,10 @@ public class PDOMFile implements IIndexFragmentFile {
return record;
}
+ public PDOM getPDOM() {
+ return fLinkage.getPDOM();
+ }
+
@Override
public boolean equals(Object obj) {
if (obj == this)
@@ -128,13 +135,116 @@ public class PDOMFile implements IIndexFragmentFile {
@Override
public final int hashCode() {
- return System.identityHashCode(fLinkage.getPDOM()) + (int)(41*record);
+ return System.identityHashCode(fLinkage.getPDOM()) + (int) (41 * record);
}
/**
- * Directly changes this record's internal location string. The format
- * of this string is unspecified in general and is determined by the
- * associated IIndexLocationConverter
+ * Transfers names, macros and includes from another file to this one and deletes the other file.
+ * @param sourceFile the file to transfer the local bindings from.
+ * @throws CoreException
+ */
+ public void replaceContentsFrom(PDOMFile sourceFile) throws CoreException {
+ ICPPUsingDirective[] directives= getUsingDirectives();
+ for (ICPPUsingDirective ud : directives) {
+ if (ud instanceof IPDOMNode) {
+ ((IPDOMNode) ud).delete(null);
+ }
+ }
+ setFirstUsingDirectiveRec(sourceFile.getLastUsingDirectiveRec());
+
+ // Replace the includes
+ PDOMInclude include = getFirstInclude();
+ while (include != null) {
+ PDOMInclude nextInclude = include.getNextInIncludes();
+ IIndexFile includedBy = include.getIncludedBy();
+ if (this.equals(includedBy)) {
+ include.delete();
+ }
+ include = nextInclude;
+ }
+ include = sourceFile.getFirstInclude();
+ setFirstInclude(include);
+ while (include != null) {
+ IIndexFile includedBy = include.getIncludedBy();
+ if (sourceFile.equals(includedBy)) {
+ include.setIncludedBy(this);
+ if (sourceFile.equals(include.getIncludes())) {
+ include.setIncludes(this);
+ }
+ }
+ include = include.getNextInIncludes();
+ }
+
+ // Replace all the macros in this file.
+ PDOMLinkage linkage= getLinkage();
+ PDOMMacro macro = getFirstMacro();
+ while (macro != null) {
+ PDOMMacro nextMacro = macro.getNextMacro();
+ macro.delete(linkage);
+ macro = nextMacro;
+ }
+ macro = sourceFile.getFirstMacro();
+ setFirstMacro(macro);
+ for (; macro != null; macro = macro.getNextMacro()) {
+ macro.setFile(this);
+ }
+
+ // Replace all macro references
+ ArrayList mrefs= new ArrayList();
+ PDOMMacroReferenceName mref = getFirstMacroReference();
+ while (mref != null) {
+ mrefs.add(mref);
+ mref= mref.getNextInFile();
+ }
+ for (PDOMMacroReferenceName m : mrefs) {
+ m.delete();
+ }
+ mref = sourceFile.getFirstMacroReference();
+ setFirstMacroReference(mref);
+ for (; mref != null; mref = mref.getNextInFile()) {
+ mref.setFile(this);
+ }
+
+ // Replace all the names in this file
+ ArrayList names= new ArrayList();
+ PDOMName name = getFirstName();
+ for (; name != null; name= name.getNextInFile()) {
+ names.add(name);
+ linkage.onDeleteName(name);
+ }
+ for (Iterator iterator = names.iterator(); iterator.hasNext();) {
+ name = iterator.next();
+ name.delete();
+ }
+ name = sourceFile.getFirstName();
+ setFirstName(name);
+ for (; name != null; name= name.getNextInFile()) {
+ name.setFile(this);
+ }
+
+ setTimestamp(sourceFile.getTimestamp());
+ setScannerConfigurationHashcode(sourceFile.getScannerConfigurationHashcode());
+
+ sourceFile.delete();
+ }
+
+ /**
+ * This method should not be called on PDOMFile objects that are referenced by the file index.
+ * @param location a new location
+ * @throws CoreException
+ */
+ public void setLocation(IIndexFileLocation location) throws CoreException {
+ String locationString = fLinkage.getPDOM().getLocationConverter().toInternalFormat(location);
+ if (locationString == null)
+ throw new CoreException(CCorePlugin.createStatus(Messages.getString("PDOMFile.toInternalProblem") + //$NON-NLS-1$
+ location.getURI()));
+ setInternalLocation(locationString);
+ }
+
+ /**
+ * Directly changes this record's internal location string. The format of this string is unspecified
+ * in general and is determined by the associated IIndexLocationConverter.
+ * This method should not be called on PDOMFile objects that are referenced by the file index.
* @param internalLocation
* @throws CoreException
*/
@@ -256,7 +366,7 @@ public class PDOMFile implements IIndexFragmentFile {
return fLinkage;
}
- public void addNames(IASTName[][] names) throws CoreException {
+ public void addNames(IASTName[][] names, YieldableIndexLock lock) throws CoreException, InterruptedException {
assert getFirstName() == null;
assert getFirstMacroReference() == null;
final PDOMLinkage linkage= getLinkage();
@@ -265,6 +375,9 @@ public class PDOMFile implements IIndexFragmentFile {
PDOMMacroReferenceName lastMacroName= null;
for (IASTName[] name : names) {
if (name[0] != null) {
+ if (lock != null) {
+ lock.yield();
+ }
PDOMName caller= nameCache.get(name[1]);
IIndexFragmentName fname= createPDOMName(linkage, name[0], caller);
if (fname instanceof PDOMName) {
@@ -340,7 +453,7 @@ public class PDOMFile implements IIndexFragmentFile {
include.delete();
include = nextInclude;
}
- setFirstInclude(include);
+ setFirstInclude(null);
// Delete all the macros in this file
PDOMLinkage linkage= getLinkage();
@@ -381,6 +494,15 @@ public class PDOMFile implements IIndexFragmentFile {
setTimestamp(-1);
}
+ /**
+ * Deletes this file from PDOM. Only uncommitted files can be safely deleted.
+ *
+ * @throws CoreException
+ */
+ public void delete() throws CoreException {
+ fLinkage.getDB().free(record);
+ }
+
public void addIncludesTo(IncludeInformation[] includeInfos) throws CoreException {
assert getFirstInclude() == null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java
index 8ec79306035..28b45654ab8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java
@@ -141,6 +141,11 @@ public class PDOMInclude implements IIndexFragmentInclude {
return rec != 0 ? new PDOMFile(linkage, rec) : null;
}
+ void setIncludes(PDOMFile includedFile) throws CoreException {
+ long rec = includedFile != null ? includedFile.getRecord() : 0;
+ linkage.getDB().putRecPtr(record + INCLUDED_FILE, rec);
+ }
+
/**
* Checks if the name is the same as the end part of the path of the included file.
*/
@@ -166,7 +171,7 @@ public class PDOMInclude implements IIndexFragmentInclude {
return rec != 0 ? new PDOMFile(linkage, rec) : null;
}
- private void setIncludedBy(PDOMFile includedBy) throws CoreException {
+ void setIncludedBy(PDOMFile includedBy) throws CoreException {
long rec = includedBy != null ? includedBy.getRecord() : 0;
linkage.getDB().putRecPtr(record + INCLUDED_BY, rec);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
index a41393de695..a0399058e37 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
@@ -9,6 +9,7 @@
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@@ -116,7 +117,7 @@ public class PDOMMacro implements IIndexMacro, IPDOMBinding, IASTFileLocation {
public PDOM getPDOM() {
return fLinkage.getPDOM();
}
-
+
public long getRecord() {
return fRecord;
}
@@ -269,6 +270,14 @@ public class PDOMMacro implements IIndexMacro, IPDOMBinding, IASTFileLocation {
return filerec != 0 ? new PDOMFile(fLinkage, filerec) : null;
}
+ public long getFileRecord() throws CoreException {
+ return fLinkage.getDB().getRecPtr(fRecord + FILE);
+ }
+
+ void setFile(PDOMFile file) throws CoreException {
+ fLinkage.getDB().putRecPtr(fRecord + FILE, file != null ? file.getRecord() : 0);
+ }
+
public int getEndingLineNumber() {
return 0;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroReferenceName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroReferenceName.java
index 60f4b027f68..ccd4fa9c5d6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroReferenceName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroReferenceName.java
@@ -8,6 +8,7 @@
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@@ -21,6 +22,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
+import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -67,6 +69,10 @@ public final class PDOMMacroReferenceName implements IIndexFragmentName, IASTFil
return record;
}
+ public PDOM getPDOM() {
+ return linkage.getPDOM();
+ }
+
private long getRecField(int offset) throws CoreException {
return linkage.getDB().getRecPtr(record + offset);
}
@@ -110,7 +116,15 @@ public final class PDOMMacroReferenceName implements IIndexFragmentName, IASTFil
long filerec = linkage.getDB().getRecPtr(record + FILE_REC_OFFSET);
return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
}
-
+
+ public long getFileRecord() throws CoreException {
+ return linkage.getDB().getRecPtr(record + FILE_REC_OFFSET);
+ }
+
+ void setFile(PDOMFile file) throws CoreException {
+ linkage.getDB().putRecPtr(record + FILE_REC_OFFSET, file != null ? file.getRecord() : 0);
+ }
+
PDOMMacroReferenceName getNextInFile() throws CoreException {
return getNameField(FILE_NEXT_OFFSET);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
index 5d2a4518274..7bce580de92 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
@@ -8,6 +8,7 @@
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@@ -22,6 +23,7 @@ import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
+import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -121,6 +123,10 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
linkage.getDB().putRecPtr(record + offset, fieldrec);
}
+ public PDOM getPDOM() {
+ return linkage.getPDOM();
+ }
+
public PDOMBinding getBinding() throws CoreException {
long bindingrec = getRecField(BINDING_REC_OFFSET);
return linkage.getBinding(bindingrec);
@@ -162,6 +168,14 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
}
+ public long getFileRecord() throws CoreException {
+ return linkage.getDB().getRecPtr(record + FILE_REC_OFFSET);
+ }
+
+ void setFile(PDOMFile file) throws CoreException {
+ linkage.getDB().putRecPtr(record + FILE_REC_OFFSET, file != null ? file.getRecord() : 0);
+ }
+
public IIndexName getEnclosingDefinition() throws CoreException {
long namerec = getEnclosingDefinitionRecord();
return namerec != 0 ? new PDOMName(linkage, namerec) : null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index 43a932f73e1..15795a7516f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -299,7 +299,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (fromName.isDefinition()) {
return true;
}
- return !pdomBinding.hasDefinition();
+ return !getPDOM().hasLastingDefinition(pdomBinding);
}
return false;
}
@@ -444,8 +444,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (!(method instanceof IProblemBinding)) {
PDOMBinding pdomBinding= adaptBinding(method);
if (pdomBinding == null) {
- createBinding(type, method, fileLocalRec);
- } else if (!pdomBinding.hasDefinition()) {
+ pdomBinding = createBinding(type, method, fileLocalRec);
+ } else if (!getPDOM().hasLastingDefinition(pdomBinding)) {
pdomBinding.update(this, method);
}
}