package org.apache.solr.request.compare;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.alimama.mdrill.distinct.DistinctCount;
import com.alimama.mdrill.distinct.DistinctCount.DistinctCountAutoAjuest;
import com.alimama.mdrill.utils.UniqConfig;
/**
* 用于记录groupby的每条记录以及统计值
* @author yannian.mu
*/
public class GroupbyRow implements Comparable<GroupbyRow>, GroupbyItem{
public Integer docidkey;//仅仅用于明细
private ColumnKey key;
public void setKey(ColumnKey key) {
this.key = key;
}
private long value;
private ArrayList<ArrayList<Double>> stat=new ArrayList<ArrayList<Double>>();
public ArrayList<DistinctCount> dist=new ArrayList<DistinctCount>();
private String[] crossFs;
private String[] distFS;
public void setCross(String[] crossFs,String[] distFS){
this.crossFs=crossFs;
this.distFS=distFS;
if(this.crossFs!=null)
{
int diff=this.crossFs.length-stat.size();
for(int i=diff;i>0;i--)
{
stat.add(new ArrayList<Double>(Arrays.asList(this.mkStat())));
}
}
if(this.distFS!=null)
{
int diff=this.distFS.length-dist.size();
for(int i=diff;i>0;i--)
{
dist.add(new DistinctCount());
}
}
}
public GroupbyRow() {
}
public void setDist(DistinctCountAutoAjuest autoDist)
{
if(dist!=null)
{
for(int i=0;i<dist.size();i++)
{
autoDist.put(Arrays.asList(this.key,new Integer(i)),dist.get(i));
}
}
}
public void removeDist(DistinctCountAutoAjuest autoDist)
{
if(dist!=null)
{
for(int i=0;i<dist.size();i++)
{
autoDist.remove(Arrays.asList(this.key,new Integer(i)));
}
}
}
public void ToCrcSet(MergerGroupByGroupbyRowCompare cmp,Map<Long,String> cache)
{
this.key.ToCrcSet(cmp,cache);
}
public GroupbyRow(ColumnKey key, Long value) {
this.key = key;
this.value = value;
}
public GroupbyRow(ArrayList<Object> nst)
{
this.key=new ColumnKey((ArrayList<Object>)nst.get(0));
ArrayList<byte[]> compress=(ArrayList<byte[]>) nst.get(2);
this.stat=(ArrayList<ArrayList<Double>>) nst.get(3);
this.value=(Long) nst.get(4);
int compresssize=compress.size();
this.dist=new ArrayList<DistinctCount>(compresssize);
for(int i=0;i<compresssize;i++)
{
DistinctCount dc=new DistinctCount(compress.get(i));
this.dist.add(dc);
}
}
public void shardsMerge(GroupbyItem o)
{
GroupbyRow instance=(GroupbyRow)o;
if (this.key == null ) {
this.key = instance.key;
}
this.value += instance.value;
this.mergeStat((GroupbyRow)o);
this.mergeDist((GroupbyRow)o);
}
private void mergeDist(GroupbyRow o)
{
int compresssize=o.dist.size();
for(int i=0;i<compresssize;i++)
{
DistinctCount vv =o.dist.get(i);
DistinctCount curr=this.dist.get(i);
curr.merge(vv);
}
}
private void mergeStat(GroupbyRow o)
{
int statsize=stat.size();
for(int field=0;field<statsize;field++)
{
ArrayList<Double> vv = o.stat.get(field);
int sz=vv.size();
for(int i=0;i<sz;i++)
{
this.addStat(field, i, vv.get(i));
}
}
}
public boolean isrecordcount(){
return false;
}
private Double[] mkStat()
{
return new Double[]{0d,0d,0d,0d,0d};
}
private String transKeyName(int i)
{
String keyname=null;
switch(i)
{
case 0:
{
keyname="dist";
break;
}
case 1:
{
keyname="sum";
break;
}
case 2:
{
keyname="max";
break;
}
case 3:
{
keyname="min";
break;
}
case 4:
{
keyname="cnt";
break;
}
}
return keyname;
}
public static HashMap<String,Integer> typeIndex=new HashMap<String, Integer>();
static{
typeIndex.put("sum", 1);
typeIndex.put("max", 2);
typeIndex.put("min", 3);
typeIndex.put("cnt", 4);
}
public double getStat(String field,String type)
{
ArrayList<Double> vv = this.stat.get(UniqTypeNum.foundIndex(this.crossFs, field));
return vv.get(typeIndex.get(type));
}
public double getDist(String field)
{
DistinctCount vv = this.dist.get(UniqTypeNum.foundIndex(this.distFS, field));
return vv.getValue();
}
public ArrayList<Object> toNamedList()
{
ArrayList<Object> rtn=new ArrayList<Object>();
ArrayList<byte[]> compress=new ArrayList<byte[]>();
for(int field=0;field<this.dist.size();field++)
{
DistinctCount vv =this.dist.get(field) ;
compress.add(field, vv.toBytes());
}
rtn.add(0, this.key.toNamedList());//"key"
rtn.add(1, 1);//"rc"
rtn.add(2,compress);//"dist"
rtn.add(3, this.stat);//"stat"
rtn.add(4,this.value);//"count"
return rtn;
}
public ColumnKey getKey() {
return key;
}
public double getStatVal(int field,int index)
{
return stat.get(field).get(index);
}
public void addStat(int field, int type, Double value) {
ArrayList<Double> w = stat.get(field);
Double lastValue = w.get(type);
Double cnt = w.get(4);
if(cnt<=0)
{
w.set(type,value);
return ;
}
switch(type)
{
case 1://sum
{
w.set(type, lastValue+value);
break;
}
case 2://max
{
w.set(type, Math.max(value, lastValue));
break;
}
case 3://min
{
w.set(type, Math.min(value, lastValue));
break;
}
case 4://cnt
{
w.set(type, lastValue+value);
break;
}
default:{
w.set(type,value);
break;
}
}
}
public void addDistinct(Integer field, DistinctCount value) {
DistinctCount w = dist.get(field);
w.merge(value);
}
public void setDistinct(Integer field, DistinctCount value) {
dist.set(field, value);
}
public Long getValue() {
return value;
}
@Override
public int compareTo(GroupbyRow o) {
return Double.compare(this.value, o.value);
}
/**
*
NamedList rtn=new NamedList();
rtn.add("count", value);
HashMap<String,ArrayList<Double>> finalResult=new HashMap<String, ArrayList<Double>>();
for(int field=0;field<this.dist.size();field++)
{
DistinctCount vv = this.dist.get(field);
ArrayList<Double> result=finalResult.get(this.distFS[field]);
if(result==null)
{
result=new ArrayList<Double>(Arrays.asList(this.mkStat()));
finalResult.put(this.distFS[field], result);
}
result.set(0, (double)vv.getValue());
}
for(int field=0;field<this.stat.size();field++)
{
ArrayList<Double> vv = this.stat.get(field);
ArrayList<Double> result=finalResult.get(this.crossFs[field]);
if(result==null)
{
result=new ArrayList<Double>(Arrays.asList(this.mkStat()));
finalResult.put(this.crossFs[field], result);
}
int size=Math.min(vv.size(), result.size());
for(int i=0;i<size;i++)
{
result.set(i, vv.get(i));
}
}
for(Entry<String,ArrayList<Double>> e:finalResult.entrySet())
{
String field = e.getKey();
ArrayList<Double> vv = e.getValue();
NamedList stat=new NamedList();
int sz=vv.size();
for(int i=0;i<sz;i++)
{
String keyname=transKeyName(i);
if(keyname!=null)
{
stat.add(keyname, vv.get(i));
}
}
rtn.add(field, stat);
}
return rtn;
*/
}