cbe47fe244a1851db098a5e5805b127254258a52
1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.analysis
.timing
.core
.store
;
12 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Collection
;
16 import java
.util
.Collections
;
17 import java
.util
.Comparator
;
18 import java
.util
.Iterator
;
19 import java
.util
.List
;
20 import java
.util
.concurrent
.locks
.ReentrantLock
;
21 import java
.util
.stream
.Collectors
;
23 import org
.eclipse
.jdt
.annotation
.NonNull
;
24 import org
.eclipse
.jdt
.annotation
.Nullable
;
25 import org
.eclipse
.tracecompass
.segmentstore
.core
.BasicSegment
;
26 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
27 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
29 import com
.google
.common
.collect
.ImmutableList
;
32 * Implementation of an {@link ISegmentStore} using one in-memory
33 * {@link ArrayList}. This relatively simple implementation holds everything in
34 * memory, and as such cannot contain too much data.
36 * The LazyArrayListStore itself is {@link Iterable}, and its iteration order
37 * will be by ascending order of start times. For segments with identical start
38 * times, the secondary comparator will be the end time. If even those are
39 * equal, it will defer to the segments' natural ordering (
40 * {@link ISegment#compareTo}).
42 * This structure sorts in a lazy way to allow faster insertions. However, if
43 * the structure is out of order, the next read (getting intersecting elements,
44 * iterating...) will perform a sort. It may have inconsistent performance, but
45 * should be faster at building when receiving shuffled datasets than the
46 * {@link ArrayListStore}.
48 * Removal operations are not supported.
51 * The type of segment held in this store
53 * @author Matthew Khouzam
55 public class LazyArrayListStore
<@NonNull E
extends ISegment
> implements ISegmentStore
<E
> {
57 private static final String ERROR_MESSAGE
= "Cannot remove from a segment store"; //$NON-NLS-1$
59 private final Comparator
<E
> COMPARATOR
= (o1
, o2
) -> {
60 int ret
= Long
.compare(o1
.getStart(), o2
.getStart());
62 return Long
.compare(o1
.getEnd(), o2
.getEnd());
67 private final ReentrantLock fLock
= new ReentrantLock(false);
69 private final @NonNull List
<E
> fStore
= new ArrayList
<>();
71 private @Nullable transient Iterable
<E
> fLastSnapshot
= null;
73 private volatile boolean fDirty
= false;
78 public LazyArrayListStore() {
86 * an array of elements to wrap in the segment store
89 public LazyArrayListStore(Object
[] array
) {
90 for (int i
= 0; i
< array
.length
; i
++) {
91 if (array
[i
] instanceof ISegment
) {
92 E element
= (E
) array
[i
];
93 setDirtyIfNeeded(element
);
102 private void setDirtyIfNeeded(@NonNull E value
) {
103 if (!fStore
.isEmpty() && COMPARATOR
.compare(fStore
.get(size() - 1), value
) > 0) {
107 // ------------------------------------------------------------------------
108 // Methods from Collection
109 // ------------------------------------------------------------------------
112 public Iterator
<E
> iterator() {
118 Iterable
<E
> lastSnapshot
= fLastSnapshot
;
119 if (lastSnapshot
== null) {
120 lastSnapshot
= ImmutableList
.copyOf(fStore
);
121 fLastSnapshot
= lastSnapshot
;
123 return checkNotNull(lastSnapshot
.iterator());
130 * DO NOT CALL FROM OUTSIDE OF A LOCK!
132 private void sortStore() {
133 fStore
.sort(COMPARATOR
);
138 public boolean add(@Nullable E val
) {
140 throw new IllegalArgumentException("Cannot add null value"); //$NON-NLS-1$
145 setDirtyIfNeeded(val
);
147 fLastSnapshot
= null;
156 return fStore
.size();
160 public boolean isEmpty() {
163 return fStore
.isEmpty();
170 public boolean contains(@Nullable Object o
) {
173 return fStore
.contains(o
);
180 public boolean containsAll(@Nullable Collection
<?
> c
) {
183 return fStore
.containsAll(c
);
190 public Object
[] toArray() {
196 return fStore
.toArray();
203 public <T
> T
[] toArray(T
[] a
) {
209 return fStore
.toArray(a
);
216 public boolean addAll(@Nullable Collection
<?
extends E
> c
) {
218 throw new IllegalArgumentException();
223 boolean changed
= false;
236 public boolean removeAll(@Nullable Collection
<?
> c
) {
237 throw new UnsupportedOperationException(ERROR_MESSAGE
);
241 public boolean retainAll(@Nullable Collection
<?
> c
) {
242 throw new UnsupportedOperationException(ERROR_MESSAGE
);
246 public boolean remove(@Nullable Object o
) {
247 throw new UnsupportedOperationException(ERROR_MESSAGE
);
251 public void clear() {
255 fLastSnapshot
= null;
262 // ------------------------------------------------------------------------
263 // Methods added by ISegmentStore
264 // ------------------------------------------------------------------------
267 public Iterable
<E
> getIntersectingElements(long position
) {
273 * The intervals intersecting 't' are those whose 1) start time is
274 * *lower* than 't' AND 2) end time is *higher* than 't'.
278 * as fStore is sorted by start then end times, restrict sub array
279 * to elements whose start times <= t as stream.filter won't do it.
281 int index
= Collections
.binarySearch(fStore
, new BasicSegment(position
, Long
.MAX_VALUE
));
282 index
= (index
>= 0) ? index
: -index
- 1;
283 return fStore
.subList(0, index
).stream().filter(element
-> position
>= element
.getStart() && position
<= element
.getEnd()).collect(Collectors
.toList());
290 public Iterable
<E
> getIntersectingElements(long start
, long end
) {
296 int index
= Collections
.binarySearch(fStore
, new BasicSegment(end
, Long
.MAX_VALUE
));
297 index
= (index
>= 0) ? index
: -index
- 1;
298 return fStore
.subList(0, index
).stream().filter(element
-> !(start
> element
.getEnd() || end
< element
.getStart())).collect(Collectors
.toList());
305 public void dispose() {
This page took 0.037576 seconds and 4 git commands to generate.