/***********************************************************************
* Copyright (c) 2004, 2005 Actuate Corporation.
* 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:
* Actuate Corporation - initial API and implementation
* Elliott Baron <ebaron@redhat.com> - Modified implementation
***********************************************************************/
package org.eclipse.linuxtools.internal.valgrind.massif.charting;
import org.eclipse.linuxtools.internal.valgrind.massif.MassifSnapshot;
import org.eclipse.linuxtools.internal.valgrind.massif.MassifSnapshot.TimeUnit;
import org.eclipse.swt.widgets.Composite;
public class HeapChart {
private static String[] byteUnits = { Messages.getString("HeapChart.B"), //$NON-NLS-1$
Messages.getString("HeapChart.KiB"), //$NON-NLS-1$
Messages.getString("HeapChart.MiB"), //$NON-NLS-1$
Messages.getString("HeapChart.GiB"), //$NON-NLS-1$
Messages.getString("HeapChart.TiB") //$NON-NLS-1$
};
private static String[] instrUnits = { Messages.getString("HeapChart.i"), //$NON-NLS-1$
Messages.getString("HeapChart.Ki"), //$NON-NLS-1$
Messages.getString("HeapChart.Mi"), //$NON-NLS-1$
Messages.getString("HeapChart.Gi"), //$NON-NLS-1$
Messages.getString("HeapChart.Ti") //$NON-NLS-1$
};
private static String[] secondUnits = { Messages.getString("HeapChart.ms"), //$NON-NLS-1$
Messages.getString("HeapChart.s") //$NON-NLS-1$
};
protected static final int BYTE_MULT = 1024;
protected static final int BYTE_LIMIT = byteUnits.length - 1;
protected static final int INSTR_MULT = 1000;
protected static final int INSTR_LIMIT = instrUnits.length - 1;
protected static final int MS_MULT = 1000;
protected static final int MS_LIMIT = secondUnits.length - 1;
protected static final int SCALING_THRESHOLD = 20;
protected String title;
protected String xUnits;
protected String yUnits;
public double [] time, dataUseful, dataExtra, dataStacks, dataTotal;
private Composite chartControl;
public HeapChart(MassifSnapshot[] snapshots, String title) {
TimeUnit timeUnit = snapshots[0].getUnit();
long xScaling = getXScaling(snapshots, timeUnit);
long yScaling = getYScaling(snapshots);
this.title = title;
time = new double[snapshots.length];
dataUseful = new double[snapshots.length];
dataExtra = new double[snapshots.length];
dataStacks = null;
boolean isStack = isStackProfiled(snapshots);
if (isStack) {
dataStacks = new double[snapshots.length];
}
dataTotal = new double[snapshots.length];
for (int i = 0; i < snapshots.length; i++) {
time[i] = snapshots[i].getTime() / (double) xScaling;
dataUseful[i] = snapshots[i].getHeapBytes() / (double) yScaling;
dataExtra[i] = snapshots[i].getHeapExtra() / (double) yScaling;
dataTotal[i] = dataUseful[i] + dataExtra[i];
if (isStack) {
dataStacks[i] = snapshots[i].getStacks() / (double) yScaling;
}
}
}
private boolean isStackProfiled(MassifSnapshot[] snapshots) {
return getMaxStack(snapshots) > 0;
}
private long getYScaling(MassifSnapshot[] snapshots) {
long max = getMaxValue(snapshots);
int count = 0;
while (max > BYTE_MULT * SCALING_THRESHOLD && count < BYTE_LIMIT) {
max /= BYTE_MULT;
count++;
}
yUnits = byteUnits[count];
return (long) Math.pow(BYTE_MULT, count);
}
private long getXScaling(MassifSnapshot[] snapshots, TimeUnit unit) {
long max = snapshots[snapshots.length - 1].getTime();
int mult, limit;
String[] units;
switch (unit) {
case BYTES:
mult = BYTE_MULT;
limit = BYTE_LIMIT;
units = byteUnits;
break;
case INSTRUCTIONS:
mult = INSTR_MULT;
limit = INSTR_LIMIT;
units = instrUnits;
break;
default:
mult = MS_MULT;
limit = MS_LIMIT;
units = secondUnits;
break;
}
int count = 0;
while (max > mult * SCALING_THRESHOLD && count < limit) {
max /= mult;
count++;
}
xUnits = units[count];
return (long) Math.pow(mult, count);
}
private static long getMaxValue(MassifSnapshot[] snapshots) {
long max = 0;
for (MassifSnapshot snapshot : snapshots) {
if (snapshot.getTotal() > max) {
max = snapshot.getTotal();
}
}
return max;
}
private static long getMaxStack(MassifSnapshot[] snapshots) {
long max = 0;
for (MassifSnapshot snapshot : snapshots) {
if (snapshot.getTotal() > max) {
max = snapshot.getStacks();
}
}
return max;
}
public String getXUnits() {
return xUnits;
}
public String getYUnits() {
return yUnits;
}
public static String[] getByteUnits() {
return byteUnits;
}
public static String[] getInstrUnits() {
return instrUnits;
}
public static String[] getSecondUnits() {
return secondUnits;
}
public void setChartControl(Composite control) {
chartControl = control;
}
public Composite getChartControl (){
return chartControl;
}
}