1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.statesystem
;
12 import java
.util
.List
;
15 import java
.util
.WeakHashMap
;
16 import java
.util
.function
.Function
;
18 import org
.eclipse
.jdt
.annotation
.NonNull
;
19 import org
.eclipse
.jdt
.annotation
.Nullable
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
23 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.TmfStateSystemAnalysisModule
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
25 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.TimeGraphModelProvider
;
26 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.arrows
.ITimeGraphModelArrowProvider
;
27 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.provider
.states
.ITimeGraphModelStateProvider
;
28 import org
.lttng
.scope
.tmf2
.views
.core
.timegraph
.model
.render
.tree
.TimeGraphTreeRender
;
31 * Basic implementation of a {@link TimeGraphModelProvider} backed by a state
34 * @author Alexandre Montplaisir
36 public abstract class StateSystemModelProvider
extends TimeGraphModelProvider
{
39 * The context of a tree render. Should contain all the information to
40 * generate the corresponding tree render, according to all configuration
41 * options like sorting, filtering etc. specified by the user.
43 protected static final class TreeRenderContext
{
46 public final String traceName
;
48 public final ITmfStateSystem ss
;
50 public final SortingMode sortingMode
;
52 public final Set
<FilterMode
> filterModes
;
54 public final List
<ITmfStateInterval
> fullQueryAtRangeStart
;
62 * Current sorting mode
64 * Current filter modes
65 * @param fullQueryAtRangeStart
66 * Full query at the start of the time range.
68 public TreeRenderContext(String traceName
,
70 SortingMode sortingMode
,
71 Set
<FilterMode
> filterModes
,
72 List
<ITmfStateInterval
> fullQueryAtRangeStart
) {
73 this.traceName
= traceName
;
75 this.sortingMode
= sortingMode
;
76 this.filterModes
= filterModes
;
77 this.fullQueryAtRangeStart
= fullQueryAtRangeStart
;
82 * Class to encapsulate a cached {@link TimeGraphTreeRender}. This render
83 * should never change, except if the number of attributes in the state
84 * system does (for example, if queries were made before the state system
87 private static final class CachedTreeRender
{
89 public final int nbAttributes
;
90 public final TimeGraphTreeRender treeRender
;
92 public CachedTreeRender(int nbAttributes
, TimeGraphTreeRender treeRender
) {
93 this.nbAttributes
= nbAttributes
;
94 this.treeRender
= treeRender
;
98 private final String fStateSystemModuleId
;
99 private final Function
<TreeRenderContext
, TimeGraphTreeRender
> fTreeRenderFunction
;
101 private final Map
<ITmfStateSystem
, CachedTreeRender
> fLastTreeRenders
= new WeakHashMap
<>();
103 private transient @Nullable ITmfStateSystem fStateSystem
= null;
109 * The name of this provider
110 * @param sortingModes
111 * The available sorting modes
113 * The available filter modes
114 * @param stateProvider
115 * The state provider part of this model provider
116 * @param arrowProviders
117 * The arrow provider(s) supplied by this model provider
118 * @param stateSystemModuleId
119 * ID of the state system from which data will be fetched
120 * @param treeRenderFunction
121 * Function to generate a tree render for a given tree context
123 public StateSystemModelProvider(String name
,
124 @Nullable List
<SortingMode
> sortingModes
,
125 @Nullable List
<FilterMode
> filterModes
,
126 ITimeGraphModelStateProvider stateProvider
,
127 @Nullable List
<ITimeGraphModelArrowProvider
> arrowProviders
,
128 String stateSystemModuleId
,
129 Function
<TreeRenderContext
, TimeGraphTreeRender
> treeRenderFunction
) {
131 super(name
, sortingModes
, filterModes
, stateProvider
, arrowProviders
);
133 fStateSystemModuleId
= stateSystemModuleId
;
134 fTreeRenderFunction
= treeRenderFunction
;
137 * Change listener which will take care of keeping the target state
140 traceProperty().addListener((obs
, oldValue
, newValue
) -> {
141 ITmfTrace trace
= newValue
;
148 * Set the state system in another thread, so that if it blocks on
149 * waitForInitialization, it does not block the application
152 * FIXME We ought to get rid of this blocking in Jabberwocky.
154 Thread thread
= new Thread(() -> {
155 fStateSystem
= TmfStateSystemAnalysisModule
.getStateSystem(trace
, fStateSystemModuleId
);
161 // ------------------------------------------------------------------------
162 // Render generation methods
163 // ------------------------------------------------------------------------
166 public @NonNull TimeGraphTreeRender
getTreeRender() {
167 ITmfStateSystem ss
= fStateSystem
;
169 /* This trace does not provide the expected state system */
170 return TimeGraphTreeRender
.EMPTY_RENDER
;
173 CachedTreeRender cachedRender
= fLastTreeRenders
.get(ss
);
174 if (cachedRender
!= null && cachedRender
.nbAttributes
== ss
.getNbAttributes()) {
175 /* The last render is still valid, we can re-use it */
176 return cachedRender
.treeRender
;
179 /* First generate the tree render context */
180 List
<ITmfStateInterval
> fullStateAtStart
;
182 fullStateAtStart
= ss
.queryFullState(ss
.getStartTime());
183 } catch (StateSystemDisposedException e
) {
184 return TimeGraphTreeRender
.EMPTY_RENDER
;
187 ITmfTrace trace
= getTrace();
188 String traceName
= (trace
== null ?
"" : trace
.getName()); //$NON-NLS-1$
190 TreeRenderContext treeContext
= new TreeRenderContext(traceName
,
192 getCurrentSortingMode(),
193 getActiveFilterModes(),
196 /* Generate a new tree render */
197 TimeGraphTreeRender treeRender
= fTreeRenderFunction
.apply(treeContext
);
199 fLastTreeRenders
.put(ss
, new CachedTreeRender(ss
.getNbAttributes(), treeRender
));