package htsjdk.samtools.cram.encoding.reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import htsjdk.samtools.cram.encoding.reader.NameCollate.IRead;
import htsjdk.samtools.util.Log;
public abstract class NameCollate<R extends IRead> {
private static final Log log = Log.getInstance(NameCollate.class);
private Map<R, R> readSet = new TreeMap<R, R>();
private int maxCacheSize = 100000;
private long generation = 0;
protected void foundCollision(R key, R alien) {
R anchor = readSet.remove(key);
ready(anchor);
ready(alien);
}
private Comparator<R> byGenerationComparator = new Comparator<R>() {
@Override
public int compare(R o1, R o2) {
return (int) (o1.getAge() - o2.getAge());
}
};
private List<R> list = new ArrayList<R>();
protected void purgeCache() {
long time1 = System.nanoTime();
list.clear();
for (R read : readSet.keySet())
list.add(read);
Collections.sort(list, byGenerationComparator);
for (int i = 0; i < list.size() / 2; i++) {
readSet.remove(list.get(i));
kickedFromCache(list.get(i));
}
list.clear();
long time2 = System.nanoTime();
log.debug(String.format("Cache purged in %.2fms.\n", (time2 - time1) / 1000000f));
}
protected abstract boolean needsCollating(R read);
protected abstract void ready(R read);
protected abstract void kickedFromCache(R read);
public void add(R read) {
read.setAge(generation++);
if (!needsCollating(read)) {
ready(read);
return;
}
if (readSet.containsKey(read)) {
foundCollision(readSet.get(read), read);
} else {
readSet.put(read, read);
if (readSet.size() > maxCacheSize)
purgeCache();
}
}
public void close() {
for (R read : readSet.keySet()) {
kickedFromCache(read);
}
readSet.clear();
}
public interface IRead extends Comparable<IRead> {
public long getAge();
public void setAge(long age);
}
}