package edu.brown.mappings;
import java.io.File;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.voltdb.catalog.Column;
import org.voltdb.catalog.Database;
import org.voltdb.catalog.ProcParameter;
import org.voltdb.catalog.Statement;
import org.voltdb.catalog.StmtParameter;
import edu.brown.catalog.CatalogUtil;
import edu.brown.plannodes.PlanNodeUtil;
import edu.brown.utils.JSONSerializable;
import edu.brown.utils.JSONUtil;
public class ParameterMapping implements Comparable<ParameterMapping>, JSONSerializable, Cloneable {
enum Members {
STATEMENT,
STATEMENT_INDEX,
STATEMENT_PARAMETER,
STATEMENT_COLUMN,
PROCEDURE_PARAMETER,
PROCEDURE_PARAMETER_INDEX,
COEFFICIENT,
}
public Statement statement;
public int statement_index;
public StmtParameter statement_parameter;
public Column statement_column;
public ProcParameter procedure_parameter;
public int procedure_parameter_index;
public double coefficient;
private transient Integer hashcode;
/**
* Constructor
*/
protected ParameterMapping() {
// Needed for deserialization
}
/**
* Constructor
* @param catalog_param
* @param index
* @param coefficient
*/
public ParameterMapping(Statement catalog_stmt, int catalog_stmt_index, StmtParameter catalog_stmt_param, ProcParameter catalog_proc_param, int catalog_proc_param_index, double coefficient) {
this.statement = catalog_stmt;
this.statement_index = catalog_stmt_index;
this.statement_parameter = catalog_stmt_param;
this.procedure_parameter = catalog_proc_param;
this.coefficient = coefficient;
// My father told me to trust no one...
// He took that advice to the grave...
// He ended up shooting a cop that was trying to help when he got a flat tire...
// Let that be a lesson for you little Billy
assert(this.procedure_parameter != null);
assert(this.statement != null);
assert(this.procedure_parameter.getParent().equals(this.statement.getParent()));
assert(this.statement_index >= 0);
assert(this.statement_parameter != null);
assert(this.statement_parameter.getParent().equals(this.statement));
assert(this.coefficient >= -1.0);
assert(this.coefficient <= 1.0);
if (this.procedure_parameter.getIsarray()) {
assert(this.procedure_parameter_index >= 0);
this.procedure_parameter_index = catalog_proc_param_index;
} else {
this.procedure_parameter_index = ParametersUtil.NULL_PROC_PARAMETER_OFFSET;
}
// Always grab the Column that the StmtParameter is mapped to in the Statement
try {
this.statement_column = PlanNodeUtil.getColumnForStmtParameter(this.statement_parameter);
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
@Override
public ParameterMapping clone() throws CloneNotSupportedException {
return (ParameterMapping)super.clone();
}
public Statement getStatement() {
return this.statement;
}
public Column getStatementColumn() {
return (this.statement_column);
}
public int getStatementIndex() {
return this.statement_index;
}
public StmtParameter getStmtParameter() {
return this.statement_parameter;
}
public ProcParameter getProcParameter() {
return this.procedure_parameter;
}
public boolean hasProcParameterIndex() {
return (this.procedure_parameter_index != ParametersUtil.NULL_PROC_PARAMETER_OFFSET);
}
public int getProcParameterIndex() {
return this.procedure_parameter_index;
}
public double getCoefficient() {
return this.coefficient;
}
public Column getColumn() {
return this.statement_column;
}
/**
* Compares this object to another
* @return -1 if this object is less than the other, 1 if this object is greater than the other, 0 otherwise
*/
@SuppressWarnings("unchecked")
@Override
public int compareTo(ParameterMapping o) {
assert(o != null);
assert(o instanceof ParameterMapping);
// Sort them by their attributes as they appear in the catalog
// No! We want to sort them by their coefficients!
@SuppressWarnings("rawtypes")
final Comparable items0[] = new Comparable<?>[] {
this.coefficient,
this.statement,
this.statement_index,
this.statement_parameter,
this.procedure_parameter,
this.procedure_parameter_index,
};
@SuppressWarnings("rawtypes")
final Comparable items1[] = new Comparable<?>[] {
o.coefficient,
o.statement,
o.statement_index,
o.statement_parameter,
o.procedure_parameter,
o.procedure_parameter_index,
};
assert(items0.length == items1.length);
for (int i = 0; i < items0.length; i++) {
int result = items1[i].compareTo(items0[i]);
if (result != 0) return (result);
} // FOR
return (0);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ParameterMapping) {
ParameterMapping c = (ParameterMapping)obj;
return (this.statement.equals(c.statement) &&
this.statement_index == c.statement_index &&
this.statement_parameter.equals(c.statement_parameter) &&
this.procedure_parameter.equals(c.procedure_parameter) &&
this.procedure_parameter_index == c.procedure_parameter_index);
}
return (false);
}
@Override
public int hashCode() {
if (this.hashcode == null) {
this.hashcode = (this.statement.getName() +
this.statement_index +
this.statement_parameter.getName() +
this.procedure_parameter.getName() +
this.procedure_parameter_index).intern().hashCode();
}
return (this.hashcode);
}
// ----------------------------------------------------------------------------
// 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 {
JSONUtil.fieldsToJSON(stringer, this, ParameterMapping.class, ParameterMapping.Members.values());
}
@Override
public void fromJSON(JSONObject json_object, Database catalog_db) throws JSONException {
JSONUtil.fieldsFromJSON(json_object, catalog_db, this, ParameterMapping.class, ParameterMapping.Members.values());
// Hack for the column
if (this.statement_column == null) {
try {
this.statement_column = PlanNodeUtil.getColumnForStmtParameter(this.statement_parameter);
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
}
@Override
public String toString() {
return ("{" +
"Statement[" + CatalogUtil.getDisplayName(this.statement) + "-#" + String.format("%02d", this.statement_index) + "]," +
"StmtParameter[" + this.statement_parameter.getName() + "]," +
"ProcParameter[" + this.procedure_parameter.getName() + "-#" + String.format("%02d", this.procedure_parameter_index) + "]," +
"Coefficient[" + String.format("%.3g", this.coefficient) + "]" +
"}");
}
} // END CLASS