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. [codevs1105][COJ0183][NOIP2005]过河

    [codevs1105][COJ0183][NOIP2005]过河 试题描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青 ...

  2. 2016年11月28日--ADO.Net 查、插、删、改 小练习

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. MongoDB C Driver使用教程

    MongoDB C Driver使用教程 转载请注明出处http://www.cnblogs.com/oloroso/ 本指南提供简介 MongoDB C 驱动程序. 在 C API 的详细信息,请参 ...

  4. Alcatraz,

    今天重装Alcatraz,运行github上的命令后,安装成功,可是配置界面没出来. 无奈重装, 先删除原本的插件 rm -rf ~/Library/Application\ Support/Deve ...

  5. MySQL5.6 新特性之GTID

    背景: MySQL5.6在5.5的基础上增加了一些改进,本文章先对其中一个一个比较大的改进"GTID"进行说明. 概念: GTID即全局事务ID(global transactio ...

  6. mac下剪切文件或文件夹

    首先选中文件,按Command+C复制文件:然后按Command+Option+V:就可以把你的文件剪走了!

  7. 基于STM32和W5500的Modbus TCP通讯

    在最近的一个项目中需要实现Modbus TCP通讯,而选用的硬件平台则是STM32F103和W5500,软件平台则选用IAR EWAR6.4来实现. 1.移植千的准备工作 为了实现Modbus TCP ...

  8. (转: daifubing的博客 )Delphi二维码中文支持、分组、批量打印经验小结

    一直也没接触到什么复杂的报表,都是一些简单的报表,在DelphI下使用QuickReport一般也就能满足需要了,由于公司现在需求的变化,对条码扫描提出了新的要求,主要是扫码要包含更多地内容,以前的一 ...

  9. meta标签用法总结

    注:本文并非本人撰写,摘自百度百科 meta标签用来描述一个HTML网页文档的属性,例如作者.日期和时间.网页描述.关键词.页面刷新等. 一.作用:       META标签是HTML标记HEAD区的 ...

  10. Spring事务管理

    Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring的事务管理分为声明式跟编程式.声明式就是在Spring的配置文件中进行相关配置 ...