From: Alexandre Montplaisir Date: Fri, 4 Sep 2015 21:32:13 +0000 (-0400) Subject: ctf: Assign a CtfTmfEventFactory to each trace X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=8e3764747b89563f868311b458e148d50a92580e;p=deliverable%2Ftracecompass.git ctf: Assign a CtfTmfEventFactory to each trace A singleton factory means we cannot possibly extend CtfTmfEvent, because the sole factory can only generate CtfTmfEvent objects. To rectify this, we can turn the factory into a standard non-static class, and have each trace take ownership of its event factory. This means that sub-classes of CtfTmfTrace will be able to provide their own extension of CtfTmfEventFactory if they want to generate other event types. Bug: 476679 Change-Id: I66e9cd49044edd2a77276d779d0f563a2e20d520 Signed-off-by: Alexandre Montplaisir Signed-off-by: Matthew Khouzam Reviewed-on: https://git.eclipse.org/r/56191 Reviewed-by: Hudson CI --- diff --git a/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/event/CtfTmfEventTest.java b/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/event/CtfTmfEventTest.java index 525dd9571d..6b83b268f4 100644 --- a/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/event/CtfTmfEventTest.java +++ b/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/event/CtfTmfEventTest.java @@ -17,7 +17,6 @@ package org.eclipse.tracecompass.tmf.ctf.core.tests.event; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; import java.util.Collection; import java.util.Set; @@ -190,13 +189,13 @@ public class CtfTmfEventTest { } /** - * Test the {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} method, and + * Test the {@link CtfTmfEventFactory#getNullEvent()} method, and * the nullEvent's values. */ @Test public void testNullEvent() { CtfTmfEvent nullEvent2 = CtfTmfEventFactory.getNullEvent(fixture.getTrace()); - assertSame(nullEvent2, nullEvent); + assertEquals(nullEvent2, nullEvent); assertNotNull(nullEvent); assertEquals(-1, nullEvent.getCPU()); assertEquals("Empty CTF event", nullEvent.getType().getName()); diff --git a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/trace/iterator/CtfIterator.java b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/trace/iterator/CtfIterator.java index 29d8d63c17..d621d5266f 100644 --- a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/trace/iterator/CtfIterator.java +++ b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/trace/iterator/CtfIterator.java @@ -26,7 +26,6 @@ import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocation; import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocationInfo; import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent; -import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventFactory; import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace; /** @@ -146,8 +145,7 @@ public class CtfIterator extends CTFTraceReader if (top != null) { if (!fCurLocation.equals(fPreviousLocation)) { fPreviousLocation = fCurLocation; - fPreviousEvent = CtfTmfEventFactory.createEvent(top.getCurrentEvent(), - top.getFilename(), fTrace); + fPreviousEvent = fTrace.getEventFactory().createEvent(fTrace, top.getCurrentEvent(), top.getFilename()); } return fPreviousEvent; } diff --git a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEvent.java b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEvent.java index 9fb7548515..17ef0213ca 100644 --- a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEvent.java +++ b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEvent.java @@ -84,10 +84,35 @@ public class CtfTmfEvent extends TmfEvent // ------------------------------------------------------------------------ /** - * Constructor used by {@link CtfTmfEventFactory#createEvent} + * Constructor, used by {@link CtfTmfEventFactory#createEvent}. + * + * Only subclasses should call this. It is imperative that the subclass also + * has a constructor with the EXACT same parameter signature, because the + * factory will look for a constructor with the same arguments. + * + * @param trace + * The trace to which this event belongs + * @param rank + * The rank of the event + * @param timestamp + * The timestamp + * @param channel + * The CTF channel of this event + * @param cpu + * The event's CPU + * @param declaration + * The event declaration + * @param eventDefinition + * The event definition + * @since 2.0 */ - CtfTmfEvent(CtfTmfTrace trace, long rank, TmfNanoTimestamp timestamp, - String channel, int cpu, IEventDeclaration declaration, EventDefinition eventDefinition) { + protected CtfTmfEvent(CtfTmfTrace trace, + long rank, + TmfNanoTimestamp timestamp, + String channel, + int cpu, + IEventDeclaration declaration, + EventDefinition eventDefinition) { super(trace, rank, timestamp, diff --git a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventFactory.java b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventFactory.java index 83fdf47093..d0632bb49c 100644 --- a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventFactory.java +++ b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventFactory.java @@ -31,34 +31,55 @@ import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace; * * @author Alexandre Montplaisir */ -public final class CtfTmfEventFactory { +public class CtfTmfEventFactory { - private static final @NonNull String NO_STREAM = "No stream"; //$NON-NLS-1$ + private static final @NonNull CtfTmfEventFactory INSTANCE = new CtfTmfEventFactory(); /** - * Don't let anyone instantiate this class. + * The file name to use when none is specified. + * + * FIXME Externalize? + * + * @since 2.0 */ - private CtfTmfEventFactory() {} + protected static final @NonNull String NO_STREAM = "No stream"; //$NON-NLS-1$ /** - * Factory method to instantiate new {@link CtfTmfEvent}'s. + * Protected constructor, only for use by sub-classes. Users should call + * the {@link #instance()} method instead. * + * @since 2.0 + */ + protected CtfTmfEventFactory() {} + + /** + * Get the singleton factory instance + * + * @return The instance + * @since 2.0 + */ + public static @NonNull CtfTmfEventFactory instance() { + return INSTANCE; + } + + /** + * Factory method to instantiate new CTF events. + * + * @param trace + * The trace to which the new event will belong * @param eventDef * CTF EventDefinition object corresponding to this trace event * @param fileName * The path to the trace file - * @param originTrace - * The trace from which this event originates * @return The newly-built CtfTmfEvent + * @since 2.0 */ - public static CtfTmfEvent createEvent(EventDefinition eventDef, - String fileName, CtfTmfTrace originTrace) { + public CtfTmfEvent createEvent(CtfTmfTrace trace, EventDefinition eventDef, String fileName) { /* Prepare what to pass to CtfTmfEvent's constructor */ final IEventDeclaration eventDecl = eventDef.getDeclaration(); final long ts = eventDef.getTimestamp(); - final TmfNanoTimestamp timestamp = originTrace.createTimestamp( - originTrace.timestampCyclesToNanos(ts)); + final TmfNanoTimestamp timestamp = trace.createTimestamp(trace.timestampCyclesToNanos(ts)); int sourceCPU = eventDef.getCPU(); @@ -66,59 +87,83 @@ public final class CtfTmfEventFactory { /* Handle the special case of lost events */ if (eventDecl.getName().equals(CTFStrings.LOST_EVENT_NAME)) { - IDefinition nbLostEventsDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_FIELD); - IDefinition durationDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_DURATION); - if (!(nbLostEventsDef instanceof IntegerDefinition) || !(durationDef instanceof IntegerDefinition)) { - /* - * One or both of these fields doesn't exist, or is not of the - * right type. The event claims to be a "lost event", but is - * malformed. Log it and return a null event instead. - */ - return getNullEvent(originTrace); - } - long nbLostEvents = ((IntegerDefinition) nbLostEventsDef).getValue(); - long duration = ((IntegerDefinition) durationDef).getValue(); - TmfNanoTimestamp timestampEnd = new TmfNanoTimestamp( - originTrace.timestampCyclesToNanos(ts) + duration); - - CtfTmfLostEvent lostEvent = new CtfTmfLostEvent(originTrace, - ITmfContext.UNKNOWN_RANK, - reference, // filename - sourceCPU, - eventDecl, - new TmfTimeRange(timestamp, timestampEnd), - nbLostEvents, - eventDef); - return lostEvent; + return createLostEvent(trace, eventDef, eventDecl, ts, timestamp, sourceCPU, reference); } /* Handle standard event types */ - CtfTmfEvent event = new CtfTmfEvent( - originTrace, + return new CtfTmfEvent(trace, ITmfContext.UNKNOWN_RANK, timestamp, reference, // filename sourceCPU, eventDecl, eventDef); - return event; } - /* Singleton instance of a null event */ - private static CtfTmfEvent nullEvent = null; + /** + * Create a new CTF lost event. + * + * @param trace + * The trace to which the new event will belong + * @param eventDef + * The CTF event definition + * @param eventDecl + * The CTF event declaration + * @param ts + * The event's timestamp + * @param timestamp + * The event's timestamp (FIXME again??) + * @param sourceCPU + * The source CPU + * @param fileName + * The file name + * @return The new lost event + * @since 2.0 + */ + protected static CtfTmfEvent createLostEvent(CtfTmfTrace trace, + EventDefinition eventDef, + final IEventDeclaration eventDecl, + final long ts, + final TmfNanoTimestamp timestamp, + int sourceCPU, + String fileName) { + + IDefinition nbLostEventsDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_FIELD); + IDefinition durationDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_DURATION); + if (!(nbLostEventsDef instanceof IntegerDefinition) || !(durationDef instanceof IntegerDefinition)) { + /* + * One or both of these fields doesn't exist, or is not of the right + * type. The event claims to be a "lost event", but is malformed. + * Log it and return a null event instead. + */ + return getNullEvent(trace); + } + long nbLostEvents = ((IntegerDefinition) nbLostEventsDef).getValue(); + long duration = ((IntegerDefinition) durationDef).getValue(); + TmfNanoTimestamp timestampEnd = new TmfNanoTimestamp( + trace.timestampCyclesToNanos(ts) + duration); + + CtfTmfLostEvent lostEvent = new CtfTmfLostEvent(trace, + ITmfContext.UNKNOWN_RANK, + fileName, + sourceCPU, + eventDecl, + new TmfTimeRange(timestamp, timestampEnd), + nbLostEvents, + eventDef); + return lostEvent; + } /** * Get an instance of a null event. * * @param trace - * A trace to associate with this null event + * The trace to which the new null event will belong * @return An empty event + * @since 2.0 */ - public static CtfTmfEvent getNullEvent(@NonNull CtfTmfTrace trace) { - if (nullEvent == null) { - nullEvent = new CtfTmfEvent(trace); - } - return nullEvent; + public static CtfTmfEvent getNullEvent(CtfTmfTrace trace) { + return new CtfTmfEvent(trace); } diff --git a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/CtfTmfTrace.java b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/CtfTmfTrace.java index 5328b5b293..b3cd9261cc 100644 --- a/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/CtfTmfTrace.java +++ b/ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/CtfTmfTrace.java @@ -66,6 +66,7 @@ import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocation; import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocationInfo; import org.eclipse.tracecompass.tmf.ctf.core.context.CtfTmfContext; import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventFactory; import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventType; import org.eclipse.tracecompass.tmf.ctf.core.event.aspect.CtfChannelAspect; import org.eclipse.tracecompass.tmf.ctf.core.event.aspect.CtfCpuAspect; @@ -122,9 +123,37 @@ public class CtfTmfTrace extends TmfTrace private final CtfIteratorManager fIteratorManager = new CtfIteratorManager(this); - /* Reference to the CTF Trace */ + private final @NonNull CtfTmfEventFactory fEventFactory; + + /** Reference to the CTF Trace */ private CTFTrace fTrace; + // ------------------------------------------- + // Constructor + // ------------------------------------------- + + /** + * Default constructor + */ + public CtfTmfTrace() { + super(); + + /* Use default event factory */ + fEventFactory = CtfTmfEventFactory.instance(); + } + + /** + * Constructor for sub-classes to specify their own event factory. + * + * @param eventFactory + * The event factory to use to generate trace events + * @since 2.0 + */ + protected CtfTmfTrace(@NonNull CtfTmfEventFactory eventFactory) { + super(); + fEventFactory = eventFactory; + } + // ------------------------------------------- // TmfTrace Overrides // ------------------------------------------- @@ -495,6 +524,16 @@ public class CtfTmfTrace extends TmfTrace // CtfIterator factory methods // ------------------------------------------- + /** + * Get the event factory for this trace to generate new events for it. + * + * @return The event factory + * @since 2.0 + */ + public @NonNull CtfTmfEventFactory getEventFactory() { + return fEventFactory; + } + /** * Get an iterator to the trace *