package topasin.calculate;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import topasin.compare.AsinComparable;
import topasin.util.TopAsinContext;
import topasin.util.TopAsinUtil;
/**
* hold top asin queue(heap)
*
* @author mengzang
*
*/
public final class TopAsinsCalculator {
private static int TOP_ASIN_COUNT;
/*
* this uses AsinComparable for sort
*/
private Queue<AsinDetailAnalysisFields> topAsins = new PriorityQueue<AsinDetailAnalysisFields>(TOP_ASIN_COUNT);
/*
* this uses asin string to avoid duplication
*/
private Set<String> topAsinSet = new HashSet<String>(TOP_ASIN_COUNT * 2);
private ReentrantLock sizeLock = new ReentrantLock();
public static void init(Map<String, Object> rtOptions) {
int topAsinCount = TopAsinUtil.getInt(rtOptions.get(TopAsinContext.TOP_ASIN_COUNT), 10);
TOP_ASIN_COUNT = topAsinCount;
}
AtomicInteger totalChanged = new AtomicInteger();
public boolean addTopAsin(AsinDetailAnalysisFields asinTopUnhealthDiff) {
if (asinTopUnhealthDiff.comparable.isValidAsinForTopAsin() == false) {
return false;
}
sizeLock.lock();
try {
if (topAsinSet.contains(asinTopUnhealthDiff.asin) == true) {
return true;
}
if (topAsins.size() == TOP_ASIN_COUNT) {
AsinComparable mini = topAsins.peek().comparable;
if (mini.compareForTopAsin(asinTopUnhealthDiff.comparable) >= 0) {
return false;
}
AsinDetailAnalysisFields notTop = topAsins.poll();
topAsinSet.remove(notTop.asin);
}
boolean ret = topAsins.add(asinTopUnhealthDiff);
topAsinSet.add(asinTopUnhealthDiff.asin);
return ret;
} finally {
sizeLock.unlock();
}
}
public Collection<AsinDetailAnalysisFields> getTopAsins() {
return topAsins;
}
public int getTotalUnhealthy() {
return totalChanged.get();
}
}