package com.alimama.mdrill.partion.thedate; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import java.util.Map.Entry; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.solr.common.SolrInputDocument; import com.alimama.mdrill.index.utils.JobIndexPublic; import com.alimama.mdrill.json.JSONArray; import com.alimama.mdrill.json.JSONException; import com.alimama.mdrill.json.JSONObject; import com.alimama.mdrill.partion.MdrillPartions; import com.alimama.mdrill.partion.MdrillPartionsInterface; import com.alimama.mdrill.partion.StatListenerInterface; import com.alimama.mdrill.ui.service.utils.OperateType; import com.alimama.mdrill.ui.service.utils.WebServiceParams; public class ThedatePartions implements MdrillPartionsInterface{ private String parttype="default"; public void setPartionType(String parttype) { this.parttype=parttype; } private SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); public String InsertPartion(SolrInputDocument doc) throws Exception{ String thedate=String.valueOf(doc.getFieldValue("thedate")); return ThedatePartionsUtils.parseDay(thedate, this.parttype); } @Override public String[] SqlPartions(String queryStr) throws Exception { HashSet<String> rtn = new HashSet<String>(); boolean isset = false; Long small = -1l; Long bigger = -1l; JSONArray jsonStr = new JSONArray(queryStr.trim()); for (int j = 0; j < jsonStr.length(); j++) { JSONObject obj = jsonStr.getJSONObject(j); if (obj.has("thedate")) { JSONObject thedate = obj.getJSONObject("thedate"); Integer operate = Integer.parseInt(thedate.get("operate").toString()); OperateType optype=WebServiceParams.parseOperateType(operate); String[] val = WebServiceParams.parseFqValue(thedate.getString("value"), operate).split(","); if (optype.equals(OperateType.eq)||optype.equals(OperateType.in)) { for (String day : val) { Date d = fmt.parse(day.replaceAll("-", "")); String[] partions = get(d.getTime(), d.getTime(), parttype); for (String partion : partions) { rtn.add(partion); isset = true; } } } if (optype.equals(OperateType.range))// =,range { Long min = Long.MAX_VALUE; Long max = Long.MIN_VALUE; for (String day : val) { Date d = fmt.parse(day.replaceAll("-", "")); Long time = d.getTime(); max = Math.max(max, time); min = Math.min(min, time); isset = true; } String[] partions = get(min, max, parttype); for (String partion : partions) { rtn.add(partion); } break; } if (optype.equals(OperateType.gt)||optype.equals(OperateType.gteq)) { for (String day : val) { Date d = fmt.parse(day.replaceAll("-", "")); Long time = d.getTime() + (operate == 3 ? 0 : 1); small = small > 0 ? Math.min(small, time) : time; } } if (optype.equals(OperateType.lg)||optype.equals(OperateType.lgeq)) { for (String day : val) { Date d = fmt.parse(day.replaceAll("-", "")); Long time = d.getTime() - (operate == 4 ? 0 : 1); bigger = bigger > 0 ? Math.max(bigger, time) : time; } } if (bigger > 0 && small > 0) { isset = true; String[] partions = get(small, bigger, parttype); for (String partion : partions) { rtn.add(partion); } small = Long.MAX_VALUE; bigger = Long.MIN_VALUE; break; } } } if (isset) { String[] rtnarr = new String[rtn.size()]; return rtn.toArray(rtnarr); } Long step = 1000l * 3600 * 24*30; Long max = 0l; Long initDate = (new Date()).getTime(); max = initDate; Long min = initDate - step; return get(min, max, parttype); } public String SqlFilter(String queryStr) throws Exception { return queryStr; // JSONArray rtn = new JSONArray(); // JSONArray jsonStr = new JSONArray(queryStr.trim()); // // for (int j = 0; j < jsonStr.length(); j++) { // JSONObject obj = jsonStr.getJSONObject(j); // if (!obj.has("thedate")) { // rtn.put(obj); // } // } // return rtn.toString(); } private String[] get(Long min,Long max,String parttype) throws JSONException, ParseException { Long step=1000l*3600*24; Long start=min; HashSet<String> list=new HashSet<String>(); SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); while(start<=max) { list.add(fmt.format(new Date(start))); start+=step; } HashMap<String,HashSet<String>> rtn=ThedatePartionsUtils.parseDays(list,parttype); Set<String> ks=rtn.keySet(); String[] rtnarr=new String[ks.size()]; return ks.toArray(rtnarr); } public StatListenerInterface getStatObj() throws Exception { StatListenerInterface rtn=new ThedateListener(); rtn.setPartionType(this.parttype); rtn.init(); return rtn; } private String getToday() { SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); return fmt.format(new Date()); } private String getMonth(String str) { return str.substring(0, 6); } private Date transDay(String str) throws ParseException { SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); return fmt.parse(str); } private String DatePlus(String str, int day) throws ParseException { SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); Date d = fmt.parse(str); Date pd = new Date(); pd.setTime(d.getTime() - 1000l * 3600 * 24 * day); return fmt.format(pd); } private String getStartDay( int delay,int maxRunDays, String starday) throws ParseException { String minday = this.DatePlus(this.getToday(), maxRunDays+delay); Date min = this.transDay(minday); Date start = this.transDay(starday); if(min.compareTo(start)>=0) { return minday; } return starday; } private HashSet<String> getNameList(FileSystem fs, String inputBase, String startPoint) throws IOException, ParseException { HashSet<String> rtn = new HashSet<String>(); Date start = this.transDay(startPoint); FileStatus[] list = fs.listStatus(new Path(inputBase)); if (list != null) { for (FileStatus f : list) { String name = f.getPath().getName().trim(); name = JobIndexPublic.parseThedate(name); if (name != null &&!name.isEmpty()&& this.transDay(name).compareTo(start) >= 0) { rtn.add(name); } } } return rtn; } public HashSet<String> getNameList(FileSystem fs,String inputBase,String startday,int dayDelay, int maxRunDays) throws Exception{ String startyyyymmddd=this.getStartDay(dayDelay, maxRunDays, startday); return getNameList(fs,inputBase,startyyyymmddd); } public HashMap<String,HashSet<String>> indexPartions(HashSet<String> namelist,String startday,int dayDelay, int maxRunDays) throws Exception{ return ThedatePartionsUtils.parseDays(namelist,this.parttype); } public String getUpdateFinishDay( int delay,String starday) throws ParseException { String minday = this.DatePlus(this.getToday(),delay); Date min = this.transDay(minday); Date start = this.transDay(starday); if(min.compareTo(start)>=0) { return minday; } return starday; } public HashMap<String,String> indexVertify(HashMap<String,HashSet<String>> partions,int shards,String startday,int dayDelay, int maxRunDays) throws Exception{ String upFinishyyyymmdd=this.getUpdateFinishDay(dayDelay,startday); HashMap<String,String> rtn=new HashMap<String,String>(); for(Entry<String,HashSet<String>> e:partions.entrySet()) { String partion=e.getKey(); HashSet<String> days=e.getValue(); boolean writeDay=false; for(String day:days) { if(day.compareTo(upFinishyyyymmdd)>=0) { writeDay=true; break; } } String partionvertify = "partionV"+MdrillPartions.PARTION_VERSION+"@001@"+partion + "@" + shards + "@"+ days.size()+"@"+days.hashCode(); if(writeDay) { partionvertify+="@"+this.getToday()+"@"+upFinishyyyymmdd; } rtn.put(partion, partionvertify); } return rtn; } @Override public String getDropComparePartion(long days) throws Exception { if(days<=0) { return null; } long dayms=1000l*3600*24; int index=0; while(true) { long before=System.currentTimeMillis()-(days+index)*dayms; long prev=System.currentTimeMillis()-(days+index)*dayms+dayms; String day=fmt.format(new Date(before)); String prevday=fmt.format(new Date(prev)); String p1=ThedatePartionsUtils.parseDay(day, this.parttype); String pprev=ThedatePartionsUtils.parseDay(prevday, this.parttype); if(!pprev.equals(p1)) { return p1; } index++; } // private SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); } @Override public boolean isAllowDropPartion(String partion, String cmp) throws Exception { if(cmp==null||partion==null) { return false; } return cmp.compareTo(partion)>=0; } }