Import views plugins
[deliverable/tracecompass.git] / tmf / org.lttng.scope.tmf2.views.core / src / org / lttng / scope / tmf2 / views / core / timegraph / model / provider / statesystem / StateSystemModelProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
3 *
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 *******************************************************************************/
9
10 package org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem;
11
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15 import java.util.WeakHashMap;
16 import java.util.function.Function;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
21 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
22 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.TimeGraphModelProvider;
23 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.arrows.ITimeGraphModelArrowProvider;
24 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.states.ITimeGraphModelStateProvider;
25 import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
26
27 import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
28 import ca.polymtl.dorsal.libdelorean.exceptions.StateSystemDisposedException;
29 import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
30
31 /**
32 * Basic implementation of a {@link TimeGraphModelProvider} backed by a state
33 * system.
34 *
35 * @author Alexandre Montplaisir
36 */
37 public abstract class StateSystemModelProvider extends TimeGraphModelProvider {
38
39 /**
40 * The context of a tree render. Should contain all the information to
41 * generate the corresponding tree render, according to all configuration
42 * options like sorting, filtering etc. specified by the user.
43 */
44 protected static final class TreeRenderContext {
45
46 /** Trace name */
47 public final String traceName;
48 /** State system */
49 public final ITmfStateSystem ss;
50 /** Sorting mode */
51 public final SortingMode sortingMode;
52 /** Filter modes */
53 public final Set<FilterMode> filterModes;
54 /** Full query */
55 public final List<ITmfStateInterval> fullQueryAtRangeStart;
56
57 /**
58 * Constructor
59 *
60 * @param ss
61 * State system
62 * @param sortingMode
63 * Current sorting mode
64 * @param filterModes
65 * Current filter modes
66 * @param fullQueryAtRangeStart
67 * Full query at the start of the time range.
68 */
69 public TreeRenderContext(String traceName,
70 ITmfStateSystem ss,
71 SortingMode sortingMode,
72 Set<FilterMode> filterModes,
73 List<ITmfStateInterval> fullQueryAtRangeStart) {
74 this.traceName = traceName;
75 this.ss = ss;
76 this.sortingMode = sortingMode;
77 this.filterModes = filterModes;
78 this.fullQueryAtRangeStart = fullQueryAtRangeStart;
79 }
80 }
81
82 /**
83 * Class to encapsulate a cached {@link TimeGraphTreeRender}. This render
84 * should never change, except if the number of attributes in the state
85 * system does (for example, if queries were made before the state system
86 * was done building).
87 */
88 private static final class CachedTreeRender {
89
90 public final int nbAttributes;
91 public final TimeGraphTreeRender treeRender;
92
93 public CachedTreeRender(int nbAttributes, TimeGraphTreeRender treeRender) {
94 this.nbAttributes = nbAttributes;
95 this.treeRender = treeRender;
96 }
97 }
98
99 private final String fStateSystemModuleId;
100 private final Function<TreeRenderContext, TimeGraphTreeRender> fTreeRenderFunction;
101
102 private final Map<ITmfStateSystem, CachedTreeRender> fLastTreeRenders = new WeakHashMap<>();
103
104 private transient @Nullable ITmfStateSystem fStateSystem = null;
105
106 /**
107 * Constructor
108 *
109 * @param name
110 * The name of this provider
111 * @param sortingModes
112 * The available sorting modes
113 * @param filterModes
114 * The available filter modes
115 * @param stateProvider
116 * The state provider part of this model provider
117 * @param arrowProviders
118 * The arrow provider(s) supplied by this model provider
119 * @param stateSystemModuleId
120 * ID of the state system from which data will be fetched
121 * @param treeRenderFunction
122 * Function to generate a tree render for a given tree context
123 */
124 public StateSystemModelProvider(String name,
125 @Nullable List<SortingMode> sortingModes,
126 @Nullable List<FilterMode> filterModes,
127 ITimeGraphModelStateProvider stateProvider,
128 @Nullable List<ITimeGraphModelArrowProvider> arrowProviders,
129 String stateSystemModuleId,
130 Function<TreeRenderContext, TimeGraphTreeRender> treeRenderFunction) {
131
132 super(name, sortingModes, filterModes, stateProvider, arrowProviders);
133
134 fStateSystemModuleId = stateSystemModuleId;
135 fTreeRenderFunction = treeRenderFunction;
136
137 /*
138 * Change listener which will take care of keeping the target state
139 * system up to date.
140 */
141 traceProperty().addListener((obs, oldValue, newValue) -> {
142 ITmfTrace trace = newValue;
143 if (trace == null) {
144 fStateSystem = null;
145 return;
146 }
147
148 /*
149 * Set the state system in another thread, so that if it blocks on
150 * waitForInitialization, it does not block the application
151 * thread...
152 *
153 * FIXME We ought to get rid of this blocking in Jabberwocky.
154 */
155 Thread thread = new Thread(() -> {
156 fStateSystem = TmfStateSystemAnalysisModule.getStateSystem(trace, fStateSystemModuleId);
157 });
158 thread.start();
159 });
160 }
161
162 // ------------------------------------------------------------------------
163 // Render generation methods
164 // ------------------------------------------------------------------------
165
166 @Override
167 public @NonNull TimeGraphTreeRender getTreeRender() {
168 ITmfStateSystem ss = fStateSystem;
169 if (ss == null) {
170 /* This trace does not provide the expected state system */
171 return TimeGraphTreeRender.EMPTY_RENDER;
172 }
173
174 CachedTreeRender cachedRender = fLastTreeRenders.get(ss);
175 if (cachedRender != null && cachedRender.nbAttributes == ss.getNbAttributes()) {
176 /* The last render is still valid, we can re-use it */
177 return cachedRender.treeRender;
178 }
179
180 /* First generate the tree render context */
181 List<ITmfStateInterval> fullStateAtStart;
182 try {
183 fullStateAtStart = ss.queryFullState(ss.getStartTime());
184 } catch (StateSystemDisposedException e) {
185 return TimeGraphTreeRender.EMPTY_RENDER;
186 }
187
188 ITmfTrace trace = getTrace();
189 String traceName = (trace == null ? "" : trace.getName()); //$NON-NLS-1$
190
191 TreeRenderContext treeContext = new TreeRenderContext(traceName,
192 ss,
193 getCurrentSortingMode(),
194 getActiveFilterModes(),
195 fullStateAtStart);
196
197 /* Generate a new tree render */
198 TimeGraphTreeRender treeRender = fTreeRenderFunction.apply(treeContext);
199
200 fLastTreeRenders.put(ss, new CachedTreeRender(ss.getNbAttributes(), treeRender));
201 return treeRender;
202 }
203
204 }
This page took 0.035035 seconds and 5 git commands to generate.