| /******************************************************************************* |
| * Copyright (c) 2016 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.ui.views.vresources; |
| |
| import java.util.Comparator; |
| import java.util.Iterator; |
| import java.util.NoSuchElementException; |
| |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; |
| |
| /** |
| * Caching iterator of time events with a couple extras. |
| * <ul> |
| * <li>peek() allows reading the head without removing it</li> |
| * <li>trim() allows removing a bit of the first event</li> |
| * </ul> |
| * |
| * @author Matthew Khouzam |
| */ |
| class CachingIterator implements Iterator<@NonNull ITimeEvent>, Comparable<CachingIterator> { |
| private ITimeEvent fEvent; |
| private @NonNull Iterator<@NonNull ? extends ITimeEvent> fIterator; |
| private final Comparator<ITimeEvent> fComparator; |
| |
| public CachingIterator(@NonNull Iterator<@NonNull ? extends ITimeEvent> iterator, Comparator<ITimeEvent> comparator) { |
| fIterator = iterator; |
| fComparator = comparator; |
| fEvent = iterator.hasNext() ? iterator.next() : null; |
| } |
| |
| @Override |
| public ITimeEvent next() { |
| ITimeEvent retVal = fEvent; |
| fEvent = fIterator.hasNext() ? fIterator.next() : null; |
| if (retVal == null) { |
| throw new NoSuchElementException("Iterator is empty"); //$NON-NLS-1$ |
| } |
| return retVal; |
| } |
| |
| @Override |
| public boolean hasNext() { |
| return fEvent != null; |
| } |
| |
| /** |
| * Retrieves, but does not remove, the next element of this iterator, or |
| * returns {@code null} if this iterator does not have a next. |
| * |
| * @return the next element of the iterator |
| */ |
| public ITimeEvent peek() { |
| return fEvent; |
| } |
| |
| @Override |
| public int compareTo(CachingIterator o) { |
| final ITimeEvent myEvent = peek(); |
| final ITimeEvent otherEvent = o.peek(); |
| return fComparator.compare(myEvent, otherEvent); |
| } |
| |
| /** |
| * Trims the next element in the iterator to be after a cut-off time. |
| * |
| * @param time |
| * the cut-off time |
| * @return true if there was a trim |
| */ |
| public boolean trim(long time) { |
| if (time <= fEvent.getTime()) { |
| return false; |
| } |
| if (time < fEvent.getTime() + fEvent.getDuration()) { |
| fEvent = fEvent.splitAfter(time); |
| return true; |
| } |
| fEvent = fIterator.hasNext() ? fIterator.next() : null; |
| return true; |
| } |
| |
| } |