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