linux.ui: Add CPU entries under Resources View aggregated IRQ entries
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.segmentstore.core / src / org / eclipse / tracecompass / segmentstore / core / treemap / TreeMapStore.java
CommitLineData
26a6a7eb 1/*******************************************************************************
e5083481 2 * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir and others.
26a6a7eb
AM
3 *
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 *
9 * Contributors:
10 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.segmentstore.core.treemap;
14
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
1a9cb076 17import java.util.Collection;
26a6a7eb 18import java.util.Iterator;
26a6a7eb 19import java.util.TreeMap;
71e78f69
MK
20import java.util.concurrent.locks.ReadWriteLock;
21import java.util.concurrent.locks.ReentrantReadWriteLock;
26a6a7eb 22
c66ca500 23import org.eclipse.jdt.annotation.NonNull;
4dafe201 24import org.eclipse.jdt.annotation.Nullable;
26a6a7eb
AM
25import org.eclipse.tracecompass.segmentstore.core.ISegment;
26import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
e5083481 27import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
26a6a7eb 28
4dafe201 29import com.google.common.collect.ImmutableList;
26a6a7eb 30import com.google.common.collect.Iterables;
e5083481 31import com.google.common.collect.Ordering;
26a6a7eb
AM
32import com.google.common.collect.Sets;
33import com.google.common.collect.TreeMultimap;
34
35/**
36 * Implementation of a {@link ISegmentStore} using in-memory {@link TreeMap}'s.
37 * This relatively simple implementation holds everything in memory, and as such
38 * cannot contain too much data.
39 *
e5083481
PT
40 * The TreeMapStore itself is Iterable, and its iteration order will be by
41 * ascending order of start times. For segments with identical start times, the
42 * secondary comparator will be the end time. If even those are equal, it will
43 * defer to the segments' natural ordering ({@link ISegment#compareTo}).
44 *
45 * The store's tree maps will not accept duplicate key-value pairs, which means
46 * that if you want several segments with the same start and end times, make
47 * sure their compareTo() differentiates them.
48 *
1a9cb076
AM
49 * Removal operations are not supported.
50 *
51 * @param <E>
e5083481 52 * The type of segment held in this store
26a6a7eb
AM
53 *
54 * @author Alexandre Montplaisir
55 */
c66ca500 56public class TreeMapStore<@NonNull E extends ISegment> implements ISegmentStore<E> {
26a6a7eb 57
71e78f69
MK
58 private final ReadWriteLock fLock = new ReentrantReadWriteLock(false);
59
1a9cb076
AM
60 private final TreeMultimap<Long, E> fStartTimesIndex;
61 private final TreeMultimap<Long, E> fEndTimesIndex;
26a6a7eb 62
1a9cb076 63 private volatile long fSize;
26a6a7eb 64
1a9cb076 65 private @Nullable transient Iterable<E> fLastSnapshot = null;
4dafe201 66
26a6a7eb 67 /**
e5083481 68 * Constructor
26a6a7eb
AM
69 */
70 public TreeMapStore() {
e5083481
PT
71 /*
72 * For the start times index, the "key comparator" will compare the
73 * start times as longs directly. This is the primary comparator for its
74 * tree map.
75 *
76 * The secondary "value" comparator will check the end times first, and
77 * in the event of a tie, defer to the ISegment's Comparable
78 * implementation, a.k.a. its natural ordering.
79 *
80 * The same is done for the end times index, but swapping the first two
81 * comparators instead.
82 */
df2597e0 83 fStartTimesIndex = checkNotNull(TreeMultimap.create(
e5083481
PT
84 SegmentComparators.LONG_COMPARATOR,
85 Ordering.from(SegmentComparators.INTERVAL_END_COMPARATOR).compound(Ordering.natural())));
86
df2597e0 87 fEndTimesIndex = checkNotNull(TreeMultimap.create(
e5083481
PT
88 SegmentComparators.LONG_COMPARATOR,
89 Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR).compound(Ordering.natural())));
90
26a6a7eb
AM
91 fSize = 0;
92 }
93
1a9cb076
AM
94 // ------------------------------------------------------------------------
95 // Methods from Collection
96 // ------------------------------------------------------------------------
97
26a6a7eb 98 @Override
1a9cb076 99 public Iterator<E> iterator() {
4dafe201
MK
100 fLock.readLock().lock();
101 try {
1a9cb076 102 Iterable<E> lastSnapshot = fLastSnapshot;
4dafe201
MK
103 if (lastSnapshot == null) {
104 lastSnapshot = checkNotNull(ImmutableList.copyOf(fStartTimesIndex.values()));
105 fLastSnapshot = lastSnapshot;
106 }
107 return checkNotNull(lastSnapshot.iterator());
108 } finally {
109 fLock.readLock().unlock();
110 }
26a6a7eb
AM
111 }
112
113 @Override
1a9cb076
AM
114 public boolean add(@Nullable E val) {
115 if (val == null) {
116 throw new IllegalArgumentException();
117 }
118
71e78f69
MK
119 fLock.writeLock().lock();
120 try {
121 if (fStartTimesIndex.put(Long.valueOf(val.getStart()), val)) {
122 fEndTimesIndex.put(Long.valueOf(val.getEnd()), val);
123 fSize++;
4dafe201 124 fLastSnapshot = null;
8b246d45 125 return true;
71e78f69 126 }
8b246d45 127 return false;
71e78f69
MK
128 } finally {
129 fLock.writeLock().unlock();
e5083481 130 }
1a9cb076
AM
131 }
132
133 @Override
134 public int size() {
135 return Long.valueOf(fSize).intValue();
136 }
137
138 @Override
139 public boolean isEmpty() {
140 return (fSize == 0);
26a6a7eb
AM
141 }
142
143 @Override
1a9cb076 144 public boolean contains(@Nullable Object o) {
71e78f69
MK
145 fLock.readLock().lock();
146 try {
1a9cb076 147 return fStartTimesIndex.containsValue(o);
71e78f69
MK
148 } finally {
149 fLock.readLock().unlock();
150 }
26a6a7eb
AM
151 }
152
1a9cb076
AM
153
154 @Override
155 public boolean containsAll(@Nullable Collection<?> c) {
156 fLock.readLock().lock();
157 try {
158 return fStartTimesIndex.values().containsAll(c);
159 } finally {
160 fLock.readLock().unlock();
161 }
162 }
163
164 @Override
165 public Object[] toArray() {
166 fLock.readLock().lock();
167 try {
df2597e0 168 return fStartTimesIndex.values().toArray();
1a9cb076
AM
169 } finally {
170 fLock.readLock().unlock();
171 }
172 }
173
174 @Override
95bcb6c4 175 public <T> T[] toArray(T[] a) {
1a9cb076
AM
176 fLock.readLock().lock();
177 try {
df2597e0 178 return fStartTimesIndex.values().toArray(a);
1a9cb076
AM
179 } finally {
180 fLock.readLock().unlock();
181 }
182 }
183
184 @Override
185 public boolean remove(@Nullable Object o) {
186 throw new UnsupportedOperationException();
187 }
188
189 @Override
190 public boolean addAll(@Nullable Collection<? extends E> c) {
191 if (c == null) {
192 throw new IllegalArgumentException();
193 }
194
195 fLock.writeLock().lock();
196 try {
197 boolean changed = false;
198 for (E elem : c) {
199 if (this.add(elem)) {
200 changed = true;
201 }
202 }
203 return changed;
204 } finally {
205 fLock.writeLock().unlock();
206 }
207 }
208
209 @Override
210 public boolean removeAll(@Nullable Collection<?> c) {
211 throw new UnsupportedOperationException();
212 }
213
214 @Override
215 public boolean retainAll(@Nullable Collection<?> c) {
216 throw new UnsupportedOperationException();
217 }
218
219 @Override
220 public void clear() {
221 throw new UnsupportedOperationException();
222 }
223
224 // ------------------------------------------------------------------------
225 // Methods added by ISegmentStore
226 // ------------------------------------------------------------------------
227
26a6a7eb 228 @Override
1a9cb076 229 public Iterable<E> getIntersectingElements(long position) {
26a6a7eb
AM
230 /*
231 * The intervals intersecting 't' are those whose 1) start time is
232 * *lower* than 't' AND 2) end time is *higher* than 't'.
233 */
71e78f69
MK
234 fLock.readLock().lock();
235 try {
1a9cb076
AM
236 Iterable<E> matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(position, true).values());
237 Iterable<E> matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(position, true).values());
71e78f69
MK
238 return checkNotNull(Sets.intersection(Sets.newHashSet(matchStarts), Sets.newHashSet(matchEnds)));
239 } finally {
240 fLock.readLock().unlock();
241 }
26a6a7eb
AM
242 }
243
244 @Override
1a9cb076 245 public Iterable<E> getIntersectingElements(long start, long end) {
71e78f69
MK
246 fLock.readLock().lock();
247 try {
1a9cb076
AM
248 Iterable<E> matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(end, true).values());
249 Iterable<E> matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(start, true).values());
71e78f69
MK
250 return checkNotNull(Sets.intersection(Sets.newHashSet(matchStarts), Sets.newHashSet(matchEnds)));
251 } finally {
252 fLock.readLock().unlock();
253 }
26a6a7eb
AM
254 }
255
256 @Override
71e78f69
MK
257 public void dispose() {
258 fLock.writeLock().lock();
259 try {
260 fStartTimesIndex.clear();
261 fEndTimesIndex.clear();
262 fSize = 0;
263 } finally {
264 fLock.writeLock().unlock();
265 }
26a6a7eb 266 }
26a6a7eb 267}
This page took 0.075877 seconds and 5 git commands to generate.