From 4dafe201d93c6d2f6ff9ab955a8eebc88811bac3 Mon Sep 17 00:00:00 2001 From: Matthew Khouzam Date: Tue, 22 Sep 2015 15:26:31 -0400 Subject: [PATCH] treemapstore: make the iterator copy on read after write. 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 Reviewed-on: https://git.eclipse.org/r/56468 Reviewed-by: Hudson CI Reviewed-by: Alexandre Montplaisir Tested-by: Alexandre Montplaisir --- .../core/treemap/TreeMapStore.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java index e0acbab718..81f37a0306 100644 --- a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java @@ -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 implements ISegmentStore { private long fSize; + private @Nullable transient Iterable fLastSnapshot = null; + /** * Constructor */ @@ -83,13 +87,19 @@ public class TreeMapStore implements ISegmentStore { fSize = 0; } - /** - * Warning, this is not thread safe, and can cause concurrent modification - * exceptions - */ @Override public Iterator iterator() { - return checkNotNull(fStartTimesIndex.values().iterator()); + fLock.readLock().lock(); + try { + Iterable 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 implements ISegmentStore { if (fStartTimesIndex.put(Long.valueOf(val.getStart()), val)) { fEndTimesIndex.put(Long.valueOf(val.getEnd()), val); fSize++; + fLastSnapshot = null; } } finally { fLock.writeLock().unlock(); -- 2.34.1