package com.alipay.bluewhale.core.task.group;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import backtype.storm.generated.Grouping;
import backtype.storm.generated.JavaObject;
import backtype.storm.grouping.CustomStreamGrouping;
import backtype.storm.tuple.Fields;
import backtype.storm.utils.Utils;
import com.alipay.bluewhale.core.thrift.GroupingConstants;
import com.alipay.bluewhale.core.thrift.Thrift;
import com.alipay.bluewhale.core.utils.RandomRange;
import com.alipay.bluewhale.core.utils.StormUtils;
/**
* ����grouper������һ��tuplesӦ�ñ����͵��Ǹ�task��������
*
* @author yannian
*
*/
public class MkGrouper {
private Fields out_fields;
private Grouping thrift_grouping;
private int num_tasks;
private Grouping._Fields fields;
private RandomRange randomrange;
private Random random;
private GrouperType grouptype;
private MkCustomGrouper custom_grouper;
private MkFieldsGrouper fields_grouper;
public MkGrouper(Fields _out_fields, Grouping _thrift_grouping,
int _num_tasks) {
this.out_fields = _out_fields;
this.thrift_grouping = _thrift_grouping;
this.num_tasks = _num_tasks;
this.fields = Thrift.groupingType(thrift_grouping);
this.grouptype = this.parseGroupType();
}
public GrouperType gettype() {
return grouptype;
}
private GrouperType parseGroupType() {
GrouperType grouperType = null;
if (GroupingConstants.fields.equals(fields)) {
// ȫ��group ������taskid=0��task���tuple
if (Thrift.isGlobalGrouping(thrift_grouping)) {
grouperType = GrouperType.global;
} else {
List<String> fields_group = Thrift.fieldGrouping(thrift_grouping);
Fields fields = new Fields(fields_group);
fields_grouper = new MkFieldsGrouper(out_fields, fields,num_tasks);
// ����fields��ֵ��hashcode����
grouperType = GrouperType.fields;
}
} else if (GroupingConstants.all.equals(fields)) {
// ÿ��task������
grouperType = GrouperType.all;
} else if (GroupingConstants.shuffle.equals(fields)) {
// ������䣬��none��ʵ�ַ�ʽ��ͬ���ǣ�����ıȽϾ���
this.randomrange = new RandomRange(num_tasks);
grouperType = GrouperType.shuffle;
} else if (GroupingConstants.none.equals(fields)) {
// ͨ������������ķ�ʽ����ȫ���
this.random = new Random();
grouperType = GrouperType.none;
} else if (GroupingConstants.custom_object.equals(fields)) {
// �û��Զ������
JavaObject jobj = thrift_grouping.get_custom_object();
CustomStreamGrouping g = Thrift.instantiateJavaObject(jobj);
custom_grouper = new MkCustomGrouper(g, out_fields, num_tasks);
grouperType = GrouperType.custom_obj;
} else if (GroupingConstants.custom_serialized.equals(fields)) {
// �û��Զ�������л�����ķ���
byte[] obj = thrift_grouping.get_custom_serialized();
CustomStreamGrouping g = (CustomStreamGrouping) Utils
.deserialize(obj);
custom_grouper = new MkCustomGrouper(g, out_fields, num_tasks);
grouperType = GrouperType.custom_serialized;
} else if (GroupingConstants.direct.equals(fields)) {
// ֱ�ӷ���-spout��bolt��ֱ��ָ����Ŀ��
grouperType = GrouperType.direct;
}
return grouperType;
}
// ���ص�ǰtupleӦ�ñ����͵���Щtask��ȥ
public List<Integer> grouper(List<Object> values) {
if (GrouperType.global.equals(gettype())) {
return StormUtils.mk_list(new Integer(0));
}
if (GrouperType.fields.equals(gettype())) {
// ����fields��ֵ��hashcode����
return fields_grouper.grouper(values);
}
// ÿ��task������
if (GrouperType.all.equals(gettype())) {
List<Integer> rtn = new ArrayList<Integer>();
for (int i = 0; i < num_tasks; i++) {
rtn.add(i);
}
return rtn;
}
// ������䣬��none��ʵ�ַ�ʽ��ͬ���ǣ�����ıȼ۾���
if (GrouperType.shuffle.equals(gettype())) {
int rnd = randomrange.nextInt();
return StormUtils.mk_list(new Integer(rnd));
}
// ͨ������������ķ�ʽ����ȫ���
if (GrouperType.none.equals(gettype())) {
int rnd = random.nextInt() % num_tasks;
return StormUtils.mk_list(new Integer(rnd));
}
// �û��Զ������
if (GrouperType.custom_obj.equals(gettype())) {
return custom_grouper.grouper(values);
}
// �û��Զ�������л�����ķ���
if (GrouperType.custom_serialized.equals(gettype())) {
return custom_grouper.grouper(values);
}
return new ArrayList<Integer>();
}
}