package proj.zoie.perf.mbean;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermEnum;
import proj.zoie.api.ZoieIndexReader;
import proj.zoie.impl.indexing.ZoieSystem;
import proj.zoie.perf.server.MonitoredZoieService;
import proj.zoie.service.api.SearchRequest;
import proj.zoie.service.api.SearchResult;
public class PerfZoieServiceAdmin implements PerfZoieServiceMBean
{
protected static int numThreads = 4;
protected int _waitTimeMillis = 0;
protected ExecutorService _threadPool = Executors.newFixedThreadPool(numThreads + 1);
protected volatile boolean _perfRunStarted = false;
protected volatile ZoieSystem<IndexReader,?> _zoieSystem;
protected volatile MonitoredZoieService<?> _svc;
protected volatile Thread _perfThread;
// #queries per minute monitoring
protected long _beginTime=0L;
protected long _beginCount = 0;
public void setWaitTimeMillis(int waitTimeMillis)
{
_waitTimeMillis = waitTimeMillis;
}
public int getWaitTimeMillis()
{
return _waitTimeMillis;
}
public void setMonitoredZoieService(MonitoredZoieService<?> svc)
{
_svc = svc;
}
public MonitoredZoieService<?> getMonitoredZoieService()
{
return _svc;
}
public void setZoieSystem(ZoieSystem<IndexReader,?> system)
{
_zoieSystem = system;
}
public ZoieSystem<?,?> getZoieSystem()
{
return _zoieSystem;
}
public synchronized void startPerfRun()
{
if(!_perfRunStarted)
{
_perfRunStarted = true;
_perfThread = new Thread(new QueryDriverRunnable());
_perfThread.start();
}
}
public synchronized void endPerfRun()
{
_perfRunStarted = false;
}
public int percentileLatency(int pct)
{
return _svc.percentileLatency(pct);
}
public int percentileQPS(int pct)
{
return _svc.percentileQps(pct);
}
public int percentileHits(int pct)
{
return _svc.percentileHits(pct);
}
protected class QueryDriverRunnable implements Runnable
{
public void run()
{
List<String> queryTerms = new ArrayList<String>();
List<ZoieIndexReader<IndexReader>> readers = null;
TermEnum terms = null;
try
{
readers = _zoieSystem.getIndexReaders();
MultiReader reader = new MultiReader(readers.toArray(new IndexReader[readers.size()]));
int numDocs = reader.numDocs();
terms = reader.terms();
while(terms.next() && queryTerms.size() < 10000)
{
Term term = terms.term();
int docFreq = reader.docFreq(term);
if(docFreq * 100 >= numDocs) queryTerms.add(term.text());
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try
{
if(terms != null)
terms.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
while(_perfRunStarted)
{
int i = (int) (queryTerms.size() * Math.random());
String q = queryTerms.get(i);
final SearchRequest req = new SearchRequest();
req.setQuery(q);
_threadPool.submit(new Callable<SearchResult>()
{
public SearchResult call() throws Exception
{
Thread.sleep(_waitTimeMillis);
return _svc.search(req);
}
});
}
}
}
public int getNumSearches()
{
return _svc.numSearches();
}
public void beginTiming()
{
_beginTime = System.nanoTime()/1000000; // in millis
_beginCount = _svc.numSearches();
}
public long getAverage(){
return _svc.getAverage();
}
public long getQueiesPerMinute()
{
long currentCount = _svc.numSearches();
long currentTime = System.nanoTime()/1000000;
long delta = (currentCount -_beginCount)*60000;
long duration = currentTime - _beginTime;
if (duration < 1) return 0;
// one minute is 60s = 60000 ms;
long speed = delta / duration;
return speed;
}
}