HIVE内置函数hash() – 源码解析
在hash()值求解中,hive支持多类型,多参数的哈希值求解,那么底层是如何实现的?
首先HIVE提供的hash()内置函数的源码是怎么要求的?
hash内置函数在类中表明:
org.apache.hadoop.hive.ql.udf.generic.GenericUDFHash
一、initialize方法
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentTypeException {
argumentOIs = arguments;
return PrimitiveObjectInspectorFactory.writableIntObjectInspector;
}
在初始化参数的时候,并没有做任何的校验,直接返回了一个Int类型,所以在编译阶段是可以随意通过的,无论传入什么参数
二、evaluate方法
private final IntWritable result = new IntWritable();
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
Object[] fieldValues = new Object[arguments.length];
// 将参数取出
for(int i = 0; i < arguments.length; i++) {
fieldValues[i] = arguments[i].get();
}
int r = ObjectInspectorUtils.getBucketHashCode(fieldValues, argumentOIs);
result.set(r);
return result;
}
可以看到在处理阶段是可以传入多个参数的,也就是说hash()这个函数可以传入多个参数,其实最主要的处理方法是调用了ObjectInspectorUtils.getBucketHashCode(fieldValues, argumentOIs);
int r = ObjectInspectorUtils.getBucketHashCode(fieldValues, argumentOIs);
getBucketHashCode方法
点进去看一下这个方法是什么?
public static int getBucketHashCode(Object[] bucketFields, ObjectInspector[] bucketFieldInspectors) {
int hashCode = 0;
// 对传入的object,遍历调用hashCode方法
for(int i = 0; i < bucketFields.length; ++i) {
int fieldHash = hashCode(bucketFields[i], bucketFieldInspectors[i]);
hashCode = 31 * hashCode + fieldHash;
}