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; */ }