ss: Make ISegmentStore implement Collection
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Thu, 24 Sep 2015 21:55:23 +0000 (17:55 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 25 Sep 2015 22:03:31 +0000 (18:03 -0400)
It used to implement Iterable, not many changes are required to
support the entirety of Collection.

Change-Id: I1622c222d3eb72afdde47ca0a462003dda85d0cd
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-on: https://git.eclipse.org/r/56680
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/LatencyAnalysis.java
statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/treemap/TreeMapStoreTest.java
statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/ISegmentStore.java
statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java

index 8b8d50f6d0fbdb58bde5c580ed9192fb379b90c8..7aaf4396d0203f466a0a06b939f01af0ea0c9077 100644 (file)
@@ -202,7 +202,7 @@ public class LatencyAnalysis extends TmfAbstractAnalysisModule {
                 long endTime = event.getTimestamp().getValue();
                 int ret = ((Long) event.getContent().getField("ret").getValue()).intValue(); //$NON-NLS-1$
                 ISegment syscall = new SystemCall(info, endTime, ret);
-                fFullSyscalls.addElement(syscall);
+                fFullSyscalls.add(syscall);
             }
         }
 
index f9f112133b3aa60f1e9dfdf4a47b59681932a20a..ecd7629fef423da2c8c62c4b2bf3bdbf67f766aa 100644 (file)
@@ -11,7 +11,10 @@ package org.eclipse.tracecompass.segmentstore.core.tests.treemap;
 
 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
@@ -50,7 +53,7 @@ public class TreeMapStoreTest {
     public void setup() {
         fSegmentStore = new TreeMapStore<>();
         for (ISegment segment : SEGMENTS) {
-            fSegmentStore.addElement(checkNotNull(segment));
+            fSegmentStore.add(checkNotNull(segment));
         }
     }
 
@@ -63,11 +66,61 @@ public class TreeMapStoreTest {
     }
 
     /**
-     * Testing method getNbElements
+     * Testing method size()
      */
     @Test
-    public void testGetNbElements() {
-        assertEquals(SEGMENTS.size(), fSegmentStore.getNbElements());
+    public void testSize() {
+        assertEquals(SEGMENTS.size(), fSegmentStore.size());
+    }
+
+    /**
+     * Test the contains() method.
+     */
+    @Test
+    public void testContains() {
+        ISegment otherSegment = new BasicSegment(0, 20);
+
+        assertTrue(fSegmentStore.contains(SEGMENT_2_6));
+        assertTrue(fSegmentStore.contains(SEGMENT_4_8));
+        assertFalse(fSegmentStore.contains(otherSegment));
+    }
+
+    /**
+     * Test the toArray() method.
+     */
+    @Test
+    public void testToObjectArray() {
+        Object[] array = fSegmentStore.toArray();
+
+        assertEquals(SEGMENTS.size(), array.length);
+        assertTrue(Arrays.asList(array).containsAll(SEGMENTS));
+    }
+
+    /**
+     * Test the toArray(T[]) method.
+     */
+    @Test
+    public void testToSpecificArray() {
+        ISegment[] array = fSegmentStore.toArray(new ISegment[0]);
+
+        assertEquals(SEGMENTS.size(), array.length);
+        assertTrue(Arrays.asList(array).containsAll(SEGMENTS));
+    }
+
+    /**
+     * Test the toArray(T[]) method with a subtype of ISegment.
+     */
+    @Test
+    public void testToSpecifyArraySubtype() {
+        TreeMapStore<BasicSegment> tms2 = new TreeMapStore<>();
+        BasicSegment otherSegment = new BasicSegment(2, 6);
+        tms2.add(otherSegment);
+        BasicSegment[] array = tms2.toArray(new BasicSegment[0]);
+
+        assertEquals(1, array.length);
+        assertTrue(Arrays.asList(array).contains(otherSegment));
+
+        tms2.dispose();
     }
 
     /**
@@ -76,9 +129,9 @@ public class TreeMapStoreTest {
     @Test
     public void testNoDuplicateElements() {
         for (ISegment segment : SEGMENTS) {
-            fSegmentStore.addElement(new BasicSegment(segment.getStart(), segment.getEnd()));
+            fSegmentStore.add(new BasicSegment(segment.getStart(), segment.getEnd()));
         }
-        assertEquals(SEGMENTS.size(), fSegmentStore.getNbElements());
+        assertEquals(SEGMENTS.size(), fSegmentStore.size());
     }
 
     /**
@@ -101,7 +154,7 @@ public class TreeMapStoreTest {
         /* Prepare the segment store, we don't use the 'fixture' in this test */
         TreeMapStore<ISegment> store = new TreeMapStore<>();
         for (ISegment segment : REVERSE_SEGMENTS) {
-            store.addElement(checkNotNull(segment));
+            store.add(checkNotNull(segment));
         }
 
         /*
@@ -238,8 +291,8 @@ public class TreeMapStoreTest {
     @Test
     public void testDispose() {
         TreeMapStore<ISegment> store = new TreeMapStore<>();
-        store.addElement(checkNotNull(SEGMENT_2_6));
+        store.add(SEGMENT_2_6);
         store.dispose();
-        assertEquals(0, store.getNbElements());
+        assertEquals(0, store.size());
     }
 }
\ No newline at end of file
index 41af51d1442467ab303c59af30d518a7f48bc3e0..774dac2833a1005776ccaf0538c622483062c6df 100644 (file)
 
 package org.eclipse.tracecompass.segmentstore.core;
 
+import java.util.Collection;
+
 /**
  * Interface for segment-storing backends.
  *
- * @param <T>
+ * @param <E>
  *            The type of {@link ISegment} element that will be stored in this
  *            database.
  *
  * @author Alexandre Montplaisir
  */
-public interface ISegmentStore<T extends ISegment> extends Iterable<T> {
-
-    /**
-     * Add an element to the database.
-     *
-     * @param elem The element to add.
-     */
-    void addElement(T elem);
-
-    /**
-     * Get the number of element currently existing in the database.
-     *
-     * @return The number of elements.
-     */
-    long getNbElements();
+public interface ISegmentStore<E extends ISegment> extends Collection<E> {
 
     /**
      * Retrieve all elements that inclusively cross the given position.
@@ -45,7 +33,7 @@ public interface ISegmentStore<T extends ISegment> extends Iterable<T> {
      *            tree's X axis represents time.
      * @return The intervals that cross this position
      */
-    Iterable<T> getIntersectingElements(long position);
+    Iterable<E> getIntersectingElements(long position);
 
     /**
      * Retrieve all elements that inclusively cross another segment. We define
@@ -64,7 +52,7 @@ public interface ISegmentStore<T extends ISegment> extends Iterable<T> {
      *            The target end position
      * @return The elements overlapping with this segment
      */
-    Iterable<T> getIntersectingElements(long start, long end);
+    Iterable<E> getIntersectingElements(long start, long end);
 
     /**
      * Dispose the data structure and release any system resources associated
index 81f37a03068713ec82c493aef29cb3182a5e691d..1632d91c041f5a373b4b7a98ce6ad7fe687f2323 100644 (file)
@@ -14,6 +14,7 @@ package org.eclipse.tracecompass.segmentstore.core.treemap;
 
 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
 
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.TreeMap;
 import java.util.concurrent.locks.ReadWriteLock;
@@ -44,21 +45,23 @@ import com.google.common.collect.TreeMultimap;
  * that if you want several segments with the same start and end times, make
  * sure their compareTo() differentiates them.
  *
- * @param <T>
+ * Removal operations are not supported.
+ *
+ * @param <E>
  *            The type of segment held in this store
  *
  * @author Alexandre Montplaisir
  */
-public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
+public class TreeMapStore<E extends ISegment> implements ISegmentStore<E> {
 
     private final ReadWriteLock fLock = new ReentrantReadWriteLock(false);
 
-    private final TreeMultimap<Long, T> fStartTimesIndex;
-    private final TreeMultimap<Long, T> fEndTimesIndex;
+    private final TreeMultimap<Long, E> fStartTimesIndex;
+    private final TreeMultimap<Long, E> fEndTimesIndex;
 
-    private long fSize;
+    private volatile long fSize;
 
-    private @Nullable transient Iterable<T> fLastSnapshot = null;
+    private @Nullable transient Iterable<E> fLastSnapshot = null;
 
     /**
      * Constructor
@@ -76,22 +79,26 @@ public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
          * The same is done for the end times index, but swapping the first two
          * comparators instead.
          */
-        fStartTimesIndex = checkNotNull(TreeMultimap.<Long, T> create(
+        fStartTimesIndex = checkNotNull(TreeMultimap.<Long, E> create(
                 SegmentComparators.LONG_COMPARATOR,
                 Ordering.from(SegmentComparators.INTERVAL_END_COMPARATOR).compound(Ordering.natural())));
 
-        fEndTimesIndex = checkNotNull(TreeMultimap.<Long, T> create(
+        fEndTimesIndex = checkNotNull(TreeMultimap.<Long, E> create(
                 SegmentComparators.LONG_COMPARATOR,
                 Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR).compound(Ordering.natural())));
 
         fSize = 0;
     }
 
+    // ------------------------------------------------------------------------
+    // Methods from Collection
+    // ------------------------------------------------------------------------
+
     @Override
-    public Iterator<T> iterator() {
+    public Iterator<E> iterator() {
         fLock.readLock().lock();
         try {
-            Iterable<T> lastSnapshot = fLastSnapshot;
+            Iterable<E> lastSnapshot = fLastSnapshot;
             if (lastSnapshot == null) {
                 lastSnapshot = checkNotNull(ImmutableList.copyOf(fStartTimesIndex.values()));
                 fLastSnapshot = lastSnapshot;
@@ -103,9 +110,18 @@ public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
     }
 
     @Override
-    public void addElement(T val) {
+    public boolean add(@Nullable E val) {
+        if (val == null) {
+            throw new IllegalArgumentException();
+        }
+
         fLock.writeLock().lock();
         try {
+            /* We can take a read lock while holding the write lock. */
+            if (contains(val)) {
+                return false;
+            }
+
             if (fStartTimesIndex.put(Long.valueOf(val.getStart()), val)) {
                 fEndTimesIndex.put(Long.valueOf(val.getEnd()), val);
                 fSize++;
@@ -114,28 +130,114 @@ public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
         } finally {
             fLock.writeLock().unlock();
         }
+        return true;
+    }
+
+    @Override
+    public int size() {
+        return Long.valueOf(fSize).intValue();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return (fSize == 0);
     }
 
     @Override
-    public long getNbElements() {
+    public boolean contains(@Nullable Object o) {
         fLock.readLock().lock();
         try {
-            return fSize;
+            return fStartTimesIndex.containsValue(o);
         } finally {
             fLock.readLock().unlock();
         }
     }
 
+
+    @Override
+    public boolean containsAll(@Nullable Collection<?> c) {
+        fLock.readLock().lock();
+        try {
+            return fStartTimesIndex.values().containsAll(c);
+        } finally {
+            fLock.readLock().unlock();
+        }
+    }
+
+    @Override
+    public Object[] toArray() {
+        fLock.readLock().lock();
+        try {
+            return checkNotNull(fStartTimesIndex.values().toArray());
+        } finally {
+            fLock.readLock().unlock();
+        }
+    }
+
+    @Override
+    public <T> T[] toArray(@Nullable T[] a) {
+        fLock.readLock().lock();
+        try {
+            return checkNotNull(fStartTimesIndex.values().toArray(a));
+        } finally {
+            fLock.readLock().unlock();
+        }
+    }
+
+    @Override
+    public boolean remove(@Nullable Object o) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean addAll(@Nullable Collection<? extends E> c) {
+        if (c == null) {
+            throw new IllegalArgumentException();
+        }
+
+        fLock.writeLock().lock();
+        try {
+            boolean changed = false;
+            for (E elem : c) {
+                if (this.add(elem)) {
+                    changed = true;
+                }
+            }
+            return changed;
+        } finally {
+            fLock.writeLock().unlock();
+        }
+    }
+
+    @Override
+    public boolean removeAll(@Nullable Collection<?> c) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean retainAll(@Nullable Collection<?> c) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    // ------------------------------------------------------------------------
+    // Methods added by ISegmentStore
+    // ------------------------------------------------------------------------
+
     @Override
-    public Iterable<T> getIntersectingElements(long position) {
+    public Iterable<E> getIntersectingElements(long position) {
         /*
          * The intervals intersecting 't' are those whose 1) start time is
          * *lower* than 't' AND 2) end time is *higher* than 't'.
          */
         fLock.readLock().lock();
         try {
-            Iterable<T> matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(position, true).values());
-            Iterable<T> matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(position, true).values());
+            Iterable<E> matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(position, true).values());
+            Iterable<E> matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(position, true).values());
             return checkNotNull(Sets.intersection(Sets.newHashSet(matchStarts), Sets.newHashSet(matchEnds)));
         } finally {
             fLock.readLock().unlock();
@@ -143,11 +245,11 @@ public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
     }
 
     @Override
-    public Iterable<T> getIntersectingElements(long start, long end) {
+    public Iterable<E> getIntersectingElements(long start, long end) {
         fLock.readLock().lock();
         try {
-            Iterable<T> matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(end, true).values());
-            Iterable<T> matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(start, true).values());
+            Iterable<E> matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(end, true).values());
+            Iterable<E> matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(start, true).values());
             return checkNotNull(Sets.intersection(Sets.newHashSet(matchStarts), Sets.newHashSet(matchEnds)));
         } finally {
             fLock.readLock().unlock();
This page took 0.03373 seconds and 5 git commands to generate.