treemapstore: make the iterator copy on read after write.
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Tue, 22 Sep 2015 19:26:31 +0000 (15:26 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Thu, 24 Sep 2015 22:55:48 +0000 (18:55 -0400)
This may appear to be an odd synchronization scheme, but
there are normally 1 million writes per read, and then at
the end there are no more writes, so this will minimize copies
of the data much more than a traditional copy on write.

Change-Id: I9d78bc2a1de788ca41742e57d0df45d42ac4642a
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/56468
Reviewed-by: Hudson CI
Reviewed-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Tested-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java

index e0acbab718ea0af6c26ed323dce6f43d7e2b32e9..81f37a03068713ec82c493aef29cb3182a5e691d 100644 (file)
@@ -19,10 +19,12 @@ import java.util.TreeMap;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.segmentstore.core.ISegment;
 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
 import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Ordering;
 import com.google.common.collect.Sets;
@@ -56,6 +58,8 @@ public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
 
     private long fSize;
 
+    private @Nullable transient Iterable<T> fLastSnapshot = null;
+
     /**
      * Constructor
      */
@@ -83,13 +87,19 @@ public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
         fSize = 0;
     }
 
-    /**
-     * Warning, this is not thread safe, and can cause concurrent modification
-     * exceptions
-     */
     @Override
     public Iterator<T> iterator() {
-        return checkNotNull(fStartTimesIndex.values().iterator());
+        fLock.readLock().lock();
+        try {
+            Iterable<T> lastSnapshot = fLastSnapshot;
+            if (lastSnapshot == null) {
+                lastSnapshot = checkNotNull(ImmutableList.copyOf(fStartTimesIndex.values()));
+                fLastSnapshot = lastSnapshot;
+            }
+            return checkNotNull(lastSnapshot.iterator());
+        } finally {
+            fLock.readLock().unlock();
+        }
     }
 
     @Override
@@ -99,6 +109,7 @@ public class TreeMapStore<T extends ISegment> implements ISegmentStore<T> {
             if (fStartTimesIndex.put(Long.valueOf(val.getStart()), val)) {
                 fEndTimesIndex.put(Long.valueOf(val.getEnd()), val);
                 fSize++;
+                fLastSnapshot = null;
             }
         } finally {
             fLock.writeLock().unlock();
This page took 0.027518 seconds and 5 git commands to generate.