diff options
author | Benno Baumgartner | 2007-09-03 15:07:32 +0000 |
---|---|---|
committer | Benno Baumgartner | 2007-09-03 15:07:32 +0000 |
commit | f8019ed032daaf9f8f71eea12cdd1203b2e58445 (patch) | |
tree | ef2d9b688fa5f2cc40c0cd6877ac3c0b6b726656 | |
parent | fbe5748f0a2d1a9b0eaa2733ef2a0c21ae15c4f3 (diff) | |
download | eclipse.jdt.ui-f8019ed032daaf9f8f71eea12cdd1203b2e58445.tar.gz eclipse.jdt.ui-f8019ed032daaf9f8f71eea12cdd1203b2e58445.tar.xz eclipse.jdt.ui-f8019ed032daaf9f8f71eea12cdd1203b2e58445.zip |
Bug 132121 [clean up] Use heapsize info to decide about number of AST to build
2 files changed, 196 insertions, 74 deletions
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTBatchParser.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTBatchParser.java new file mode 100644 index 0000000000..3530171905 --- /dev/null +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTBatchParser.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.dom; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.ASTRequestor; +import org.eclipse.jdt.core.dom.IBinding; + +/** + * Creates AST from a set of compilation units. Uses the + * batch parser. Splits the set of compilation units in subsets + * such that it is unlikely that a out of memory exception will occur. + * + * @since 3.4 + */ +public class ASTBatchParser { + + private static final int MAX_AT_ONCE; + static { + long maxMemory= Runtime.getRuntime().maxMemory(); + int ratio= (int) Math.round((double) maxMemory / (64 * 0x100000)); + switch (ratio) { + case 0: + MAX_AT_ONCE= 25; + break; + case 1: + MAX_AT_ONCE= 100; + break; + case 2: + MAX_AT_ONCE= 200; + break; + case 3: + MAX_AT_ONCE= 300; + break; + case 4: + MAX_AT_ONCE= 400; + break; + default: + MAX_AT_ONCE= 500; + break; + } + } + + /** + * Creates ASTs for each compilation unit in <code>units</code>. + * <p> + * <code>ASTRequestor.acceptAST</code> is called in no particular order to + * pass the compilation unit and the corresponding AST to <code>requestor</code>. + * </p> + * <p> + * The <code>bindingKeys</code> parameter specifies bindings keys + * ({@link IBinding#getKey()}) that are to be looked up. + * </p> + * + * @param compilationUnits the compilation units to create ASTs for + * @param bindingKeys the binding keys to create bindings for + * @param requestor the AST requestor that collects abstract syntax trees and bindings + * @param monitor the progress monitor used to report progress and request cancelation, + * or <code>null</code> if none + * @see ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor) + */ + public final void createASTs(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor requestor, IProgressMonitor monitor) { + if (compilationUnits.length == 0) + return; + + if (monitor == null) + monitor= new NullProgressMonitor(); + + monitor.beginTask("", compilationUnits.length); //$NON-NLS-1$ + try { + + ICompilationUnit[][] splited= splitByProject(compilationUnits); + for (int i= 0; i < splited.length; i++) { + ICompilationUnit[] units= splited[i]; + + if (units.length <= MAX_AT_ONCE) { + createParser(units[0].getJavaProject()).createASTs(units, bindingKeys, requestor, new SubProgressMonitor(monitor, units.length)); + } else { + List list= Arrays.asList(units); + int end= 0; + int cursor= 0; + while (cursor < units.length) { + end= Math.min(end + MAX_AT_ONCE, units.length); + List toParse= list.subList(cursor, end); + + createParser(units[0].getJavaProject()).createASTs((ICompilationUnit[]) toParse.toArray(new ICompilationUnit[toParse.size()]), bindingKeys, requestor, + new SubProgressMonitor(monitor, toParse.size())); + cursor= end; + } + } + } + } finally { + monitor.done(); + } + } + + /** + * Creates a new parser which can be used to create ASTs + * for compilation units in <code>project</code> + * <p> + * Subclasses may override + * </p> + * + * @param project the project for which ASTs are been generated + * @return an AST parser capable of creating ASTs of compilation units in project + */ + protected ASTParser createParser(IJavaProject project) { + ASTParser result= ASTParser.newParser(AST.JLS3); + result.setResolveBindings(true); + result.setProject(project); + + return result; + } + + private static ICompilationUnit[][] splitByProject(ICompilationUnit[] units) { + if (hasOnlyOneProject(units)) + return new ICompilationUnit[][] { units }; + + Hashtable projectTable= new Hashtable(); + + for (int i= 0; i < units.length; i++) { + ICompilationUnit unit= units[i]; + ArrayList list= (ArrayList) projectTable.get(unit.getJavaProject()); + if (list == null) { + list= new ArrayList(); + projectTable.put(unit.getJavaProject(), list); + } + list.add(unit); + } + + Collection values= projectTable.values(); + + ICompilationUnit[][] result= new ICompilationUnit[values.size()][]; + int i= 0; + for (Iterator iterator= values.iterator(); iterator.hasNext();) { + ArrayList cus= (ArrayList) iterator.next(); + result[i]= (ICompilationUnit[]) cus.toArray(new ICompilationUnit[cus.size()]); + i++; + } + + return result; + } + + private static boolean hasOnlyOneProject(ICompilationUnit[] units) { + IJavaProject javaProject= units[0].getJavaProject(); + for (int i= 1; i < units.length; i++) { + if (!javaProject.equals(units[i].getJavaProject())) + return false; + } + + return true; + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpRefactoring.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpRefactoring.java index 8e33f384d8..c649e96ef7 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpRefactoring.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpRefactoring.java @@ -11,7 +11,6 @@ package org.eclipse.jdt.internal.corext.fix; import java.util.ArrayList; -import java.util.Arrays; import java.util.Hashtable; import java.util.Iterator; import java.util.List; @@ -57,6 +56,7 @@ import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTRequestor; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.internal.corext.dom.ASTBatchParser; import org.eclipse.jdt.internal.corext.refactoring.Checks; import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange; import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange; @@ -271,71 +271,16 @@ public class CleanUpRefactoring extends Refactoring implements IScheduledRefacto } } - private static abstract class CleanUpParser { - - private static final int MAX_AT_ONCE; - static { - long maxMemory= Runtime.getRuntime().maxMemory(); - int ratio= (int)Math.round((double)maxMemory / (64 * 0x100000)); - switch (ratio) { - case 0: - MAX_AT_ONCE= 25; - break; - case 1: - MAX_AT_ONCE= 100; - break; - case 2: - MAX_AT_ONCE= 200; - break; - case 3: - MAX_AT_ONCE= 300; - break; - case 4: - MAX_AT_ONCE= 400; - break; - default: - MAX_AT_ONCE= 500; - break; - } - } - - public void createASTs(ICompilationUnit[] units, String[] bindingKeys, CleanUpASTRequestor requestor, IProgressMonitor monitor) { - if (monitor == null) - monitor= new NullProgressMonitor(); - - try { - monitor.beginTask("", units.length); //$NON-NLS-1$ - - List list= Arrays.asList(units); - int end= 0; - int cursor= 0; - while (cursor < units.length) { - end= Math.min(end + MAX_AT_ONCE, units.length); - List toParse= list.subList(cursor, end); - - createParser().createASTs((ICompilationUnit[])toParse.toArray(new ICompilationUnit[toParse.size()]), bindingKeys, requestor, new SubProgressMonitor(monitor, toParse.size())); - cursor= end; - } - } finally { - monitor.done(); - } - } - - protected abstract ASTParser createParser(); - } - private class CleanUpFixpointIterator { private List/*<ParseListElement>*/fParseList; private final Hashtable/*<ICompilationUnit, List<CleanUpChange>>*/fSolutions; private final Hashtable/*<ICompilationUnit (primary), ICompilationUnit (working copy)>*/fWorkingCopies; - private final IJavaProject fProject; private final Map fCleanUpOptions; private final int fSize; private int fIndex; - public CleanUpFixpointIterator(IJavaProject project, ICompilationUnit[] units, ICleanUp[] cleanUps) { - fProject= project; + public CleanUpFixpointIterator(ICompilationUnit[] units, ICleanUp[] cleanUps) { fSolutions= new Hashtable(units.length); fWorkingCopies= new Hashtable(); @@ -388,23 +333,25 @@ public class CleanUpRefactoring extends Refactoring implements IScheduledRefacto CleanUpRefactoringProgressMonitor cuMonitor= new CleanUpRefactoringProgressMonitor(monitor, parseList.size() + sourceList.size(), fSize, fIndex); CleanUpASTRequestor requestor= new CleanUpASTRequestor(fParseList, fSolutions, cuMonitor); - CleanUpParser parser= new CleanUpParser() { - protected ASTParser createParser() { - ASTParser result= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL); - result.setResolveBindings(true); - result.setProject(fProject); - - Map options= RefactoringASTParser.getCompilerOptions(fProject); - options.putAll(fCleanUpOptions); - result.setCompilerOptions(options); - return result; + if (parseList.size() > 0) { + ASTBatchParser parser= new ASTBatchParser() { + protected ASTParser createParser(IJavaProject project) { + ASTParser result= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL); + result.setResolveBindings(true); + result.setProject(project); + + Map options= RefactoringASTParser.getCompilerOptions(project); + options.putAll(fCleanUpOptions); + result.setCompilerOptions(options); + return result; + } + }; + try { + ICompilationUnit[] units= (ICompilationUnit[])parseList.toArray(new ICompilationUnit[parseList.size()]); + parser.createASTs(units, new String[0], requestor, cuMonitor); + } catch (FixCalculationException e) { + throw e.getException(); } - }; - try { - ICompilationUnit[] units= (ICompilationUnit[])parseList.toArray(new ICompilationUnit[parseList.size()]); - parser.createASTs(units, new String[0], requestor, cuMonitor); - } catch (FixCalculationException e) { - throw e.getException(); } for (Iterator iterator= sourceList.iterator(); iterator.hasNext();) { @@ -697,7 +644,7 @@ public class CleanUpRefactoring extends Refactoring implements IScheduledRefacto } private Change[] cleanUpProject(IJavaProject project, ICompilationUnit[] compilationUnits, ICleanUp[] cleanUps, IProgressMonitor monitor) throws CoreException { - CleanUpFixpointIterator iter= new CleanUpFixpointIterator(project, compilationUnits, cleanUps); + CleanUpFixpointIterator iter= new CleanUpFixpointIterator(compilationUnits, cleanUps); SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, 2 * compilationUnits.length * cleanUps.length); subMonitor.beginTask("", compilationUnits.length); //$NON-NLS-1$ |