/*******************************************************************************
* Copyright (c) 2007, 2010 Association for Decentralized Information Management
* in Industry THTH ry.
* 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:
* VTT Technical Research Centre of Finland - initial API and implementation
*******************************************************************************/
package org.simantics.utils.datastructures;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* MapSet is an associative data structure a key type on the left side (L) and a
* set element type of the right side.
*
*
* Based on {@link MapList} by Toni Kalajainen.
*
*
* @author Tuukka Lehtonen
*/
public abstract class MapSet {
protected Map> sets;
public static class Hash extends MapSet {
public Hash() {
sets = new HashMap>();
}
protected Set getOrCreateSet(L key) {
Set set = sets.get(key);
if (set == null) {
set = new HashSet();
sets.put(key, set);
}
return set;
}
}
public static class Tree extends MapSet {
public Tree() {
sets = new TreeMap>();
}
public Tree(Comparator super L> comparator) {
sets = new TreeMap>(comparator);
}
protected Set getOrCreateSet(L key) {
Set set = sets.get(key);
if (set == null) {
set = new HashSet();
sets.put(key, set);
}
return set;
}
}
public boolean add(L key, R value) {
Set set = getOrCreateSet(key);
return set.add(value);
}
protected abstract Set getOrCreateSet(L key);
private Set getSet(L key) {
return sets.get(key);
}
/**
* @param key
* @return a valid set, empty if no values exist
*/
public Set removeValues(L key) {
Set set = sets.remove(key);
if (set == null)
return Collections.emptySet();
return set;
}
public boolean remove(L key, R value) {
Set set = getSet(key);
if (set == null)
return false;
boolean result = set.remove(value);
if (set.isEmpty())
sets.remove(key);
return result;
}
public void clear() {
sets.clear();
}
public L[] getKeys(L[] list) {
return sets.keySet().toArray(list);
}
public Set getKeys() {
return sets.keySet();
}
public boolean hasValues(L key) {
return sets.containsKey(key);
}
public R[] getValues(L key, R[] list) {
Set l = sets.get(key);
if (l == null)
return null;
return l.toArray(list);
}
public Set getValues(L key) {
Set l = sets.get(key);
if (l == null)
return null;
return new HashSet(l);
}
public Set getValuesUnsafe(L key) {
return sets.get(key);
}
}