package org.wikibrain.utils; /** * Priority queue that stores the largest or smallest n scores. * * @author Shilad Sen */ public class Scoreboard<T> { public static enum Order { INCREASING, DECREASING } private T[] elements; private double[] scores; private Order order; public Scoreboard(int maxCapacity) { this(maxCapacity, Order.DECREASING); } public Scoreboard(int maxCapacity, Order order) { this.order = order; this.elements = (T[]) new Object[maxCapacity]; this.scores = new double[maxCapacity]; } public void add(T element, double score) { if (!belongs(score)) { return; } // Find the correct index. int nextIndex = scores.length - 1; if (order == Order.DECREASING) { for (nextIndex = scores.length - 1; nextIndex >= 0; nextIndex--) { if (elements[nextIndex] != null && score < scores[nextIndex]) { break; } } } else { for (nextIndex = scores.length - 1; nextIndex >= 0; nextIndex--) { if (elements[nextIndex] != null && score > scores[nextIndex]) { break; } } } int targetIndex = nextIndex + 1; if (targetIndex >= scores.length) { throw new IllegalStateException(); } // Slide things down, drop the last element for (int i = scores.length - 2 ;i >= targetIndex; i--) { scores[i+1] = scores[i]; elements[i+1] = elements[i]; } // insert the right element scores[targetIndex] = score; elements[targetIndex] = element; } public int size() { for (int i = 0; i < elements.length; i++) { if (elements[i] == null) { return i; } } return elements.length; } public double getScore(int i) { return scores[i]; } public T getElement(int i) { return elements[i]; } private boolean belongs(double score) { if (elements[elements.length - 1] == null) { return true; } double lastScore = scores[elements.length - 1]; if (order == Order.DECREASING) { return (score > lastScore); } else { return (score < lastScore); } } }