UDAF: 多进一出

GenericUDAFEvaluator : 就是根据job的不同阶段执行不同的方法
Hive通过GenericUDAFEvaluator.Modle来确定job的执行阶段
PARTIAL1: 从原始数据到部分聚合,调用方法iterate和terminatePartial方法
PARTIAL2: 从部分数据聚合到部分数据聚合,会调用merge和terminatePartial
FINAL: 从部分数据聚合到全部数据聚合,会调用merge和terminate
COMPLETE: 从原始数据全部聚合,会调用方法iterate和terminate
除了上面提到的iterate,merge,terminatePartial以外,还有init(初始化并返回,返回值的类型)
getNewAggregationBuffer(获取新的buffer,也就是方法间传递参数的对象),reset(重置buffer对象)
需求: 实现一个自定义的sum函数,要求韩函数支持整型和浮点型的sum操作

简单示例,重写SUM函数

package com.hive.udaf;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.parse.SemanticException;
import org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFParameterInfo;
import org.apache.hadoop.hive.serde2.io.DoubleWritable;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.AbstractPrimitiveWritableObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
import org.apache.hadoop.io.LongWritable; /**
* @author liuwl
* mysum support float & double
*/
public class mysum extends AbstractGenericUDAFResolver{   public GenericUDAFEvaluator getEvaluator(GenericUDAFParameterInfo info) throws SemanticException { // parameters is all clomuns
if(info.isAllColumns()){
  throw new SemanticException("this function is not support all parameters");
}
// only one clomun parameter
ObjectInspector[] inspectors = info.getParameterObjectInspectors();
if(inspectors.length != 1){
  throw new SemanticException("the parameters is only one clomun");
}
if(inspectors[0].getCategory() != ObjectInspector.Category.PRIMITIVE){
  throw new SemanticException("the parameters must be Basic data types");
}
// input parameter's Category
AbstractPrimitiveWritableObjectInspector woi = (AbstractPrimitiveWritableObjectInspector)inspectors[0];
switch (woi.getPrimitiveCategory()) {
  case INT:
  case LONG:
  case BYTE:
  case SHORT:
    return new udafLong();
  case FLOAT:
  case DOUBLE:
    return new udafDouble();
  default:
    throw new SemanticException("the parameter's Category is not support");
}
  }   /**
  * sum the long data
  */
  public static class udafLong extends GenericUDAFEvaluator{     // define data Category
    public PrimitiveObjectInspector longInputor;     static class sumlongagg implements AggregationBuffer{
      long sum;
      boolean empty;
    }     @Override
    public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {       super.init(m, parameters);
      if(parameters.length!=1){
        throw new UDFArgumentException("Argument Exception");
      }
      if(this.longInputor == null){
        this.longInputor=(PrimitiveObjectInspector)parameters[0];
      }
      return PrimitiveObjectInspectorFactory.writableLongObjectInspector;
    }     @Override
    public AggregationBuffer getNewAggregationBuffer() throws HiveException {       sumlongagg slg = new sumlongagg();
      this.reset(slg);
      return slg;
    }     @Override
    public void reset(AggregationBuffer agg) throws HiveException {       sumlongagg slg = (sumlongagg)agg;
      slg.sum = 0;
      slg.empty = true;
    }     @Override
    public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {       if(parameters.length !=1 ){
        throw new UDFArgumentException("Argument Exception");
      }
      this.merge(agg, parameters[0]);
    }     @Override
    public Object terminatePartial(AggregationBuffer agg) throws HiveException {
      return this.terminate(agg);
    }     @Override
    public void merge(AggregationBuffer agg, Object partial) throws HiveException {       sumlongagg slg = (sumlongagg)agg;
      if(partial != null){
        slg.sum += PrimitiveObjectInspectorUtils.getLong(partial, longInputor);
        slg.empty = false;
      }
    }     @Override
    public Object terminate(AggregationBuffer agg) throws HiveException {       sumlongagg slg = (sumlongagg)agg;
      if(slg.empty){
        return null;
      }
      return new LongWritable(slg.sum);
    }   }   /**
  * sum the double data
  */
  public static class udafDouble extends GenericUDAFEvaluator{     // define data Category
    public PrimitiveObjectInspector doubleInputor;       static class sumdoubleagg implements AggregationBuffer{
        double sum;
        boolean empty;
      }
    @Override
    public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {       super.init(m, parameters);
      if(parameters.length!=1){
        throw new UDFArgumentException("Argument Exception");
      }
      if(this.doubleInputor == null){
        this.doubleInputor=(PrimitiveObjectInspector)parameters[0];
      }
      return PrimitiveObjectInspectorFactory.writableDoubleObjectInspector; }     @Override
    public AggregationBuffer getNewAggregationBuffer() throws HiveException {       sumdoubleagg sdg = new sumdoubleagg();
        this.reset(sdg);
        return sdg;
      }     @Override
    public void reset(AggregationBuffer agg) throws HiveException {       sumdoubleagg sdg = (sumdoubleagg)agg;
      sdg.sum = 0;
      sdg.empty = true;
    }     @Override
    public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {       if(parameters.length !=1 ){
        throw new UDFArgumentException("Argument Exception");
      }
      this.merge(agg, parameters[0]);
    }     @Override
    public Object terminatePartial(AggregationBuffer agg) throws HiveException {
      return this.terminate(agg);
    }     @Override
    public void merge(AggregationBuffer agg, Object partial) throws HiveException {       sumdoubleagg sdg = (sumdoubleagg)agg;
      if(partial != null){
        sdg.sum += PrimitiveObjectInspectorUtils.getDouble(partial, doubleInputor);
        sdg.empty = false;
      }
    }     @Override
    public Object terminate(AggregationBuffer agg) throws HiveException {       sumdoubleagg sdg = (sumdoubleagg)agg;
      if(sdg.empty){
        return null;
      }
      return new DoubleWritable(sdg.sum);
    }
  }
}

测试

hive (workdb)> add jar /home/liuwl/opt/datas/mysum.jar;
hive (workdb)> create temporary function mysum as 'com.hive.udaf.mysum';
hive (workdb)> select sum(deptno),mysum(deptno) from emp;
结果: _c0  _c1
310  310

Hadoop_UDAF示例的更多相关文章

  1. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  2. .NET跨平台之旅:将示例站点升级至 ASP.NET Core 1.1

    微软今天在 Connect(); // 2016 上发布了 .NET Core 1.1 ,ASP.NET Core 1.1 以及 Entity Framework Core 1.1.紧跟这次发布,我们 ...

  3. 通过Jexus 部署 dotnetcore版本MusicStore 示例程序

    ASPNET Music Store application 是一个展示最新的.NET 平台(包括.NET Core/Mono等)上使用MVC 和Entity Framework的示例程序,本文将展示 ...

  4. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  5. JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

  6. XAMARIN ANDROID 二维码扫描示例

    现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile  做一个简单的 Android 条码扫描示 ...

  7. iOS之ProtocolBuffer搭建和示例demo

    这次搭建iOS的ProtocolBuffer编译器和把*.proto源文件编译成*.pbobjc.h 和 *.pbobjc.m文件时,碰到不少问题! 搭建pb编译器到时没有什么问题,只是在把*.pro ...

  8. Android种使用Notification实现通知管理以及自定义通知栏(Notification示例四)

    示例一:实现通知栏管理 当针对相同类型的事件多次发出通知,作为开发者,应该避免使用全新的通知,这时就应该考虑更新之前通知栏的一些值来达到提醒用户的目的.例如我们手机的短信系统,当不断有新消息传来时,我 ...

  9. oracle常用函数及示例

    学习oracle也有一段时间了,发现oracle中的函数好多,对于做后台的程序猿来说,大把大把的时间还要学习很多其他的新东西,再把这些函数也都记住是不太现实的,所以总结了一下oracle中的一些常用函 ...

随机推荐

  1. ML 基础知识

    A computer program is said to learn from experience E with respect to some task T and some performan ...

  2. PHP大数(浮点数)取余

    一般我们进行取余运算第一个想到的就是用百分号%,但当除数是个很大的数值,超出了int范围时,这样取余就不准确了. php大数(浮点数)取余函数 /** * php大数取余 * * @param int ...

  3. js导出表格数据

    考虑到浏览器兼容性问题,采用原生js和后台交互下载网页数据 js: var table = $('.table-panel table'); // Header var tdData ="& ...

  4. 【Android自学日记】搭建Android开发环境

    搭建Android应用开发环境所需工具 1_> JDK(JAVA Development)推荐使用6.0以后版本 配置环境变量(以下是环境变量的具体内容及介绍) ================ ...

  5. error 502 in ngin php5-fpm

    unix:/var/run/php5-fpm.sock failed (11: Resource temporarily unavailable) http://stackoverflow.com/q ...

  6. Android 如何在 ListView 中更新 ProgressBar 进度

    =======================ListView原理============================== Android 的 ListView 的原理打个简单的比喻就是: 演员演 ...

  7. render()方法是render_to_response

    自django1.3开始:render()方法是render_to_response的一个崭新的快捷方式, 前者会自动使用 RequestContext.而后者必须coding 出来,这是最明显的区别 ...

  8. 文本框value联动修改

    <input id="ipt-edit" value="" /><input id="ipt-target" value= ...

  9. Droidbox恶意软件动态分析环境搭建

    @author : Dlive 0x01 DroidBox简介 DroidBox是一款,可以获得以下信息 1.APK包hash值 2.网络通信数据 3.文件读写操作 4.网络通信,文件读写,SMS中的 ...

  10. Python 开发轻量级爬虫08

    Python 开发轻量级爬虫 (imooc总结08--爬虫实例--分析目标) 怎么开发一个爬虫?开发一个爬虫包含哪些步骤呢? 1.确定要抓取得目标,即抓取哪些网站的哪些网页的哪部分数据. 本实例确定抓 ...