1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-30 12:25:35 +02:00

Performance improvement for indexing template based source code.

This commit is contained in:
Markus Schorn 2008-04-18 07:56:46 +00:00
parent 501ebcad7f
commit 324a584c99
6 changed files with 156 additions and 122 deletions

View file

@ -256,8 +256,7 @@ public class PDOM extends PlatformObject implements IPDOM {
} }
public void accept(IPDOMVisitor visitor) throws CoreException { public void accept(IPDOMVisitor visitor) throws CoreException {
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { for (PDOMLinkage linkage : fLinkageIDCache.values()) {
PDOMLinkage linkage = iter.next();
linkage.accept(visitor); linkage.accept(visitor);
} }
} }
@ -454,8 +453,7 @@ public class PDOM extends PlatformObject implements IPDOM {
monitor= new NullProgressMonitor(); monitor= new NullProgressMonitor();
} }
BindingFinder finder = new BindingFinder(pattern, isFullyQualified, filter, monitor); BindingFinder finder = new BindingFinder(pattern, isFullyQualified, filter, monitor);
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { for (PDOMLinkage linkage : fLinkageIDCache.values()) {
PDOMLinkage linkage = iter.next();
if (filter.acceptLinkage(linkage)) { if (filter.acceptLinkage(linkage)) {
try { try {
linkage.accept(finder); linkage.accept(finder);
@ -475,8 +473,7 @@ public class PDOM extends PlatformObject implements IPDOM {
monitor= new NullProgressMonitor(); monitor= new NullProgressMonitor();
} }
MacroContainerPatternCollector finder = new MacroContainerPatternCollector(this, pattern, monitor); MacroContainerPatternCollector finder = new MacroContainerPatternCollector(this, pattern, monitor);
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { for (PDOMLinkage linkage : fLinkageIDCache.values()) {
PDOMLinkage linkage = iter.next();
if (filter.acceptLinkage(linkage)) { if (filter.acceptLinkage(linkage)) {
try { try {
linkage.getMacroIndex().accept(finder); linkage.getMacroIndex().accept(finder);
@ -497,8 +494,7 @@ public class PDOM extends PlatformObject implements IPDOM {
} }
ArrayList<PDOMBinding> result= new ArrayList<PDOMBinding>(); ArrayList<PDOMBinding> result= new ArrayList<PDOMBinding>();
ArrayList<PDOMNamedNode> nodes= new ArrayList<PDOMNamedNode>(); ArrayList<PDOMNamedNode> nodes= new ArrayList<PDOMNamedNode>();
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { for (PDOMLinkage linkage : fLinkageIDCache.values()) {
PDOMLinkage linkage = iter.next();
if (filter.acceptLinkage(linkage)) { if (filter.acceptLinkage(linkage)) {
nodes.add(linkage); nodes.add(linkage);
for (int i=0; i < names.length-1; i++) { for (int i=0; i < names.length-1; i++) {
@ -753,8 +749,8 @@ public class PDOM extends PlatformObject implements IPDOM {
findNamesForMyBinding(pdomBinding, options, names); findNamesForMyBinding(pdomBinding, options, names);
if ((options & SEARCH_ACCROSS_LANGUAGE_BOUNDARIES) != 0) { if ((options & SEARCH_ACCROSS_LANGUAGE_BOUNDARIES) != 0) {
PDOMBinding[] xlangBindings= getCrossLanguageBindings(binding); PDOMBinding[] xlangBindings= getCrossLanguageBindings(binding);
for (int j = 0; j < xlangBindings.length; j++) { for (PDOMBinding xlangBinding : xlangBindings) {
findNamesForMyBinding(xlangBindings[j], options, names); findNamesForMyBinding(xlangBinding, options, names);
} }
} }
} }
@ -763,8 +759,8 @@ public class PDOM extends PlatformObject implements IPDOM {
findNamesForMyBinding(macroContainer, options, names); findNamesForMyBinding(macroContainer, options, names);
if ((options & SEARCH_ACCROSS_LANGUAGE_BOUNDARIES) != 0) { if ((options & SEARCH_ACCROSS_LANGUAGE_BOUNDARIES) != 0) {
PDOMMacroContainer[] xlangBindings= getCrossLanguageBindings(macroContainer); PDOMMacroContainer[] xlangBindings= getCrossLanguageBindings(macroContainer);
for (int j = 0; j < xlangBindings.length; j++) { for (PDOMMacroContainer xlangBinding : xlangBindings) {
findNamesForMyBinding(xlangBindings[j], options, names); findNamesForMyBinding(xlangBinding, options, names);
} }
} }
} }
@ -831,8 +827,7 @@ public class PDOM extends PlatformObject implements IPDOM {
public IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException { public IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
ArrayList<IIndexFragmentBinding> result= new ArrayList<IIndexFragmentBinding>(); ArrayList<IIndexFragmentBinding> result= new ArrayList<IIndexFragmentBinding>();
for (Iterator<PDOMLinkage> iter= fLinkageIDCache.values().iterator(); iter.hasNext();) { for (PDOMLinkage linkage : fLinkageIDCache.values()) {
PDOMLinkage linkage= iter.next();
if (filter.acceptLinkage(linkage)) { if (filter.acceptLinkage(linkage)) {
PDOMBinding[] bindings; PDOMBinding[] bindings;
BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false); BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false);
@ -847,8 +842,8 @@ public class PDOM extends PlatformObject implements IPDOM {
} }
bindings= visitor.getBindings(); bindings= visitor.getBindings();
for (int j = 0; j < bindings.length; j++) { for (PDOMBinding binding : bindings) {
result.add(bindings[j]); result.add(binding);
} }
} }
} }
@ -857,8 +852,7 @@ public class PDOM extends PlatformObject implements IPDOM {
public IIndexFragmentBinding[] findBindings(char[] name, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException { public IIndexFragmentBinding[] findBindings(char[] name, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
ArrayList<IIndexFragmentBinding> result= new ArrayList<IIndexFragmentBinding>(); ArrayList<IIndexFragmentBinding> result= new ArrayList<IIndexFragmentBinding>();
for (Iterator<PDOMLinkage> iter= fLinkageIDCache.values().iterator(); iter.hasNext();) { for (PDOMLinkage linkage : fLinkageIDCache.values()) {
PDOMLinkage linkage= iter.next();
if (filter.acceptLinkage(linkage)) { if (filter.acceptLinkage(linkage)) {
PDOMBinding[] bindings; PDOMBinding[] bindings;
BindingCollector visitor = new BindingCollector(linkage, name, filter, false, true); BindingCollector visitor = new BindingCollector(linkage, name, filter, false, true);
@ -873,8 +867,8 @@ public class PDOM extends PlatformObject implements IPDOM {
} }
bindings= visitor.getBindings(); bindings= visitor.getBindings();
for (int j = 0; j < bindings.length; j++) { for (PDOMBinding binding : bindings) {
result.add(bindings[j]); result.add(binding);
} }
} }
} }
@ -886,8 +880,7 @@ public class PDOM extends PlatformObject implements IPDOM {
MacroContainerCollector visitor = new MacroContainerCollector(this, prefix, isPrefix, isCaseSensitive); MacroContainerCollector visitor = new MacroContainerCollector(this, prefix, isPrefix, isCaseSensitive);
visitor.setMonitor(monitor); visitor.setMonitor(monitor);
try { try {
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { for (PDOMLinkage linkage : fLinkageIDCache.values()) {
PDOMLinkage linkage = iter.next();
if (filter.acceptLinkage(linkage)) { if (filter.acceptLinkage(linkage)) {
linkage.getMacroIndex().accept(visitor); linkage.getMacroIndex().accept(visitor);
} }
@ -956,6 +949,12 @@ public class PDOM extends PlatformObject implements IPDOM {
} }
} }
public void removeCachedResult(Object key) {
synchronized(fResultCache) {
fResultCache.remove(key);
}
}
public String createKeyForCache(int record, char[] name) { public String createKeyForCache(int record, char[] name) {
return new StringBuilder(name.length+2).append((char) (record >> 16)).append((char) record).append(name).toString(); return new StringBuilder(name.length+2).append((char) (record >> 16)).append((char) record).append(name).toString();
} }

View file

@ -38,6 +38,8 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
protected final PDOM pdom; protected final PDOM pdom;
protected final int record; protected final int record;
private PDOMBinding fCachedBaseClass;
public PDOMCPPBase(PDOM pdom, int record) { public PDOMCPPBase(PDOM pdom, int record) {
this.pdom = pdom; this.pdom = pdom;
this.record = record; this.record = record;
@ -73,7 +75,7 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
return pdom.getDB().getByte(record + FLAGS); return pdom.getDB().getByte(record + FLAGS);
} }
public PDOMName getBaseClassSpecifierNameImpl() { public PDOMName getBaseClassSpecifierName() {
try { try {
int rec = pdom.getDB().getInt(record + BASECLASS_SPECIFIER); int rec = pdom.getDB().getInt(record + BASECLASS_SPECIFIER);
if (rec != 0) { if (rec != 0) {
@ -85,19 +87,18 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
return null; return null;
} }
public IName getBaseClassSpecifierName() {
return getBaseClassSpecifierNameImpl();
}
public IBinding getBaseClass() { public IBinding getBaseClass() {
if (fCachedBaseClass != null)
return fCachedBaseClass;
try { try {
PDOMName name= getBaseClassSpecifierNameImpl(); PDOMName name= getBaseClassSpecifierName();
if (name != null) { if (name != null) {
PDOMBinding b = name.getBinding(); PDOMBinding b = name.getBinding();
while( b instanceof PDOMCPPTypedef && ((PDOMCPPTypedef)b).getType() instanceof PDOMBinding ){ while( b instanceof PDOMCPPTypedef && ((PDOMCPPTypedef)b).getType() instanceof PDOMBinding ){
b = (PDOMBinding) ((PDOMCPPTypedef)b).getType(); b = (PDOMBinding) ((PDOMCPPTypedef)b).getType();
} }
return b; return fCachedBaseClass= b;
} }
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);

View file

@ -115,7 +115,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
PDOMCPPBase predecessor= null; PDOMCPPBase predecessor= null;
int nameRec= pdomName.getRecord(); int nameRec= pdomName.getRecord();
while (base != null) { while (base != null) {
PDOMName name = base.getBaseClassSpecifierNameImpl(); PDOMName name = base.getBaseClassSpecifierName();
if (name != null && name.getRecord() == nameRec) { if (name != null && name.getRecord() == nameRec) {
break; break;
} }
@ -157,8 +157,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
if (pdomBases != null) { if (pdomBases != null) {
ICPPBase[] result = null; ICPPBase[] result = null;
for (int i = 0; i < pdomBases.length; i++) { for (ICPPBase origBase : pdomBases) {
ICPPBase origBase = pdomBases[i];
ICPPBase specBase = (ICPPBase) ((ICPPInternalBase)origBase).clone(); ICPPBase specBase = (ICPPBase) ((ICPPInternalBase)origBase).clone();
IBinding origClass = origBase.getBaseClass(); IBinding origClass = origBase.getBaseClass();
if (origClass instanceof IType) { if (origClass instanceof IType) {
@ -271,8 +270,8 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
private ObjectMap specMap; private ObjectMap specMap;
public SpecializationFinder(IBinding[] specialized) { public SpecializationFinder(IBinding[] specialized) {
specMap = new ObjectMap(specialized.length); specMap = new ObjectMap(specialized.length);
for (int i = 0; i < specialized.length; i++) { for (IBinding element : specialized) {
specMap.put(specialized[i], null); specMap.put(element, null);
} }
} }
public boolean visit(IPDOMNode node) throws CoreException { public boolean visit(IPDOMNode node) throws CoreException {

View file

@ -16,7 +16,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IPDOMNode; import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
@ -36,11 +35,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalTemplateInstantiator; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalTemplateInstantiator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
@ -147,68 +144,11 @@ class PDOMCPPClassTemplate extends PDOMCPPClassType
return null; return null;
} }
@Override
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) throws DOMException {
try {
if (getDBName().equals(name.toCharArray())) {
if (CPPClassScope.isConstructorReference(name)) {
return CPPSemantics.resolveAmbiguities(name, getConstructors());
}
//9.2 ... The class-name is also inserted into the scope of the class itself
return this;
}
IndexFilter filter = new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return !(binding instanceof ICPPTemplateParameter || binding instanceof ICPPSpecialization);
}
@Override
public boolean acceptLinkage(ILinkage linkage) {
return linkage.getLinkageID() == ILinkage.CPP_LINKAGE_ID;
}
};
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), filter,
false, true);
accept(visitor);
return CPPSemantics.resolveAmbiguities(name, visitor.getBindings());
} catch (CoreException e) {
CCorePlugin.log(e);
}
return null;
}
@Override @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) protected void bindingsOfScopeAccept(IPDOMVisitor visitor) throws CoreException {
throws DOMException { // don't visit parameters and instances
IBinding[] result = null; super.accept(visitor);
try {
if ((!prefixLookup && getDBName().compare(name.toCharArray(), true) == 0)
|| (prefixLookup && getDBName().comparePrefix(name.toCharArray(), false) == 0)) {
// 9.2 ... The class-name is also inserted into the scope of
// the class itself
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, this);
}
IndexFilter filter = new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return !(binding instanceof ICPPTemplateParameter || binding instanceof ICPPSpecialization);
}
@Override
public boolean acceptLinkage(ILinkage linkage) {
return linkage.getLinkageID() == ILinkage.CPP_LINKAGE_ID;
}
};
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), filter,
prefixLookup, !prefixLookup);
accept(visitor);
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, visitor.getBindings());
} catch (CoreException e) {
CCorePlugin.log(e);
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }
private class PDOMCPPTemplateScope implements ICPPTemplateScope, IIndexScope { private class PDOMCPPTemplateScope implements ICPPTemplateScope, IIndexScope {

View file

@ -12,9 +12,10 @@
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -28,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -41,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.CharArrayMap;
import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope;
@ -73,6 +76,9 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 12; protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 12;
private static final int CACHE_MEMBERS= 0;
private static final int CACHE_BASES = 1;
public PDOMCPPClassType(PDOM pdom, PDOMNode parent, ICPPClassType classType) public PDOMCPPClassType(PDOM pdom, PDOMNode parent, ICPPClassType classType)
throws CoreException { throws CoreException {
super(pdom, parent, classType.getNameCharArray()); super(pdom, parent, classType.getNameCharArray());
@ -103,6 +109,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
} }
public void addMember(PDOMNode member) throws CoreException { public void addMember(PDOMNode member) throws CoreException {
pdom.removeCachedResult(record+CACHE_MEMBERS);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl()); PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl());
list.addMember(member); list.addMember(member);
} }
@ -117,7 +124,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
return IIndexCPPBindingConstants.CPPCLASSTYPE; return IIndexCPPBindingConstants.CPPCLASSTYPE;
} }
public PDOMCPPBase getFirstBase() throws CoreException { private PDOMCPPBase getFirstBase() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRSTBASE); int rec = pdom.getDB().getInt(record + FIRSTBASE);
return rec != 0 ? new PDOMCPPBase(pdom, rec) : null; return rec != 0 ? new PDOMCPPBase(pdom, rec) : null;
} }
@ -128,6 +135,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
} }
public void addBase(PDOMCPPBase base) throws CoreException { public void addBase(PDOMCPPBase base) throws CoreException {
pdom.removeCachedResult(record+CACHE_BASES);
PDOMCPPBase firstBase = getFirstBase(); PDOMCPPBase firstBase = getFirstBase();
base.setNextBase(firstBase); base.setNextBase(firstBase);
setFirstBase(base); setFirstBase(base);
@ -161,12 +169,18 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
} }
public ICPPBase[] getBases() throws DOMException { public ICPPBase[] getBases() throws DOMException {
Integer key= record + 1;
ICPPBase[] bases= (ICPPBase[]) pdom.getCachedResult(key);
if (bases != null)
return bases;
try { try {
List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>(); List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>();
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase())
list.add(base); list.add(base);
Collections.reverse(list); Collections.reverse(list);
ICPPBase[] bases = list.toArray(new ICPPBase[list.size()]); bases = list.toArray(new ICPPBase[list.size()]);
pdom.putCachedResult(key, bases);
return bases; return bases;
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
@ -184,7 +198,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPMethod[] getDeclaredMethods() throws DOMException { public ICPPMethod[] getDeclaredMethods() throws DOMException {
try { try {
PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false); PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false);
accept(methods); cachedBindingsAccept(methods);
return methods.getMethods(); return methods.getMethods();
} catch (CoreException e) { } catch (CoreException e) {
return new ICPPMethod[0]; return new ICPPMethod[0];
@ -263,7 +277,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPField[] getDeclaredFields() throws DOMException { public ICPPField[] getDeclaredFields() throws DOMException {
try { try {
PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector(); PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector();
accept(visitor); cachedBindingsAccept(visitor);
return visitor.getFields(); return visitor.getFields();
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
@ -288,7 +302,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPClassType[] getNestedClasses() throws DOMException { public ICPPClassType[] getNestedClasses() throws DOMException {
try { try {
NestedClassCollector visitor = new NestedClassCollector(); NestedClassCollector visitor = new NestedClassCollector();
accept(visitor); cachedBindingsAccept(visitor);
return visitor.getNestedClasses(); return visitor.getNestedClasses();
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
@ -296,6 +310,33 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
} }
} }
private void cachedBindingsAccept(IPDOMVisitor visitor) throws CoreException {
CharArrayMap<Object> map= getBindingMap();
for (Object obj : map.values()) {
if (obj instanceof List) {
for (Object binding : (List<?>)obj) {
if (binding instanceof IPDOMNode) {
final IPDOMNode node = (IPDOMNode) binding;
if (visitor.visit(node))
return;
visitor.leave(node);
}
}
}
else if (obj instanceof Object[]) {
Object[] array= (Object[]) obj;
for (Object binding : array) {
if (binding instanceof IPDOMNode) {
final IPDOMNode node = (IPDOMNode) binding;
if (visitor.visit(node))
return;
visitor.leave(node);
}
}
}
}
}
public IScope getCompositeScope() throws DOMException { public IScope getCompositeScope() throws DOMException {
return this; return this;
} }
@ -330,7 +371,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPConstructor[] getConstructors() throws DOMException { public ICPPConstructor[] getConstructors() throws DOMException {
PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector(); PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector();
try { try {
accept(visitor); cachedBindingsAccept(visitor);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
@ -377,7 +418,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
visitor.visit(this); visitor.visit(this);
} }
visitor.setVisitAnonymousClassTypes(true); visitor.setVisitAnonymousClassTypes(true);
accept(visitor); bindingsOfScopeAccept(visitor);
result= visitor.getBindings(); result= visitor.getBindings();
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
@ -385,21 +426,73 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
return result; return result;
} }
private IBinding[] getBindingsViaCache(final char[] name) throws CoreException { /**
final String key = pdom.createKeyForCache(record, name); * Return whether or not the nested binding should go into the cache.
IBinding[] result= (IBinding[]) pdom.getCachedResult(key); * @throws CoreException
if (result != null) { * @since 5.0
return result; */
protected boolean isBindingOfScope(IBinding member) throws CoreException {
return IndexFilter.ALL_DECLARED_OR_IMPLICIT.acceptBinding(member);
}
IBinding[] getBindingsViaCache(final char[] name) throws CoreException {
CharArrayMap<Object> map = getBindingMap();
Object result= map.get(name);
if (result instanceof IBinding[])
return (IBinding[]) result;
if (result instanceof List) {
final List<?> list = (List<?>) result;
final IBinding[] bresult= list.toArray(new IBinding[list.size()]);
map.put(name, bresult);
return bresult;
} }
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name, IndexFilter.ALL_DECLARED_OR_IMPLICIT, false, true); return IBinding.EMPTY_BINDING_ARRAY;
if (getDBName().compare(name, true) == 0) { }
private CharArrayMap<Object> getBindingMap() throws CoreException {
final Integer key= record;
@SuppressWarnings("unchecked")
Reference<CharArrayMap<Object>> cached= (Reference<CharArrayMap<Object>>) pdom.getCachedResult(key);
CharArrayMap<Object> map= cached == null ? null : cached.get();
if (map == null) {
// there is no cache, build it:
final CharArrayMap<Object> result= new CharArrayMap<Object>();
IPDOMVisitor visitor= new IPDOMVisitor() {
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof IBinding) {
final IBinding binding= (IBinding) node;
final char[] nchars = binding.getNameCharArray();
if (nchars.length > 0 && isBindingOfScope(binding)) {
@SuppressWarnings("unchecked")
List<IBinding> list= (List<IBinding>) result.get(nchars);
if (list == null) {
list= new ArrayList<IBinding>();
result.put(nchars, list);
}
list.add(binding);
if (binding instanceof ICompositeType && nchars[0] == '{') {
return true; // visit children
}
}
}
return false;
}
public void leave(IPDOMNode node){}
};
visitor.visit(this); visitor.visit(this);
bindingsOfScopeAccept(visitor);
map= result;
pdom.putCachedResult(key, new SoftReference<CharArrayMap<?>>(map));
} }
visitor.setVisitAnonymousClassTypes(true); return map;
accept(visitor); }
result = visitor.getBindings();
pdom.putCachedResult(key, result); protected void bindingsOfScopeAccept(IPDOMVisitor visitor) throws CoreException {
return result; this.accept(visitor);
} }
public IBinding[] find(String name) throws DOMException { public IBinding[] find(String name) throws DOMException {
@ -419,11 +512,13 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
} }
public void removeBase(PDOMName pdomName) throws CoreException { public void removeBase(PDOMName pdomName) throws CoreException {
pdom.removeCachedResult(record+CACHE_BASES);
PDOMCPPBase base= getFirstBase(); PDOMCPPBase base= getFirstBase();
PDOMCPPBase predecessor= null; PDOMCPPBase predecessor= null;
int nameRec= pdomName.getRecord(); int nameRec= pdomName.getRecord();
while (base != null) { while (base != null) {
PDOMName name = base.getBaseClassSpecifierNameImpl(); PDOMName name = base.getBaseClassSpecifierName();
if (name != null && name.getRecord() == nameRec) { if (name != null && name.getRecord() == nameRec) {
break; break;
} }

View file

@ -166,12 +166,12 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
return IIndexCPPBindingConstants.CPPFUNCTION; return IIndexCPPBindingConstants.CPPFUNCTION;
} }
public PDOMCPPParameter getFirstParameter() throws CoreException { private PDOMCPPParameter getFirstParameter() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRST_PARAM); int rec = pdom.getDB().getInt(record + FIRST_PARAM);
return rec != 0 ? new PDOMCPPParameter(pdom, rec) : null; return rec != 0 ? new PDOMCPPParameter(pdom, rec) : null;
} }
public void setFirstParameter(PDOMCPPParameter param) throws CoreException { private void setFirstParameter(PDOMCPPParameter param) throws CoreException {
if (param != null) if (param != null)
param.setNextParameter(getFirstParameter()); param.setNextParameter(getFirstParameter());
int rec = param != null ? param.getRecord() : 0; int rec = param != null ? param.getRecord() : 0;