/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.core.util.collections;
import java.lang.reflect.Method;
import java.util.*;
import org.eclipse.php.internal.core.PHPCorePlugin;
public class BucketMap<K, V> {
private Map<K, Set<V>> map;
private Set<V> defaultSet = new HashSet<V>(1);
public BucketMap() {
map = new HashMap<K, Set<V>>();
}
public BucketMap(Set<V> set) {
this();
defaultSet = set;
}
public BucketMap(int size) {
map = new HashMap<K, Set<V>>(size);
}
public void add(K key, V value) {
Set<V> values = map.get(key);
if (values == null) {
values = createSet();
map.put(key, values);
}
values.add(value);
}
/**
* @return
*/
private Set<V> createSet() {
if (defaultSet instanceof Cloneable) {
try {
Method method = defaultSet.getClass().getMethod("clone", (Class<?>) null); //$NON-NLS-1$
return (Set<V>) method.invoke(defaultSet, new Object[] {});
} catch (Exception e) {
}
}
try {
return defaultSet.getClass().newInstance();
} catch (Exception e) {
PHPCorePlugin.log(e);
return new HashSet<V>(1);
}
}
public void addAll(K key, Collection<V> newValues) {
Set<V> values = map.get(key);
if (values == null) {
values = createSet();
map.put(key, values);
}
values.addAll(newValues);
}
public void merge(BucketMap<K, V> bucketMap) {
for (K key : bucketMap.getKeys()) {
addAll(key, bucketMap.getSet(key));
}
}
public boolean contains(K key, V value) {
Set<V> values = map.get(key);
if (values == null)
return false;
return values.contains(value);
}
public boolean containsKey(/* K */Object key) {
return map.containsKey(key);
}
public Set<V> get(K key) {
Set<V> values = getSet(key);
if (values == null)
return createSet();
return values;
}
public Set<V> getSet(Object key) {
return map.get(key);
}
public Set<V> getAll() {
Set<V> valuesSet = createSet();
for (Set<V> values : map.values()) {
for (V v : values)
valuesSet.add(v);
}
return valuesSet;
}
public boolean remove(K key, V value) {
Set<V> values = map.get(key);
if (values == null)
return false;
boolean result = values.remove(value);
if (values.size() == 0) {
map.remove(key);
}
return result;
}
public Collection<V> removeAll(K key) {
if (map.remove(key) != null)
return map.remove(key);
return createSet();
}
public void clear() {
map.clear();
}
public Set<K> getKeys() {
return map.keySet();
}
}