content: package com.alimama.mdrill.partion.thedate;
  
  import java.net.MalformedURLException;
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map.Entry;
  import java.util.concurrent.atomic.AtomicInteger;
  
  import org.apache.log4j.Logger;
  import org.apache.solr.client.solrj.SolrServerException;
  
  import com.alimama.mdrill.json.JSONException;
  import com.alimama.mdrill.partion.PartionListener;
  import com.alimama.mdrill.partion.GetPartions.*;
  import com.alimama.mdrill.topology.SolrStartJetty;
  import com.alipay.bluewhale.core.cluster.SolrInfo;
  import com.alipay.bluewhale.core.cluster.SolrInfo.ShardCount;
  public class ThedateListener extends PartionListener{
  
  	private HashMap<String, String> dayPartions=new HashMap<String, String>();
  	private HashMap<String, ShardCount> daycount = new HashMap<String, ShardCount>();
  	private AtomicInteger lastDayIndex = new AtomicInteger(0);
  
  	
  	private String smallestPartion=null;
  	private HashMap<String, ShardCount> smallest = new HashMap<String, ShardCount>();
  	private AtomicInteger lastsmallDayIndex = new AtomicInteger(0);
  
  	private String biggestPartion=null;
  	private HashMap<String, ShardCount> biggest = new HashMap<String, ShardCount>();
  	private AtomicInteger lastbigDayIndex = new AtomicInteger(0);
  
  	private void requestDaycount(SolrStartJetty solrservice,String tablename) throws MalformedURLException, SolrServerException
  	{
  		ArrayList<String> toremove=new ArrayList<String>();
  		for(String strday:this.daycount.keySet())
  		{
  			if(!dayPartions.containsKey(strday))
      		{
  				toremove.add(strday);
      		}
  		}
  		
  		for(String rmday:toremove)
  		{
  			this.daycount.remove(rmday);
  		}
  		
  		int loopcount=1;
  		if(this.daycount.size()<=1)
  		{
  			loopcount=7;
  		}
  		
  		
  		for(int i=0;i<loopcount;i++)
  		{
  			if(i>0)
  			{
  				try {
  					Thread.sleep(100);
  				} catch (InterruptedException e) {}
  			}
      		int index = lastDayIndex.incrementAndGet();
      		if (index >= 7) {
      			index = 0;
      			lastDayIndex.set(0);
      			index=lastDayIndex.get();
      		}
      		
      		long dayl=System.currentTimeMillis()-1000l*3600*24*index;
      		SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
      		String strday=fmt.format(new Date(dayl));
      		if(dayPartions.containsKey(strday))
      		{
      			String part=dayPartions.get(strday);
      			if(this.containsTablePartion(part))
      			{
      				long cnt = solrservice.checkSolr(tablename, part,strday);
      				this.daycount.put(strday, new ShardCount(cnt));
      			}
      		}
  		}
  	}
  	
  	private void requestSmallest(SolrStartJetty solrservice,String tablename,TablePartion part) throws MalformedURLException, SolrServerException
  	{
  		if(this.smallestPartion==null)
  		{
  			return ;
  		}
  		
  		ArrayList<String> toremove=new ArrayList<String>();
  
  		HashSet<String> smallestdays=ThedatePartionsUtils.partion2Days(smallestPartion, part.parttype);
  		String[] smallestdaysarr=smallestdays.toArray(new String[smallestdays.size()]);
  		Arrays.sort(smallestdaysarr);
  		toremove.clear();
  		for(String strday:this.smallest.keySet())
  		{
  			if(!smallestdays.contains(strday))
      		{
  				toremove.add(strday);
      		}
  		}
  		
  		for(String rmday:toremove)
  		{
  			this.smallest.remove(rmday);
  		}
  		
  		
  		int smallloopcnt=1;
  		if(this.smallest.size()<1)
  		{
  			smallloopcnt=smallestdaysarr.length;
  		}
  		
  		for(int i=0;i<smallloopcnt;i++)
  		{
  			if(i>0)
  			{
  				try {
  					Thread.sleep(100);
  				} catch (InterruptedException e) {}
  			}
      		int index = lastsmallDayIndex.incrementAndGet();
      		if (index >= smallestdaysarr.length) {
      			index = 0;
      			lastsmallDayIndex.set(0);
      		}
      		String strday=smallestdaysarr[index];
      		long cnt = solrservice.checkSolr(tablename, smallestPartion,strday);
  			this.smallest.put(strday, new ShardCount(cnt));
  		}
  	}
  	
  	private void requestBiggest(SolrStartJetty solrservice,String tablename,TablePartion part) throws MalformedURLException, SolrServerException
  	{
  		if(this.biggestPartion==null)
  		{
  			return ;
  		}
  		
  		ArrayList<String> toremove=new ArrayList<String>();
  
  		HashSet<String> biggestestdays=ThedatePartionsUtils.partion2Days(biggestPartion, part.parttype);
  		String[] biggestestdaysarr=biggestestdays.toArray(new String[biggestestdays.size()]);
  		Arrays.sort(biggestestdaysarr);
  		toremove.clear();
  		for(String strday:this.biggest.keySet())
  		{
  			if(!biggestestdays.contains(strday))
      		{
  				toremove.add(strday);
      		}
  		}
  		
  		for(String rmday:toremove)
  		{
  			this.biggest.remove(rmday);
  		}
  		
  		
  		int smallloopcnt=1;
  		if(this.biggest.size()<1)
  		{
  			smallloopcnt=biggestestdaysarr.length;
  		}
  		
  		for(int i=0;i<smallloopcnt;i++)
  		{
  			if(i>0)
  			{
  				try {
  					Thread.sleep(100);
  				} catch (InterruptedException e) {}
  			}
      		int index = lastbigDayIndex.incrementAndGet();
      		if (index >= biggestestdaysarr.length) {
      			index = 0;
      			lastbigDayIndex.set(0);
      		}
      		String strday=biggestestdaysarr[index];
      		long cnt = solrservice.checkSolr(tablename, biggestPartion,strday);
  			this.biggest.put(strday, new ShardCount(cnt));
  		}
  	}
  		
  	public void fetchCount(SolrStartJetty solrservice,String tablename,TablePartion part) throws MalformedURLException, SolrServerException
  	{
  		super.fetchCount(solrservice, tablename, part);
  		
  		if(ThedatePartionsUtils.canUsedThedate(part.parttype))
  		{
  			this.requestDaycount(solrservice,tablename);
  			this.requestSmallest(solrservice,tablename,part);
  			this.requestBiggest(solrservice, tablename, part);
  		}
  	}
  	
  	public void syncClearPartions()
  	{
  		super.syncClearPartions();
  		smallestPartion=null;
  		biggestPartion=null;
  	
  	}
  	public void addPartionStat(String partion)
  	{
  		super.addPartionStat(partion);
  		if(smallestPartion==null||partion.compareTo(smallestPartion)<=0)
  		{
  			smallestPartion=partion;
  		}
  		if(biggestPartion==null||partion.compareTo(biggestPartion)>=0)
  		{
  			biggestPartion=partion;
  		}
  	}
  	
  	public void syncClearStat()
  	{
  		super.syncClearStat();
  		long now=System.currentTimeMillis();
  		dayPartions.clear();
  		try {
  
  			 HashMap<String, HashSet<String>> w=dayPartion(now-1000l*3600*24*15, now+1000l*3600*24*1, this.getPartionType());
  			 for(Entry<String, HashSet<String>> e:w.entrySet())
  			 {
  				 String part=e.getKey();
  				 for(String day:e.getValue())
  				 {
  					 dayPartions.put(day, part);
  				 }
  			 }
  		} catch (Exception e1) {
  		}
  	}
  	
  	 private HashMap<String,HashSet<String>> dayPartion(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;
  			}
  			return ThedatePartionsUtils.parseDays(list,parttype);
  	    }
  	
  	public HashMap<String, ShardCount> getSmallestDaycount() {
  		return this.topMap(this.smallest, false, 2);
  	}
  	
  	public HashMap<String, ShardCount> getBiggestDaycount() {
  		HashMap<String, ShardCount> daystat=new HashMap<String, SolrInfo.ShardCount>();
  		daystat.putAll(this.topMap(this.daycount,true,5));
  		daystat.putAll(this.topMap(this.biggest,true,5));
  		return this.topMap(daystat, true, 5);
  	}
  	public HashMap<String, ShardCount> getPartioncount() {
  		return super.getPartioncount();
  	}
  	
  	public HashMap<String, ShardCount> getExtaCount(){
  		HashMap<String, ShardCount> daystat=new HashMap<String, SolrInfo.ShardCount>();
  		daystat.putAll(this.getSmallestDaycount());
  		daystat.putAll(this.getBiggestDaycount());
  		return daystat;
  	}
  
  	public HashMap<String, ShardCount> topMap(HashMap<String, ShardCount> map,boolean isdesc,int num)
  	{
  		ArrayList<shardCountDayCmp> list=new ArrayList<shardCountDayCmp>();
  		for(Entry<String, ShardCount> e:map.entrySet())
  		{
  			ShardCount sc=e.getValue();
  			if(sc.cnt>0&&!sc.isTimeout())
  			{
  				list.add(new shardCountDayCmp(e.getKey(), sc,isdesc));
  			}
  		}
  		
  		Collections.sort(list);
  		
  		HashMap<String, ShardCount> daystat=new HashMap<String, SolrInfo.ShardCount>();
  		for(int i=0;i<num&&i<list.size();i++)
  		{
  			shardCountDayCmp cmp=list.get(i);
  			daystat.put(cmp.day, cmp.shardCount);
  		}
  		
  		return daystat;
  	}
  	
  	private static class shardCountDayCmp implements Comparable<shardCountDayCmp>{
  		public String day;
  		public ShardCount shardCount;
  		public boolean isdesc=false;
  		public shardCountDayCmp(String day, ShardCount shardCount,boolean isdesc) {
  			super();
  			this.day = day;
  			this.shardCount = shardCount;
  			this.isdesc=isdesc;
  		}
  		@Override
  		public int compareTo(shardCountDayCmp o) {
  			int rtn= this.day.compareTo(o.day);
  			if(isdesc)
  			{
  				rtn*=-1;
  			}
  			return rtn;
  		}
  	}
  }
  