@Test public void whenInsertDuplicatesInMultiSet_thenInserted() { final Multiset<String> names = HashMultiset.create(); names.add("John"); names.add("Adam", 3); names.add("John"); assertEquals(2, names.count("John")); names.remove("John"); assertEquals(1, names.count("John")); assertEquals(3, names.count("Adam")); names.remove("Adam", 2); assertEquals(1, names.count("Adam")); }
public void testCreateWithSize() { Multiset<String> multiset = HashMultiset.create(50); multiset.add("foo", 2); multiset.add("bar"); assertEquals(3, multiset.size()); assertEquals(2, multiset.count("foo")); }
public void testCreateWithComparator() { Multiset<String> multiset = TreeMultiset.create(Collections.reverseOrder()); multiset.add("foo", 2); multiset.add("bar"); assertEquals(3, multiset.size()); assertEquals(2, multiset.count("foo")); assertEquals("[foo x 2, bar]", multiset.toString()); }
@Override public int count(Object element) { int count = unfiltered.count(element); if (count > 0) { @SuppressWarnings("unchecked") // element is equal to an E E e = (E) element; return predicate.apply(e) ? count : 0; } return 0; }
/** An implementation of {@link Multiset#setCount(Object, int, int)}. */ static <E> boolean setCountImpl(Multiset<E> self, E element, int oldCount, int newCount) { checkNonnegative(oldCount, "oldCount"); checkNonnegative(newCount, "newCount"); if (self.count(element) == oldCount) { self.setCount(element, newCount); return true; } else { return false; } }
/** * Returns {@code true} if {@code subMultiset.count(o) <= superMultiset.count(o)} for all {@code * o}. * * @since 10.0 */ public static boolean containsOccurrences(Multiset<?> superMultiset, Multiset<?> subMultiset) { checkNotNull(superMultiset); checkNotNull(subMultiset); for (Entry<?> entry : subMultiset.entrySet()) { int superCount = superMultiset.count(entry.getElement()); if (superCount < entry.getCount()) { return false; } } return true; }
/** An implementation of {@link Multiset#setCount(Object, int)}. */ static <E> int setCountImpl(Multiset<E> self, E element, int count) { checkNonnegative(count, "count"); int oldCount = self.count(element); int delta = count - oldCount; if (delta > 0) { self.add(element, delta); } else if (delta < 0) { self.remove(element, -delta); } return oldCount; }
/** * For each occurrence of an element {@code e} in {@code occurrencesToRemove}, removes one * occurrence of {@code e} in {@code multisetToModify}. * * <p>Equivalently, this method modifies {@code multisetToModify} so that {@code * multisetToModify.count(e)} is set to {@code Math.max(0, multisetToModify.count(e) - * occurrencesToRemove.count(e))}. * * <p>This is <i>not</i> the same as {@code multisetToModify.} {@link Multiset#removeAll * removeAll}{@code (occurrencesToRemove)}, which removes all occurrences of elements that appear * in {@code occurrencesToRemove}. However, this operation <i>is</i> equivalent to, albeit * sometimes more efficient than, the following: * * <pre>{@code * for (E e : occurrencesToRemove) { * multisetToModify.remove(e); * } * }</pre> * * @return {@code true} if {@code multisetToModify} was changed as a result of this operation * @since 10.0 (missing in 18.0 when only the overload taking an {@code Iterable} was present) */ public static boolean removeOccurrences( Multiset<?> multisetToModify, Multiset<?> occurrencesToRemove) { checkNotNull(multisetToModify); checkNotNull(occurrencesToRemove); boolean changed = false; Iterator<? extends Entry<?>> entryIterator = multisetToModify.entrySet().iterator(); while (entryIterator.hasNext()) { Entry<?> entry = entryIterator.next(); int removeCount = occurrencesToRemove.count(entry.getElement()); if (removeCount >= entry.getCount()) { entryIterator.remove(); changed = true; } else if (removeCount > 0) { multisetToModify.remove(entry.getElement(), removeCount); changed = true; } } return changed; }
/** Delegate implementation which cares about the element type. */ private static <E> boolean retainOccurrencesImpl( Multiset<E> multisetToModify, Multiset<?> occurrencesToRetain) { checkNotNull(multisetToModify); checkNotNull(occurrencesToRetain); // Avoiding ConcurrentModificationExceptions is tricky. Iterator<Entry<E>> entryIterator = multisetToModify.entrySet().iterator(); boolean changed = false; while (entryIterator.hasNext()) { Entry<E> entry = entryIterator.next(); int retainCount = occurrencesToRetain.count(entry.getElement()); if (retainCount == 0) { entryIterator.remove(); changed = true; } else if (retainCount < entry.getCount()) { multisetToModify.setCount(entry.getElement(), retainCount); changed = true; } } return changed; }
/** An implementation of {@link Multiset#equals}. */ static boolean equalsImpl(Multiset<?> multiset, Object object) { if (object == multiset) { return true; } if (object instanceof Multiset) { Multiset<?> that = (Multiset<?>) object; /* * We can't simply check whether the entry sets are equal, since that * approach fails when a TreeMultiset has a comparator that returns 0 * when passed unequal elements. */ if (multiset.size() != that.size() || multiset.entrySet().size() != that.entrySet().size()) { return false; } for (Entry<?> entry : that.entrySet()) { if (multiset.count(entry.getElement()) != entry.getCount()) { return false; } } return true; } return false; }
public void testCreateFromIterable() { Multiset<String> multiset = HashMultiset.create(Arrays.asList("foo", "bar", "foo")); assertEquals(3, multiset.size()); assertEquals(2, multiset.count("foo")); }
public void testCreateFromIterable() { Multiset<String> multiset = TreeMultiset.create(Arrays.asList("foo", "bar", "foo")); assertEquals(3, multiset.size()); assertEquals(2, multiset.count("foo")); assertEquals("[bar, foo x 2]", multiset.toString()); }
/** * The core scoring method for statistics queries * * @param statisticsQuery query to be peformed on statisticsStorage * @param statisticsStorage core data for Statistics qeries * @param scoringExps an out parameter. * <p>- If null, experiment counts result of statisticsQuery should be returned. if - If * non-null, it serves as a flag that an optimised statisticsQuery should be performed to just * collect Experiments for which non-zero counts exist for Statistics query. A typical call * scenario in this case is just one efv per statisticsQuery, in which we can both: 1. check * if the efv Attribute itself is a scoring one 2. map this Attribute and Experimeants in * scoringExps to efo terms - via the reverse mapping efv-experiment-> efo term in EfoIndex * (c.f. atlasStatisticsQueryService.getScoringAttributesForGenes()) * @return Multiset of aggregated experiment counts, where the set of scores genes is intersected * across statisticsQuery.getConditions(), and union-ed across attributes within each * condition in statisticsQuery.getConditions(). */ public static Multiset<Integer> scoreQuery( StatisticsQueryCondition statisticsQuery, final StatisticsStorage statisticsStorage, Set<ExperimentInfo> scoringExps) { // gatherScoringExpsOnly -> experiment counts should be calculated for statisticsQuery // !gatherScoringExpsOnly -> scoring experiments should be collected (into scoringExps) only boolean gatherScoringExpsOnly = scoringExps != null; Set<StatisticsQueryOrConditions<StatisticsQueryCondition>> andStatisticsQueryConditions = statisticsQuery.getConditions(); Multiset<Integer> results = null; if (andStatisticsQueryConditions.isEmpty()) { // End of recursion Set<Integer> bioEntityIdRestrictionSet = statisticsQuery.getBioEntityIdRestrictionSet(); Set<EfAttribute> attributes = statisticsQuery.getAttributes(); if (attributes.isEmpty()) { // No attributes were provided - we have to use pre-computed scores across all attributes Multiset<Integer> scoresAcrossAllEfos = statisticsStorage.getScoresAcrossAllEfos(statisticsQuery.getStatisticsType()); results = intersect(scoresAcrossAllEfos, bioEntityIdRestrictionSet); } else { results = HashMultiset.create(); setQueryExperiments(statisticsQuery, statisticsStorage); // For each experiment in the query, traverse through all attributes and add all gene // indexes into one ConciseSet. This way a gene can score // only once for a single experiment - across all OR attributes in this query. Once all // attributes have been traversed for a single experiment, // add ConciseSet to Multiset results for (ExperimentInfo exp : statisticsQuery.getExperiments()) { FastSet statsForExperiment = new FastSet(); for (EfAttribute attr : attributes) { Map<ExperimentInfo, ConciseSet> expsToStats = getStatisticsForAttribute( statisticsQuery.getStatisticsType(), attr, statisticsStorage); if (expsToStats != null) { if (expsToStats.isEmpty()) { log.debug( "Failed to retrieve stats for stat: " + statisticsQuery.getStatisticsType() + " and attr: " + attr); } else { if (expsToStats.get(exp) != null) { if (!gatherScoringExpsOnly) { statsForExperiment.addAll( intersect(expsToStats.get(exp), bioEntityIdRestrictionSet)); } else if (containsAtLeastOne(expsToStats.get(exp), bioEntityIdRestrictionSet)) { // exp contains at least one non-zero score for at least one gene index in // bioEntityIdRestrictionSet -> add it to scoringExps scoringExps.add(exp); } } else { log.debug( "Failed to retrieve stats for stat: " + statisticsQuery.getStatisticsType() + " exp: " + exp.getAccession() + " and attr: " + attr); } } } } if (!gatherScoringExpsOnly) { results.addAll(statsForExperiment); } } } } else { // run over all AND conditions, do "OR" inside (cf. scoreOrStatisticsQueryConditions()) , // "AND"'ing over the whole thing for (StatisticsQueryOrConditions<StatisticsQueryCondition> orConditions : andStatisticsQueryConditions) { // Pass gene restriction set down to orConditions orConditions.setGeneRestrictionSet(statisticsQuery.getBioEntityIdRestrictionSet()); // process OR conditions Multiset<Integer> condGenes = getScoresForOrConditions(orConditions, statisticsStorage, scoringExps); if (results == null) results = condGenes; else { Iterator<Multiset.Entry<Integer>> resultGenes = results.entrySet().iterator(); while (resultGenes.hasNext()) { Multiset.Entry<Integer> entry = resultGenes.next(); if (!condGenes.contains( entry.getElement())) // AND operation between different top query conditions resultGenes.remove(); else // for all gene ids belonging to intersection of all conditions seen so far, we // accumulate experiment counts results.setCount( entry.getElement(), entry.getCount() + condGenes.count(entry.getElement())); } } } } if (results == null) { results = HashMultiset.create(); } return results; }