package org.wikibrain.sr.utils; import org.wikibrain.sr.SRResultList; public class Leaderboard { private double[] values; private int[] keys; private int size; public Leaderboard(int n) { values = new double[n+1]; keys = new int[n+1]; size = 0 ; keys[0] = Integer.MIN_VALUE; values[0] = Double.NEGATIVE_INFINITY; } public void tallyScore(int key, double value) { if (size < values.length - 1) { insert(key, value); } else if (value > values[1]) { assert(size == values.length - 1); removeMin(); insert(key, value); } } public SRResultList getTop() { SRResultList scores = new SRResultList(size); for (int i = 1; i <= size; i++) { scores.set(i - 1, keys[i], values[i]); } scores.sortDescending(); return scores; } public void print() { int i; for (i=1; i<=size;i++) System.out.print(values[i] + " "); System.out.println(); } private int leftChild(int pos) { return 2*pos; } private int rightChild(int pos) { return 2*pos + 1; } private int parent(int pos) { return pos / 2; } private boolean isLeaf(int pos) { return ((pos > size/2) && (pos <= size)); } private void swap(int pos1, int pos2) { double tmpVal; tmpVal = values[pos1]; values[pos1] = values[pos2]; values[pos2] = tmpVal; int tmpKey; tmpKey = keys[pos1]; keys[pos1] = keys[pos2]; keys[pos2] = tmpKey; } private void insert(int key, double value) { assert(size < values.length - 1); size++; keys[size] = key; values[size] = value; int current = size; while (values[current] < values[parent(current)]) { swap(current, parent(current)); current = parent(current); } } private int minKey() { return keys[1]; } private double minValue() { return values[1]; } private void removeMin() { swap(1,size); size--; if (size != 0) pushDown(1); } private void pushDown(int position) { int smallestChild; while (!isLeaf(position)) { smallestChild = leftChild(position); if ((smallestChild < size) && (values[smallestChild] > values[smallestChild+1])) smallestChild = smallestChild + 1; if (values[position] <= values[smallestChild]) return; swap(position,smallestChild); position = smallestChild; } } }