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