org.junit,
org.eclipse.tracecompass.analysis.timing.core.tests,
org.eclipse.tracecompass.tmf.ui.tests,
- org.eclipse.tracecompass.segmentstore.core
+ org.eclipse.tracecompass.segmentstore.core,
+ org.eclipse.tracecompass.datastore.core
Import-Package: com.google.common.collect,
org.swtchart
private static final String CALLGRAPHDENSITY_ID = CallGraphDensityView.ID;
private final @NonNull ISegmentStoreDensityViewerDataListener fSyncListener = new ISegmentStoreDensityViewerDataListener() {
+ @Deprecated
@Override
public void dataChanged(List<ISegment> newData) {
fLatch.countDown();
}
+ @Deprecated
@Override
public void dataSelectionChanged(@Nullable List<@NonNull ISegment> newSelectionData) {
// do nothing
}
+ @Override
+ public void viewDataChanged(@NonNull Iterable<? extends @NonNull ISegment> newData) {
+ fLatch.countDown();
+ }
+
+ @Override
+ public void selectedDataChanged(@Nullable Iterable<? extends @NonNull ISegment> newSelectionData) {
+ // do nothing
+ }
+
};
private SWTWorkbenchBot fBot;
private SWTBotView fView;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayList;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableView;
import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableViewer;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.BasicSegment2;
import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
*/
@Test
public void climbTest() {
- List<@NonNull ISegment> fixture = new ArrayList<>();
+ ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore();
for (int i = 0; i < 100; i++) {
fixture.add(createSegment(i, 2 * i));
}
*/
@Test
public void decrementingTest() {
- List<@NonNull ISegment> fixture = new ArrayList<>();
+ ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore();
for (int i = 100; i >= 0; i--) {
fixture.add(createSegment(i, 2 * i));
}
assertNotNull(getTable());
getTable().updateModel(fixture);
SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
- fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "100", 0, 2));
+ fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
tableBot.header("Duration").click();
fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
tableBot.header("Duration").click();
*/
@Test
public void smallTest() {
- List<@NonNull ISegment> fixture = new ArrayList<>();
+ ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore();
for (int i = 1; i >= 0; i--) {
fixture.add(createSegment(i, 2 * i));
}
assertNotNull(getTable());
getTable().updateModel(fixture);
SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
- fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
+ fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
tableBot.header("Duration").click();
fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
tableBot.header("Duration").click();
@Test
public void largeTest() {
final int size = 1000000;
- ISegment[] fixture = new ISegment[size];
+ ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore();
for (int i = 0; i < size; i++) {
- fixture[i] = createSegment(i, 2 * i);
+ fixture.add(createSegment(i, 2 * i));
}
assertNotNull(getTable());
getTable().updateModel(fixture);
Random rnd = new Random();
rnd.setSeed(1234);
final int size = 1000000;
- ISegment[] fixture = new ISegment[size];
+ ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore();
for (int i = 0; i < size; i++) {
int start = Math.abs(rnd.nextInt(100000000));
int end = start + Math.abs(rnd.nextInt(1000000));
- fixture[i] = (createSegment(start, end));
+ fixture.add(createSegment(start, end));
}
assertNotNull(getTable());
getTable().updateModel(fixture);
SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
- fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "894,633", 0, 2));
+ fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "374,153", 0, 2));
tableBot.header("Duration").click();
fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
tableBot.header("Duration").click();
public void gaussianNoiseTest() {
Random rnd = new Random();
rnd.setSeed(1234);
- List<@NonNull ISegment> fixture = new ArrayList<>();
+ ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore();
for (int i = 1; i <= 1000000; i++) {
int start = Math.abs(rnd.nextInt(100000000));
final int delta = Math.abs(rnd.nextInt(1000));
assertNotNull(getTable());
getTable().updateModel(fixture);
SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
- fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "400,689", 0, 2));
+ fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "23,409", 0, 2));
tableBot.header("Duration").click();
fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
tableBot.header("Duration").click();
fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "998,001", 0, 2));
}
+ /**
+ * Test table with an on-disk segment store that is lazy loaded in the table
+ *
+ * @throws IOException
+ */
+ @Test
+ public void onDiskSegStoreTest() throws IOException {
+ Path segmentFile = Files.createTempFile("tmpSegStore", ".tmp");
+ try {
+ final int size = 1000000;
+ ISegmentStore<@NonNull BasicSegment2> fixture = SegmentStoreFactory.createOnDiskSegmentStore(segmentFile, BasicSegment2.BASIC_SEGMENT_READ_FACTORY);
+ for (int i = 0; i < size; i++) {
+ fixture.add(new BasicSegment2(i, 2 * i));
+ }
+ assertNotNull(getTable());
+ getTable().updateModel(fixture);
+ SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+ fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+ tableBot.header("Duration").click();
+ fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+ tableBot.header("Duration").click();
+ // FIXME: Should be 999,999, but sorting on disk does not work well yet
+ fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "818,799", 0, 2));
+ } finally {
+ Files.delete(segmentFile);
+ }
+ }
+
/**
* Test creating a tsv
*
@Test
public void testWriteToTsv() throws NoSuchMethodException, IOException {
- List<@NonNull ISegment> fixture = new ArrayList<>();
+ ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore();
for (int i = 1; i <= 20; i++) {
int start = i;
final int delta = i;
import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
* Used to keep the table in sync with the density viewer.
*/
private final class DataChangedListener implements ISegmentStoreDensityViewerDataListener {
+ @Deprecated
@Override
public void dataChanged(List<ISegment> data) {
updateTableModel(data);
private void updateTableModel(@Nullable List<ISegment> data) {
final AbstractSegmentStoreTableViewer viewer = fTableViewer;
if (viewer != null && data != null) {
- viewer.updateModel(data.toArray(new ISegment[] {}));
+ viewer.updateModel(data);
}
}
+ private void updateTableModel(@Nullable Iterable<? extends ISegment> data) {
+ final AbstractSegmentStoreTableViewer viewer = fTableViewer;
+ if (viewer != null && data != null) {
+ viewer.updateModel(data);
+ }
+ }
+
+ @Deprecated
@Override
public void dataSelectionChanged(@Nullable List<ISegment> data) {
updateTableModel(data);
}
+
+ @Override
+ public void viewDataChanged(@NonNull Iterable<? extends @NonNull ISegment> newData) {
+ updateTableModel(newData);
+ }
+
+ @Override
+ public void selectedDataChanged(@Nullable Iterable<? extends @NonNull ISegment> newSelectionData) {
+ updateTableModel(newSelectionData);
+ }
+
}
@Override
import java.text.Format;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Predicate;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.density.MouseDragZoomProvider;
import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.density.MouseSelectionProvider;
import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.density.SimpleTooltipProvider;
+import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.table.SegmentStoreContentProvider.SegmentStoreWithRange;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
import org.swtchart.Range;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
/**
* Displays the segment store provider data in a density chart.
return TmfTraceManager.getInstance().getActiveTrace();
}
- private void updateDisplay(List<ISegment> data) {
- if (data.isEmpty()) {
- return;
- }
+ private void updateDisplay(SegmentStoreWithRange<ISegment> data) {
IBarSeries series = (IBarSeries) fChart.getSeriesSet().createSeries(SeriesType.BAR, Messages.AbstractSegmentStoreDensityViewer_SeriesLabel);
series.setVisible(true);
series.setBarPadding(0);
double[] xOrigSeries = new double[width];
double[] yOrigSeries = new double[width];
Arrays.fill(yOrigSeries, 1.0);
- long maxLength = data.get(data.size() - 1).getLength();
+ data.setComparator(SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
+ ISegment maxSegment = data.getElement(SegmentStoreWithRange.LAST);
+ long maxLength = Long.MAX_VALUE;
+ if (maxSegment != null) {
+ maxLength = maxSegment.getLength();
+ }
double maxFactor = 1.0 / (maxLength + 1.0);
long minX = Long.MAX_VALUE;
for (ISegment segment : data) {
public void select(Range durationRange) {
computeDataAsync(fCurrentTimeRange, durationRange).thenAccept((data) -> {
for (ISegmentStoreDensityViewerDataListener listener : fListeners) {
- listener.dataSelectionChanged(data);
+ listener.selectedDataChanged(data);
}
});
}
computeDataAsync(fCurrentTimeRange, durationRange).thenAccept((data) -> applyData(data));
}
- private CompletableFuture<@Nullable List<ISegment>> computeDataAsync(final TmfTimeRange timeRange, final Range durationRange) {
+ private CompletableFuture<@Nullable SegmentStoreWithRange<ISegment>> computeDataAsync(final TmfTimeRange timeRange, final Range durationRange) {
return CompletableFuture.supplyAsync(() -> computeData(timeRange, durationRange));
}
- private @Nullable List<ISegment> computeData(final TmfTimeRange timeRange, final Range durationRange) {
+ private @Nullable SegmentStoreWithRange<ISegment> computeData(final TmfTimeRange timeRange, final Range durationRange) {
final ISegmentStoreProvider segmentProvider = fSegmentStoreProvider;
if (segmentProvider == null) {
return null;
return null;
}
- Iterator<ISegment> intersectingElements = segStore.getIntersectingElements(timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue()).iterator();
-
+ // Filter on the segment duration if necessary
if (durationRange.lower > Double.MIN_VALUE || durationRange.upper < Double.MAX_VALUE) {
- Predicate<? super ISegment> predicate = new Predicate<ISegment>() {
+ Predicate<ISegment> predicate = new Predicate<ISegment>() {
@Override
- public boolean apply(@Nullable ISegment input) {
- return input != null && input.getLength() >= durationRange.lower && input.getLength() <= durationRange.upper;
+ public boolean test(@NonNull ISegment segment) {
+ return segment.getLength() >= durationRange.lower && segment.getLength() <= durationRange.upper;
}
};
- intersectingElements = Iterators.filter(intersectingElements, predicate);
+ return new SegmentStoreWithRange<>(segStore, timeRange, predicate);
}
- return Lists.newArrayList(intersectingElements);
+ return new SegmentStoreWithRange<>(segStore, timeRange);
+
}
- private void applyData(final @Nullable List<ISegment> data) {
+ private void applyData(final @Nullable SegmentStoreWithRange<ISegment> data) {
if (data != null) {
- Collections.sort(data, SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
+ data.setComparator(SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
Display.getDefault().asyncExec(() -> updateDisplay(data));
for (ISegmentStoreDensityViewerDataListener l : fListeners) {
- l.dataChanged(data);
+ l.viewDataChanged(data);
}
}
}
*
* @param newData
* the new data
+ * @deprecated Use {@link #viewDataChanged(Iterable)} instead
*/
+ @Deprecated
void dataChanged(List<ISegment> newData);
/**
*
* @param newSelectionData
* the new selection of the data
+ * @deprecated Use {@link #selectedDataChanged(Iterable)} instead
*/
+ @Deprecated
void dataSelectionChanged(@Nullable List<ISegment> newSelectionData);
+
+ /**
+ * Notification that the data changed in the viewer.
+ *
+ * @param newData
+ * the new data
+ * @since 1.4
+ */
+ default void viewDataChanged(Iterable<? extends ISegment> newData) {
+ // To be implemented by children
+ }
+
+ /**
+ * Notification that the selection of the data changed in the viewer.
+ *
+ * @param newSelectionData
+ * the new selection of the data
+ * @since 1.4
+ */
+ default void selectedDataChanged(@Nullable Iterable<? extends ISegment> newSelectionData) {
+ // To be implemented in children
+ }
}
addPackListener();
tableViewer.setInput(dataInput);
SegmentStoreContentProvider contentProvider = (SegmentStoreContentProvider) getTableViewer().getContentProvider();
- tableViewer.setItemCount(contentProvider.getSegmentCount());
+ tableViewer.setItemCount((int) Math.min(Integer.MAX_VALUE, contentProvider.getSegmentCount()));
}
}
});
package org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.table;
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNullContents;
-
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Predicate;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.ui.viewers.table.ISortingLazyContentProvider;
import com.google.common.collect.Iterables;
public class SegmentStoreContentProvider implements ISortingLazyContentProvider {
/**
- * Array of all the segments in the segment store of the current trace
+ * Class that wraps a segment store and a time range.
+ *
+ * Note: this class is not thread-safe. It is not meant to be used by many
+ * threads simultaneously. Many methods are synchronized, so at best, the
+ * performances will be bad, but at worst, it may return false results.
+ *
+ * @author Geneviève Bastien
+ * @param <E>
+ * The type of segment in the segment store
*/
- private ISegment @Nullable [] fSegmentArray = null;
+ public static class SegmentStoreWithRange<E extends ISegment> implements Iterable<E> {
+ /**
+ * Constant used in the {@link #getElement(long)} method to return the
+ * last element of the store
+ */
+ public static final long LAST = Long.MIN_VALUE;
+ private final ISegmentStore<E> fSegmentStore;
+ private final TmfTimeRange fRange;
+
+ private @Nullable Comparator<ISegment> fComparator = null;
+ private @Nullable Iterable<E> fIterable = null;
+ private @Nullable Predicate<E> fPredicate = null;
+
+ private long fLastReadPos = -1;
+ private @Nullable Iterator<E> fIterator = null;
+
+ /**
+ * Constructor
+ *
+ * @param segStore
+ * The segment store
+ * @param range
+ * The time range to get for this segment store
+ */
+ public SegmentStoreWithRange(ISegmentStore<E> segStore, TmfTimeRange range) {
+ fSegmentStore = segStore;
+ fRange = range;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param segStore
+ * The segment store
+ * @param range
+ * The time range to get for this segment store
+ * @param predicate
+ * An extra predicate to further filter the segments
+ */
+ public SegmentStoreWithRange(ISegmentStore<E> segStore, TmfTimeRange range, Predicate<E> predicate) {
+ fSegmentStore = segStore;
+ fRange = range;
+ fPredicate = predicate;
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return NonNullUtils.checkNotNull(getIterable().iterator());
+ }
+
+ /**
+ * Set the comparator for this store
+ *
+ * @param comparator
+ * The comparator to use for this store
+ */
+ public void setComparator(Comparator<ISegment> comparator) {
+ fComparator = comparator;
+ fIterable = null;
+ resetIterator();
+ }
+
+ /**
+ * Get the iterable to iterate over this segment store
+ *
+ * @return The iterable object to iterate through the segment store
+ */
+ private Iterable<E> getIterable() {
+ Iterable<E> iterable = fIterable;
+ if (iterable == null) {
+ Comparator<ISegment> comparator = fComparator;
+ Predicate<? super E> predicate = fPredicate;
+ if (comparator != null) {
+ iterable = fSegmentStore.getIntersectingElements(fRange.getStartTime().toNanos(), fRange.getEndTime().toNanos(), comparator);
+ } else {
+ iterable = fSegmentStore.getIntersectingElements(fRange.getStartTime().toNanos(), fRange.getEndTime().toNanos());
+ }
+ if (predicate != null) {
+ iterable = Iterables.filter(iterable, input -> predicate.test(input));
+ }
+ fIterable = iterable;
+ }
+ return iterable;
+ }
+
+ private Iterator<? extends @NonNull ISegment> resetIterator() {
+ Iterator<E> iterator = NonNullUtils.checkNotNull(getIterable().iterator());
+ fIterator = iterator;
+ fLastReadPos = -1;
+ return iterator;
+ }
+
+ /**
+ * Get the element at position index. If the index is {@link #LAST}, it
+ * will return the last element from the end of the iterator, if a
+ * comparator was specified, otherwise it will return the first event.
+ * This method with {@link #LAST} is meant to be used with sorted
+ * stores.
+ *
+ * @param index
+ * The index of the requested element. If index is
+ * {@link #LAST} it will return the last element, at the end
+ * of the iterator.
+ * @return The segment at position index or <code>null</code> if it is
+ * not available
+ */
+ public @Nullable ISegment getElement(long index) {
+ long idx = index;
+ // Special code path if we are looking for an element from the end there is a comparator
+ if (index == LAST) {
+ Comparator<@NonNull ISegment> comparator = fComparator;
+ if (comparator != null) {
+ return getLastElement(comparator);
+ }
+ // No comparator, so impossible the easily get last element,
+ // just return the first as it is random anyway
+ idx = 0;
+ }
+ Iterable<? extends @NonNull ISegment> iterable = fIterable;
+ if (iterable instanceof List<?> && idx <= Integer.MAX_VALUE) {
+ return Iterables.get(iterable, (int) idx, null);
+ }
+ Iterator<? extends @NonNull ISegment> iterator = fIterator;
+ if (iterator == null || idx <= fLastReadPos) {
+ iterator = resetIterator();
+ }
+ ISegment segment = null;
+ while (fLastReadPos < idx && iterator.hasNext()) {
+ fLastReadPos++;
+ segment = NonNullUtils.checkNotNull(iterator.next());
+ }
+ if (fLastReadPos == idx) {
+ return segment;
+ }
+ return null;
+ }
+
+ private @Nullable ISegment getLastElement(Comparator<@NonNull ISegment> comparator) {
+ Iterable<? extends ISegment> baseIterable = fIterable;
+ if (baseIterable instanceof List<?>) {
+ return Iterables.getLast(baseIterable, null);
+ }
+ // Not a trivial get, so get an iterable for the reverse comparator
+ // and fetch first element
+ Predicate<? super E> predicate = fPredicate;
+ Iterable<E> iterable = fSegmentStore.getIntersectingElements(fRange.getStartTime().toNanos(), fRange.getEndTime().toNanos(), comparator.reversed());
+ if (predicate != null) {
+ iterable = Iterables.filter(iterable, input -> predicate.test(input));
+ }
+ // FIXME: The cast turns an error into a warning for this null
+ // value, but it is completely unnecessary otherwise
+ return Iterables.getFirst((Iterable<? extends ISegment>) iterable, null);
+ }
+
+ /**
+ * Get the number of segments
+ *
+ * TODO: Try to live without this method, this is not lazy enough
+ *
+ * @return The number of segment in the current iterable
+ */
+ public long getSegmentCount() {
+ return Iterables.size(getIterable());
+ }
+ }
/**
* Table viewer of the latency table viewer
* Segment comparator
*/
private @Nullable Comparator<ISegment> fComparator = null;
+ private @Nullable SegmentStoreWithRange<?> fStore;
@Override
public void updateElement(int index) {
final TableViewer tableViewer = fTableViewer;
- final ISegment @Nullable [] segmentArray = fSegmentArray;
- if (tableViewer != null && segmentArray != null) {
- tableViewer.replace(segmentArray[index], index);
+ SegmentStoreWithRange<?> store = fStore;
+ if (tableViewer == null || store == null) {
+ return;
}
+ tableViewer.replace(store.getElement(index), index);
}
@Override
public void dispose() {
- fSegmentArray = null;
+ fStore = null;
fTableViewer = null;
fComparator = null;
}
@Override
public void inputChanged(@Nullable Viewer viewer, @Nullable Object oldInput, @Nullable Object newInput) {
fTableViewer = (TableViewer) viewer;
- if (newInput instanceof Collection<?> || newInput instanceof ISegmentStore) {
- @SuppressWarnings("unchecked")
- Collection<ISegment> segmentStore = (Collection<@NonNull ISegment>) newInput;
- ISegment[] array = Iterables.toArray(segmentStore, ISegment.class);
- @NonNull ISegment[] checkedArray = checkNotNullContents(array);
- if (fComparator != null) {
- Arrays.sort(checkedArray, fComparator);
+ if (newInput instanceof SegmentStoreWithRange) {
+ SegmentStoreWithRange<?> sswr = (SegmentStoreWithRange<?>) newInput;
+ Comparator<ISegment> comparator = fComparator;
+ if (comparator != null) {
+ sswr.setComparator(comparator);
}
- fSegmentArray = checkedArray;
- } else if (newInput instanceof ISegment[]) {
- /*
- * Ensure that there are no null elements in the array, so we can
- * set it back to fSegmentArray, which does not allow nulls.
- */
- @NonNull ISegment[] checkedArray = checkNotNullContents((@Nullable ISegment[]) newInput);
- if (fComparator != null) {
- Arrays.sort(checkedArray, fComparator);
+ fStore = sswr;
+ } else if (newInput instanceof ISegmentStore<?>) {
+ ISegmentStore<? extends ISegment> segmentStore = (ISegmentStore<?>) newInput;
+ SegmentStoreWithRange<?> sswr = new SegmentStoreWithRange<>(segmentStore, TmfTimeRange.ETERNITY);
+ Comparator<ISegment> comparator = fComparator;
+
+ if (comparator != null) {
+ sswr.setComparator(comparator);
}
- fSegmentArray = checkedArray;
+ fStore = sswr;
} else {
- fSegmentArray = null;
+ fStore = null;
}
}
@Override
public void setSortOrder(@Nullable Comparator<?> comparator) {
- @NonNull ISegment @Nullable [] segmentArray = fSegmentArray;
- if (comparator == null) {
- return;
- }
- if (segmentArray == null) {
- return;
- }
+ SegmentStoreWithRange<?> store = fStore;
final TableViewer tableViewer = fTableViewer;
- if (tableViewer == null) {
+ if (comparator == null || store == null || tableViewer == null) {
return;
}
@SuppressWarnings("unchecked")
Comparator<ISegment> comp = (Comparator<ISegment>) comparator;
fComparator = comp;
- Arrays.sort(segmentArray, fComparator);
+ store.setComparator(comp);
tableViewer.refresh();
}
*
* @return the segment count
*/
- public int getSegmentCount() {
- ISegment[] segmentArray = fSegmentArray;
- return (segmentArray == null ? 0 : segmentArray.length);
+ public long getSegmentCount() {
+ SegmentStoreWithRange<?> store = fStore;
+ return (store == null ? 0 : store.getSegmentCount());
}
}
--- /dev/null
+class com/google/common/collect/Iterables
+filter
+ <T:Ljava/lang/Object;>(Ljava/lang/Iterable<TT;>;Lcom/google/common/base/Predicate<-TT;>;)Ljava/lang/Iterable<TT;>;
+ <T:Ljava/lang/Object;>(Ljava/lang/Iterable<TT;>;Lcom/google/common/base/Predicate<-TT;>;)L1java/lang/Iterable<TT;>;
--- /dev/null
+class java/util/Comparator
+reversed
+ ()Ljava/util/Comparator<TT;>;
+ ()L1java/util/Comparator<TT;>;
import java.util.Comparator;
import java.util.List;
-import com.google.common.collect.Lists;
-
import org.eclipse.jdt.annotation.Nullable;
+import com.google.common.collect.Lists;
+
/**
* Interface for segment-storing backends.
*