mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Yielding of index write lock. Bug 287907.
This commit is contained in:
parent
c3c9c83823
commit
1bb19098d3
19 changed files with 587 additions and 79 deletions
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Andrew Ferguson (Symbian) - initial API and implementation
|
* Andrew Ferguson (Symbian) - initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.index.tests;
|
package org.eclipse.cdt.internal.index.tests;
|
||||||
|
|
||||||
|
@ -123,6 +124,11 @@ public class EmptyIndexFragment implements IIndexFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void releaseReadLock() {}
|
public void releaseReadLock() {}
|
||||||
|
|
||||||
|
public boolean hasWaitingReaders() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void resetCacheCounters() {}
|
public void resetCacheCounters() {}
|
||||||
|
|
||||||
public IIndexFragmentFileSet createFileSet() {
|
public IIndexFragmentFileSet createFileSet() {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
* Bryan Wilkinson (QNX)
|
* Bryan Wilkinson (QNX)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.index;
|
package org.eclipse.cdt.core.index;
|
||||||
|
|
||||||
|
@ -91,6 +92,12 @@ public interface IIndex {
|
||||||
*/
|
*/
|
||||||
public void releaseReadLock();
|
public void releaseReadLock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <code>true</code> 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
|
* 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
|
* be used to figure out whether information read from the index is
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
* Bryan Wilkinson (QNX)
|
* Bryan Wilkinson (QNX)
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.index;
|
package org.eclipse.cdt.internal.core.index;
|
||||||
|
|
||||||
|
@ -355,6 +356,15 @@ public class CIndex implements IIndex {
|
||||||
return fReadLock;
|
return fReadLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasWaitingReaders() {
|
||||||
|
for (int i= 0; i < fFragments.length; i++) {
|
||||||
|
if (fFragments[i].hasWaitingReaders()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public long getLastWriteAccess() {
|
public long getLastWriteAccess() {
|
||||||
long result= 0;
|
long result= 0;
|
||||||
for (int i = 0; i < fFragments.length; i++) {
|
for (int i = 0; i < fFragments.length; i++) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Bryan Wilkinson (QNX)
|
* Bryan Wilkinson (QNX)
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.core.index;
|
package org.eclipse.cdt.internal.core.index;
|
||||||
|
@ -85,6 +86,10 @@ final public class EmptyCIndex implements IIndex {
|
||||||
public void releaseReadLock() {
|
public void releaseReadLock() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasWaitingReaders() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public long getLastWriteAccess() {
|
public long getLastWriteAccess() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Bryan Wilkinson (QNX)
|
* Bryan Wilkinson (QNX)
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.index;
|
package org.eclipse.cdt.internal.core.index;
|
||||||
|
|
||||||
|
@ -190,6 +191,11 @@ public interface IIndexFragment {
|
||||||
*/
|
*/
|
||||||
void releaseReadLock();
|
void releaseReadLock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <code>true</code> if there are threads waiting for read locks.
|
||||||
|
*/
|
||||||
|
public boolean hasWaitingReaders();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the timestamp of the last modification to the index.
|
* Returns the timestamp of the last modification to the index.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.core.index;
|
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.IIndexFile;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||||
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
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.
|
* 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.
|
* Adds content to the given file.
|
||||||
|
@ -73,7 +96,7 @@ public interface IWritableIndex extends IIndex {
|
||||||
void setFileContent(IIndexFragmentFile sourceFile,
|
void setFileContent(IIndexFragmentFile sourceFile,
|
||||||
int linkageID, IncludeInformation[] includes,
|
int linkageID, IncludeInformation[] includes,
|
||||||
IASTPreprocessorStatement[] macros, IASTName[][] names,
|
IASTPreprocessorStatement[] macros, IASTName[][] names,
|
||||||
ASTFilePathResolver resolver) throws CoreException;
|
ASTFilePathResolver resolver, YieldableIndexLock lock) throws CoreException, InterruptedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the entire index.
|
* Clears the entire index.
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
*******************************************************************************/
|
* Sergey Prigogin (Google)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.core.index;
|
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.core.index.IIndexFileLocation;
|
||||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
||||||
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
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.
|
* 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
|
* @param fileLocation an IIndexFileLocation representing the location of the file.
|
||||||
* @return the existing IIndexFragmentFile for this location, or a newly created one
|
* @return the existing IIndexFragmentFile for this location, or a newly created one.
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) 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,
|
IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
|
||||||
IncludeInformation[] includes,
|
|
||||||
IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver) 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.
|
* Acquires a write lock, while giving up a certain amount of read locks.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.core.index;
|
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.IIndexFile;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||||
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
public class WritableCIndex extends CIndex implements IWritableIndex {
|
public class WritableCIndex extends CIndex implements IWritableIndex {
|
||||||
|
@ -50,17 +52,29 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
||||||
return fWritableFragment.getFiles(location);
|
return fWritableFragment.getFiles(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException {
|
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||||
return fWritableFragment.addFile(linkageID, fileLocation);
|
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) {
|
private boolean isWritableFragment(IIndexFragment frag) {
|
||||||
return frag == fWritableFragment;
|
return frag == fWritableFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFileContent(IIndexFragmentFile file, int linkageID,
|
public void setFileContent(IIndexFragmentFile file, int linkageID, IncludeInformation[] includes,
|
||||||
IncludeInformation[] includes,
|
IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver,
|
||||||
IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver) throws CoreException {
|
YieldableIndexLock lock) throws CoreException, InterruptedException {
|
||||||
IIndexFragment indexFragment = file.getIndexFragment();
|
IIndexFragment indexFragment = file.getIndexFragment();
|
||||||
if (!isWritableFragment(indexFragment)) {
|
if (!isWritableFragment(indexFragment)) {
|
||||||
assert false : "Attempt to update file of read-only fragment"; //$NON-NLS-1$
|
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);
|
ii.fTargetFile= addFile(linkageID, ii.fLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names, resolver);
|
((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names, resolver, lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Doug Schaefer (QNX) - Initial API and implementation
|
* Doug Schaefer (QNX) - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* IBM Corporation
|
* IBM Corporation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom;
|
package org.eclipse.cdt.internal.core.pdom;
|
||||||
|
|
||||||
|
@ -96,6 +97,7 @@ import org.eclipse.core.runtime.Status;
|
||||||
public class PDOM extends PlatformObject implements IPDOM {
|
public class PDOM extends PlatformObject implements IPDOM {
|
||||||
private static final int BLOCKED_WRITE_LOCK_OUTPUT_INTERVAL = 30000;
|
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_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.
|
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);
|
PDOMLinkage pdomLinkage= fLinkageIDCache.get(linkageID);
|
||||||
if (pdomLinkage == null) {
|
if (pdomLinkage == null) {
|
||||||
final String linkageName= Linkage.getLinkageName(linkageID);
|
final String linkageName= Linkage.getLinkageName(linkageID);
|
||||||
|
@ -766,6 +768,7 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
private long timeWriteLockAcquired;
|
private long timeWriteLockAcquired;
|
||||||
|
|
||||||
public void acquireReadLock() throws InterruptedException {
|
public void acquireReadLock() throws InterruptedException {
|
||||||
|
long t = sDEBUG_LOCKS ? System.nanoTime() : 0;
|
||||||
synchronized (mutex) {
|
synchronized (mutex) {
|
||||||
++waitingReaders;
|
++waitingReaders;
|
||||||
try {
|
try {
|
||||||
|
@ -778,12 +781,15 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
db.setLocked(true);
|
db.setLocked(true);
|
||||||
|
|
||||||
if (sDEBUG_LOCKS) {
|
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);
|
incReadLock(fLockDebugging);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void releaseReadLock() {
|
public void releaseReadLock() {
|
||||||
boolean clearCache= false;
|
boolean clearCache= false;
|
||||||
synchronized (mutex) {
|
synchronized (mutex) {
|
||||||
|
@ -884,6 +890,12 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
fireChange(event);
|
fireChange(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasWaitingReaders() {
|
||||||
|
synchronized (mutex) {
|
||||||
|
return waitingReaders > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long getLastWriteAccess() {
|
public long getLastWriteAccess() {
|
||||||
return lastWriteAccess;
|
return lastWriteAccess;
|
||||||
}
|
}
|
||||||
|
@ -957,17 +969,23 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
PDOMName name;
|
PDOMName name;
|
||||||
if ((options & FIND_DECLARATIONS) != 0) {
|
if ((options & FIND_DECLARATIONS) != 0) {
|
||||||
for (name= pdomBinding.getFirstDeclaration(); name != null; name= name.getNextInBinding()) {
|
for (name= pdomBinding.getFirstDeclaration(); name != null; name= name.getNextInBinding()) {
|
||||||
names.add(name);
|
if (isCommitted(name)) {
|
||||||
|
names.add(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((options & FIND_DEFINITIONS) != 0) {
|
if ((options & FIND_DEFINITIONS) != 0) {
|
||||||
for (name = pdomBinding.getFirstDefinition(); name != null; name= name.getNextInBinding()) {
|
for (name = pdomBinding.getFirstDefinition(); name != null; name= name.getNextInBinding()) {
|
||||||
names.add(name);
|
if (isCommitted(name)) {
|
||||||
|
names.add(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((options & FIND_REFERENCES) != 0) {
|
if ((options & FIND_REFERENCES) != 0) {
|
||||||
for (name = pdomBinding.getFirstReference(); name != null; name= name.getNextInBinding()) {
|
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) {
|
if ((options & FIND_DEFINITIONS) != 0) {
|
||||||
for (PDOMMacro macro= container.getFirstDefinition(); macro != null; macro= macro.getNextInContainer()) {
|
for (PDOMMacro macro= container.getFirstDefinition(); macro != null; macro= macro.getNextInContainer()) {
|
||||||
final IIndexFragmentName name = macro.getDefinition();
|
final IIndexFragmentName name = macro.getDefinition();
|
||||||
if (name != null) {
|
if (name != null && isCommitted(macro)) {
|
||||||
names.add(name);
|
names.add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((options & FIND_REFERENCES) != 0) {
|
if ((options & FIND_REFERENCES) != 0) {
|
||||||
for (PDOMMacroReferenceName name = container.getFirstReference(); name != null; name= name.getNextInContainer()) {
|
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 {
|
public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) throws CoreException {
|
||||||
PDOMFile pdomFile= adaptFile(file);
|
PDOMFile pdomFile= adaptFile(file);
|
||||||
if (pdomFile != null) {
|
if (pdomFile != null) {
|
||||||
List<PDOMInclude> result = new ArrayList<PDOMInclude>();
|
List<PDOMInclude> result = new ArrayList<PDOMInclude>();
|
||||||
for (PDOMInclude i= pdomFile.getFirstIncludedBy(); i != null; i= i.getNextInIncludedBy()) {
|
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()]);
|
return result.toArray(new PDOMInclude[result.size()]);
|
||||||
}
|
}
|
||||||
|
@ -1198,6 +1232,10 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
return new StringBuilder(name.length + 2).append((char) (record >> 16)).append((char) record).append(name).toString();
|
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 {
|
private PDOMBinding[] getCrossLanguageBindings(IBinding binding) throws CoreException {
|
||||||
switch(binding.getLinkage().getLinkageID()) {
|
switch(binding.getLinkage().getLinkageID()) {
|
||||||
case ILinkage.C_LINKAGE_ID:
|
case ILinkage.C_LINKAGE_ID:
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom;
|
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() {
|
public synchronized void resetCacheCounters() {
|
||||||
if (fDelegate != null)
|
if (fDelegate != null)
|
||||||
fDelegate.resetCacheCounters();
|
fDelegate.resetCacheCounters();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* IBM Corporation
|
* IBM Corporation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom;
|
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.ICPPTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
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.core.parser.IProblem;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
|
@ -68,6 +70,9 @@ import org.eclipse.osgi.util.NLS;
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
abstract public class PDOMWriter {
|
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_ALL_REFERENCES= -1;
|
||||||
public static int SKIP_TYPE_REFERENCES= 1;
|
public static int SKIP_TYPE_REFERENCES= 1;
|
||||||
public static int SKIP_MACRO_REFERENCES= 2;
|
public static int SKIP_MACRO_REFERENCES= 2;
|
||||||
|
@ -200,11 +205,11 @@ abstract public class PDOMWriter {
|
||||||
if (fShowActivity) {
|
if (fShowActivity) {
|
||||||
trace("Indexer: adding " + ifl.getURI()); //$NON-NLS-1$
|
trace("Indexer: adding " + ifl.getURI()); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
index.acquireWriteLock(readlockCount);
|
|
||||||
long start= System.currentTimeMillis();
|
|
||||||
Throwable th= null;
|
Throwable th= null;
|
||||||
|
YieldableIndexLock lock = new YieldableIndexLock(index, readlockCount, flushIndex);
|
||||||
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
storeFileInIndex(index, ifl, symbolMap, linkageID, configHash, contextIncludes);
|
storeFileInIndex(index, ifl, symbolMap, linkageID, configHash, contextIncludes, lock);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
th= e;
|
th= e;
|
||||||
} catch (PDOMNotImplementedError e) {
|
} catch (PDOMNotImplementedError e) {
|
||||||
|
@ -214,7 +219,7 @@ abstract public class PDOMWriter {
|
||||||
} catch (AssertionError e) {
|
} catch (AssertionError e) {
|
||||||
th= e;
|
th= e;
|
||||||
} finally {
|
} finally {
|
||||||
index.releaseWriteLock(readlockCount, flushIndex);
|
lock.release();
|
||||||
}
|
}
|
||||||
if (th != null) {
|
if (th != null) {
|
||||||
stati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
|
stati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
|
||||||
|
@ -223,7 +228,7 @@ abstract public class PDOMWriter {
|
||||||
if (i < ifls.length - 1) {
|
if (i < ifls.length - 1) {
|
||||||
updateFileCount(0, 0, 1); // update header count
|
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,
|
private IIndexFragmentFile storeFileInIndex(IWritableIndex index, IIndexFileLocation location,
|
||||||
Map<IIndexFileLocation, Symbols> symbolMap, int linkageID, int configHash,
|
Map<IIndexFileLocation, Symbols> symbolMap, int linkageID, int configHash,
|
||||||
Set<IASTPreprocessorIncludeStatement> contextIncludes) throws CoreException {
|
Set<IASTPreprocessorIncludeStatement> contextIncludes, YieldableIndexLock lock)
|
||||||
|
throws CoreException, InterruptedException {
|
||||||
Set<IIndexFileLocation> clearedContexts= Collections.emptySet();
|
Set<IIndexFileLocation> clearedContexts= Collections.emptySet();
|
||||||
IIndexFragmentFile file= index.getWritableFile(linkageID, location);
|
IIndexFragmentFile file;
|
||||||
if (file != null) {
|
long timestamp = fResolver.getLastModified(location);
|
||||||
clearedContexts= new HashSet<IIndexFileLocation>();
|
if (SEMI_TRANSACTIONAL_UPDATES) {
|
||||||
index.clearFile(file, clearedContexts);
|
// 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<IIndexFileLocation>();
|
||||||
|
for (IIndexInclude include : includedBy) {
|
||||||
|
clearedContexts.add(include.getIncludedByLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file= index.addUncommittedFile(linkageID, location);
|
||||||
} else {
|
} else {
|
||||||
file= index.addFile(linkageID, location);
|
file= index.getWritableFile(linkageID, location);
|
||||||
|
if (file != null) {
|
||||||
|
clearedContexts= new HashSet<IIndexFileLocation>();
|
||||||
|
index.clearFile(file, clearedContexts);
|
||||||
|
} else {
|
||||||
|
file= index.addFile(linkageID, location);
|
||||||
|
}
|
||||||
|
file.setTimestamp(timestamp);
|
||||||
}
|
}
|
||||||
file.setTimestamp(fResolver.getLastModified(location));
|
try {
|
||||||
file.setScannerConfigurationHashcode(configHash);
|
file.setScannerConfigurationHashcode(configHash);
|
||||||
Symbols lists= symbolMap.get(location);
|
Symbols lists= symbolMap.get(location);
|
||||||
if (lists != null) {
|
if (lists != null) {
|
||||||
IASTPreprocessorStatement[] macros= lists.fMacros.toArray(new IASTPreprocessorStatement[lists.fMacros.size()]);
|
IASTPreprocessorStatement[] macros= lists.fMacros.toArray(new IASTPreprocessorStatement[lists.fMacros.size()]);
|
||||||
IASTName[][] names= lists.fNames.toArray(new IASTName[lists.fNames.size()][]);
|
IASTName[][] names= lists.fNames.toArray(new IASTName[lists.fNames.size()][]);
|
||||||
for (IASTName[] name2 : names) {
|
for (IASTName[] name2 : names) {
|
||||||
final IASTName name= name2[0];
|
final IASTName name= name2[0];
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
ASTInternal.setFullyResolved(name.getBinding(), true);
|
ASTInternal.setFullyResolved(name.getBinding(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
IncludeInformation[] includeInfos= new IncludeInformation[lists.fIncludes.size()];
|
IncludeInformation[] includeInfos= new IncludeInformation[lists.fIncludes.size()];
|
||||||
for (int i= 0; i < lists.fIncludes.size(); i++) {
|
for (int i= 0; i < lists.fIncludes.size(); i++) {
|
||||||
final IASTPreprocessorIncludeStatement include = lists.fIncludes.get(i);
|
final IASTPreprocessorIncludeStatement include = lists.fIncludes.get(i);
|
||||||
final IncludeInformation info= includeInfos[i]= new IncludeInformation();
|
final IncludeInformation info= includeInfos[i]= new IncludeInformation();
|
||||||
info.fStatement= include;
|
info.fStatement= include;
|
||||||
if (include.isResolved()) {
|
if (include.isResolved()) {
|
||||||
info.fLocation= fResolver.resolveASTPath(include.getPath());
|
info.fLocation= fResolver.resolveASTPath(include.getPath());
|
||||||
info.fIsContext= include.isActive() &&
|
info.fIsContext= include.isActive() &&
|
||||||
(contextIncludes.contains(include) || clearedContexts.contains(info.fLocation));
|
(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;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom;
|
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.IIndexFragmentFile;
|
||||||
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
||||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
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.ChunkCache;
|
||||||
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
|
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.db.IBTreeVisitor;
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
|
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.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;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
private boolean fClearedBecauseOfVersionMismatch= false;
|
private boolean fClearedBecauseOfVersionMismatch= false;
|
||||||
private boolean fCreatedFromScratch= false;
|
private boolean fCreatedFromScratch= false;
|
||||||
private ASTFilePathResolver fPathResolver;
|
private ASTFilePathResolver fPathResolver;
|
||||||
|
private PDOMFile fileBeingUpdated;
|
||||||
|
private PDOMFile uncommittedFile;
|
||||||
|
private IIndexFileLocation uncommittedLocation;
|
||||||
|
|
||||||
public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter,
|
public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter,
|
||||||
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
|
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
|
||||||
|
@ -53,11 +63,57 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||||
|
if (uncommittedLocation != null && uncommittedLocation.equals(location)) {
|
||||||
|
return uncommittedFile;
|
||||||
|
}
|
||||||
return super.addFile(linkageID, location);
|
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,
|
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;
|
assert sourceFile.getIndexFragment() == this;
|
||||||
|
|
||||||
PDOMFile pdomFile = (PDOMFile) sourceFile;
|
PDOMFile pdomFile = (PDOMFile) sourceFile;
|
||||||
|
@ -66,14 +122,16 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
final ASTFilePathResolver origResolver= fPathResolver;
|
final ASTFilePathResolver origResolver= fPathResolver;
|
||||||
fPathResolver= pathResolver;
|
fPathResolver= pathResolver;
|
||||||
try {
|
try {
|
||||||
pdomFile.addNames(names);
|
pdomFile.addNames(names, lock);
|
||||||
} finally {
|
} finally {
|
||||||
fPathResolver= origResolver;
|
fPathResolver= origResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
final IIndexFileLocation location = pdomFile.getLocation();
|
final IIndexFileLocation location = pdomFile.getLocation();
|
||||||
fEvent.fClearedFiles.remove(location);
|
if (location != null) {
|
||||||
fEvent.fFilesWritten.add(location);
|
fEvent.fClearedFiles.remove(location);
|
||||||
|
fEvent.fFilesWritten.add(location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved)
|
public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved)
|
||||||
|
@ -171,11 +229,47 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
|
|
||||||
public PDOMFile getFileForASTPath(int linkageID, String astPath) throws CoreException {
|
public PDOMFile getFileForASTPath(int linkageID, String astPath) throws CoreException {
|
||||||
if (fPathResolver != null && astPath != null) {
|
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;
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.index.IWritableIndexFragment#getDatabaseSizeBytes()
|
* @see org.eclipse.cdt.internal.core.index.IWritableIndexFragment#getDatabaseSizeBytes()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
* QNX - Initial API and implementation
|
* QNX - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom.dom;
|
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.IMacroBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
|
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.IIndexFileLocation;
|
||||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||||
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
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.IndexFileLocation;
|
||||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
||||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
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.BTree;
|
||||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
|
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
|
||||||
|
@ -115,6 +118,10 @@ public class PDOMFile implements IIndexFragmentFile {
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PDOM getPDOM() {
|
||||||
|
return fLinkage.getPDOM();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj == this)
|
if (obj == this)
|
||||||
|
@ -128,13 +135,116 @@ public class PDOMFile implements IIndexFragmentFile {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int hashCode() {
|
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
|
* Transfers names, macros and includes from another file to this one and deletes the other file.
|
||||||
* of this string is unspecified in general and is determined by the
|
* @param sourceFile the file to transfer the local bindings from.
|
||||||
* associated IIndexLocationConverter
|
* @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<PDOMMacroReferenceName> mrefs= new ArrayList<PDOMMacroReferenceName>();
|
||||||
|
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<PDOMName> names= new ArrayList<PDOMName>();
|
||||||
|
PDOMName name = getFirstName();
|
||||||
|
for (; name != null; name= name.getNextInFile()) {
|
||||||
|
names.add(name);
|
||||||
|
linkage.onDeleteName(name);
|
||||||
|
}
|
||||||
|
for (Iterator<PDOMName> 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
|
* @param internalLocation
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
|
@ -256,7 +366,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
||||||
return fLinkage;
|
return fLinkage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNames(IASTName[][] names) throws CoreException {
|
public void addNames(IASTName[][] names, YieldableIndexLock lock) throws CoreException, InterruptedException {
|
||||||
assert getFirstName() == null;
|
assert getFirstName() == null;
|
||||||
assert getFirstMacroReference() == null;
|
assert getFirstMacroReference() == null;
|
||||||
final PDOMLinkage linkage= getLinkage();
|
final PDOMLinkage linkage= getLinkage();
|
||||||
|
@ -265,6 +375,9 @@ public class PDOMFile implements IIndexFragmentFile {
|
||||||
PDOMMacroReferenceName lastMacroName= null;
|
PDOMMacroReferenceName lastMacroName= null;
|
||||||
for (IASTName[] name : names) {
|
for (IASTName[] name : names) {
|
||||||
if (name[0] != null) {
|
if (name[0] != null) {
|
||||||
|
if (lock != null) {
|
||||||
|
lock.yield();
|
||||||
|
}
|
||||||
PDOMName caller= nameCache.get(name[1]);
|
PDOMName caller= nameCache.get(name[1]);
|
||||||
IIndexFragmentName fname= createPDOMName(linkage, name[0], caller);
|
IIndexFragmentName fname= createPDOMName(linkage, name[0], caller);
|
||||||
if (fname instanceof PDOMName) {
|
if (fname instanceof PDOMName) {
|
||||||
|
@ -340,7 +453,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
||||||
include.delete();
|
include.delete();
|
||||||
include = nextInclude;
|
include = nextInclude;
|
||||||
}
|
}
|
||||||
setFirstInclude(include);
|
setFirstInclude(null);
|
||||||
|
|
||||||
// Delete all the macros in this file
|
// Delete all the macros in this file
|
||||||
PDOMLinkage linkage= getLinkage();
|
PDOMLinkage linkage= getLinkage();
|
||||||
|
@ -381,6 +494,15 @@ public class PDOMFile implements IIndexFragmentFile {
|
||||||
setTimestamp(-1);
|
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 {
|
public void addIncludesTo(IncludeInformation[] includeInfos) throws CoreException {
|
||||||
assert getFirstInclude() == null;
|
assert getFirstInclude() == null;
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,11 @@ public class PDOMInclude implements IIndexFragmentInclude {
|
||||||
return rec != 0 ? new PDOMFile(linkage, rec) : null;
|
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.
|
* 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;
|
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;
|
long rec = includedBy != null ? includedBy.getRecord() : 0;
|
||||||
linkage.getDB().putRecPtr(record + INCLUDED_BY, rec);
|
linkage.getDB().putRecPtr(record + INCLUDED_BY, rec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* QNX - Initial API and implementation
|
* QNX - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom.dom;
|
package org.eclipse.cdt.internal.core.pdom.dom;
|
||||||
|
|
||||||
|
@ -269,6 +270,14 @@ public class PDOMMacro implements IIndexMacro, IPDOMBinding, IASTFileLocation {
|
||||||
return filerec != 0 ? new PDOMFile(fLinkage, filerec) : null;
|
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() {
|
public int getEndingLineNumber() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX - Initial API and implementation
|
* QNX - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom.dom;
|
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.IIndexFragment;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
|
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
|
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.cdt.internal.core.pdom.db.Database;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
@ -67,6 +69,10 @@ public final class PDOMMacroReferenceName implements IIndexFragmentName, IASTFil
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PDOM getPDOM() {
|
||||||
|
return linkage.getPDOM();
|
||||||
|
}
|
||||||
|
|
||||||
private long getRecField(int offset) throws CoreException {
|
private long getRecField(int offset) throws CoreException {
|
||||||
return linkage.getDB().getRecPtr(record + offset);
|
return linkage.getDB().getRecPtr(record + offset);
|
||||||
}
|
}
|
||||||
|
@ -111,6 +117,14 @@ public final class PDOMMacroReferenceName implements IIndexFragmentName, IASTFil
|
||||||
return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
|
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 {
|
PDOMMacroReferenceName getNextInFile() throws CoreException {
|
||||||
return getNameField(FILE_NEXT_OFFSET);
|
return getNameField(FILE_NEXT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX - Initial API and implementation
|
* QNX - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom.dom;
|
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.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
|
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.cdt.internal.core.pdom.db.Database;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
@ -121,6 +123,10 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
|
||||||
linkage.getDB().putRecPtr(record + offset, fieldrec);
|
linkage.getDB().putRecPtr(record + offset, fieldrec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PDOM getPDOM() {
|
||||||
|
return linkage.getPDOM();
|
||||||
|
}
|
||||||
|
|
||||||
public PDOMBinding getBinding() throws CoreException {
|
public PDOMBinding getBinding() throws CoreException {
|
||||||
long bindingrec = getRecField(BINDING_REC_OFFSET);
|
long bindingrec = getRecField(BINDING_REC_OFFSET);
|
||||||
return linkage.getBinding(bindingrec);
|
return linkage.getBinding(bindingrec);
|
||||||
|
@ -162,6 +168,14 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
|
||||||
return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
|
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 {
|
public IIndexName getEnclosingDefinition() throws CoreException {
|
||||||
long namerec = getEnclosingDefinitionRecord();
|
long namerec = getEnclosingDefinitionRecord();
|
||||||
return namerec != 0 ? new PDOMName(linkage, namerec) : null;
|
return namerec != 0 ? new PDOMName(linkage, namerec) : null;
|
||||||
|
|
|
@ -299,7 +299,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
if (fromName.isDefinition()) {
|
if (fromName.isDefinition()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return !pdomBinding.hasDefinition();
|
return !getPDOM().hasLastingDefinition(pdomBinding);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -444,8 +444,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
if (!(method instanceof IProblemBinding)) {
|
if (!(method instanceof IProblemBinding)) {
|
||||||
PDOMBinding pdomBinding= adaptBinding(method);
|
PDOMBinding pdomBinding= adaptBinding(method);
|
||||||
if (pdomBinding == null) {
|
if (pdomBinding == null) {
|
||||||
createBinding(type, method, fileLocalRec);
|
pdomBinding = createBinding(type, method, fileLocalRec);
|
||||||
} else if (!pdomBinding.hasDefinition()) {
|
} else if (!getPDOM().hasLastingDefinition(pdomBinding)) {
|
||||||
pdomBinding.update(this, method);
|
pdomBinding.update(this, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue