co.turnus.analysis.bottlenecks.util.HotspotsDataAnalyser.java Source code

Java tutorial

Introduction

Here is the source code for co.turnus.analysis.bottlenecks.util.HotspotsDataAnalyser.java

Source

/* 
 * TURNUS, the co-exploration framework
 * 
 * Copyright (C) 2014 EPFL SCI STI MM
 *
 * This file is part of TURNUS.
 *
 * TURNUS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * TURNUS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with TURNUS.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Additional permission under GNU GPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or combining it
 * with Eclipse (or a modified version of Eclipse or an Eclipse plugin or 
 * an Eclipse library), containing parts covered by the terms of the 
 * Eclipse Public License (EPL), the licensors of this Program grant you 
 * additional permission to convey the resulting work.  Corresponding Source 
 * for a non-source form of such a combination shall include the source code 
 * for the parts of Eclipse libraries used as well as that of the  covered work.
 * 
 */
package co.turnus.analysis.bottlenecks.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections.map.LinkedMap;

import co.turnus.analysis.data.bottlenecks.ActionHotspotsData;
import co.turnus.analysis.data.bottlenecks.AlgoBottlenecksData;
import co.turnus.analysis.data.bottlenecks.ExecData;
import co.turnus.analysis.data.bottlenecks.ExtendExecData;
import co.turnus.analysis.data.bottlenecks.HotspotsData;
import co.turnus.analysis.data.util.DataUtil;
import co.turnus.dataflow.Action;
import co.turnus.dataflow.Actor;
import co.turnus.dataflow.ActorClass;
import co.turnus.dataflow.Network;
import co.turnus.dataflow.util.DataflowComparators;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;

public class HotspotsDataAnalyser {

    private class ActionDataComparator implements Comparator<ActionHotspotsData> {

        private Key key;
        private Order order;
        private ExecDataComparator subComparator = new ExecDataComparator();

        @Override
        public int compare(ActionHotspotsData o1, ActionHotspotsData o2) {
            if (o1 == null && o2 == null) {
                return 0;
            } else if (o1 == null) {
                return 1;
            } else if (o2 == null) {
                return -1;
            }
            switch (key) {
            case ALPHABETICAL: {
                int val = DataflowComparators.action(false).compare(o1.getAction(), o2.getAction());
                return order == Order.INCREASING ? val : -val;
            }
            case TOTAL_EXECUTIONS:
            case TOTAL_VARIANCE:
            case TOTAL_CLOCKCYCLES: {
                ExecData d1 = o1.getTotalExec();
                ExecData d2 = o2.getTotalExec();
                return subComparator.compare(d1, d2);
            }
            case NOTDEFERRABLE_EXECUTIONS:
            case NOTDEFERRABLE_VARIANCE:
            case NOTDEFERRABLE_CLOCKCYCLES: {
                ExecData d1 = o1.getNotDeferrableExec();
                ExecData d2 = o2.getNotDeferrableExec();
                return subComparator.compare(d1, d2);
            }
            case CRITICAL_EXECUTIONS:
            case CRITICAL_VARIANCE:
            case CRITICAL_CLOCKCYCLES: {
                ExecData d1 = o1.getCriticalExec();
                ExecData d2 = o2.getCriticalExec();
                return subComparator.compare(d1, d2);
            }
            default:
                return 0;
            }
        }

        private void setDirection(Key key, Order order) {
            this.key = key;
            this.order = order;
            subComparator.setSorting(key, order);
        }

    }

    private class ExecDataComparator implements Comparator<ExecData> {
        private Key key;
        private Order order;

        @Override
        public int compare(ExecData o1, ExecData o2) {
            if (o1 == null && o2 == null) {
                return 0;
            } else if (o1 == null) {
                return 1;
            } else if (o2 == null) {
                return -1;
            }
            switch (key) {
            case TOTAL_EXECUTIONS:
            case CRITICAL_EXECUTIONS:
            case NOTDEFERRABLE_EXECUTIONS: {
                long d1 = o1.getExecutions();
                long d2 = o2.getExecutions();
                int val = Long.compare(d1, d2);
                return order == Order.INCREASING ? val : -val;
            }
            case TOTAL_VARIANCE:
            case NOTDEFERRABLE_VARIANCE:
            case CRITICAL_VARIANCE: {
                double d1 = o1.getClockCyclesVariance();
                double d2 = o2.getClockCyclesVariance();
                int val = Double.compare(d1, d2);
                return order == Order.INCREASING ? val : -val;
            }
            case TOTAL_CLOCKCYCLES:
            case NOTDEFERRABLE_CLOCKCYCLES:
            case CRITICAL_CLOCKCYCLES: {
                double d1 = o1.getClockCyclesMean();
                double d2 = o2.getClockCyclesMean();
                int val = Double.compare(d1, d2);
                return order == Order.INCREASING ? val : -val;
            }
            default:
                return 0;
            }
        }

        private void setSorting(Key key, Order order) {
            this.key = key;
            this.order = order;
        }

    }

    private class ExecDataMapComparator implements Comparator<Map.Entry<?, ExtendExecData>> {

        private Key key;
        private Order order;
        private ExecDataComparator subComparator = new ExecDataComparator();

        @Override
        public int compare(Entry<?, ExtendExecData> o1, Entry<?, ExtendExecData> o2) {
            if (o1 == null && o2 == null) {
                return 0;
            } else if (o1 == null) {
                return 1;
            } else if (o2 == null) {
                return -1;
            }

            switch (key) {
            case ALPHABETICAL: {
                int val = 0;
                if (o1.getKey() instanceof Actor) {
                    val = DataflowComparators.actor(false).compare((Actor) o1.getKey(), (Actor) o2.getKey());
                } else if (o1.getKey() instanceof ActorClass) {
                    val = DataflowComparators.actorClass(false).compare((ActorClass) o1.getKey(),
                            (ActorClass) o2.getKey());
                } else if (o1.getKey() instanceof Action) {
                    val = DataflowComparators.action(false).compare((Action) o1.getKey(), (Action) o2.getKey());
                } else {
                    return val;
                }

                return order == Order.INCREASING ? val : -val;
            }
            case TOTAL_EXECUTIONS:
            case TOTAL_VARIANCE:
            case TOTAL_CLOCKCYCLES: {
                ExecData d1 = o1.getValue().getTotalExec();
                ExecData d2 = o2.getValue().getTotalExec();
                return subComparator.compare(d1, d2);

            }
            case NOTDEFERRABLE_EXECUTIONS:
            case NOTDEFERRABLE_VARIANCE:
            case NOTDEFERRABLE_CLOCKCYCLES: {
                ExecData d1 = o1.getValue().getNotDeferrableExec();
                ExecData d2 = o2.getValue().getNotDeferrableExec();
                return subComparator.compare(d1, d2);
            }
            case CRITICAL_EXECUTIONS:
            case CRITICAL_VARIANCE:
            case CRITICAL_CLOCKCYCLES: {
                ExecData d1 = o1.getValue().getCriticalExec();
                ExecData d2 = o2.getValue().getCriticalExec();
                return subComparator.compare(d1, d2);
            }
            default:
                return 0;
            }
        }

        private void setSorting(Key key, Order order) {
            subComparator.setSorting(key, order);
            this.key = key;
            this.order = order;
        }
    }

    private class ExecDataTableComparator extends Ordering<Table.Cell<?, Action, ExtendExecData>> {

        private Key key;
        private Order order;
        private ExecDataComparator subComparator = new ExecDataComparator();

        @Override
        public int compare(Cell<?, Action, ExtendExecData> o1, Cell<?, Action, ExtendExecData> o2) {

            if (o1 == null && o2 == null) {
                return 0;
            } else if (o1 == null) {
                return 1;
            } else if (o2 == null) {
                return -1;
            }
            switch (key) {
            case ALPHABETICAL: {
                int val = 0;
                if (o1.getRowKey() instanceof Actor) {
                    val = DataflowComparators.actor(false).compare((Actor) o1.getRowKey(), (Actor) o2.getRowKey());
                } else if (o1.getRowKey() instanceof ActorClass) {
                    val = DataflowComparators.actorClass(false).compare((ActorClass) o1.getRowKey(),
                            (ActorClass) o2.getRowKey());
                } else {
                    return val;
                }
                return order == Order.INCREASING ? val : -val;
            }
            case TOTAL_EXECUTIONS:
            case TOTAL_VARIANCE:
            case TOTAL_CLOCKCYCLES: {
                ExecData d1 = o1.getValue().getTotalExec();
                ExecData d2 = o2.getValue().getTotalExec();
                return subComparator.compare(d1, d2);

            }
            case NOTDEFERRABLE_EXECUTIONS:
            case NOTDEFERRABLE_VARIANCE:
            case NOTDEFERRABLE_CLOCKCYCLES: {
                ExecData d1 = o1.getValue().getNotDeferrableExec();
                ExecData d2 = o2.getValue().getNotDeferrableExec();
                return subComparator.compare(d1, d2);
            }
            case CRITICAL_EXECUTIONS:
            case CRITICAL_VARIANCE:
            case CRITICAL_CLOCKCYCLES: {
                ExecData d1 = o1.getValue().getCriticalExec();
                ExecData d2 = o2.getValue().getCriticalExec();
                return subComparator.compare(d1, d2);
            }
            default:
                return 0;
            }
        }

        private void setSorting(Key key, Order order) {
            subComparator.setSorting(key, order);
            this.key = key;
            this.order = order;
        }

    }

    public enum Key {
        /** */
        ALPHABETICAL,
        /** */
        TOTAL_EXECUTIONS,
        /** */
        TOTAL_CLOCKCYCLES,
        /** */
        TOTAL_VARIANCE,
        /** */
        NOTDEFERRABLE_EXECUTIONS,
        /** */
        NOTDEFERRABLE_CLOCKCYCLES,
        /** */
        NOTDEFERRABLE_VARIANCE,
        /** */
        CRITICAL_EXECUTIONS,
        /** */
        CRITICAL_CLOCKCYCLES,
        /** */
        CRITICAL_VARIANCE;
    }

    public enum Order {
        /** */
        DECREASING,
        /** */
        INCREASING;
    }

    private HotspotsData data;
    private Network network;
    private ActionDataComparator listComparator;
    private ExecDataTableComparator tableComparator;
    private ExecDataMapComparator mapComparator;

    public HotspotsDataAnalyser(AlgoBottlenecksData data) {
        this.data = data.getHotspotsData();
        this.network = data.getNetwork();
        listComparator = new ActionDataComparator();
        tableComparator = new ExecDataTableComparator();
        mapComparator = new ExecDataMapComparator();
    }

    public ActionHotspotsData getData(Actor actor, Action action) {
        for (ActionHotspotsData aData : data.getActionsData()) {
            if (aData.getActor().equals(actor) && aData.getAction().equals(action))
                return aData;
        }
        return null;
    }

    public List<ActionHotspotsData> getSortedData(Action action, Key key, Order order) {
        ArrayList<ActionHotspotsData> list = new ArrayList<>();
        for (ActionHotspotsData aData : data.getActionsData()) {
            if (aData.getAction().equals(action))
                list.add(aData);
        }
        sortList(list, key, order);
        return list;
    }

    public List<ActionHotspotsData> getSortedData(Actor actor, Key key, Order order) {
        ArrayList<ActionHotspotsData> list = new ArrayList<>();
        for (ActionHotspotsData aData : data.getActionsData()) {
            if (aData.getActor().equals(actor))
                list.add(aData);
        }
        sortList(list, key, order);
        return list;
    }

    public List<ActionHotspotsData> getSortedData(ActorClass actorClass, Key key, Order order) {
        ArrayList<ActionHotspotsData> list = new ArrayList<>();
        for (ActionHotspotsData aData : data.getActionsData()) {
            if (aData.getActor().getActorClass().equals(actorClass))
                list.add(aData);
        }
        sortList(list, key, order);
        return list;
    }

    public List<ActionHotspotsData> getSortedData(Key key, Order order) {
        ArrayList<ActionHotspotsData> list = new ArrayList<>(data.getActionsData());
        sortList(list, key, order);
        return list;
    }

    public ExtendExecData getSumData() {
        List<ActionHotspotsData> list = data.getActionsData();
        return DataUtil.sum(list.toArray(new ExtendExecData[list.size()]));
    }

    public ExtendExecData getSumData(Action action) {
        List<ActionHotspotsData> list = new ArrayList<ActionHotspotsData>();
        for (ActionHotspotsData actionData : data.getActionsData()) {
            if (actionData.getAction().equals(action)) {
                list.add(actionData);
            }
        }
        return DataUtil.sum(list.toArray(new ExtendExecData[list.size()]));
    }

    public ExtendExecData getSumData(Actor actor) {
        List<ActionHotspotsData> list = new ArrayList<ActionHotspotsData>();
        for (ActionHotspotsData actionData : data.getActionsData()) {
            if (actionData.getActor().equals(actor)) {
                list.add(actionData);
            }
        }
        return DataUtil.sum(list.toArray(new ExtendExecData[list.size()]));
    }

    public ExtendExecData getSumData(ActorClass actorClass) {
        List<ActionHotspotsData> list = new ArrayList<ActionHotspotsData>();
        for (ActionHotspotsData actionData : data.getActionsData()) {
            if (actionData.getActor().getActorClass().equals(actorClass)) {
                list.add(actionData);
            }
        }
        return DataUtil.sum(list.toArray(new ExtendExecData[list.size()]));
    }

    @SuppressWarnings("unchecked")
    public <T> Map<T, ExtendExecData> getSumDataMap(Class<T> type, Key key, Order order) {
        Map<T, ExtendExecData> tmpMap = Maps.newHashMap();
        List<Map.Entry<T, ExtendExecData>> list = new ArrayList<>();

        if (type.isAssignableFrom(Actor.class)) {
            for (Actor actor : network.getActors()) {
                tmpMap.put((T) actor, getSumData(actor));
            }
            list.addAll(tmpMap.entrySet());
        } else if (type.isAssignableFrom(ActorClass.class)) {
            for (ActorClass clazz : network.getActorClasses()) {
                tmpMap.put((T) clazz, getSumData(clazz));
            }
            list.addAll(tmpMap.entrySet());
        } else if (type.isAssignableFrom(Action.class)) {
            Collection<Action> actions = Sets.newHashSet();
            for (ActorClass clazz : network.getActorClasses()) {
                actions.addAll(clazz.getActions());
            }
            for (Action action : actions) {
                tmpMap.put((T) action, getSumData(action));
            }
            list.addAll(tmpMap.entrySet());
        } else {
            return null;
        }

        mapComparator.setSorting(key, order);
        Collections.sort(list, mapComparator);

        Map<T, ExtendExecData> data = new LinkedMap();
        for (Entry<T, ExtendExecData> entry : list) {
            data.put(entry.getKey(), entry.getValue());
        }
        return data;
    }

    @SuppressWarnings("unchecked")
    public <T> Table<T, Action, ExtendExecData> getSumDataTable(Class<T> type, Key key, Order order) {
        if (type.isAssignableFrom(Actor.class)) {
            // create a temporary table
            Table<Actor, Action, ExtendExecData> table = HashBasedTable.create();
            for (ActionHotspotsData aData : data.getActionsData()) {
                table.put(aData.getActor(), aData.getAction(), aData);
            }

            // sort the table
            tableComparator.setSorting(key, order);
            ImmutableTable.Builder<Actor, Action, ExtendExecData> sortedBuilder = ImmutableTable.builder(); // preserves insertion order
            for (Table.Cell<Actor, Action, ExtendExecData> cell : tableComparator.sortedCopy(table.cellSet())) {
                sortedBuilder.put(cell);
            }

            // return a sorted table
            return (Table<T, Action, ExtendExecData>) sortedBuilder.build();

        } else if (type.isAssignableFrom(ActorClass.class)) {
            // create a temporary table
            Table<ActorClass, Action, ExtendExecData> table = HashBasedTable.create();
            for (ActionHotspotsData aData : data.getActionsData()) {
                ActorClass clazz = aData.getActor().getActorClass();
                Action action = aData.getAction();
                ExtendExecData actionData = table.get(clazz, action);
                if (actionData == null) {
                    actionData = aData;
                    table.put(clazz, action, actionData);
                } else {
                    DataUtil.merge(actionData, aData);
                }

            }

            // sort the table
            tableComparator.setSorting(key, order);
            ImmutableTable.Builder<ActorClass, Action, ExtendExecData> sortedBuilder = ImmutableTable.builder(); // preserves insertion order
            for (Table.Cell<ActorClass, Action, ExtendExecData> cell : tableComparator
                    .sortedCopy(table.cellSet())) {
                sortedBuilder.put(cell);
            }

            // return a sorted table
            return (Table<T, Action, ExtendExecData>) sortedBuilder.build();
        }
        return null;
    }

    private void sortList(ArrayList<ActionHotspotsData> list, Key key, Order order) {
        listComparator.setDirection(key, order);
        Collections.sort(list, listComparator);
    }
}