mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
CModelBuilder and scalability problems
This commit is contained in:
parent
54490364bb
commit
9e4f258b9a
11 changed files with 75 additions and 143 deletions
|
@ -1,3 +1,8 @@
|
|||
2004-04-12 Hoda Amer
|
||||
CModelBuilder and scalability problems: Building the CModel takes a long time
|
||||
when translation unit has lots of children (25,000 children taking ~ 45 sec to build model).
|
||||
Revising Parent.addChild() and TranslationUnit.removeChildren() (now 25,000 children taking ~ 160 ms).
|
||||
|
||||
2004-04-07 David Inglis
|
||||
|
||||
Fixed event problem
|
||||
|
|
|
@ -213,9 +213,7 @@ public class CContainer extends Openable implements ICContainer {
|
|||
//e.printStackTrace();
|
||||
throw new CModelException(e);
|
||||
}
|
||||
ICElement[] children = new ICElement[vChildren.size()];
|
||||
vChildren.toArray(children);
|
||||
info.setChildren(children);
|
||||
info.setChildren(vChildren);
|
||||
if (info instanceof CContainerInfo) {
|
||||
((CContainerInfo) info).setNonCResources(null);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ package org.eclipse.cdt.internal.core.model;
|
|||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
|
@ -16,11 +18,6 @@ import org.eclipse.core.resources.IResource;
|
|||
*/
|
||||
class CElementInfo {
|
||||
|
||||
/**
|
||||
* Shared empty collection used for efficiency.
|
||||
*/
|
||||
static Object[] NO_NON_C_RESOURCES = new Object[] {};
|
||||
|
||||
protected CElement element;
|
||||
|
||||
/**
|
||||
|
@ -28,12 +25,7 @@ class CElementInfo {
|
|||
* object. This is an empty array if this element has
|
||||
* no children.
|
||||
*/
|
||||
protected ICElement[] fChildren;
|
||||
|
||||
/**
|
||||
* Shared empty collection used for efficiency.
|
||||
*/
|
||||
protected static ICElement[] fgEmptyChildren = new ICElement[]{};
|
||||
protected List fChildren;
|
||||
|
||||
/**
|
||||
* Is the structure of this element known
|
||||
|
@ -45,7 +37,7 @@ class CElementInfo {
|
|||
|
||||
protected CElementInfo(CElement element) {
|
||||
this.element = element;
|
||||
fChildren = fgEmptyChildren;
|
||||
fChildren = new ArrayList();
|
||||
}
|
||||
|
||||
protected CElement getElement() {
|
||||
|
@ -53,41 +45,21 @@ class CElementInfo {
|
|||
}
|
||||
|
||||
protected void addChild(ICElement child) {
|
||||
if (fChildren == fgEmptyChildren) {
|
||||
setChildren(new ICElement[] {child});
|
||||
} else {
|
||||
if (!includesChild(child)) {
|
||||
setChildren(growAndAddToArray(fChildren, child));
|
||||
}
|
||||
}
|
||||
fChildren.add(child);
|
||||
}
|
||||
|
||||
protected ICElement[] getChildren() {
|
||||
return fChildren;
|
||||
ICElement[] array= new ICElement[fChildren.size()];
|
||||
return (ICElement[]) fChildren.toArray( array );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new element to a new array that contains all of the elements of the old array.
|
||||
* Returns the new array.
|
||||
*/
|
||||
protected ICElement[] growAndAddToArray(ICElement[] array, ICElement addition) {
|
||||
ICElement[] old = array;
|
||||
array = new ICElement[old.length + 1];
|
||||
System.arraycopy(old, 0, array, 0, old.length);
|
||||
array[old.length] = addition;
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this child is in my children collection
|
||||
*/
|
||||
protected boolean includesChild(ICElement child) {
|
||||
|
||||
for (int i= 0; i < fChildren.length; i++) {
|
||||
if (fChildren[i].equals(child)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(fChildren.contains(child))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -98,42 +70,20 @@ class CElementInfo {
|
|||
return fIsStructureKnown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all the same elements as the specified array except for
|
||||
* the element to remove. Assumes that the deletion is contained in the array.
|
||||
*/
|
||||
protected ICElement[] removeAndShrinkArray(ICElement[] array, ICElement deletion) {
|
||||
ICElement[] old = array;
|
||||
array = new ICElement[old.length - 1];
|
||||
int j = 0;
|
||||
for (int i = 0; i < old.length; i++) {
|
||||
if (!old[i].equals(deletion)) {
|
||||
array[j] = old[i];
|
||||
} else {
|
||||
System.arraycopy(old, i + 1, array, j, old.length - (i + 1));
|
||||
return array;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
protected void removeChild(ICElement child) {
|
||||
if (includesChild(child)) {
|
||||
setChildren(removeAndShrinkArray(fChildren, child));
|
||||
}
|
||||
fChildren.remove(child);
|
||||
}
|
||||
|
||||
protected void removeChildren () {
|
||||
fChildren = fgEmptyChildren;
|
||||
fChildren.clear();
|
||||
}
|
||||
|
||||
protected void setChildren(ICElement[] children) {
|
||||
fChildren = children;
|
||||
protected void setChildren(List children) {
|
||||
fChildren.addAll(children);
|
||||
}
|
||||
|
||||
protected boolean hasChildren() {
|
||||
return fChildren.length > 0;
|
||||
return fChildren.size() > 0;
|
||||
}
|
||||
|
||||
protected void setChanged() {
|
||||
|
|
|
@ -150,6 +150,7 @@ public class CModelBuilder {
|
|||
|
||||
|
||||
public Map parse(boolean quickParseMode) throws Exception {
|
||||
long startTime = System.currentTimeMillis();
|
||||
try
|
||||
{
|
||||
compilationUnit = parse( translationUnit, quickParseMode, true);
|
||||
|
@ -160,7 +161,9 @@ public class CModelBuilder {
|
|||
Util.debugLog( "Parse Exception in CModelBuilder", IDebugLogConstants.MODEL ); //$NON-NLS-1$
|
||||
//e.printStackTrace();
|
||||
}
|
||||
long startTime = System.currentTimeMillis();
|
||||
Util.debugLog("CModel parsing: "+ ( System.currentTimeMillis() - startTime ) + "ms", IDebugLogConstants.MODEL); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
try
|
||||
{
|
||||
generateModelElements();
|
||||
|
@ -170,13 +173,12 @@ public class CModelBuilder {
|
|||
catch( NullPointerException npe )
|
||||
{
|
||||
Util.debugLog( "NullPointer exception in CModelBuilder", IDebugLogConstants.MODEL); //$NON-NLS-1$
|
||||
//npe.printStackTrace();
|
||||
}
|
||||
|
||||
// For the debuglog to take place, you have to call
|
||||
// Util.setDebugging(true);
|
||||
// Or set debug to true in the core plugin preference
|
||||
Util.debugLog("CModel build: "+ ( System.currentTimeMillis() - startTime ) + "ms", IDebugLogConstants.MODEL); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
Util.debugLog("CModel building: "+ ( System.currentTimeMillis() - startTime ) + "ms", IDebugLogConstants.MODEL); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
return this.newElements;
|
||||
|
||||
}
|
||||
|
@ -344,6 +346,7 @@ public class CModelBuilder {
|
|||
element.setLines( macro.getStartingLine(), macro.getEndingLine() );
|
||||
this.newElements.put(element, element.getElementInfo());
|
||||
return element;
|
||||
|
||||
}
|
||||
|
||||
private Namespace createNamespace(Parent parent, IASTNamespaceDefinition nsDef){
|
||||
|
@ -656,4 +659,10 @@ public class CModelBuilder {
|
|||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the newElements.
|
||||
*/
|
||||
public Map getNewElements() {
|
||||
return newElements;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class CModelInfo extends OpenableInfo {
|
|||
}
|
||||
}
|
||||
if (index == 0) {
|
||||
return NO_NON_C_RESOURCES;
|
||||
return new Object[] {}; // NO_NON_C_RESOURCES
|
||||
}
|
||||
if (index < length) {
|
||||
System.arraycopy(nonCProjects, 0, nonCProjects = new Object[index], 0, index);
|
||||
|
|
|
@ -4,6 +4,9 @@ package org.eclipse.cdt.internal.core.model;
|
|||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ICModelStatus;
|
||||
|
@ -24,7 +27,7 @@ public class CModelStatus extends Status implements ICModelStatus, ICModelStatus
|
|||
* The elements related to the failure, or <code>null</code>
|
||||
* if no elements are involved.
|
||||
*/
|
||||
protected ICElement[] fElements = new ICElement[0];
|
||||
protected List fElements = new ArrayList();
|
||||
/**
|
||||
* The path related to the failure, or <code>null</code>
|
||||
* if no path is involved.
|
||||
|
@ -59,7 +62,7 @@ public class CModelStatus extends Status implements ICModelStatus, ICModelStatus
|
|||
*/
|
||||
public CModelStatus(int code) {
|
||||
super(ERROR, CCorePlugin.PLUGIN_ID, code, "CModelStatus", null); //$NON-NLS-1$
|
||||
fElements= CElementInfo.fgEmptyChildren;
|
||||
fElements.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,7 +71,8 @@ public class CModelStatus extends Status implements ICModelStatus, ICModelStatus
|
|||
*/
|
||||
public CModelStatus(int code, ICElement[] elements) {
|
||||
super(ERROR, CCorePlugin.PLUGIN_ID, code, "CModelStatus", null); //$NON-NLS-1$
|
||||
fElements= elements;
|
||||
for(int i=0; i<elements.length; ++i)
|
||||
fElements.add(elements[i]);
|
||||
fPath= null;
|
||||
}
|
||||
|
||||
|
@ -81,7 +85,7 @@ public class CModelStatus extends Status implements ICModelStatus, ICModelStatus
|
|||
|
||||
public CModelStatus(int severity, int code, String string) {
|
||||
super(severity, CCorePlugin.PLUGIN_ID, code, "CModelStatus", null); //$NON-NLS-1$
|
||||
fElements= CElementInfo.fgEmptyChildren;
|
||||
fElements.clear();
|
||||
fPath= null;
|
||||
fString = string;
|
||||
}
|
||||
|
@ -91,7 +95,7 @@ public class CModelStatus extends Status implements ICModelStatus, ICModelStatus
|
|||
*/
|
||||
public CModelStatus(int code, Throwable throwable) {
|
||||
super(ERROR, CCorePlugin.PLUGIN_ID, code, "CModelStatus", throwable); //$NON-NLS-1$
|
||||
fElements= CElementInfo.fgEmptyChildren;
|
||||
fElements.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +103,7 @@ public class CModelStatus extends Status implements ICModelStatus, ICModelStatus
|
|||
*/
|
||||
public CModelStatus(int code, IPath path) {
|
||||
super(ERROR, CCorePlugin.PLUGIN_ID, code, "CModelStatus", null); //$NON-NLS-1$
|
||||
fElements= CElementInfo.fgEmptyChildren;
|
||||
fElements.clear();
|
||||
fPath= path;
|
||||
}
|
||||
|
||||
|
@ -150,7 +154,7 @@ public class CModelStatus extends Status implements ICModelStatus, ICModelStatus
|
|||
* @see ICModelStatus
|
||||
*/
|
||||
public ICElement[] getElements() {
|
||||
return fElements;
|
||||
return (ICElement[])fElements.toArray(new ICElement[fElements.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCProjectNature;
|
||||
|
@ -425,8 +426,6 @@ public class CProject extends Openable implements ICProject {
|
|||
System.arraycopy(children, 0, roots, 0, length);
|
||||
|
||||
return roots;
|
||||
|
||||
//return computeSourceRoots();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,10 +440,10 @@ public class CProject extends Openable implements ICProject {
|
|||
if (pinfo.sourceRoots != null) {
|
||||
roots = pinfo.sourceRoots;
|
||||
} else {
|
||||
roots = pinfo.sourceRoots = computeSourceRoots();
|
||||
roots = pinfo.sourceRoots = (ISourceRoot[])computeSourceRoots().toArray(new ISourceRoot[computeSourceRoots().size()]);
|
||||
}
|
||||
} else {
|
||||
roots = computeSourceRoots();
|
||||
roots = (ISourceRoot[])computeSourceRoots().toArray(new ISourceRoot[computeSourceRoots().size()]);
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
@ -535,7 +534,7 @@ public class CProject extends Openable implements ICProject {
|
|||
return validInfo;
|
||||
}
|
||||
|
||||
protected ISourceRoot[] computeSourceRoots() throws CModelException {
|
||||
protected List computeSourceRoots() throws CModelException {
|
||||
IPathEntry[] entries = getResolvedPathEntries();
|
||||
ArrayList list = new ArrayList(entries.length);
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
|
@ -547,9 +546,7 @@ public class CProject extends Openable implements ICProject {
|
|||
}
|
||||
}
|
||||
}
|
||||
ISourceRoot[] roots = new ISourceRoot[list.size()];
|
||||
list.toArray(roots);
|
||||
return roots;
|
||||
return list;
|
||||
}
|
||||
|
||||
protected boolean computeSourceRoots(OpenableInfo info, IResource res) throws CModelException {
|
||||
|
|
|
@ -114,9 +114,7 @@ public class IncludeReference extends Openable implements IIncludeReference {
|
|||
}
|
||||
}
|
||||
}
|
||||
ICElement[] children = new ICElement[vChildren.size()];
|
||||
vChildren.toArray(children);
|
||||
info.setChildren(children);
|
||||
info.setChildren(vChildren);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,9 +78,7 @@ public class SourceRoot extends CContainer implements ISourceRoot {
|
|||
//e.printStackTrace();
|
||||
throw new CModelException(e);
|
||||
}
|
||||
ICElement[] children = new ICElement[vChildren.size()];
|
||||
vChildren.toArray(children);
|
||||
info.setChildren(children);
|
||||
info.setChildren(vChildren);
|
||||
if (info instanceof CContainerInfo) {
|
||||
((CContainerInfo) info).setNonCResources(null);
|
||||
}
|
||||
|
|
|
@ -11,20 +11,24 @@ import java.util.Iterator;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.model.*;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.IBuffer;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.IInclude;
|
||||
import org.eclipse.cdt.core.model.IParent;
|
||||
import org.eclipse.cdt.core.model.ISourceManipulation;
|
||||
import org.eclipse.cdt.core.model.ISourceRange;
|
||||
import org.eclipse.cdt.core.model.ISourceReference;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IUsing;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
|
||||
/**
|
||||
* @see ITranslationUnit
|
||||
|
@ -473,19 +477,28 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
* Parse the buffer contents of this element.
|
||||
*/
|
||||
public Map parse(){
|
||||
removeChildren(this);
|
||||
final CModelBuilder modelBuilder = new CModelBuilder(this);
|
||||
final boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode());
|
||||
try {
|
||||
removeChildren();
|
||||
CModelBuilder modelBuilder = new CModelBuilder(this);
|
||||
|
||||
boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode());
|
||||
return modelBuilder.parse(quickParseMode);
|
||||
return modelBuilder.parse(quickParseMode);
|
||||
} catch (Exception e) {
|
||||
// FIXME: use the debug log for this exception.
|
||||
//System.out.println(e);
|
||||
// use the debug log for this exception.
|
||||
Util.debugLog( "Exception in CModelBuilder", IDebugLogConstants.MODEL); //$NON-NLS-1$
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeChildren(ICElement element){
|
||||
if (element instanceof Parent){
|
||||
Parent parent = (Parent) element;
|
||||
ICElement[] children = parent.getChildren();
|
||||
for(int i =0; i< children.length; ++i){
|
||||
removeChildren(children[i]);
|
||||
}
|
||||
parent.removeChildren();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ package org.eclipse.cdt.internal.core.model;
|
|||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ISourceRange;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
|
@ -24,45 +23,6 @@ class TranslationUnitInfo extends OpenableInfo {
|
|||
super(element);
|
||||
}
|
||||
|
||||
protected boolean hasChildren() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ICElement [] getChildren() {
|
||||
// CHECKPOINT: replacing the parsing done here before
|
||||
return fChildren;
|
||||
}
|
||||
/*
|
||||
protected Map parse(InputStream in, boolean requiresLineNumbers) {
|
||||
try {
|
||||
removeChildren();
|
||||
if (CCorePlugin.getDefault().useNewParser()) {
|
||||
// new parser
|
||||
CModelBuilder modelBuilder = new CModelBuilder((TranslationUnit)getElement());
|
||||
return (modelBuilder.parse(requiresLineNumbers));
|
||||
|
||||
} else {
|
||||
// cdt 1.0 parser
|
||||
ModelBuilder modelBuilder= new ModelBuilder((TranslationUnit)getElement());
|
||||
CStructurizer.getCStructurizer().parse(modelBuilder, in);
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Map parse(String buf, boolean requiresLineNumbers) {
|
||||
// CHECKPOINT: Parsing a string using the StringBufferInputStream
|
||||
// FIXME: quick fix for the IBinary which uses fake translationUnit
|
||||
if (buf != null) {
|
||||
StringBufferInputStream in = new StringBufferInputStream (buf);
|
||||
return (parse (in, requiresLineNumbers));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
/* Overide the SourceManipulation for the range. */
|
||||
protected ISourceRange getSourceRange() {
|
||||
IPath location = ((TranslationUnit)getElement()).getLocation();
|
||||
|
|
Loading…
Add table
Reference in a new issue