Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 287907 | Differences between
and this patch

Collapse All | Expand All

(-)parser/org/eclipse/cdt/core/index/IIndex.java (+7 lines)
Lines 9-14 Link Here
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Andrew Ferguson (Symbian)
10
 *    Andrew Ferguson (Symbian)
11
 *    Bryan Wilkinson (QNX)
11
 *    Bryan Wilkinson (QNX)
12
 *    Sergey Prigogin (Google)
12
 *******************************************************************************/ 
13
 *******************************************************************************/ 
13
package org.eclipse.cdt.core.index;
14
package org.eclipse.cdt.core.index;
14
15
Lines 92-97 Link Here
92
	public void releaseReadLock();
93
	public void releaseReadLock();
93
	
94
	
94
	/**
95
	/**
96
	 * @return <code>true</code> if there are threads waiting for read locks.
97
	 * @since 5.2
98
	 */
99
	public boolean hasWaitingReaders();
100
101
	/**
95
	 * Returns a timestamp of when the index was last written to. This can
102
	 * Returns a timestamp of when the index was last written to. This can
96
	 * be used to figure out whether information read from the index is 
103
	 * be used to figure out whether information read from the index is 
97
	 * still reliable or not.
104
	 * still reliable or not.
(-)parser/org/eclipse/cdt/internal/core/index/CIndex.java (+10 lines)
Lines 10-15 Link Here
10
 *    Bryan Wilkinson (QNX)
10
 *    Bryan Wilkinson (QNX)
11
 *    Andrew Ferguson (Symbian)
11
 *    Andrew Ferguson (Symbian)
12
 *    Anton Leherbauer (Wind River Systems)
12
 *    Anton Leherbauer (Wind River Systems)
13
 *    Sergey Prigogin (Google)
13
 *******************************************************************************/ 
14
 *******************************************************************************/ 
14
package org.eclipse.cdt.internal.core.index;
15
package org.eclipse.cdt.internal.core.index;
15
16
Lines 355-360 Link Here
355
		return fReadLock;
356
		return fReadLock;
356
	}
357
	}
357
358
359
	public boolean hasWaitingReaders() {
360
		for (int i= 0; i < fFragments.length; i++) {
361
			if (fFragments[i].hasWaitingReaders()) {
362
				return true;
363
			}
364
		}
365
		return false;
366
	}
367
358
	public long getLastWriteAccess() {
368
	public long getLastWriteAccess() {
359
		long result= 0;
369
		long result= 0;
360
		for (int i = 0; i < fFragments.length; i++) {
370
		for (int i = 0; i < fFragments.length; i++) {
(-)parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java (+5 lines)
Lines 9-14 Link Here
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Bryan Wilkinson (QNX)
10
 *    Bryan Wilkinson (QNX)
11
 *    Andrew Ferguson (Symbian)
11
 *    Andrew Ferguson (Symbian)
12
 *    Sergey Prigogin (Google)
12
 *******************************************************************************/ 
13
 *******************************************************************************/ 
13
14
14
package org.eclipse.cdt.internal.core.index;
15
package org.eclipse.cdt.internal.core.index;
Lines 85-90 Link Here
85
	public void releaseReadLock() {
86
	public void releaseReadLock() {
86
	}
87
	}
87
88
89
	public boolean hasWaitingReaders() {
90
		return false;
91
	}
92
88
	public long getLastWriteAccess() {
93
	public long getLastWriteAccess() {
89
		return 0;
94
		return 0;
90
	}
95
	}
(-)parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java (+6 lines)
Lines 9-14 Link Here
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Bryan Wilkinson (QNX)
10
 *    Bryan Wilkinson (QNX)
11
 *    Andrew Ferguson (Symbian)
11
 *    Andrew Ferguson (Symbian)
12
 *    Sergey Prigogin (Google)
12
 *******************************************************************************/ 
13
 *******************************************************************************/ 
13
package org.eclipse.cdt.internal.core.index;
14
package org.eclipse.cdt.internal.core.index;
14
15
Lines 191-196 Link Here
191
	void releaseReadLock();
192
	void releaseReadLock();
192
	
193
	
193
	/**
194
	/**
195
	 * @return <code>true</code> if there are threads waiting for read locks.
196
	 */
197
	public boolean hasWaitingReaders();
198
199
	/**
194
	 * Returns the timestamp of the last modification to the index.
200
	 * Returns the timestamp of the last modification to the index.
195
	 */
201
	 */
196
	long getLastWriteAccess();
202
	long getLastWriteAccess();
(-)parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java (-2 / +25 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Andrew Ferguson (Symbian)
10
 *    Andrew Ferguson (Symbian)
11
 *    Sergey Prigogin (Google)
11
 *******************************************************************************/ 
12
 *******************************************************************************/ 
12
13
13
package org.eclipse.cdt.internal.core.index;
14
package org.eclipse.cdt.internal.core.index;
Lines 21-26 Link Here
21
import org.eclipse.cdt.core.index.IIndexFile;
22
import org.eclipse.cdt.core.index.IIndexFile;
22
import org.eclipse.cdt.core.index.IIndexFileLocation;
23
import org.eclipse.cdt.core.index.IIndexFileLocation;
23
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
24
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
25
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
24
import org.eclipse.core.runtime.CoreException;
26
import org.eclipse.core.runtime.CoreException;
25
27
26
/**
28
/**
Lines 65-71 Link Here
65
	/**
67
	/**
66
	 * Creates a file object for the given location or returns an existing one.
68
	 * Creates a file object for the given location or returns an existing one.
67
	 */
69
	 */
68
	IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
70
	IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException;
71
72
	/**
73
	 * Creates a uncommitted file object for the given location.
74
	 */
75
	IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException;
76
77
	/**
78
	 * Makes an uncommitted file that was created earlier by calling
79
	 * {@link #addUncommittedFile(int, IIndexFileLocation)} method visible in the index.
80
	 *
81
	 * @return The file that was updated.
82
	 * @throws CoreException
83
	 */
84
	IIndexFragmentFile commitUncommittedFile() throws CoreException;
85
86
	/**
87
	 * Removes an uncommitted file if there is one. Used to recover from a failed index update.
88
	 *  
89
	 * @throws CoreException
90
	 */
91
	void clearUncommittedFile() throws CoreException;
69
92
70
	/**
93
	/**
71
	 * Adds content to the given file.
94
	 * Adds content to the given file.
Lines 73-79 Link Here
73
	void setFileContent(IIndexFragmentFile sourceFile, 
96
	void setFileContent(IIndexFragmentFile sourceFile, 
74
			int linkageID, IncludeInformation[] includes, 
97
			int linkageID, IncludeInformation[] includes, 
75
			IASTPreprocessorStatement[] macros, IASTName[][] names,
98
			IASTPreprocessorStatement[] macros, IASTName[][] names,
76
			ASTFilePathResolver resolver) throws CoreException;
99
			ASTFilePathResolver resolver, YieldableIndexLock lock) throws CoreException, InterruptedException;
77
100
78
	/**
101
	/**
79
	 * Clears the entire index.
102
	 * Clears the entire index.
(-)parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java (-7 / +34 lines)
Lines 8-14 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Andrew Ferguson (Symbian)
10
 *    Andrew Ferguson (Symbian)
11
 *******************************************************************************/ 
11
 *    Sergey Prigogin (Google)
12
******************************************************************************/ 
12
13
13
package org.eclipse.cdt.internal.core.index;
14
package org.eclipse.cdt.internal.core.index;
14
15
Lines 19-24 Link Here
19
import org.eclipse.cdt.core.index.IIndexFileLocation;
20
import org.eclipse.cdt.core.index.IIndexFileLocation;
20
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
21
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
21
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
22
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
23
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
22
import org.eclipse.core.runtime.CoreException;
24
import org.eclipse.core.runtime.CoreException;
23
25
24
/**
26
/**
Lines 41-58 Link Here
41
43
42
	/**
44
	/**
43
	 * Creates a file object for the given location and linkage or returns an existing one.
45
	 * Creates a file object for the given location and linkage or returns an existing one.
44
	 * @param fileLocation an IIndexFileLocation representing the location of the file
46
	 * @param fileLocation an IIndexFileLocation representing the location of the file.
45
	 * @return the existing IIndexFragmentFile for this location, or a newly created one 
47
	 * @return the existing IIndexFragmentFile for this location, or a newly created one. 
46
	 * @throws CoreException
48
	 * @throws CoreException
47
	 */
49
	 */
48
	IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
50
	IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
49
51
50
	/**
52
	/**
51
	 * Adds an include to the given file.
53
	 * Creates a file object for the given location and linkage. The created file object is not added to
54
	 * the file index.
55
	 * @param fileLocation an IIndexFileLocation representing the location of the file.
56
	 * @return a newly created IIndexFragmentFile. 
57
	 * @throws CoreException
58
	 */
59
	IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
60
61
	/**
62
	 * Makes an uncommitted file that was created earlier by calling
63
	 * {@link #addUncommittedFile(int, IIndexFileLocation)} method visible in the index.
64
     *
65
	 * @return The file that was updated.
66
	 * @throws CoreException
67
	 */
68
	IIndexFragmentFile commitUncommittedFile() throws CoreException;
69
70
	/**
71
	 * Removes an uncommitted file if there is one. Used to recover from a failed index update.
72
	 *  
73
	 * @throws CoreException
74
	 */
75
	void clearUncommittedFile() throws CoreException;
76
77
	/**
78
	 * Adds includes, macros and names to the given file.
52
	 */
79
	 */
53
	void addFileContent(IIndexFragmentFile sourceFile, 
80
	void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes,  
54
			IncludeInformation[] includes,  
81
			IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver,
55
			IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver) throws CoreException;
82
			YieldableIndexLock lock) throws CoreException, InterruptedException;
56
83
57
	/**
84
	/**
58
	 * Acquires a write lock, while giving up a certain amount of read locks.
85
	 * Acquires a write lock, while giving up a certain amount of read locks.
(-)parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java (-6 / +20 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Andrew Ferguson (Symbian)
10
 *    Andrew Ferguson (Symbian)
11
 *    Sergey Prigogin (Google)
11
 *******************************************************************************/ 
12
 *******************************************************************************/ 
12
13
13
package org.eclipse.cdt.internal.core.index;
14
package org.eclipse.cdt.internal.core.index;
Lines 19-24 Link Here
19
import org.eclipse.cdt.core.index.IIndexFile;
20
import org.eclipse.cdt.core.index.IIndexFile;
20
import org.eclipse.cdt.core.index.IIndexFileLocation;
21
import org.eclipse.cdt.core.index.IIndexFileLocation;
21
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
22
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
23
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
22
import org.eclipse.core.runtime.CoreException;
24
import org.eclipse.core.runtime.CoreException;
23
25
24
public class WritableCIndex extends CIndex implements IWritableIndex {
26
public class WritableCIndex extends CIndex implements IWritableIndex {
Lines 50-66 Link Here
50
		return fWritableFragment.getFiles(location);
52
		return fWritableFragment.getFiles(location);
51
	}
53
	}
52
54
53
	public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException {
55
	public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
54
		return fWritableFragment.addFile(linkageID, fileLocation);
56
		return fWritableFragment.addFile(linkageID, location);
57
	}
58
59
	public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException {
60
		return fWritableFragment.addUncommittedFile(linkageID, location);
61
	}
62
63
	public IIndexFragmentFile commitUncommittedFile() throws CoreException {
64
		return fWritableFragment.commitUncommittedFile();
65
	}
66
67
	public void clearUncommittedFile() throws CoreException {
68
		fWritableFragment.clearUncommittedFile();
55
	}
69
	}
56
70
57
	private boolean isWritableFragment(IIndexFragment frag) {
71
	private boolean isWritableFragment(IIndexFragment frag) {
58
		return frag == fWritableFragment;
72
		return frag == fWritableFragment;
59
	}
73
	}
60
74
61
	public void setFileContent(IIndexFragmentFile file, int linkageID,
75
	public void setFileContent(IIndexFragmentFile file, int linkageID, IncludeInformation[] includes,
62
			IncludeInformation[] includes,
76
			IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver,
63
			IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver) throws CoreException {
77
			YieldableIndexLock lock) throws CoreException, InterruptedException {
64
		IIndexFragment indexFragment = file.getIndexFragment();
78
		IIndexFragment indexFragment = file.getIndexFragment();
65
		if (!isWritableFragment(indexFragment)) {
79
		if (!isWritableFragment(indexFragment)) {
66
			assert false : "Attempt to update file of read-only fragment"; //$NON-NLS-1$
80
			assert false : "Attempt to update file of read-only fragment"; //$NON-NLS-1$
Lines 70-76 Link Here
70
					ii.fTargetFile= addFile(linkageID, ii.fLocation);
84
					ii.fTargetFile= addFile(linkageID, ii.fLocation);
71
				}
85
				}
72
			}
86
			}
73
			((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names, resolver);
87
			((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names, resolver, lock);
74
		}
88
		}
75
	}
89
	}
76
90
(-)parser/org/eclipse/cdt/internal/core/pdom/PDOM.java (-14 / +52 lines)
Lines 6-16 Link Here
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Doug Schaefer (QNX) - Initial API and implementation
9
 *    Doug Schaefer (QNX) - Initial API and implementation
10
 *     Markus Schorn (Wind River Systems)
10
 *    Markus Schorn (Wind River Systems)
11
 *     IBM Corporation
11
 *    IBM Corporation
12
 *     Andrew Ferguson (Symbian)
12
 *    Andrew Ferguson (Symbian)
13
 *     Anton Leherbauer (Wind River Systems)
13
 *    Anton Leherbauer (Wind River Systems)
14
 *    Sergey Prigogin (Google)
14
 *******************************************************************************/
15
 *******************************************************************************/
15
package org.eclipse.cdt.internal.core.pdom;
16
package org.eclipse.cdt.internal.core.pdom;
16
17
Lines 96-101 Link Here
96
public class PDOM extends PlatformObject implements IPDOM {
97
public class PDOM extends PlatformObject implements IPDOM {
97
	private static final int BLOCKED_WRITE_LOCK_OUTPUT_INTERVAL = 30000;
98
	private static final int BLOCKED_WRITE_LOCK_OUTPUT_INTERVAL = 30000;
98
	private static final int LONG_WRITE_LOCK_REPORT_THRESHOLD = 1000;
99
	private static final int LONG_WRITE_LOCK_REPORT_THRESHOLD = 1000;
100
	private static final int LONG_READ_LOCK_WAIT_REPORT_THRESHOLD = 1000;
99
	static boolean sDEBUG_LOCKS= false; // initialized in the PDOMManager, because IBM needs PDOM independent of runtime plugin.
101
	static boolean sDEBUG_LOCKS= false; // initialized in the PDOMManager, because IBM needs PDOM independent of runtime plugin.
100
102
101
	/**
103
	/**
Lines 341-347 Link Here
341
		}
343
		}
342
	}
344
	}
343
345
344
	private PDOMLinkage createLinkage(int linkageID) throws CoreException {
346
	protected PDOMLinkage createLinkage(int linkageID) throws CoreException {
345
		PDOMLinkage pdomLinkage= fLinkageIDCache.get(linkageID);
347
		PDOMLinkage pdomLinkage= fLinkageIDCache.get(linkageID);
346
		if (pdomLinkage == null) {
348
		if (pdomLinkage == null) {
347
			final String linkageName= Linkage.getLinkageName(linkageID);
349
			final String linkageName= Linkage.getLinkageName(linkageID);
Lines 766-771 Link Here
766
	private long timeWriteLockAcquired;
768
	private long timeWriteLockAcquired;
767
769
768
	public void acquireReadLock() throws InterruptedException {
770
	public void acquireReadLock() throws InterruptedException {
771
		long t = sDEBUG_LOCKS ? System.nanoTime() : 0;
769
		synchronized (mutex) {
772
		synchronized (mutex) {
770
			++waitingReaders;
773
			++waitingReaders;
771
			try {
774
			try {
Lines 776-789 Link Here
776
			}
779
			}
777
			++lockCount;
780
			++lockCount;
778
			db.setLocked(true);
781
			db.setLocked(true);
779
			
782
780
			if (sDEBUG_LOCKS) {
783
			if (sDEBUG_LOCKS) {
784
				t = (System.nanoTime() - t) / 1000000;
785
				if (t >= LONG_READ_LOCK_WAIT_REPORT_THRESHOLD) {
786
					System.out.println("Acquired index read lock after " + t + " ms wait."); //$NON-NLS-1$//$NON-NLS-2$
787
				}
781
				incReadLock(fLockDebugging);
788
				incReadLock(fLockDebugging);
782
			}
789
			}
783
		}
790
		}
784
	}
791
	}
785
792
786
787
	public void releaseReadLock() {
793
	public void releaseReadLock() {
788
		boolean clearCache= false;
794
		boolean clearCache= false;
789
		synchronized (mutex) {
795
		synchronized (mutex) {
Lines 884-889 Link Here
884
		fireChange(event);
890
		fireChange(event);
885
	}
891
	}
886
892
893
	public boolean hasWaitingReaders() {
894
		synchronized (mutex) {
895
			return waitingReaders > 0;
896
		}
897
	}
898
	
887
	public long getLastWriteAccess() {
899
	public long getLastWriteAccess() {
888
		return lastWriteAccess;
900
		return lastWriteAccess;
889
	}
901
	}
Lines 957-973 Link Here
957
		PDOMName name;
969
		PDOMName name;
958
		if ((options & FIND_DECLARATIONS) != 0) {
970
		if ((options & FIND_DECLARATIONS) != 0) {
959
			for (name= pdomBinding.getFirstDeclaration(); name != null; name= name.getNextInBinding()) {
971
			for (name= pdomBinding.getFirstDeclaration(); name != null; name= name.getNextInBinding()) {
960
				names.add(name);
972
				if (isCommitted(name)) {
973
					names.add(name);
974
				}
961
			}
975
			}
962
		}
976
		}
963
		if ((options & FIND_DEFINITIONS) != 0) {
977
		if ((options & FIND_DEFINITIONS) != 0) {
964
			for (name = pdomBinding.getFirstDefinition(); name != null; name= name.getNextInBinding()) {
978
			for (name = pdomBinding.getFirstDefinition(); name != null; name= name.getNextInBinding()) {
965
				names.add(name);
979
				if (isCommitted(name)) {
980
					names.add(name);
981
				}
966
			}
982
			}
967
		}
983
		}
968
		if ((options & FIND_REFERENCES) != 0) {
984
		if ((options & FIND_REFERENCES) != 0) {
969
			for (name = pdomBinding.getFirstReference(); name != null; name= name.getNextInBinding()) {
985
			for (name = pdomBinding.getFirstReference(); name != null; name= name.getNextInBinding()) {
970
				names.add(name);
986
				if (isCommitted(name)) {
987
					names.add(name);
988
				}
971
			}
989
			}
972
		}
990
		}
973
	}
991
	}
Lines 977-1000 Link Here
977
		if ((options & FIND_DEFINITIONS) != 0) {
995
		if ((options & FIND_DEFINITIONS) != 0) {
978
			for (PDOMMacro macro= container.getFirstDefinition(); macro != null; macro= macro.getNextInContainer()) {
996
			for (PDOMMacro macro= container.getFirstDefinition(); macro != null; macro= macro.getNextInContainer()) {
979
				final IIndexFragmentName name = macro.getDefinition();
997
				final IIndexFragmentName name = macro.getDefinition();
980
				if (name != null) {
998
				if (name != null && isCommitted(macro)) {
981
					names.add(name);
999
					names.add(name);
982
				}
1000
				}
983
			}
1001
			}
984
		}
1002
		}
985
		if ((options & FIND_REFERENCES) != 0) {
1003
		if ((options & FIND_REFERENCES) != 0) {
986
			for (PDOMMacroReferenceName name = container.getFirstReference(); name != null; name= name.getNextInContainer()) {
1004
			for (PDOMMacroReferenceName name = container.getFirstReference(); name != null; name= name.getNextInContainer()) {
987
				names.add(name);
1005
				if (isCommitted(name)) {
1006
					names.add(name);
1007
				}
988
			}
1008
			}
989
		}
1009
		}
990
	}
1010
	}
991
1011
1012
	protected boolean isCommitted(PDOMName name) throws CoreException {
1013
		return true;
1014
	}
1015
1016
	protected boolean isCommitted(PDOMMacro name) throws CoreException {
1017
		return true;
1018
	}
1019
1020
	protected boolean isCommitted(PDOMMacroReferenceName name) throws CoreException {
1021
		return true;
1022
	}
1023
992
	public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) throws CoreException {
1024
	public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) throws CoreException {
993
		PDOMFile pdomFile= adaptFile(file);
1025
		PDOMFile pdomFile= adaptFile(file);
994
		if (pdomFile != null) {
1026
		if (pdomFile != null) {
995
			List<PDOMInclude> result = new ArrayList<PDOMInclude>();
1027
			List<PDOMInclude> result = new ArrayList<PDOMInclude>();
996
			for (PDOMInclude i= pdomFile.getFirstIncludedBy(); i != null; i= i.getNextInIncludedBy()) {
1028
			for (PDOMInclude i= pdomFile.getFirstIncludedBy(); i != null; i= i.getNextInIncludedBy()) {
997
				result.add(i);
1029
				if (i.getIncludedBy().getTimestamp() > 0) {
1030
					result.add(i);
1031
				}
998
			}
1032
			}
999
			return result.toArray(new PDOMInclude[result.size()]);
1033
			return result.toArray(new PDOMInclude[result.size()]);
1000
		}
1034
		}
Lines 1197-1202 Link Here
1197
	public String createKeyForCache(long record, char[] name) {
1231
	public String createKeyForCache(long record, char[] name) {
1198
		return new StringBuilder(name.length + 2).append((char) (record >> 16)).append((char) record).append(name).toString();
1232
		return new StringBuilder(name.length + 2).append((char) (record >> 16)).append((char) record).append(name).toString();
1199
	}
1233
	}
1234
1235
	public boolean hasLastingDefinition(PDOMBinding binding) throws CoreException {
1236
		return binding.hasDefinition();
1237
	}
1200
	
1238
	
1201
	private PDOMBinding[] getCrossLanguageBindings(IBinding binding) throws CoreException {
1239
	private PDOMBinding[] getCrossLanguageBindings(IBinding binding) throws CoreException {
1202
		switch(binding.getLinkage().getLinkageID()) {
1240
		switch(binding.getLinkage().getLinkageID()) {
(-)parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java (+5 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Sergey Prigogin (Google)
10
 *******************************************************************************/ 
11
 *******************************************************************************/ 
11
package org.eclipse.cdt.internal.core.pdom;
12
package org.eclipse.cdt.internal.core.pdom;
12
13
Lines 187-192 Link Here
187
		}
188
		}
188
	}
189
	}
189
190
191
	public boolean hasWaitingReaders() {
192
		return fDelegate != null && fDelegate.hasWaitingReaders();
193
	}
194
190
	public synchronized void resetCacheCounters() {
195
	public synchronized void resetCacheCounters() {
191
		if (fDelegate != null)
196
		if (fDelegate != null)
192
			fDelegate.resetCacheCounters();
197
			fDelegate.resetCacheCounters();
(-)parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java (-33 / +68 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    IBM Corporation
10
 *    IBM Corporation
11
 *    Sergey Prigogin (Google)
11
 *******************************************************************************/ 
12
 *******************************************************************************/ 
12
package org.eclipse.cdt.internal.core.pdom;
13
package org.eclipse.cdt.internal.core.pdom;
13
14
Lines 46-51 Link Here
46
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
47
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
47
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
48
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
48
import org.eclipse.cdt.core.index.IIndexFileLocation;
49
import org.eclipse.cdt.core.index.IIndexFileLocation;
50
import org.eclipse.cdt.core.index.IIndexInclude;
49
import org.eclipse.cdt.core.parser.IProblem;
51
import org.eclipse.cdt.core.parser.IProblem;
50
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
52
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
51
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
53
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
Lines 68-73 Link Here
68
 * @since 4.0
70
 * @since 4.0
69
 */
71
 */
70
abstract public class PDOMWriter {
72
abstract public class PDOMWriter {
73
	// TODO(sprigogin): Remove SEMI_TRANSACTIONAL_UPDATES and ALLOW_LOCK_YIELDING constants and simplify the code.
74
	public static boolean SEMI_TRANSACTIONAL_UPDATES = true;
75
	public static boolean ALLOW_LOCK_YIELDING = true;
71
	public static int SKIP_ALL_REFERENCES= -1;
76
	public static int SKIP_ALL_REFERENCES= -1;
72
	public static int SKIP_TYPE_REFERENCES= 1;
77
	public static int SKIP_TYPE_REFERENCES= 1;
73
	public static int SKIP_MACRO_REFERENCES= 2;
78
	public static int SKIP_MACRO_REFERENCES= 2;
Lines 200-210 Link Here
200
				if (fShowActivity) {
205
				if (fShowActivity) {
201
					trace("Indexer: adding " + ifl.getURI());  //$NON-NLS-1$
206
					trace("Indexer: adding " + ifl.getURI());  //$NON-NLS-1$
202
				}
207
				}
203
				index.acquireWriteLock(readlockCount);
204
				long start= System.currentTimeMillis();
205
				Throwable th= null;
208
				Throwable th= null;
209
				YieldableIndexLock lock = new YieldableIndexLock(index, readlockCount, flushIndex);
210
				lock.acquire();
206
				try {
211
				try {
207
					storeFileInIndex(index, ifl, symbolMap, linkageID, configHash, contextIncludes);
212
					storeFileInIndex(index, ifl, symbolMap, linkageID, configHash, contextIncludes, lock);
208
				} catch (RuntimeException e) {
213
				} catch (RuntimeException e) {
209
					th= e; 
214
					th= e; 
210
				} catch (PDOMNotImplementedError e) {
215
				} catch (PDOMNotImplementedError e) {
Lines 214-220 Link Here
214
				} catch (AssertionError e) {
219
				} catch (AssertionError e) {
215
					th= e;
220
					th= e;
216
				} finally {
221
				} finally {
217
					index.releaseWriteLock(readlockCount, flushIndex);
222
					lock.release();
218
				}
223
				}
219
				if (th != null) {
224
				if (th != null) {
220
					stati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
225
					stati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
Lines 223-229 Link Here
223
				if (i < ifls.length - 1) {
228
				if (i < ifls.length - 1) {
224
					updateFileCount(0, 0, 1); // update header count
229
					updateFileCount(0, 0, 1); // update header count
225
				}
230
				}
226
				fStatistics.fAddToIndexTime += System.currentTimeMillis() - start;
231
				fStatistics.fAddToIndexTime += lock.getCumulativeLockTime();
227
			}
232
			}
228
		}
233
		}
229
	}
234
	}
Lines 448-487 Link Here
448
453
449
	private IIndexFragmentFile storeFileInIndex(IWritableIndex index, IIndexFileLocation location,
454
	private IIndexFragmentFile storeFileInIndex(IWritableIndex index, IIndexFileLocation location,
450
			Map<IIndexFileLocation, Symbols> symbolMap, int linkageID, int configHash,
455
			Map<IIndexFileLocation, Symbols> symbolMap, int linkageID, int configHash,
451
			Set<IASTPreprocessorIncludeStatement> contextIncludes) throws CoreException {
456
			Set<IASTPreprocessorIncludeStatement> contextIncludes, YieldableIndexLock lock)
457
			throws CoreException, InterruptedException {
452
		Set<IIndexFileLocation> clearedContexts= Collections.emptySet();
458
		Set<IIndexFileLocation> clearedContexts= Collections.emptySet();
453
		IIndexFragmentFile file= index.getWritableFile(linkageID, location);
459
		IIndexFragmentFile file;
454
		if (file != null) {
460
		long timestamp = fResolver.getLastModified(location);
455
			clearedContexts= new HashSet<IIndexFileLocation>();
461
		if (SEMI_TRANSACTIONAL_UPDATES) {
456
			index.clearFile(file, clearedContexts);
462
			// In fine grained locking mode we create a temporary PDOMFile with zero timestamp,
463
			// add names to it, then replace contents of the old file from the temporary one, then
464
			// delete the temporary file. The write lock on the index is periodically yielded while
465
			// adding names to the temporary file, if the process takes long time.
466
			IIndexFragmentFile oldFile = index.getWritableFile(linkageID, location);
467
			if (oldFile != null) {
468
				IIndexInclude[] includedBy = index.findIncludedBy(oldFile);
469
				if (includedBy.length > 0) {
470
					clearedContexts= new HashSet<IIndexFileLocation>();
471
					for (IIndexInclude include : includedBy) {
472
						clearedContexts.add(include.getIncludedByLocation());
473
					}
474
				}
475
			}
476
			file= index.addUncommittedFile(linkageID, location);
457
		} else {
477
		} else {
458
			file= index.addFile(linkageID, location);
478
			file= index.getWritableFile(linkageID, location);
479
			if (file != null) {
480
				clearedContexts= new HashSet<IIndexFileLocation>();
481
				index.clearFile(file, clearedContexts);
482
			} else {
483
				file= index.addFile(linkageID, location);
484
			}
485
			file.setTimestamp(timestamp);
459
		}
486
		}
460
		file.setTimestamp(fResolver.getLastModified(location));
487
		try {
461
		file.setScannerConfigurationHashcode(configHash);
488
			file.setScannerConfigurationHashcode(configHash);
462
		Symbols lists= symbolMap.get(location);
489
			Symbols lists= symbolMap.get(location);
463
		if (lists != null) {
490
			if (lists != null) {
464
			IASTPreprocessorStatement[] macros= lists.fMacros.toArray(new IASTPreprocessorStatement[lists.fMacros.size()]);
491
				IASTPreprocessorStatement[] macros= lists.fMacros.toArray(new IASTPreprocessorStatement[lists.fMacros.size()]);
465
			IASTName[][] names= lists.fNames.toArray(new IASTName[lists.fNames.size()][]);
492
				IASTName[][] names= lists.fNames.toArray(new IASTName[lists.fNames.size()][]);
466
			for (IASTName[] name2 : names) {
493
				for (IASTName[] name2 : names) {
467
				final IASTName name= name2[0];
494
					final IASTName name= name2[0];
468
				if (name != null) {
495
					if (name != null) {
469
					ASTInternal.setFullyResolved(name.getBinding(), true);
496
						ASTInternal.setFullyResolved(name.getBinding(), true);
497
					}
470
				}
498
				}
471
			}
499
	
472
500
				IncludeInformation[] includeInfos= new IncludeInformation[lists.fIncludes.size()];
473
			IncludeInformation[] includeInfos= new IncludeInformation[lists.fIncludes.size()];
501
				for (int i= 0; i < lists.fIncludes.size(); i++) {
474
			for (int i= 0; i < lists.fIncludes.size(); i++) {
502
					final IASTPreprocessorIncludeStatement include = lists.fIncludes.get(i);
475
				final IASTPreprocessorIncludeStatement include = lists.fIncludes.get(i);
503
					final IncludeInformation info= includeInfos[i]= new IncludeInformation();
476
				final IncludeInformation info= includeInfos[i]= new IncludeInformation();
504
					info.fStatement= include;
477
				info.fStatement= include;
505
					if (include.isResolved()) {
478
				if (include.isResolved()) {
506
						info.fLocation= fResolver.resolveASTPath(include.getPath());
479
					info.fLocation= fResolver.resolveASTPath(include.getPath());
507
						info.fIsContext= include.isActive() && 
480
					info.fIsContext= include.isActive() && 
508
							(contextIncludes.contains(include) || clearedContexts.contains(info.fLocation));
481
						(contextIncludes.contains(include) || clearedContexts.contains(info.fLocation));
509
					}
482
				}
510
				}
511
				index.setFileContent(file, linkageID, includeInfos, macros, names, fResolver,
512
						SEMI_TRANSACTIONAL_UPDATES && ALLOW_LOCK_YIELDING ? lock : null);
513
			}
514
			if (SEMI_TRANSACTIONAL_UPDATES) {
515
				file.setTimestamp(timestamp);
516
				file = index.commitUncommittedFile();
483
			}
517
			}
484
			index.setFileContent(file, linkageID, includeInfos, macros, names, fResolver);
518
		} finally {
519
			index.clearUncommittedFile();
485
		}
520
		}
486
		return file;
521
		return file;
487
	}
522
	}
(-)parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java (-5 / +99 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    Markus Schorn - initial API and implementation
9
 *    Markus Schorn - initial API and implementation
10
 *    Andrew Ferguson (Symbian)
10
 *    Andrew Ferguson (Symbian)
11
 *    Sergey Prigogin (Google)
11
 *******************************************************************************/ 
12
 *******************************************************************************/ 
12
package org.eclipse.cdt.internal.core.pdom;
13
package org.eclipse.cdt.internal.core.pdom;
13
14
Lines 25-41 Link Here
25
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
26
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
26
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
27
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
27
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
28
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
29
import org.eclipse.cdt.internal.core.pdom.db.BTree;
28
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
30
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
29
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
31
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
30
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
32
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
31
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
33
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
34
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
32
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
35
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
36
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
37
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
38
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacroReferenceName;
39
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
33
import org.eclipse.core.runtime.CoreException;
40
import org.eclipse.core.runtime.CoreException;
34
41
35
public class WritablePDOM extends PDOM implements IWritableIndexFragment {	
42
public class WritablePDOM extends PDOM implements IWritableIndexFragment {	
36
	private boolean fClearedBecauseOfVersionMismatch= false;
43
	private boolean fClearedBecauseOfVersionMismatch= false;
37
	private boolean fCreatedFromScratch= false;
44
	private boolean fCreatedFromScratch= false;
38
	private ASTFilePathResolver fPathResolver;
45
	private ASTFilePathResolver fPathResolver;
46
	private PDOMFile fileBeingUpdated;
47
	private PDOMFile uncommittedFile;
48
	private IIndexFileLocation uncommittedLocation;
39
49
40
	public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter,
50
	public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter,
41
			Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
51
			Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
Lines 53-63 Link Here
53
63
54
	@Override
64
	@Override
55
	public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
65
	public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
66
		if (uncommittedLocation != null && uncommittedLocation.equals(location)) {
67
			return uncommittedFile;
68
		}
56
		return super.addFile(linkageID, location);
69
		return super.addFile(linkageID, location);
57
	}
70
	}
58
71
72
	public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException {
73
		uncommittedLocation = location;
74
		fileBeingUpdated = getFile(linkageID, uncommittedLocation);
75
		PDOMLinkage linkage= createLinkage(linkageID);
76
		uncommittedFile = new PDOMFile(linkage, location, linkageID);
77
		return uncommittedFile;
78
	}
79
80
	public IIndexFragmentFile commitUncommittedFile() throws CoreException {
81
		if (uncommittedFile == null)
82
			return null;
83
		IIndexFragmentFile file;
84
		if (fileBeingUpdated == null) {
85
			// New file.
86
			BTree fileIndex = getFileIndex();
87
			fileIndex.insert(uncommittedFile.getRecord());
88
			file = uncommittedFile;
89
		} else {
90
			// Existing file.
91
			fileBeingUpdated.replaceContentsFrom(uncommittedFile);
92
			file = fileBeingUpdated;
93
			fileBeingUpdated = null;
94
		}
95
		fEvent.fFilesWritten.add(uncommittedLocation);
96
		uncommittedFile = null;
97
		uncommittedLocation = null;
98
		return file;
99
	}
100
101
	public void clearUncommittedFile() throws CoreException {
102
		if (uncommittedFile != null) {
103
			try {
104
				uncommittedFile.clear(null);
105
				uncommittedFile.delete();
106
			} finally {
107
				uncommittedFile = null;
108
				uncommittedLocation = null;
109
				fileBeingUpdated = null;
110
			}
111
		}
112
	}
113
59
	public void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes, 
114
	public void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes, 
60
			IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver) throws CoreException {
115
			IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver,
116
			YieldableIndexLock lock) throws CoreException, InterruptedException {
61
		assert sourceFile.getIndexFragment() == this;
117
		assert sourceFile.getIndexFragment() == this;
62
		
118
		
63
		PDOMFile pdomFile = (PDOMFile) sourceFile;
119
		PDOMFile pdomFile = (PDOMFile) sourceFile;
Lines 66-79 Link Here
66
		final ASTFilePathResolver origResolver= fPathResolver;
122
		final ASTFilePathResolver origResolver= fPathResolver;
67
		fPathResolver= pathResolver;
123
		fPathResolver= pathResolver;
68
		try {
124
		try {
69
			pdomFile.addNames(names);
125
			pdomFile.addNames(names, lock);
70
		} finally {
126
		} finally {
71
			fPathResolver= origResolver;
127
			fPathResolver= origResolver;
72
		}
128
		}
73
		
129
		
74
		final IIndexFileLocation location = pdomFile.getLocation();
130
		final IIndexFileLocation location = pdomFile.getLocation();
75
		fEvent.fClearedFiles.remove(location);
131
		if (location != null) {
76
		fEvent.fFilesWritten.add(location);
132
			fEvent.fClearedFiles.remove(location);
133
			fEvent.fFilesWritten.add(location);
134
		}
77
	}
135
	}
78
136
79
	public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved)
137
	public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved)
Lines 171-181 Link Here
171
229
172
	public PDOMFile getFileForASTPath(int linkageID, String astPath) throws CoreException {
230
	public PDOMFile getFileForASTPath(int linkageID, String astPath) throws CoreException {
173
		if (fPathResolver != null && astPath != null) {
231
		if (fPathResolver != null && astPath != null) {
174
			return getFile(linkageID, fPathResolver.resolveASTPath(astPath));
232
			IIndexFileLocation location = fPathResolver.resolveASTPath(astPath);
233
			if (location.equals(uncommittedLocation))
234
				return fileBeingUpdated != null ? fileBeingUpdated : uncommittedFile;
235
			return getFile(linkageID, location);
175
		}
236
		}
176
		return null;
237
		return null;
177
	}
238
	}
178
239
240
	@Override
241
	public boolean hasLastingDefinition(PDOMBinding binding) throws CoreException {
242
		if (fileBeingUpdated == null) {
243
			return binding.hasDefinition();
244
		}
245
		// Definitions in fileBeingUpdated will soon go away, so look for a definition elsewhere.
246
		for (PDOMName name = binding.getFirstDefinition(); name != null; name = name.getNextInBinding()) {
247
			if (!fileBeingUpdated.getPDOM().equals(name.getPDOM()) ||
248
					fileBeingUpdated.getRecord() != name.getFileRecord()) {
249
				return true;
250
			}
251
		}
252
		return false;
253
	}
254
255
	@Override
256
	protected boolean isCommitted(PDOMName name) throws CoreException {
257
		return uncommittedFile == null || !uncommittedFile.getPDOM().equals(name.getPDOM()) ||
258
				uncommittedFile.getRecord() != name.getFileRecord();
259
	}
260
261
	@Override
262
	protected boolean isCommitted(PDOMMacro name) throws CoreException {
263
		return uncommittedFile == null || !uncommittedFile.getPDOM().equals(name.getPDOM()) ||
264
				uncommittedFile.getRecord() != name.getFileRecord();
265
	}
266
267
	@Override
268
	protected boolean isCommitted(PDOMMacroReferenceName name) throws CoreException {
269
		return uncommittedFile == null || !uncommittedFile.getPDOM().equals(name.getPDOM()) ||
270
				uncommittedFile.getRecord() != name.getFileRecord();
271
	}
272
179
	/* (non-Javadoc)
273
	/* (non-Javadoc)
180
	 * @see org.eclipse.cdt.internal.core.index.IWritableIndexFragment#getDatabaseSizeBytes()
274
	 * @see org.eclipse.cdt.internal.core.index.IWritableIndexFragment#getDatabaseSizeBytes()
181
	 */
275
	 */
(-)parser/org/eclipse/cdt/internal/core/pdom/YieldableIndexLock.java (+74 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Google, Inc and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 * 	  Sergey Prigogin (Google) - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.cdt.internal.core.pdom;
12
13
import org.eclipse.cdt.internal.core.index.IWritableIndex;
14
15
/**
16
 * Write lock on the index that can be yielded temporarily to unblock threads that need
17
 * read access to the index. 
18
 * @since 5.2
19
 */
20
public class YieldableIndexLock {
21
	private final IWritableIndex index;
22
	private final int readlockCount;
23
	private final boolean flushIndex;
24
	private long lastLockTime;
25
	private long cumulativeLockTime;
26
27
	public YieldableIndexLock(IWritableIndex index, int readlockCount, boolean flushIndex) {
28
		this.index = index;
29
		this.readlockCount = readlockCount;
30
		this.flushIndex = flushIndex;
31
	}
32
33
	/**
34
	 * Acquires the lock.
35
	 * 
36
	 * @throws InterruptedException
37
	 */
38
	public void acquire() throws InterruptedException {
39
		index.acquireWriteLock(readlockCount);
40
		lastLockTime = System.currentTimeMillis();
41
	}
42
43
	/**
44
	 * Releases the lock.
45
	 */
46
	public void release() {
47
		if (lastLockTime != 0) {
48
			index.releaseWriteLock(readlockCount, flushIndex);
49
			cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
50
			lastLockTime = 0;
51
		}
52
	}
53
54
	/**
55
	 * Yields the lock temporarily if it was held for YIELD_INTERVAL or more, and somebody is waiting
56
	 * for a read lock. 
57
	 * @throws InterruptedException
58
	 */
59
	public void yield() throws InterruptedException {
60
		if (index.hasWaitingReaders()) {
61
			index.releaseWriteLock(readlockCount, false);
62
			cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
63
			lastLockTime = 0;
64
			acquire();
65
		}
66
	}
67
68
	/**
69
	 * @return Total time the lock was held in milliseconds. 
70
	 */
71
	public long getCumulativeLockTime() {
72
		return cumulativeLockTime;
73
	}
74
}
(-)parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java (-6 / +128 lines)
Lines 9-14 Link Here
9
 *    QNX - Initial API and implementation
9
 *    QNX - Initial API and implementation
10
 *    Markus Schorn (Wind River Systems)
10
 *    Markus Schorn (Wind River Systems)
11
 *    Andrew Ferguson (Symbian)
11
 *    Andrew Ferguson (Symbian)
12
 *    Sergey Prigogin (Google)
12
 *******************************************************************************/
13
 *******************************************************************************/
13
package org.eclipse.cdt.internal.core.pdom.dom;
14
package org.eclipse.cdt.internal.core.pdom.dom;
14
15
Lines 30-35 Link Here
30
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
31
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
31
import org.eclipse.cdt.core.dom.ast.IParameter;
32
import org.eclipse.cdt.core.dom.ast.IParameter;
32
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
33
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
34
import org.eclipse.cdt.core.index.IIndexFile;
33
import org.eclipse.cdt.core.index.IIndexFileLocation;
35
import org.eclipse.cdt.core.index.IIndexFileLocation;
34
import org.eclipse.cdt.core.index.IIndexInclude;
36
import org.eclipse.cdt.core.index.IIndexInclude;
35
import org.eclipse.cdt.core.index.IIndexLocationConverter;
37
import org.eclipse.cdt.core.index.IIndexLocationConverter;
Lines 42-47 Link Here
42
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
44
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
43
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
45
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
44
import org.eclipse.cdt.internal.core.pdom.PDOM;
46
import org.eclipse.cdt.internal.core.pdom.PDOM;
47
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
45
import org.eclipse.cdt.internal.core.pdom.db.BTree;
48
import org.eclipse.cdt.internal.core.pdom.db.BTree;
46
import org.eclipse.cdt.internal.core.pdom.db.Database;
49
import org.eclipse.cdt.internal.core.pdom.db.Database;
47
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
50
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
Lines 115-120 Link Here
115
		return record;
118
		return record;
116
	}
119
	}
117
120
121
	public PDOM getPDOM() {
122
		return fLinkage.getPDOM();
123
	}
124
	
118
	@Override
125
	@Override
119
	public boolean equals(Object obj) {
126
	public boolean equals(Object obj) {
120
		if (obj == this)
127
		if (obj == this)
Lines 128-140 Link Here
128
135
129
	@Override
136
	@Override
130
	public final int hashCode() {
137
	public final int hashCode() {
131
		return System.identityHashCode(fLinkage.getPDOM()) + (int)(41*record);
138
		return System.identityHashCode(fLinkage.getPDOM()) + (int) (41 * record);
132
	}
139
	}
133
	
140
	
134
	/**
141
	/**
135
	 * Directly changes this record's internal location string. The format
142
	 * Transfers names, macros and includes from another file to this one and deletes the other file.
136
	 * of this string is unspecified in general and is determined by the 
143
	 * @param sourceFile the file to transfer the local bindings from.
137
	 * associated IIndexLocationConverter
144
	 * @throws CoreException
145
	 */
146
	public void replaceContentsFrom(PDOMFile sourceFile) throws CoreException {
147
		ICPPUsingDirective[] directives= getUsingDirectives();
148
		for (ICPPUsingDirective ud : directives) {
149
			if (ud instanceof IPDOMNode) {
150
				((IPDOMNode) ud).delete(null);
151
			}
152
		}
153
		setFirstUsingDirectiveRec(sourceFile.getLastUsingDirectiveRec());
154
155
		// Replace the includes
156
		PDOMInclude include = getFirstInclude();
157
		while (include != null) {
158
			PDOMInclude nextInclude = include.getNextInIncludes();
159
			IIndexFile includedBy = include.getIncludedBy();
160
			if (this.equals(includedBy)) {
161
				include.delete();
162
			}
163
			include = nextInclude;
164
		}
165
		include = sourceFile.getFirstInclude();
166
		setFirstInclude(include);
167
		while (include != null) {
168
			IIndexFile includedBy = include.getIncludedBy();
169
			if (sourceFile.equals(includedBy)) {
170
				include.setIncludedBy(this);
171
				if (sourceFile.equals(include.getIncludes())) {
172
					include.setIncludes(this);
173
				}
174
			}
175
			include = include.getNextInIncludes();
176
		}
177
178
		// Replace all the macros in this file.
179
		PDOMLinkage linkage= getLinkage();
180
		PDOMMacro macro = getFirstMacro();
181
		while (macro != null) {
182
			PDOMMacro nextMacro = macro.getNextMacro();
183
			macro.delete(linkage);
184
			macro = nextMacro;
185
		}
186
		macro = sourceFile.getFirstMacro();
187
		setFirstMacro(macro);
188
		for (; macro != null; macro = macro.getNextMacro()) {
189
			macro.setFile(this);
190
		}
191
192
		// Replace all macro references
193
		ArrayList<PDOMMacroReferenceName> mrefs= new ArrayList<PDOMMacroReferenceName>();
194
		PDOMMacroReferenceName mref = getFirstMacroReference();
195
		while (mref != null) {
196
			mrefs.add(mref);
197
			mref= mref.getNextInFile();
198
		}
199
		for (PDOMMacroReferenceName m : mrefs) {
200
			m.delete();
201
		}
202
		mref = sourceFile.getFirstMacroReference();
203
		setFirstMacroReference(mref);
204
		for (; mref != null; mref = mref.getNextInFile()) {
205
			mref.setFile(this);
206
		}
207
208
		// Replace all the names in this file
209
		ArrayList<PDOMName> names= new ArrayList<PDOMName>();
210
		PDOMName name = getFirstName();
211
		for (; name != null; name= name.getNextInFile()) {
212
			names.add(name);
213
			linkage.onDeleteName(name);
214
		}
215
		for (Iterator<PDOMName> iterator = names.iterator(); iterator.hasNext();) {
216
			name = iterator.next();
217
			name.delete();
218
		}
219
		name = sourceFile.getFirstName();
220
		setFirstName(name);
221
		for (; name != null; name= name.getNextInFile()) {
222
			name.setFile(this);
223
		}
224
225
		setTimestamp(sourceFile.getTimestamp());
226
		setScannerConfigurationHashcode(sourceFile.getScannerConfigurationHashcode());
227
228
		sourceFile.delete();
229
	}
230
231
	/**
232
	 * This method should not be called on PDOMFile objects that are referenced by the file index.
233
	 * @param location a new location
234
	 * @throws CoreException
235
	 */
236
	public void setLocation(IIndexFileLocation location) throws CoreException {
237
		String locationString = fLinkage.getPDOM().getLocationConverter().toInternalFormat(location);
238
		if (locationString == null)
239
			throw new CoreException(CCorePlugin.createStatus(Messages.getString("PDOMFile.toInternalProblem") + //$NON-NLS-1$
240
					location.getURI()));
241
		setInternalLocation(locationString);
242
	}
243
244
	/**
245
	 * Directly changes this record's internal location string. The format of this string is unspecified
246
	 * in general and is determined by the associated IIndexLocationConverter.
247
	 * This method should not be called on PDOMFile objects that are referenced by the file index.
138
	 * @param internalLocation
248
	 * @param internalLocation
139
	 * @throws CoreException
249
	 * @throws CoreException
140
	 */
250
	 */
Lines 256-262 Link Here
256
		return fLinkage;
366
		return fLinkage;
257
	}
367
	}
258
368
259
	public void addNames(IASTName[][] names) throws CoreException {
369
	public void addNames(IASTName[][] names, YieldableIndexLock lock) throws CoreException, InterruptedException {
260
		assert getFirstName() == null;
370
		assert getFirstName() == null;
261
		assert getFirstMacroReference() == null;
371
		assert getFirstMacroReference() == null;
262
		final PDOMLinkage linkage= getLinkage();
372
		final PDOMLinkage linkage= getLinkage();
Lines 265-270 Link Here
265
		PDOMMacroReferenceName lastMacroName= null;
375
		PDOMMacroReferenceName lastMacroName= null;
266
		for (IASTName[] name : names) {
376
		for (IASTName[] name : names) {
267
			if (name[0] != null) {
377
			if (name[0] != null) {
378
				if (lock != null) {
379
					lock.yield();
380
				}
268
				PDOMName caller= nameCache.get(name[1]);
381
				PDOMName caller= nameCache.get(name[1]);
269
				IIndexFragmentName fname= createPDOMName(linkage, name[0], caller);
382
				IIndexFragmentName fname= createPDOMName(linkage, name[0], caller);
270
				if (fname instanceof PDOMName) {
383
				if (fname instanceof PDOMName) {
Lines 340-346 Link Here
340
			include.delete();
453
			include.delete();
341
			include = nextInclude;
454
			include = nextInclude;
342
		}
455
		}
343
		setFirstInclude(include);
456
		setFirstInclude(null);
344
457
345
		// Delete all the macros in this file
458
		// Delete all the macros in this file
346
		PDOMLinkage linkage= getLinkage();
459
		PDOMLinkage linkage= getLinkage();
Lines 381-386 Link Here
381
		setTimestamp(-1);
494
		setTimestamp(-1);
382
	}
495
	}
383
496
497
	/**
498
	 * Deletes this file from PDOM. Only uncommitted files can be safely deleted.
499
	 *
500
	 * @throws CoreException
501
	 */
502
	public void delete() throws CoreException {
503
		fLinkage.getDB().free(record);
504
	}
505
384
	public void addIncludesTo(IncludeInformation[] includeInfos) throws CoreException {
506
	public void addIncludesTo(IncludeInformation[] includeInfos) throws CoreException {
385
		assert getFirstInclude() == null;
507
		assert getFirstInclude() == null;
386
508
(-)parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java (-1 / +6 lines)
Lines 141-146 Link Here
141
		return rec != 0 ? new PDOMFile(linkage, rec) : null;
141
		return rec != 0 ? new PDOMFile(linkage, rec) : null;
142
	}
142
	}
143
143
144
	void setIncludes(PDOMFile includedFile) throws CoreException {
145
		long rec = includedFile != null ? includedFile.getRecord() : 0;
146
		linkage.getDB().putRecPtr(record + INCLUDED_FILE, rec);
147
	}
148
144
	/**
149
	/**
145
	 * Checks if the name is the same as the end part of the path of the included file.
150
	 * Checks if the name is the same as the end part of the path of the included file.
146
	 */
151
	 */
Lines 166-172 Link Here
166
		return rec != 0 ? new PDOMFile(linkage, rec) : null;
171
		return rec != 0 ? new PDOMFile(linkage, rec) : null;
167
	}
172
	}
168
173
169
	private void setIncludedBy(PDOMFile includedBy) throws CoreException {
174
	void setIncludedBy(PDOMFile includedBy) throws CoreException {
170
		long rec = includedBy != null ? includedBy.getRecord() : 0;
175
		long rec = includedBy != null ? includedBy.getRecord() : 0;
171
		linkage.getDB().putRecPtr(record + INCLUDED_BY, rec);
176
		linkage.getDB().putRecPtr(record + INCLUDED_BY, rec);
172
	}
177
	}
(-)parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java (-1 / +10 lines)
Lines 9-14 Link Here
9
 *    QNX - Initial API and implementation
9
 *    QNX - Initial API and implementation
10
 *    Markus Schorn (Wind River Systems)
10
 *    Markus Schorn (Wind River Systems)
11
 *    Andrew Ferguson (Symbian)
11
 *    Andrew Ferguson (Symbian)
12
 *    Sergey Prigogin (Google)
12
 *******************************************************************************/
13
 *******************************************************************************/
13
package org.eclipse.cdt.internal.core.pdom.dom;
14
package org.eclipse.cdt.internal.core.pdom.dom;
14
15
Lines 116-122 Link Here
116
	public PDOM getPDOM() {
117
	public PDOM getPDOM() {
117
		return fLinkage.getPDOM();
118
		return fLinkage.getPDOM();
118
	}
119
	}
119
	
120
120
	public long getRecord() {
121
	public long getRecord() {
121
		return fRecord;
122
		return fRecord;
122
	}
123
	}
Lines 269-274 Link Here
269
		return filerec != 0 ? new PDOMFile(fLinkage, filerec) : null;
270
		return filerec != 0 ? new PDOMFile(fLinkage, filerec) : null;
270
	}
271
	}
271
272
273
	public long getFileRecord() throws CoreException {
274
		return fLinkage.getDB().getRecPtr(fRecord + FILE);
275
	}
276
277
	void setFile(PDOMFile file) throws CoreException {
278
		fLinkage.getDB().putRecPtr(fRecord + FILE, file != null ? file.getRecord() : 0);
279
	}
280
272
	public int getEndingLineNumber() {
281
	public int getEndingLineNumber() {
273
		return 0;
282
		return 0;
274
	}
283
	}
(-)parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroReferenceName.java (-1 / +15 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    QNX - Initial API and implementation
9
 *    QNX - Initial API and implementation
10
 *    Markus Schorn (Wind River Systems)
10
 *    Markus Schorn (Wind River Systems)
11
 *    Sergey Prigogin (Google)
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.cdt.internal.core.pdom.dom;
13
package org.eclipse.cdt.internal.core.pdom.dom;
13
14
Lines 21-26 Link Here
21
import org.eclipse.cdt.internal.core.index.IIndexFragment;
22
import org.eclipse.cdt.internal.core.index.IIndexFragment;
22
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
23
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
23
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
24
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
25
import org.eclipse.cdt.internal.core.pdom.PDOM;
24
import org.eclipse.cdt.internal.core.pdom.db.Database;
26
import org.eclipse.cdt.internal.core.pdom.db.Database;
25
import org.eclipse.core.runtime.CoreException;
27
import org.eclipse.core.runtime.CoreException;
26
import org.eclipse.core.runtime.IPath;
28
import org.eclipse.core.runtime.IPath;
Lines 67-72 Link Here
67
		return record;
69
		return record;
68
	}
70
	}
69
71
72
	public PDOM getPDOM() {
73
		return linkage.getPDOM();
74
	}
75
70
	private long getRecField(int offset) throws CoreException {
76
	private long getRecField(int offset) throws CoreException {
71
		return linkage.getDB().getRecPtr(record + offset);
77
		return linkage.getDB().getRecPtr(record + offset);
72
	}
78
	}
Lines 110-116 Link Here
110
		long filerec = linkage.getDB().getRecPtr(record + FILE_REC_OFFSET);
116
		long filerec = linkage.getDB().getRecPtr(record + FILE_REC_OFFSET);
111
		return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
117
		return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
112
	}
118
	}
113
	
119
120
	public long getFileRecord() throws CoreException {
121
		return linkage.getDB().getRecPtr(record + FILE_REC_OFFSET);
122
	}
123
124
	void setFile(PDOMFile file) throws CoreException {
125
		linkage.getDB().putRecPtr(record + FILE_REC_OFFSET, file != null ? file.getRecord() : 0);
126
	}
127
114
	PDOMMacroReferenceName getNextInFile() throws CoreException {
128
	PDOMMacroReferenceName getNextInFile() throws CoreException {
115
		return getNameField(FILE_NEXT_OFFSET);
129
		return getNameField(FILE_NEXT_OFFSET);
116
	}
130
	}
(-)parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java (+14 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    QNX - Initial API and implementation
9
 *    QNX - Initial API and implementation
10
 *    Markus Schorn (Wind River Systems)
10
 *    Markus Schorn (Wind River Systems)
11
 *    Sergey Prigogin (Google)
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.cdt.internal.core.pdom.dom;
13
package org.eclipse.cdt.internal.core.pdom.dom;
13
14
Lines 22-27 Link Here
22
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
23
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
23
import org.eclipse.cdt.internal.core.index.IIndexFragment;
24
import org.eclipse.cdt.internal.core.index.IIndexFragment;
24
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
25
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
26
import org.eclipse.cdt.internal.core.pdom.PDOM;
25
import org.eclipse.cdt.internal.core.pdom.db.Database;
27
import org.eclipse.cdt.internal.core.pdom.db.Database;
26
import org.eclipse.core.runtime.CoreException;
28
import org.eclipse.core.runtime.CoreException;
27
import org.eclipse.core.runtime.IPath;
29
import org.eclipse.core.runtime.IPath;
Lines 121-126 Link Here
121
		linkage.getDB().putRecPtr(record + offset, fieldrec);
123
		linkage.getDB().putRecPtr(record + offset, fieldrec);
122
	}
124
	}
123
125
126
	public PDOM getPDOM() {
127
		return linkage.getPDOM();
128
	}
129
	
124
	public PDOMBinding getBinding() throws CoreException {
130
	public PDOMBinding getBinding() throws CoreException {
125
		long bindingrec = getRecField(BINDING_REC_OFFSET);
131
		long bindingrec = getRecField(BINDING_REC_OFFSET);
126
		return linkage.getBinding(bindingrec);
132
		return linkage.getBinding(bindingrec);
Lines 162-167 Link Here
162
		return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
168
		return filerec != 0 ? new PDOMFile(linkage, filerec) : null;
163
	}
169
	}
164
170
171
	public long getFileRecord() throws CoreException {
172
		return linkage.getDB().getRecPtr(record + FILE_REC_OFFSET);
173
	}
174
175
	void setFile(PDOMFile file) throws CoreException {
176
		linkage.getDB().putRecPtr(record + FILE_REC_OFFSET, file != null ? file.getRecord() : 0);
177
	}
178
165
	public IIndexName getEnclosingDefinition() throws CoreException {
179
	public IIndexName getEnclosingDefinition() throws CoreException {
166
		long namerec = getEnclosingDefinitionRecord();
180
		long namerec = getEnclosingDefinitionRecord();
167
		return namerec != 0 ? new PDOMName(linkage, namerec) : null;
181
		return namerec != 0 ? new PDOMName(linkage, namerec) : null;
(-)parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java (-3 / +3 lines)
Lines 299-305 Link Here
299
			if (fromName.isDefinition()) {
299
			if (fromName.isDefinition()) {
300
				return true;
300
				return true;
301
			}
301
			}
302
			return !pdomBinding.hasDefinition();
302
			return !getPDOM().hasLastingDefinition(pdomBinding);
303
		}
303
		}
304
		return false;
304
		return false;
305
	}
305
	}
Lines 444-451 Link Here
444
					if (!(method instanceof IProblemBinding)) {
444
					if (!(method instanceof IProblemBinding)) {
445
						PDOMBinding pdomBinding= adaptBinding(method);
445
						PDOMBinding pdomBinding= adaptBinding(method);
446
						if (pdomBinding == null) {
446
						if (pdomBinding == null) {
447
							createBinding(type, method, fileLocalRec);
447
							pdomBinding = createBinding(type, method, fileLocalRec);
448
						} else if (!pdomBinding.hasDefinition()) {
448
						} else if (!getPDOM().hasLastingDefinition(pdomBinding)) {
449
							pdomBinding.update(this, method);
449
							pdomBinding.update(this, method);
450
						}
450
						}
451
					}
451
					}
(-)parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java (+6 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *    Andrew Ferguson (Symbian) - initial API and implementation
9
 *    Andrew Ferguson (Symbian) - initial API and implementation
10
 *    Markus Schorn (Wind River Systems)
10
 *    Markus Schorn (Wind River Systems)
11
 *    Sergey Prigogin (Google)
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.cdt.internal.index.tests;
13
package org.eclipse.cdt.internal.index.tests;
13
14
Lines 123-128 Link Here
123
	}
124
	}
124
125
125
	public void releaseReadLock() {}
126
	public void releaseReadLock() {}
127
128
	public boolean hasWaitingReaders() {
129
		return false;
130
	}
131
126
	public void resetCacheCounters() {}
132
	public void resetCacheCounters() {}
127
133
128
	public IIndexFragmentFileSet createFileSet() {
134
	public IIndexFragmentFileSet createFileSet() {

Return to bug 287907