package org.apache.hadoop.hive.ql.plan.mapper;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import org.apache.hadoop.hive.ql.exec.Operator;
import org.apache.hadoop.hive.ql.optimizer.signature.OpTreeSignature;
import org.apache.hadoop.hive.ql.optimizer.signature.OpTreeSignatureFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
public class PlanMapper {
Set groups = new HashSet<>();
private Map
我们开始解析剩余代码。
方法add
public void add(Object o) {
if (members.contains(o)) {
return;
}
members.add(o);
objectMap.put(o, this);
}
members.contains()这是什么方法?那么我们首先来看members是一个什么变量。我们看类EquivGroup内部的全局变量定义,找到了关于members变量的定义: Set members = new HashSet<>(); 那么我们就需要寻找Set是否有一个叫contains的方法了。当然,我们不需要急着去网上搜寻,我们先浏览下文看看这是否是一个内部定义的方法。浏览后发现并没有包含该方法,我们从网上搜寻后得到如下信息:Java 集合类中的 Set.contains() 方法判断 Set 集合是否包含指定的对象。该方法返回值为 boolean 类型,如果 Set 集合包含指定的对象,则返回 true,否则返回 false。其调用语法为:contains(Object o),其中o是要进行查询的对象,可以为任意的类型。我们不妨看一个例子来理解该方法:
public static void main(String[] args){
Set set = new HashSet();
set.add(new Date());
set.add("apple");
set.add(new Socket());
boolean contains = set.contains("apple");
if(contains){
System.out.println("Set集合包含字符串apple");
}else{
System.out.println("Set集合不包含字符串apple");
}
}
我们接着往后看,这个objectMap是什么东西?我们猜测这是一个全局变量,于是我们从文件开头往下寻找,找到了关于这个变量的定义: private Map objectMap = new CompositeMap<>(OpTreeSignature.class); 那么objectMap.put(o,this)方法是什么?这就是Map类自带的put方法,需要传入一个key和一个value。而key显而易见是o,那么this是什么?我们查阅资料得知:把this作为参数传递。当你要把自己作为参数传递给别的对象时,也可以用this。例如下面的例子:
public class A{
public A(){
new B(this).print();
}
public void print(){
System.out.println("From A!");
}
public static void main(String[] args) {
new A();
}
}
public class B{
A a;
public B(A a){
this.a = a;
}
public void print(){
a.print();
System.out.println("From B!");
}
}
@SuppressWarnings("unchecked")
public List getAll(Class clazz) {
List ret = new ArrayList<>();
for (Object m : members) {
if (clazz.isInstance(m)) {
ret.add((T) m);
}
}
return ret;
}
我们先来看一下Class.isInstance是什么一个方法。首先,我们先要知道什么是instanceof关键字:instanceof 关键字用于判断某个实例是否是某个类的实例化对象,形如: String.class instanceof Class 和 "test" instanceof String 那么,知道了instance是啥,isInstance()方法也就知道了:isInstance是Class类中的方法,也是用于判断某个实例是否是某个类的实例化对象,但是指向则相反。但这样就带来一个疑问,为什么我们需要这个方法呢,官方文档如此解释:
Determines if the specified Object is assignment-compatible with the object represented by this Class.
This method is the dynamic equivalent of the Java language instanceof operator.
The method returns true if the specified Object argument is non-null
and can be cast to the reference type represented by this Class object without raising a ClassCastException.
It returns false otherwise.
public static void main(String[] args){
Listlist = new ArrayList();
list.add("保护环境"); //向列表中添加数据
list.add("爱护地球"); //向列表中添加数据
list.add("从我做起"); //向列表中添加数据
list.add(1,"从我做起"); //在第1+1个元素的位置添加数据
Listlist_ad = new ArrayList();
list_ad.add("公益广告"); //将list中的全部元素添加到list_ad中
System.out.println("是否添加成功:"+list_ad.addAll(list)); //通过循环输出列表中的内容
for(int i=0;i
输出
是否添加成功:true
0:公益广告
1:保护环境
2:从我做起
3:爱护地球
4:从我做起
我们先来看看groups是一个什么东西。我们在上面已经说过了,它是一个集合,里面的元素类型为EquivGroup。那么这个EquivGroup是什么东西呢?我们在Apache官网API接口上找到了关于这个类的详细信息: A set of objects which are representing the same thing. A Group may contain different kind of things which are connected by their purpose; For example currently a group may contain the following objects:
Operator(s) - which are doing the actual work; there might be more than one, since an optimization may replace an operator with a new one
Signature - to enable inter-plan look up of the same data
public List lookupAll(Class clazz, Object key) {
EquivGroup group = objectMap.get(key);
if (group == null) {
throw new NoSuchElementException(Objects.toString(key));
}
return group.getAll(clazz);
}
public T lookup(Class clazz, Object key) {
List all = lookupAll(clazz, key);
if (all.size() != 1) {
// FIXME: use a different exception type?
throw new IllegalArgumentException("Expected match count is 1; but got:" + all);
}
return all.get(0);
}