/* =====================================================================
* Ocelotl Visualization Tool
* =====================================================================
*
* Ocelotl is a Framesoc plug in that enables to visualize a trace
* overview by using aggregation techniques
*
* (C) Copyright 2013 INRIA
*
* 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:
* Damien Dosimont <damien.dosimont@imag.fr>
* Generoso Pagano <generoso.pagano@inria.fr>
*/
package fr.inria.soctrace.tools.ocelotl.microdesc.operators;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.inria.soctrace.lib.model.Event;
import fr.inria.soctrace.lib.model.EventProducer;
import fr.inria.soctrace.lib.model.utils.SoCTraceException;
import fr.inria.soctrace.lib.search.utils.IntervalDesc;
import fr.inria.soctrace.tools.ocelotl.core.events.IVariable;
import fr.inria.soctrace.tools.ocelotl.core.exceptions.OcelotlException;
import fr.inria.soctrace.tools.ocelotl.core.microdesc.Microscopic3DDescription;
import fr.inria.soctrace.tools.ocelotl.core.timeslice.TimeSliceVariableManager;
import fr.inria.soctrace.tools.ocelotl.core.utils.DeltaManagerOcelotl;
import fr.inria.soctrace.tools.ocelotl.microdesc.genericevents.GenericVariable;
public class VariableDistribution extends Microscopic3DDescription {
private static final Logger logger = LoggerFactory
.getLogger(VariableDistribution.class);
class OcelotlThread extends Thread {
List<EventProducer> localActiveEventProducers;
int threadNumber;
int thread;
int size;
IProgressMonitor monitor;
public OcelotlThread(final int threadNumber, final int thread,
final int size, IProgressMonitor monitor) {
super();
this.threadNumber = threadNumber;
this.thread = thread;
this.size = size;
this.monitor = monitor;
localActiveEventProducers = new ArrayList<EventProducer>();
start();
}
private void matrixUpdate(final IVariable variable,
final EventProducer ep, final Map<Long, Double> distrib) {
// Mutex
synchronized (getMatrix()) {
if (!getMatrix().get(0).get(ep).containsKey(variable.getType())) {
logger.debug("Adding " + variable.getType() + " variable");
for (int incr = 0; incr < getMatrix().size(); incr++)
for (final EventProducer epset : getMatrix().get(incr)
.keySet())
matrixPushType(incr, epset, variable.getType());
}
for (final long it : distrib.keySet())
matrixWrite(it, ep, variable.getType(), distrib);
}
}
@Override
public void run() {
EventProducer currentEP = null;
while (true) {
final List<Event> events = getEvents(size, monitor);
if (events.size() == 0)
break;
if (monitor.isCanceled())
return;
IVariable variable;
for (final Event event : events) {
variable = new GenericVariable(event,
(TimeSliceVariableManager) timeSliceManager);
final Map<Long, Double> distrib = variable
.getTimeSlicesDistribution();
EventProducer eventEP = event.getEventProducer();
if(aggregatedProducers.containsKey(event.getEventProducer()))
eventEP = aggregatedProducers.get(event.getEventProducer());
matrixUpdate(variable, eventEP, distrib);
if (currentEP != eventEP) {
currentEP = eventEP;
// If the event producer is not in the active producers
// list
if (!localActiveEventProducers.contains(eventEP)) {
// Add it
localActiveEventProducers.add(eventEP);
}
}
if (monitor.isCanceled())
return;
}
monitor.worked(events.size());
}
// Merge local active event producers to the global one
synchronized (activeProducers) {
for (EventProducer ep : localActiveEventProducers) {
if (!activeProducers.contains(ep))
activeProducers.add(ep);
}
}
}
}
public VariableDistribution() {
super();
}
@Override
public void computeSubMatrix(List<EventProducer> eventProducers,
List<IntervalDesc> time, IProgressMonitor monitor)
throws SoCTraceException, InterruptedException, OcelotlException {
dm = new DeltaManagerOcelotl();
dm.start();
monitorMessageDatabaseQuery(monitor);
eventIterator = ocelotlQueries.getVariableIterator(eventProducers,
time, monitor);
if (monitor.isCanceled()) {
ocelotlQueries.closeIterator();
return;
}
setTimeSliceManager(new TimeSliceVariableManager(getOcelotlParameters()
.getTimeRegion(), getOcelotlParameters().getTimeSlicesNumber()));
final List<OcelotlThread> threadlist = new ArrayList<OcelotlThread>();
monitorMessageDatabaseQuery(monitor);
for (int t = 0; t < getOcelotlParameters().getNumberOfThreads(); t++)
threadlist.add(new OcelotlThread(getOcelotlParameters()
.getNumberOfThreads(), t, getOcelotlParameters()
.getEventsPerThread(), monitor));
for (final Thread thread : threadlist)
thread.join();
ocelotlQueries.closeIterator();
dm.end("VECTORS COMPUTATION: "
+ getOcelotlParameters().getTimeSlicesNumber() + " timeslices");
}
@Override
public void rebuildMatrix(String[] values, EventProducer ep,
int sliceMultiple) {
String evType = values[2];
// If the event type is filtered out
if (!typeNames.contains(evType))
return;
EventProducer eventEP = ep;
if(aggregatedProducers.containsKey(ep))
eventEP = aggregatedProducers.get(ep);
// If the event producer is flag as inactive
if (!getActiveProducers().contains(eventEP)) {
// Remove it
getActiveProducers().add(eventEP);
}
int slice = Integer.parseInt(values[0]);
double value = Double.parseDouble(values[3]);
// If the number of time slice is a multiple of the cached time
// slice number
if (sliceMultiple > 1) {
// Compute the correct slice number
slice = slice / sliceMultiple;
// And add the value to the one already in the matrix
if (matrix.get(slice).get(eventEP).get(evType) != null)
value = matrix.get(slice).get(eventEP).get(evType) + (value / sliceMultiple);
}
matrix.get(slice).get(eventEP).put(evType, value);
}
@Override
public void rebuildMatrixFromDirtyCache(String[] values, EventProducer ep,
int slice, double factor) {
String evType = values[2];
// If the event type is filtered out
if (!typeNames.contains(evType))
return;
EventProducer eventEP = ep;
if(aggregatedProducers.containsKey(ep))
eventEP = aggregatedProducers.get(ep);
// If the event producer is flag as inactive
if (!getActiveProducers().contains(eventEP)) {
// Remove it
getActiveProducers().add(eventEP);
}
// Compute a value proportional to the time ratio spent in the slice
double value = Double.parseDouble(values[3]) * factor;
// Add the value to the one potentially already in the matrix
if (matrix.get(slice).get(eventEP).get(evType) != null)
value = matrix.get(slice).get(eventEP).get(evType) + value / parameters.getTimeSliceFactor();
matrix.get(slice).get(eventEP).put(evType, value);
}
@Override
public void rebuildDirty(File aCacheFile,
HashMap<String, EventProducer> eventProducers,
IProgressMonitor monitor) throws SoCTraceException,
InterruptedException, OcelotlException {
buildNormalMatrix(monitor);
}
}