// now synchronized
persistable sclass MultiBest {
Cl best = new L;
double score = negativeInfinity();
bool verboseNewBest;
synchronized double bestScore aka score aka getScore() {
ret best == null ? minusInfinity() : score;
}
bool isEmpty() { ret best.isEmpty(); }
synchronized float floatScoreOr(float defaultValue) {
ret best == null ? defaultValue : (float) score;
}
void put(Pair extends A, Double> p) {
if (p != null) put(p.a, p.b);
}
void put(A a, double score) {
ping();
bool newBest;
if (a != null) synchronized(this) {
if (score > this.score) {
best.clear();
this.score = score;
set newBest;
}
if (score >= this.score) {
best.add(a);
}
}
if (newBest && verboseNewBest) print("New best! " + this);
}
synchronized Cl get() { ret best; }
synchronized bool has() { ret !isEmpty(); }
toString {
ret isEmpty() ? "-"
: "Score " + formatDouble_significant2(score, 4)
+ (tied() ? ", " + nWinners(duplicity()) : "")
+ ": " + joinWithComma(map stringify(best));
}
S stringify(A a) { ret str(a); }
bool tied() { ret duplicity() > 1; }
int duplicity() { ret best.size(); }
synchronized void clear() { best.clear(); score = 0; }
}