soot.jimple.infoflow.collect.ConcurrentIdentityHashMultiMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of soot-infoflow Show documentation
Show all versions of soot-infoflow Show documentation
Soot extending data flow tracking components for Java
The newest version!
/* Soot - a J*va Optimization Framework
* Copyright (C) 2002 Ondrej Lhotak
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package soot.jimple.infoflow.collect;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import soot.util.AbstractMultiMap;
import soot.util.HashMultiMap;
import soot.util.MultiMap;
/**
* A concurrent version of the {@link HashMultiMap} that uses object identity
* for comparison
*
* @author Steven Arzt
*
*/
public class ConcurrentIdentityHashMultiMap extends AbstractMultiMap {
private static final long serialVersionUID = -6721251660349964507L;
Map> m = new ConcurrentIdentityHashMap>();
public ConcurrentIdentityHashMultiMap() {
}
public ConcurrentIdentityHashMultiMap(MultiMap m) {
putAll(m);
}
@Override
public int numKeys() {
return m.size();
}
@Override
public boolean containsKey(Object key) {
return m.containsKey(key);
}
@Override
public boolean containsValue(V value) {
for (Map s : m.values())
if (s.containsKey(value))
return true;
return false;
}
protected ConcurrentMap newSet() {
return new ConcurrentHashMap();
}
private ConcurrentMap findSet(K key) {
ConcurrentMap 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;
}
@Override
public boolean put(K key, V value) {
return findSet(key).put(value, value) == null;
}
public V putIfAbsent(K key, V value) {
return findSet(key).putIfAbsent(value, value);
}
@Override
public boolean putAll(K key, Collection values) {
if (values.isEmpty())
return false;
Map set = findSet(key);
boolean ok = false;
for (V v : values)
if (set.put(v, v) == null)
ok = true;
return ok;
}
@Override
public boolean remove(K key, V value) {
Map s = m.get(key);
if (s == null)
return false;
boolean ret = s.remove(value) != null;
if (s.isEmpty()) {
m.remove(key);
}
return ret;
}
@Override
public boolean remove(K key) {
return null != m.remove(key);
}
@Override
public boolean removeAll(K key, Collection values) {
Map s = m.get(key);
if (s == null)
return false;
boolean ret = false;
for (V v : values)
if (s.remove(v) != null)
ret = true;
if (s.isEmpty()) {
m.remove(key);
}
return ret;
}
@Override
public Set get(K o) {
Map ret = m.get(o);
if (ret == null)
return Collections.emptySet();
return ret.keySet();
}
@Override
public Set keySet() {
return m.keySet();
}
@Override
public Set values() {
Set ret = new HashSet(m.size());
for (Map s : m.values())
ret.addAll(s.keySet());
return ret;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof MultiMap))
return false;
@SuppressWarnings("unchecked")
MultiMap mm = (MultiMap) o;
if (!keySet().equals(mm.keySet()))
return false;
for (Map.Entry> e : m.entrySet()) {
Map s = e.getValue();
Set otherValues = mm.get(e.getKey());
if (!s.keySet().equals(otherValues))
return false;
}
return true;
}
@Override
public int hashCode() {
return m.hashCode();
}
@Override
public int size() {
return m.size();
}
@Override
public void clear() {
m.clear();
}
}