@Override public boolean equals(Object o) { if (!(o instanceof MultiMap)) { return false; } @SuppressWarnings("unchecked") MultiMap<K, V> mm = (MultiMap<K, V>) o; if (!keySet().equals(mm.keySet())) { return false; } for (Map.Entry<K, ConcurrentMap<V, V>> e : m.entrySet()) { Map<V, V> s = e.getValue(); if (!s.equals(mm.get(e.getKey()))) { return false; } } return true; }
@Override public boolean put(K key, V value) { return findSet(key).put(value, value) == null; }
private ConcurrentMap<V, V> findSet(K key) { ConcurrentMap<V, V> s = m.get(key); if (s == null) { synchronized (this) { // Better check twice, another thread may have created a set in // the meantime s = m.get(key); if (s == null) { s = newSet(); m.put(key, s); } } } return s; }
/** * Ensures that the clear collection exists */ private void ensureClears() { if (clears == null) { synchronized (this) { if (clears == null) clears = new ConcurrentHashMultiMap<>(); } } }
/** * Adds the given abstraction and statement to the result map * * @param abs * The abstraction to be collected * @param stmt * The statement at which the abstraction was collected */ protected void addResult(Abstraction abs, Stmt stmt) { // Add the abstraction to the map. If we already have an equal // abstraction, we must add the current one as a neighbor. if (!this.result.put(abs, stmt)) { for (Abstraction abs2 : result.keySet()) { if (abs.equals(abs2)) { abs2.addNeighbor(abs); break; } } } }
/** * Removes all collected abstractions that are neither returned from the method * to be summarized, nor referenced in gaps */ private void purgeResults() { for (Iterator<Abstraction> absIt = result.keySet().iterator(); absIt.hasNext();) { Abstraction abs = absIt.next(); // If this a taint on a field of a gap object, we need to report it as // well. Code can obtain references to library objects are store data in // there. boolean isGapField = gapManager.isLocalReferencedInGap(abs.getAccessPath().getPlainValue()); // If this abstraction is neither referenced in a gap, nor returned, // we remove it if (!isGapField) { boolean isReturned = false; for (Stmt stmt : result.get(abs)) if (isValueReturnedFromCall(stmt, abs)) { isReturned = true; break; } if (!isReturned) absIt.remove(); } } }
public ConcurrentHashMultiMap(MultiMap<K, V> m) { putAll(m); }
/** * Ensures that the flow collection exists */ private void ensureFlows() { if (flows == null) { synchronized (this) { if (flows == null) flows = new ConcurrentHashMultiMap<>(); } } }
public MethodSummaries() { this(new ConcurrentHashMultiMap<String, MethodFlow>()); }
public V putIfAbsent(K key, V value) { return findSet(key).putIfAbsent(value, value); }
ConcurrentMap<V, V> newSet = newSet(); for (V v : values) { newSet.put(v, v);
/** * Adds the given result to this data structure * * @param sink The sink at which the taint arrived * @param source The source from which the taint originated */ public void addResult(ResultSinkInfo sink, ResultSourceInfo source) { if (results == null) { synchronized (this) { if (results == null) results = new ConcurrentHashMultiMap<>(); } } this.results.put(sink, source); }