X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=org.eclipse.linuxtools.tmf.core%2Fsrc%2Forg%2Feclipse%2Flinuxtools%2Ftmf%2Fcore%2Fctfadaptor%2FCtfTmfTrace.java;h=700b0a9d7d228c807e0bbe948349375249192527;hb=102e61914a8eef26355ca4e1430b529bfd643e48;hp=ee34c41161bb741dbf524194dcda08aa3dfedee4;hpb=11d6f4681ecc6f587db224a7d4bc5e37b90a975b;p=deliverable%2Ftracecompass.git diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java index ee34c41161..700b0a9d7d 100644 --- a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java @@ -1,333 +1,406 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Patrick Tasse - Updated for removal of context clone + *******************************************************************************/ + package org.eclipse.linuxtools.tmf.core.ctfadaptor; +import java.util.Collections; +import java.util.Map; + import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; import org.eclipse.linuxtools.ctf.core.trace.CTFTrace; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp; +import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader; +import org.eclipse.linuxtools.internal.tmf.core.Activator; +import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.statesystem.StateSystem; +import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; +import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -public class CtfTmfTrace extends TmfEventProvider implements ITmfTrace { - - // ------------------------------------------------------------------------ +import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties; +import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; + +/** + * The CTf trace handler + * + * @version 1.0 + * @author Matthew khouzam + */ +public class CtfTmfTrace extends TmfTrace + implements ITmfEventParser, ITmfTraceProperties { + + // ------------------------------------------- // Constants - // ------------------------------------------------------------------------ + // ------------------------------------------- + /** + * Default cache size for CTF traces + */ + protected static final int DEFAULT_CACHE_SIZE = 50000; - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ + // ------------------------------------------- + // Fields + // ------------------------------------------- - // the Ctf Trace + /* Reference to the CTF Trace */ private CTFTrace fTrace; - // The number of events collected - protected long fNbEvents = 0; - - // The time span of the event stream - private ITmfTimestamp fStartTime = TmfTimestamp.BIG_CRUNCH; - private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG; - - // The trace resource - private IResource fResource; - - /* - * Since in TMF, "traces" can read events, this trace here will have its own - * iterator. The user can instantiate extra iterator if they want to seek at - * many places at the same time. + // ------------------------------------------- + // TmfTrace Overrides + // ------------------------------------------- + /** + * Method initTrace. + * + * @param resource + * The resource associated with this trace + * @param path + * The path to the trace file + * @param eventType + * The type of events that will be read from this trace + * @throws TmfTraceException + * If something when wrong while reading the trace */ - protected CtfIterator iterator; + @Override + public void initTrace(final IResource resource, final String path, final Class eventType) + throws TmfTraceException { + /* + * Set the cache size. This has to be done before the call to super() + * because the super needs to know the cache size. + */ + setCacheSize(); - /* Reference to the state system assigned to this trace */ - protected StateSystem ss = null; + super.initTrace(resource, path, eventType); - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ + @SuppressWarnings("unused") + CtfTmfEventType type; - public CtfTmfTrace() { - super(); - } - - @Override - public void initTrace(final IResource resource, final String path, final Class eventType) - throws TmfTraceException { - this.fResource = resource; try { this.fTrace = new CTFTrace(path); + CtfIteratorManager.addTrace(this); + CtfTmfContext ctx; + /* Set the start and (current) end times for this trace */ + ctx = (CtfTmfContext) seekEvent(0L); + CtfTmfEvent event = getNext(ctx); + if ((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) { + /* Handle the case where the trace is empty */ + this.setStartTime(TmfTimestamp.BIG_BANG); + } else { + final ITmfTimestamp curTime = event.getTimestamp(); + this.setStartTime(curTime); + this.setEndTime(curTime); + } + } catch (final CTFReaderException e) { /* * If it failed at the init(), we can assume it's because the file * was not found or was not recognized as a CTF trace. Throw into * the new type of exception expected by the rest of TMF. */ - throw new TmfTraceException(e.getMessage()); + throw new TmfTraceException(e.getMessage(), e); } - this.iterator = new CtfIterator(this, 0, 0); - setStartTime(iterator.getCurrentEvent().getTimestamp()); - TmfSignalManager.register(this); - // this.currLocation.setTimestamp(this.fEvent.getTimestamp().getValue()); - // this.fStartTime = new TmfSimpleTimestamp(this.currLocation - // .getLocation().getStartTime()); - // this.fEndTime = new TmfSimpleTimestamp(this.currLocation - // .getLocation().getEndTime()); - // setTimeRange(new TmfTimeRange(this.fStartTime.clone(), - // this.fEndTime.clone())); - - buildStateSystem(); } @Override - public void dispose() { - TmfSignalManager.deregister(this); - } - - @Override - public void broadcast(final TmfSignal signal) { - TmfSignalManager.dispatchSignal(signal); + public synchronized void dispose() { + CtfIteratorManager.removeTrace(this); + if (fTrace != null) { + fTrace.dispose(); + fTrace = null; + } + super.dispose(); } + /** + * Method validate. + * + * @param project + * IProject + * @param path + * String + * @return IStatus IStatus.error or Status.OK_STATUS + * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String) + * @since 2.0 + */ @Override - public boolean validate(final IProject project, final String path) { + public IStatus validate(final IProject project, final String path) { + IStatus validTrace = Status.OK_STATUS; try { final CTFTrace temp = new CTFTrace(path); - return temp.majortIsSet(); // random test + if (!temp.majortIsSet()) { + validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet); + } else { + CTFTraceReader ctfTraceReader = new CTFTraceReader(temp); + if (!ctfTraceReader.hasMoreEvents()) { + // TODO: This will need an additional check when we support live traces + // because having no event is valid for a live trace + validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_NoEvent); + } + ctfTraceReader.dispose(); + } + temp.dispose(); } catch (final CTFReaderException e) { - /* Nope, not a CTF trace we can read */ - return false; + validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError +": " + e.toString()); //$NON-NLS-1$ } + return validTrace; } - @Override - public CtfTmfTrace clone() throws CloneNotSupportedException { - CtfTmfTrace clone = null; - clone = (CtfTmfTrace) super.clone(); - clone.fStartTime = this.fStartTime.clone(); - clone.fEndTime = this.fEndTime.clone(); - clone.fTrace = this.fTrace; - return clone; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - /** - * @return the trace path + * Method getCurrentLocation. This is not applicable in CTF + * + * @return null, since the trace has no knowledge of the current location + * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation() */ @Override - public Class getEventType() { - return fType; - } - - public int getNbEnvVars() { - return this.fTrace.getEnvironment().size(); - } - - - public String[] getEnvNames() { - final String[] s = new String[getNbEnvVars()]; - return this.fTrace.getEnvironment().keySet().toArray(s); + public ITmfLocation getCurrentLocation() { + return null; } - public String getEnvValue(final String key) { - return this.fTrace.getEnvironment().get(key); + @Override + public double getLocationRatio(ITmfLocation location) { + final CtfLocation curLocation = (CtfLocation) location; + final CtfTmfContext context = new CtfTmfContext(this); + context.setLocation(curLocation); + context.seek(curLocation.getLocationInfo()); + final CtfLocationInfo currentTime = ((CtfLocationInfo) context.getLocation().getLocationInfo()); + final long startTime = getIterator(this, context).getStartTime(); + final long endTime = getIterator(this, context).getEndTime(); + return ((double) currentTime.getTimestamp() - startTime) + / (endTime - startTime); } - /** - * @return the trace path + * Method seekEvent. + * + * @param location + * ITmfLocation + * @return ITmfContext */ @Override - public String getPath() { - return this.fTrace.getPath(); - } - - @Override - public String getName() { - final String temp[] = this.fTrace.getPath().split( - System.getProperty("file.separator")); //$NON-NLS-1$ - if (temp.length > 2) { - return temp[temp.length - 1]; + public synchronized ITmfContext seekEvent(final ITmfLocation location) { + CtfLocation currentLocation = (CtfLocation) location; + CtfTmfContext context = new CtfTmfContext(this); + if (fTrace == null) { + context.setLocation(null); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; } - return temp[0]; + /* + * The rank is set to 0 if the iterator seeks the beginning. If not, it + * will be set to UNKNOWN_RANK, since CTF traces don't support seeking + * by rank for now. + */ + if (currentLocation == null) { + currentLocation = new CtfLocation(new CtfLocationInfo(0L, 0L)); + context.setRank(0); + } + if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) { + currentLocation = new CtfLocation(getEndTime().getValue() + 1, 0L); + } + context.setLocation(currentLocation); + if (location == null) { + CtfTmfEvent event = getIterator(this, context).getCurrentEvent(); + if (event != null) { + currentLocation = new CtfLocation(event.getTimestamp().getValue(), 0); + } + } + if (context.getRank() != 0) { + context.setRank(ITmfContext.UNKNOWN_RANK); + } + return context; } @Override - public int getCacheSize() { - return 50000; // not true, but it works + public synchronized ITmfContext seekEvent(double ratio) { + CtfTmfContext context = new CtfTmfContext(this); + if (fTrace == null) { + context.setLocation(null); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } + final long end = this.getEndTime().getValue(); + final long start = this.getStartTime().getValue(); + final long diff = end - start; + final long ratioTs = Math.round(diff * ratio) + start; + context.seek(ratioTs); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; } + /** + * Method readNextEvent. + * + * @param context + * ITmfContext + * @return CtfTmfEvent + * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext) + */ @Override - public long getNbEvents() { - return this.fNbEvents; - } + public synchronized CtfTmfEvent getNext(final ITmfContext context) { + if (fTrace == null) { + return null; + } + CtfTmfEvent event = null; + if (context instanceof CtfTmfContext) { + if (context.getLocation() == null || CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocationInfo())) { + return null; + } + CtfTmfContext ctfContext = (CtfTmfContext) context; + event = ctfContext.getCurrentEvent(); + + if (event != null) { + updateAttributes(context, event.getTimestamp()); + ctfContext.advance(); + ctfContext.increaseRank(); + } + } - @Override - public TmfTimeRange getTimeRange() { - return new TmfTimeRange(this.fStartTime, this.fEndTime); + return event; } - @Override - public ITmfTimestamp getStartTime() { - return this.fStartTime; + /** + * gets the CTFtrace that this is wrapping + * + * @return the CTF trace + */ + public CTFTrace getCTFTrace() { + return fTrace; } - @Override - public ITmfTimestamp getEndTime() { - return this.fEndTime; - } + // ------------------------------------------- + // ITmfTraceProperties + // ------------------------------------------- + /** + * @since 2.0 + */ @Override - public ITmfLocation getCurrentLocation() { - return iterator.getLocation(); - } - - // ------------------------------------------------------------------------ - // Operators - // ------------------------------------------------------------------------ - - protected void setTimeRange(final TmfTimeRange range) { - this.fStartTime = range.getStartTime(); - this.fEndTime = range.getEndTime(); - } - - protected void setStartTime(final ITmfTimestamp startTime) { - this.fStartTime = startTime; - } - - protected void setEndTime(final ITmfTimestamp endTime) { - this.fEndTime = endTime; + public Map getTraceProperties() { + return Collections.unmodifiableMap(fTrace.getEnvironment()); } - // ------------------------------------------------------------------------ - // TmfProvider - // ------------------------------------------------------------------------ - - @Override - public ITmfContext armRequest(final ITmfDataRequest request) { - if ((request instanceof ITmfEventRequest) - && !TmfTimestamp.BIG_BANG - .equals(((ITmfEventRequest) request) - .getRange().getStartTime()) - && (request.getIndex() == 0)) { - final ITmfContext context = seekEvent(((ITmfEventRequest) request) - .getRange().getStartTime()); - ((ITmfEventRequest) request) - .setStartIndex((int) context.getRank()); - return context; - } - return seekEvent(request.getIndex()); - } + // ------------------------------------------- + // Clocks + // ------------------------------------------- /** - * The trace reader keeps its own iterator: the "context" parameter here - * will be ignored. - * - * If you wish to specify a new context, instantiate a new CtfIterator and - * seek() it to where you want, and use that to read events. + * gets the clock offset * - * FIXME merge with getNextEvent below once they both use the same parameter - * type. + * @return the clock offset in ns */ - @Override - public CtfTmfEvent getNext(final ITmfContext context) { - iterator.advance(); - return iterator.getCurrentEvent(); - } - - // ------------------------------------------------------------------------ - // ITmfTrace - // ------------------------------------------------------------------------ - - @Override - public ITmfContext seekEvent(final ITmfLocation location) { - CtfLocation currentLocation = (CtfLocation) location; - if (currentLocation == null) { - currentLocation = new CtfLocation(0L); + public long getOffset() { + if (fTrace != null) { + return fTrace.getOffset(); } - iterator.setLocation(currentLocation); - return iterator; - } - - @Override - public double getLocationRatio(final ITmfLocation location) { - final CtfLocation curLocation = (CtfLocation) location; - iterator.seek(curLocation.getLocation()); - return ((double) iterator.getCurrentEvent().getTimestampValue() - iterator - .getStartTime()) - / (iterator.getEndTime() - iterator.getStartTime()); - } - - @Override - public long getStreamingInterval() { return 0; } - @Override - public ITmfContext seekEvent(final ITmfTimestamp timestamp) { - iterator.seek(timestamp.getValue()); - return iterator; - } - /** - * Seek by rank + * Returns whether or not an event is in the metadata of the trace, + * therefore if it can possibly be in the trace. It does not verify whether + * or not the event is actually in the trace + * + * @param eventName + * The name of the event to check + * @return Whether the event is in the metadata or not + * @since 2.1 */ - @Override - public ITmfContext seekEvent(final long rank) { - iterator.setRank(rank); - return iterator; + public boolean hasEvent(final String eventName) { + Map events = fTrace.getEvents(0L); + if (events != null) { + for (IEventDeclaration decl : events.values()) { + if (decl.getName().equals(eventName)) { + return true; + } + } + } + return false; } /** - * Seek rank ratio + * Return whether all requested events are in the metadata + * + * @param names + * The array of events to check for + * @return Whether all events are in the metadata + * @since 2.1 */ - @Override - public ITmfContext seekEvent(final double ratio) { - iterator.seek((long) (this.fNbEvents * ratio)); - return iterator; + public boolean hasAllEvents(String[] names) { + for (String name : names) { + if (!hasEvent(name)) { + return false; + } + } + return true; } - @Override - public CtfTmfEvent readNextEvent(final ITmfContext context) { - iterator.advance(); - return iterator.getCurrentEvent(); + /** + * Returns whether the metadata contains at least one of the requested + * events + * + * @param names + * The array of event names of check for + * @return Whether one of the event is present in trace metadata + * @since 2.1 + */ + public boolean hasAtLeastOneOfEvents(String[] names) { + for (String name : names) { + if (hasEvent(name)) { + return true; + } + } + return false; } -// @Override -// public CtfTmfEvent parseEvent(final ITmfContext context) { -// return iterator.getCurrentEvent(); -// } + // ------------------------------------------- + // Parser + // ------------------------------------------- @Override - public IResource getResource() { - return this.fResource; + public CtfTmfEvent parseEvent(ITmfContext context) { + CtfTmfEvent event = null; + if (context instanceof CtfTmfContext) { + final ITmfContext tmpContext = seekEvent(context.getLocation()); + event = getNext(tmpContext); + } + return event; } - public StateSystem getStateSystem() { - return this.ss; + /** + * Sets the cache size for a CtfTmfTrace. + */ + protected void setCacheSize() { + setCacheSize(DEFAULT_CACHE_SIZE); } - CTFTrace getCTFTrace() { - return fTrace; - } + // ------------------------------------------- + // Helpers + // ------------------------------------------- - protected void buildStateSystem() throws TmfTraceException { - /* - * Nothing is done in the basic implementation, please specify - * how/if to build a state system in derived classes. - */ - return; + private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfContext context) { + return CtfIteratorManager.getIterator(trace, context); } + /** + * Get an iterator to the trace + * + * @return an iterator to the trace + * @since 2.0 + */ + public CtfIterator createIterator() { + return new CtfIterator(this); + } }