1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Fix for 189811, Open Element is slow to initialize.

This commit is contained in:
Markus Schorn 2007-07-20 08:36:03 +00:00
parent 238ca43d28
commit 61c38d0f85
21 changed files with 416 additions and 107 deletions

View file

@ -284,6 +284,16 @@ public class DBTest extends BaseTestCase {
assertSignEquals(expected, -biss.compare(aisc, caseSensitive)); assertSignEquals(expected, -biss.compare(aisc, caseSensitive));
assertSignEquals(expected, -biss.compare(a, caseSensitive)); assertSignEquals(expected, -biss.compare(a, caseSensitive));
assertSignEquals(expected, -biss.comparePrefix(acs, caseSensitive)); assertSignEquals(expected, -biss.comparePrefix(acs, caseSensitive));
if (!caseSensitive && expected != 0) {
assertSignEquals(expected, aiss.compareCompatibleWithIgnoreCase(bcs));
assertSignEquals(expected, aiss.compareCompatibleWithIgnoreCase(biss));
assertSignEquals(expected, aiss.compareCompatibleWithIgnoreCase(bisc));
assertSignEquals(expected, -biss.compareCompatibleWithIgnoreCase(acs));
assertSignEquals(expected, -biss.compareCompatibleWithIgnoreCase(aiss));
assertSignEquals(expected, -biss.compareCompatibleWithIgnoreCase(aisc));
}
} }
private void assertSignEquals(int a, int b) { private void assertSignEquals(int a, int b) {

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests; package org.eclipse.cdt.internal.pdom.tests;
@ -103,6 +104,7 @@ public class GeneratePDOMApplicationTest extends PDOMTestBase {
}); });
assertTrue(target.exists()); assertTrue(target.exists());
WritablePDOM wpdom= new WritablePDOM(target, new URIRelativeLocationConverter(baseURI), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); WritablePDOM wpdom= new WritablePDOM(target, new URIRelativeLocationConverter(baseURI), LanguageManager.getInstance().getPDOMLinkageFactoryMappings());
assertEquals(36, wpdom.getDB().getVersion()); // faked version, remove for CDT 4.1
verifyProject1Content(wpdom); verifyProject1Content(wpdom);
String fid; String fid;

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.provider; package org.eclipse.cdt.internal.core.index.provider;
@ -74,7 +75,7 @@ class PDOMCache {
result.acquireReadLock(); result.acquireReadLock();
try { try {
if(result.versionMismatch()) { if(!result.isSupportedVersion()) {
versionMismatch.add(file); versionMismatch.add(file);
String msg= MessageFormat.format(Messages.PDOMCache_VersionTooOld, new Object[] {file}); String msg= MessageFormat.format(Messages.PDOMCache_VersionTooOld, new Object[] {file});
CCorePlugin.log(msg); CCorePlugin.log(msg);

View file

@ -73,7 +73,9 @@ import org.eclipse.core.runtime.Status;
public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
protected Database db; protected Database db;
public static final int VERSION = 36; public static final int CURRENT_VERSION = 37;
public static final int MIN_SUPPORTED_VERSION= 36;
public static final int MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX= 37; // to be removed in 4.1
// 0 - the beginning of it all // 0 - the beginning of it all
// 1 - first change to kick off upgrades // 1 - first change to kick off upgrades
// 2 - added file inclusions // 2 - added file inclusions
@ -111,10 +113,16 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
// 34 - fix for base classes represented by qualified names (183843) // 34 - fix for base classes represented by qualified names (183843)
// 35 - add scanner configuration hash-code (62366) // 35 - add scanner configuration hash-code (62366)
// 36 - changed chunk size back to 4K (184892) // 36 - changed chunk size back to 4K (184892)
// 37 - added index for nested bindings (189811), compatible with version 36.
public static final int LINKAGES = Database.DATA_AREA; public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4; public static final int FILE_INDEX = Database.DATA_AREA + 4;
public static final int PROPERTIES = Database.DATA_AREA + 8; public static final int PROPERTIES = Database.DATA_AREA + 8;
public static final int HAS_NESTED_BINDING_BTREES= Database.DATA_AREA + 12;
public static final int END= Database.DATA_AREA + 13;
static {
assert END <= Database.CHUNK_SIZE;
}
// Local caches // Local caches
private BTree fileIndex; private BTree fileIndex;
@ -122,6 +130,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
private File fPath; private File fPath;
private IIndexLocationConverter locationConverter; private IIndexLocationConverter locationConverter;
private Map fPDOMLinkageFactoryCache; private Map fPDOMLinkageFactoryCache;
private boolean fHasBTreeForNestedBindings;
public PDOM(File dbPath, IIndexLocationConverter locationConverter, Map linkageFactoryMappings) throws CoreException { public PDOM(File dbPath, IIndexLocationConverter locationConverter, Map linkageFactoryMappings) throws CoreException {
this(dbPath, locationConverter, ChunkCache.getSharedInstance(), linkageFactoryMappings); this(dbPath, locationConverter, ChunkCache.getSharedInstance(), linkageFactoryMappings);
@ -144,13 +153,22 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
fPath= dbPath; fPath= dbPath;
final boolean lockDB= db == null || lockCount != 0; final boolean lockDB= db == null || lockCount != 0;
db = new Database(fPath, cache, VERSION, isPermanentlyReadOnly()); db = new Database(fPath, cache, CURRENT_VERSION, isPermanentlyReadOnly());
fileIndex= null; // holds on to the database, so clear it. fileIndex= null; // holds on to the database, so clear it.
db.setLocked(lockDB); db.setLocked(lockDB);
int version= db.getVersion(); int version= db.getVersion();
if (version == VERSION) { if (version >= MIN_SUPPORTED_VERSION) {
readLinkages(); readLinkages();
fHasBTreeForNestedBindings= db.getByte(HAS_NESTED_BINDING_BTREES) == 1;
// new PDOM with version ready to write nested bindings index
if (version >= MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) {
if (!fHasBTreeForNestedBindings && !isPermanentlyReadOnly()) {
fHasBTreeForNestedBindings= true;
db.putByte(HAS_NESTED_BINDING_BTREES, (byte) 1);
}
}
} }
db.setLocked(lockCount != 0); db.setLocked(lockCount != 0);
} }
@ -159,11 +177,12 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
return locationConverter; return locationConverter;
} }
public boolean versionMismatch() throws CoreException { public boolean isCurrentVersion() throws CoreException {
if (db.getVersion() != VERSION) { return db.getVersion() == CURRENT_VERSION;
return true; }
} else
return false; public boolean isSupportedVersion() throws CoreException {
return db.getVersion() >= MIN_SUPPORTED_VERSION;
} }
public void accept(IPDOMVisitor visitor) throws CoreException { public void accept(IPDOMVisitor visitor) throws CoreException {
@ -247,7 +266,9 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
assert lockCount < 0; // needs write-lock. assert lockCount < 0; // needs write-lock.
// Clear out the database, everything is set to zero. // Clear out the database, everything is set to zero.
getDB().clear(VERSION); db.clear(CURRENT_VERSION);
db.putByte(HAS_NESTED_BINDING_BTREES, (byte) 1);
fHasBTreeForNestedBindings= true;
clearCaches(); clearCaches();
} }
@ -713,26 +734,22 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
PDOMLinkage linkage= (PDOMLinkage) iter.next(); PDOMLinkage linkage= (PDOMLinkage) iter.next();
if (filter.acceptLinkage(linkage)) { if (filter.acceptLinkage(linkage)) {
IBinding[] bindings; IBinding[] bindings;
if(filescope) {
BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false); BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false);
visitor.setMonitor(monitor); visitor.setMonitor(monitor);
try { try {
linkage.accept(visitor); linkage.accept(visitor);
if (!filescope) {
if (fHasBTreeForNestedBindings) {
linkage.getNestedBindingsIndex().accept(visitor);
} }
catch (OperationCanceledException e) { else {
}
bindings= visitor.getBindings();
} else {
BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false);
visitor.setMonitor(monitor);
try {
linkage.accept(visitor);
linkage.accept(new ApplyVisitor(linkage, visitor)); linkage.accept(new ApplyVisitor(linkage, visitor));
} }
}
}
catch (OperationCanceledException e) { catch (OperationCanceledException e) {
} }
bindings= visitor.getBindings(); bindings= visitor.getBindings();
}
for (int j = 0; j < bindings.length; j++) { for (int j = 0; j < bindings.length; j++) {
result.add(bindings[j]); result.add(bindings[j]);

View file

@ -46,6 +46,7 @@ public class PDOMIndexerJob extends Job {
} }
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
final long start= System.currentTimeMillis();
fMonitor = monitor; fMonitor = monitor;
String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$ String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$
monitor.beginTask(taskName, TOTAL_MONITOR_WORK); monitor.beginTask(taskName, TOTAL_MONITOR_WORK);
@ -97,6 +98,16 @@ public class PDOMIndexerJob extends Job {
} }
} }
while (currentTask != null); while (currentTask != null);
// work-around for https://bugs.eclipse.org/bugs/show_bug.cgi?id=197258
long rest= 100-(System.currentTimeMillis()-start);
if (rest > 0) {
try {
Thread.sleep(rest);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return Status.OK_STATUS; return Status.OK_STATUS;
} }
catch (RuntimeException e) { catch (RuntimeException e) {

View file

@ -327,7 +327,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
WritablePDOM pdom= new WritablePDOM(dbFile, new PDOMProjectIndexLocationConverter(rproject), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); WritablePDOM pdom= new WritablePDOM(dbFile, new PDOMProjectIndexLocationConverter(rproject), LanguageManager.getInstance().getPDOMLinkageFactoryMappings());
if (pdom.versionMismatch() || fromScratch) { if (!pdom.isSupportedVersion() || fromScratch) {
try { try {
pdom.acquireWriteLock(); pdom.acquireWriteLock();
} catch (InterruptedException e) { } catch (InterruptedException e) {

View file

@ -203,7 +203,7 @@ public class TeamPDOMImportOperation implements IWorkspaceRunnable {
WritablePDOM pdom= (WritablePDOM) obj; WritablePDOM pdom= (WritablePDOM) obj;
pdom.acquireReadLock(); pdom.acquireReadLock();
try { try {
if (pdom.versionMismatch()) { if (!pdom.isSupportedVersion()) {
throw new CoreException(CCorePlugin.createStatus( throw new CoreException(CCorePlugin.createStatus(
NLS.bind(Messages.PDOMImportTask_errorInvalidPDOMVersion, fProject.getElementName()))); NLS.bind(Messages.PDOMImportTask_errorInvalidPDOMVersion, fProject.getElementName())));
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems and others. * Copyright (c) 2005, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -47,7 +47,7 @@ public class BTree {
} }
/** /**
* Contructor. * Constructor.
* *
* @param db the database containing the btree * @param db the database containing the btree
* @param root offset into database of the pointer to the root node * @param root offset into database of the pointer to the root node
@ -160,24 +160,34 @@ public class BTree {
} }
} }
// search to find the insert point // binary search to find the insert point
int i; int lower= 0;
for (i = 0; i < MAX_RECORDS; ++i) { int upper= MAX_RECORDS-1;
int record1 = getRecord(chunk, node, i); while (lower < upper && getRecord(chunk, node, upper-1) == 0) {
if (record1 == 0) { upper--;
// past the end
break;
} else {
int compare = cmp.compare(record1, record);
if (compare == 0)
// found it, no insert, just return the record
return record;
else if (compare > 0)
// past it
break;
}
} }
while (lower < upper) {
int middle= (lower+upper)/2;
int checkRec= getRecord(chunk, node, middle);
if (checkRec == 0) {
upper= middle;
}
else {
int compare= cmp.compare(checkRec, record);
if (compare > 0) {
upper= middle;
}
else if (compare < 0) {
lower= middle+1;
}
else {
// found it, no insert, just return the record
return record;
}
}
}
final int i= lower;
int child = getChild(chunk, node, i); int child = getChild(chunk, node, i);
if (child != 0) { if (child != 0) {
// visit the children // visit the children
@ -472,7 +482,7 @@ public class BTree {
* @param src the node to read from * @param src the node to read from
* @param srcPos the initial index to read from (inclusive) * @param srcPos the initial index to read from (inclusive)
* @param dst the node to write to * @param dst the node to write to
* @param dstPos the intial index to write to (inclusive) * @param dstPos the initial index to write to (inclusive)
* @param length the number of (key,(predecessor)child) nodes to write * @param length the number of (key,(predecessor)child) nodes to write
*/ */
private void nodeContentCopy(BTNode src, int srcPos, BTNode dst, int dstPos, int length) { private void nodeContentCopy(BTNode src, int srcPos, BTNode dst, int dstPos, int length) {
@ -539,13 +549,37 @@ public class BTree {
try { try {
Chunk chunk = db.getChunk(node); Chunk chunk = db.getChunk(node);
int i= 0; // binary search to find first record greater or equal
int lower= 0;
int upper= MAX_RECORDS-1;
while (lower < upper && getRecord(chunk, node, upper-1) == 0) {
upper--;
}
while (lower < upper) {
int middle= (lower+upper)/2;
int checkRec= getRecord(chunk, node, middle);
if (checkRec == 0) {
upper= middle;
}
else {
int compare= visitor.compare(checkRec);
if (compare >= 0) {
upper= middle;
}
else {
lower= middle+1;
}
}
}
// start with first record greater or equal, reuse comparison results.
int i= lower;
for (; i < MAX_RECORDS; ++i) { for (; i < MAX_RECORDS; ++i) {
int record = getRecord(chunk, node, i); int record = getRecord(chunk, node, i);
if (record == 0) if (record == 0)
break; break;
int compare = visitor.compare(record); int compare= visitor.compare(record);
if (compare > 0) { if (compare > 0) {
// start point is to the left // start point is to the left
return accept(getChild(chunk, node, i), visitor); return accept(getChild(chunk, node, i), visitor);

View file

@ -111,7 +111,7 @@ public class Database {
} }
else { else {
fHeaderChunk.read(); fHeaderChunk.read();
fVersion= fHeaderChunk.getInt(0); fVersion= fHeaderChunk.getInt(VERSION_OFFSET);
fChunks = new Chunk[nChunksOnDisk]; // chunk[0] is unused. fChunks = new Chunk[nChunksOnDisk]; // chunk[0] is unused.
} }
} catch (IOException e) { } catch (IOException e) {
@ -139,7 +139,7 @@ public class Database {
public void setVersion(int version) throws CoreException { public void setVersion(int version) throws CoreException {
assert fExclusiveLock; assert fExclusiveLock;
fHeaderChunk.putInt(0, version); fHeaderChunk.putInt(VERSION_OFFSET, version);
fVersion= version; fVersion= version;
} }
@ -574,7 +574,7 @@ public class Database {
if (isComplete) { if (isComplete) {
if (fHeaderChunk.fDirty || fIsMarkedIncomplete) { if (fHeaderChunk.fDirty || fIsMarkedIncomplete) {
fHeaderChunk.putInt(0, fVersion); fHeaderChunk.putInt(VERSION_OFFSET, fVersion);
fHeaderChunk.flush(); fHeaderChunk.flush();
fIsMarkedIncomplete= false; fIsMarkedIncomplete= false;
} }

View file

@ -8,6 +8,7 @@
* Contributors: * Contributors:
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db; package org.eclipse.cdt.internal.core.pdom.db;
@ -30,7 +31,7 @@ public interface IString {
// strcmp equivalents // strcmp equivalents
/** /**
* Compare this IString record and the specified IString record * Compare this IString record and the specified IString record
* @param chars * @param string
* @param caseSensitive whether to compare in a case-sensitive way * @param caseSensitive whether to compare in a case-sensitive way
* @return <ul><li> -1 if this &lt; string * @return <ul><li> -1 if this &lt; string
* <li> 0 if this == string * <li> 0 if this == string
@ -42,7 +43,7 @@ public interface IString {
/** /**
* Compare this IString record and the specified String object * Compare this IString record and the specified String object
* @param chars * @param string
* @param caseSensitive whether to compare in a case-sensitive way * @param caseSensitive whether to compare in a case-sensitive way
* @return <ul><li> -1 if this &lt; string * @return <ul><li> -1 if this &lt; string
* <li> 0 if this == string * <li> 0 if this == string
@ -64,6 +65,29 @@ public interface IString {
*/ */
public int compare(char[] chars, boolean caseSensitive) throws CoreException; public int compare(char[] chars, boolean caseSensitive) throws CoreException;
/**
* Compare this IString record and the specified IString record in a case sensitive manner
* such that it is compatible with case insensitive comparison.
* @param string
* @return <ul><li> -1 if this &lt; string
* <li> 0 if this == string
* <li> 1 if this &gt; string
* </ul>
* @throws CoreException
*/
public int compareCompatibleWithIgnoreCase(IString string) throws CoreException;
/**
* Compare this IString record and the specified char array in a case sensitive manner
* such that it is compatible with case insensitive comparison.
* @param chars
* @return <ul><li> -1 if this &lt; string
* <li> 0 if this == string
* <li> 1 if this &gt; string
* </ul>
* @throws CoreException
*/
public int compareCompatibleWithIgnoreCase(char[] chars) throws CoreException;
/** /**
* Compare this IString record and the specified character array * Compare this IString record and the specified character array

View file

@ -8,6 +8,7 @@
* Contributors: * Contributors:
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db; package org.eclipse.cdt.internal.core.pdom.db;
@ -329,4 +330,13 @@ public class LongString implements IString {
return buffer.toString(); return buffer.toString();
} }
public int compareCompatibleWithIgnoreCase(IString string) throws CoreException {
int cmp= compare(string, false);
return cmp==0 ? compare(string, true) : cmp;
}
public int compareCompatibleWithIgnoreCase(char[] chars) throws CoreException {
int cmp= compare(chars, false);
return cmp==0 ? compare(chars, true) : cmp;
}
} }

View file

@ -8,6 +8,7 @@
* Contributors: * Contributors:
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db; package org.eclipse.cdt.internal.core.pdom.db;
@ -241,6 +242,94 @@ public class ShortString implements IString {
return 0; return 0;
} }
public int compareCompatibleWithIgnoreCase(IString string) throws CoreException {
if (string instanceof ShortString)
return compareCompatibleWithIgnoreCase((ShortString)string);
else if (string instanceof LongString)
return - ((LongString)string).compareCompatibleWithIgnoreCase(this);
else
throw new IllegalArgumentException();
}
public int compareCompatibleWithIgnoreCase(ShortString other) throws CoreException {
Chunk chunk1 = db.getChunk(record);
Chunk chunk2 = other.db.getChunk(other.record);
int i1 = record + CHARS;
int i2 = other.record + CHARS;
int n1 = i1 + chunk1.getInt(record + LENGTH) * 2;
int n2 = i2 + chunk2.getInt(other.record + LENGTH) * 2;
int sensitiveCmp= 0;
while (i1 < n1 && i2 < n2) {
final char c1= chunk1.getChar(i1);
final char c2= chunk2.getChar(i2);
if (c1 != c2) {
int cmp= compareChars(c1, c2, false); // insensitive
if(cmp!=0)
return cmp;
if (sensitiveCmp == 0) {
if (c1 < c2) {
sensitiveCmp= -1;
}
else {
sensitiveCmp= 1;
}
}
}
i1 += 2;
i2 += 2;
}
if (i1 == n1 && i2 != n2)
return -1;
else if (i2 == n2 && i1 != n1)
return 1;
return sensitiveCmp;
}
public int compareCompatibleWithIgnoreCase(char[] chars) throws CoreException {
Chunk chunk1 = db.getChunk(record);
int i1 = record + CHARS;
int i2 = 0;
int n1 = i1 + chunk1.getInt(record + LENGTH) * 2;
int n2 = chars.length;
int sensitiveCmp= 0;
while (i1 < n1 && i2 < n2) {
final char c1= chunk1.getChar(i1);
final char c2= chars[i2];
if (c1 != c2) {
int cmp= compareChars(c1, c2, false); // insensitive
if(cmp!=0)
return cmp;
if (sensitiveCmp == 0) {
if (c1 < c2) {
sensitiveCmp= -1;
}
else {
sensitiveCmp= 1;
}
}
}
i1 += 2;
i2++;
}
if (i1 == n1 && i2 != n2)
return -1;
else if (i2 == n2 && i1 != n1)
return 1;
return sensitiveCmp;
}
public int comparePrefix(char[] other, boolean caseSensitive) throws CoreException { public int comparePrefix(char[] other, boolean caseSensitive) throws CoreException {
Chunk chunk = db.getChunk(record); Chunk chunk = db.getChunk(record);

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial API and implementation * Andrew Ferguson (Symbian) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom; package org.eclipse.cdt.internal.core.pdom.dom;
@ -34,27 +35,46 @@ public class FindBinding {
public int compare(int record1, int record2) throws CoreException { public int compare(int record1, int record2) throws CoreException {
IString nm1 = PDOMNamedNode.getDBName(pdom, record1); IString nm1 = PDOMNamedNode.getDBName(pdom, record1);
IString nm2 = PDOMNamedNode.getDBName(pdom, record2); IString nm2 = PDOMNamedNode.getDBName(pdom, record2);
int cmp= nm1.compare(nm2, false); int cmp= nm1.compareCompatibleWithIgnoreCase(nm2);
cmp= cmp==0 ? nm1.compare(nm2, true) : cmp;
if(cmp == 0) { if(cmp == 0) {
int t1 = PDOMNamedNode.getNodeType(pdom, record1); int t1 = PDOMNode.getNodeType(pdom, record1);
int t2 = PDOMNamedNode.getNodeType(pdom, record2); int t2 = PDOMNode.getNodeType(pdom, record2);
return t1 < t2 ? -1 : (t1 > t2 ? 1 : 0); return t1 < t2 ? -1 : (t1 > t2 ? 1 : 0);
} }
return cmp; return cmp;
} }
} }
public static class NestedBindingsBTreeComparator extends DefaultBindingBTreeComparator implements IBTreeComparator {
protected PDOMLinkage linkage;
public NestedBindingsBTreeComparator(PDOMLinkage linkage) {
super(linkage.pdom);
this.linkage= linkage;
}
public int compare(int record1, int record2) throws CoreException {
int cmp= super.compare(record1, record2); // compare names
if (cmp==0) { // any order will do.
if (record1 < record2) {
return -1;
}
else if (record1 > record2) {
return 1;
}
}
return cmp;
}
}
public static PDOMBinding findBinding(BTree btree, final PDOM pdom, final char[]name, final int[] constants) throws CoreException { public static PDOMBinding findBinding(BTree btree, final PDOM pdom, final char[]name, final int[] constants) throws CoreException {
final PDOMBinding[] result = new PDOMBinding[1]; final PDOMBinding[] result = new PDOMBinding[1];
btree.accept(new IBTreeVisitor() { btree.accept(new IBTreeVisitor() {
public int compare(int record) throws CoreException { public int compare(int record) throws CoreException {
IString nm1 = PDOMNamedNode.getDBName(pdom, record); IString nm1 = PDOMNamedNode.getDBName(pdom, record);
int cmp= nm1.compare(name, false); return nm1.compareCompatibleWithIgnoreCase(name);
return cmp==0 ? nm1.compare(name, true) : cmp;
} }
public boolean visit(int record) throws CoreException { public boolean visit(int record) throws CoreException {
PDOMNamedNode nnode = (PDOMNamedNode) PDOMLinkage.getLinkage(pdom, record).getNode(record); PDOMNamedNode nnode = (PDOMNamedNode) PDOMNode.getLinkage(pdom, record).getNode(record);
if(nnode.hasName(name)) { if(nnode.hasName(name)) {
int constant = nnode.getNodeType(); int constant = nnode.getNodeType();
for(int i=0; i<constants.length; i++) { for(int i=0; i<constants.length; i++) {

View file

@ -62,6 +62,8 @@ public class NamedNodeCollector implements IBTreeVisitor, IPDOMVisitor {
} }
final public int compare(int record) throws CoreException { final public int compare(int record) throws CoreException {
if (monitor != null)
checkCancelled();
IString name= PDOMNamedNode.getDBName(linkage.getPDOM(), record); IString name= PDOMNamedNode.getDBName(linkage.getPDOM(), record);
return compare(name); return compare(name);
} }
@ -75,9 +77,11 @@ public class NamedNodeCollector implements IBTreeVisitor, IPDOMVisitor {
} }
return cmp; return cmp;
} else { } else {
cmp= rhsName.compare(name, false);
if(caseSensitive) { if(caseSensitive) {
cmp= cmp==0 ? rhsName.compare(name, true) : cmp; cmp= rhsName.compareCompatibleWithIgnoreCase(name);
}
else {
cmp= rhsName.compare(name, false);
} }
} }
return cmp; return cmp;

View file

@ -64,8 +64,9 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
private static final int ID_OFFSET = PDOMNamedNode.RECORD_SIZE + 0; private static final int ID_OFFSET = PDOMNamedNode.RECORD_SIZE + 0;
private static final int NEXT_OFFSET = PDOMNamedNode.RECORD_SIZE + 4; private static final int NEXT_OFFSET = PDOMNamedNode.RECORD_SIZE + 4;
private static final int INDEX_OFFSET = PDOMNamedNode.RECORD_SIZE + 8; private static final int INDEX_OFFSET = PDOMNamedNode.RECORD_SIZE + 8;
private static final int NESTED_BINDINGS_INDEX = PDOMNamedNode.RECORD_SIZE + 12;
protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 12; protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 16;
// node types // node types
protected static final int LINKAGE= 0; // special one for myself protected static final int LINKAGE= 0; // special one for myself
@ -110,6 +111,15 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
return new BTree(pdom.getDB(), record + INDEX_OFFSET, getIndexComparator()); return new BTree(pdom.getDB(), record + INDEX_OFFSET, getIndexComparator());
} }
/**
* Returns the BTree for the nested bindings.
* @return
* @throws CoreException
*/
public BTree getNestedBindingsIndex() throws CoreException {
return new BTree(getPDOM().getDB(), record + NESTED_BINDINGS_INDEX, getNestedBindingsComparator());
}
public void accept(final IPDOMVisitor visitor) throws CoreException { public void accept(final IPDOMVisitor visitor) throws CoreException {
if (visitor instanceof IBTreeVisitor) { if (visitor instanceof IBTreeVisitor) {
getIndex().accept((IBTreeVisitor) visitor); getIndex().accept((IBTreeVisitor) visitor);
@ -167,6 +177,10 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
public abstract IBTreeComparator getIndexComparator(); public abstract IBTreeComparator getIndexComparator();
public IBTreeComparator getNestedBindingsComparator() {
return new FindBinding.NestedBindingsBTreeComparator(this);
}
public abstract PDOMBinding addBinding(IASTName name) throws CoreException; public abstract PDOMBinding addBinding(IASTName name) throws CoreException;
public abstract PDOMBinding addBinding(IBinding binding) throws CoreException; public abstract PDOMBinding addBinding(IBinding binding) throws CoreException;
@ -326,6 +340,34 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
public void onDeleteName(PDOMName nextName) throws CoreException { public void onDeleteName(PDOMName nextName) throws CoreException {
} }
/**
* Callback informing the linkage that a binding has been added. Used to index nested bindings.
* @param pdomBinding
* @throws CoreException
* @since 4.0.1
*/
public void afterAddBinding(PDOMBinding pdomBinding) throws CoreException {
if (pdomBinding.getParentNodeRec() != record) {
if (pdom.getDB().getVersion() >= PDOM.MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) {
getNestedBindingsIndex().insert(pdomBinding.getRecord());
}
}
}
/**
* Callback informing the linkage that a binding is about to be removed. Used to index nested bindings.
* @param pdomBinding
* @throws CoreException
* @since 4.0.1
*/
public void beforeRemoveBinding(PDOMBinding pdomBinding) throws CoreException {
if (pdomBinding.getParentNodeRec() != record) {
if (pdom.getDB().getVersion() >= PDOM.MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) {
getNestedBindingsIndex().delete(pdomBinding.getRecord());
}
}
}
/** /**
* Searches for the a file local scope object. If none is found depending * Searches for the a file local scope object. If none is found depending
* on the value of the parameter 'create' such an object is created. * on the value of the parameter 'create' such an object is created.

View file

@ -90,8 +90,12 @@ public abstract class PDOMNode implements IPDOMNode {
return pdom.getDB().getInt(record + TYPE); return pdom.getDB().getInt(record + TYPE);
} }
public int getParentNodeRec() throws CoreException {
return pdom.getDB().getInt(record + PARENT);
}
public PDOMNode getParentNode() throws CoreException { public PDOMNode getParentNode() throws CoreException {
int parentrec = pdom.getDB().getInt(record + PARENT); int parentrec = getParentNodeRec();
return parentrec != 0 ? getLinkageImpl().getNode(parentrec) : null; return parentrec != 0 ? getLinkageImpl().getNode(parentrec) : null;
} }

View file

@ -100,8 +100,9 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
} else if (binding instanceof ITypedef) } else if (binding instanceof ITypedef)
pdomBinding = new PDOMCTypedef(pdom, parent, (ITypedef)binding); pdomBinding = new PDOMCTypedef(pdom, parent, (ITypedef)binding);
if(pdomBinding!=null) { if (pdomBinding!=null) {
parent.addChild(pdomBinding); parent.addChild(pdomBinding);
afterAddBinding(pdomBinding);
} }
} }
return pdomBinding; return pdomBinding;

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial API and implementation * Andrew Ferguson (Symbian) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -43,9 +44,7 @@ public class CPPFindBinding extends FindBinding {
public int compare(int record) throws CoreException { public int compare(int record) throws CoreException {
IString nm1 = PDOMNamedNode.getDBName(pdom, record); IString nm1 = PDOMNamedNode.getDBName(pdom, record);
int cmp = nm1.compare(name, false); int cmp = nm1.compareCompatibleWithIgnoreCase(name);
cmp = cmp == 0 ? nm1.compare(name, true) : cmp;
if (cmp == 0) { if (cmp == 0) {
int c1 = PDOMNode.getNodeType(pdom, record); int c1 = PDOMNode.getNodeType(pdom, record);
cmp = c1 < c2 ? -1 : (c1 > c2 ? 1 : 0); cmp = c1 < c2 ? -1 : (c1 > c2 ? 1 : 0);

View file

@ -364,6 +364,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if(pdomBinding!=null) { if(pdomBinding!=null) {
parent.addChild(pdomBinding); parent.addChild(pdomBinding);
afterAddBinding(pdomBinding);
} }
pushPostProcesses(pdomBinding, binding); pushPostProcesses(pdomBinding, binding);

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.export; package org.eclipse.cdt.internal.core.pdom.export;
@ -21,6 +22,7 @@ import org.eclipse.cdt.core.index.export.IExportProjectProvider;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM; import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -78,6 +80,10 @@ public class GeneratePDOM implements ISafeRunnable {
exportedPDOM.setProperty((String) entry.getKey(), (String) entry.getValue()); exportedPDOM.setProperty((String) entry.getKey(), (String) entry.getValue());
} }
} }
// fake version of pdom, such that it works with CDT 4.0.0, also.
if (PDOM.CURRENT_VERSION == PDOM.MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) {
exportedPDOM.getDB().setVersion(PDOM.CURRENT_VERSION-1);
}
exportedPDOM.close(); exportedPDOM.close();
} }
finally { finally {

View file

@ -209,6 +209,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
} }
// sources first // sources first
sources= sortByContentType(sources);
for (Iterator iter = sources.iterator(); iter.hasNext();) { for (Iterator iter = sources.iterator(); iter.hasNext();) {
if (monitor.isCanceled()) if (monitor.isCanceled())
return; return;
@ -220,6 +221,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
} }
// headers with context // headers with context
headers= sortByContentType(headers);
for (Iterator iter = headers.iterator(); iter.hasNext();) { for (Iterator iter = headers.iterator(); iter.hasNext();) {
if (monitor.isCanceled()) if (monitor.isCanceled())
return; return;
@ -253,6 +255,38 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
} }
} }
private Collection sortByContentType(Collection sources) {
HashMap ctToLists= new HashMap();
for (Iterator iterator = sources.iterator(); iterator.hasNext();) {
final ITranslationUnit tu = (ITranslationUnit) iterator.next();
final String ct= tu.getContentTypeId();
List list= (List) ctToLists.get(ct);
if (list == null) {
list= new ArrayList();
ctToLists.put(ct, list);
}
list.add(tu);
}
if (ctToLists.size() <= 1) {
return sources;
}
Collection result= new ArrayList(sources.size());
// do C++ first
List list= (List) ctToLists.remove(CCorePlugin.CONTENT_TYPE_CXXSOURCE);
if (list != null) {
result.addAll(list);
}
list= (List) ctToLists.remove(CCorePlugin.CONTENT_TYPE_CXXHEADER);
if (list != null) {
result.addAll(list);
}
for (Iterator iterator = ctToLists.values().iterator(); iterator.hasNext();) {
list = (List) iterator.next();
result.addAll(list);
}
return result;
}
/** /**
* Convenience method to check whether a translation unit in the index is outdated * Convenience method to check whether a translation unit in the index is outdated
* with respect to its timestamp. * with respect to its timestamp.