ss: Replace AttributeNotFoundException with IOOBE for quark parameters
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / internal / statesystem / core / backend / InMemoryBackend.java
CommitLineData
f9a76cac 1/*******************************************************************************
ed48dc75 2 * Copyright (c) 2013, 2016 Ericsson
f9a76cac
AM
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 * Contributors:
10 * Alexandre Montplaisir - Initial API and implementation
f606c6fa 11 * Matthew Khouzam - Modified to use a TreeSet
e13bd4cd 12 * Patrick Tasse - Add message to exceptions
f9a76cac
AM
13 ******************************************************************************/
14
0306a843 15package org.eclipse.tracecompass.internal.statesystem.core.backend;
f9a76cac
AM
16
17import java.io.File;
18import java.io.FileInputStream;
19import java.io.PrintWriter;
f9a76cac 20import java.util.Comparator;
f606c6fa 21import java.util.Iterator;
f9a76cac 22import java.util.List;
866b9976 23import java.util.NavigableSet;
f606c6fa
MK
24import java.util.SortedSet;
25import java.util.TreeSet;
f9a76cac 26
b2f62cb5 27import org.eclipse.jdt.annotation.NonNull;
0306a843 28import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
e894a508
AM
29import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
30import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
31import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
32import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
aa353506 33import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
f9a76cac
AM
34
35/**
36 * State history back-end that stores its intervals in RAM only. It cannot be
37 * saved to disk, which means we need to rebuild it every time we re-open a
38 * trace. But it's relatively quick to build, so this shouldn't be a problem in
39 * most cases.
40 *
41 * This should only be used with very small state histories (and/or, very small
42 * traces). Since it's stored in standard Collections, it's limited to 2^31
43 * intervals.
44 *
45 * @author Alexandre Montplaisir
46 */
47public class InMemoryBackend implements IStateHistoryBackend {
48
f606c6fa
MK
49 /**
50 * We need to compare the end time and the attribute, because we can have 2
51 * intervals with the same end time (for different attributes). And TreeSet
52 * needs a unique "key" per element.
53 */
cb42195c 54 private static final Comparator<ITmfStateInterval> END_COMPARATOR =
f606c6fa
MK
55 new Comparator<ITmfStateInterval>() {
56 @Override
57 public int compare(ITmfStateInterval o1, ITmfStateInterval o2) {
58 final long e1 = o1.getEndTime();
59 final long e2 = o2.getEndTime();
60 final int a1 = o1.getAttribute();
61 final int a2 = o2.getAttribute();
62 if (e1 < e2) {
63 return -1;
64 } else if (e1 > e2) {
65 return 1;
66 } else if (a1 < a2) {
67 return -1;
68 } else if (a1 > a2) {
69 return 1;
70 } else {
71 return 0;
72 }
73 }
f9a76cac 74
f606c6fa
MK
75 };
76
b2f62cb5 77 private final @NonNull String ssid;
866b9976 78 private final NavigableSet<ITmfStateInterval> intervals;
f9a76cac 79 private final long startTime;
b2f62cb5 80
eaf12e04 81 private volatile long latestTime;
f9a76cac
AM
82
83 /**
84 * Constructor
85 *
b2f62cb5
AM
86 * @param ssid
87 * The state system's ID
f9a76cac
AM
88 * @param startTime
89 * The start time of this interval store
90 */
b2f62cb5
AM
91 public InMemoryBackend(@NonNull String ssid, long startTime) {
92 this.ssid = ssid;
f9a76cac
AM
93 this.startTime = startTime;
94 this.latestTime = startTime;
a4524c1b 95 this.intervals = new TreeSet<>(END_COMPARATOR);
f9a76cac
AM
96 }
97
b2f62cb5
AM
98 @Override
99 public String getSSID() {
100 return ssid;
101 }
102
f9a76cac
AM
103 @Override
104 public long getStartTime() {
105 return startTime;
106 }
107
108 @Override
109 public long getEndTime() {
110 return latestTime;
111 }
112
113 @Override
114 public void insertPastState(long stateStartTime, long stateEndTime,
115 int quark, ITmfStateValue value) throws TimeRangeException {
116 /* Make sure the passed start/end times make sense */
117 if (stateStartTime > stateEndTime || stateStartTime < startTime) {
e13bd4cd 118 throw new TimeRangeException(ssid + " Interval Start:" + stateStartTime + ", Interval End:" + stateEndTime + ", Backend Start:" + startTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
f9a76cac
AM
119 }
120
121 ITmfStateInterval interval = new TmfStateInterval(stateStartTime, stateEndTime, quark, value);
122
eaf12e04
AM
123 /* Add the interval into the tree */
124 synchronized (intervals) {
125 intervals.add(interval);
126 }
127
f9a76cac
AM
128 /* Update the "latest seen time" */
129 if (stateEndTime > latestTime) {
130 latestTime = stateEndTime;
131 }
f9a76cac
AM
132 }
133
f9a76cac
AM
134 @Override
135 public void doQuery(List<ITmfStateInterval> currentStateInfo, long t)
136 throws TimeRangeException {
137 if (!checkValidTime(t)) {
e13bd4cd 138 throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + startTime + ", End:" + latestTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
f9a76cac
AM
139 }
140
141 /*
142 * The intervals are sorted by end time, so we can binary search to get
143 * the first possible interval, then only compare their start times.
144 */
eaf12e04 145 synchronized (intervals) {
866b9976 146 Iterator<ITmfStateInterval> iter = searchforEndTime(intervals, t);
eaf12e04
AM
147 for (int modCount = 0; iter.hasNext() && modCount < currentStateInfo.size();) {
148 ITmfStateInterval entry = iter.next();
149 final long entryStartTime = entry.getStartTime();
150 if (entryStartTime <= t) {
151 /* Add this interval to the returned values */
152 currentStateInfo.set(entry.getAttribute(), entry);
153 modCount++;
154 }
f9a76cac
AM
155 }
156 }
157 }
158
159 @Override
160 public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
ed48dc75 161 throws TimeRangeException {
f9a76cac 162 if (!checkValidTime(t)) {
e13bd4cd 163 throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + startTime + ", End:" + latestTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
f9a76cac
AM
164 }
165
166 /*
167 * The intervals are sorted by end time, so we can binary search to get
168 * the first possible interval, then only compare their start times.
169 */
eaf12e04 170 synchronized (intervals) {
866b9976 171 Iterator<ITmfStateInterval> iter = searchforEndTime(intervals, t);
eaf12e04
AM
172 while (iter.hasNext()) {
173 ITmfStateInterval entry = iter.next();
174 final boolean attributeMatches = (entry.getAttribute() == attributeQuark);
175 final long entryStartTime = entry.getStartTime();
176 if (attributeMatches) {
177 if (entryStartTime <= t) {
178 /* This is the droid we are looking for */
179 return entry;
180 }
f9a76cac 181 }
f606c6fa 182 }
f9a76cac 183 }
ed48dc75 184 return null;
f9a76cac
AM
185 }
186
0d26a9d0 187 private boolean checkValidTime(long t) {
f9a76cac
AM
188 if (t >= startTime && t <= latestTime) {
189 return true;
190 }
191 return false;
192 }
193
194 @Override
195 public void finishedBuilding(long endTime) throws TimeRangeException {
196 /* Nothing to do */
197 }
198
199 @Override
200 public FileInputStream supplyAttributeTreeReader() {
201 /* Saving to disk not supported */
202 return null;
203 }
204
205 @Override
206 public File supplyAttributeTreeWriterFile() {
207 /* Saving to disk not supported */
208 return null;
209 }
210
211 @Override
212 public long supplyAttributeTreeWriterFilePosition() {
213 /* Saving to disk not supported */
214 return -1;
215 }
216
217 @Override
218 public void removeFiles() {
219 /* Nothing to do */
220 }
221
222 @Override
223 public void dispose() {
224 /* Nothing to do */
225 }
226
227 @Override
228 public void debugPrint(PrintWriter writer) {
eaf12e04
AM
229 synchronized (intervals) {
230 writer.println(intervals.toString());
231 }
f9a76cac
AM
232 }
233
866b9976 234 private static Iterator<ITmfStateInterval> searchforEndTime(NavigableSet<ITmfStateInterval> tree, long time) {
aa353506 235 ITmfStateInterval dummyInterval = new TmfStateInterval(-1, time, -1, TmfStateValue.nullValue());
f606c6fa
MK
236 ITmfStateInterval myInterval = tree.lower(dummyInterval);
237 if (myInterval == null) {
238 return tree.iterator();
f9a76cac 239 }
f606c6fa
MK
240 final SortedSet<ITmfStateInterval> tailSet = tree.tailSet(myInterval);
241 Iterator<ITmfStateInterval> retVal = tailSet.iterator();
242 retVal.next();
243 return retVal;
f9a76cac
AM
244 }
245
246}
This page took 0.082 seconds and 5 git commands to generate.