tmf: Bug 500542: Missing zoomed events in time graph entry
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / model / TimeGraphEntry.java
index 4882800e77e984a9a1cd0c7834715914d8b569dd..8f36276a5ef45b8f47e970872b4e649b308b8abc 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2012, 2016 Ericsson, École Polytechnique de Montréal
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -19,7 +19,9 @@ import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.regex.Pattern;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.swt.SWT;
 
 /**
@@ -28,17 +30,17 @@ import org.eclipse.swt.SWT;
 public class TimeGraphEntry implements ITimeGraphEntry {
 
     /** Entry's parent */
-    private ITimeGraphEntry fParent = null;
+    private TimeGraphEntry fParent = null;
 
     /** List of child entries */
-    private final List<ITimeGraphEntry> fChildren = new CopyOnWriteArrayList<>();
+    private final List<@NonNull TimeGraphEntry> fChildren = new CopyOnWriteArrayList<>();
 
     /** Name of this entry (text to show) */
     private String fName;
     private long fStartTime = SWT.DEFAULT;
     private long fEndTime = SWT.DEFAULT;
-    private List<ITimeEvent> fEventList = new ArrayList<>();
-    private List<ITimeEvent> fZoomedEventList = new ArrayList<>();
+    private @NonNull List<ITimeEvent> fEventList = new ArrayList<>();
+    private @NonNull List<ITimeEvent> fZoomedEventList = new ArrayList<>();
     private Comparator<ITimeGraphEntry> fComparator;
 
     /**
@@ -61,32 +63,21 @@ public class TimeGraphEntry implements ITimeGraphEntry {
     // Getters and setters
     // ---------------------------------------------
 
-    @Override
-    public ITimeGraphEntry getParent() {
-        return fParent;
-    }
-
     /**
-     * Sets the entry's parent
-     *
-     * @param entry The new parent entry
+     * @since 2.0
      */
-    /*
-     * TODO: This method can be removed in the next major API version.
-     */
-    protected void setParent(TimeGraphEntry entry) {
-        fParent = entry;
+    @Override
+    public TimeGraphEntry getParent() {
+        return fParent;
     }
 
     /**
      * Sets the entry's parent
      *
      * @param entry The new parent entry
+     * @since 2.0
      */
-    /*
-     * TODO: This method should be added to the interface in the next major API version.
-     */
-    protected void setParent(ITimeGraphEntry entry) {
+    public void setParent(TimeGraphEntry entry) {
         fParent = entry;
     }
 
@@ -96,10 +87,19 @@ public class TimeGraphEntry implements ITimeGraphEntry {
     }
 
     @Override
-    public synchronized List<? extends ITimeGraphEntry> getChildren() {
+    public synchronized List<@NonNull TimeGraphEntry> getChildren() {
         return fChildren;
     }
 
+    /**
+     * Clear the children of the entry
+     *
+     * @since 2.0
+     */
+    public synchronized void clearChildren() {
+        fChildren.clear();
+    }
+
     @Override
     public String getName() {
         return fName;
@@ -141,7 +141,7 @@ public class TimeGraphEntry implements ITimeGraphEntry {
     }
 
     @Override
-    public Iterator<ITimeEvent> getTimeEventsIterator() {
+    public Iterator<@NonNull ITimeEvent> getTimeEventsIterator() {
         if (hasTimeEvents()) {
             return new EventIterator(fEventList, fZoomedEventList);
         }
@@ -149,7 +149,7 @@ public class TimeGraphEntry implements ITimeGraphEntry {
     }
 
     @Override
-    public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
+    public Iterator<@NonNull ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
         if (!hasTimeEvents()) {
             return null;
         }
@@ -167,61 +167,90 @@ public class TimeGraphEntry implements ITimeGraphEntry {
     public void addEvent(ITimeEvent event) {
         long start = event.getTime();
         long end = start + event.getDuration();
-        synchronized (fEventList) {
-            int lastIndex = fEventList.size() - 1;
-            if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) {
-                fEventList.set(lastIndex, event);
-            } else {
-                fEventList.add(event);
-            }
-            if (fStartTime == SWT.DEFAULT || start < fStartTime) {
-                fStartTime = start;
-            }
-            if (fEndTime == SWT.DEFAULT || end > fEndTime) {
-                fEndTime = end;
-            }
+        int lastIndex = fEventList.size() - 1;
+        if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) {
+            fEventList.set(lastIndex, event);
+        } else {
+            fEventList.add(event);
+        }
+        if (event instanceof NullTimeEvent) {
+            /* A NullTimeEvent should not affect the entry bounds */
+            return;
+        }
+        if (fStartTime == SWT.DEFAULT || start < fStartTime) {
+            fStartTime = start;
+        }
+        if (fEndTime == SWT.DEFAULT || end > fEndTime) {
+            fEndTime = end;
         }
     }
 
     /**
-     * Set the general event list of this entry.
+     * Set the general event list of this entry. The list should be modifiable
+     * but will only increase in size over time.
      *
      * @param eventList
-     *            The list of time events
+     *            The modifiable list of time events, or null to clear the list
      */
     public void setEventList(List<ITimeEvent> eventList) {
         if (eventList != null) {
-            fEventList = new ArrayList<>(eventList);
+            fEventList = eventList;
         } else {
             fEventList = new ArrayList<>();
         }
     }
 
     /**
-     * Set the zoomed event list of this entry.
+     * Set the zoomed event list of this entry. The list should be modifiable
+     * but will only increase in size over time.
      *
      * @param eventList
-     *            The list of time events
+     *            The modifiable list of time events, or null to clear the list
      */
     public void setZoomedEventList(List<ITimeEvent> eventList) {
         if (eventList != null) {
-            fZoomedEventList = new ArrayList<>(eventList);
+            fZoomedEventList = eventList;
         } else {
             fZoomedEventList = new ArrayList<>();
         }
     }
 
     /**
-     * Add a child entry to this one
+     * Add an event to this entry's zoomed event list. If necessary, update the
+     * start and end time of the entry. If the zoomed event list's last event
+     * starts at the same time as the event to add, it is replaced by the new
+     * event. If the new event starts before the zoomed event list's last event,
+     * the new event is ignored and is assumed to be already part of the list.
+     * If the new event starts before the zoomed event list's first event, the
+     * list is assumed to be incomplete and is cleared, and the event is added.
      *
-     * @param child
-     *            The child entry
-     */
-    /*
-     * TODO: This method can be removed in the next major API version.
+     * @param event
+     *            The time event to add
+     * @since 1.1
      */
-    public synchronized void addChild(TimeGraphEntry child) {
-        addChild((ITimeGraphEntry) child);
+    public void addZoomedEvent(ITimeEvent event) {
+        long start = event.getTime();
+        long end = start + event.getDuration();
+        int lastIndex = fZoomedEventList.size() - 1;
+        long lastStart = lastIndex >= 0 ? fZoomedEventList.get(lastIndex).getTime() : Long.MIN_VALUE;
+        if (start > lastStart) {
+            fZoomedEventList.add(event);
+        } else if (start == lastStart) {
+            fZoomedEventList.set(lastIndex, event);
+        } else if (start < fZoomedEventList.get(0).getTime()) {
+            fZoomedEventList.clear();
+            fZoomedEventList.add(event);
+        }
+        if (event instanceof NullTimeEvent) {
+            /* A NullTimeEvent should not affect the entry bounds */
+            return;
+        }
+        if (fStartTime == SWT.DEFAULT || start < fStartTime) {
+            fStartTime = start;
+        }
+        if (fEndTime == SWT.DEFAULT || end > fEndTime) {
+            fEndTime = end;
+        }
     }
 
     /**
@@ -232,13 +261,8 @@ public class TimeGraphEntry implements ITimeGraphEntry {
      * @param child
      *            The child entry
      */
-    public synchronized void addChild(ITimeGraphEntry child) {
-        /*
-         * TODO: Use setParent() once it is added to the interface.
-         */
-        if (child instanceof TimeGraphEntry) {
-            ((TimeGraphEntry) child).fParent = this;
-        }
+    public synchronized void addChild(@NonNull TimeGraphEntry child) {
+        child.setParent(this);
         if (fComparator == null) {
             fChildren.add(child);
         } else {
@@ -260,20 +284,28 @@ public class TimeGraphEntry implements ITimeGraphEntry {
      *            Index at which the specified entry is to be inserted
      * @param child
      *            The child entry
+     * @since 2.0
      */
-    public synchronized void addChild(int index, ITimeGraphEntry child) {
-        /*
-         * TODO: Use setParent() once it is added to the interface.
-         */
-        if (child instanceof TimeGraphEntry) {
-            ((TimeGraphEntry) child).fParent = this;
-        }
+    public synchronized void addChild(int index, @NonNull TimeGraphEntry child) {
+        child.setParent(this);
         fChildren.add(index, child);
     }
 
+    /**
+     * Remove a child entry from this one.
+     *
+     * @param child
+     *            The child entry
+     * @since 2.0
+     */
+    public synchronized void removeChild(@NonNull TimeGraphEntry child) {
+        child.setParent(null);
+        fChildren.remove(child);
+    }
+
     /**
      * Sort the children of this entry using the provided comparator. Subsequent
-     * calls to {@link #addChild(ITimeGraphEntry)} will use this comparator to
+     * calls to {@link #addChild(TimeGraphEntry)} will use this comparator to
      * maintain the sort order.
      *
      * @param comparator
@@ -284,7 +316,7 @@ public class TimeGraphEntry implements ITimeGraphEntry {
         if (comparator == null) {
             return;
         }
-        ITimeGraphEntry[] array = fChildren.toArray(new ITimeGraphEntry[0]);
+        @NonNull TimeGraphEntry[] array = fChildren.toArray(new @NonNull TimeGraphEntry[0]);
         Arrays.sort(array, comparator);
         fChildren.clear();
         fChildren.addAll(Arrays.asList(array));
@@ -295,4 +327,13 @@ public class TimeGraphEntry implements ITimeGraphEntry {
         return getClass().getSimpleName() + '(' + fName + ')';
     }
 
+    /**
+     * @since 2.0
+     */
+    @Override
+    public boolean matches(@NonNull Pattern pattern) {
+        // Default implementation
+        return pattern.matcher(fName).find();
+    }
+
 }
This page took 0.032916 seconds and 5 git commands to generate.