/******************************************************************************* * Copyright (c) 2012-2015 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> * Youenn Corre <youenn.corret@inria.fr> ******************************************************************************/ package fr.inria.soctrace.tools.ocelotl.microdesc.operators; 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.IState; import fr.inria.soctrace.tools.ocelotl.core.exceptions.OcelotlException; import fr.inria.soctrace.tools.ocelotl.core.timeslice.TimeSliceStateManager; import fr.inria.soctrace.tools.ocelotl.core.utils.DeltaManagerOcelotl; import fr.inria.soctrace.tools.ocelotl.microdesc.genericevents.GenericState; public class StateAverageDistribution extends StateDistribution { private static final Logger logger = LoggerFactory .getLogger(StateAverageDistribution.class); protected List<HashMap<EventProducer, HashMap<String, Integer>>> stateCounter; public StateAverageDistribution() { super(); stateCounter = new ArrayList<HashMap<EventProducer, HashMap<String, Integer>>>(); } @Override public void computeSubMatrix(final List<EventProducer> eventProducers, List<IntervalDesc> time, IProgressMonitor monitor) throws SoCTraceException, InterruptedException, OcelotlException { dm = new DeltaManagerOcelotl(); dm.start(); monitorMessageDatabaseQuery(monitor); eventIterator = ocelotlQueries.getStateIterator(eventProducers, time, monitor); if (monitor.isCanceled()) { ocelotlQueries.closeIterator(); return; } setTimeSliceManager(new TimeSliceStateManager(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(); computeAverage(); ocelotlQueries.closeIterator(); dm.end("VECTORS COMPUTATION: " + getOcelotlParameters().getTimeSlicesNumber() + " timeslices"); } /** * Compute the average duration of a state for each time slice */ private void computeAverage() { // For each time slice for (int i = 0; i < matrix.size(); i++) { // For each event producer for (final EventProducer ep : matrix.get(i).keySet()) { // For each state for (String aState : matrix.get(i).get(ep).keySet()) { if (stateCounter.get(i).get(ep).get(aState) != 0) // Divide the current value by the number of state in // the time slice matrix.get(i) .get(ep) .put(aState, matrix.get(i).get(ep).get(aState) / stateCounter.get(i).get(ep) .get(aState)); } } } } class OcelotlThread extends Thread { List<EventProducer> localActiveEventProducers; int threadNumber; int thread; int size; IProgressMonitor monitor; public OcelotlThread() { super(); } 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(); } protected void matrixUpdate(final IState state, final EventProducer ep, final Map<Long, Double> distrib) { // Mutex synchronized (getMatrix()) { // If the event type is not in the matrix yet if (!getMatrix().get(0).get(ep) .containsKey(state.getType())) { logger.debug("Adding " + state.getType() + " state"); // Add the type for each slice and ep and init to zero for (int incr = 0; incr < getMatrix().size(); incr++) for (final EventProducer epset : getMatrix().get(incr) .keySet()) { matrixPushType(incr, epset, state.getType()); stateCounter.get(incr).get(epset) .put(state.getType(), 0); } } for (final long it : distrib.keySet()) { matrixWrite(it, ep, state.getType(), distrib); stateCounter .get((int) it) .get(ep) .put(state.getType(), (stateCounter.get((int) it).get(ep) .get(state.getType())) + 1); } } } @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; IState state; // For each event for (final Event event : events) { // Convert to state state = new GenericState(event, (TimeSliceStateManager) timeSliceManager); // Get duration of the state for every time slice it is in final Map<Long, Double> distrib = state .getTimeSlicesDistribution(); EventProducer eventEP = event.getEventProducer(); if(aggregatedProducers.containsKey(event.getEventProducer())) eventEP = aggregatedProducers.get(event.getEventProducer()); matrixUpdate(state, 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); } } } } @Override public void initMatrix() throws SoCTraceException { matrix = new ArrayList<HashMap<EventProducer, HashMap<String, Double>>>(); final List<EventProducer> producers = parameters.getCurrentProducers(); for (long i = 0; i < parameters.getTimeSlicesNumber(); i++) { matrix.add(new HashMap<EventProducer, HashMap<String, Double>>()); stateCounter .add(new HashMap<EventProducer, HashMap<String, Integer>>()); for (final EventProducer ep : producers) { if (!aggregatedProducers.containsKey(ep)) { matrix.get((int) i).put(ep, new HashMap<String, Double>()); stateCounter.get((int) i).put(ep, new HashMap<String, Integer>()); } } } } }