package org.apache.hadoop.hive.mastiff;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.metastore.HiveMetaHook;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hadoop.hive.ql.index.IndexSearchCondition;
import org.apache.hadoop.hive.ql.metadata.DefaultStorageHandler;
import org.apache.hadoop.hive.ql.metadata.HiveStoragePredicateHandler;
import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
import org.apache.hadoop.hive.ql.plan.TableDesc;
import org.apache.hadoop.hive.serde2.Deserializer;
import org.apache.hadoop.hive.serde2.SerDe;
import org.apache.hadoop.mapred.InputFormat;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.OutputFormat;
/**
*
* MastiffStorageHandler provides a HiveStorageHandler implementation for
* Segment File
*
*/
public class MastiffStorageHandler extends DefaultStorageHandler implements
HiveStoragePredicateHandler, HiveMetaHook {
public static Log LOG = LogFactory.getLog(MastiffStorageHandler.class);
private Configuration conf;
private String mastiffMetastoreIp = null;
private MastiffMetastoreClient mmclient = null;
@Override
public Class<? extends InputFormat> getInputFormatClass() {
return SegmentFileInputFormat.class;
}
@Override
public Class<? extends OutputFormat> getOutputFormatClass() {
return SegmentFileOutputFormat.class;
}
@Override
public Class<? extends SerDe> getSerDeClass() {
return MastiffSerDe.class;
}
@Override
public void configureInputJobProperties(TableDesc tableDesc,
Map<String, String> jobProperties) {
configureTableJobProperties(tableDesc, jobProperties);
}
@Override
public void configureOutputJobProperties(TableDesc tableDesc,
Map<String, String> jobProperties) {
configureTableJobProperties(tableDesc, jobProperties);
}
@Override
public void configureTableJobProperties(TableDesc tableDesc,
Map<String, String> jobProperties) {
Properties tableProperties = tableDesc.getProperties();
String tblName = tableProperties.getProperty("name");
jobProperties.put(MastiffHandlerUtil.CF_TABLE_NAME, tblName);
}
/**
* In order to user filter in building ScanMap and record filter at record level,
* we need filter passed into InputFormat as well as recordReader
*/
@Override
public DecomposedPredicate decomposePredicate(JobConf jobConf, Deserializer deserializer,
ExprNodeDesc predicate) {
MastiffIndexPredicateAnalyzer analyzer = new MastiffIndexPredicateAnalyzer();
List<IndexSearchCondition> searchConditions = new ArrayList<IndexSearchCondition>();
ExprNodeDesc residualPredicate = analyzer.analyzePredicate(predicate, searchConditions);
DecomposedPredicate decomposedPredicate = new DecomposedPredicate();
decomposedPredicate.pushedPredicate = analyzer.translateSearchConditions(searchConditions);
decomposedPredicate.residualPredicate = residualPredicate;
return decomposedPredicate;
}
@Override
public HiveMetaHook getMetaHook() {
return this;
}
@Override
public void preCreateTable(Table table) throws MetaException {
init_mms();
Hashtable meta = mmclient.getMetadata(table.getTableName());
if (meta != null) {
throw new MetaException("Table with name:" + table.getTableName() + " already exist");
}
}
@Override
public void rollbackCreateTable(Table table) throws MetaException {
// TODO Auto-generated method stub
}
@Override
public void commitCreateTable(Table table) throws MetaException {
init_mms();
String tableName = table.getTableName();
Map<String, String> serdeInfoParams = table.getSd().getSerdeInfo().getParameters();
String columnmap = serdeInfoParams.get(MastiffHandlerUtil.CF_COLUMN_MAPPING);
String codingtype = serdeInfoParams.get(MastiffHandlerUtil.CF_CODING);
String algorithm = serdeInfoParams.get(MastiffHandlerUtil.CF_ALGO);
if (columnmap == null || codingtype == null || algorithm == null) {
throw new MetaException("Mastiff Metadata incomplete");
}
boolean succ = mmclient.create_mmtable(tableName, columnmap, algorithm, codingtype);
if (!succ) {
throw new MetaException("Fail to insert metadata into mastiff metastore");
}
}
@Override
public void preDropTable(Table table) throws MetaException {
// TODO Auto-generated method stub
}
@Override
public void rollbackDropTable(Table table) throws MetaException {
// TODO Auto-generated method stub
}
@Override
public void commitDropTable(Table table, boolean deleteData) throws MetaException {
init_mms();
String tableName = table.getTableName();
mmclient.delete_mmtable(tableName);
}
public void init_mms() throws MetaException {
if (mastiffMetastoreIp == null) {
mastiffMetastoreIp = conf.get("mastiff.metastore.ip");
}
if (mastiffMetastoreIp == null) {
throw new MetaException("Mastiff Metastore ip not set in hive-site.xml");
}
if (mmclient == null) {
mmclient = new MastiffMetastoreClient(mastiffMetastoreIp);
}
}
@Override
public Configuration getConf() {
return conf;
}
@Override
public void setConf(Configuration conf) {
this.conf = conf;
}
}