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>
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
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 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;
import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
+ private @Nullable transient Iterable<T> fLastSnapshot = null;
+
- /**
- * Warning, this is not thread safe, and can cause concurrent modification
- * exceptions
- */
@Override
public Iterator<T> iterator() {
@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();
+ }
if (fStartTimesIndex.put(Long.valueOf(val.getStart()), val)) {
fEndTimesIndex.put(Long.valueOf(val.getEnd()), val);
fSize++;
if (fStartTimesIndex.put(Long.valueOf(val.getStart()), val)) {
fEndTimesIndex.put(Long.valueOf(val.getEnd()), val);
fSize++;
}
} finally {
fLock.writeLock().unlock();
}
} finally {
fLock.writeLock().unlock();