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