1 /*******************************************************************************
2 * Copyright (c) 2013 Ericsson
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
10 * Alexandre Montplaisir - Initial API and implementation
11 ******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.backends
;
16 import java
.io
.FileInputStream
;
17 import java
.io
.PrintWriter
;
18 import java
.util
.ArrayList
;
19 import java
.util
.Collections
;
20 import java
.util
.Comparator
;
21 import java
.util
.List
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.AttributeNotFoundException
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TimeRangeException
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.interval
.ITmfStateInterval
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.interval
.TmfIntervalEndComparator
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.interval
.TmfStateInterval
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.ITmfStateValue
;
31 * State history back-end that stores its intervals in RAM only. It cannot be
32 * saved to disk, which means we need to rebuild it every time we re-open a
33 * trace. But it's relatively quick to build, so this shouldn't be a problem in
36 * This should only be used with very small state histories (and/or, very small
37 * traces). Since it's stored in standard Collections, it's limited to 2^31
40 * @author Alexandre Montplaisir
42 public class InMemoryBackend
implements IStateHistoryBackend
{
44 private final static Comparator
<ITmfStateInterval
> endComparator
=
45 new TmfIntervalEndComparator();
47 private final List
<ITmfStateInterval
> intervals
;
48 private final long startTime
;
49 private long latestTime
;
55 * The start time of this interval store
57 public InMemoryBackend(long startTime
) {
58 this.startTime
= startTime
;
59 this.latestTime
= startTime
;
60 this.intervals
= new ArrayList
<ITmfStateInterval
>();
64 public long getStartTime() {
69 public long getEndTime() {
74 public void insertPastState(long stateStartTime
, long stateEndTime
,
75 int quark
, ITmfStateValue value
) throws TimeRangeException
{
76 /* Make sure the passed start/end times make sense */
77 if (stateStartTime
> stateEndTime
|| stateStartTime
< startTime
) {
78 throw new TimeRangeException();
81 ITmfStateInterval interval
= new TmfStateInterval(stateStartTime
, stateEndTime
, quark
, value
);
83 /* Update the "latest seen time" */
84 if (stateEndTime
> latestTime
) {
85 latestTime
= stateEndTime
;
88 /* Add the interval into the-array */
89 intervals
.add(interval
);
94 public void doQuery(List
<ITmfStateInterval
> currentStateInfo
, long t
)
95 throws TimeRangeException
{
96 if (!checkValidTime(t
)) {
97 throw new TimeRangeException();
101 * The intervals are sorted by end time, so we can binary search to get
102 * the first possible interval, then only compare their start times.
104 ITmfStateInterval entry
;
105 for (int i
= binarySearchEndTime(intervals
, t
); i
< intervals
.size(); i
++) {
106 entry
= intervals
.get(i
);
107 if (entry
.getStartTime() <= t
) {
108 /* Add this interval to the returned values */
109 currentStateInfo
.set(entry
.getAttribute(), entry
);
115 public ITmfStateInterval
doSingularQuery(long t
, int attributeQuark
)
116 throws TimeRangeException
, AttributeNotFoundException
{
117 if (!checkValidTime(t
)) {
118 throw new TimeRangeException();
122 * The intervals are sorted by end time, so we can binary search to get
123 * the first possible interval, then only compare their start times.
125 ITmfStateInterval entry
;
126 for (int i
= binarySearchEndTime(intervals
, t
); i
< intervals
.size(); i
++) {
127 entry
= intervals
.get(i
);
128 if (entry
.getStartTime() <= t
&& entry
.getAttribute() == attributeQuark
) {
129 /* This is the droid we are looking for */
133 throw new AttributeNotFoundException();
137 public boolean checkValidTime(long t
) {
138 if (t
>= startTime
&& t
<= latestTime
) {
145 public void finishedBuilding(long endTime
) throws TimeRangeException
{
150 public FileInputStream
supplyAttributeTreeReader() {
151 /* Saving to disk not supported */
156 public File
supplyAttributeTreeWriterFile() {
157 /* Saving to disk not supported */
162 public long supplyAttributeTreeWriterFilePosition() {
163 /* Saving to disk not supported */
168 public void removeFiles() {
173 public void dispose() {
178 public void debugPrint(PrintWriter writer
) {
179 writer
.println(intervals
.toString());
182 private static int binarySearchEndTime(List
<ITmfStateInterval
> list
, long time
) {
183 ITmfStateInterval dummyInterval
= new TmfStateInterval(-1, time
, -1, null);
184 int mid
= Collections
.binarySearch(list
, dummyInterval
, endComparator
);
186 /* The returned value is < 0 if the exact key was not found. */
192 * Collections.binarySearch doesn't guarantee which element is returned
193 * if it falls on one of many equal ones. So make sure we are at the
194 * first one provided.
197 (list
.get(mid
).getEndTime() == list
.get(mid
-1).getEndTime())) {