sclass MultiSetAndTopTen { int maxEntries = 100000, topTenTargetLength = 10; Map ms; L topTen; Set topTenSet; *() {} *(Map *ms, L *topTen) { topTenSet = new TreeSet(topTen); } void add(A a) { long count = longMultiSet_add(ms, a); insertToTopTen(a, count); if (l(ms) >= maxEntries) longMultiSet_dropBottomPart(ms, l(ms)-iround(maxEntries*0.9)); } void insertToTopTen(A a, long count) { int originalIndex = topTenSet.contains(a) ? indexOf(topTen, a) : -1; int i = originalIndex < 0 ? l(topTen) : originalIndex; while (i > 0 && count >= toLong(ms.get(topTen.get(i-1)))) --i; if (i >= topTenTargetLength || i == originalIndex) ret; if (originalIndex >= 0) topTen.remove(originalIndex); topTen.add(i, a); topTenSet.add(a); while (l(topTen) > topTenTargetLength) topTenSet.remove(popLast(topTen)); } void printTopTen { printAsciiHeading("TOP TEN (OF " + l(ms) + ")"); pnl(map(topTen, func(S s) { s + " [" + ms.get(s) + "]" })); } void newTopTen(int size) { topTenTargetLength = size; replaceCollection(topTen, takeFirst(size, sortByDescScore(keys(ms), ms))); topTenSet = new TreeSet(topTen); } int numEntries() { ret l(ms); } long numOccurrences() { ret longMultiSet_l(ms); } bool contains(A a) { ret ms.contains(a); } long get(A a) { ret toLong(ms.get(a)); } L topTen() { ret cloneList(topTen); } }