/*************************************************************************** * Copyright (C) 2009 by H-Store Project * * Brown University * * Massachusetts Institute of Technology * * Yale University * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.* * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * * OTHER DEALINGS IN THE SOFTWARE. * ***************************************************************************/ package edu.brown.statistics; import java.lang.reflect.Field; import java.util.SortedMap; import java.util.TreeMap; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONStringer; import org.voltdb.catalog.Database; import org.voltdb.catalog.Statement; import org.voltdb.catalog.StmtParameter; import edu.brown.catalog.CatalogKey; import edu.brown.mappings.AbstractMapping; import edu.brown.workload.QueryTrace; import edu.brown.workload.TransactionTrace; /** * @author pavlo */ public class QueryStatistics extends AbstractStatistics<Statement> { public enum Members { // Number of times executed (per procedure) EXECUTE_COUNT_TOTAL, EXECUTE_PROC_COUNT, EXECUTE_COUNT_MIN, EXECUTE_COUNT_MAX, EXECUTE_COUNT_AVG, // Parameter Information PARAM_HISTOGRAMS, // PARAM_PROC_CORELATIONS, }; public Long execute_count_total = 0l; public Long execute_proc_count = 0l; public Long execute_count_min = null; public Long execute_count_max = null; public Long execute_count_avg = null; public final SortedMap<Integer, ObjectHistogram> param_histograms = new TreeMap<Integer, ObjectHistogram>(); public final SortedMap<Integer, SortedMap<Integer, AbstractMapping>> param_proc_corelations = new TreeMap<Integer, SortedMap<Integer, AbstractMapping>>(); /** * Constructor * * @param catalog_key */ public QueryStatistics(String catalog_key) { super(catalog_key); } /** * Constructor * * @param catalog_stmt */ public QueryStatistics(Statement catalog_stmt) { super(catalog_stmt); this.preprocess((Database) catalog_stmt.getParent().getParent()); } @Override public Statement getCatalogItem(Database catalog_db) { Statement ret = CatalogKey.getFromKey(catalog_db, this.catalog_key, Statement.class); return (ret); } @Override public void preprocess(Database catalog_db) { if (this.has_preprocessed) return; final Statement catalog_stmt = this.getCatalogItem(catalog_db); for (StmtParameter catalog_stmt_param : catalog_stmt.getParameters()) { int stmt_param_idx = catalog_stmt_param.getIndex(); this.param_histograms.put(stmt_param_idx, new ObjectHistogram()); } // FOR this.has_preprocessed = true; } @Override public void process(Database catalog_db, TransactionTrace xact) throws Exception { final Statement catalog_stmt = this.getCatalogItem(catalog_db); // // For each query, check whether they are going to our table // If so, then we need to update our statistics // int num_params = catalog_stmt.getParameters().size(); long execute_count = 0; LOG.debug("Examining " + xact + " for instances of " + catalog_stmt); for (QueryTrace query : xact.getQueries()) { if (!query.getCatalogItemName().equals(CatalogKey.getNameFromKey(this.getCatalogKey()))) continue; this.execute_count_total++; execute_count++; Object params[] = query.getParams(); if (params != null) { for (int i = 0; i < params.length; i++) { if (this.param_histograms.containsKey(i) && params[i] != null) { this.param_histograms.get(i).put((Comparable<?>) params[i]); } } // FOR } } // FOR if (execute_count > 0) this.execute_proc_count++; if (this.execute_count_min == null || execute_count < this.execute_count_min) { this.execute_count_min = execute_count; } if (this.execute_count_max == null || execute_count > this.execute_count_max) { this.execute_count_max = execute_count; } return; } @Override public void postprocess(Database catalog_db) throws Exception { // Query Exec Avg this.execute_count_avg = this.execute_count_total / this.execute_proc_count; } @Override public String debug(Database catalog_db) { return (this.debug(catalog_db, QueryStatistics.Members.values())); } @Override public void toJSONString(JSONStringer stringer) throws JSONException { for (Members element : QueryStatistics.Members.values()) { try { Field field = QueryStatistics.class.getDeclaredField(element.toString().toLowerCase()); if (element == Members.PARAM_HISTOGRAMS) { stringer.key(element.name()).object(); for (Integer idx : this.param_histograms.keySet()) { stringer.key(idx.toString()).object(); this.param_histograms.get(idx).toJSON(stringer); stringer.endObject(); } // FOR stringer.endObject(); // } else if (element == Members.PARAM_PROC_CORELATIONS) { } else { stringer.key(element.name()).value(field.get(this)); } } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } // FOR } @Override public void fromJSONObject(JSONObject object, Database catalog_db) throws JSONException { this.preprocess(catalog_db); for (Members element : QueryStatistics.Members.values()) { try { Field field = QueryStatistics.class.getDeclaredField(element.toString().toLowerCase()); if (element == Members.PARAM_HISTOGRAMS) { // } else if (element == Members.PARAM_PROC_CORELATIONS) { } else if (object.isNull(element.name())) { field.set(this, null); } else { field.set(this, object.getLong(element.name())); } } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } // FOR } }