tmf: Update the Javadoc for everything GSS-related
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / StateHistorySystem.java
CommitLineData
a52fde77
AM
1/*******************************************************************************
2 * Copyright (c) 2012 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
5df842b3 5 *
a52fde77
AM
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
5df842b3 10 *
a52fde77
AM
11 *******************************************************************************/
12
18ab1d18 13package org.eclipse.linuxtools.internal.tmf.core.statesystem;
a52fde77
AM
14
15import java.io.File;
a52fde77
AM
16import java.io.IOException;
17import java.io.PrintWriter;
18import java.util.ArrayList;
19import java.util.List;
20
867920fd 21import org.eclipse.linuxtools.internal.tmf.core.Tracer;
6d08acca
AM
22import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
23import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
a52fde77 24import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
867920fd 25import org.eclipse.linuxtools.tmf.core.interval.TmfStateInterval;
18ab1d18 26import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemBuilder;
867920fd 27import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
a52fde77
AM
28
29/**
30 * This is the extension of the StateSystem, which will save the state intervals
31 * that are created from the transient state (instead of discarding them, like a
32 * simple StateSystem would do).
5df842b3 33 *
a52fde77 34 * This allows the user to then run queries at past timestamps.
5df842b3 35 *
a52fde77
AM
36 * DON'T FORGET to call .closeHistory() when you are done inserting intervals,
37 * or the storage backend will have no way of knowing it can close and write
38 * itself to disk, and its thread will keep running.
5df842b3 39 *
a52fde77 40 * @author alexmont
5df842b3 41 *
a52fde77 42 */
d26f90fd
AM
43public class StateHistorySystem extends StateSystem implements
44 IStateSystemBuilder {
a52fde77 45
dad01d27
AM
46 /**
47 * In addition, a state "history" system has a storage back-end from which
48 * it can restore past states.
a52fde77 49 */
dad01d27 50 private final IStateHistoryBackend backend;
a52fde77
AM
51
52 /**
53 * General constructor
5df842b3 54 *
a52fde77
AM
55 * @param backend
56 * The "state history storage" backend to use.
57 * @param newFile
58 * Put true if this is a new history started from scratch. It is
59 * used to tell the state system where to get its attribute tree.
60 * @throws IOException
5df842b3 61 * If there was a problem creating the new history file
a52fde77
AM
62 */
63 public StateHistorySystem(IStateHistoryBackend backend, boolean newFile)
64 throws IOException {
65 this.backend = backend;
66 transState = new TransientState(backend);
a52fde77
AM
67
68 if (newFile) {
69 attributeTree = new AttributeTree(this);
70 } else {
71 /* We're opening an existing file */
f3d43860 72 this.attributeTree = new AttributeTree(this, backend.supplyAttributeTreeReader());
a52fde77
AM
73 transState.setInactive();
74 }
75 }
76
d26f90fd
AM
77 @Override
78 public long getStartTime() {
79 return backend.getStartTime();
a52fde77
AM
80 }
81
d26f90fd
AM
82 @Override
83 public long getCurrentEndTime() {
84 return backend.getEndTime();
85 }
86
87 @Override
a52fde77
AM
88 public void closeHistory(long endTime) throws TimeRangeException {
89 File attributeTreeFile;
90 long attributeTreeFilePos;
91 long realEndTime = endTime;
92
93 if (realEndTime < backend.getEndTime()) {
94 /*
95 * This can happen (empty nodes pushing the border further, etc.)
96 * but shouldn't be too big of a deal.
97 */
98 realEndTime = backend.getEndTime();
99 }
100 transState.closeTransientState(realEndTime);
101 backend.finishedBuilding(realEndTime);
102
103 attributeTreeFile = backend.supplyAttributeTreeWriterFile();
104 attributeTreeFilePos = backend.supplyAttributeTreeWriterFilePosition();
105 if (attributeTreeFile != null) {
106 /*
107 * If null was returned, we simply won't save the attribute tree,
108 * too bad!
109 */
110 attributeTree.writeSelf(attributeTreeFile, attributeTreeFilePos);
111 }
112 }
113
114 /**
115 * @name External query methods
116 */
117
d26f90fd 118 @Override
2fc8ca37 119 public synchronized List<ITmfStateInterval> queryFullState(long t)
dad01d27
AM
120 throws TimeRangeException {
121 List<ITmfStateInterval> stateInfo = new ArrayList<ITmfStateInterval>(
a52fde77 122 attributeTree.getNbAttributes());
dad01d27
AM
123
124 /* Bring the size of the array to the current number of attributes */
a52fde77 125 for (int i = 0; i < attributeTree.getNbAttributes(); i++) {
dad01d27 126 stateInfo.add(null);
a52fde77
AM
127 }
128
dad01d27
AM
129 /* Query the storage backend */
130 backend.doQuery(stateInfo, t);
a52fde77 131
dad01d27
AM
132 /*
133 * If we are currently building the history, also query the "ongoing"
134 * states for stuff that might not yet be written to the history.
135 */
a52fde77 136 if (transState.isActive()) {
dad01d27 137 transState.doQuery(stateInfo, t);
a52fde77 138 }
867920fd
AM
139
140 /*
141 * We should have previously inserted an interval for every attribute.
142 * If we do happen do see a 'null' object here, just replace it with a a
143 * dummy internal with a null value, to avoid NPE's further up.
144 */
dad01d27
AM
145 for (int i = 0; i < stateInfo.size(); i++) {
146 if (stateInfo.get(i) == null) {
5a9227ce 147 //logMissingInterval(i, t);
867920fd 148 stateInfo.set(i, new TmfStateInterval(t, t, i, TmfStateValue.nullValue()));
dad01d27 149 }
a52fde77 150 }
dad01d27 151 return stateInfo;
a52fde77
AM
152 }
153
d26f90fd 154 @Override
a52fde77
AM
155 public ITmfStateInterval querySingleState(long t, int attributeQuark)
156 throws AttributeNotFoundException, TimeRangeException {
157 ITmfStateInterval ret;
158
159 if (transState.hasInfoAboutStateOf(t, attributeQuark)) {
160 ret = transState.getOngoingInterval(attributeQuark);
161 } else {
162 ret = backend.doSingularQuery(t, attributeQuark);
163 }
867920fd
AM
164
165 /*
166 * Return a fake interval if we could not find anything in the history.
167 * We do NOT want to return 'null' here.
168 */
169 if (ret == null) {
5a9227ce 170 //logMissingInterval(attributeQuark, t);
867920fd
AM
171 return new TmfStateInterval(t, this.getCurrentEndTime(),
172 attributeQuark, TmfStateValue.nullValue());
173 }
a52fde77
AM
174 return ret;
175 }
176
d26f90fd 177 @Override
dad01d27
AM
178 public List<ITmfStateInterval> queryHistoryRange(int attributeQuark,
179 long t1, long t2) throws TimeRangeException,
180 AttributeNotFoundException {
b255ae4b 181 List<ITmfStateInterval> intervals;
a52fde77 182 ITmfStateInterval currentInterval;
3f77712d 183 long ts, tEnd;
dad01d27 184
3c10e471
AM
185 /* Make sure the time range makes sense */
186 if (t2 <= t1) {
187 throw new TimeRangeException();
188 }
a52fde77 189
3f77712d
AM
190 /* Set the actual, valid end time of the range query */
191 if (t2 > this.getCurrentEndTime()) {
192 tEnd = this.getCurrentEndTime();
193 } else {
194 tEnd = t2;
195 }
196
a52fde77 197 /* Get the initial state at time T1 */
b255ae4b 198 intervals = new ArrayList<ITmfStateInterval>();
a52fde77
AM
199 currentInterval = querySingleState(t1, attributeQuark);
200 intervals.add(currentInterval);
201
202 /* Get the following state changes */
203 ts = currentInterval.getEndTime();
3f77712d 204 while (ts != -1 && ts < tEnd) {
a52fde77 205 ts++; /* To "jump over" to the next state in the history */
3f77712d 206 currentInterval = querySingleState(ts, attributeQuark);
a52fde77
AM
207 intervals.add(currentInterval);
208 ts = currentInterval.getEndTime();
209 }
210 return intervals;
211 }
212
d26f90fd 213 @Override
ec951a4d
AM
214 public List<ITmfStateInterval> queryHistoryRange(int attributeQuark,
215 long t1, long t2, long resolution) throws TimeRangeException,
216 AttributeNotFoundException {
217 List<ITmfStateInterval> intervals;
218 ITmfStateInterval currentInterval;
3f77712d 219 long ts, tEnd;
ec951a4d 220
3c10e471 221 /* Make sure the time range makes sense */
6b4551de 222 if (t2 < t1 || resolution <= 0) {
3c10e471
AM
223 throw new TimeRangeException();
224 }
ec951a4d 225
3f77712d
AM
226 /* Set the actual, valid end time of the range query */
227 if (t2 > this.getCurrentEndTime()) {
228 tEnd = this.getCurrentEndTime();
229 } else {
230 tEnd = t2;
231 }
232
ec951a4d
AM
233 /* Get the initial state at time T1 */
234 intervals = new ArrayList<ITmfStateInterval>();
235 currentInterval = querySingleState(t1, attributeQuark);
236 intervals.add(currentInterval);
237
238 /*
239 * Iterate over the "resolution points". We skip unneeded queries in the
240 * case the current interval is longer than the resolution.
241 */
3f77712d 242 for (ts = t1; (currentInterval.getEndTime() != -1) && (ts < tEnd);
a9f966a2 243 ts += resolution) {
ec951a4d
AM
244 if (ts <= currentInterval.getEndTime()) {
245 continue;
246 }
3f77712d 247 currentInterval = querySingleState(ts, attributeQuark);
ec951a4d
AM
248 intervals.add(currentInterval);
249 }
6db45983
AM
250
251 /* Add the interval at t2, if it wasn't included already. */
3f77712d
AM
252 if (currentInterval.getEndTime() < tEnd) {
253 currentInterval = querySingleState(tEnd, attributeQuark);
6db45983 254 intervals.add(currentInterval);
5df842b3 255 }
ec951a4d
AM
256 return intervals;
257 }
258
5a9227ce 259 static void logMissingInterval(int attribute, long timestamp) {
867920fd
AM
260 Tracer.traceInfo("No data found in history for attribute " + //$NON-NLS-1$
261 attribute + " at time " + timestamp + //$NON-NLS-1$
262 ", returning dummy interval"); //$NON-NLS-1$
263 }
264
a52fde77
AM
265 /**
266 * @name Debugging methods
267 */
268
269 /**
270 * Print out the contents of the inner structures to the selected
271 * PrintWriter.
272 */
273 @Override
ab604305 274 public synchronized void debugPrint(PrintWriter writer) {
a52fde77
AM
275 /* Only used for debugging, shouldn't be externalized */
276 writer.println("------------------------------"); //$NON-NLS-1$
a52fde77
AM
277
278 /* Print the other inner containers */
279 super.debugPrint(writer);
280 backend.debugPrint(writer);
281 }
ec951a4d 282}
This page took 0.042706 seconds and 5 git commands to generate.