Package org.apache.hadoop.chukwa.analysis.salsa.visualization

Source Code of org.apache.hadoop.chukwa.analysis.salsa.visualization.Heatmap$HeatmapData

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.chukwa.analysis.salsa.visualization;

import prefuse.data.io.sql.*;
import prefuse.data.Table;
import prefuse.data.expression.parser.*;
import prefuse.data.expression.*;
import prefuse.data.column.*;
import prefuse.data.query.*;
import prefuse.data.*;
import prefuse.action.*;
import prefuse.action.layout.*;
import prefuse.action.assignment.*;
import prefuse.visual.expression.*;
import prefuse.visual.*;
import prefuse.render.*;
import prefuse.util.*;
import prefuse.*;

import org.apache.hadoop.chukwa.hicc.OfflineTimeHandler;
import org.apache.hadoop.chukwa.hicc.TimeHandler;
import org.apache.hadoop.chukwa.util.DatabaseWriter;
import org.apache.hadoop.chukwa.database.Macro;
import org.apache.hadoop.chukwa.util.XssFilter;

import javax.servlet.http.*;
import javax.swing.BorderFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.sql.*;
import java.util.*;
import java.text.NumberFormat;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.awt.Font;
import java.awt.geom.Rectangle2D;
import java.awt.Color;

/**
* Static image rendering for heatmap visualization of spatial HDFS
* activity patterns for scalable rendering on front-end (web-browser)
* Handles database data retrieval, transforming data to form for
* visualization elements, and initializing and calling visualization
* elements
*/
public class Heatmap {

  /**
   * Internal representation of all data needed to render heatmap;
   * data-handling code populates this data structure
   */
  protected static class HeatmapData {
    public Table agg_tab;
    public long [][] stats;
    public long min;
    public long max;
    public int num_hosts;
    public String [] hostnames;
    public HeatmapData() {
    }
  }

  private static Log log = LogFactory.getLog(Heatmap.class);

  static final String START_FIELD_NAME = "start_time_num";
  static final String END_FIELD_NAME = "finish_time_num";

  int BOXWIDTH = 250;
  int SIZE_X = 1600, SIZE_Y=1600;
  final int [] BORDER = {200,150,150,150};
  final int LEGEND_X_OFFSET = 10;
  final int LEGEND_Y_OFFSET = 0;
  final int LEGEND_TEXT_OFFSET = 10;
  final int LEGEND_FONT_SIZE = 24;
  final int AXIS_NAME_FONT_SIZE = 24;

  protected boolean offline_use = true;
  protected HttpServletRequest request;

  // for offline use only
  // keys that need to be filled:
  // period (last1/2/3/6/12/24hr,last7d,last30d), time_type (range/last), start, end
  protected HashMap<String, String> param_map;
 
  protected String cluster;
  protected String timezone;
  protected String query_state;
  protected String query_stat_type;
  protected final String table = new String("filesystem_fsm");
  protected boolean plot_legend = false; // controls whether to plot hostnames
  protected boolean sort_nodes = true;
  protected boolean plot_additional_info = true;
  protected String add_info_extra = null;
 
  protected Display dis;
  protected Visualization viz;
 
  protected Rectangle2D dataBound = new Rectangle2D.Double();
  protected Rectangle2D xlabBound = new Rectangle2D.Double();
  protected Rectangle2D ylabBound = new Rectangle2D.Double();
  protected Rectangle2D labelBottomBound = new Rectangle2D.Double();
 
  protected HashMap<String, String> prettyStateNames;
 
  /* Different group names allow control of what Renderers to use */
  final String maingroup = "Data";
  final String othergroup = "Misc";
  final String labelgroup = "Label";
  final String legendgroup = "Legend";
  final String legendshapegroup = "LegendShape";
  final String addinfogroup = "AddInfo";
  final String addinfoshapegroup = "AddInfoShape";
 
  public Heatmap() {
    this.cluster = new String("");
    this.timezone = new String("");
    this.query_state = new String("");
    this.query_stat_type = new String("");
    param_map = new HashMap<String, String>();   
  }
 
  /**
   * @brief Constructor for Swimlanes visualization object
   * @param timezone Timezone string from environment
   * @param cluster Cluster name from environment
   * @param event_type Whether to display shuffles or not
   * @param valmap HashMap of key/value pairs simulating parameters from a HttpRequest
   */
  public Heatmap
    (String timezone, String cluster, String event_type,
     String query_stat_type,
     HashMap<String, String> valmap)
  {
    this.cluster = new String(cluster);
    if (timezone != null) {
      this.timezone = new String(timezone);
    } else {
      this.timezone = null;
    }   
    this.query_state = new String(event_type);
    this.query_stat_type = new String(query_stat_type);

    /* This should "simulate" an HttpServletRequest
     * Need to have "start" and "end" in seconds since Epoch
     */
    this.param_map = valmap;
  }
 
  public Heatmap
    (String timezone, String cluster, String query_state,
     String query_stat_type,
     HashMap<String, String> valmap, String shuffles)
  {
   
    this.cluster = new String(cluster);
    if (timezone != null) {
      this.timezone = new String(timezone);
    } else {
      this.timezone = null;
    }
    this.query_state = new String(query_state);
    this.query_stat_type = new String(query_stat_type);

    /* This should "simulate" an HttpServletRequest
     * Need to have "start" and "end" in seconds since Epoch
     */
    this.param_map = valmap;
   
  }
 
  public Heatmap
    (String timezone, String cluster, String query_state,
     String query_stat_type,
     HashMap<String, String> valmap,
     int w, int h)
  {
   
    this.cluster = new String(cluster);
    if (timezone != null) {
      this.timezone = new String(timezone);
    } else {
      this.timezone = null;
    }
    this.query_state = new String(query_state);
    this.query_stat_type = new String(query_stat_type);

    /* This should "simulate" an HttpServletRequest
     * Need to have "start" and "end" in seconds since Epoch
     */
    this.param_map = valmap;
       
    this.SIZE_X = w;
    this.SIZE_Y = h;
  }
 
  public Heatmap(HttpServletRequest request) {
    XssFilter xf = new XssFilter(request);
    this.offline_use = false;
    this.request = request;
    HttpSession session = request.getSession();
    this.cluster = session.getAttribute("cluster").toString();
    String query_state = xf.getParameter("query_state");
    if (query_state != null) {
      this.query_state = new String(query_state);
    } else {
      this.query_state = new String("read");
    }
    String query_stat_type = xf.getParameter("query_stat_type");
    if (query_stat_type != null) {
      this.query_stat_type = new String(query_stat_type);
    } else {
      this.query_stat_type = new String("transaction_count");
    }
    this.timezone = session.getAttribute("time_zone").toString();
  }

  /**
   * Set dimensions of image to be generated
   * Call before calling @see #run
   */
  public void setDimensions(int width, int height) {
    this.SIZE_X=width;
    this.SIZE_Y=height;
  }
 
  /**
   * Specify whether to print labels of hosts along axes
   * Call before calling @see #run
   */
  public void setLegend(boolean legendopt) {
    if (legendopt) {
      this.plot_legend = true;
    } else {
      this.plot_legend = false;
    }
  }
 
 
  /**
   * Generates image in specified format, and writes image as binary
   * output to supplied output stream
   */
  public boolean getImage(java.io.OutputStream output, String img_fmt, double scale) {
    dis = new Display(this.viz);
    dis.setSize(SIZE_X,SIZE_Y);
    dis.setHighQuality(true);
    dis.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,24));
    return dis.saveImage(output, img_fmt, scale);
  }
 
  protected void setupRenderer() {
    this.viz.setRendererFactory(new RendererFactory(){
      AbstractShapeRenderer sr = new ShapeRenderer();
      ShapeRenderer sr_big = new ShapeRenderer(BOXWIDTH);
      Renderer arY = new AxisRenderer(Constants.LEFT, Constants.TOP);
      Renderer arX = new AxisRenderer(Constants.CENTER, Constants.BOTTOM);
      PolygonRenderer pr = new PolygonRenderer(Constants.POLY_TYPE_LINE);
      LabelRenderer lr = new LabelRenderer("label");
      LabelRenderer lr_legend = new LabelRenderer("label");
           
      public Renderer getRenderer(VisualItem item) {
        lr_legend.setHorizontalAlignment(Constants.LEFT);
        lr_legend.setVerticalAlignment(Constants.CENTER);
        lr.setHorizontalAlignment(Constants.CENTER);
        lr.setVerticalAlignment(Constants.CENTER);
        if (item.isInGroup(maingroup)) {
          return sr_big;
        } else if (item.isInGroup(legendgroup)) {
          return lr_legend;
        } else if (item.isInGroup(addinfogroup)) {
          return lr;
        }
        return sr;
      }
    });
  }
 
  // setup columns: add additional time fields
  protected HeatmapData setupDataTable() {
    HeatmapData hd = this.getData();   
    return hd;
  }
 
  protected void setupHeatmap(VisualTable vtab, HeatmapData hd)
  {
    long [][] stats = hd.stats;
    int i, j, curr_idx;
    long curr_val;
    int num_hosts = hd.num_hosts;
    ColorMap cm = new ColorMap(
      ColorLib.getInterpolatedPalette(
        ColorLib.color(ColorLib.getColor(32,0,0)),
        ColorLib.color(Color.WHITE)
      ),
      (double)hd.min,(double)hd.max
    );
   
    for (i = 0; i < num_hosts; i++) {
      for (j = 0; j < num_hosts; j++) {
        curr_idx = j+(i*num_hosts);
        curr_val = stats[i][j];
        if (curr_val >= hd.min) {
          vtab.setFillColor(curr_idx, cm.getColor((double)curr_val));
        } else if (curr_val == 0) {
          vtab.setFillColor(curr_idx, ColorLib.color(Color.BLACK));
        }
      }
    }
   
    // gridlayout puts tiles on row-wise (row1, followed by row2, etc.)
    GridLayout gl = new GridLayout(maingroup, num_hosts, num_hosts);
    gl.setLayoutBounds(this.dataBound);
    ActionList gl_list = new ActionList();
    gl_list.add(gl);
    this.viz.putAction("gridlayout",gl_list);
    this.viz.run("gridlayout");
  }
 
  protected void addHostLabels(HeatmapData hd) {
    Table legend_labels_table = new Table();
    legend_labels_table.addColumn("label",String.class);
    legend_labels_table.addRows(hd.hostnames.length);
    for (int i = 0; i < hd.hostnames.length; i++) {
      legend_labels_table.setString(i,"label",hd.hostnames[i]);
    }
    float start_x = LEGEND_X_OFFSET;
    float start_y = LEGEND_Y_OFFSET + BORDER[1] + (BOXWIDTH/2);   
    float incr = this.BOXWIDTH;
    VisualTable legend_labels_table_viz = this.viz.addTable(legendgroup, legend_labels_table);
    for (int i = 0; i < hd.hostnames.length; i++) {
      legend_labels_table_viz.setFloat(i, VisualItem.X, start_x + LEGEND_TEXT_OFFSET);
      legend_labels_table_viz.setFloat(i, VisualItem.Y, start_y + (i * incr));
      legend_labels_table_viz.setTextColor(i,ColorLib.color(java.awt.Color.BLACK));
      legend_labels_table_viz.setFont(i,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));
    }
  }
 
  protected void addAddlInfo(HeatmapData hd) {
    Table legend_labels_table = new Table();
    legend_labels_table.addColumn("label",String.class);
    legend_labels_table.addRows(3);
   
    String hostnumstring = "Number of hosts: " + hd.num_hosts;
    if (sort_nodes) {
      hostnumstring += " (nodes sorted)";
    } else {
      hostnumstring += " (nodes not sorted)";
    }
    if (add_info_extra != null) hostnumstring += add_info_extra;
    legend_labels_table.setString(0,"label",hostnumstring);
    legend_labels_table.setString(1,"label","Src. Hosts");
    legend_labels_table.setString(2,"label","Dest. Hosts");
   
    float start_x = LEGEND_X_OFFSET;
    float start_y = LEGEND_Y_OFFSET + BORDER[1] + (BOXWIDTH/2);   
    float incr = this.BOXWIDTH;
    VisualTable legend_labels_table_viz = this.viz.addTable(addinfogroup, legend_labels_table);

    legend_labels_table_viz.setFloat(0, VisualItem.X, this.SIZE_X/2);
    legend_labels_table_viz.setFloat(0, VisualItem.Y, BORDER[1]/2);
    legend_labels_table_viz.setTextColor(0,ColorLib.color(java.awt.Color.BLACK));
    legend_labels_table_viz.setFont(0,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));

    legend_labels_table_viz.setFloat(1, VisualItem.X, this.SIZE_X/2);
    legend_labels_table_viz.setFloat(1, VisualItem.Y, BORDER[1] + (BOXWIDTH*hd.num_hosts) + BORDER[3]/2);
    legend_labels_table_viz.setTextColor(1,ColorLib.color(java.awt.Color.BLACK));
    legend_labels_table_viz.setFont(1,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));

    legend_labels_table_viz.setFloat(2, VisualItem.X, BORDER[0] + (BOXWIDTH*hd.num_hosts) + BORDER[2]/2);
    legend_labels_table_viz.setFloat(2, VisualItem.Y, this.SIZE_Y/2);
    legend_labels_table_viz.setTextColor(2,ColorLib.color(java.awt.Color.BLACK));
    legend_labels_table_viz.setFont(2,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));

  }
 
  protected void initPrettyNames() {
    this.prettyStateNames = new HashMap<String, String>();

    prettyStateNames.put("read","Block Reads");
    prettyStateNames.put("write","Block Writes");
    prettyStateNames.put("read_local", "Local Block Reads");
    prettyStateNames.put("write_local", "Local Block Writes");
    prettyStateNames.put("read_remote", "Remote Block Reads");
    prettyStateNames.put("write_remote", "Remote Block Writes");
    prettyStateNames.put("write_replicated", "Replicated Block Writes");   
  }
 
  /**
   * Actual code that calls data, generates heatmap, and saves it
   */
  public void run() {
    initPrettyNames();
   
    // setup visualization
    this.viz = new Visualization();
   
    // add table to visualization
    HeatmapData hd = this.setupDataTable();

    // setup bounds
    int width, realwidth;
    if (SIZE_X-BORDER[0]-BORDER[2] < SIZE_Y-BORDER[1]-BORDER[3]) {
      BOXWIDTH = (SIZE_X-BORDER[0]-BORDER[2]) / hd.num_hosts;
    } else {
      BOXWIDTH = (SIZE_Y-BORDER[1]-BORDER[3]) / hd.num_hosts;
    }
    width = hd.num_hosts * BOXWIDTH;
    this.dataBound.setRect(
      BORDER[0]+BOXWIDTH/2,
      BORDER[1]+BOXWIDTH/2,
      width-BOXWIDTH,width-BOXWIDTH
    );
    this.SIZE_X = BORDER[0] + BORDER[2] + (hd.num_hosts * BOXWIDTH);
    this.SIZE_Y = BORDER[1] + BORDER[3] + (hd.num_hosts * BOXWIDTH);
   
    log.debug("width total: " + width + " width per state: " + BOXWIDTH + " xstart: "
      + (BORDER[0]+BOXWIDTH/2)
      + " ystart: " + (BORDER[1]+BOXWIDTH/2) + " (num hosts: "+hd.num_hosts+")");
    log.debug("X size: " + this.SIZE_X + " Y size: " + this.SIZE_Y);
   
    this.setupRenderer();
    VisualTable data_tab_viz = viz.addTable(maingroup, hd.agg_tab);
    setupHeatmap(data_tab_viz, hd);
   
    ShapeAction legend_sa1 = null, legend_sa2 = null;
    SpecifiedLayout legendlabels_sl1 = null, legendlabels_sl2 = null;
   
    if (plot_legend) {
      addHostLabels(hd);
      legend_sa1 = new ShapeAction(legendshapegroup);
      legendlabels_sl1 = new SpecifiedLayout(legendgroup, VisualItem.X, VisualItem.Y);
      ActionList legenddraw = new ActionList();
      legenddraw.add(legend_sa1);
      this.viz.putAction(legendshapegroup, legenddraw);
      ActionList legendlabelsdraw = new ActionList();
      legendlabelsdraw.add(legendlabels_sl1);
      this.viz.putAction(legendgroup,legendlabelsdraw);
    }

    if (plot_additional_info) {
      addAddlInfo(hd);
      legend_sa2 = new ShapeAction(addinfoshapegroup);
      legendlabels_sl2 = new SpecifiedLayout(addinfogroup, VisualItem.X, VisualItem.Y);   
      ActionList legenddraw = new ActionList();
      legenddraw.add(legend_sa2);
      this.viz.putAction(addinfoshapegroup, legenddraw);
      ActionList legendlabelsdraw = new ActionList();
      legendlabelsdraw.add(legendlabels_sl2);
      this.viz.putAction(addinfogroup,legendlabelsdraw);
    }

  }
 
  protected boolean checkDone(int [] clustId) {
    for (int i = 1; i < clustId.length; i++) {
      if (clustId[i] != clustId[0]) return false;
    }
    return true;
  }
 
  /**
   * Sort data for better visualization of patterns
   */
  protected int [] hClust (long [][] stat)
  {
    int statlen = stat.length;
    long [] rowSums = new long[statlen];
    int [] permute = new int[statlen];
    int i,j,k;

    // initialize permutation
    for (i = 0; i < statlen; i++) {
      permute[i] = i;
    }
   
    for (i = 0; i < statlen; i++) {
      rowSums[i] = 0;
      for (j = 0; j < statlen; j++) {
        rowSums[i] += stat[i][j];
      }
    }
   
    // insertion sort
    for (i = 0; i < statlen-1; i++) {
      long val = rowSums[i];
      int thispos = permute[i];
      j = i-1;
      while (j >= 0 && rowSums[j] > val) {
        rowSums[j+1] = rowSums[j];
        permute[j+1] = permute[j];
        j--;
      }
      rowSums[j+1] = val;
      permute[j+1] = thispos;
    }
   
    return permute;
     
  }
 
  /**
   * Reorder rows (and columns) according to a given ordering
   * Maintains same ordering along rows and columns
   */
  protected long [][] doPermute (long [][] stat, int [] permute) {
    int statlen = stat.length;
    int i, j, curr_pos;
    long [][] stat2 = new long[statlen][statlen];
   
    assert(stat.length == permute.length);
   
    for (i = 0; i < statlen; i++) {
      curr_pos = permute[i];
      for (j = 0; j < statlen; j++) {
        stat2[i][j] = stat[curr_pos][permute[j]];
      }
    }
   
    return stat2;
  }
 
  /**
   * Interfaces with database to get data and
   * populate data structures for rendering
   */
  public HeatmapData getData() {
    // preliminary setup
    OfflineTimeHandler time_offline;
    TimeHandler time_online;
    long start, end, min, max;
   
    if (offline_use) {
      time_offline = new OfflineTimeHandler(param_map, this.timezone);
      start = time_offline.getStartTime();
      end = time_offline.getEndTime();
    } else {
      time_online = new TimeHandler(this.request, this.timezone);
      start = time_online.getStartTime();
      end = time_online.getEndTime();
    }
   
    DatabaseWriter dbw = new DatabaseWriter(this.cluster);
   
    // setup query
    String query;
    if (this.query_state != null && this.query_state.equals("read")) {
      query = "select block_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname,other_host,bytes from ["+table+"] where finish_time between '[start]' and '[end]' and (state_name like 'read_local' or state_name like 'read_remote')";
    } else if (this.query_state != null && this.query_state.equals("write")) {
      query = "select block_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname,other_host,bytes from ["+table+"] where finish_time between '[start]' and '[end]' and (state_name like 'write_local' or state_name like 'write_remote' or state_name like 'write_replicated')";
    } else {
      query = "select block_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname,other_host,bytes from ["+table+"] where finish_time between '[start]' and '[end]' and state_name like '" + query_state + "'";
    }
    Macro mp = new Macro(start,end,query);
    query = mp.toString() + " order by start_time";
   
    ArrayList<HashMap<String, Object>> events = new ArrayList<HashMap<String, Object>>();

    ResultSet rs = null;
   
    log.debug("Query: " + query);
    // run query, extract results
    try {
      rs = dbw.query(query);
      ResultSetMetaData rmeta = rs.getMetaData();
      int col = rmeta.getColumnCount();
      while (rs.next()) {
        HashMap<String, Object> event = new HashMap<String, Object>();
        long event_time=0;
        for(int i=1;i<=col;i++) {
          if(rmeta.getColumnType(i)==java.sql.Types.TIMESTAMP) {
            event.put(rmeta.getColumnName(i),rs.getTimestamp(i).getTime());
          } else {
            event.put(rmeta.getColumnName(i),rs.getString(i));
          }
        }
        events.add(event);
      }
    } catch (SQLException ex) {
      // handle any errors
      log.error("SQLException: " + ex.getMessage());
      log.error("SQLState: " + ex.getSQLState());
      log.error("VendorError: " + ex.getErrorCode());
    } finally {
      dbw.close();
    }   
    SimpleDateFormat format = new SimpleDateFormat("MMM dd yyyy HH:mm:ss");

    log.info(events.size() + " results returned.");

    HashSet<String> host_set = new HashSet<String>();
    HashMap<String, Integer> host_indices = new HashMap<String, Integer>();
    HashMap<Integer, String> host_rev_indices = new HashMap<Integer, String>();

    // collect hosts, name unique hosts
    for(int i = 0; i < events.size(); i++) {
      HashMap<String, Object> event = events.get(i);
      String curr_host = (String) event.get("hostname");
      String other_host = (String) event.get("other_host");
      host_set.add(curr_host);
      host_set.add(other_host);
    }
    int num_hosts = host_set.size();

    Iterator<String> host_iter = host_set.iterator();
    for (int i = 0; i < num_hosts && host_iter.hasNext(); i++) {
      String curr_host = host_iter.next();
      host_indices.put(curr_host, new Integer(i));
      host_rev_indices.put(new Integer(i),curr_host);
    }

    System.out.println("Number of hosts: " + num_hosts);
    long stats[][] = new long[num_hosts][num_hosts];
    long count[][] = new long[num_hosts][num_hosts]; // used for averaging

    int start_millis = 0, end_millis = 0;

    // deliberate design choice to duplicate code PER possible operation
    // otherwise we have to do the mode check N times, for N states returned
    //
    // compute aggregate statistics
    log.info("Query statistic type: "+this.query_stat_type);
    if (this.query_stat_type.equals("transaction_count")) {
      for(int i=0;i<events.size();i++) {
        HashMap<String, Object> event = events.get(i);
        start=(Long)event.get("start_time");
        end=(Long)event.get("finish_time");
        start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
        end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));     
        String cell = (String) event.get("state_name");     
        String this_host = (String) event.get("hostname");
        String other_host = (String) event.get("other_host");
        int this_host_idx = host_indices.get(this_host).intValue();
        int other_host_idx = host_indices.get(other_host).intValue();

        // to, from
        stats[other_host_idx][this_host_idx] += 1;
      }
    } else if (this.query_stat_type.equals("avg_duration")) {
      for(int i=0;i<events.size();i++) {
        HashMap<String, Object> event = events.get(i);
        start=(Long)event.get("start_time");
        end=(Long)event.get("finish_time");
        start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
        end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));     
        String cell = (String) event.get("state_name");     
        String this_host = (String) event.get("hostname");
        String other_host = (String) event.get("other_host");
        int this_host_idx = host_indices.get(this_host).intValue();
        int other_host_idx = host_indices.get(other_host).intValue();

        long curr_val = end_millis - start_millis + ((end - start)*1000);

        // to, from
        stats[other_host_idx][this_host_idx] += curr_val;
        count[other_host_idx][this_host_idx] += 1;
      }   
      for (int i = 0; i < num_hosts; i++) {
        for (int j = 0; j < num_hosts; j++) {
          if (count[i][j] > 0) stats[i][j] = stats[i][j] / count[i][j];
        }
      }
    } else if (this.query_stat_type.equals("avg_volume")) {
      for(int i=0;i<events.size();i++) {
        HashMap<String, Object> event = events.get(i);
        start=(Long)event.get("start_time");
        end=(Long)event.get("finish_time");
        start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
        end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));     
        String cell = (String) event.get("state_name");     
        String this_host = (String) event.get("hostname");
        String other_host = (String) event.get("other_host");
        int this_host_idx = host_indices.get(this_host).intValue();
        int other_host_idx = host_indices.get(other_host).intValue();

        long curr_val = Long.parseLong((String)event.get("bytes"));

        // to, from
        stats[other_host_idx][this_host_idx] += curr_val;
        count[other_host_idx][this_host_idx] += 1;
      }   
      for (int i = 0; i < num_hosts; i++) {
        for (int j = 0; j < num_hosts; j++) {
          if (count[i][j] > 0) stats[i][j] = stats[i][j] / count[i][j];
        }
      }
    } else if (this.query_stat_type.equals("total_duration")) {
      for(int i=0;i<events.size();i++) {
        HashMap<String, Object> event = events.get(i);
        start=(Long)event.get("start_time");
        end=(Long)event.get("finish_time");
        start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
        end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));     
        String cell = (String) event.get("state_name");     
        String this_host = (String) event.get("hostname");
        String other_host = (String) event.get("other_host");
        int this_host_idx = host_indices.get(this_host).intValue();
        int other_host_idx = host_indices.get(other_host).intValue();

        double curr_val = end_millis - start_millis + ((end - start)*1000);

        // to, from
        stats[other_host_idx][this_host_idx] += curr_val;
      }
    } else if (this.query_stat_type.equals("total_volume")) {
      for(int i=0;i<events.size();i++) {
        HashMap<String, Object> event = events.get(i);
        start=(Long)event.get("start_time");
        end=(Long)event.get("finish_time");
        start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
        end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));     
        String cell = (String) event.get("state_name");     
        String this_host = (String) event.get("hostname");
        String other_host = (String) event.get("other_host");
        int this_host_idx = host_indices.get(this_host).intValue();
        int other_host_idx = host_indices.get(other_host).intValue();

        long curr_val = Long.parseLong((String)event.get("bytes"));

        // to, from
        stats[other_host_idx][this_host_idx] += curr_val;
      }   
    }
   
    int [] permute = null;
    if (sort_nodes) {
      permute = hClust(stats);
      stats = doPermute(stats,permute);
    }
   
    Table agg_tab = new Table();
    agg_tab.addColumn("stat", long.class);
    min = Long.MAX_VALUE;
    max = Long.MIN_VALUE;
    agg_tab.addRows(num_hosts*num_hosts);
   
    // row-wise placement (row1, followed by row2, etc.)
    for (int i = 0; i < num_hosts; i++) {
      for (int j = 0; j < num_hosts; j++) {
        agg_tab.setLong((i*num_hosts)+j,"stat",stats[i][j]);
        if (stats[i][j] > max) max = stats[i][j];
        if (stats[i][j] > 0 && stats[i][j] < min) min = stats[i][j];
      }
    }
    if (min == Long.MAX_VALUE) min = 0;
   
    log.info(agg_tab);
   
    // collate data
    HeatmapData hd = new HeatmapData();
    hd.stats = new long[num_hosts][num_hosts];
    hd.stats = stats;
    hd.min = min;
    hd.max = max;
    hd.num_hosts = num_hosts;
    hd.agg_tab = agg_tab;
   
    this.add_info_extra = new String("\nState: "+this.prettyStateNames.get(this.query_state)+
      " ("+events.size()+" "+this.query_state+"'s ["+this.query_stat_type+"])\n" +
      "Plotted value range: ["+hd.min+","+hd.max+"] (Zeros in black)");

    hd.hostnames = new String [num_hosts];
    for (int i = 0; i < num_hosts; i++) {
      String curr_host = host_rev_indices.get(new Integer(permute[i]));
      if (sort_nodes) {
        hd.hostnames[i] = new String(curr_host);
      } else {
        hd.hostnames[i] = new String(curr_host);
      }
    }
   
    return hd;
  }
 
}
TOP

Related Classes of org.apache.hadoop.chukwa.analysis.salsa.visualization.Heatmap$HeatmapData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.