< prev index next >
application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/common/ThreadGraphLanes.java
Print this page
@@ -1,7 +1,8 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The contents of this file are subject to the terms of either the Universal Permissive License
* v 1.0 as shown at http://oss.oracle.com/licenses/upl
@@ -40,10 +41,11 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -59,10 +61,11 @@
import org.openjdk.jmc.common.item.IItem;
import org.openjdk.jmc.common.item.IItemCollection;
import org.openjdk.jmc.common.item.IItemFilter;
import org.openjdk.jmc.common.item.IItemIterable;
import org.openjdk.jmc.common.item.ItemFilters;
+import org.openjdk.jmc.common.item.ItemFilters.Types;
import org.openjdk.jmc.common.unit.IQuantity;
import org.openjdk.jmc.flightrecorder.JfrAttributes;
import org.openjdk.jmc.flightrecorder.jdk.JdkFilters;
import org.openjdk.jmc.flightrecorder.jdk.JdkTypeIDs;
import org.openjdk.jmc.flightrecorder.ui.EventTypeFolderNode;
@@ -92,20 +95,29 @@
private List<LaneDefinition> naLanes;
private Supplier<StreamModel> dataSourceSupplier;
private Runnable buildChart;
private List<IAction> actions;
private String tooltipTitle;
+ private EventTypeFolderNode typeTree;
+ private boolean quickFilterExist;
public ThreadGraphLanes(Supplier<StreamModel> dataSourceSupplier, Runnable buildChart) {
this.dataSourceSupplier = dataSourceSupplier;
this.buildChart = buildChart;
this.actions = new ArrayList<>();
+ this.quickFilterExist = false;
+ this.typeTree = dataSourceSupplier.get().getTypeTree(ItemCollectionToolkit
+ .stream(dataSourceSupplier.get().getItems()).filter(this::typeWithThreadAndDuration));
+ }
+
+ protected EventTypeFolderNode getTypeTree() {
+ return typeTree;
}
public void openEditLanesDialog(MCContextMenuManager mm, boolean isLegendMenu) {
// FIXME: Might there be other interesting events that don't really have duration?
- EventTypeFolderNode typeTree = dataSourceSupplier.get().getTypeTree(ItemCollectionToolkit
+ typeTree = dataSourceSupplier.get().getTypeTree(ItemCollectionToolkit
.stream(dataSourceSupplier.get().getItems()).filter(this::typeWithThreadAndDuration));
laneDefs = LaneEditor.openDialog(typeTree, laneDefs.stream().collect(Collectors.toList()),
Messages.JavaApplicationPage_EDIT_THREAD_LANES_DIALOG_TITLE,
Messages.JavaApplicationPage_EDIT_THREAD_LANES_DIALOG_MESSAGE);
updateContextMenu(mm, isLegendMenu);
@@ -125,10 +137,23 @@
.filter((Predicate<? super LaneDefinition>) LaneDefinition::isEnabled).map(ld -> ld.getFilter())
.collect(Collectors.toList());
return ItemFilters.or(laneFilters.toArray(new IItemFilter[laneFilters.size()]));
}
+ /**
+ * Retrieves the set of lane names that are currently enabled.<br>
+ * Note: The "Rest lane" is of type ItemFilters$Composite, and cannot be cast to Types,
+ * so it gets filtered out of the end result.
+ * @return the enabled lanes independent from the rest lane
+ */
+ public Set<String> getEnabledLanes() {
+ List<IItemFilter> laneFilters = laneDefs.stream()
+ .filter((Predicate<? super LaneDefinition>) LaneDefinition::isEnabledAndNotRestLane).map(ld -> ld.getFilter())
+ .collect(Collectors.toList());
+ return ((Types) ItemFilters.or(laneFilters.toArray(new IItemFilter[laneFilters.size()]))).getTypes();
+ }
+
private void setTooltipTitle(String description) {
this.tooltipTitle = description;
}
private String getTooltipTitle() {
@@ -137,10 +162,41 @@
private void resetTooltipTitle() {
this.tooltipTitle = null;
}
+ /**
+ * Introduces a "Quick Filter" to the lane definitions which is controlled by the
+ * dropdown lane filter. Initially, the enabled activity lanes will be a copy of
+ * the currently enabled lanes. When initially used, the "Quick Filter" will be
+ * the only active lane definition in an attempt to preserve the lane activity of
+ * the existing lane definitions. The "Quick Filter" is meant for easy viewing of
+ * activities, and will not be persisted.
+ */
+ public void useDropdownFilter(LaneDefinition quickFilterDef) {
+ if (quickFilterExist) {
+ for (int i = 0; i < laneDefs.size(); i++) {
+ if (quickFilterDef.getName().equals(laneDefs.get(i).getName())) {
+ laneDefs.remove(laneDefs.get(i));
+ laneDefs.add(i, quickFilterDef);
+ }
+ }
+ } else {
+ for (int i = 0; i < laneDefs.size(); i++) {
+ setLaneDefinitionEnablement(laneDefs.get(i), i, false);
+ }
+ laneDefs.add(0, quickFilterDef);
+ quickFilterExist = true;
+ }
+ buildChart.run();
+ }
+
+ private void setLaneDefinitionEnablement(LaneDefinition oldLd, int laneIndex, boolean isEnabled) {
+ LaneDefinition newLd = new LaneDefinition(oldLd.getName(), isEnabled, oldLd.getFilter(), oldLd.isRestLane());
+ laneDefs.set(laneIndex, newLd);
+ }
+
public IXDataRenderer buildThreadRenderer(Object thread, IItemCollection items) {
this.resetTooltipTitle();
String threadName = thread == null ? "" : ((IMCThread) thread).getThreadName(); //$NON-NLS-1$
// FIXME: Workaround since this method can be called from super class constructor. Refactor to avoid this.
List<LaneDefinition> laneFilters = this.laneDefs == null ? Collections.emptyList() : this.laneDefs;
@@ -266,13 +322,11 @@
Action checkAction = new Action(ld.getName(), IAction.AS_CHECK_BOX) {
int laneIndex = laneDefs.indexOf(ld);
@Override
public void run() {
- LaneDefinition newLd = new LaneDefinition(ld.getName(), isChecked(), ld.getFilter(),
- ld.isRestLane());
- laneDefs.set(laneIndex, newLd);
+ setLaneDefinitionEnablement(ld, laneIndex, isChecked());
buildChart.run();
}
};
String identifier = ld.getName() + checkAction.hashCode();
checkAction.setId(identifier);
< prev index next >