package edu.brown.api.results;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.voltdb.catalog.Database;
import edu.brown.hstore.Hstoreservice.Status;
import edu.brown.statistics.FastIntHistogram;
import edu.brown.statistics.ObjectHistogram;
import edu.brown.utils.JSONSerializable;
import edu.brown.utils.JSONUtil;
/**
* Raw results collected for each BenchmarkComponent instance
* @author pavlo
*/
public class BenchmarkComponentResults implements JSONSerializable {
/**
* The number of txns executed base on ProcedureID
*/
public FastIntHistogram transactions = new FastIntHistogram(true);
/**
* The number of speculatively executed txns
*/
public FastIntHistogram specexecs = new FastIntHistogram(true);
/**
* The number of distributed txns executed based on ProcedureId
*/
public FastIntHistogram dtxns = new FastIntHistogram(true);
/**
* Transaction Name Index -> Latencies
*/
public final Map<Integer, ObjectHistogram<Integer>> spLatencies = new HashMap<Integer, ObjectHistogram<Integer>>();
public final Map<Integer, ObjectHistogram<Integer>> dtxnLatencies = new HashMap<Integer, ObjectHistogram<Integer>>();
public FastIntHistogram basePartitions = new FastIntHistogram(true);
private boolean enableBasePartitions = false;
public FastIntHistogram responseStatuses = new FastIntHistogram(true, Status.values().length);
private boolean enableResponseStatuses = false;
/**
* Constructor
*/
public BenchmarkComponentResults() {
// Nothing to do...
}
public BenchmarkComponentResults copy() {
final BenchmarkComponentResults copy = new BenchmarkComponentResults();
assert(copy.transactions != null);
copy.transactions.setDebugLabels(this.transactions.getDebugLabels());
copy.transactions.put(this.transactions);
assert(copy.specexecs != null);
copy.specexecs.setDebugLabels(this.transactions.getDebugLabels());
copy.specexecs.put(this.specexecs);
assert(copy.dtxns != null);
copy.dtxns.setDebugLabels(this.transactions.getDebugLabels());
copy.dtxns.put(this.dtxns);
copy.spLatencies.clear();
synchronized (this.spLatencies) {
for (Entry<Integer, ObjectHistogram<Integer>> e : this.spLatencies.entrySet()) {
ObjectHistogram<Integer> h = new ObjectHistogram<Integer>();
synchronized (e.getValue()) {
h.put(e.getValue());
} // SYNCH
copy.spLatencies.put(e.getKey(), h);
} // FOR
} // SYNCH
copy.dtxnLatencies.clear();
synchronized (this.dtxnLatencies) {
for (Entry<Integer, ObjectHistogram<Integer>> e : this.dtxnLatencies.entrySet()) {
ObjectHistogram<Integer> h = new ObjectHistogram<Integer>();
synchronized (e.getValue()) {
h.put(e.getValue());
} // SYNCH
copy.dtxnLatencies.put(e.getKey(), h);
} // FOR
} // SYNCH
copy.enableBasePartitions = this.enableBasePartitions;
copy.basePartitions.put(this.basePartitions);
copy.enableResponseStatuses = this.enableResponseStatuses;
copy.responseStatuses.put(this.responseStatuses);
return (copy);
}
public boolean isBasePartitionsEnabled() {
return (this.enableBasePartitions);
}
public void setEnableBasePartitions(boolean val) {
this.enableBasePartitions = val;
}
public boolean isResponsesStatusesEnabled() {
return (this.enableResponseStatuses);
}
public void setEnableResponsesStatuses(boolean val) {
this.enableResponseStatuses = val;
}
public void clear(boolean includeTxns) {
if (includeTxns && this.transactions != null) {
this.transactions.clearValues();
this.specexecs.clearValues();
this.dtxns.clearValues();
}
this.spLatencies.clear();
this.dtxnLatencies.clear();
this.basePartitions.clearValues();
this.responseStatuses.clearValues();
}
// ----------------------------------------------------------------------------
// SERIALIZATION METHODS
// ----------------------------------------------------------------------------
@Override
public void load(File input_path, Database catalog_db) throws IOException {
JSONUtil.load(this, catalog_db, input_path);
}
@Override
public void save(File output_path) throws IOException {
JSONUtil.save(this, output_path);
}
@Override
public String toJSONString() {
return (JSONUtil.toJSONString(this));
}
@Override
public void toJSON(JSONStringer stringer) throws JSONException {
String exclude[] = {
(this.enableBasePartitions == false ? "basePartitions" : ""),
(this.enableResponseStatuses == false ? "responseStatuses" : ""),
};
// HACK
this.specexecs.setDebugLabels(null);
this.dtxns.setDebugLabels(null);
Field fields[] = JSONUtil.getSerializableFields(this.getClass(), exclude);
JSONUtil.fieldsToJSON(stringer, this, BenchmarkComponentResults.class, fields);
this.specexecs.setDebugLabels(this.transactions.getDebugLabels());
this.dtxns.setDebugLabels(this.transactions.getDebugLabels());
}
@Override
public void fromJSON(JSONObject json_object, Database catalog_db) throws JSONException {
this.spLatencies.clear();
this.dtxnLatencies.clear();
Field fields[] = JSONUtil.getSerializableFields(this.getClass());
JSONUtil.fieldsFromJSON(json_object, catalog_db, this, BenchmarkComponentResults.class, true, fields);
assert(this.transactions != null);
assert(this.specexecs != null);
assert(this.dtxns != null);
// HACK: Copy the transaction's debug labels into these histograms
if (this.specexecs.hasDebugLabels() == false) {
this.specexecs.setDebugLabels(this.transactions.getDebugLabels());
}
if (this.dtxns.hasDebugLabels() == false) {
this.dtxns.setDebugLabels(this.transactions.getDebugLabels());
}
}
} // END CLASS