Skip to content

Commit

Permalink
scripting: Move the script event request to its own class
Browse files Browse the repository at this point in the history
It is possible to make event requests without having an analysis. So now
the trace module also provides a getEventIterator method for a trace,
the request has been moved to its own file, and has a #getEventIterator
method

Change-Id: I73a1d51aafdb87960e6b91877fb4102e41b6a6d2
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/151118
Tested-by: CI Bot
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
  • Loading branch information
tahini committed Oct 16, 2019
1 parent 632d834 commit ff613fe
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
Expand All @@ -31,8 +32,10 @@
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.incubator.internal.scripting.core.trace.Messages;
import org.eclipse.tracecompass.incubator.scripting.core.tests.ActivatorTest;
import org.eclipse.tracecompass.incubator.scripting.core.tests.stubs.ScriptingTestUtils;
import org.eclipse.tracecompass.incubator.scripting.core.trace.TraceScriptingModule;
import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.io.ResourceUtil;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub;
Expand Down Expand Up @@ -254,4 +257,31 @@ public void testNonexistentTraceFile() {
}
assertTrue(!fileExist);
}

/**
* Test the event iterator
*/
@Test
public void testEventIterator() {
TraceScriptingModule traceScriptingModule = new TraceScriptingModule();

ITmfTrace trace = ScriptingTestUtils.getTrace();
try {

Iterator<ITmfEvent> eventIterator = traceScriptingModule.getEventIterator(trace);
assertNotNull(eventIterator);

int count = 0;
while (eventIterator.hasNext()) {
eventIterator.next();
count++;
}
// Make sure it parsed the whole trace
assertEquals(36, count);

} finally {
trace.dispose();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*******************************************************************************
* Copyright (c) 2019 École Polytechnique de Montréal
*
* 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
*******************************************************************************/

package org.eclipse.tracecompass.incubator.internal.scripting.core.trace;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.collect.BufferedBlockingQueue;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;

/**
* An event request for scripted analysis. This class has a {link
* #getEventIterator()} method which returns the iterator to go through the
* events. Callers need to explicitly send the request to a trace or experiment,
* using {@link ITmfTrace#sendRequest(ITmfEventRequest)}.
*
* @author Geneviève Bastien
*/
public class ScriptEventRequest extends TmfEventRequest {

private static final int DEFAULT_EVENTS_QUEUE_SIZE = 127;
private static final int DEFAULT_EVENTS_CHUNK_SIZE = 127;

/**
* Fake event indicating the build is over, and the provider should close
*/
private static class EndEvent extends TmfEvent {
public EndEvent() {
super(null, ITmfContext.UNKNOWN_RANK, null, null, null);
}
}

private static final EndEvent END_EVENT = new EndEvent();

private final BufferedBlockingQueue<ITmfEvent> fEventsQueue;
private final EventIterator fEventIterator;

/**
* Constructor
*/
public ScriptEventRequest() {
super(ITmfEvent.class, TmfTimeRange.ETERNITY, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND, 100);
fEventsQueue = new BufferedBlockingQueue<>(DEFAULT_EVENTS_QUEUE_SIZE, DEFAULT_EVENTS_CHUNK_SIZE);
fEventIterator = new EventIterator(fEventsQueue);
}

@Override
public void handleData(@NonNull ITmfEvent event) {
super.handleData(event);
fEventsQueue.put(event);
}

@Override
public synchronized void done() {
super.done();
fEventsQueue.put(END_EVENT);
fEventsQueue.flushInputBuffer();
}

@Override
public synchronized void cancel() {
super.cancel();
fEventsQueue.put(END_EVENT);
fEventsQueue.flushInputBuffer();
}

/**
* Get the event iterator that will contain the events being read.
*
* @return The event iterator
*/
public Iterator<ITmfEvent> getEventIterator() {
return fEventIterator;
}

private static class EventIterator implements Iterator<ITmfEvent> {

private final BufferedBlockingQueue<ITmfEvent> fEventsQueue;
private @Nullable ITmfEvent fNext;

public EventIterator(BufferedBlockingQueue<ITmfEvent> eventsQueue) {
fEventsQueue = eventsQueue;
}

@Override
public synchronized boolean hasNext() {
ITmfEvent next = fNext;
if (next == null) {
next = fEventsQueue.take();
fNext = next;
}
return next != END_EVENT;
}

@Override
public synchronized ITmfEvent next() {
if (hasNext()) {
ITmfEvent next = fNext;
fNext = null;
if (next != null) {
return next;
}
}
throw new NoSuchElementException("No more elements in the queue"); //$NON-NLS-1$
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,14 @@
package org.eclipse.tracecompass.incubator.scripting.core.analysis;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.eclipse.ease.modules.ScriptParameter;
import org.eclipse.ease.modules.WrapToScript;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.collect.BufferedBlockingQueue;
import org.eclipse.tracecompass.incubator.internal.scripting.core.analysis.TmfScriptAnalysis;
import org.eclipse.tracecompass.incubator.internal.scripting.core.trace.ScriptEventRequest;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;

Expand All @@ -37,20 +30,6 @@
*/
public class ScriptedAnalysis {

private static final int DEFAULT_EVENTS_QUEUE_SIZE = 127;
private static final int DEFAULT_EVENTS_CHUNK_SIZE = 127;

/**
* Fake event indicating the build is over, and the provider should close
*/
private static class EndEvent extends TmfEvent {
public EndEvent() {
super(null, ITmfContext.UNKNOWN_RANK, null, null, null);
}
}

private static final EndEvent END_EVENT = new EndEvent();

private final ITmfTrace fTrace;
private final String fName;

Expand Down Expand Up @@ -115,73 +94,9 @@ public EndEvent() {
*/
@WrapToScript
public Iterator<ITmfEvent> getEventIterator() {
BufferedBlockingQueue<ITmfEvent> eventsQueue = new BufferedBlockingQueue<>(DEFAULT_EVENTS_QUEUE_SIZE, DEFAULT_EVENTS_CHUNK_SIZE);
fTrace.sendRequest(new ScriptEventRequest(eventsQueue));
return new EventIterator(eventsQueue);
}

private static class EventIterator implements Iterator<ITmfEvent> {

private final BufferedBlockingQueue<ITmfEvent> fEventsQueue;
private @Nullable ITmfEvent fNext;

public EventIterator(BufferedBlockingQueue<ITmfEvent> eventsQueue) {
fEventsQueue = eventsQueue;
}

@Override
public synchronized boolean hasNext() {
ITmfEvent next = fNext;
if (next == null) {
next = fEventsQueue.take();
fNext = next;
}
return next != END_EVENT;
}

@Override
public synchronized ITmfEvent next() {
if (hasNext()) {
ITmfEvent next = fNext;
fNext = null;
if (next != null) {
return next;
}
}
throw new NoSuchElementException("No more elements in the queue"); //$NON-NLS-1$
}

}

private static class ScriptEventRequest extends TmfEventRequest {

private BufferedBlockingQueue<ITmfEvent> fEventsQueue;

public ScriptEventRequest(BufferedBlockingQueue<ITmfEvent> eventsQueue) {
super(ITmfEvent.class, TmfTimeRange.ETERNITY, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND, 100);
fEventsQueue = eventsQueue;
}

@Override
public void handleData(@NonNull ITmfEvent event) {
super.handleData(event);
fEventsQueue.put(event);
}

@Override
public synchronized void done() {
super.done();
fEventsQueue.put(END_EVENT);
fEventsQueue.flushInputBuffer();
}

@Override
public synchronized void cancel() {
super.cancel();
fEventsQueue.put(END_EVENT);
fEventsQueue.flushInputBuffer();
}

ScriptEventRequest scriptEventRequest = new ScriptEventRequest();
fTrace.sendRequest(scriptEventRequest);
return scriptEventRequest.getEventIterator();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package org.eclipse.tracecompass.incubator.scripting.core.trace;

import java.io.FileNotFoundException;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

Expand All @@ -22,6 +23,7 @@
import org.eclipse.ease.modules.WrapToScript;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.incubator.internal.scripting.core.trace.Messages;
import org.eclipse.tracecompass.incubator.internal.scripting.core.trace.ScriptEventRequest;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException;
Expand Down Expand Up @@ -139,4 +141,39 @@ private static ITmfTrace openAndInitializeTrace(IFile file, String location, Str
public @Nullable ITmfTrace getActiveTrace() {
return TmfTraceManager.getInstance().getActiveTrace();
}

/**
* Get an iterator to iterate chronologically through the events of the
* trace.
*
* Thus, to iterate through the events of a trace in a scripted analysis,
* one can just do the following snippet (javascript)
*
* <pre>
* var trace = getActiveTrace();
* var iter = getEventIterator(trace);
*
* var event = null;
* while (iter.hasNext()) {
*
* event = iter.next();
*
* // Do something with the event
* }
* </pre>
*
* @param trace
* The trace for which to get the event iterator
*
* @return The event iterator, starting from the first event
*/
@WrapToScript
public Iterator<ITmfEvent> getEventIterator(@Nullable ITmfTrace trace) {
if (trace == null) {
throw new NullPointerException("Trace should not be null"); //$NON-NLS-1$
}
ScriptEventRequest scriptEventRequest = new ScriptEventRequest();
trace.sendRequest(scriptEventRequest);
return scriptEventRequest.getEventIterator();
}
}

0 comments on commit ff613fe

Please sign in to comment.