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:
|
||||
* 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() {
|
||||
|
|
|
@ -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 <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
|
||||
* be used to figure out whether information read from the index is
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <code>true</code> if there are threads waiting for read locks.
|
||||
*/
|
||||
public boolean hasWaitingReaders();
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the last modification to the index.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<PDOMInclude> result = new ArrayList<PDOMInclude>();
|
||||
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()) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<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();
|
||||
IIndexFragmentFile file= index.getWritableFile(linkageID, location);
|
||||
if (file != null) {
|
||||
clearedContexts= new HashSet<IIndexFileLocation>();
|
||||
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<IIndexFileLocation>();
|
||||
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<IIndexFileLocation>();
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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<String, IPDOMLinkageFactory> 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<IIndexFileLocation> 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()
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
* 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<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
|
||||
* @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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue