1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 314428: speedup build console - better handle duplicate markers

This changes the algorithm used to handle duplicate markers when build
is running.

Change-Id: I8d8b61edd80ae4da4c0e0eea3806b0efecb570e0
This commit is contained in:
Jonah Graham 2016-12-13 00:36:14 +00:00
parent 88c6da2e40
commit f14ee6a61d
5 changed files with 189 additions and 37 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2010, 2016 Wind River Systems and others. * Copyright (c) 2010, 2017 Wind River 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
@ -125,7 +125,14 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
buildRunnerHelper.removeOldMarkers(project, new SubProgressMonitor(monitor, TICKS_DELETE_MARKERS, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); buildRunnerHelper.removeOldMarkers(project, new SubProgressMonitor(monitor, TICKS_DELETE_MARKERS, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
buildRunnerHelper.greeting(kind, cfgName, toolchainName, isSupported); buildRunnerHelper.greeting(kind, cfgName, toolchainName, isSupported);
int state = buildRunnerHelper.build(new SubProgressMonitor(monitor, TICKS_EXECUTE_COMMAND, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
int state;
epm.deferDeDuplication();
try {
state = buildRunnerHelper.build(new SubProgressMonitor(monitor, TICKS_EXECUTE_COMMAND, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
} finally {
epm.deDuplicate();
}
buildRunnerHelper.close(); buildRunnerHelper.close();
buildRunnerHelper.goodbye(); buildRunnerHelper.goodbye();

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2010, 2013 Wind River Systems and others. * Copyright (c) 2010, 2017 Wind River 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
@ -124,6 +124,9 @@ public class InternalBuildRunner extends AbstractBuildRunner {
OutputStream stderr = buildRunnerHelper.getErrorStream(); OutputStream stderr = buildRunnerHelper.getErrorStream();
int status; int status;
epm.deferDeDuplication();
try {
if (dBuilder != null) { if (dBuilder != null) {
status = dBuilder.build(stdout, stderr, new SubProgressMonitor(monitor, TICKS_EXECUTE_COMMAND, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); status = dBuilder.build(stdout, stderr, new SubProgressMonitor(monitor, TICKS_EXECUTE_COMMAND, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
} else { } else {
@ -136,9 +139,11 @@ public class InternalBuildRunner extends AbstractBuildRunner {
cBS.setState(0); cBS.setState(0);
buildRunnerHelper.printLine(ManagedMakeMessages.getFormattedString("CommonBuilder.7", Integer.toString(ParallelBuilder.lastThreadsUsed))); //$NON-NLS-1$ buildRunnerHelper.printLine(ManagedMakeMessages.getFormattedString("CommonBuilder.7", Integer.toString(ParallelBuilder.lastThreadsUsed))); //$NON-NLS-1$
} }
} finally {
epm.deDuplicate();
}
bsMngr.setProjectBuildState(project, pBS); bsMngr.setProjectBuildState(project, pBS);
buildRunnerHelper.close(); buildRunnerHelper.close();
buildRunnerHelper.goodbye(); buildRunnerHelper.goodbye();

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2016 IBM Corporation and others. * Copyright (c) 2005, 2017 IBM Corporation 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
@ -101,6 +101,8 @@ public class ErrorParserManager extends OutputStream implements IConsoleParser,
private URI cachedWorkingDirectory = null; private URI cachedWorkingDirectory = null;
private IFile cachedFile = null; private IFile cachedFile = null;
private boolean deferDeDuplication = false;
private static boolean isCygwin = true; private static boolean isCygwin = true;
/** /**
@ -599,6 +601,7 @@ outer:
if ( ! ProblemMarkerFilterManager.getInstance().acceptMarker(problemMarkerInfo) ) if ( ! ProblemMarkerFilterManager.getInstance().acceptMarker(problemMarkerInfo) )
return; return;
fErrors.add(problemMarkerInfo); fErrors.add(problemMarkerInfo);
problemMarkerInfo.setDeferDeDuplication(deferDeDuplication);
fMarkerGenerator.addMarker(problemMarkerInfo); fMarkerGenerator.addMarker(problemMarkerInfo);
if (problemMarkerInfo.severity == IMarkerGenerator.SEVERITY_ERROR_RESOURCE) { if (problemMarkerInfo.severity == IMarkerGenerator.SEVERITY_ERROR_RESOURCE) {
hasErrors = true; hasErrors = true;
@ -897,4 +900,29 @@ outer:
} }
} }
} }
/**
* Flag the marker generator to defer the de-duplication of error markers
* until {@link #deDuplicate()} is called
*
* @since 6.3
*/
public void deferDeDuplication() {
if (fMarkerGenerator instanceof ACBuilder) {
deferDeDuplication = true;
}
}
/**
* De-duplicate error markers on resource that have had error markers added
* since {@link #deferDeDuplication()} was called.
*
* @since 6.3
*/
public void deDuplicate() {
if (deferDeDuplication) {
deferDeDuplication = false;
((ACBuilder) fMarkerGenerator).deDuplicate();
}
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2015 Siemens AG and others. * Copyright (c) 2006, 2017 Siemens AG and others.
* All rights reserved. This content and the accompanying materials * All rights reserved. This content 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
@ -50,6 +50,12 @@ public class ProblemMarkerInfo {
private Map<String, String> attributes; private Map<String, String> attributes;
private String type; private String type;
/**
* Flag marker for potential deferred de-duplication. See
* {@link ACBuilder#deDuplicate()}
*/
private boolean deferDeDuplication;
/** /**
* Create a new {@link ProblemMarkerInfo} object. * Create a new {@link ProblemMarkerInfo} object.
* *
@ -161,4 +167,26 @@ public class ProblemMarkerInfo {
public void setType(String type){ public void setType(String type){
this.type = type; this.type = type;
} }
/**
* Flag marker for potential deferred de-duplication. See
* {@link ACBuilder#deDuplicate()}
*
* @return the deferDeDuplication
* @since 6.3
*/
public boolean isDeferDeDuplication() {
return deferDeDuplication;
}
/**
* Flag marker for potential deferred de-duplication. See
* {@link ACBuilder#deDuplicate()}
*
* @param deferDeDuplication the deferDeDuplication to set
* @since 6.3
*/
public void setDeferDeDuplication(boolean deferDeDuplication) {
this.deferDeDuplication = deferDeDuplication;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2000, 2016 QNX Software Systems and others. * Copyright (c) 2000, 2017 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
@ -9,13 +9,19 @@
* QNX Software Systems - Initial API and implementation * QNX Software Systems - Initial API and implementation
* IBM Corporation * IBM Corporation
* James Blackburn (Broadcom Corp.) * James Blackburn (Broadcom Corp.)
* Jonah Graham (Kichwa Coders) - Bug 314428: New implementation for removing duplicate error markers
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.resources; package org.eclipse.cdt.core.resources;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CCorePreferenceConstants; import org.eclipse.cdt.core.CCorePreferenceConstants;
@ -44,6 +50,7 @@ public abstract class ACBuilder extends IncrementalProjectBuilder implements IMa
protected static final boolean DEBUG_EVENTS = false; protected static final boolean DEBUG_EVENTS = false;
private IProject currentProject; private IProject currentProject;
private Set<IResource> resourcesToDeduplicate = new HashSet<>();
/** /**
* Constructor for ACBuilder * Constructor for ACBuilder
@ -80,6 +87,79 @@ public abstract class ACBuilder extends IncrementalProjectBuilder implements IMa
addMarker(problemMarkerInfo); addMarker(problemMarkerInfo);
} }
private static class MarkerWithInfo {
private static final String[] ATTRIBUTE_NAMES = new String[] { IMarker.LINE_NUMBER, IMarker.SEVERITY,
IMarker.MESSAGE, ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, IMarker.SOURCE_ID };
private Object[] attributes;
MarkerWithInfo(IMarker marker) throws CoreException {
attributes = marker.getAttributes(ATTRIBUTE_NAMES);
}
@Override
public int hashCode() {
return Arrays.hashCode(attributes);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MarkerWithInfo otherInfo = (MarkerWithInfo)obj;
return Arrays.equals(attributes, otherInfo.attributes);
}
}
/**
* Remove duplicate error markers that may have been created by
* {@link ACBuilder#addMarker(ProblemMarkerInfo)} with the
* {@link ProblemMarkerInfo#isDeferDeDuplication()} flag set.
*
* This method will also remove other duplicate
* ICModelMarker.C_MODEL_PROBLEM_MARKER markers on the resources referred to
* by ProblemMarkerInfo.
*
* @since 6.3
*/
public void deDuplicate() {
/*
* In practice it is actually faster to create all the markers and then
* remove duplicates than try to search on each marker creation if the
* marker already exists. This code is faster because it makes one pass
* through the markers, instead of one pass for each new marker. As
* getting attributes for makers is very expensive, only having to fetch
* marker attributes once per marker speeds things up considerably.
*/
for (IResource resource : resourcesToDeduplicate) {
try {
IMarker[] markers = resource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true,
IResource.DEPTH_ZERO);
List<IMarker> dups = new ArrayList<>(markers.length);
Set<MarkerWithInfo> unique = new HashSet<>(markers.length);
for (IMarker marker : markers) {
MarkerWithInfo info = new MarkerWithInfo(marker);
if (!unique.add(info)) {
dups.add(marker);
}
}
for (IMarker marker : dups) {
marker.delete();
}
} catch (CoreException e) {
CCorePlugin.log(e.getStatus());
}
}
resourcesToDeduplicate = new HashSet<>();
}
/** /**
* Callback from Output Parser * Callback from Output Parser
*/ */
@ -96,6 +176,7 @@ public abstract class ACBuilder extends IncrementalProjectBuilder implements IMa
externalLocation = problemMarkerInfo.externalPath.toOSString(); externalLocation = problemMarkerInfo.externalPath.toOSString();
} }
if (!problemMarkerInfo.isDeferDeDuplication()) {
// Try to find matching markers and don't put in duplicates // Try to find matching markers and don't put in duplicates
IMarker[] markers = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ONE); IMarker[] markers = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ONE);
for (IMarker m : markers) { for (IMarker m : markers) {
@ -115,6 +196,9 @@ public abstract class ACBuilder extends IncrementalProjectBuilder implements IMa
} }
} }
} }
} else {
resourcesToDeduplicate.add(markerResource);
}
String type = problemMarkerInfo.getType(); String type = problemMarkerInfo.getType();
if (type == null) { if (type == null) {