PageRenderTime 28ms CodeModel.GetById 12ms app.highlight 11ms RepoModel.GetById 2ms app.codeStats 0ms

/tags/release-0.0.0-rc0/hive/external/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFBridge.java

#
Java | 193 lines | 129 code | 33 blank | 31 comment | 15 complexity | 995d5102640b898956c43dac390687e1 MD5 | raw file
  1/**
  2 * Licensed to the Apache Software Foundation (ASF) under one
  3 * or more contributor license agreements.  See the NOTICE file
  4 * distributed with this work for additional information
  5 * regarding copyright ownership.  The ASF licenses this file
  6 * to you under the Apache License, Version 2.0 (the
  7 * "License"); you may not use this file except in compliance
  8 * with the License.  You may obtain a copy of the License at
  9 *
 10 *     http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing, software
 13 * distributed under the License is distributed on an "AS IS" BASIS,
 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18package org.apache.hadoop.hive.ql.udf.generic;
 19
 20import java.io.Serializable;
 21import java.lang.reflect.Method;
 22import java.lang.reflect.Type;
 23import java.util.Arrays;
 24
 25import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
 26import org.apache.hadoop.hive.ql.exec.UDAF;
 27import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
 28import org.apache.hadoop.hive.ql.metadata.HiveException;
 29import org.apache.hadoop.hive.ql.parse.SemanticException;
 30import org.apache.hadoop.hive.ql.udf.generic.GenericUDFUtils.ConversionHelper;
 31import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 32import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
 33import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory.ObjectInspectorOptions;
 34import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
 35import org.apache.hadoop.util.ReflectionUtils;
 36
 37/**
 38 * This class is a bridge between GenericUDAF and UDAF. Old UDAF can be used
 39 * with the GenericUDAF infrastructure through this bridge.
 40 */
 41public class GenericUDAFBridge extends AbstractGenericUDAFResolver {
 42
 43  UDAF udaf;
 44
 45  public GenericUDAFBridge(UDAF udaf) {
 46    this.udaf = udaf;
 47  }
 48
 49  public Class<? extends UDAF> getUDAFClass() {
 50    return udaf.getClass();
 51  }
 52
 53  @Override
 54  public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) throws SemanticException {
 55
 56    Class<? extends UDAFEvaluator> udafEvaluatorClass = udaf.getResolver()
 57        .getEvaluatorClass(Arrays.asList(parameters));
 58
 59    return new GenericUDAFBridgeEvaluator(udafEvaluatorClass);
 60  }
 61
 62  /**
 63   * GenericUDAFBridgeEvaluator.
 64   *
 65   */
 66  public static class GenericUDAFBridgeEvaluator extends GenericUDAFEvaluator
 67      implements Serializable {
 68
 69    private static final long serialVersionUID = 1L;
 70
 71    // Used by serialization only
 72    public GenericUDAFBridgeEvaluator() {
 73    }
 74
 75    public Class<? extends UDAFEvaluator> getUdafEvaluator() {
 76      return udafEvaluator;
 77    }
 78
 79    public void setUdafEvaluator(Class<? extends UDAFEvaluator> udafEvaluator) {
 80      this.udafEvaluator = udafEvaluator;
 81    }
 82
 83    public GenericUDAFBridgeEvaluator(
 84        Class<? extends UDAFEvaluator> udafEvaluator) {
 85      this.udafEvaluator = udafEvaluator;
 86    }
 87
 88    Class<? extends UDAFEvaluator> udafEvaluator;
 89
 90    transient ObjectInspector[] parameterOIs;
 91    transient Object result;
 92
 93    transient Method iterateMethod;
 94    transient Method mergeMethod;
 95    transient Method terminatePartialMethod;
 96    transient Method terminateMethod;
 97
 98    transient ConversionHelper conversionHelper;
 99
100    @Override
101    public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {
102      super.init(m, parameters);
103      parameterOIs = parameters;
104
105      // Get the reflection methods from ue
106      for (Method method : udafEvaluator.getMethods()) {
107        method.setAccessible(true);
108        if (method.getName().equals("iterate")) {
109          iterateMethod = method;
110        }
111        if (method.getName().equals("merge")) {
112          mergeMethod = method;
113        }
114        if (method.getName().equals("terminatePartial")) {
115          terminatePartialMethod = method;
116        }
117        if (method.getName().equals("terminate")) {
118          terminateMethod = method;
119        }
120      }
121
122      // Input: do Java/Writable conversion if needed
123      Method aggregateMethod = null;
124      if (mode == Mode.PARTIAL1 || mode == Mode.COMPLETE) {
125        aggregateMethod = iterateMethod;
126      } else {
127        aggregateMethod = mergeMethod;
128      }
129      conversionHelper = new ConversionHelper(aggregateMethod, parameters);
130
131      // Output: get the evaluate method
132      Method evaluateMethod = null;
133      if (mode == Mode.PARTIAL1 || mode == Mode.PARTIAL2) {
134        evaluateMethod = terminatePartialMethod;
135      } else {
136        evaluateMethod = terminateMethod;
137      }
138      // Get the output ObjectInspector from the return type.
139      Type returnType = evaluateMethod.getGenericReturnType();
140      try {
141        return ObjectInspectorFactory.getReflectionObjectInspector(returnType,
142            ObjectInspectorOptions.JAVA);
143      } catch (RuntimeException e) {
144        throw new HiveException("Cannot recognize return type " + returnType
145            + " from " + evaluateMethod, e);
146      }
147    }
148
149    /** class for storing UDAFEvaluator value. */
150    static class UDAFAgg implements AggregationBuffer {
151      UDAFEvaluator ueObject;
152
153      UDAFAgg(UDAFEvaluator ueObject) {
154        this.ueObject = ueObject;
155      }
156    }
157
158    @Override
159    public AggregationBuffer getNewAggregationBuffer() {
160      return new UDAFAgg((UDAFEvaluator)ReflectionUtils.newInstance(udafEvaluator, null));
161    }
162
163    @Override
164    public void reset(AggregationBuffer agg) throws HiveException {
165      ((UDAFAgg) agg).ueObject.init();
166    }
167
168    @Override
169    public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {
170      FunctionRegistry.invoke(iterateMethod, ((UDAFAgg) agg).ueObject,
171          conversionHelper.convertIfNecessary(parameters));
172    }
173
174    @Override
175    public void merge(AggregationBuffer agg, Object partial) throws HiveException {
176      FunctionRegistry.invoke(mergeMethod, ((UDAFAgg) agg).ueObject,
177          conversionHelper.convertIfNecessary(partial));
178    }
179
180    @Override
181    public Object terminate(AggregationBuffer agg) throws HiveException {
182      return FunctionRegistry.invoke(terminateMethod, ((UDAFAgg) agg).ueObject);
183    }
184
185    @Override
186    public Object terminatePartial(AggregationBuffer agg) throws HiveException {
187      return FunctionRegistry.invoke(terminatePartialMethod,
188          ((UDAFAgg) agg).ueObject);
189    }
190
191  }
192
193}