|
From: Christopher W. <caw...@us...> - 2005-03-30 00:12:42
|
Update of /cvsroot/rubyeclipse/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25424/src/org/rubypeople/rdt/internal/core/builder Modified Files: RubyBuilder.java Added Files: WorkQueue.java Log Message: update builder to allow cancelling. Attempt to speed the builder up by not recreating a parser and warnings object for every file. --- NEW FILE: WorkQueue.java --- /** * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.rubypeople.rdt.internal.core.builder; import java.util.ArrayList; import org.eclipse.core.resources.IFile; public class WorkQueue { ArrayList needsCompileList; ArrayList compiledList; public WorkQueue() { this.needsCompileList = new ArrayList(11); this.compiledList = new ArrayList(11); } public void add(IFile element) { needsCompileList.add(element); } public void addAll(IFile[] elements) { for (int i = 0, l = elements.length; i < l; i++) add(elements[i]); } public void clear() { this.needsCompileList.clear(); this.compiledList.clear(); } public void finished(IFile element) { needsCompileList.remove(element); compiledList.add(element); } public boolean isCompiled(IFile element) { return compiledList.contains(element); } public boolean isWaiting(IFile element) { return needsCompileList.contains(element); } public String toString() { return "WorkQueue: " + needsCompileList; //$NON-NLS-1$ } } Index: RubyBuilder.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/RubyBuilder.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** RubyBuilder.java 17 Mar 2005 01:11:30 -0000 1.6 --- RubyBuilder.java 30 Mar 2005 00:12:29 -0000 1.7 *************** *** 19,24 **** --- 19,26 ---- import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; + import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.jruby.lexer.yacc.SyntaxException; + import org.rubypeople.rdt.core.IRubyModelMarker; import org.rubypeople.rdt.core.RubyCore; import org.rubypeople.rdt.internal.core.parser.MarkerUtility; *************** *** 34,41 **** private static final boolean DEBUG = false; private IProject currentProject; private int totalWork = 10000; ! public RubyBuilder() {} /* --- 36,58 ---- private static final boolean DEBUG = false; + private static final int MAX_AT_ONCE = 1000; private IProject currentProject; private int totalWork = 10000; + private WorkQueue workQueue; + private boolean compiledAllAtOnce; + private int percentPerUnit = 0; + private int grandTotal = 0; ! private RdtWarnings warnings; ! private RubyParser parser; ! private TaskParser taskParser; ! ! public RubyBuilder() { ! this.workQueue = new WorkQueue(); ! warnings = new RdtWarnings(); ! parser = new RubyParser(warnings); ! IEclipsePreferences preferences = RubyCore.getInstancePreferences(); ! taskParser = new TaskParser(preferences); ! } /* *************** *** 50,56 **** this.currentProject = getProject(); if (currentProject == null || !currentProject.isAccessible()) return returnProjects; ! if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) { if (DEBUG) System.out.println("INCREMENTAL build..."); IResourceDelta delta = getDelta(currentProject); List files = getAffectedFiles(delta.getAffectedChildren()); --- 67,76 ---- this.currentProject = getProject(); if (currentProject == null || !currentProject.isAccessible()) return returnProjects; ! ! checkCancel(monitor); ! if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) { if (DEBUG) System.out.println("INCREMENTAL build..."); + workQueue.clear(); IResourceDelta delta = getDelta(currentProject); List files = getAffectedFiles(delta.getAffectedChildren()); *************** *** 58,64 **** --- 78,86 ---- System.arraycopy(files.toArray(), 0, fileArray, 0, fileArray.length); compile(fileArray, monitor); + cleanUp(); return returnProjects; } build(monitor); + cleanUp(); // FIXME Get the required projects as in JavaBuilder *************** *** 68,71 **** --- 90,108 ---- } + private void cleanUp() { + workQueue.clear(); + percentPerUnit = 0; + warnings.clear(); + } + + /** + * Check whether the build has been canceled. + * + * @param monitor + */ + public void checkCancel(IProgressMonitor monitor) { + if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); + } + private List getAffectedFiles(IResourceDelta[] deltas) { List files = new ArrayList(); *************** *** 90,93 **** --- 127,132 ---- try { + RubyBuilder.removeProblemsAndTasksFor(currentProject); + ArrayList sourceFiles = new ArrayList(33); addAllSourceFiles(sourceFiles); *************** *** 96,99 **** --- 135,140 ---- IFile[] allSourceFiles = new IFile[sourceFiles.size()]; sourceFiles.toArray(allSourceFiles); + workQueue.clear(); + workQueue.addAll(allSourceFiles); compile(allSourceFiles, monitor); } *************** *** 105,108 **** --- 146,160 ---- } + public static void removeProblemsAndTasksFor(IResource resource) { + try { + if (resource != null && resource.exists()) { + resource.deleteMarkers(IRubyModelMarker.RUBY_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + resource.deleteMarkers(IRubyModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE); + } + } catch (CoreException e) { + // assume there were no problems + } + } + protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException { currentProject.accept(new IResourceProxyVisitor() { *************** *** 129,147 **** protected void compile(IFile[] units, IProgressMonitor monitor) { int unitsLength = units.length; if (unitsLength == 0) { ! monitor.worked(totalWork); return; } ! ! int percentPerUnit = totalWork / unitsLength; // do them all now for (int i = 0; i < unitsLength; i++) { try { IFile file = units[i]; if (DEBUG) System.out.println("About to compile " + file); //$NON-NLS-1$ ! RdtWarnings warnings = new RdtWarnings(); ! RubyParser parser = new RubyParser(warnings); MarkerUtility.removeMarkers(file); ! try { parser.parse(units[i].getName(), new InputStreamReader(file.getContents())); } catch (SyntaxException e) { --- 181,239 ---- protected void compile(IFile[] units, IProgressMonitor monitor) { int unitsLength = units.length; + grandTotal = unitsLength; + percentPerUnit = totalWork / unitsLength; + + this.compiledAllAtOnce = unitsLength <= MAX_AT_ONCE; + if (this.compiledAllAtOnce) { + // do them all now + doCompile(units, null); + } else { + int i = 0; + boolean compilingFirstGroup = true; + while (i < unitsLength) { + int doNow = unitsLength < MAX_AT_ONCE ? unitsLength : MAX_AT_ONCE; + int index = 0; + IFile[] toCompile = new IFile[doNow]; + while (i < unitsLength && index < doNow) { + // Although it needed compiling when this method was called, + // it may have + // already been compiled when it was referenced by another + // unit. + IFile unit = units[i++]; + if (compilingFirstGroup || workQueue.isWaiting(unit)) { + toCompile[index++] = unit; + } + } + if (index < doNow) System.arraycopy(toCompile, 0, toCompile = new IFile[index], 0, index); + IFile[] additionalUnits = new IFile[unitsLength - i]; + System.arraycopy(units, i, additionalUnits, 0, additionalUnits.length); + compilingFirstGroup = false; + doCompile(toCompile, monitor); + } + } + } + + /* + * Compile the given elements, adding more elements to the work queue if + * they are affected by the changes. + */ + protected void doCompile(IFile[] units, IProgressMonitor monitor) { + int unitsLength = units.length; if (unitsLength == 0) { ! monitor.worked(unitsLength * percentPerUnit); return; } ! // do them all now for (int i = 0; i < unitsLength; i++) { + checkCancel(monitor); try { IFile file = units[i]; if (DEBUG) System.out.println("About to compile " + file); //$NON-NLS-1$ ! String name = file.getFullPath().makeRelative().toString(); ! monitor.subTask(name + ": (" + i + " of " + grandTotal + ")"); ! MarkerUtility.removeMarkers(file); ! try { parser.parse(units[i].getName(), new InputStreamReader(file.getContents())); } catch (SyntaxException e) { *************** *** 149,152 **** --- 241,245 ---- } MarkerUtility.createProblemMarkers(file, warnings.getWarnings()); + warnings.clear(); createTasks(file); monitor.worked(percentPerUnit); *************** *** 155,164 **** } } ! } private void createTasks(IFile file) throws CoreException { - IEclipsePreferences preferences = RubyCore.getInstancePreferences(); - TaskParser taskParser = new TaskParser(preferences); taskParser.parse(new InputStreamReader(file.getContents())); MarkerUtility.createTasks(file, taskParser.getTasks()); --- 248,255 ---- } } ! checkCancel(monitor); } private void createTasks(IFile file) throws CoreException { taskParser.parse(new InputStreamReader(file.getContents())); MarkerUtility.createTasks(file, taskParser.getTasks()); |