tmf: Fix some Sonar warnings in the state system code
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / backends / historytree / ThreadedHistoryTreeBackend.java
CommitLineData
a52fde77 1/*******************************************************************************
61759503 2 * Copyright (c) 2012, 2013 Ericsson
a52fde77
AM
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
1a4205d9 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
1a4205d9 10 *
a52fde77
AM
11 *******************************************************************************/
12
f9a76cac 13package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.historytree;
a52fde77
AM
14
15import java.io.File;
16import java.io.IOException;
17import java.util.concurrent.ArrayBlockingQueue;
18import java.util.concurrent.BlockingQueue;
19
cb42195c 20import org.eclipse.linuxtools.internal.tmf.core.Activator;
6d08acca 21import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
a52fde77
AM
22import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
23import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
3bd46eef 24import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
a52fde77
AM
25
26/**
27 * Variant of the HistoryTreeBackend which runs all the interval-insertion logic
28 * in a separate thread.
1a4205d9 29 *
a52fde77 30 * @author alexmont
1a4205d9 31 *
a52fde77 32 */
ab604305
AM
33public final class ThreadedHistoryTreeBackend extends HistoryTreeBackend
34 implements Runnable {
a52fde77 35
a52fde77
AM
36 private BlockingQueue<HTInterval> intervalQueue;
37 private final Thread shtThread;
38
39 /**
40 * New state history constructor
1a4205d9 41 *
a52fde77
AM
42 * Note that it usually doesn't make sense to use a Threaded HT if you're
43 * opening an existing state-file, but you know what you're doing...
1a4205d9 44 *
a52fde77
AM
45 * @param newStateFile
46 * The name of the history file that will be created. Should end
47 * in ".ht"
48 * @param blockSize
49 * The size of the blocks in the file
50 * @param maxChildren
51 * The maximum number of children allowed for each core node
52 * @param startTime
53 * The earliest timestamp stored in the history
a96cc6be
AM
54 * @param providerVersion
55 * Version of of the state provider. We will only try to reopen
56 * existing files if this version matches the one in the
57 * framework.
a52fde77
AM
58 * @param queueSize
59 * The size of the interval insertion queue. 2000 - 10000 usually
60 * works well
61 * @throws IOException
62 * If there was a problem opening the history file for writing
63 */
64 public ThreadedHistoryTreeBackend(File newStateFile, int blockSize,
a96cc6be
AM
65 int maxChildren, long startTime, int providerVersion, int queueSize)
66 throws IOException {
67 super(newStateFile, blockSize, maxChildren, providerVersion, startTime);
a52fde77
AM
68
69 intervalQueue = new ArrayBlockingQueue<HTInterval>(queueSize);
70 shtThread = new Thread(this, "History Tree Thread"); //$NON-NLS-1$
71 shtThread.start();
72 }
73
74 /**
75 * New State History constructor. This version provides default values for
76 * blockSize and maxChildren.
1a4205d9 77 *
a52fde77
AM
78 * @param newStateFile
79 * The name of the history file that will be created. Should end
80 * in ".ht"
81 * @param startTime
82 * The earliest timestamp stored in the history
a96cc6be
AM
83 * @param providerVersion
84 * Version of of the state provider. We will only try to reopen
85 * existing files if this version matches the one in the
86 * framework.
a52fde77
AM
87 * @param queueSize
88 * The size of the interval insertion queue. 2000 - 10000 usually
89 * works well
90 * @throws IOException
91 * If there was a problem opening the history file for writing
92 */
93 public ThreadedHistoryTreeBackend(File newStateFile, long startTime,
a96cc6be
AM
94 int providerVersion, int queueSize) throws IOException {
95 super(newStateFile, providerVersion, startTime);
a52fde77
AM
96
97 intervalQueue = new ArrayBlockingQueue<HTInterval>(queueSize);
98 shtThread = new Thread(this, "History Tree Thread"); //$NON-NLS-1$
99 shtThread.start();
100 }
101
102 /*
103 * The Threaded version does not specify an "existing file" constructor,
104 * since the history is already built (and we only use the other thread
105 * during building). Just use a plain HistoryTreeProvider in this case.
1a4205d9 106 *
a52fde77
AM
107 * TODO but what about streaming??
108 */
109
110 @Override
111 public void insertPastState(long stateStartTime, long stateEndTime,
112 int quark, ITmfStateValue value) throws TimeRangeException {
113 /*
114 * Here, instead of directly inserting the elements in the History Tree
115 * underneath, we'll put them in the Queue. They will then be taken and
116 * processed by the other thread executing the run() method.
117 */
118 HTInterval interval = new HTInterval(stateStartTime, stateEndTime,
119 quark, (TmfStateValue) value);
120 try {
121 intervalQueue.put(interval);
122 } catch (InterruptedException e) {
cb42195c 123 Activator.logError("State system interrupted", e); //$NON-NLS-1$
a52fde77
AM
124 }
125 }
126
127 @Override
b33c7369 128 public void finishedBuilding(long endTime) {
a52fde77
AM
129 /*
130 * We need to commit everything in the History Tree and stop the
131 * standalone thread before returning to the StateHistorySystem. (SHS
132 * will then write the Attribute Tree to the file, that must not happen
133 * at the same time we are writing the last nodes!)
134 */
135
1a4205d9
AM
136 stopRunningThread(endTime);
137 isFinishedBuilding = true;
138 return;
139 }
140
141 @Override
142 public void dispose() {
143 if (!isFinishedBuilding) {
144 stopRunningThread(TmfTimestamp.PROJECT_IS_CANNED.getValue());
145 }
a52fde77 146 /*
1a4205d9
AM
147 * isFinishedBuilding remains false, so the superclass will ask the
148 * back-end to delete the file.
149 */
150 super.dispose();
151 }
152
153 private void stopRunningThread(long endTime) {
154 if (!shtThread.isAlive()) {
155 return;
156 }
157
158 /*
159 * Send a "poison pill" in the queue, then wait for the HT to finish
a52fde77
AM
160 * its closeTree()
161 */
162 try {
1a4205d9 163 HTInterval pill = new HTInterval(-1, endTime, -1, TmfStateValue.nullValue());
b33c7369 164 intervalQueue.put(pill);
a52fde77 165 shtThread.join();
b33c7369 166 } catch (TimeRangeException e) {
cb42195c 167 Activator.logError("Error closing state system", e); //$NON-NLS-1$
a52fde77 168 } catch (InterruptedException e) {
cb42195c 169 Activator.logError("State system interrupted", e); //$NON-NLS-1$
a52fde77 170 }
a52fde77
AM
171 }
172
173 @Override
174 public void run() {
175 if (intervalQueue == null) {
cb42195c 176 Activator.logError("Cannot start the storage backend without its interval queue."); //$NON-NLS-1$
a52fde77
AM
177 return;
178 }
179 HTInterval currentInterval;
180 try {
181 currentInterval = intervalQueue.take();
182 while (currentInterval.getStartTime() != -1) {
183 /* Send the interval to the History Tree */
184 sht.insertInterval(currentInterval);
185 currentInterval = intervalQueue.take();
186 }
187 assert (currentInterval.getAttribute() == -1);
188 /*
6a1074ce
AM
189 * We've been told we're done, let's write down everything and quit.
190 * The end time of this "signal interval" is actually correct.
a52fde77 191 */
6a1074ce 192 sht.closeTree(currentInterval.getEndTime());
a52fde77
AM
193 return;
194 } catch (InterruptedException e) {
195 /* We've been interrupted abnormally */
cb42195c 196 Activator.logError("State History Tree interrupted!", e); //$NON-NLS-1$
a52fde77
AM
197 } catch (TimeRangeException e) {
198 /* This also should not happen */
cb42195c 199 Activator.logError("Error starting the state system", e); //$NON-NLS-1$
a52fde77
AM
200 }
201 }
202
203}
This page took 0.044137 seconds and 5 git commands to generate.