// analogous to OptimizedMultiSet static class MultiSetMapWithTopTen extends MultiSetMap { // outer tree map for sorting // inner linked hash set for reproducability (HashSet ordering sucks) MultiSetMap byCount = multiSetMap_innerLinkedHashSet_outerRevTreeMap(); *() {} *(bool useTreeMap) { super(useTreeMap); } *(MultiSetMap map) { super(map); } *(Map> data) { super(data); } private void unindex(A key, Set values) { if (nempty(values)) byCount.remove(l(values), key); } private void index(A key, Set values) { if (nempty(values)) byCount.add(l(values), key); } bool put(A key, B value) { synchronized(data) { Set set = data.get(key); unindex(key, set); if (set == null) data.put(key, set = _makeEmptySet()); bool changed = set.add(value); index(key, set); if (!changed) false; ret true with ++size; }} void remove(A key) { synchronized(data) { Set set = data.get(key); if (set == null) ret; size -= l(set); unindex(key, set); data.remove(key); }} void remove(A key, B value) { synchronized(data) { Set set = data.get(key); if (set == null) ret; unindex(key, set); bool changed = set.remove(value); index(key, set); if (changed) { --size; if (set.isEmpty()) data.remove(key); } }} void clear() { synchronized(data) { data.clear(); byCount.clear(); size = 0; }} // keys are the values in the byCount multimap ItIt keysByPopularityIterator() { ret multiSetMapValuesIterator(byCount); } }