/*******************************************************************************
* Copyright (c) 2013 Red Hat, Inc.
* 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:
* Camilo Bernal <cabernal@redhat.com> - Initial Implementation.
*******************************************************************************/
package org.eclipse.linuxtools.internal.perf.model;
/**
* Representation of a single entry in a perf stat report.
*/
public class PMStatEntry {
// Samples of current event.
private float samples;
// Current event.
private String event;
// Metrics for current event.
private float metrics;
// Metrics' units.
private String units;
// Standard deviation of stats.
private float deviation;
// Scaling.
private float scaling;
// Types of relevant strings for a perf stat entry.
public static enum Type {
ENTRY_PATTERN, TIME_PATTERN, ENTRY_FORMAT, PERCENT_FORMAT, METRIC_FORMAT
}
// Reg-ex strings for elements in a perf stat entry.
public static final String DECIMAL = "\\d+[\\.\\,\\d]*"; //$NON-NLS-1$
public static final String PERCENTAGE = "(\\d+(\\.\\d+)?)\\%"; //$NON-NLS-1$
public static final String SAMPLES = "(" + DECIMAL + ")"; //$NON-NLS-1$ //$NON-NLS-2$
public static final String EVENT = "(\\w+(\\-\\w+)*(:\\w+)?(\\s\\(\\w+\\))?)";//$NON-NLS-1$
public static final String METRICS = "(" + DECIMAL + ")"; //$NON-NLS-1$//$NON-NLS-2$
public static final String UNITS = "([a-zA-Z\\/\\s\\%]*)"; //$NON-NLS-1$
public static final String DELTA = "(\\(\\s\\+\\-\\s*" + PERCENTAGE + "\\s\\))"; //$NON-NLS-1$ //$NON-NLS-2$
public static final String SCALE = "(\\[\\s*" + PERCENTAGE + "\\])"; //$NON-NLS-1$ //$NON-NLS-2$
public static final String TIME_UNIT = "(seconds\\stime\\selapsed)"; //$NON-NLS-1$
public static final String TIME = "seconds time elapsed"; //$NON-NLS-1$
public PMStatEntry(float samples, String event, float metrics,
String units, float deviation, float scaling) {
this.samples = samples;
this.event = event;
this.metrics = metrics;
this.units = units;
this.deviation = deviation;
this.scaling = scaling;
}
public float getSamples() {
return samples;
}
public String getEvent() {
return (event == null) ? "" : event; //$NON-NLS-1$
}
public float getMetrics() {
return metrics;
}
public String getUnits() {
return (units == null) ? "" : units.trim(); //$NON-NLS-1$
}
public float getDeviation() {
return deviation;
}
public float getScaling() {
return scaling;
}
public String getFormattedMetrics(){
return String.format("%.3f", metrics); //$NON-NLS-1$
}
public String getFormattedDeviation(){
return String.format("%.2f%%", deviation); //$NON-NLS-1$
}
@Override
public boolean equals(Object entry) {
PMStatEntry statEntry = (PMStatEntry) entry;
if (statEntry == null
|| samples != statEntry.getSamples()
|| metrics != statEntry.getMetrics()
|| deviation != statEntry.getDeviation()
|| scaling != statEntry.getScaling()) {
return false;
}
if (!getEvent().equals(statEntry.getEvent())
|| !getUnits().equals(statEntry.getUnits())) {
return false;
}
return true;
}
/**
* Check if PMStatEntry refer to the same event.
* @param entry PMStatEntry to check against
* @return true if events are equals, false otherwise.
*/
public boolean equalEvents(PMStatEntry entry) {
String event = entry.getEvent();
if (this.event != null && event != null) {
return this.event.equals(event);
}
return false;
}
/**
* Auto-generated hashCode method.
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToIntBits(deviation);
result = prime * result + ((event == null) ? 0 : event.hashCode());
result = prime * result + Float.floatToIntBits(metrics);
result = prime * result + Float.floatToIntBits(samples);
result = prime * result + Float.floatToIntBits(scaling);
result = prime * result + ((units == null) ? 0 : units.hashCode());
return result;
}
/**
* Compare this PMStatEntry with the specified one, and return an object
* with the result.
*
* @param entry PMStatEntry to compare against
* @return a PMStatEntry representing the resulting comparison.
*/
public PMStatEntry compare(PMStatEntry entry){
float occurrenceDiff = entry.getSamples() - this.samples;
float metricsDiff = entry.getMetrics() - this.metrics;
float deviationDiff = entry.getDeviation() + this.deviation;
float scalingDiff = entry.getScaling() + this.scaling;
return new PMStatEntry(occurrenceDiff, event, metricsDiff, units, deviationDiff, scalingDiff);
}
/**
* Return formatted String values of fields in a string array.
*
* @return String[] String array containing string value of fields.
*/
public String[] toStringArray(){
return new String[] { String.valueOf(samples),
getEvent(),
getFormattedMetrics(),
getUnits(),
getFormattedDeviation()};
}
/**
* Get string related to specified type of perf stat entry:
* <p>
* ENTRY_PATTERN: - Regex for a generic entry.</br>
* TIME_PATTERN: - Regex for total time entry.</br>
* ENTRY_FORMAT: - Format string for a generic entry.
* </p>
*
* @param type
* @return
*/
public static String getString(Type type) {
String stringRes = ""; //$NON-NLS-1$
switch (type) {
case ENTRY_PATTERN:
// samples, event, metrics, units, deviation, scaling
stringRes = "^" + SAMPLES; //$NON-NLS-1$
stringRes += "\\s*" + EVENT; //$NON-NLS-1$
stringRes += "\\s*(\\#\\s+" + METRICS + UNITS + ")?"; //$NON-NLS-1$ //$NON-NLS-2$
stringRes += DELTA + "?"; //$NON-NLS-1$
stringRes += "(\\s" + SCALE + ")?$"; //$NON-NLS-1$ //$NON-NLS-2$
return stringRes;
case TIME_PATTERN:
// samples, time elapsed, deviation
stringRes += "^" + SAMPLES; //$NON-NLS-1$
stringRes += "\\s" + TIME_UNIT; //$NON-NLS-1$
stringRes += "\\s+" + DELTA; //$NON-NLS-1$
return stringRes;
case ENTRY_FORMAT:
// Stat entry format
stringRes += " %%1$%1$1ds "; //$NON-NLS-1$
stringRes += "%%2$-%2$1ds # "; //$NON-NLS-1$
stringRes += "%%3$%3$1ds "; //$NON-NLS-1$
stringRes += "%%4$-%4$1ds "; //$NON-NLS-1$
stringRes += "( +- %%5$%5$1ds )\n"; //$NON-NLS-1$
return stringRes;
default:
return stringRes;
}
}
}