All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.jimple.infoflow.collect.ConcurrentIdentityHashMultiMap Maven / Gradle / Ivy

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();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy